LLVM 24.0.0git
X86TargetTransformInfo.cpp
Go to the documentation of this file.
1//===-- X86TargetTransformInfo.cpp - X86 specific TTI pass ----------------===//
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/// \file
9/// This file implements a TargetTransformInfo analysis pass specific to the
10/// X86 target machine. It uses the target's detailed information to provide
11/// more precise answers to certain TTI queries, while letting the target
12/// independent and default TTI implementations handle the rest.
13///
14//===----------------------------------------------------------------------===//
15/// About Cost Model numbers used below it's necessary to say the following:
16/// the numbers correspond to some "generic" X86 CPU instead of usage of a
17/// specific CPU model. Usually the numbers correspond to the CPU where the
18/// feature first appeared. For example, if we do Subtarget.hasSSE42() in
19/// the lookups below the cost is based on Nehalem as that was the first CPU
20/// to support that feature level and thus has most likely the worst case cost,
21/// although we may discard an outlying worst cost from one CPU (e.g. Atom).
22///
23/// Some examples of other technologies/CPUs:
24/// SSE 3 - Pentium4 / Athlon64
25/// SSE 4.1 - Penryn
26/// SSE 4.2 - Nehalem / Silvermont
27/// AVX - Sandy Bridge / Jaguar / Bulldozer
28/// AVX2 - Haswell / Ryzen
29/// AVX-512 - Xeon Phi / Skylake
30///
31/// And some examples of instruction target dependent costs (latency)
32/// divss sqrtss rsqrtss
33/// AMD K7 11-16 19 3
34/// Piledriver 9-24 13-15 5
35/// Jaguar 14 16 2
36/// Pentium II,III 18 30 2
37/// Nehalem 7-14 7-18 3
38/// Haswell 10-13 11 5
39///
40/// Interpreting the 4 TargetCostKind types:
41/// TCK_RecipThroughput and TCK_Latency should try to match the worst case
42/// values reported by the CPU scheduler models (and llvm-mca).
43/// TCK_CodeSize should match the instruction count (e.g. divss = 1), NOT the
44/// actual encoding size of the instruction.
45/// TCK_SizeAndLatency should match the worst case micro-op counts reported by
46/// by the CPU scheduler models (and llvm-mca), to ensure that they are
47/// compatible with the MicroOpBufferSize and LoopMicroOpBufferSize values which are
48/// often used as the cost thresholds where TCK_SizeAndLatency is requested.
49//===----------------------------------------------------------------------===//
50
60#include <optional>
61
62using namespace llvm;
63
64#define DEBUG_TYPE "x86tti"
65
66//===----------------------------------------------------------------------===//
67//
68// X86 cost model.
69//
70//===----------------------------------------------------------------------===//
71
72// Helper struct to store/access costs for each cost kind.
73// TODO: Move this to allow other targets to use it?
75 unsigned RecipThroughputCost = ~0U;
76 unsigned LatencyCost = ~0U;
77 unsigned CodeSizeCost = ~0U;
78 unsigned SizeAndLatencyCost = ~0U;
79
80 std::optional<unsigned>
82 unsigned Cost = ~0U;
83 switch (Kind) {
86 break;
89 break;
92 break;
95 break;
96 }
97 if (Cost == ~0U)
98 return std::nullopt;
99 return Cost;
100 }
101};
104
106X86TTIImpl::getPopcntSupport(unsigned TyWidth) const {
107 assert(isPowerOf2_32(TyWidth) && "Ty width must be power of 2");
108 // TODO: Currently the __builtin_popcount() implementation using SSE3
109 // instructions is inefficient. Once the problem is fixed, we should
110 // call ST->hasSSE3() instead of ST->hasPOPCNT().
111 return ST->hasPOPCNT() ? TTI::PSK_FastHardware : TTI::PSK_Software;
112}
113
114std::optional<unsigned> X86TTIImpl::getCacheSize(
116 switch (Level) {
118 // - Penryn
119 // - Nehalem
120 // - Westmere
121 // - Sandy Bridge
122 // - Ivy Bridge
123 // - Haswell
124 // - Broadwell
125 // - Skylake
126 // - Kabylake
127 return 32 * 1024; // 32 KiB
129 // - Penryn
130 // - Nehalem
131 // - Westmere
132 // - Sandy Bridge
133 // - Ivy Bridge
134 // - Haswell
135 // - Broadwell
136 // - Skylake
137 // - Kabylake
138 return 256 * 1024; // 256 KiB
139 }
140
141 llvm_unreachable("Unknown TargetTransformInfo::CacheLevel");
142}
143
144std::optional<unsigned> X86TTIImpl::getCacheAssociativity(
146 // - Penryn
147 // - Nehalem
148 // - Westmere
149 // - Sandy Bridge
150 // - Ivy Bridge
151 // - Haswell
152 // - Broadwell
153 // - Skylake
154 // - Kabylake
155 switch (Level) {
157 [[fallthrough]];
159 return 8;
160 }
161
162 llvm_unreachable("Unknown TargetTransformInfo::CacheLevel");
163}
164
166
168 return Vector ? VectorClass
169 : Ty && Ty->isFloatingPointTy() ? ScalarFPClass
170 : GPRClass;
171}
172
173unsigned X86TTIImpl::getNumberOfRegisters(unsigned ClassID) const {
174 if (ClassID == VectorClass && !ST->hasSSE1())
175 return 0;
176
177 if (!ST->is64Bit())
178 return 8;
179
180 if ((ClassID == GPRClass && ST->hasEGPR()) ||
181 (ClassID != GPRClass && ST->hasAVX512()))
182 return 32;
183
184 return 16;
185}
186
188 if (!ST->hasCF())
189 return false;
190 if (!Ty)
191 return true;
192 // Conditional faulting is supported by CFCMOV, which only accepts
193 // 16/32/64-bit operands.
194 // TODO: Support f32/f64 with VMOVSS/VMOVSD with zero mask when it's
195 // profitable.
196 auto *VTy = dyn_cast<FixedVectorType>(Ty);
197 if (!Ty->isIntegerTy() && (!VTy || VTy->getNumElements() != 1))
198 return false;
199 auto *ScalarTy = Ty->getScalarType();
200 switch (cast<IntegerType>(ScalarTy)->getBitWidth()) {
201 default:
202 return false;
203 case 16:
204 case 32:
205 case 64:
206 return true;
207 }
208}
209
212 unsigned PreferVectorWidth = ST->getPreferVectorWidth();
213 switch (K) {
215 return TypeSize::getFixed(ST->is64Bit() ? 64 : 32);
217 if (ST->hasAVX512() && PreferVectorWidth >= 512)
218 return TypeSize::getFixed(512);
219 if (ST->hasAVX() && PreferVectorWidth >= 256)
220 return TypeSize::getFixed(256);
221 if (ST->hasSSE1() && PreferVectorWidth >= 128)
222 return TypeSize::getFixed(128);
223 return TypeSize::getFixed(0);
225 return TypeSize::getScalable(0);
226 }
227
228 llvm_unreachable("Unsupported register kind");
229}
230
235
237 bool HasUnorderedReductions) const {
238 // If the loop will not be vectorized, don't interleave the loop.
239 // Let regular unroll to unroll the loop, which saves the overflow
240 // check and memory check cost.
241 if (VF.isScalar())
242 return 1;
243
244 if (ST->isAtom())
245 return 1;
246
247 // Sandybridge and Haswell have multiple execution ports and pipelined
248 // vector units.
249 if (ST->hasAVX())
250 return 4;
251
252 return 2;
253}
254
256 unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind,
258 ArrayRef<const Value *> Args, const Instruction *CxtI) const {
259
260 // vXi8 multiplications are always promoted to vXi16.
261 // Sub-128-bit types can be extended/packed more efficiently.
262 if (Opcode == Instruction::Mul && Ty->isVectorTy() &&
263 Ty->getPrimitiveSizeInBits() <= 64 && Ty->getScalarSizeInBits() == 8) {
264 Type *WideVecTy =
266 return getCastInstrCost(Instruction::ZExt, WideVecTy, Ty,
268 CostKind) +
269 getCastInstrCost(Instruction::Trunc, Ty, WideVecTy,
271 CostKind) +
272 getArithmeticInstrCost(Opcode, WideVecTy, CostKind, Op1Info, Op2Info);
273 }
274
275 // Legalize the type.
276 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Ty);
277
278 int ISD = TLI->InstructionOpcodeToISD(Opcode);
279 assert(ISD && "Invalid opcode");
280
281 if (ISD == ISD::MUL && Args.size() == 2 && LT.second.isVector() &&
282 (LT.second.getScalarType() == MVT::i32 ||
283 LT.second.getScalarType() == MVT::i64)) {
284 // Check if the operands can be represented as a smaller datatype.
285 bool Op1Signed = false, Op2Signed = false;
286 unsigned Op1MinSize = BaseT::minRequiredElementSize(Args[0], Op1Signed);
287 unsigned Op2MinSize = BaseT::minRequiredElementSize(Args[1], Op2Signed);
288 unsigned OpMinSize = std::max(Op1MinSize, Op2MinSize);
289 bool SignedMode = Op1Signed || Op2Signed;
290
291 // If both vXi32 are representable as i15 and at least one is constant,
292 // zero-extended, or sign-extended from vXi16 (or less pre-SSE41) then we
293 // can treat this as PMADDWD which has the same costs as a vXi16 multiply.
294 if (OpMinSize <= 15 && !ST->isPMADDWDSlow() &&
295 LT.second.getScalarType() == MVT::i32) {
296 bool Op1Constant =
297 isa<ConstantDataVector>(Args[0]) || isa<ConstantVector>(Args[0]);
298 bool Op2Constant =
299 isa<ConstantDataVector>(Args[1]) || isa<ConstantVector>(Args[1]);
300 bool Op1Sext = isa<SExtInst>(Args[0]) &&
301 (Op1MinSize == 15 || (Op1MinSize < 15 && !ST->hasSSE41()));
302 bool Op2Sext = isa<SExtInst>(Args[1]) &&
303 (Op2MinSize == 15 || (Op2MinSize < 15 && !ST->hasSSE41()));
304
305 bool IsZeroExtended = !Op1Signed || !Op2Signed;
306 bool IsConstant = Op1Constant || Op2Constant;
307 bool IsSext = Op1Sext || Op2Sext;
308 if (IsConstant || IsZeroExtended || IsSext)
309 LT.second =
310 MVT::getVectorVT(MVT::i16, 2 * LT.second.getVectorNumElements());
311 }
312
313 // Check if the vXi32 operands can be shrunk into a smaller datatype.
314 // This should match the codegen from reduceVMULWidth.
315 // TODO: Make this generic (!ST->SSE41 || ST->isPMULLDSlow()).
316 if (ST->useSLMArithCosts() && LT.second == MVT::v4i32) {
317 if (OpMinSize <= 7)
318 return LT.first * 3; // pmullw/sext
319 if (!SignedMode && OpMinSize <= 8)
320 return LT.first * 3; // pmullw/zext
321 if (OpMinSize <= 15)
322 return LT.first * 5; // pmullw/pmulhw/pshuf
323 if (!SignedMode && OpMinSize <= 16)
324 return LT.first * 5; // pmullw/pmulhw/pshuf
325 }
326
327 // If both vXi64 are representable as (unsigned) i32, then we can perform
328 // the multiple with a single PMULUDQ instruction.
329 // TODO: Add (SSE41+) PMULDQ handling for signed extensions.
330 if (!SignedMode && OpMinSize <= 32 && LT.second.getScalarType() == MVT::i64)
331 ISD = X86ISD::PMULUDQ;
332 }
333
334 // Vector multiply by pow2 will be simplified to shifts.
335 // Vector multiply by -pow2 will be simplified to shifts/negates.
336 if (ISD == ISD::MUL && Op2Info.isConstant() &&
337 (Op2Info.isPowerOf2() || Op2Info.isNegatedPowerOf2())) {
339 getArithmeticInstrCost(Instruction::Shl, Ty, CostKind,
340 Op1Info.getNoProps(), Op2Info.getNoProps());
341 if (Op2Info.isNegatedPowerOf2())
342 Cost += getArithmeticInstrCost(Instruction::Sub, Ty, CostKind);
343 return Cost;
344 }
345
346 // On X86, vector signed division by constants power-of-two are
347 // normally expanded to the sequence SRA + SRL + ADD + SRA.
348 // The OperandValue properties may not be the same as that of the previous
349 // operation; conservatively assume OP_None.
350 if ((ISD == ISD::SDIV || ISD == ISD::SREM) &&
351 Op2Info.isConstant() && Op2Info.isPowerOf2()) {
353 2 * getArithmeticInstrCost(Instruction::AShr, Ty, CostKind,
354 Op1Info.getNoProps(), Op2Info.getNoProps());
355 Cost += getArithmeticInstrCost(Instruction::LShr, Ty, CostKind,
356 Op1Info.getNoProps(), Op2Info.getNoProps());
357 Cost += getArithmeticInstrCost(Instruction::Add, Ty, CostKind,
358 Op1Info.getNoProps(), Op2Info.getNoProps());
359
360 if (ISD == ISD::SREM) {
361 // For SREM: (X % C) is the equivalent of (X - (X/C)*C)
362 Cost += getArithmeticInstrCost(Instruction::Mul, Ty, CostKind, Op1Info.getNoProps(),
363 Op2Info.getNoProps());
364 Cost += getArithmeticInstrCost(Instruction::Sub, Ty, CostKind, Op1Info.getNoProps(),
365 Op2Info.getNoProps());
366 }
367
368 return Cost;
369 }
370
371 // Vector unsigned division/remainder will be simplified to shifts/masks.
372 if ((ISD == ISD::UDIV || ISD == ISD::UREM) &&
373 Op2Info.isConstant() && Op2Info.isPowerOf2()) {
374 if (ISD == ISD::UDIV)
375 return getArithmeticInstrCost(Instruction::LShr, Ty, CostKind,
376 Op1Info.getNoProps(), Op2Info.getNoProps());
377 // UREM
378 return getArithmeticInstrCost(Instruction::And, Ty, CostKind,
379 Op1Info.getNoProps(), Op2Info.getNoProps());
380 }
381
382 // A scalar integer divide/remainder by a constant is not a hardware divide;
383 // it lowers to a magic-number multiply-high plus a few fixup ops. Cost it as
384 // that sequence rather than the generic single-instruction divide, so the
385 // vectorizers do not compare against an artificially cheap scalar lane. The
386 // power-of-two cases are handled above; negated powers of two are left to the
387 // generic handling.
388 if (!Ty->isVectorTy() && Op2Info.isConstant() && !Op2Info.isNegatedPowerOf2() &&
389 (ISD == ISD::UDIV || ISD == ISD::SDIV || ISD == ISD::UREM ||
390 ISD == ISD::SREM)) {
391 unsigned Cost = ISD == ISD::UREM || ISD == ISD::SREM ? 6 : 5;
393 Cost += 2;
394 return LT.first * Cost;
395 }
396
397 static const CostKindTblEntry GFNIUniformConstCostTable[] = {
398 { ISD::SHL, MVT::v16i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
399 { ISD::SRL, MVT::v16i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
400 { ISD::SRA, MVT::v16i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
401 { ISD::SHL, MVT::v32i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
402 { ISD::SRL, MVT::v32i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
403 { ISD::SRA, MVT::v32i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
404 { ISD::SHL, MVT::v64i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
405 { ISD::SRL, MVT::v64i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
406 { ISD::SRA, MVT::v64i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
407 };
408
409 if (Op2Info.isUniform() && Op2Info.isConstant() && ST->hasGFNI())
410 if (const auto *Entry =
411 CostTableLookup(GFNIUniformConstCostTable, ISD, LT.second))
412 if (auto KindCost = Entry->Cost[CostKind])
413 return LT.first * *KindCost;
414
415 static const CostKindTblEntry AVX512BWUniformConstCostTable[] = {
416 { ISD::SHL, MVT::v16i8, { 1, 7, 2, 3 } }, // psllw + pand.
417 { ISD::SRL, MVT::v16i8, { 1, 7, 2, 3 } }, // psrlw + pand.
418 { ISD::SRA, MVT::v16i8, { 1, 8, 4, 5 } }, // psrlw, pand, pxor, psubb.
419 { ISD::SHL, MVT::v32i8, { 1, 8, 2, 3 } }, // psllw + pand.
420 { ISD::SRL, MVT::v32i8, { 1, 8, 2, 3 } }, // psrlw + pand.
421 { ISD::SRA, MVT::v32i8, { 1, 9, 4, 5 } }, // psrlw, pand, pxor, psubb.
422 { ISD::SHL, MVT::v64i8, { 1, 8, 2, 3 } }, // psllw + pand.
423 { ISD::SRL, MVT::v64i8, { 1, 8, 2, 3 } }, // psrlw + pand.
424 { ISD::SRA, MVT::v64i8, { 1, 9, 4, 6 } }, // psrlw, pand, pxor, psubb.
425
426 { ISD::SHL, MVT::v16i16, { 1, 1, 1, 1 } }, // psllw
427 { ISD::SRL, MVT::v16i16, { 1, 1, 1, 1 } }, // psrlw
428 { ISD::SRA, MVT::v16i16, { 1, 1, 1, 1 } }, // psrlw
429 { ISD::SHL, MVT::v32i16, { 1, 1, 1, 1 } }, // psllw
430 { ISD::SRL, MVT::v32i16, { 1, 1, 1, 1 } }, // psrlw
431 { ISD::SRA, MVT::v32i16, { 1, 1, 1, 1 } }, // psrlw
432 };
433
434 if (Op2Info.isUniform() && Op2Info.isConstant() && ST->hasBWI())
435 if (const auto *Entry =
436 CostTableLookup(AVX512BWUniformConstCostTable, ISD, LT.second))
437 if (auto KindCost = Entry->Cost[CostKind])
438 return LT.first * *KindCost;
439
440 static const CostKindTblEntry AVX512DQUniformConstCostTable[] = {
441 { ISD::SDIV, MVT::v4i64, { 15 } }, // vpmullq-based MULHS sequence
442 { ISD::SREM, MVT::v4i64, { 17 } }, // vpmullq-based MULHS+mul+sub sequence
443 { ISD::SDIV, MVT::v8i64, { 15 } }, // vpmullq-based MULHS sequence
444 { ISD::SREM, MVT::v8i64, { 17 } }, // vpmullq-based MULHS+mul+sub sequence
445 // The remainder's multiply-back is a single vpmullq with DQ, just like the
446 // pmulld the vXi32 entries above rely on. Without DQ it is another
447 // vpmuludq schoolbook, so the AVX512/AVX2 tables charge more.
448 { ISD::UREM, MVT::v4i64, { 17 } }, // MULHU + vpmullq + sub sequence
449 { ISD::UREM, MVT::v8i64, { 17 } }, // MULHU + vpmullq + sub sequence
450 };
451
452 if (Op2Info.isUniform() && Op2Info.isConstant() && ST->hasDQI())
453 if (const auto *Entry =
454 CostTableLookup(AVX512DQUniformConstCostTable, ISD, LT.second))
455 if (auto KindCost = Entry->Cost[CostKind])
456 return LT.first * *KindCost;
457
458 static const CostKindTblEntry AVX512UniformConstCostTable[] = {
459 { ISD::SHL, MVT::v64i8, { 2, 12, 5, 6 } }, // psllw + pand.
460 { ISD::SRL, MVT::v64i8, { 2, 12, 5, 6 } }, // psrlw + pand.
461 { ISD::SRA, MVT::v64i8, { 3, 10, 12, 12 } }, // psrlw, pand, pxor, psubb.
462
463 { ISD::SHL, MVT::v16i16, { 2, 7, 4, 4 } }, // psllw + split.
464 { ISD::SRL, MVT::v16i16, { 2, 7, 4, 4 } }, // psrlw + split.
465 { ISD::SRA, MVT::v16i16, { 2, 7, 4, 4 } }, // psraw + split.
466
467 { ISD::SHL, MVT::v8i32, { 1, 1, 1, 1 } }, // pslld
468 { ISD::SRL, MVT::v8i32, { 1, 1, 1, 1 } }, // psrld
469 { ISD::SRA, MVT::v8i32, { 1, 1, 1, 1 } }, // psrad
470 { ISD::SHL, MVT::v16i32, { 1, 1, 1, 1 } }, // pslld
471 { ISD::SRL, MVT::v16i32, { 1, 1, 1, 1 } }, // psrld
472 { ISD::SRA, MVT::v16i32, { 1, 1, 1, 1 } }, // psrad
473
474 { ISD::SRA, MVT::v2i64, { 1, 1, 1, 1 } }, // psraq
475 { ISD::SHL, MVT::v4i64, { 1, 1, 1, 1 } }, // psllq
476 { ISD::SRL, MVT::v4i64, { 1, 1, 1, 1 } }, // psrlq
477 { ISD::SRA, MVT::v4i64, { 1, 1, 1, 1 } }, // psraq
478 { ISD::SHL, MVT::v8i64, { 1, 1, 1, 1 } }, // psllq
479 { ISD::SRL, MVT::v8i64, { 1, 1, 1, 1 } }, // psrlq
480 { ISD::SRA, MVT::v8i64, { 1, 1, 1, 1 } }, // psraq
481
482 { ISD::SDIV, MVT::v16i32, { 6 } }, // pmuludq sequence
483 { ISD::SREM, MVT::v16i32, { 8 } }, // pmuludq+mul+sub sequence
484 { ISD::UDIV, MVT::v16i32, { 5 } }, // pmuludq sequence
485 { ISD::UREM, MVT::v16i32, { 7 } }, // pmuludq+mul+sub sequence
486
487 { ISD::UDIV, MVT::v8i64, { 15 } }, // pmuludq-based MULHU sequence
488 { ISD::UREM, MVT::v8i64, { 21 } }, // pmuludq-based MULHU+mul+sub sequence
489 };
490
491 if (Op2Info.isUniform() && Op2Info.isConstant() && ST->hasAVX512())
492 if (const auto *Entry =
493 CostTableLookup(AVX512UniformConstCostTable, ISD, LT.second))
494 if (auto KindCost = Entry->Cost[CostKind])
495 return LT.first * *KindCost;
496
497 static const CostKindTblEntry AVX2UniformConstCostTable[] = {
498 { ISD::SHL, MVT::v16i8, { 1, 8, 2, 3 } }, // psllw + pand.
499 { ISD::SRL, MVT::v16i8, { 1, 8, 2, 3 } }, // psrlw + pand.
500 { ISD::SRA, MVT::v16i8, { 2, 10, 5, 6 } }, // psrlw, pand, pxor, psubb.
501 { ISD::SHL, MVT::v32i8, { 2, 8, 2, 4 } }, // psllw + pand.
502 { ISD::SRL, MVT::v32i8, { 2, 8, 2, 4 } }, // psrlw + pand.
503 { ISD::SRA, MVT::v32i8, { 3, 10, 5, 9 } }, // psrlw, pand, pxor, psubb.
504
505 { ISD::SHL, MVT::v8i16, { 1, 1, 1, 1 } }, // psllw
506 { ISD::SRL, MVT::v8i16, { 1, 1, 1, 1 } }, // psrlw
507 { ISD::SRA, MVT::v8i16, { 1, 1, 1, 1 } }, // psraw
508 { ISD::SHL, MVT::v16i16,{ 2, 2, 1, 2 } }, // psllw
509 { ISD::SRL, MVT::v16i16,{ 2, 2, 1, 2 } }, // psrlw
510 { ISD::SRA, MVT::v16i16,{ 2, 2, 1, 2 } }, // psraw
511
512 { ISD::SHL, MVT::v4i32, { 1, 1, 1, 1 } }, // pslld
513 { ISD::SRL, MVT::v4i32, { 1, 1, 1, 1 } }, // psrld
514 { ISD::SRA, MVT::v4i32, { 1, 1, 1, 1 } }, // psrad
515 { ISD::SHL, MVT::v8i32, { 2, 2, 1, 2 } }, // pslld
516 { ISD::SRL, MVT::v8i32, { 2, 2, 1, 2 } }, // psrld
517 { ISD::SRA, MVT::v8i32, { 2, 2, 1, 2 } }, // psrad
518
519 { ISD::SHL, MVT::v2i64, { 1, 1, 1, 1 } }, // psllq
520 { ISD::SRL, MVT::v2i64, { 1, 1, 1, 1 } }, // psrlq
521 { ISD::SRA, MVT::v2i64, { 2, 3, 3, 3 } }, // psrad + shuffle.
522 { ISD::SHL, MVT::v4i64, { 2, 2, 1, 2 } }, // psllq
523 { ISD::SRL, MVT::v4i64, { 2, 2, 1, 2 } }, // psrlq
524 { ISD::SRA, MVT::v4i64, { 4, 4, 3, 6 } }, // psrad + shuffle + split.
525
526 { ISD::SDIV, MVT::v8i32, { 6 } }, // pmuludq sequence
527 { ISD::SREM, MVT::v8i32, { 8 } }, // pmuludq+mul+sub sequence
528 { ISD::UDIV, MVT::v8i32, { 5 } }, // pmuludq sequence
529 { ISD::UREM, MVT::v8i32, { 7 } }, // pmuludq+mul+sub sequence
530
531 { ISD::UDIV, MVT::v4i64, { 15 } }, // pmuludq-based MULHU sequence
532 { ISD::UREM, MVT::v4i64, { 21 } }, // pmuludq-based MULHU+mul+sub sequence
533 };
534
535 if (Op2Info.isUniform() && Op2Info.isConstant() && ST->hasAVX2())
536 if (const auto *Entry =
537 CostTableLookup(AVX2UniformConstCostTable, ISD, LT.second))
538 if (auto KindCost = Entry->Cost[CostKind])
539 return LT.first * *KindCost;
540
541 static const CostKindTblEntry AVXUniformConstCostTable[] = {
542 { ISD::SHL, MVT::v16i8, { 2, 7, 2, 3 } }, // psllw + pand.
543 { ISD::SRL, MVT::v16i8, { 2, 7, 2, 3 } }, // psrlw + pand.
544 { ISD::SRA, MVT::v16i8, { 3, 9, 5, 6 } }, // psrlw, pand, pxor, psubb.
545 { ISD::SHL, MVT::v32i8, { 4, 7, 7, 8 } }, // 2*(psllw + pand) + split.
546 { ISD::SRL, MVT::v32i8, { 4, 7, 7, 8 } }, // 2*(psrlw + pand) + split.
547 { ISD::SRA, MVT::v32i8, { 7, 7, 12, 13 } }, // 2*(psrlw, pand, pxor, psubb) + split.
548
549 { ISD::SHL, MVT::v8i16, { 1, 2, 1, 1 } }, // psllw.
550 { ISD::SRL, MVT::v8i16, { 1, 2, 1, 1 } }, // psrlw.
551 { ISD::SRA, MVT::v8i16, { 1, 2, 1, 1 } }, // psraw.
552 { ISD::SHL, MVT::v16i16,{ 3, 6, 4, 5 } }, // psllw + split.
553 { ISD::SRL, MVT::v16i16,{ 3, 6, 4, 5 } }, // psrlw + split.
554 { ISD::SRA, MVT::v16i16,{ 3, 6, 4, 5 } }, // psraw + split.
555
556 { ISD::SHL, MVT::v4i32, { 1, 2, 1, 1 } }, // pslld.
557 { ISD::SRL, MVT::v4i32, { 1, 2, 1, 1 } }, // psrld.
558 { ISD::SRA, MVT::v4i32, { 1, 2, 1, 1 } }, // psrad.
559 { ISD::SHL, MVT::v8i32, { 3, 6, 4, 5 } }, // pslld + split.
560 { ISD::SRL, MVT::v8i32, { 3, 6, 4, 5 } }, // psrld + split.
561 { ISD::SRA, MVT::v8i32, { 3, 6, 4, 5 } }, // psrad + split.
562
563 { ISD::SHL, MVT::v2i64, { 1, 2, 1, 1 } }, // psllq.
564 { ISD::SRL, MVT::v2i64, { 1, 2, 1, 1 } }, // psrlq.
565 { ISD::SRA, MVT::v2i64, { 2, 3, 3, 3 } }, // psrad + shuffle.
566 { ISD::SHL, MVT::v4i64, { 3, 6, 4, 5 } }, // 2 x psllq + split.
567 { ISD::SRL, MVT::v4i64, { 3, 6, 4, 5 } }, // 2 x psllq + split.
568 { ISD::SRA, MVT::v4i64, { 5, 7, 8, 9 } }, // 2 x psrad + shuffle + split.
569
570 { ISD::SDIV, MVT::v8i32, { 14 } }, // 2*pmuludq sequence + split.
571 { ISD::SREM, MVT::v8i32, { 18 } }, // 2*pmuludq+mul+sub sequence + split.
572 { ISD::UDIV, MVT::v8i32, { 12 } }, // 2*pmuludq sequence + split.
573 { ISD::UREM, MVT::v8i32, { 16 } }, // 2*pmuludq+mul+sub sequence + split.
574 };
575
576 // XOP has faster vXi8 shifts.
577 if (Op2Info.isUniform() && Op2Info.isConstant() && ST->hasAVX() &&
578 (!ST->hasXOP() || LT.second.getScalarSizeInBits() != 8))
579 if (const auto *Entry =
580 CostTableLookup(AVXUniformConstCostTable, ISD, LT.second))
581 if (auto KindCost = Entry->Cost[CostKind])
582 return LT.first * *KindCost;
583
584 static const CostKindTblEntry SSE2UniformConstCostTable[] = {
585 { ISD::SHL, MVT::v16i8, { 1, 7, 2, 3 } }, // psllw + pand.
586 { ISD::SRL, MVT::v16i8, { 1, 7, 2, 3 } }, // psrlw + pand.
587 { ISD::SRA, MVT::v16i8, { 3, 9, 5, 6 } }, // psrlw, pand, pxor, psubb.
588
589 { ISD::SHL, MVT::v8i16, { 1, 1, 1, 1 } }, // psllw.
590 { ISD::SRL, MVT::v8i16, { 1, 1, 1, 1 } }, // psrlw.
591 { ISD::SRA, MVT::v8i16, { 1, 1, 1, 1 } }, // psraw.
592
593 { ISD::SHL, MVT::v4i32, { 1, 1, 1, 1 } }, // pslld
594 { ISD::SRL, MVT::v4i32, { 1, 1, 1, 1 } }, // psrld.
595 { ISD::SRA, MVT::v4i32, { 1, 1, 1, 1 } }, // psrad.
596
597 { ISD::SHL, MVT::v2i64, { 1, 1, 1, 1 } }, // psllq.
598 { ISD::SRL, MVT::v2i64, { 1, 1, 1, 1 } }, // psrlq.
599 { ISD::SRA, MVT::v2i64, { 3, 5, 6, 6 } }, // 2 x psrad + shuffle.
600
601 { ISD::SDIV, MVT::v4i32, { 6 } }, // pmuludq sequence
602 { ISD::SREM, MVT::v4i32, { 8 } }, // pmuludq+mul+sub sequence
603 { ISD::UDIV, MVT::v4i32, { 5 } }, // pmuludq sequence
604 { ISD::UREM, MVT::v4i32, { 7 } }, // pmuludq+mul+sub sequence
605 };
606
607 // XOP has faster vXi8 shifts.
608 if (Op2Info.isUniform() && Op2Info.isConstant() && ST->hasSSE2() &&
609 (!ST->hasXOP() || LT.second.getScalarSizeInBits() != 8))
610 if (const auto *Entry =
611 CostTableLookup(SSE2UniformConstCostTable, ISD, LT.second))
612 if (auto KindCost = Entry->Cost[CostKind])
613 return LT.first * *KindCost;
614
615 static const CostKindTblEntry AVX512BWConstCostTable[] = {
616 { ISD::SDIV, MVT::v64i8, { 14 } }, // 2*ext+2*pmulhw sequence
617 { ISD::SREM, MVT::v64i8, { 16 } }, // 2*ext+2*pmulhw+mul+sub sequence
618 { ISD::UDIV, MVT::v64i8, { 14 } }, // 2*ext+2*pmulhw sequence
619 { ISD::UREM, MVT::v64i8, { 16 } }, // 2*ext+2*pmulhw+mul+sub sequence
620
621 { ISD::SDIV, MVT::v32i16, { 6 } }, // vpmulhw sequence
622 { ISD::SREM, MVT::v32i16, { 8 } }, // vpmulhw+mul+sub sequence
623 { ISD::UDIV, MVT::v32i16, { 6 } }, // vpmulhuw sequence
624 { ISD::UREM, MVT::v32i16, { 8 } }, // vpmulhuw+mul+sub sequence
625 };
626
627 if (Op2Info.isConstant() && ST->hasBWI())
628 if (const auto *Entry =
629 CostTableLookup(AVX512BWConstCostTable, ISD, LT.second))
630 if (auto KindCost = Entry->Cost[CostKind])
631 return LT.first * *KindCost;
632
633 static const CostKindTblEntry AVX512DQConstCostTable[] = {
634 { ISD::SDIV, MVT::v4i64, { 19 } }, // vpmullq-based MULHS sequence
635 { ISD::SREM, MVT::v4i64, { 21 } }, // vpmullq-based MULHS+mul+sub sequence
636 { ISD::SDIV, MVT::v8i64, { 19 } }, // vpmullq-based MULHS sequence
637 { ISD::SREM, MVT::v8i64, { 21 } }, // vpmullq-based MULHS+mul+sub sequence
638 // The remainder's multiply-back is a single vpmullq with DQ, whereas the
639 // AVX512/AVX2 tables have to charge for another vpmuludq schoolbook.
640 { ISD::UREM, MVT::v4i64, { 24 } }, // MULHU + vpmullq + sub sequence
641 { ISD::UREM, MVT::v8i64, { 24 } }, // MULHU + vpmullq + sub sequence
642 };
643
644 if (Op2Info.isConstant() && ST->hasDQI())
645 if (const auto *Entry =
646 CostTableLookup(AVX512DQConstCostTable, ISD, LT.second))
647 if (auto KindCost = Entry->Cost[CostKind])
648 return LT.first * *KindCost;
649
650 static const CostKindTblEntry AVX512ConstCostTable[] = {
651 { ISD::SDIV, MVT::v64i8, { 28 } }, // 4*ext+4*pmulhw sequence
652 { ISD::SREM, MVT::v64i8, { 32 } }, // 4*ext+4*pmulhw+mul+sub sequence
653 { ISD::UDIV, MVT::v64i8, { 28 } }, // 4*ext+4*pmulhw sequence
654 { ISD::UREM, MVT::v64i8, { 32 } }, // 4*ext+4*pmulhw+mul+sub sequence
655
656 { ISD::SDIV, MVT::v32i16, { 12 } }, // 2*vpmulhw sequence
657 { ISD::SREM, MVT::v32i16, { 16 } }, // 2*vpmulhw+mul+sub sequence
658 { ISD::UDIV, MVT::v32i16, { 12 } }, // 2*vpmulhuw sequence
659 { ISD::UREM, MVT::v32i16, { 16 } }, // 2*vpmulhuw+mul+sub sequence
660
661 { ISD::SDIV, MVT::v16i32, { 15 } }, // vpmuldq sequence
662 { ISD::SREM, MVT::v16i32, { 17 } }, // vpmuldq+mul+sub sequence
663 { ISD::UDIV, MVT::v16i32, { 15 } }, // vpmuludq sequence
664 { ISD::UREM, MVT::v16i32, { 17 } }, // vpmuludq+mul+sub sequence
665
666 { ISD::UDIV, MVT::v8i64, { 22 } }, // vpmuludq-based MULHU sequence
667 { ISD::UREM, MVT::v8i64, { 28 } }, // vpmuludq-based MULHU+mul+sub sequence
668 };
669
670 if (Op2Info.isConstant() && ST->hasAVX512())
671 if (const auto *Entry =
672 CostTableLookup(AVX512ConstCostTable, ISD, LT.second))
673 if (auto KindCost = Entry->Cost[CostKind])
674 return LT.first * *KindCost;
675
676 static const CostKindTblEntry AVX2ConstCostTable[] = {
677 { ISD::SDIV, MVT::v32i8, { 14 } }, // 2*ext+2*pmulhw sequence
678 { ISD::SREM, MVT::v32i8, { 16 } }, // 2*ext+2*pmulhw+mul+sub sequence
679 { ISD::UDIV, MVT::v32i8, { 14 } }, // 2*ext+2*pmulhw sequence
680 { ISD::UREM, MVT::v32i8, { 16 } }, // 2*ext+2*pmulhw+mul+sub sequence
681
682 { ISD::SDIV, MVT::v16i16, { 6 } }, // vpmulhw sequence
683 { ISD::SREM, MVT::v16i16, { 8 } }, // vpmulhw+mul+sub sequence
684 { ISD::UDIV, MVT::v16i16, { 6 } }, // vpmulhuw sequence
685 { ISD::UREM, MVT::v16i16, { 8 } }, // vpmulhuw+mul+sub sequence
686
687 { ISD::SDIV, MVT::v8i32, { 15 } }, // vpmuldq sequence
688 { ISD::SREM, MVT::v8i32, { 19 } }, // vpmuldq+mul+sub sequence
689 { ISD::UDIV, MVT::v8i32, { 15 } }, // vpmuludq sequence
690 { ISD::UREM, MVT::v8i32, { 19 } }, // vpmuludq+mul+sub sequence
691
692 { ISD::UDIV, MVT::v4i64, { 22 } }, // vpmuludq-based MULHU sequence
693 { ISD::UREM, MVT::v4i64, { 28 } }, // vpmuludq-based MULHU+mul+sub sequence
694 };
695
696 if (Op2Info.isConstant() && ST->hasAVX2())
697 if (const auto *Entry = CostTableLookup(AVX2ConstCostTable, ISD, LT.second))
698 if (auto KindCost = Entry->Cost[CostKind])
699 return LT.first * *KindCost;
700
701 static const CostKindTblEntry AVXConstCostTable[] = {
702 { ISD::SDIV, MVT::v32i8, { 30 } }, // 4*ext+4*pmulhw sequence + split.
703 { ISD::SREM, MVT::v32i8, { 34 } }, // 4*ext+4*pmulhw+mul+sub sequence + split.
704 { ISD::UDIV, MVT::v32i8, { 30 } }, // 4*ext+4*pmulhw sequence + split.
705 { ISD::UREM, MVT::v32i8, { 34 } }, // 4*ext+4*pmulhw+mul+sub sequence + split.
706
707 { ISD::SDIV, MVT::v16i16, { 14 } }, // 2*pmulhw sequence + split.
708 { ISD::SREM, MVT::v16i16, { 18 } }, // 2*pmulhw+mul+sub sequence + split.
709 { ISD::UDIV, MVT::v16i16, { 14 } }, // 2*pmulhuw sequence + split.
710 { ISD::UREM, MVT::v16i16, { 18 } }, // 2*pmulhuw+mul+sub sequence + split.
711
712 { ISD::SDIV, MVT::v8i32, { 32 } }, // vpmuludq sequence
713 { ISD::SREM, MVT::v8i32, { 38 } }, // vpmuludq+mul+sub sequence
714 { ISD::UDIV, MVT::v8i32, { 32 } }, // 2*pmuludq sequence + split.
715 { ISD::UREM, MVT::v8i32, { 42 } }, // 2*pmuludq+mul+sub sequence + split.
716 };
717
718 if (Op2Info.isConstant() && ST->hasAVX())
719 if (const auto *Entry = CostTableLookup(AVXConstCostTable, ISD, LT.second))
720 if (auto KindCost = Entry->Cost[CostKind])
721 return LT.first * *KindCost;
722
723 static const CostKindTblEntry SSE41ConstCostTable[] = {
724 { ISD::SDIV, MVT::v4i32, { 15 } }, // vpmuludq sequence
725 { ISD::SREM, MVT::v4i32, { 20 } }, // vpmuludq+mul+sub sequence
726 };
727
728 if (Op2Info.isConstant() && ST->hasSSE41())
729 if (const auto *Entry =
730 CostTableLookup(SSE41ConstCostTable, ISD, LT.second))
731 if (auto KindCost = Entry->Cost[CostKind])
732 return LT.first * *KindCost;
733
734 static const CostKindTblEntry SSE2ConstCostTable[] = {
735 { ISD::SDIV, MVT::v16i8, { 14 } }, // 2*ext+2*pmulhw sequence
736 { ISD::SREM, MVT::v16i8, { 16 } }, // 2*ext+2*pmulhw+mul+sub sequence
737 { ISD::UDIV, MVT::v16i8, { 14 } }, // 2*ext+2*pmulhw sequence
738 { ISD::UREM, MVT::v16i8, { 16 } }, // 2*ext+2*pmulhw+mul+sub sequence
739
740 { ISD::SDIV, MVT::v8i16, { 6 } }, // pmulhw sequence
741 { ISD::SREM, MVT::v8i16, { 8 } }, // pmulhw+mul+sub sequence
742 { ISD::UDIV, MVT::v8i16, { 6 } }, // pmulhuw sequence
743 { ISD::UREM, MVT::v8i16, { 8 } }, // pmulhuw+mul+sub sequence
744
745 { ISD::SDIV, MVT::v4i32, { 19 } }, // pmuludq sequence
746 { ISD::SREM, MVT::v4i32, { 24 } }, // pmuludq+mul+sub sequence
747 { ISD::UDIV, MVT::v4i32, { 15 } }, // pmuludq sequence
748 { ISD::UREM, MVT::v4i32, { 20 } }, // pmuludq+mul+sub sequence
749 };
750
751 if (Op2Info.isConstant() && ST->hasSSE2())
752 if (const auto *Entry = CostTableLookup(SSE2ConstCostTable, ISD, LT.second))
753 if (auto KindCost = Entry->Cost[CostKind])
754 return LT.first * *KindCost;
755
756 static const CostKindTblEntry AVX512BWUniformCostTable[] = {
757 { ISD::SHL, MVT::v16i8, { 3, 5, 5, 7 } }, // psllw + pand.
758 { ISD::SRL, MVT::v16i8, { 3,10, 5, 8 } }, // psrlw + pand.
759 { ISD::SRA, MVT::v16i8, { 4,12, 8,12 } }, // psrlw, pand, pxor, psubb.
760 { ISD::SHL, MVT::v32i8, { 4, 7, 6, 8 } }, // psllw + pand.
761 { ISD::SRL, MVT::v32i8, { 4, 8, 7, 9 } }, // psrlw + pand.
762 { ISD::SRA, MVT::v32i8, { 5,10,10,13 } }, // psrlw, pand, pxor, psubb.
763 { ISD::SHL, MVT::v64i8, { 4, 7, 6, 8 } }, // psllw + pand.
764 { ISD::SRL, MVT::v64i8, { 4, 8, 7,10 } }, // psrlw + pand.
765 { ISD::SRA, MVT::v64i8, { 5,10,10,15 } }, // psrlw, pand, pxor, psubb.
766
767 { ISD::SHL, MVT::v32i16, { 2, 4, 2, 3 } }, // psllw
768 { ISD::SRL, MVT::v32i16, { 2, 4, 2, 3 } }, // psrlw
769 { ISD::SRA, MVT::v32i16, { 2, 4, 2, 3 } }, // psrqw
770 };
771
772 if (ST->hasBWI() && Op2Info.isUniform())
773 if (const auto *Entry =
774 CostTableLookup(AVX512BWUniformCostTable, ISD, LT.second))
775 if (auto KindCost = Entry->Cost[CostKind])
776 return LT.first * *KindCost;
777
778 static const CostKindTblEntry AVX512UniformCostTable[] = {
779 { ISD::SHL, MVT::v32i16, { 5,10, 5, 7 } }, // psllw + split.
780 { ISD::SRL, MVT::v32i16, { 5,10, 5, 7 } }, // psrlw + split.
781 { ISD::SRA, MVT::v32i16, { 5,10, 5, 7 } }, // psraw + split.
782
783 { ISD::SHL, MVT::v16i32, { 2, 4, 2, 3 } }, // pslld
784 { ISD::SRL, MVT::v16i32, { 2, 4, 2, 3 } }, // psrld
785 { ISD::SRA, MVT::v16i32, { 2, 4, 2, 3 } }, // psrad
786
787 { ISD::SRA, MVT::v2i64, { 1, 2, 1, 2 } }, // psraq
788 { ISD::SHL, MVT::v4i64, { 1, 4, 1, 2 } }, // psllq
789 { ISD::SRL, MVT::v4i64, { 1, 4, 1, 2 } }, // psrlq
790 { ISD::SRA, MVT::v4i64, { 1, 4, 1, 2 } }, // psraq
791 { ISD::SHL, MVT::v8i64, { 1, 4, 1, 2 } }, // psllq
792 { ISD::SRL, MVT::v8i64, { 1, 4, 1, 2 } }, // psrlq
793 { ISD::SRA, MVT::v8i64, { 1, 4, 1, 2 } }, // psraq
794 };
795
796 if (ST->hasAVX512() && Op2Info.isUniform())
797 if (const auto *Entry =
798 CostTableLookup(AVX512UniformCostTable, ISD, LT.second))
799 if (auto KindCost = Entry->Cost[CostKind])
800 return LT.first * *KindCost;
801
802 static const CostKindTblEntry AVX2UniformCostTable[] = {
803 // Uniform splats are cheaper for the following instructions.
804 { ISD::SHL, MVT::v16i8, { 3, 5, 5, 7 } }, // psllw + pand.
805 { ISD::SRL, MVT::v16i8, { 3, 9, 5, 8 } }, // psrlw + pand.
806 { ISD::SRA, MVT::v16i8, { 4, 5, 9,13 } }, // psrlw, pand, pxor, psubb.
807 { ISD::SHL, MVT::v32i8, { 4, 7, 6, 8 } }, // psllw + pand.
808 { ISD::SRL, MVT::v32i8, { 4, 8, 7, 9 } }, // psrlw + pand.
809 { ISD::SRA, MVT::v32i8, { 6, 9,11,16 } }, // psrlw, pand, pxor, psubb.
810
811 { ISD::SHL, MVT::v8i16, { 1, 2, 1, 2 } }, // psllw.
812 { ISD::SRL, MVT::v8i16, { 1, 2, 1, 2 } }, // psrlw.
813 { ISD::SRA, MVT::v8i16, { 1, 2, 1, 2 } }, // psraw.
814 { ISD::SHL, MVT::v16i16, { 2, 4, 2, 3 } }, // psllw.
815 { ISD::SRL, MVT::v16i16, { 2, 4, 2, 3 } }, // psrlw.
816 { ISD::SRA, MVT::v16i16, { 2, 4, 2, 3 } }, // psraw.
817
818 { ISD::SHL, MVT::v4i32, { 1, 2, 1, 2 } }, // pslld
819 { ISD::SRL, MVT::v4i32, { 1, 2, 1, 2 } }, // psrld
820 { ISD::SRA, MVT::v4i32, { 1, 2, 1, 2 } }, // psrad
821 { ISD::SHL, MVT::v8i32, { 2, 4, 2, 3 } }, // pslld
822 { ISD::SRL, MVT::v8i32, { 2, 4, 2, 3 } }, // psrld
823 { ISD::SRA, MVT::v8i32, { 2, 4, 2, 3 } }, // psrad
824
825 { ISD::SHL, MVT::v2i64, { 1, 2, 1, 2 } }, // psllq
826 { ISD::SRL, MVT::v2i64, { 1, 2, 1, 2 } }, // psrlq
827 { ISD::SRA, MVT::v2i64, { 2, 4, 5, 7 } }, // 2 x psrad + shuffle.
828 { ISD::SHL, MVT::v4i64, { 2, 4, 1, 2 } }, // psllq
829 { ISD::SRL, MVT::v4i64, { 2, 4, 1, 2 } }, // psrlq
830 { ISD::SRA, MVT::v4i64, { 4, 6, 5, 9 } }, // 2 x psrad + shuffle.
831 };
832
833 if (ST->hasAVX2() && Op2Info.isUniform())
834 if (const auto *Entry =
835 CostTableLookup(AVX2UniformCostTable, ISD, LT.second))
836 if (auto KindCost = Entry->Cost[CostKind])
837 return LT.first * *KindCost;
838
839 static const CostKindTblEntry AVXUniformCostTable[] = {
840 { ISD::SHL, MVT::v16i8, { 4, 4, 6, 8 } }, // psllw + pand.
841 { ISD::SRL, MVT::v16i8, { 4, 8, 5, 8 } }, // psrlw + pand.
842 { ISD::SRA, MVT::v16i8, { 6, 6, 9,13 } }, // psrlw, pand, pxor, psubb.
843 { ISD::SHL, MVT::v32i8, { 7, 8,11,14 } }, // psllw + pand + split.
844 { ISD::SRL, MVT::v32i8, { 7, 9,10,14 } }, // psrlw + pand + split.
845 { ISD::SRA, MVT::v32i8, { 10,11,16,21 } }, // psrlw, pand, pxor, psubb + split.
846
847 { ISD::SHL, MVT::v8i16, { 1, 3, 1, 2 } }, // psllw.
848 { ISD::SRL, MVT::v8i16, { 1, 3, 1, 2 } }, // psrlw.
849 { ISD::SRA, MVT::v8i16, { 1, 3, 1, 2 } }, // psraw.
850 { ISD::SHL, MVT::v16i16, { 3, 7, 5, 7 } }, // psllw + split.
851 { ISD::SRL, MVT::v16i16, { 3, 7, 5, 7 } }, // psrlw + split.
852 { ISD::SRA, MVT::v16i16, { 3, 7, 5, 7 } }, // psraw + split.
853
854 { ISD::SHL, MVT::v4i32, { 1, 3, 1, 2 } }, // pslld.
855 { ISD::SRL, MVT::v4i32, { 1, 3, 1, 2 } }, // psrld.
856 { ISD::SRA, MVT::v4i32, { 1, 3, 1, 2 } }, // psrad.
857 { ISD::SHL, MVT::v8i32, { 3, 7, 5, 7 } }, // pslld + split.
858 { ISD::SRL, MVT::v8i32, { 3, 7, 5, 7 } }, // psrld + split.
859 { ISD::SRA, MVT::v8i32, { 3, 7, 5, 7 } }, // psrad + split.
860
861 { ISD::SHL, MVT::v2i64, { 1, 3, 1, 2 } }, // psllq.
862 { ISD::SRL, MVT::v2i64, { 1, 3, 1, 2 } }, // psrlq.
863 { ISD::SRA, MVT::v2i64, { 3, 4, 5, 7 } }, // 2 x psrad + shuffle.
864 { ISD::SHL, MVT::v4i64, { 3, 7, 4, 6 } }, // psllq + split.
865 { ISD::SRL, MVT::v4i64, { 3, 7, 4, 6 } }, // psrlq + split.
866 { ISD::SRA, MVT::v4i64, { 6, 7,10,13 } }, // 2 x (2 x psrad + shuffle) + split.
867 };
868
869 // XOP has faster vXi8 shifts.
870 if (ST->hasAVX() && Op2Info.isUniform() &&
871 (!ST->hasXOP() || LT.second.getScalarSizeInBits() != 8))
872 if (const auto *Entry =
873 CostTableLookup(AVXUniformCostTable, ISD, LT.second))
874 if (auto KindCost = Entry->Cost[CostKind])
875 return LT.first * *KindCost;
876
877 static const CostKindTblEntry SSE2UniformCostTable[] = {
878 // Uniform splats are cheaper for the following instructions.
879 { ISD::SHL, MVT::v16i8, { 9, 10, 6, 9 } }, // psllw + pand.
880 { ISD::SRL, MVT::v16i8, { 9, 13, 5, 9 } }, // psrlw + pand.
881 { ISD::SRA, MVT::v16i8, { 11, 15, 9,13 } }, // pcmpgtb sequence.
882
883 { ISD::SHL, MVT::v8i16, { 2, 2, 1, 2 } }, // psllw.
884 { ISD::SRL, MVT::v8i16, { 2, 2, 1, 2 } }, // psrlw.
885 { ISD::SRA, MVT::v8i16, { 2, 2, 1, 2 } }, // psraw.
886
887 { ISD::SHL, MVT::v4i32, { 2, 2, 1, 2 } }, // pslld
888 { ISD::SRL, MVT::v4i32, { 2, 2, 1, 2 } }, // psrld.
889 { ISD::SRA, MVT::v4i32, { 2, 2, 1, 2 } }, // psrad.
890
891 { ISD::SHL, MVT::v2i64, { 2, 2, 1, 2 } }, // psllq.
892 { ISD::SRL, MVT::v2i64, { 2, 2, 1, 2 } }, // psrlq.
893 { ISD::SRA, MVT::v2i64, { 5, 9, 5, 7 } }, // 2*psrlq + xor + sub.
894 };
895
896 if (ST->hasSSE2() && Op2Info.isUniform() &&
897 (!ST->hasXOP() || LT.second.getScalarSizeInBits() != 8))
898 if (const auto *Entry =
899 CostTableLookup(SSE2UniformCostTable, ISD, LT.second))
900 if (auto KindCost = Entry->Cost[CostKind])
901 return LT.first * *KindCost;
902
903 static const CostKindTblEntry AVX512DQCostTable[] = {
904 { ISD::MUL, MVT::v2i64, { 2, 15, 1, 3 } }, // pmullq
905 { ISD::MUL, MVT::v4i64, { 2, 15, 1, 3 } }, // pmullq
906 { ISD::MUL, MVT::v8i64, { 3, 15, 1, 3 } } // pmullq
907 };
908
909 // Look for AVX512DQ lowering tricks for custom cases.
910 if (ST->hasDQI())
911 if (const auto *Entry = CostTableLookup(AVX512DQCostTable, ISD, LT.second))
912 if (auto KindCost = Entry->Cost[CostKind])
913 return LT.first * *KindCost;
914
915 static const CostKindTblEntry AVX512BWCostTable[] = {
916 { ISD::SHL, MVT::v16i8, { 4, 8, 4, 5 } }, // extend/vpsllvw/pack sequence.
917 { ISD::SRL, MVT::v16i8, { 4, 8, 4, 5 } }, // extend/vpsrlvw/pack sequence.
918 { ISD::SRA, MVT::v16i8, { 4, 8, 4, 5 } }, // extend/vpsravw/pack sequence.
919 { ISD::SHL, MVT::v32i8, { 4, 23,11,16 } }, // extend/vpsllvw/pack sequence.
920 { ISD::SRL, MVT::v32i8, { 4, 30,12,18 } }, // extend/vpsrlvw/pack sequence.
921 { ISD::SRA, MVT::v32i8, { 6, 13,24,30 } }, // extend/vpsravw/pack sequence.
922 { ISD::SHL, MVT::v64i8, { 6, 19,13,15 } }, // extend/vpsllvw/pack sequence.
923 { ISD::SRL, MVT::v64i8, { 7, 27,15,18 } }, // extend/vpsrlvw/pack sequence.
924 { ISD::SRA, MVT::v64i8, { 15, 15,30,30 } }, // extend/vpsravw/pack sequence.
925
926 { ISD::SHL, MVT::v8i16, { 1, 1, 1, 1 } }, // vpsllvw
927 { ISD::SRL, MVT::v8i16, { 1, 1, 1, 1 } }, // vpsrlvw
928 { ISD::SRA, MVT::v8i16, { 1, 1, 1, 1 } }, // vpsravw
929 { ISD::SHL, MVT::v16i16, { 1, 1, 1, 1 } }, // vpsllvw
930 { ISD::SRL, MVT::v16i16, { 1, 1, 1, 1 } }, // vpsrlvw
931 { ISD::SRA, MVT::v16i16, { 1, 1, 1, 1 } }, // vpsravw
932 { ISD::SHL, MVT::v32i16, { 1, 1, 1, 1 } }, // vpsllvw
933 { ISD::SRL, MVT::v32i16, { 1, 1, 1, 1 } }, // vpsrlvw
934 { ISD::SRA, MVT::v32i16, { 1, 1, 1, 1 } }, // vpsravw
935
936 { ISD::ADD, MVT::v64i8, { 1, 1, 1, 1 } }, // paddb
937 { ISD::ADD, MVT::v32i16, { 1, 1, 1, 1 } }, // paddw
938
939 { ISD::ADD, MVT::v32i8, { 1, 1, 1, 1 } }, // paddb
940 { ISD::ADD, MVT::v16i16, { 1, 1, 1, 1 } }, // paddw
941 { ISD::ADD, MVT::v8i32, { 1, 1, 1, 1 } }, // paddd
942 { ISD::ADD, MVT::v4i64, { 1, 1, 1, 1 } }, // paddq
943
944 { ISD::SUB, MVT::v64i8, { 1, 1, 1, 1 } }, // psubb
945 { ISD::SUB, MVT::v32i16, { 1, 1, 1, 1 } }, // psubw
946
947 { ISD::MUL, MVT::v16i8, { 4, 12, 4, 5 } }, // extend/pmullw/trunc
948 { ISD::MUL, MVT::v32i8, { 3, 10, 7,10 } }, // pmaddubsw
949 { ISD::MUL, MVT::v64i8, { 3, 11, 7,10 } }, // pmaddubsw
950 { ISD::MUL, MVT::v32i16, { 1, 5, 1, 1 } }, // pmullw
951
952 { ISD::SUB, MVT::v32i8, { 1, 1, 1, 1 } }, // psubb
953 { ISD::SUB, MVT::v16i16, { 1, 1, 1, 1 } }, // psubw
954 { ISD::SUB, MVT::v8i32, { 1, 1, 1, 1 } }, // psubd
955 { ISD::SUB, MVT::v4i64, { 1, 1, 1, 1 } }, // psubq
956 };
957
958 // Look for AVX512BW lowering tricks for custom cases.
959 if (ST->hasBWI())
960 if (const auto *Entry = CostTableLookup(AVX512BWCostTable, ISD, LT.second))
961 if (auto KindCost = Entry->Cost[CostKind])
962 return LT.first * *KindCost;
963
964 static const CostKindTblEntry AVX512CostTable[] = {
965 { ISD::SHL, MVT::v64i8, { 15, 19,27,33 } }, // vpblendv+split sequence.
966 { ISD::SRL, MVT::v64i8, { 15, 19,30,36 } }, // vpblendv+split sequence.
967 { ISD::SRA, MVT::v64i8, { 37, 37,51,63 } }, // vpblendv+split sequence.
968
969 { ISD::SHL, MVT::v32i16, { 11, 16,11,15 } }, // 2*extend/vpsrlvd/pack sequence.
970 { ISD::SRL, MVT::v32i16, { 11, 16,11,15 } }, // 2*extend/vpsrlvd/pack sequence.
971 { ISD::SRA, MVT::v32i16, { 11, 16,11,15 } }, // 2*extend/vpsravd/pack sequence.
972
973 { ISD::SHL, MVT::v4i32, { 1, 1, 1, 1 } },
974 { ISD::SRL, MVT::v4i32, { 1, 1, 1, 1 } },
975 { ISD::SRA, MVT::v4i32, { 1, 1, 1, 1 } },
976 { ISD::SHL, MVT::v8i32, { 1, 1, 1, 1 } },
977 { ISD::SRL, MVT::v8i32, { 1, 1, 1, 1 } },
978 { ISD::SRA, MVT::v8i32, { 1, 1, 1, 1 } },
979 { ISD::SHL, MVT::v16i32, { 1, 1, 1, 1 } },
980 { ISD::SRL, MVT::v16i32, { 1, 1, 1, 1 } },
981 { ISD::SRA, MVT::v16i32, { 1, 1, 1, 1 } },
982
983 { ISD::SHL, MVT::v2i64, { 1, 1, 1, 1 } },
984 { ISD::SRL, MVT::v2i64, { 1, 1, 1, 1 } },
985 { ISD::SRA, MVT::v2i64, { 1, 1, 1, 1 } },
986 { ISD::SHL, MVT::v4i64, { 1, 1, 1, 1 } },
987 { ISD::SRL, MVT::v4i64, { 1, 1, 1, 1 } },
988 { ISD::SRA, MVT::v4i64, { 1, 1, 1, 1 } },
989 { ISD::SHL, MVT::v8i64, { 1, 1, 1, 1 } },
990 { ISD::SRL, MVT::v8i64, { 1, 1, 1, 1 } },
991 { ISD::SRA, MVT::v8i64, { 1, 1, 1, 1 } },
992
993 { ISD::ADD, MVT::v64i8, { 3, 7, 5, 5 } }, // 2*paddb + split
994 { ISD::ADD, MVT::v32i16, { 3, 7, 5, 5 } }, // 2*paddw + split
995
996 { ISD::SUB, MVT::v64i8, { 3, 7, 5, 5 } }, // 2*psubb + split
997 { ISD::SUB, MVT::v32i16, { 3, 7, 5, 5 } }, // 2*psubw + split
998
999 { ISD::AND, MVT::v32i8, { 1, 1, 1, 1 } },
1000 { ISD::AND, MVT::v16i16, { 1, 1, 1, 1 } },
1001 { ISD::AND, MVT::v8i32, { 1, 1, 1, 1 } },
1002 { ISD::AND, MVT::v4i64, { 1, 1, 1, 1 } },
1003
1004 { ISD::OR, MVT::v32i8, { 1, 1, 1, 1 } },
1005 { ISD::OR, MVT::v16i16, { 1, 1, 1, 1 } },
1006 { ISD::OR, MVT::v8i32, { 1, 1, 1, 1 } },
1007 { ISD::OR, MVT::v4i64, { 1, 1, 1, 1 } },
1008
1009 { ISD::XOR, MVT::v32i8, { 1, 1, 1, 1 } },
1010 { ISD::XOR, MVT::v16i16, { 1, 1, 1, 1 } },
1011 { ISD::XOR, MVT::v8i32, { 1, 1, 1, 1 } },
1012 { ISD::XOR, MVT::v4i64, { 1, 1, 1, 1 } },
1013
1014 { ISD::MUL, MVT::v16i32, { 1, 10, 1, 2 } }, // pmulld (Skylake from agner.org)
1015 { ISD::MUL, MVT::v8i32, { 1, 10, 1, 2 } }, // pmulld (Skylake from agner.org)
1016 { ISD::MUL, MVT::v4i32, { 1, 10, 1, 2 } }, // pmulld (Skylake from agner.org)
1017 { ISD::MUL, MVT::v8i64, { 6, 9, 8, 8 } }, // 3*pmuludq/3*shift/2*add
1018 { ISD::MUL, MVT::i64, { 1 } }, // Skylake from http://www.agner.org/
1019
1020 { X86ISD::PMULUDQ, MVT::v8i64, { 1, 5, 1, 1 } },
1021
1022 { ISD::FNEG, MVT::v8f64, { 1, 1, 1, 2 } }, // Skylake from http://www.agner.org/
1023 { ISD::FADD, MVT::v8f64, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1024 { ISD::FADD, MVT::v4f64, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1025 { ISD::FSUB, MVT::v8f64, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1026 { ISD::FSUB, MVT::v4f64, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1027 { ISD::FMUL, MVT::v8f64, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1028 { ISD::FMUL, MVT::v4f64, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1029 { ISD::FMUL, MVT::v2f64, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1030 { ISD::FMUL, MVT::f64, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1031
1032 { ISD::FDIV, MVT::f64, { 4, 14, 1, 1 } }, // Skylake from http://www.agner.org/
1033 { ISD::FDIV, MVT::v2f64, { 4, 14, 1, 1 } }, // Skylake from http://www.agner.org/
1034 { ISD::FDIV, MVT::v4f64, { 8, 14, 1, 1 } }, // Skylake from http://www.agner.org/
1035 { ISD::FDIV, MVT::v8f64, { 16, 23, 1, 3 } }, // Skylake from http://www.agner.org/
1036
1037 { ISD::FNEG, MVT::v16f32, { 1, 1, 1, 2 } }, // Skylake from http://www.agner.org/
1038 { ISD::FADD, MVT::v16f32, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1039 { ISD::FADD, MVT::v8f32, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1040 { ISD::FSUB, MVT::v16f32, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1041 { ISD::FSUB, MVT::v8f32, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1042 { ISD::FMUL, MVT::v16f32, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1043 { ISD::FMUL, MVT::v8f32, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1044 { ISD::FMUL, MVT::v4f32, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1045 { ISD::FMUL, MVT::f32, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1046
1047 { ISD::FDIV, MVT::f32, { 3, 11, 1, 1 } }, // Skylake from http://www.agner.org/
1048 { ISD::FDIV, MVT::v4f32, { 3, 11, 1, 1 } }, // Skylake from http://www.agner.org/
1049 { ISD::FDIV, MVT::v8f32, { 5, 11, 1, 1 } }, // Skylake from http://www.agner.org/
1050 { ISD::FDIV, MVT::v16f32, { 10, 18, 1, 3 } }, // Skylake from http://www.agner.org/
1051 };
1052
1053 if (ST->hasAVX512())
1054 if (const auto *Entry = CostTableLookup(AVX512CostTable, ISD, LT.second))
1055 if (auto KindCost = Entry->Cost[CostKind])
1056 return LT.first * *KindCost;
1057
1058 static const CostKindTblEntry AVX2ShiftCostTable[] = {
1059 // Shifts on vXi64/vXi32 on AVX2 is legal even though we declare to
1060 // customize them to detect the cases where shift amount is a scalar one.
1061 { ISD::SHL, MVT::v4i32, { 2, 3, 1, 3 } }, // vpsllvd (Haswell from agner.org)
1062 { ISD::SRL, MVT::v4i32, { 2, 3, 1, 3 } }, // vpsrlvd (Haswell from agner.org)
1063 { ISD::SRA, MVT::v4i32, { 2, 3, 1, 3 } }, // vpsravd (Haswell from agner.org)
1064 { ISD::SHL, MVT::v8i32, { 4, 4, 1, 3 } }, // vpsllvd (Haswell from agner.org)
1065 { ISD::SRL, MVT::v8i32, { 4, 4, 1, 3 } }, // vpsrlvd (Haswell from agner.org)
1066 { ISD::SRA, MVT::v8i32, { 4, 4, 1, 3 } }, // vpsravd (Haswell from agner.org)
1067 { ISD::SHL, MVT::v2i64, { 2, 3, 1, 1 } }, // vpsllvq (Haswell from agner.org)
1068 { ISD::SRL, MVT::v2i64, { 2, 3, 1, 1 } }, // vpsrlvq (Haswell from agner.org)
1069 { ISD::SHL, MVT::v4i64, { 4, 4, 1, 2 } }, // vpsllvq (Haswell from agner.org)
1070 { ISD::SRL, MVT::v4i64, { 4, 4, 1, 2 } }, // vpsrlvq (Haswell from agner.org)
1071 };
1072
1073 if (ST->hasAVX512()) {
1074 if (ISD == ISD::SHL && LT.second == MVT::v32i16 && Op2Info.isConstant())
1075 // On AVX512, a packed v32i16 shift left by a constant build_vector
1076 // is lowered into a vector multiply (vpmullw).
1077 return getArithmeticInstrCost(Instruction::Mul, Ty, CostKind,
1078 Op1Info.getNoProps(), Op2Info.getNoProps());
1079 }
1080
1081 // Look for AVX2 lowering tricks (XOP is always better at v4i32 shifts).
1082 if (ST->hasAVX2() && !(ST->hasXOP() && LT.second == MVT::v4i32)) {
1083 if (ISD == ISD::SHL && LT.second == MVT::v16i16 &&
1084 Op2Info.isConstant())
1085 // On AVX2, a packed v16i16 shift left by a constant build_vector
1086 // is lowered into a vector multiply (vpmullw).
1087 return getArithmeticInstrCost(Instruction::Mul, Ty, CostKind,
1088 Op1Info.getNoProps(), Op2Info.getNoProps());
1089
1090 if (const auto *Entry = CostTableLookup(AVX2ShiftCostTable, ISD, LT.second))
1091 if (auto KindCost = Entry->Cost[CostKind])
1092 return LT.first * *KindCost;
1093 }
1094
1095 static const CostKindTblEntry XOPShiftCostTable[] = {
1096 // 128bit shifts take 1cy, but right shifts require negation beforehand.
1097 { ISD::SHL, MVT::v16i8, { 1, 3, 1, 1 } },
1098 { ISD::SRL, MVT::v16i8, { 2, 3, 1, 1 } },
1099 { ISD::SRA, MVT::v16i8, { 2, 3, 1, 1 } },
1100 { ISD::SHL, MVT::v8i16, { 1, 3, 1, 1 } },
1101 { ISD::SRL, MVT::v8i16, { 2, 3, 1, 1 } },
1102 { ISD::SRA, MVT::v8i16, { 2, 3, 1, 1 } },
1103 { ISD::SHL, MVT::v4i32, { 1, 3, 1, 1 } },
1104 { ISD::SRL, MVT::v4i32, { 2, 3, 1, 1 } },
1105 { ISD::SRA, MVT::v4i32, { 2, 3, 1, 1 } },
1106 { ISD::SHL, MVT::v2i64, { 1, 3, 1, 1 } },
1107 { ISD::SRL, MVT::v2i64, { 2, 3, 1, 1 } },
1108 { ISD::SRA, MVT::v2i64, { 2, 3, 1, 1 } },
1109 // 256bit shifts require splitting if AVX2 didn't catch them above.
1110 { ISD::SHL, MVT::v32i8, { 4, 7, 5, 6 } },
1111 { ISD::SRL, MVT::v32i8, { 6, 7, 5, 6 } },
1112 { ISD::SRA, MVT::v32i8, { 6, 7, 5, 6 } },
1113 { ISD::SHL, MVT::v16i16, { 4, 7, 5, 6 } },
1114 { ISD::SRL, MVT::v16i16, { 6, 7, 5, 6 } },
1115 { ISD::SRA, MVT::v16i16, { 6, 7, 5, 6 } },
1116 { ISD::SHL, MVT::v8i32, { 4, 7, 5, 6 } },
1117 { ISD::SRL, MVT::v8i32, { 6, 7, 5, 6 } },
1118 { ISD::SRA, MVT::v8i32, { 6, 7, 5, 6 } },
1119 { ISD::SHL, MVT::v4i64, { 4, 7, 5, 6 } },
1120 { ISD::SRL, MVT::v4i64, { 6, 7, 5, 6 } },
1121 { ISD::SRA, MVT::v4i64, { 6, 7, 5, 6 } },
1122 };
1123
1124 // Look for XOP lowering tricks.
1125 if (ST->hasXOP()) {
1126 // If the right shift is constant then we'll fold the negation so
1127 // it's as cheap as a left shift.
1128 int ShiftISD = ISD;
1129 if ((ShiftISD == ISD::SRL || ShiftISD == ISD::SRA) && Op2Info.isConstant())
1130 ShiftISD = ISD::SHL;
1131 if (const auto *Entry =
1132 CostTableLookup(XOPShiftCostTable, ShiftISD, LT.second))
1133 if (auto KindCost = Entry->Cost[CostKind])
1134 return LT.first * *KindCost;
1135 }
1136
1137 if (ISD == ISD::SHL && !Op2Info.isUniform() && Op2Info.isConstant()) {
1138 MVT VT = LT.second;
1139 // Vector shift left by non uniform constant can be lowered
1140 // into vector multiply.
1141 if (((VT == MVT::v8i16 || VT == MVT::v4i32) && ST->hasSSE2()) ||
1142 ((VT == MVT::v16i16 || VT == MVT::v8i32) && ST->hasAVX()))
1143 ISD = ISD::MUL;
1144 }
1145
1146 static const CostKindTblEntry GLMCostTable[] = {
1147 { ISD::FDIV, MVT::f32, { 18, 19, 1, 1 } }, // divss
1148 { ISD::FDIV, MVT::v4f32, { 35, 36, 1, 1 } }, // divps
1149 { ISD::FDIV, MVT::f64, { 33, 34, 1, 1 } }, // divsd
1150 { ISD::FDIV, MVT::v2f64, { 65, 66, 1, 1 } }, // divpd
1151 };
1152
1153 if (ST->useGLMDivSqrtCosts())
1154 if (const auto *Entry = CostTableLookup(GLMCostTable, ISD, LT.second))
1155 if (auto KindCost = Entry->Cost[CostKind])
1156 return LT.first * *KindCost;
1157
1158 static const CostKindTblEntry SLMCostTable[] = {
1159 { ISD::MUL, MVT::v4i32, { 11, 11, 1, 7 } }, // pmulld
1160 { ISD::MUL, MVT::v8i16, { 2, 5, 1, 1 } }, // pmullw
1161 { ISD::FMUL, MVT::f64, { 2, 5, 1, 1 } }, // mulsd
1162 { ISD::FMUL, MVT::f32, { 1, 4, 1, 1 } }, // mulss
1163 { ISD::FMUL, MVT::v2f64, { 4, 7, 1, 1 } }, // mulpd
1164 { ISD::FMUL, MVT::v4f32, { 2, 5, 1, 1 } }, // mulps
1165 { ISD::FDIV, MVT::f32, { 17, 19, 1, 1 } }, // divss
1166 { ISD::FDIV, MVT::v4f32, { 39, 39, 1, 6 } }, // divps
1167 { ISD::FDIV, MVT::f64, { 32, 34, 1, 1 } }, // divsd
1168 { ISD::FDIV, MVT::v2f64, { 69, 69, 1, 6 } }, // divpd
1169 { ISD::FADD, MVT::v2f64, { 2, 4, 1, 1 } }, // addpd
1170 { ISD::FSUB, MVT::v2f64, { 2, 4, 1, 1 } }, // subpd
1171 // v2i64/v4i64 mul is custom lowered as a series of long:
1172 // multiplies(3), shifts(3) and adds(2)
1173 // slm muldq version throughput is 2 and addq throughput 4
1174 // thus: 3X2 (muldq throughput) + 3X1 (shift throughput) +
1175 // 3X4 (addq throughput) = 17
1176 { ISD::MUL, MVT::v2i64, { 17, 22, 9, 9 } },
1177 // slm addq\subq throughput is 4
1178 { ISD::ADD, MVT::v2i64, { 4, 2, 1, 2 } },
1179 { ISD::SUB, MVT::v2i64, { 4, 2, 1, 2 } },
1180 };
1181
1182 if (ST->useSLMArithCosts())
1183 if (const auto *Entry = CostTableLookup(SLMCostTable, ISD, LT.second))
1184 if (auto KindCost = Entry->Cost[CostKind])
1185 return LT.first * *KindCost;
1186
1187 static const CostKindTblEntry AVX2CostTable[] = {
1188 { ISD::SHL, MVT::v16i8, { 6, 21,11,16 } }, // vpblendvb sequence.
1189 { ISD::SHL, MVT::v32i8, { 6, 23,11,22 } }, // vpblendvb sequence.
1190 { ISD::SHL, MVT::v8i16, { 5, 18, 5,10 } }, // extend/vpsrlvd/pack sequence.
1191 { ISD::SHL, MVT::v16i16, { 8, 10,10,14 } }, // extend/vpsrlvd/pack sequence.
1192
1193 { ISD::SRL, MVT::v16i8, { 6, 27,12,18 } }, // vpblendvb sequence.
1194 { ISD::SRL, MVT::v32i8, { 8, 30,12,24 } }, // vpblendvb sequence.
1195 { ISD::SRL, MVT::v8i16, { 5, 11, 5,10 } }, // extend/vpsrlvd/pack sequence.
1196 { ISD::SRL, MVT::v16i16, { 8, 10,10,14 } }, // extend/vpsrlvd/pack sequence.
1197
1198 { ISD::SRA, MVT::v16i8, { 17, 17,24,30 } }, // vpblendvb sequence.
1199 { ISD::SRA, MVT::v32i8, { 18, 20,24,43 } }, // vpblendvb sequence.
1200 { ISD::SRA, MVT::v8i16, { 5, 11, 5,10 } }, // extend/vpsravd/pack sequence.
1201 { ISD::SRA, MVT::v16i16, { 8, 10,10,14 } }, // extend/vpsravd/pack sequence.
1202 { ISD::SRA, MVT::v2i64, { 4, 5, 5, 5 } }, // srl/xor/sub sequence.
1203 { ISD::SRA, MVT::v4i64, { 8, 8, 5, 9 } }, // srl/xor/sub sequence.
1204
1205 { ISD::SUB, MVT::v32i8, { 1, 1, 1, 2 } }, // psubb
1206 { ISD::ADD, MVT::v32i8, { 1, 1, 1, 2 } }, // paddb
1207 { ISD::SUB, MVT::v16i16, { 1, 1, 1, 2 } }, // psubw
1208 { ISD::ADD, MVT::v16i16, { 1, 1, 1, 2 } }, // paddw
1209 { ISD::SUB, MVT::v8i32, { 1, 1, 1, 2 } }, // psubd
1210 { ISD::ADD, MVT::v8i32, { 1, 1, 1, 2 } }, // paddd
1211 { ISD::SUB, MVT::v4i64, { 1, 1, 1, 2 } }, // psubq
1212 { ISD::ADD, MVT::v4i64, { 1, 1, 1, 2 } }, // paddq
1213
1214 { ISD::MUL, MVT::v16i8, { 5, 18, 6,12 } }, // extend/pmullw/pack
1215 { ISD::MUL, MVT::v32i8, { 4, 8, 8,16 } }, // pmaddubsw
1216 { ISD::MUL, MVT::v16i16, { 2, 5, 1, 2 } }, // pmullw
1217 { ISD::MUL, MVT::v8i32, { 4, 10, 1, 2 } }, // pmulld
1218 { ISD::MUL, MVT::v4i32, { 2, 10, 1, 2 } }, // pmulld
1219 { ISD::MUL, MVT::v4i64, { 6, 10, 8,13 } }, // 3*pmuludq/3*shift/2*add
1220 { ISD::MUL, MVT::v2i64, { 6, 10, 8, 8 } }, // 3*pmuludq/3*shift/2*add
1221
1222 { X86ISD::PMULUDQ, MVT::v4i64, { 1, 5, 1, 1 } },
1223
1224 { ISD::FNEG, MVT::v4f64, { 1, 1, 1, 2 } }, // vxorpd
1225 { ISD::FNEG, MVT::v8f32, { 1, 1, 1, 2 } }, // vxorps
1226
1227 { ISD::FADD, MVT::f64, { 1, 4, 1, 1 } }, // vaddsd
1228 { ISD::FADD, MVT::f32, { 1, 4, 1, 1 } }, // vaddss
1229 { ISD::FADD, MVT::v2f64, { 1, 4, 1, 1 } }, // vaddpd
1230 { ISD::FADD, MVT::v4f32, { 1, 4, 1, 1 } }, // vaddps
1231 { ISD::FADD, MVT::v4f64, { 1, 4, 1, 2 } }, // vaddpd
1232 { ISD::FADD, MVT::v8f32, { 1, 4, 1, 2 } }, // vaddps
1233
1234 { ISD::FSUB, MVT::f64, { 1, 4, 1, 1 } }, // vsubsd
1235 { ISD::FSUB, MVT::f32, { 1, 4, 1, 1 } }, // vsubss
1236 { ISD::FSUB, MVT::v2f64, { 1, 4, 1, 1 } }, // vsubpd
1237 { ISD::FSUB, MVT::v4f32, { 1, 4, 1, 1 } }, // vsubps
1238 { ISD::FSUB, MVT::v4f64, { 1, 4, 1, 2 } }, // vsubpd
1239 { ISD::FSUB, MVT::v8f32, { 1, 4, 1, 2 } }, // vsubps
1240
1241 { ISD::FMUL, MVT::f64, { 1, 5, 1, 1 } }, // vmulsd
1242 { ISD::FMUL, MVT::f32, { 1, 5, 1, 1 } }, // vmulss
1243 { ISD::FMUL, MVT::v2f64, { 1, 5, 1, 1 } }, // vmulpd
1244 { ISD::FMUL, MVT::v4f32, { 1, 5, 1, 1 } }, // vmulps
1245 { ISD::FMUL, MVT::v4f64, { 1, 5, 1, 2 } }, // vmulpd
1246 { ISD::FMUL, MVT::v8f32, { 1, 5, 1, 2 } }, // vmulps
1247
1248 { ISD::FDIV, MVT::f32, { 7, 13, 1, 1 } }, // vdivss
1249 { ISD::FDIV, MVT::v4f32, { 7, 13, 1, 1 } }, // vdivps
1250 { ISD::FDIV, MVT::v8f32, { 14, 21, 1, 3 } }, // vdivps
1251 { ISD::FDIV, MVT::f64, { 14, 20, 1, 1 } }, // vdivsd
1252 { ISD::FDIV, MVT::v2f64, { 14, 20, 1, 1 } }, // vdivpd
1253 { ISD::FDIV, MVT::v4f64, { 28, 35, 1, 3 } }, // vdivpd
1254 };
1255
1256 // Look for AVX2 lowering tricks for custom cases.
1257 if (ST->hasAVX2())
1258 if (const auto *Entry = CostTableLookup(AVX2CostTable, ISD, LT.second))
1259 if (auto KindCost = Entry->Cost[CostKind])
1260 return LT.first * *KindCost;
1261
1262 static const CostKindTblEntry AVX1CostTable[] = {
1263 // We don't have to scalarize unsupported ops. We can issue two half-sized
1264 // operations and we only need to extract the upper YMM half.
1265 // Two ops + 1 extract + 1 insert = 4.
1266 { ISD::MUL, MVT::v32i8, { 10, 11, 18, 19 } }, // pmaddubsw + split
1267 { ISD::MUL, MVT::v16i8, { 5, 6, 8, 12 } }, // 2*pmaddubsw/3*and/psllw/or
1268 { ISD::MUL, MVT::v16i16, { 4, 8, 5, 6 } }, // pmullw + split
1269 { ISD::MUL, MVT::v8i32, { 5, 8, 5, 10 } }, // pmulld + split
1270 { ISD::MUL, MVT::v4i32, { 2, 5, 1, 3 } }, // pmulld
1271 { ISD::MUL, MVT::v4i64, { 12, 15, 19, 20 } },
1272
1273 { X86ISD::PMULUDQ, MVT::v4i64, { 3, 5, 5, 6 } }, // pmuludq + split
1274
1275 { ISD::AND, MVT::v32i8, { 1, 1, 1, 2 } }, // vandps
1276 { ISD::AND, MVT::v16i16, { 1, 1, 1, 2 } }, // vandps
1277 { ISD::AND, MVT::v8i32, { 1, 1, 1, 2 } }, // vandps
1278 { ISD::AND, MVT::v4i64, { 1, 1, 1, 2 } }, // vandps
1279
1280 { ISD::OR, MVT::v32i8, { 1, 1, 1, 2 } }, // vorps
1281 { ISD::OR, MVT::v16i16, { 1, 1, 1, 2 } }, // vorps
1282 { ISD::OR, MVT::v8i32, { 1, 1, 1, 2 } }, // vorps
1283 { ISD::OR, MVT::v4i64, { 1, 1, 1, 2 } }, // vorps
1284
1285 { ISD::XOR, MVT::v32i8, { 1, 1, 1, 2 } }, // vxorps
1286 { ISD::XOR, MVT::v16i16, { 1, 1, 1, 2 } }, // vxorps
1287 { ISD::XOR, MVT::v8i32, { 1, 1, 1, 2 } }, // vxorps
1288 { ISD::XOR, MVT::v4i64, { 1, 1, 1, 2 } }, // vxorps
1289
1290 { ISD::SUB, MVT::v32i8, { 4, 2, 5, 6 } }, // psubb + split
1291 { ISD::ADD, MVT::v32i8, { 4, 2, 5, 6 } }, // paddb + split
1292 { ISD::SUB, MVT::v16i16, { 4, 2, 5, 6 } }, // psubw + split
1293 { ISD::ADD, MVT::v16i16, { 4, 2, 5, 6 } }, // paddw + split
1294 { ISD::SUB, MVT::v8i32, { 4, 2, 5, 6 } }, // psubd + split
1295 { ISD::ADD, MVT::v8i32, { 4, 2, 5, 6 } }, // paddd + split
1296 { ISD::SUB, MVT::v4i64, { 4, 2, 5, 6 } }, // psubq + split
1297 { ISD::ADD, MVT::v4i64, { 4, 2, 5, 6 } }, // paddq + split
1298 { ISD::SUB, MVT::v2i64, { 1, 1, 1, 1 } }, // psubq
1299 { ISD::ADD, MVT::v2i64, { 1, 1, 1, 1 } }, // paddq
1300
1301 { ISD::SHL, MVT::v16i8, { 10, 21,11,17 } }, // pblendvb sequence.
1302 { ISD::SHL, MVT::v32i8, { 22, 22,27,40 } }, // pblendvb sequence + split.
1303 { ISD::SHL, MVT::v8i16, { 6, 9,11,11 } }, // pblendvb sequence.
1304 { ISD::SHL, MVT::v16i16, { 13, 16,24,25 } }, // pblendvb sequence + split.
1305 { ISD::SHL, MVT::v4i32, { 3, 11, 4, 6 } }, // pslld/paddd/cvttps2dq/pmulld
1306 { ISD::SHL, MVT::v8i32, { 9, 11,12,17 } }, // pslld/paddd/cvttps2dq/pmulld + split
1307 { ISD::SHL, MVT::v2i64, { 2, 4, 4, 6 } }, // Shift each lane + blend.
1308 { ISD::SHL, MVT::v4i64, { 6, 7,11,15 } }, // Shift each lane + blend + split.
1309
1310 { ISD::SRL, MVT::v16i8, { 11, 27,12,18 } }, // pblendvb sequence.
1311 { ISD::SRL, MVT::v32i8, { 23, 23,30,43 } }, // pblendvb sequence + split.
1312 { ISD::SRL, MVT::v8i16, { 13, 16,14,22 } }, // pblendvb sequence.
1313 { ISD::SRL, MVT::v16i16, { 28, 30,31,48 } }, // pblendvb sequence + split.
1314 { ISD::SRL, MVT::v4i32, { 6, 7,12,16 } }, // Shift each lane + blend.
1315 { ISD::SRL, MVT::v8i32, { 14, 14,26,34 } }, // Shift each lane + blend + split.
1316 { ISD::SRL, MVT::v2i64, { 2, 4, 4, 6 } }, // Shift each lane + blend.
1317 { ISD::SRL, MVT::v4i64, { 6, 7,11,15 } }, // Shift each lane + blend + split.
1318
1319 { ISD::SRA, MVT::v16i8, { 21, 22,24,36 } }, // pblendvb sequence.
1320 { ISD::SRA, MVT::v32i8, { 44, 45,51,76 } }, // pblendvb sequence + split.
1321 { ISD::SRA, MVT::v8i16, { 13, 16,14,22 } }, // pblendvb sequence.
1322 { ISD::SRA, MVT::v16i16, { 28, 30,31,48 } }, // pblendvb sequence + split.
1323 { ISD::SRA, MVT::v4i32, { 6, 7,12,16 } }, // Shift each lane + blend.
1324 { ISD::SRA, MVT::v8i32, { 14, 14,26,34 } }, // Shift each lane + blend + split.
1325 { ISD::SRA, MVT::v2i64, { 5, 6,10,14 } }, // Shift each lane + blend.
1326 { ISD::SRA, MVT::v4i64, { 12, 12,22,30 } }, // Shift each lane + blend + split.
1327
1328 { ISD::FNEG, MVT::v4f64, { 2, 2, 1, 2 } }, // BTVER2 from http://www.agner.org/
1329 { ISD::FNEG, MVT::v8f32, { 2, 2, 1, 2 } }, // BTVER2 from http://www.agner.org/
1330
1331 { ISD::FADD, MVT::f64, { 1, 5, 1, 1 } }, // BDVER2 from http://www.agner.org/
1332 { ISD::FADD, MVT::f32, { 1, 5, 1, 1 } }, // BDVER2 from http://www.agner.org/
1333 { ISD::FADD, MVT::v2f64, { 1, 5, 1, 1 } }, // BDVER2 from http://www.agner.org/
1334 { ISD::FADD, MVT::v4f32, { 1, 5, 1, 1 } }, // BDVER2 from http://www.agner.org/
1335 { ISD::FADD, MVT::v4f64, { 2, 5, 1, 2 } }, // BDVER2 from http://www.agner.org/
1336 { ISD::FADD, MVT::v8f32, { 2, 5, 1, 2 } }, // BDVER2 from http://www.agner.org/
1337
1338 { ISD::FSUB, MVT::f64, { 1, 5, 1, 1 } }, // BDVER2 from http://www.agner.org/
1339 { ISD::FSUB, MVT::f32, { 1, 5, 1, 1 } }, // BDVER2 from http://www.agner.org/
1340 { ISD::FSUB, MVT::v2f64, { 1, 5, 1, 1 } }, // BDVER2 from http://www.agner.org/
1341 { ISD::FSUB, MVT::v4f32, { 1, 5, 1, 1 } }, // BDVER2 from http://www.agner.org/
1342 { ISD::FSUB, MVT::v4f64, { 2, 5, 1, 2 } }, // BDVER2 from http://www.agner.org/
1343 { ISD::FSUB, MVT::v8f32, { 2, 5, 1, 2 } }, // BDVER2 from http://www.agner.org/
1344
1345 { ISD::FMUL, MVT::f64, { 2, 5, 1, 1 } }, // BTVER2 from http://www.agner.org/
1346 { ISD::FMUL, MVT::f32, { 1, 5, 1, 1 } }, // BTVER2 from http://www.agner.org/
1347 { ISD::FMUL, MVT::v2f64, { 2, 5, 1, 1 } }, // BTVER2 from http://www.agner.org/
1348 { ISD::FMUL, MVT::v4f32, { 1, 5, 1, 1 } }, // BTVER2 from http://www.agner.org/
1349 { ISD::FMUL, MVT::v4f64, { 4, 5, 1, 2 } }, // BTVER2 from http://www.agner.org/
1350 { ISD::FMUL, MVT::v8f32, { 2, 5, 1, 2 } }, // BTVER2 from http://www.agner.org/
1351
1352 { ISD::FDIV, MVT::f32, { 14, 14, 1, 1 } }, // SNB from http://www.agner.org/
1353 { ISD::FDIV, MVT::v4f32, { 14, 14, 1, 1 } }, // SNB from http://www.agner.org/
1354 { ISD::FDIV, MVT::v8f32, { 28, 29, 1, 3 } }, // SNB from http://www.agner.org/
1355 { ISD::FDIV, MVT::f64, { 22, 22, 1, 1 } }, // SNB from http://www.agner.org/
1356 { ISD::FDIV, MVT::v2f64, { 22, 22, 1, 1 } }, // SNB from http://www.agner.org/
1357 { ISD::FDIV, MVT::v4f64, { 44, 45, 1, 3 } }, // SNB from http://www.agner.org/
1358 };
1359
1360 if (ST->hasAVX())
1361 if (const auto *Entry = CostTableLookup(AVX1CostTable, ISD, LT.second))
1362 if (auto KindCost = Entry->Cost[CostKind])
1363 return LT.first * *KindCost;
1364
1365 static const CostKindTblEntry SSE42CostTable[] = {
1366 { ISD::FADD, MVT::f64, { 1, 3, 1, 1 } }, // Nehalem from http://www.agner.org/
1367 { ISD::FADD, MVT::f32, { 1, 3, 1, 1 } }, // Nehalem from http://www.agner.org/
1368 { ISD::FADD, MVT::v2f64, { 1, 3, 1, 1 } }, // Nehalem from http://www.agner.org/
1369 { ISD::FADD, MVT::v4f32, { 1, 3, 1, 1 } }, // Nehalem from http://www.agner.org/
1370
1371 { ISD::FSUB, MVT::f64, { 1, 3, 1, 1 } }, // Nehalem from http://www.agner.org/
1372 { ISD::FSUB, MVT::f32 , { 1, 3, 1, 1 } }, // Nehalem from http://www.agner.org/
1373 { ISD::FSUB, MVT::v2f64, { 1, 3, 1, 1 } }, // Nehalem from http://www.agner.org/
1374 { ISD::FSUB, MVT::v4f32, { 1, 3, 1, 1 } }, // Nehalem from http://www.agner.org/
1375
1376 { ISD::FMUL, MVT::f64, { 1, 5, 1, 1 } }, // Nehalem from http://www.agner.org/
1377 { ISD::FMUL, MVT::f32, { 1, 5, 1, 1 } }, // Nehalem from http://www.agner.org/
1378 { ISD::FMUL, MVT::v2f64, { 1, 5, 1, 1 } }, // Nehalem from http://www.agner.org/
1379 { ISD::FMUL, MVT::v4f32, { 1, 5, 1, 1 } }, // Nehalem from http://www.agner.org/
1380
1381 { ISD::FDIV, MVT::f32, { 14, 14, 1, 1 } }, // Nehalem from http://www.agner.org/
1382 { ISD::FDIV, MVT::v4f32, { 14, 14, 1, 1 } }, // Nehalem from http://www.agner.org/
1383 { ISD::FDIV, MVT::f64, { 22, 22, 1, 1 } }, // Nehalem from http://www.agner.org/
1384 { ISD::FDIV, MVT::v2f64, { 22, 22, 1, 1 } }, // Nehalem from http://www.agner.org/
1385
1386 { ISD::MUL, MVT::v2i64, { 6, 10,10,10 } } // 3*pmuludq/3*shift/2*add
1387 };
1388
1389 if (ST->hasSSE42())
1390 if (const auto *Entry = CostTableLookup(SSE42CostTable, ISD, LT.second))
1391 if (auto KindCost = Entry->Cost[CostKind])
1392 return LT.first * *KindCost;
1393
1394 static const CostKindTblEntry SSE41CostTable[] = {
1395 { ISD::SHL, MVT::v16i8, { 15, 24,17,22 } }, // pblendvb sequence.
1396 { ISD::SHL, MVT::v8i16, { 11, 14,11,11 } }, // pblendvb sequence.
1397 { ISD::SHL, MVT::v4i32, { 14, 20, 4,10 } }, // pslld/paddd/cvttps2dq/pmulld
1398
1399 { ISD::SRL, MVT::v16i8, { 16, 27,18,24 } }, // pblendvb sequence.
1400 { ISD::SRL, MVT::v8i16, { 22, 26,23,27 } }, // pblendvb sequence.
1401 { ISD::SRL, MVT::v4i32, { 16, 17,15,19 } }, // Shift each lane + blend.
1402 { ISD::SRL, MVT::v2i64, { 4, 6, 5, 7 } }, // splat+shuffle sequence.
1403
1404 { ISD::SRA, MVT::v16i8, { 38, 41,30,36 } }, // pblendvb sequence.
1405 { ISD::SRA, MVT::v8i16, { 22, 26,23,27 } }, // pblendvb sequence.
1406 { ISD::SRA, MVT::v4i32, { 16, 17,15,19 } }, // Shift each lane + blend.
1407 { ISD::SRA, MVT::v2i64, { 8, 17, 5, 7 } }, // splat+shuffle sequence.
1408
1409 { ISD::MUL, MVT::v4i32, { 2, 11, 1, 1 } } // pmulld (Nehalem from agner.org)
1410 };
1411
1412 if (ST->hasSSE41())
1413 if (const auto *Entry = CostTableLookup(SSE41CostTable, ISD, LT.second))
1414 if (auto KindCost = Entry->Cost[CostKind])
1415 return LT.first * *KindCost;
1416
1417 static const CostKindTblEntry SSSE3CostTable[] = {
1418 { ISD::MUL, MVT::v16i8, { 5, 18,10,12 } }, // 2*pmaddubsw/3*and/psllw/or
1419 };
1420
1421 if (ST->hasSSSE3())
1422 if (const auto *Entry = CostTableLookup(SSSE3CostTable, ISD, LT.second))
1423 if (auto KindCost = Entry->Cost[CostKind])
1424 return LT.first * *KindCost;
1425
1426 static const CostKindTblEntry SSE2CostTable[] = {
1427 // We don't correctly identify costs of casts because they are marked as
1428 // custom.
1429 { ISD::SHL, MVT::v16i8, { 13, 21,26,28 } }, // cmpgtb sequence.
1430 { ISD::SHL, MVT::v8i16, { 24, 27,16,20 } }, // cmpgtw sequence.
1431 { ISD::SHL, MVT::v4i32, { 17, 19,10,12 } }, // pslld/paddd/cvttps2dq/pmuludq.
1432 { ISD::SHL, MVT::v2i64, { 4, 6, 5, 7 } }, // splat+shuffle sequence.
1433
1434 { ISD::SRL, MVT::v16i8, { 14, 28,27,30 } }, // cmpgtb sequence.
1435 { ISD::SRL, MVT::v8i16, { 16, 19,31,31 } }, // cmpgtw sequence.
1436 { ISD::SRL, MVT::v4i32, { 12, 12,15,19 } }, // Shift each lane + blend.
1437 { ISD::SRL, MVT::v2i64, { 4, 6, 5, 7 } }, // splat+shuffle sequence.
1438
1439 { ISD::SRA, MVT::v16i8, { 27, 30,54,54 } }, // unpacked cmpgtb sequence.
1440 { ISD::SRA, MVT::v8i16, { 16, 19,31,31 } }, // cmpgtw sequence.
1441 { ISD::SRA, MVT::v4i32, { 12, 12,15,19 } }, // Shift each lane + blend.
1442 { ISD::SRA, MVT::v2i64, { 8, 11,12,16 } }, // srl/xor/sub splat+shuffle sequence.
1443
1444 { ISD::AND, MVT::v16i8, { 1, 1, 1, 1 } }, // pand
1445 { ISD::AND, MVT::v8i16, { 1, 1, 1, 1 } }, // pand
1446 { ISD::AND, MVT::v4i32, { 1, 1, 1, 1 } }, // pand
1447 { ISD::AND, MVT::v2i64, { 1, 1, 1, 1 } }, // pand
1448
1449 { ISD::OR, MVT::v16i8, { 1, 1, 1, 1 } }, // por
1450 { ISD::OR, MVT::v8i16, { 1, 1, 1, 1 } }, // por
1451 { ISD::OR, MVT::v4i32, { 1, 1, 1, 1 } }, // por
1452 { ISD::OR, MVT::v2i64, { 1, 1, 1, 1 } }, // por
1453
1454 { ISD::XOR, MVT::v16i8, { 1, 1, 1, 1 } }, // pxor
1455 { ISD::XOR, MVT::v8i16, { 1, 1, 1, 1 } }, // pxor
1456 { ISD::XOR, MVT::v4i32, { 1, 1, 1, 1 } }, // pxor
1457 { ISD::XOR, MVT::v2i64, { 1, 1, 1, 1 } }, // pxor
1458
1459 { ISD::ADD, MVT::v2i64, { 1, 2, 1, 2 } }, // paddq
1460 { ISD::SUB, MVT::v2i64, { 1, 2, 1, 2 } }, // psubq
1461
1462 { ISD::MUL, MVT::v16i8, { 6, 18,12,12 } }, // 2*unpack/2*pmullw/2*and/pack
1463 { ISD::MUL, MVT::v8i16, { 1, 5, 1, 1 } }, // pmullw
1464 { ISD::MUL, MVT::v4i32, { 6, 8, 7, 7 } }, // 3*pmuludq/4*shuffle
1465 { ISD::MUL, MVT::v2i64, { 7, 10,10,10 } }, // 3*pmuludq/3*shift/2*add
1466
1467 { X86ISD::PMULUDQ, MVT::v2i64, { 1, 5, 1, 1 } },
1468
1469 { ISD::FDIV, MVT::f32, { 23, 23, 1, 1 } }, // Pentium IV from http://www.agner.org/
1470 { ISD::FDIV, MVT::v4f32, { 39, 39, 1, 1 } }, // Pentium IV from http://www.agner.org/
1471 { ISD::FDIV, MVT::f64, { 38, 38, 1, 1 } }, // Pentium IV from http://www.agner.org/
1472 { ISD::FDIV, MVT::v2f64, { 69, 69, 1, 1 } }, // Pentium IV from http://www.agner.org/
1473
1474 { ISD::FNEG, MVT::f32, { 1, 1, 1, 1 } }, // Pentium IV from http://www.agner.org/
1475 { ISD::FNEG, MVT::f64, { 1, 1, 1, 1 } }, // Pentium IV from http://www.agner.org/
1476 { ISD::FNEG, MVT::v4f32, { 1, 1, 1, 1 } }, // Pentium IV from http://www.agner.org/
1477 { ISD::FNEG, MVT::v2f64, { 1, 1, 1, 1 } }, // Pentium IV from http://www.agner.org/
1478
1479 { ISD::FADD, MVT::f32, { 2, 3, 1, 1 } }, // Pentium IV from http://www.agner.org/
1480 { ISD::FADD, MVT::f64, { 2, 3, 1, 1 } }, // Pentium IV from http://www.agner.org/
1481 { ISD::FADD, MVT::v2f64, { 2, 3, 1, 1 } }, // Pentium IV from http://www.agner.org/
1482
1483 { ISD::FSUB, MVT::f32, { 2, 3, 1, 1 } }, // Pentium IV from http://www.agner.org/
1484 { ISD::FSUB, MVT::f64, { 2, 3, 1, 1 } }, // Pentium IV from http://www.agner.org/
1485 { ISD::FSUB, MVT::v2f64, { 2, 3, 1, 1 } }, // Pentium IV from http://www.agner.org/
1486
1487 { ISD::FMUL, MVT::f64, { 2, 5, 1, 1 } }, // Pentium IV from http://www.agner.org/
1488 { ISD::FMUL, MVT::v2f64, { 2, 5, 1, 1 } }, // Pentium IV from http://www.agner.org/
1489 };
1490
1491 if (ST->hasSSE2())
1492 if (const auto *Entry = CostTableLookup(SSE2CostTable, ISD, LT.second))
1493 if (auto KindCost = Entry->Cost[CostKind])
1494 return LT.first * *KindCost;
1495
1496 static const CostKindTblEntry SSE1CostTable[] = {
1497 { ISD::FDIV, MVT::f32, { 17, 18, 1, 1 } }, // Pentium III from http://www.agner.org/
1498 { ISD::FDIV, MVT::v4f32, { 34, 48, 1, 1 } }, // Pentium III from http://www.agner.org/
1499
1500 { ISD::FNEG, MVT::f32, { 2, 2, 1, 2 } }, // Pentium III from http://www.agner.org/
1501 { ISD::FNEG, MVT::v4f32, { 2, 2, 1, 2 } }, // Pentium III from http://www.agner.org/
1502
1503 { ISD::FADD, MVT::f32, { 1, 3, 1, 1 } }, // Pentium III from http://www.agner.org/
1504 { ISD::FADD, MVT::v4f32, { 2, 3, 1, 1 } }, // Pentium III from http://www.agner.org/
1505
1506 { ISD::FSUB, MVT::f32, { 1, 3, 1, 1 } }, // Pentium III from http://www.agner.org/
1507 { ISD::FSUB, MVT::v4f32, { 2, 3, 1, 1 } }, // Pentium III from http://www.agner.org/
1508
1509 { ISD::FMUL, MVT::f32, { 2, 5, 1, 1 } }, // Pentium III from http://www.agner.org/
1510 { ISD::FMUL, MVT::v4f32, { 2, 5, 1, 1 } }, // Pentium III from http://www.agner.org/
1511 };
1512
1513 if (ST->hasSSE1())
1514 if (const auto *Entry = CostTableLookup(SSE1CostTable, ISD, LT.second))
1515 if (auto KindCost = Entry->Cost[CostKind])
1516 return LT.first * *KindCost;
1517
1518 static const CostKindTblEntry X64CostTbl[] = { // 64-bit targets
1519 { ISD::ADD, MVT::i64, { 1 } }, // Core (Merom) from http://www.agner.org/
1520 { ISD::SUB, MVT::i64, { 1 } }, // Core (Merom) from http://www.agner.org/
1521 { ISD::MUL, MVT::i64, { 2, 6, 1, 2 } },
1522 };
1523
1524 if (ST->is64Bit())
1525 if (const auto *Entry = CostTableLookup(X64CostTbl, ISD, LT.second))
1526 if (auto KindCost = Entry->Cost[CostKind])
1527 return LT.first * *KindCost;
1528
1529 static const CostKindTblEntry X86CostTbl[] = { // 32 or 64-bit targets
1530 { ISD::ADD, MVT::i8, { 1 } }, // Pentium III from http://www.agner.org/
1531 { ISD::ADD, MVT::i16, { 1 } }, // Pentium III from http://www.agner.org/
1532 { ISD::ADD, MVT::i32, { 1 } }, // Pentium III from http://www.agner.org/
1533
1534 { ISD::SUB, MVT::i8, { 1 } }, // Pentium III from http://www.agner.org/
1535 { ISD::SUB, MVT::i16, { 1 } }, // Pentium III from http://www.agner.org/
1536 { ISD::SUB, MVT::i32, { 1 } }, // Pentium III from http://www.agner.org/
1537
1538 { ISD::MUL, MVT::i8, { 3, 4, 1, 1 } },
1539 { ISD::MUL, MVT::i16, { 2, 4, 1, 1 } },
1540 { ISD::MUL, MVT::i32, { 1, 4, 1, 1 } },
1541
1542 { ISD::FNEG, MVT::f64, { 2, 2, 1, 3 } }, // (x87)
1543 { ISD::FADD, MVT::f64, { 2, 3, 1, 1 } }, // (x87)
1544 { ISD::FSUB, MVT::f64, { 2, 3, 1, 1 } }, // (x87)
1545 { ISD::FMUL, MVT::f64, { 2, 5, 1, 1 } }, // (x87)
1546 { ISD::FDIV, MVT::f64, { 38, 38, 1, 1 } }, // (x87)
1547 };
1548
1549 if (const auto *Entry = CostTableLookup(X86CostTbl, ISD, LT.second))
1550 if (auto KindCost = Entry->Cost[CostKind])
1551 return LT.first * *KindCost;
1552
1553 // It is not a good idea to vectorize division. We have to scalarize it and
1554 // in the process we will often end up having to spilling regular
1555 // registers. The overhead of division is going to dominate most kernels
1556 // anyways so try hard to prevent vectorization of division - it is
1557 // generally a bad idea. Assume somewhat arbitrarily that we have to be able
1558 // to hide "20 cycles" for each lane.
1559 if (CostKind == TTI::TCK_RecipThroughput && LT.second.isVector() &&
1560 (ISD == ISD::SDIV || ISD == ISD::SREM || ISD == ISD::UDIV ||
1561 ISD == ISD::UREM)) {
1562 InstructionCost ScalarCost =
1563 getArithmeticInstrCost(Opcode, Ty->getScalarType(), CostKind,
1564 Op1Info.getNoProps(), Op2Info.getNoProps());
1565 return 20 * LT.first * LT.second.getVectorNumElements() * ScalarCost;
1566 }
1567
1568 // Handle some basic single instruction code size cases.
1569 if (CostKind == TTI::TCK_CodeSize) {
1570 switch (ISD) {
1571 case ISD::FADD:
1572 case ISD::FSUB:
1573 case ISD::FMUL:
1574 case ISD::FDIV:
1575 case ISD::FNEG:
1576 case ISD::AND:
1577 case ISD::OR:
1578 case ISD::XOR:
1579 return LT.first;
1580 break;
1581 }
1582 }
1583
1584 // Fallback to the default implementation.
1585 return BaseT::getArithmeticInstrCost(Opcode, Ty, CostKind, Op1Info, Op2Info,
1586 Args, CxtI);
1587}
1588
1591 unsigned Opcode1, const SmallBitVector &OpcodeMask,
1593 if (isLegalAltInstr(VecTy, Opcode0, Opcode1, OpcodeMask))
1594 return TTI::TCC_Basic;
1596}
1597
1599 VectorType *DstTy, VectorType *SrcTy,
1600 ArrayRef<int> Mask,
1602 int Index, VectorType *SubTp,
1604 const Instruction *CxtI) const {
1605 assert((Mask.empty() || DstTy->isScalableTy() ||
1606 Mask.size() == DstTy->getElementCount().getKnownMinValue()) &&
1607 "Expected the Mask to match the return size if given");
1608 assert(SrcTy->getScalarType() == DstTy->getScalarType() &&
1609 "Expected the same scalar types");
1610
1611 // 64-bit packed float vectors (v2f32) are widened to type v4f32.
1612 // 64-bit packed integer vectors (v2i32) are widened to type v4i32.
1613 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(SrcTy);
1614
1615 Kind = improveShuffleKindFromMask(Kind, Mask, SrcTy, Index, SubTp);
1616
1617 // If all args are constant than this will be constant folded away.
1618 if (!Args.empty() &&
1619 all_of(Args, [](const Value *Arg) { return isa<Constant>(Arg); }))
1620 return TTI::TCC_Free;
1621
1622 // Recognize a basic concat_vector shuffle.
1623 if (Kind == TTI::SK_PermuteTwoSrc &&
1624 Mask.size() == (2 * SrcTy->getElementCount().getKnownMinValue()) &&
1625 ShuffleVectorInst::isIdentityMask(Mask, Mask.size()))
1629 CostKind, Mask.size() / 2, SrcTy);
1630
1631 // Treat Transpose as 2-op shuffles - there's no difference in lowering.
1632 if (Kind == TTI::SK_Transpose)
1633 if (LT.second != MVT::v4f64 && LT.second != MVT::v4i64)
1634 Kind = TTI::SK_PermuteTwoSrc;
1635
1636 if (Kind == TTI::SK_Broadcast) {
1637 // For Broadcasts we are splatting the first element from the first input
1638 // register, so only need to reference that input and all the output
1639 // registers are the same.
1640 LT.first = 1;
1641
1642 // If we're broadcasting a load then AVX/AVX2 can do this for free.
1643 // If many-used-load whose every use is one of a small set of operations
1644 // that SLP can rewrite into a single vector lane, codegen can fold it into
1645 // the free broadcast.
1646 using namespace PatternMatch;
1647 auto IsBroadcastLoadFoldUser = [&](const User *U) {
1648 if (isa<InsertElementInst>(U) && U->getOperand(1) == Args[0])
1649 return true;
1650 if (U->getType()->isVectorTy())
1651 return false;
1652 // Terminators (return/branch/switch/indirectbr/resume/invoke EH)
1653 // and phis carry the value across control flow.
1654 if (const auto *I = dyn_cast<Instruction>(U))
1655 if (I->isTerminator() ||
1657 return false;
1658 // Only pure calls can be folded.
1659 if (const auto *CB = dyn_cast<CallBase>(U))
1660 return CB->doesNotAccessMemory() && !CB->mayHaveSideEffects();
1661 return true;
1662 };
1663 auto IsFoldableSLPBroadcastLoad = [&]() {
1664 if (!match(Args[0], m_Load(m_Value())))
1665 return false;
1666 auto *FVT = dyn_cast<FixedVectorType>(DstTy);
1667 if (!FVT)
1668 return false;
1669 // getNumUses() counts each Use, matching the per-lane broadcast
1670 // accounting (a use like `op %x, %x` consumes two broadcast lanes).
1671 if (Args[0]->getNumUses() != FVT->getNumElements())
1672 return false;
1673 return all_of(Args[0]->users(), IsBroadcastLoadFoldUser);
1674 };
1675 if (!Args.empty() &&
1676 (match(Args[0], m_OneUse(m_Load(m_Value()))) ||
1677 IsFoldableSLPBroadcastLoad()) &&
1678 (ST->hasAVX2() ||
1679 (ST->hasAVX() && LT.second.getScalarSizeInBits() >= 32)))
1680 return TTI::TCC_Free;
1681 }
1682
1683 // Attempt to detect a cheaper inlane shuffle, avoiding 128-bit subvector
1684 // permutation.
1685 // Attempt to detect a shuffle mask with a single defined element.
1686 bool IsInLaneShuffle = false;
1687 bool IsSingleElementMask = false;
1688 if (SrcTy->getPrimitiveSizeInBits() > 0 &&
1689 (SrcTy->getPrimitiveSizeInBits() % 128) == 0 &&
1690 SrcTy->getScalarSizeInBits() == LT.second.getScalarSizeInBits() &&
1691 Mask.size() == SrcTy->getElementCount().getKnownMinValue()) {
1692 unsigned NumLanes = SrcTy->getPrimitiveSizeInBits() / 128;
1693 unsigned NumEltsPerLane = Mask.size() / NumLanes;
1694 if ((Mask.size() % NumLanes) == 0) {
1695 IsInLaneShuffle = all_of(enumerate(Mask), [&](const auto &P) {
1696 return P.value() == PoisonMaskElem ||
1697 ((P.value() % Mask.size()) / NumEltsPerLane) ==
1698 (P.index() / NumEltsPerLane);
1699 });
1700 IsSingleElementMask =
1701 (Mask.size() - 1) == static_cast<unsigned>(count_if(Mask, [](int M) {
1702 return M == PoisonMaskElem;
1703 }));
1704 }
1705 }
1706
1707 // Treat <X x bfloat> shuffles as <X x half>.
1708 if (LT.second.isVectorOf(MVT::bf16))
1709 LT.second = LT.second.changeVectorElementType(MVT::f16);
1710
1711 // Subvector extractions are free if they start at the beginning of a
1712 // vector and cheap if the subvectors are aligned.
1713 if (Kind == TTI::SK_ExtractSubvector && LT.second.isVector()) {
1714 int NumElts = LT.second.getVectorNumElements();
1715 if ((Index % NumElts) == 0)
1716 return TTI::TCC_Free;
1717 std::pair<InstructionCost, MVT> SubLT = getTypeLegalizationCost(SubTp);
1718 if (SubLT.second.isVector()) {
1719 int NumSubElts = SubLT.second.getVectorNumElements();
1720 if ((Index % NumSubElts) == 0 && (NumElts % NumSubElts) == 0)
1721 return SubLT.first;
1722 // Handle some cases for widening legalization. For now we only handle
1723 // cases where the original subvector was naturally aligned and evenly
1724 // fit in its legalized subvector type.
1725 // FIXME: Remove some of the alignment restrictions.
1726 // FIXME: We can use permq for 64-bit or larger extracts from 256-bit
1727 // vectors.
1728 int OrigSubElts = cast<FixedVectorType>(SubTp)->getNumElements();
1729 if (NumSubElts > OrigSubElts && (Index % OrigSubElts) == 0 &&
1730 (NumSubElts % OrigSubElts) == 0 &&
1731 LT.second.getVectorElementType() ==
1732 SubLT.second.getVectorElementType() &&
1733 LT.second.getVectorElementType().getSizeInBits() ==
1734 SrcTy->getElementType()->getPrimitiveSizeInBits()) {
1735 assert(NumElts >= NumSubElts && NumElts > OrigSubElts &&
1736 "Unexpected number of elements!");
1737 auto *VecTy = FixedVectorType::get(SrcTy->getElementType(),
1738 LT.second.getVectorNumElements());
1739 auto *SubTy = FixedVectorType::get(SrcTy->getElementType(),
1740 SubLT.second.getVectorNumElements());
1741 int ExtractIndex = alignDown((Index % NumElts), NumSubElts);
1742 InstructionCost ExtractCost =
1744 ExtractIndex, SubTy);
1745
1746 // If the original size is 32-bits or more, we can use pshufd. Otherwise
1747 // if we have SSSE3 we can use pshufb.
1748 if (SubTp->getPrimitiveSizeInBits() >= 32 || ST->hasSSSE3())
1749 return ExtractCost + 1; // pshufd or pshufb
1750
1751 assert(SubTp->getPrimitiveSizeInBits() == 16 &&
1752 "Unexpected vector size");
1753
1754 return ExtractCost + 2; // worst case pshufhw + pshufd
1755 }
1756 }
1757 // If the extract subvector is not optimal, treat it as single op shuffle.
1759 }
1760
1761 // Subvector insertions are cheap if the subvectors are aligned.
1762 // Note that in general, the insertion starting at the beginning of a vector
1763 // isn't free, because we need to preserve the rest of the wide vector,
1764 // but if the destination vector legalizes to the same width as the subvector
1765 // then the insertion will simplify to a (free) register copy.
1766 if (Kind == TTI::SK_InsertSubvector && LT.second.isVector()) {
1767 std::pair<InstructionCost, MVT> DstLT = getTypeLegalizationCost(DstTy);
1768 int NumElts = DstLT.second.getVectorNumElements();
1769 std::pair<InstructionCost, MVT> SubLT = getTypeLegalizationCost(SubTp);
1770 if (SubLT.second.isVector()) {
1771 int NumSubElts = SubLT.second.getVectorNumElements();
1772 bool MatchingTypes =
1773 NumElts == NumSubElts &&
1774 (SubTp->getElementCount().getKnownMinValue() % NumSubElts) == 0;
1775 if ((Index % NumSubElts) == 0 && (NumElts % NumSubElts) == 0)
1776 return MatchingTypes ? TTI::TCC_Free : SubLT.first;
1777 }
1778
1779 // Attempt to match MOVSS (Idx == 0) or INSERTPS pattern. This will have
1780 // been matched by improveShuffleKindFromMask as a SK_InsertSubvector of
1781 // v1f32 (legalised to f32) into a v4f32.
1782 if (LT.first == 1 && LT.second == MVT::v4f32 && SubLT.first == 1 &&
1783 SubLT.second == MVT::f32 && (Index == 0 || ST->hasSSE41()))
1784 return 1;
1785
1786 // If the insertion is the lowest subvector then it will be blended
1787 // otherwise treat it like a 2-op shuffle.
1788 Kind =
1789 (Index == 0 && LT.first == 1) ? TTI::SK_Select : TTI::SK_PermuteTwoSrc;
1790 }
1791
1792 // Handle some common (illegal) sub-vector types as they are often very cheap
1793 // to shuffle even on targets without PSHUFB.
1794 EVT VT = TLI->getValueType(DL, SrcTy);
1795 if (VT.isSimple() && VT.isVector() && VT.getSizeInBits() < 128 &&
1796 !ST->hasSSSE3()) {
1797 static const CostKindTblEntry SSE2SubVectorShuffleTbl[] = {
1798 {TTI::SK_Broadcast, MVT::v4i16, {1,1,1,1}}, // pshuflw
1799 {TTI::SK_Broadcast, MVT::v2i16, {1,1,1,1}}, // pshuflw
1800 {TTI::SK_Broadcast, MVT::v8i8, {2,2,2,2}}, // punpck/pshuflw
1801 {TTI::SK_Broadcast, MVT::v4i8, {2,2,2,2}}, // punpck/pshuflw
1802 {TTI::SK_Broadcast, MVT::v2i8, {1,1,1,1}}, // punpck
1803
1804 {TTI::SK_Reverse, MVT::v4i16, {1,1,1,1}}, // pshuflw
1805 {TTI::SK_Reverse, MVT::v2i16, {1,1,1,1}}, // pshuflw
1806 {TTI::SK_Reverse, MVT::v4i8, {3,3,3,3}}, // punpck/pshuflw/packus
1807 {TTI::SK_Reverse, MVT::v2i8, {1,1,1,1}}, // punpck
1808
1809 {TTI::SK_Splice, MVT::v4i16, {2,2,2,2}}, // punpck+psrldq
1810 {TTI::SK_Splice, MVT::v2i16, {2,2,2,2}}, // punpck+psrldq
1811 {TTI::SK_Splice, MVT::v4i8, {2,2,2,2}}, // punpck+psrldq
1812 {TTI::SK_Splice, MVT::v2i8, {2,2,2,2}}, // punpck+psrldq
1813
1814 {TTI::SK_PermuteTwoSrc, MVT::v4i16, {2,2,2,2}}, // punpck/pshuflw
1815 {TTI::SK_PermuteTwoSrc, MVT::v2i16, {2,2,2,2}}, // punpck/pshuflw
1816 {TTI::SK_PermuteTwoSrc, MVT::v8i8, {7,7,7,7}}, // punpck/pshuflw
1817 {TTI::SK_PermuteTwoSrc, MVT::v4i8, {4,4,4,4}}, // punpck/pshuflw
1818 {TTI::SK_PermuteTwoSrc, MVT::v2i8, {2,2,2,2}}, // punpck
1819
1820 {TTI::SK_PermuteSingleSrc, MVT::v4i16, {1,1,1,1}}, // pshuflw
1821 {TTI::SK_PermuteSingleSrc, MVT::v2i16, {1,1,1,1}}, // pshuflw
1822 {TTI::SK_PermuteSingleSrc, MVT::v8i8, {5,5,5,5}}, // punpck/pshuflw
1823 {TTI::SK_PermuteSingleSrc, MVT::v4i8, {3,3,3,3}}, // punpck/pshuflw
1824 {TTI::SK_PermuteSingleSrc, MVT::v2i8, {1,1,1,1}}, // punpck
1825 };
1826
1827 if (ST->hasSSE2())
1828 if (const auto *Entry =
1829 CostTableLookup(SSE2SubVectorShuffleTbl, Kind, VT.getSimpleVT()))
1830 if (auto KindCost = Entry->Cost[CostKind])
1831 return LT.first * *KindCost;
1832 }
1833
1834 // We are going to permute multiple sources and the result will be in multiple
1835 // destinations. Providing an accurate cost only for splits where the element
1836 // type remains the same.
1837 if (LT.first != 1) {
1838 MVT LegalVT = LT.second;
1839 if (LegalVT.isVector() &&
1840 LegalVT.getVectorElementType().getSizeInBits() ==
1841 SrcTy->getElementType()->getPrimitiveSizeInBits() &&
1842 LegalVT.getVectorNumElements() <
1843 cast<FixedVectorType>(SrcTy)->getNumElements()) {
1844 unsigned VecTySize = DL.getTypeStoreSize(SrcTy);
1845 unsigned LegalVTSize = LegalVT.getStoreSize();
1846 // Number of source vectors after legalization:
1847 unsigned NumOfSrcs = (VecTySize + LegalVTSize - 1) / LegalVTSize;
1848 // Number of destination vectors after legalization:
1849 InstructionCost NumOfDests = LT.first;
1850
1851 auto *SingleOpTy = FixedVectorType::get(SrcTy->getElementType(),
1852 LegalVT.getVectorNumElements());
1853
1854 if (!Mask.empty() && NumOfDests.isValid()) {
1855 // Try to perform better estimation of the permutation.
1856 // 1. Split the source/destination vectors into real registers.
1857 // 2. Do the mask analysis to identify which real registers are
1858 // permuted. If more than 1 source registers are used for the
1859 // destination register building, the cost for this destination register
1860 // is (Number_of_source_register - 1) * Cost_PermuteTwoSrc. If only one
1861 // source register is used, build mask and calculate the cost as a cost
1862 // of PermuteSingleSrc.
1863 // Also, for the single register permute we try to identify if the
1864 // destination register is just a copy of the source register or the
1865 // copy of the previous destination register (the cost is
1866 // TTI::TCC_Basic). If the source register is just reused, the cost for
1867 // this operation is TTI::TCC_Free.
1868 NumOfDests =
1870 FixedVectorType::get(SrcTy->getElementType(), Mask.size()))
1871 .first;
1872 unsigned E = NumOfDests.getValue();
1873 unsigned NormalizedVF =
1874 LegalVT.getVectorNumElements() * std::max(NumOfSrcs, E);
1875 unsigned NumOfSrcRegs = NormalizedVF / LegalVT.getVectorNumElements();
1876 unsigned NumOfDestRegs = NormalizedVF / LegalVT.getVectorNumElements();
1877 SmallVector<int> NormalizedMask(NormalizedVF, PoisonMaskElem);
1878 copy(Mask, NormalizedMask.begin());
1879 unsigned PrevSrcReg = 0;
1880 ArrayRef<int> PrevRegMask;
1883 NormalizedMask, NumOfSrcRegs, NumOfDestRegs, NumOfDestRegs, []() {},
1884 [this, SingleOpTy, CostKind, &PrevSrcReg, &PrevRegMask,
1885 &Cost](ArrayRef<int> RegMask, unsigned SrcReg, unsigned DestReg) {
1886 if (!ShuffleVectorInst::isIdentityMask(RegMask, RegMask.size())) {
1887 // Check if the previous register can be just copied to the next
1888 // one.
1889 if (PrevRegMask.empty() || PrevSrcReg != SrcReg ||
1890 PrevRegMask != RegMask)
1891 Cost +=
1893 SingleOpTy, RegMask, CostKind, 0, nullptr);
1894 else
1895 // Just a copy of previous destination register.
1897 return;
1898 }
1899 if (SrcReg != DestReg &&
1900 any_of(RegMask, not_equal_to(PoisonMaskElem))) {
1901 // Just a copy of the source register.
1903 }
1904 PrevSrcReg = SrcReg;
1905 PrevRegMask = RegMask;
1906 },
1907 [this, SingleOpTy, CostKind,
1908 &Cost](ArrayRef<int> RegMask, unsigned /*Unused*/,
1909 unsigned /*Unused*/, bool /*Unused*/) {
1911 SingleOpTy, RegMask, CostKind, 0, nullptr);
1912 });
1913 return Cost;
1914 }
1915
1916 InstructionCost NumOfShuffles = (NumOfSrcs - 1) * NumOfDests;
1917 return NumOfShuffles * getShuffleCost(TTI::SK_PermuteTwoSrc, SingleOpTy,
1918 SingleOpTy, {}, CostKind, 0,
1919 nullptr);
1920 }
1921
1922 return BaseT::getShuffleCost(Kind, DstTy, SrcTy, Mask, CostKind, Index,
1923 SubTp);
1924 }
1925
1926 // If we're just moving a single element around (probably as an alternative to
1927 // extracting it), we can assume this is cheap.
1928 if (LT.first == 1 && IsInLaneShuffle && IsSingleElementMask)
1929 return TTI::TCC_Basic;
1930
1931 static const CostKindTblEntry AVX512VBMIShuffleTbl[] = {
1932 { TTI::SK_Reverse, MVT::v64i8, { 1, 1, 1, 1 } }, // vpermb
1933 { TTI::SK_Reverse, MVT::v32i8, { 1, 1, 1, 1 } }, // vpermb
1934 { TTI::SK_PermuteSingleSrc, MVT::v64i8, { 1, 1, 1, 1 } }, // vpermb
1935 { TTI::SK_PermuteSingleSrc, MVT::v32i8, { 1, 1, 1, 1 } }, // vpermb
1936 { TTI::SK_PermuteTwoSrc, MVT::v64i8, { 2, 2, 2, 2 } }, // vpermt2b
1937 { TTI::SK_PermuteTwoSrc, MVT::v32i8, { 2, 2, 2, 2 } }, // vpermt2b
1938 { TTI::SK_PermuteTwoSrc, MVT::v16i8, { 2, 2, 2, 2 } } // vpermt2b
1939 };
1940
1941 if (ST->hasVBMI())
1942 if (const auto *Entry =
1943 CostTableLookup(AVX512VBMIShuffleTbl, Kind, LT.second))
1944 if (auto KindCost = Entry->Cost[CostKind])
1945 return LT.first * *KindCost;
1946
1947 static const CostKindTblEntry AVX512BWShuffleTbl[] = {
1948 { TTI::SK_Broadcast, MVT::v32i16, { 1, 3, 1, 1 } }, // vpbroadcastw
1949 { TTI::SK_Broadcast, MVT::v32f16, { 1, 3, 1, 1 } }, // vpbroadcastw
1950 { TTI::SK_Broadcast, MVT::v64i8, { 1, 3, 1, 1 } }, // vpbroadcastb
1951
1952 { TTI::SK_Reverse, MVT::v32i16, { 2, 6, 2, 4 } }, // vpermw
1953 { TTI::SK_Reverse, MVT::v32f16, { 2, 6, 2, 4 } }, // vpermw
1954 { TTI::SK_Reverse, MVT::v16i16, { 2, 2, 2, 2 } }, // vpermw
1955 { TTI::SK_Reverse, MVT::v16f16, { 2, 2, 2, 2 } }, // vpermw
1956 { TTI::SK_Reverse, MVT::v64i8, { 2, 9, 2, 3 } }, // pshufb + vshufi64x2
1957
1958 { TTI::SK_PermuteSingleSrc, MVT::v32i16, { 2, 2, 2, 2 } }, // vpermw
1959 { TTI::SK_PermuteSingleSrc, MVT::v32f16, { 2, 2, 2, 2 } }, // vpermw
1960 { TTI::SK_PermuteSingleSrc, MVT::v16i16, { 2, 2, 2, 2 } }, // vpermw
1961 { TTI::SK_PermuteSingleSrc, MVT::v16f16, { 2, 2, 2, 2 } }, // vpermw
1962 { TTI::SK_PermuteSingleSrc, MVT::v64i8, { 8, 8, 8, 8 } }, // extend to v32i16
1963
1964 { TTI::SK_PermuteTwoSrc, MVT::v32i16,{ 2, 2, 2, 2 } }, // vpermt2w
1965 { TTI::SK_PermuteTwoSrc, MVT::v32f16,{ 2, 2, 2, 2 } }, // vpermt2w
1966 { TTI::SK_PermuteTwoSrc, MVT::v16i16,{ 2, 2, 2, 2 } }, // vpermt2w
1967 { TTI::SK_PermuteTwoSrc, MVT::v8i16, { 2, 2, 2, 2 } }, // vpermt2w
1968 { TTI::SK_PermuteTwoSrc, MVT::v64i8, { 19, 19, 19, 19 } }, // 6 * v32i8 + 1
1969
1970 { TTI::SK_Select, MVT::v32i16, { 1, 1, 1, 1 } }, // vblendmw
1971 { TTI::SK_Select, MVT::v64i8, { 1, 1, 1, 1 } }, // vblendmb
1972
1973 { TTI::SK_Splice, MVT::v32i16, { 2, 2, 2, 2 } }, // vshufi64x2 + palignr
1974 { TTI::SK_Splice, MVT::v32f16, { 2, 2, 2, 2 } }, // vshufi64x2 + palignr
1975 { TTI::SK_Splice, MVT::v64i8, { 2, 2, 2, 2 } }, // vshufi64x2 + palignr
1976 };
1977
1978 if (ST->hasBWI())
1979 if (const auto *Entry =
1980 CostTableLookup(AVX512BWShuffleTbl, Kind, LT.second))
1981 if (auto KindCost = Entry->Cost[CostKind])
1982 return LT.first * *KindCost;
1983
1984 static const CostKindTblEntry AVX512InLaneShuffleTbl[] = {
1985 {TTI::SK_PermuteTwoSrc, MVT::v8f64, { 1, 3, 1, 1 } },
1986 {TTI::SK_PermuteTwoSrc, MVT::v16f32, { 1, 3, 1, 1 } },
1987 {TTI::SK_PermuteTwoSrc, MVT::v8i64, { 1, 3, 1, 1 } },
1988 {TTI::SK_PermuteTwoSrc, MVT::v16i32, { 1, 3, 1, 1 } },
1989 {TTI::SK_PermuteTwoSrc, MVT::v4f64, { 1, 3, 1, 1 } },
1990 {TTI::SK_PermuteTwoSrc, MVT::v8f32, { 1, 3, 1, 1 } },
1991 {TTI::SK_PermuteTwoSrc, MVT::v4i64, { 1, 3, 1, 1 } },
1992 {TTI::SK_PermuteTwoSrc, MVT::v8i32, { 1, 3, 1, 1 } },
1993 };
1994
1995 if (IsInLaneShuffle && ST->hasAVX512())
1996 if (const auto *Entry =
1997 CostTableLookup(AVX512InLaneShuffleTbl, Kind, LT.second))
1998 if (auto KindCost = Entry->Cost[CostKind])
1999 return LT.first * *KindCost;
2000
2001 static const CostKindTblEntry AVX512ShuffleTbl[] = {
2002 {TTI::SK_Broadcast, MVT::v8f64, { 1, 3, 1, 1 } }, // vbroadcastsd
2003 {TTI::SK_Broadcast, MVT::v4f64, { 1, 3, 1, 1 } }, // vbroadcastsd
2004 {TTI::SK_Broadcast, MVT::v16f32, { 1, 3, 1, 1 } }, // vbroadcastss
2005 {TTI::SK_Broadcast, MVT::v8f32, { 1, 3, 1, 1 } }, // vbroadcastss
2006 {TTI::SK_Broadcast, MVT::v8i64, { 1, 3, 1, 1 } }, // vpbroadcastq
2007 {TTI::SK_Broadcast, MVT::v4i64, { 1, 3, 1, 1 } }, // vpbroadcastq
2008 {TTI::SK_Broadcast, MVT::v16i32, { 1, 3, 1, 1 } }, // vpbroadcastd
2009 {TTI::SK_Broadcast, MVT::v8i32, { 1, 3, 1, 1 } }, // vpbroadcastd
2010 {TTI::SK_Broadcast, MVT::v32i16, { 1, 3, 1, 1 } }, // vpbroadcastw
2011 {TTI::SK_Broadcast, MVT::v16i16, { 1, 3, 1, 1 } }, // vpbroadcastw
2012 {TTI::SK_Broadcast, MVT::v32f16, { 1, 3, 1, 1 } }, // vpbroadcastw
2013 {TTI::SK_Broadcast, MVT::v16f16, { 1, 3, 1, 1 } }, // vpbroadcastw
2014 {TTI::SK_Broadcast, MVT::v64i8, { 1, 3, 1, 1 } }, // vpbroadcastb
2015 {TTI::SK_Broadcast, MVT::v32i8, { 1, 3, 1, 1 }}, // vpbroadcastb
2016
2017 {TTI::SK_Reverse, MVT::v8f64, { 1, 5, 2, 3 } }, // vpermpd
2018 {TTI::SK_Reverse, MVT::v16f32, { 1, 3, 2, 3 } }, // vpermps
2019 {TTI::SK_Reverse, MVT::v8i64, { 1, 5, 2, 3 } }, // vpermq
2020 {TTI::SK_Reverse, MVT::v16i32, { 1, 3, 2, 3 } }, // vpermd
2021 {TTI::SK_Reverse, MVT::v32i16, { 7, 7, 7, 7 } }, // per mca
2022 {TTI::SK_Reverse, MVT::v32f16, { 7, 7, 7, 7 } }, // per mca
2023 {TTI::SK_Reverse, MVT::v64i8, { 7, 7, 7, 7 } }, // per mca
2024
2025 {TTI::SK_Splice, MVT::v8f64, { 1, 1, 1, 1 } }, // vpalignd
2026 {TTI::SK_Splice, MVT::v4f64, { 1, 1, 1, 1 } }, // vpalignd
2027 {TTI::SK_Splice, MVT::v16f32, { 1, 1, 1, 1 } }, // vpalignd
2028 {TTI::SK_Splice, MVT::v8f32, { 1, 1, 1, 1 } }, // vpalignd
2029 {TTI::SK_Splice, MVT::v8i64, { 1, 1, 1, 1 } }, // vpalignd
2030 {TTI::SK_Splice, MVT::v4i64, { 1, 1, 1, 1 } }, // vpalignd
2031 {TTI::SK_Splice, MVT::v16i32, { 1, 1, 1, 1 } }, // vpalignd
2032 {TTI::SK_Splice, MVT::v8i32, { 1, 1, 1, 1 } }, // vpalignd
2033 {TTI::SK_Splice, MVT::v32i16, { 4, 4, 4, 4 } }, // split + palignr
2034 {TTI::SK_Splice, MVT::v32f16, { 4, 4, 4, 4 } }, // split + palignr
2035 {TTI::SK_Splice, MVT::v64i8, { 4, 4, 4, 4 } }, // split + palignr
2036
2037 {TTI::SK_PermuteSingleSrc, MVT::v8f64, { 1, 3, 1, 1 } }, // vpermpd
2038 {TTI::SK_PermuteSingleSrc, MVT::v4f64, { 1, 3, 1, 1 } }, // vpermpd
2039 {TTI::SK_PermuteSingleSrc, MVT::v2f64, { 1, 3, 1, 1 } }, // vpermpd
2040 {TTI::SK_PermuteSingleSrc, MVT::v16f32, { 1, 3, 1, 1 } }, // vpermps
2041 {TTI::SK_PermuteSingleSrc, MVT::v8f32, { 1, 3, 1, 1 } }, // vpermps
2042 {TTI::SK_PermuteSingleSrc, MVT::v4f32, { 1, 3, 1, 1 } }, // vpermps
2043 {TTI::SK_PermuteSingleSrc, MVT::v8i64, { 1, 3, 1, 1 } }, // vpermq
2044 {TTI::SK_PermuteSingleSrc, MVT::v4i64, { 1, 3, 1, 1 } }, // vpermq
2045 {TTI::SK_PermuteSingleSrc, MVT::v2i64, { 1, 3, 1, 1 } }, // vpermq
2046 {TTI::SK_PermuteSingleSrc, MVT::v16i32, { 1, 3, 1, 1 } }, // vpermd
2047 {TTI::SK_PermuteSingleSrc, MVT::v8i32, { 1, 3, 1, 1 } }, // vpermd
2048 {TTI::SK_PermuteSingleSrc, MVT::v4i32, { 1, 3, 1, 1 } }, // vpermd
2049 {TTI::SK_PermuteSingleSrc, MVT::v16i8, { 1, 3, 1, 1 } }, // pshufb
2050
2051 {TTI::SK_PermuteTwoSrc, MVT::v8f64, { 2, 3, 1, 1 } }, // vpermt2pd
2052 {TTI::SK_PermuteTwoSrc, MVT::v16f32, { 2, 3, 1, 1 } }, // vpermt2ps
2053 {TTI::SK_PermuteTwoSrc, MVT::v8i64, { 2, 3, 1, 1 } }, // vpermt2q
2054 {TTI::SK_PermuteTwoSrc, MVT::v16i32, { 2, 3, 1, 1 } }, // vpermt2d
2055 {TTI::SK_PermuteTwoSrc, MVT::v4f64, { 2, 3, 1, 1 } }, // vpermt2pd
2056 {TTI::SK_PermuteTwoSrc, MVT::v8f32, { 2, 3, 1, 1 } }, // vpermt2ps
2057 {TTI::SK_PermuteTwoSrc, MVT::v4i64, { 2, 3, 1, 1 } }, // vpermt2q
2058 {TTI::SK_PermuteTwoSrc, MVT::v8i32, { 2, 3, 1, 1 } }, // vpermt2d
2059 {TTI::SK_PermuteTwoSrc, MVT::v2f64, { 1, 3, 1, 1 } },
2060 {TTI::SK_PermuteTwoSrc, MVT::v4f32, { 1, 3, 1, 1 } },
2061 {TTI::SK_PermuteTwoSrc, MVT::v2i64, { 1, 3, 1, 1 } },
2062 {TTI::SK_PermuteTwoSrc, MVT::v4i32, { 1, 3, 1, 1 } },
2063
2064 // FIXME: This just applies the type legalization cost rules above
2065 // assuming these completely split.
2066 {TTI::SK_PermuteSingleSrc, MVT::v32i16, { 14, 14, 14, 14 } },
2067 {TTI::SK_PermuteSingleSrc, MVT::v32f16, { 14, 14, 14, 14 } },
2068 {TTI::SK_PermuteSingleSrc, MVT::v64i8, { 14, 14, 14, 14 } },
2069 {TTI::SK_PermuteTwoSrc, MVT::v32i16, { 42, 42, 42, 42 } },
2070 {TTI::SK_PermuteTwoSrc, MVT::v32f16, { 42, 42, 42, 42 } },
2071 {TTI::SK_PermuteTwoSrc, MVT::v64i8, { 42, 42, 42, 42 } },
2072
2073 {TTI::SK_Select, MVT::v32i16, { 1, 1, 1, 1 } }, // vpternlogq
2074 {TTI::SK_Select, MVT::v32f16, { 1, 1, 1, 1 } }, // vpternlogq
2075 {TTI::SK_Select, MVT::v64i8, { 1, 1, 1, 1 } }, // vpternlogq
2076 {TTI::SK_Select, MVT::v8f64, { 1, 1, 1, 1 } }, // vblendmpd
2077 {TTI::SK_Select, MVT::v16f32, { 1, 1, 1, 1 } }, // vblendmps
2078 {TTI::SK_Select, MVT::v8i64, { 1, 1, 1, 1 } }, // vblendmq
2079 {TTI::SK_Select, MVT::v16i32, { 1, 1, 1, 1 } }, // vblendmd
2080 };
2081
2082 if (ST->hasAVX512())
2083 if (const auto *Entry = CostTableLookup(AVX512ShuffleTbl, Kind, LT.second))
2084 if (auto KindCost = Entry->Cost[CostKind])
2085 return LT.first * *KindCost;
2086
2087 static const CostKindTblEntry AVX2InLaneShuffleTbl[] = {
2088 { TTI::SK_PermuteSingleSrc, MVT::v16i16, { 1, 1, 1, 1 } }, // vpshufb
2089 { TTI::SK_PermuteSingleSrc, MVT::v16f16, { 1, 1, 1, 1 } }, // vpshufb
2090 { TTI::SK_PermuteSingleSrc, MVT::v32i8, { 1, 1, 1, 1 } }, // vpshufb
2091
2092 { TTI::SK_Transpose, MVT::v4f64, { 1, 1, 1, 1 } }, // vshufpd/vunpck
2093 { TTI::SK_Transpose, MVT::v4i64, { 1, 1, 1, 1 } }, // vshufpd/vunpck
2094
2095 { TTI::SK_PermuteTwoSrc, MVT::v4f64, { 2, 2, 2, 2 } }, // 2*vshufpd + vblendpd
2096 { TTI::SK_PermuteTwoSrc, MVT::v8f32, { 2, 2, 2, 2 } }, // 2*vshufps + vblendps
2097 { TTI::SK_PermuteTwoSrc, MVT::v4i64, { 2, 2, 2, 2 } }, // 2*vpshufd + vpblendd
2098 { TTI::SK_PermuteTwoSrc, MVT::v8i32, { 2, 2, 2, 2 } }, // 2*vpshufd + vpblendd
2099 { TTI::SK_PermuteTwoSrc, MVT::v16i16, { 2, 2, 2, 2 } }, // 2*vpshufb + vpor
2100 { TTI::SK_PermuteTwoSrc, MVT::v16f16, { 2, 2, 2, 2 } }, // 2*vpshufb + vpor
2101 { TTI::SK_PermuteTwoSrc, MVT::v32i8, { 2, 2, 2, 2 } }, // 2*vpshufb + vpor
2102 };
2103
2104 if (IsInLaneShuffle && ST->hasAVX2())
2105 if (const auto *Entry =
2106 CostTableLookup(AVX2InLaneShuffleTbl, Kind, LT.second))
2107 if (auto KindCost = Entry->Cost[CostKind])
2108 return LT.first * *KindCost;
2109
2110 static const CostKindTblEntry AVX2ShuffleTbl[] = {
2111 { TTI::SK_Broadcast, MVT::v4f64, { 1, 3, 1, 2 } }, // vbroadcastpd
2112 { TTI::SK_Broadcast, MVT::v8f32, { 1, 3, 1, 2 } }, // vbroadcastps
2113 { TTI::SK_Broadcast, MVT::v4i64, { 1, 3, 1, 2 } }, // vpbroadcastq
2114 { TTI::SK_Broadcast, MVT::v8i32, { 1, 3, 1, 2 } }, // vpbroadcastd
2115 { TTI::SK_Broadcast, MVT::v16i16, { 1, 3, 1, 2 } }, // vpbroadcastw
2116 { TTI::SK_Broadcast, MVT::v8i16, { 1, 3, 1, 1 } }, // vpbroadcastw
2117 { TTI::SK_Broadcast, MVT::v16f16, { 1, 3, 1, 2 } }, // vpbroadcastw
2118 { TTI::SK_Broadcast, MVT::v8f16, { 1, 3, 1, 1 } }, // vpbroadcastw
2119 { TTI::SK_Broadcast, MVT::v32i8, { 1, 3, 1, 2 } }, // vpbroadcastb
2120 { TTI::SK_Broadcast, MVT::v16i8, { 1, 3, 1, 1 } }, // vpbroadcastb
2121
2122 { TTI::SK_Reverse, MVT::v4f64, { 1, 6, 1, 2 } }, // vpermpd
2123 { TTI::SK_Reverse, MVT::v8f32, { 2, 7, 2, 4 } }, // vpermps
2124 { TTI::SK_Reverse, MVT::v4i64, { 1, 6, 1, 2 } }, // vpermq
2125 { TTI::SK_Reverse, MVT::v8i32, { 2, 7, 2, 4 } }, // vpermd
2126 { TTI::SK_Reverse, MVT::v16i16, { 2, 9, 2, 4 } }, // vperm2i128 + pshufb
2127 { TTI::SK_Reverse, MVT::v16f16, { 2, 9, 2, 4 } }, // vperm2i128 + pshufb
2128 { TTI::SK_Reverse, MVT::v32i8, { 2, 9, 2, 4 } }, // vperm2i128 + pshufb
2129
2130 { TTI::SK_Select, MVT::v16i16, { 1, 1, 1, 1 } }, // vpblendvb
2131 { TTI::SK_Select, MVT::v16f16, { 1, 1, 1, 1 } }, // vpblendvb
2132 { TTI::SK_Select, MVT::v32i8, { 1, 1, 1, 1 } }, // vpblendvb
2133
2134 { TTI::SK_Splice, MVT::v8i32, { 2, 2, 2, 2 } }, // vperm2i128 + vpalignr
2135 { TTI::SK_Splice, MVT::v8f32, { 2, 2, 2, 2 } }, // vperm2i128 + vpalignr
2136 { TTI::SK_Splice, MVT::v16i16, { 2, 2, 2, 2 } }, // vperm2i128 + vpalignr
2137 { TTI::SK_Splice, MVT::v16f16, { 2, 2, 2, 2 } }, // vperm2i128 + vpalignr
2138 { TTI::SK_Splice, MVT::v32i8, { 2, 2, 2, 2 } }, // vperm2i128 + vpalignr
2139
2140 { TTI::SK_PermuteSingleSrc, MVT::v4f64, { 1, 1, 1, 1 } }, // vpermpd
2141 { TTI::SK_PermuteSingleSrc, MVT::v8f32, { 1, 1, 1, 1 } }, // vpermps
2142 { TTI::SK_PermuteSingleSrc, MVT::v4i64, { 1, 1, 1, 1 } }, // vpermq
2143 { TTI::SK_PermuteSingleSrc, MVT::v8i32, { 1, 1, 1, 1 } }, // vpermd
2144 { TTI::SK_PermuteSingleSrc, MVT::v16i16, { 4, 4, 4, 4 } },
2145 { TTI::SK_PermuteSingleSrc, MVT::v16f16, { 4, 4, 4, 4 } },
2146 { TTI::SK_PermuteSingleSrc, MVT::v32i8, { 4, 4, 4, 4 } },
2147
2148 { TTI::SK_PermuteTwoSrc, MVT::v4f64, { 3, 3, 3, 3 } }, // 2*vpermpd + vblendpd
2149 { TTI::SK_PermuteTwoSrc, MVT::v8f32, { 3, 3, 3, 3 } }, // 2*vpermps + vblendps
2150 { TTI::SK_PermuteTwoSrc, MVT::v4i64, { 3, 3, 3, 3 } }, // 2*vpermq + vpblendd
2151 { TTI::SK_PermuteTwoSrc, MVT::v8i32, { 3, 3, 3, 3 } }, // 2*vpermd + vpblendd
2152 { TTI::SK_PermuteTwoSrc, MVT::v16i16, { 7, 7, 7, 7 } },
2153 { TTI::SK_PermuteTwoSrc, MVT::v16f16, { 7, 7, 7, 7 } },
2154 { TTI::SK_PermuteTwoSrc, MVT::v32i8, { 7, 7, 7, 7 } },
2155 };
2156
2157 if (ST->hasAVX2())
2158 if (const auto *Entry = CostTableLookup(AVX2ShuffleTbl, Kind, LT.second))
2159 if (auto KindCost = Entry->Cost[CostKind])
2160 return LT.first * *KindCost;
2161
2162 static const CostKindTblEntry XOPShuffleTbl[] = {
2163 { TTI::SK_PermuteSingleSrc, MVT::v4f64, { 2, 2, 2, 2 } }, // vperm2f128 + vpermil2pd
2164 { TTI::SK_PermuteSingleSrc, MVT::v8f32, { 2, 2, 2, 2 } }, // vperm2f128 + vpermil2ps
2165 { TTI::SK_PermuteSingleSrc, MVT::v4i64, { 2, 2, 2, 2 } }, // vperm2f128 + vpermil2pd
2166 { TTI::SK_PermuteSingleSrc, MVT::v8i32, { 2, 2, 2, 2 } }, // vperm2f128 + vpermil2ps
2167 { TTI::SK_PermuteSingleSrc, MVT::v16i16,{ 4, 4, 4, 4 } }, // vextractf128 + 2*vpperm
2168 // + vinsertf128
2169 { TTI::SK_PermuteSingleSrc, MVT::v32i8, { 4, 4, 4, 4 } }, // vextractf128 + 2*vpperm
2170 // + vinsertf128
2171
2172 { TTI::SK_PermuteTwoSrc, MVT::v16i16, { 9, 9, 9, 9 } }, // 2*vextractf128 + 6*vpperm
2173 // + vinsertf128
2174
2175 { TTI::SK_PermuteTwoSrc, MVT::v8i16, { 1, 1, 1, 1 } }, // vpperm
2176 { TTI::SK_PermuteTwoSrc, MVT::v32i8, { 9, 9, 9, 9 } }, // 2*vextractf128 + 6*vpperm
2177 // + vinsertf128
2178 { TTI::SK_PermuteTwoSrc, MVT::v16i8, { 1, 1, 1, 1 } }, // vpperm
2179 };
2180
2181 if (ST->hasXOP())
2182 if (const auto *Entry = CostTableLookup(XOPShuffleTbl, Kind, LT.second))
2183 if (auto KindCost = Entry->Cost[CostKind])
2184 return LT.first * *KindCost;
2185
2186 static const CostKindTblEntry AVX1InLaneShuffleTbl[] = {
2187 { TTI::SK_PermuteSingleSrc, MVT::v4f64, { 1, 1, 1, 1 } }, // vpermilpd
2188 { TTI::SK_PermuteSingleSrc, MVT::v4i64, { 1, 1, 1, 1 } }, // vpermilpd
2189 { TTI::SK_PermuteSingleSrc, MVT::v8f32, { 1, 1, 1, 1 } }, // vpermilps
2190 { TTI::SK_PermuteSingleSrc, MVT::v8i32, { 1, 1, 1, 1 } }, // vpermilps
2191
2192 { TTI::SK_PermuteSingleSrc, MVT::v16i16, { 4, 4, 4, 4 } }, // vextractf128 + 2*pshufb
2193 // + vpor + vinsertf128
2194 { TTI::SK_PermuteSingleSrc, MVT::v16f16, { 4, 4, 4, 4 } }, // vextractf128 + 2*pshufb
2195 // + vpor + vinsertf128
2196 { TTI::SK_PermuteSingleSrc, MVT::v32i8, { 4, 4, 4, 4 } }, // vextractf128 + 2*pshufb
2197 // + vpor + vinsertf128
2198
2199 { TTI::SK_Transpose, MVT::v4f64, { 1, 1, 1, 1 } }, // vshufpd/vunpck
2200 { TTI::SK_Transpose, MVT::v4i64, { 1, 1, 1, 1 } }, // vshufpd/vunpck
2201
2202 { TTI::SK_PermuteTwoSrc, MVT::v4f64, { 2, 2, 2, 2 } }, // 2*vshufpd + vblendpd
2203 { TTI::SK_PermuteTwoSrc, MVT::v8f32, { 2, 2, 2, 2 } }, // 2*vshufps + vblendps
2204 { TTI::SK_PermuteTwoSrc, MVT::v4i64, { 2, 2, 2, 2 } }, // 2*vpermilpd + vblendpd
2205 { TTI::SK_PermuteTwoSrc, MVT::v8i32, { 2, 2, 2, 2 } }, // 2*vpermilps + vblendps
2206 { TTI::SK_PermuteTwoSrc, MVT::v16i16, { 9, 9, 9, 9 } }, // 2*vextractf128 + 4*pshufb
2207 // + 2*vpor + vinsertf128
2208 { TTI::SK_PermuteTwoSrc, MVT::v16f16, { 9, 9, 9, 9 } }, // 2*vextractf128 + 4*pshufb
2209 // + 2*vpor + vinsertf128
2210 { TTI::SK_PermuteTwoSrc, MVT::v32i8, { 9, 9, 9, 9 } }, // 2*vextractf128 + 4*pshufb
2211 // + 2*vpor + vinsertf128
2212 };
2213
2214 if (IsInLaneShuffle && ST->hasAVX())
2215 if (const auto *Entry =
2216 CostTableLookup(AVX1InLaneShuffleTbl, Kind, LT.second))
2217 if (auto KindCost = Entry->Cost[CostKind])
2218 return LT.first * *KindCost;
2219
2220 static const CostKindTblEntry AVX1ShuffleTbl[] = {
2221 {TTI::SK_Broadcast, MVT::v4f64, {2,3,2,3}}, // vperm2f128 + vpermilpd
2222 {TTI::SK_Broadcast, MVT::v8f32, {2,3,2,3}}, // vperm2f128 + vpermilps
2223 {TTI::SK_Broadcast, MVT::v4i64, {2,3,2,3}}, // vperm2f128 + vpermilpd
2224 {TTI::SK_Broadcast, MVT::v8i32, {2,3,2,3}}, // vperm2f128 + vpermilps
2225 {TTI::SK_Broadcast, MVT::v16i16, {2,3,3,4}}, // vpshuflw + vpshufd + vinsertf128
2226 {TTI::SK_Broadcast, MVT::v16f16, {2,3,3,4}}, // vpshuflw + vpshufd + vinsertf128
2227 {TTI::SK_Broadcast, MVT::v32i8, {3,4,3,6}}, // vpshufb + vinsertf128
2228
2229 {TTI::SK_Reverse, MVT::v4f64, {2,6,2,2}}, // vperm2f128 + vpermilpd
2230 {TTI::SK_Reverse, MVT::v8f32, {2,7,2,4}}, // vperm2f128 + vpermilps
2231 {TTI::SK_Reverse, MVT::v4i64, {2,6,2,2}}, // vperm2f128 + vpermilpd
2232 {TTI::SK_Reverse, MVT::v8i32, {2,7,2,4}}, // vperm2f128 + vpermilps
2233 {TTI::SK_Reverse, MVT::v16i16, {2,9,5,5}}, // vextractf128 + 2*pshufb
2234 // + vinsertf128
2235 {TTI::SK_Reverse, MVT::v16f16, {2,9,5,5}}, // vextractf128 + 2*pshufb
2236 // + vinsertf128
2237 {TTI::SK_Reverse, MVT::v32i8, {2,9,5,5}}, // vextractf128 + 2*pshufb
2238 // + vinsertf128
2239
2240 {TTI::SK_Select, MVT::v4i64, {1,1,1,1}}, // vblendpd
2241 {TTI::SK_Select, MVT::v4f64, {1,1,1,1}}, // vblendpd
2242 {TTI::SK_Select, MVT::v8i32, {1,1,1,1}}, // vblendps
2243 {TTI::SK_Select, MVT::v8f32, {1,1,1,1}}, // vblendps
2244 {TTI::SK_Select, MVT::v16i16, {3,3,3,3}}, // vpand + vpandn + vpor
2245 {TTI::SK_Select, MVT::v16f16, {3,3,3,3}}, // vpand + vpandn + vpor
2246 {TTI::SK_Select, MVT::v32i8, {3,3,3,3}}, // vpand + vpandn + vpor
2247
2248 {TTI::SK_Splice, MVT::v4i64, {2,2,2,2}}, // vperm2f128 + shufpd
2249 {TTI::SK_Splice, MVT::v4f64, {2,2,2,2}}, // vperm2f128 + shufpd
2250 {TTI::SK_Splice, MVT::v8i32, {4,4,4,4}}, // 2*vperm2f128 + 2*vshufps
2251 {TTI::SK_Splice, MVT::v8f32, {4,4,4,4}}, // 2*vperm2f128 + 2*vshufps
2252 {TTI::SK_Splice, MVT::v16i16, {5,5,5,5}}, // 2*vperm2f128 + 2*vpalignr + vinsertf128
2253 {TTI::SK_Splice, MVT::v16f16, {5,5,5,5}}, // 2*vperm2f128 + 2*vpalignr + vinsertf128
2254 {TTI::SK_Splice, MVT::v32i8, {5,5,5,5}}, // 2*vperm2f128 + 2*vpalignr + vinsertf128
2255
2256 {TTI::SK_PermuteSingleSrc, MVT::v4f64, {2,2,2,2}}, // vperm2f128 + vshufpd
2257 {TTI::SK_PermuteSingleSrc, MVT::v4i64, {2,2,2,2}}, // vperm2f128 + vshufpd
2258 {TTI::SK_PermuteSingleSrc, MVT::v8f32, {4,4,4,4}}, // 2*vperm2f128 + 2*vshufps
2259 {TTI::SK_PermuteSingleSrc, MVT::v8i32, {4,4,4,4}}, // 2*vperm2f128 + 2*vshufps
2260 {TTI::SK_PermuteSingleSrc, MVT::v16i16,{8,8,8,8}}, // vextractf128 + 4*pshufb
2261 // + 2*por + vinsertf128
2262 {TTI::SK_PermuteSingleSrc, MVT::v16f16,{8,8,8,8}}, // vextractf128 + 4*pshufb
2263 // + 2*por + vinsertf128
2264 {TTI::SK_PermuteSingleSrc, MVT::v32i8, {8,8,8,8}}, // vextractf128 + 4*pshufb
2265 // + 2*por + vinsertf128
2266
2267 {TTI::SK_PermuteTwoSrc, MVT::v4f64, {3,3,3,3}}, // 2*vperm2f128 + vshufpd
2268 {TTI::SK_PermuteTwoSrc, MVT::v4i64, {3,3,3,3}}, // 2*vperm2f128 + vshufpd
2269 {TTI::SK_PermuteTwoSrc, MVT::v8f32, {4,4,4,4}}, // 2*vperm2f128 + 2*vshufps
2270 {TTI::SK_PermuteTwoSrc, MVT::v8i32, {4,4,4,4}}, // 2*vperm2f128 + 2*vshufps
2271 {TTI::SK_PermuteTwoSrc, MVT::v16i16,{15,15,15,15}}, // 2*vextractf128 + 8*pshufb
2272 // + 4*por + vinsertf128
2273 {TTI::SK_PermuteTwoSrc, MVT::v16f16,{15,15,15,15}}, // 2*vextractf128 + 8*pshufb
2274 // + 4*por + vinsertf128
2275 {TTI::SK_PermuteTwoSrc, MVT::v32i8, {15,15,15,15}}, // 2*vextractf128 + 8*pshufb
2276 // + 4*por + vinsertf128
2277 };
2278
2279 if (ST->hasAVX())
2280 if (const auto *Entry = CostTableLookup(AVX1ShuffleTbl, Kind, LT.second))
2281 if (auto KindCost = Entry->Cost[CostKind])
2282 return LT.first * *KindCost;
2283
2284 static const CostKindTblEntry SSE41ShuffleTbl[] = {
2285 {TTI::SK_Select, MVT::v2i64, {1,1,1,1}}, // pblendw
2286 {TTI::SK_Select, MVT::v2f64, {1,1,1,1}}, // movsd
2287 {TTI::SK_Select, MVT::v4i32, {1,1,1,1}}, // pblendw
2288 {TTI::SK_Select, MVT::v4f32, {1,1,1,1}}, // blendps
2289 {TTI::SK_Select, MVT::v8i16, {1,1,1,1}}, // pblendw
2290 {TTI::SK_Select, MVT::v8f16, {1,1,1,1}}, // pblendw
2291 {TTI::SK_Select, MVT::v16i8, {1,1,1,1}} // pblendvb
2292 };
2293
2294 if (ST->hasSSE41())
2295 if (const auto *Entry = CostTableLookup(SSE41ShuffleTbl, Kind, LT.second))
2296 if (auto KindCost = Entry->Cost[CostKind])
2297 return LT.first * *KindCost;
2298
2299 static const CostKindTblEntry SSSE3ShuffleTbl[] = {
2300 {TTI::SK_Broadcast, MVT::v8i16, {1, 3, 2, 2}}, // pshufb
2301 {TTI::SK_Broadcast, MVT::v8f16, {1, 3, 2, 2}}, // pshufb
2302 {TTI::SK_Broadcast, MVT::v16i8, {1, 3, 2, 2}}, // pshufb
2303
2304 {TTI::SK_Reverse, MVT::v8i16, {1, 2, 1, 2}}, // pshufb
2305 {TTI::SK_Reverse, MVT::v8f16, {1, 2, 1, 2}}, // pshufb
2306 {TTI::SK_Reverse, MVT::v16i8, {1, 2, 1, 2}}, // pshufb
2307
2308 {TTI::SK_Splice, MVT::v4i32, {1, 1, 1, 1}}, // palignr
2309 {TTI::SK_Splice, MVT::v4f32, {1, 1, 1, 1}}, // palignr
2310 {TTI::SK_Splice, MVT::v8i16, {1, 1, 1, 1}}, // palignr
2311 {TTI::SK_Splice, MVT::v8f16, {1, 1, 1, 1}}, // palignr
2312 {TTI::SK_Splice, MVT::v16i8, {1, 1, 1, 1}}, // palignr
2313
2314 {TTI::SK_PermuteSingleSrc, MVT::v8i16, {1, 1, 1, 1}}, // pshufb
2315 {TTI::SK_PermuteSingleSrc, MVT::v8f16, {1, 1, 1, 1}}, // pshufb
2316 {TTI::SK_PermuteSingleSrc, MVT::v16i8, {1, 1, 1, 1}}, // pshufb
2317
2318 {TTI::SK_PermuteTwoSrc, MVT::v8i16, {3, 3, 3, 3}}, // 2*pshufb + por
2319 {TTI::SK_PermuteTwoSrc, MVT::v8f16, {3, 3, 3, 3}}, // 2*pshufb + por
2320 {TTI::SK_PermuteTwoSrc, MVT::v16i8, {3, 3, 3, 3}}, // 2*pshufb + por
2321 };
2322
2323 if (ST->hasSSSE3())
2324 if (const auto *Entry = CostTableLookup(SSSE3ShuffleTbl, Kind, LT.second))
2325 if (auto KindCost = Entry->Cost[CostKind])
2326 return LT.first * *KindCost;
2327
2328 static const CostKindTblEntry SSE2ShuffleTbl[] = {
2329 {TTI::SK_Broadcast, MVT::v2f64, {1, 1, 1, 1}}, // shufpd
2330 {TTI::SK_Broadcast, MVT::v2i64, {1, 1, 1, 1}}, // pshufd
2331 {TTI::SK_Broadcast, MVT::v4i32, {1, 1, 1, 1}}, // pshufd
2332 {TTI::SK_Broadcast, MVT::v8i16, {1, 2, 2, 2}}, // pshuflw + pshufd
2333 {TTI::SK_Broadcast, MVT::v8f16, {1, 2, 2, 2}}, // pshuflw + pshufd
2334 {TTI::SK_Broadcast, MVT::v16i8, {2, 3, 3, 4}}, // unpck + pshuflw + pshufd
2335
2336 {TTI::SK_Reverse, MVT::v2f64, {1, 1, 1, 1}}, // shufpd
2337 {TTI::SK_Reverse, MVT::v2i64, {1, 1, 1, 1}}, // pshufd
2338 {TTI::SK_Reverse, MVT::v4i32, {1, 1, 1, 1}}, // pshufd
2339 {TTI::SK_Reverse, MVT::v8i16, {2, 3, 3, 3}}, // pshuflw + pshufhw + pshufd
2340 {TTI::SK_Reverse, MVT::v8f16, {2, 3, 3, 3}}, // pshuflw + pshufhw + pshufd
2341 {TTI::SK_Reverse, MVT::v16i8, {5, 6,11,11}}, // 2*pshuflw + 2*pshufhw
2342 // + 2*pshufd + 2*unpck + packus
2343
2344 {TTI::SK_Select, MVT::v2i64, {1, 1, 1, 1}}, // movsd
2345 {TTI::SK_Select, MVT::v2f64, {1, 1, 1, 1}}, // movsd
2346 {TTI::SK_Select, MVT::v4i32, {2, 2, 2, 2}}, // 2*shufps
2347 {TTI::SK_Select, MVT::v8i16, {2, 2, 3, 3}}, // pand + pandn + por
2348 {TTI::SK_Select, MVT::v8f16, {2, 2, 3, 3}}, // pand + pandn + por
2349 {TTI::SK_Select, MVT::v16i8, {2, 2, 3, 3}}, // pand + pandn + por
2350
2351 {TTI::SK_Splice, MVT::v2i64, {1, 1, 1, 1}}, // shufpd
2352 {TTI::SK_Splice, MVT::v2f64, {1, 1, 1, 1}}, // shufpd
2353 {TTI::SK_Splice, MVT::v4i32, {2, 2, 2, 2}}, // 2*{unpck,movsd,pshufd}
2354 {TTI::SK_Splice, MVT::v8i16, {3, 3, 3, 3}}, // psrldq + psrlldq + por
2355 {TTI::SK_Splice, MVT::v8f16, {3, 3, 3, 3}}, // psrldq + psrlldq + por
2356 {TTI::SK_Splice, MVT::v16i8, {3, 3, 3, 3}}, // psrldq + psrlldq + por
2357
2358 {TTI::SK_PermuteSingleSrc, MVT::v2f64, {1, 1, 1, 1}}, // shufpd
2359 {TTI::SK_PermuteSingleSrc, MVT::v2i64, {1, 1, 1, 1}}, // pshufd
2360 {TTI::SK_PermuteSingleSrc, MVT::v4i32, {1, 1, 1, 1}}, // pshufd
2361 {TTI::SK_PermuteSingleSrc, MVT::v8i16, {3, 5, 5, 5}}, // 2*pshuflw + 2*pshufhw
2362 // + pshufd/unpck
2363 {TTI::SK_PermuteSingleSrc, MVT::v8f16, {3, 5, 5, 5}}, // 2*pshuflw + 2*pshufhw
2364 // + pshufd/unpck
2365 {TTI::SK_PermuteSingleSrc, MVT::v16i8, {8, 10, 10, 10}}, // 2*pshuflw + 2*pshufhw
2366 // + 2*pshufd + 2*unpck + 2*packus
2367
2368 {TTI::SK_PermuteTwoSrc, MVT::v2f64, {1, 1, 1, 1}}, // shufpd
2369 {TTI::SK_PermuteTwoSrc, MVT::v2i64, {1, 1, 1, 1}}, // shufpd
2370 {TTI::SK_PermuteTwoSrc, MVT::v4i32, {2, 2, 2, 2}}, // 2*{unpck,movsd,pshufd}
2371 {TTI::SK_PermuteTwoSrc, MVT::v8i16, {6, 8, 8, 8}}, // blend+permute
2372 {TTI::SK_PermuteTwoSrc, MVT::v8f16, {6, 8, 8, 8}}, // blend+permute
2373 {TTI::SK_PermuteTwoSrc, MVT::v16i8, {11, 13, 13, 13}}, // blend+permute
2374 };
2375
2376 static const CostTblEntry SSE3BroadcastLoadTbl[] = {
2377 {TTI::SK_Broadcast, MVT::v2f64, 0}, // broadcast handled by movddup
2378 };
2379
2380 if (ST->hasSSE2()) {
2381 bool IsLoad =
2382 llvm::any_of(Args, [](const auto &V) { return isa<LoadInst>(V); });
2383 if (ST->hasSSE3() && IsLoad)
2384 if (const auto *Entry =
2385 CostTableLookup(SSE3BroadcastLoadTbl, Kind, LT.second)) {
2386 assert(isLegalBroadcastLoad(SrcTy->getElementType(),
2387 LT.second.getVectorElementCount()) &&
2388 "Table entry missing from isLegalBroadcastLoad()");
2389 return LT.first * Entry->Cost;
2390 }
2391
2392 if (const auto *Entry = CostTableLookup(SSE2ShuffleTbl, Kind, LT.second))
2393 if (auto KindCost = Entry->Cost[CostKind])
2394 return LT.first * *KindCost;
2395 }
2396
2397 static const CostKindTblEntry SSE1ShuffleTbl[] = {
2398 { TTI::SK_Broadcast, MVT::v4f32, {1,1,1,1} }, // shufps
2399 { TTI::SK_Reverse, MVT::v4f32, {1,1,1,1} }, // shufps
2400 { TTI::SK_Select, MVT::v4f32, {2,2,2,2} }, // 2*shufps
2401 { TTI::SK_Splice, MVT::v4f32, {2,2,2,2} }, // 2*shufps
2402 { TTI::SK_PermuteSingleSrc, MVT::v4f32, {1,1,1,1} }, // shufps
2403 { TTI::SK_PermuteTwoSrc, MVT::v4f32, {2,2,2,2} }, // 2*shufps
2404 };
2405
2406 if (ST->hasSSE1()) {
2407 if (LT.first == 1 && LT.second == MVT::v4f32 && Mask.size() == 4) {
2408 // SHUFPS: both pairs must come from the same source register.
2409 auto MatchSHUFPS = [](int X, int Y) {
2410 return X < 0 || Y < 0 || ((X & 4) == (Y & 4));
2411 };
2412 if (MatchSHUFPS(Mask[0], Mask[1]) && MatchSHUFPS(Mask[2], Mask[3]))
2413 return 1;
2414 }
2415 if (const auto *Entry = CostTableLookup(SSE1ShuffleTbl, Kind, LT.second))
2416 if (auto KindCost = Entry->Cost[CostKind])
2417 return LT.first * *KindCost;
2418 }
2419
2420 return BaseT::getShuffleCost(Kind, DstTy, SrcTy, Mask, CostKind, Index,
2421 SubTp);
2422}
2423
2425 Type *Src,
2428 const Instruction *I) const {
2429 int ISD = TLI->InstructionOpcodeToISD(Opcode);
2430 assert(ISD && "Invalid opcode");
2431
2432 // The cost tables include both specific, custom (non-legal) src/dst type
2433 // conversions and generic, legalized types. We test for customs first, before
2434 // falling back to legalization.
2435 // FIXME: Need a better design of the cost table to handle non-simple types of
2436 // potential massive combinations (elem_num x src_type x dst_type).
2437 static const TypeConversionCostKindTblEntry AVX512BWConversionTbl[]{
2438 { ISD::SIGN_EXTEND, MVT::v32i16, MVT::v32i8, { 1, 1, 1, 1 } },
2439 { ISD::ZERO_EXTEND, MVT::v32i16, MVT::v32i8, { 1, 1, 1, 1 } },
2440
2441 // Mask sign extend has an instruction.
2442 { ISD::SIGN_EXTEND, MVT::v2i8, MVT::v2i1, { 1, 1, 1, 1 } },
2443 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v2i1, { 1, 1, 1, 1 } },
2444 { ISD::SIGN_EXTEND, MVT::v2i16, MVT::v2i1, { 1, 1, 1, 1 } },
2445 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v2i1, { 1, 1, 1, 1 } },
2446 { ISD::SIGN_EXTEND, MVT::v4i8, MVT::v4i1, { 1, 1, 1, 1 } },
2447 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v4i1, { 1, 1, 1, 1 } },
2448 { ISD::SIGN_EXTEND, MVT::v4i16, MVT::v4i1, { 1, 1, 1, 1 } },
2449 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v4i1, { 1, 1, 1, 1 } },
2450 { ISD::SIGN_EXTEND, MVT::v8i8, MVT::v8i1, { 1, 1, 1, 1 } },
2451 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v8i1, { 1, 1, 1, 1 } },
2452 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v8i1, { 1, 1, 1, 1 } },
2453 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v16i1, { 1, 1, 1, 1 } },
2454 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i1, { 1, 1, 1, 1 } },
2455 { ISD::SIGN_EXTEND, MVT::v32i8, MVT::v32i1, { 1, 1, 1, 1 } },
2456 { ISD::SIGN_EXTEND, MVT::v32i16, MVT::v32i1, { 1, 1, 1, 1 } },
2457 { ISD::SIGN_EXTEND, MVT::v64i8, MVT::v64i1, { 1, 1, 1, 1 } },
2458 { ISD::SIGN_EXTEND, MVT::v32i16, MVT::v64i1, { 1, 1, 1, 1 } },
2459
2460 // Mask zero extend is a sext + shift.
2461 { ISD::ZERO_EXTEND, MVT::v2i8, MVT::v2i1, { 2, 1, 1, 1 } },
2462 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v2i1, { 2, 1, 1, 1 } },
2463 { ISD::ZERO_EXTEND, MVT::v2i16, MVT::v2i1, { 2, 1, 1, 1 } },
2464 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v2i1, { 2, 1, 1, 1 } },
2465 { ISD::ZERO_EXTEND, MVT::v4i8, MVT::v4i1, { 2, 1, 1, 1 } },
2466 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v4i1, { 2, 1, 1, 1 } },
2467 { ISD::ZERO_EXTEND, MVT::v4i16, MVT::v4i1, { 2, 1, 1, 1 } },
2468 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v4i1, { 2, 1, 1, 1 } },
2469 { ISD::ZERO_EXTEND, MVT::v8i8, MVT::v8i1, { 2, 1, 1, 1 } },
2470 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v8i1, { 2, 1, 1, 1 } },
2471 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v8i1, { 2, 1, 1, 1 } },
2472 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v16i1, { 2, 1, 1, 1 } },
2473 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i1, { 2, 1, 1, 1 } },
2474 { ISD::ZERO_EXTEND, MVT::v32i8, MVT::v32i1, { 2, 1, 1, 1 } },
2475 { ISD::ZERO_EXTEND, MVT::v32i16, MVT::v32i1, { 2, 1, 1, 1 } },
2476 { ISD::ZERO_EXTEND, MVT::v64i8, MVT::v64i1, { 2, 1, 1, 1 } },
2477 { ISD::ZERO_EXTEND, MVT::v32i16, MVT::v64i1, { 2, 1, 1, 1 } },
2478
2479 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i8, { 2, 1, 1, 1 } },
2480 { ISD::TRUNCATE, MVT::v2i1, MVT::v16i8, { 2, 1, 1, 1 } },
2481 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i16, { 2, 1, 1, 1 } },
2482 { ISD::TRUNCATE, MVT::v2i1, MVT::v8i16, { 2, 1, 1, 1 } },
2483 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i8, { 2, 1, 1, 1 } },
2484 { ISD::TRUNCATE, MVT::v4i1, MVT::v16i8, { 2, 1, 1, 1 } },
2485 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i16, { 2, 1, 1, 1 } },
2486 { ISD::TRUNCATE, MVT::v4i1, MVT::v8i16, { 2, 1, 1, 1 } },
2487 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i8, { 2, 1, 1, 1 } },
2488 { ISD::TRUNCATE, MVT::v8i1, MVT::v16i8, { 2, 1, 1, 1 } },
2489 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i16, { 2, 1, 1, 1 } },
2490 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i8, { 2, 1, 1, 1 } },
2491 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i16, { 2, 1, 1, 1 } },
2492 { ISD::TRUNCATE, MVT::v32i1, MVT::v32i8, { 2, 1, 1, 1 } },
2493 { ISD::TRUNCATE, MVT::v32i1, MVT::v32i16, { 2, 1, 1, 1 } },
2494 { ISD::TRUNCATE, MVT::v64i1, MVT::v64i8, { 2, 1, 1, 1 } },
2495 { ISD::TRUNCATE, MVT::v64i1, MVT::v32i16, { 2, 1, 1, 1 } },
2496
2497 { ISD::TRUNCATE, MVT::v32i8, MVT::v32i16, { 2, 1, 1, 1 } },
2498 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i16, { 2, 1, 1, 1 } }, // widen to zmm
2499 { ISD::TRUNCATE, MVT::v2i8, MVT::v2i16, { 2, 1, 1, 1 } }, // vpmovwb
2500 { ISD::TRUNCATE, MVT::v4i8, MVT::v4i16, { 2, 1, 1, 1 } }, // vpmovwb
2501 { ISD::TRUNCATE, MVT::v8i8, MVT::v8i16, { 2, 1, 1, 1 } }, // vpmovwb
2502 };
2503
2504 static const TypeConversionCostKindTblEntry AVX512DQConversionTbl[] = {
2505 // Mask sign extend has an instruction.
2506 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v2i1, { 1, 1, 1, 1 } },
2507 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v2i1, { 1, 1, 1, 1 } },
2508 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v4i1, { 1, 1, 1, 1 } },
2509 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i1, { 1, 1, 1, 1 } },
2510 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i1, { 1, 1, 1, 1 } },
2511 { ISD::SIGN_EXTEND, MVT::v8i64, MVT::v16i1, { 1, 1, 1, 1 } },
2512 { ISD::SIGN_EXTEND, MVT::v8i64, MVT::v8i1, { 1, 1, 1, 1 } },
2513 { ISD::SIGN_EXTEND, MVT::v16i32, MVT::v16i1, { 1, 1, 1, 1 } },
2514
2515 // Mask zero extend is a sext + shift.
2516 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v2i1, { 2, 1, 1, 1, } },
2517 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v2i1, { 2, 1, 1, 1, } },
2518 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v4i1, { 2, 1, 1, 1, } },
2519 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i1, { 2, 1, 1, 1, } },
2520 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i1, { 2, 1, 1, 1, } },
2521 { ISD::ZERO_EXTEND, MVT::v8i64, MVT::v16i1, { 2, 1, 1, 1, } },
2522 { ISD::ZERO_EXTEND, MVT::v8i64, MVT::v8i1, { 2, 1, 1, 1, } },
2523 { ISD::ZERO_EXTEND, MVT::v16i32, MVT::v16i1, { 2, 1, 1, 1, } },
2524
2525 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i64, { 2, 1, 1, 1 } },
2526 { ISD::TRUNCATE, MVT::v2i1, MVT::v4i32, { 2, 1, 1, 1 } },
2527 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i32, { 2, 1, 1, 1 } },
2528 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i64, { 2, 1, 1, 1 } },
2529 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i32, { 2, 1, 1, 1 } },
2530 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i64, { 2, 1, 1, 1 } },
2531 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i32, { 2, 1, 1, 1 } },
2532 { ISD::TRUNCATE, MVT::v16i1, MVT::v8i64, { 2, 1, 1, 1 } },
2533
2534 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v8i64, { 1, 1, 1, 1 } },
2535 { ISD::SINT_TO_FP, MVT::v8f64, MVT::v8i64, { 1, 1, 1, 1 } },
2536
2537 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i64, { 1, 1, 1, 1 } },
2538 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i64, { 1, 1, 1, 1 } },
2539
2540 { ISD::FP_TO_SINT, MVT::v8i64, MVT::v8f32, { 1, 1, 1, 1 } },
2541 { ISD::FP_TO_SINT, MVT::v8i64, MVT::v8f64, { 1, 1, 1, 1 } },
2542
2543 { ISD::FP_TO_UINT, MVT::v8i64, MVT::v8f32, { 1, 1, 1, 1 } },
2544 { ISD::FP_TO_UINT, MVT::v8i64, MVT::v8f64, { 1, 1, 1, 1 } },
2545 };
2546
2547 // TODO: For AVX512DQ + AVX512VL, we also have cheap casts for 128-bit and
2548 // 256-bit wide vectors.
2549
2550 static const TypeConversionCostKindTblEntry AVX512FConversionTbl[] = {
2551 { ISD::FP_EXTEND, MVT::v8f64, MVT::v8f32, { 1, 1, 1, 1 } },
2552 { ISD::FP_EXTEND, MVT::v8f64, MVT::v16f32, { 3, 1, 1, 1 } },
2553 { ISD::FP_EXTEND, MVT::v16f64, MVT::v16f32, { 4, 1, 1, 1 } }, // 2*vcvtps2pd+vextractf64x4
2554 { ISD::FP_EXTEND, MVT::v16f32, MVT::v16f16, { 1, 1, 1, 1 } }, // vcvtph2ps
2555 { ISD::FP_EXTEND, MVT::v8f64, MVT::v8f16, { 2, 1, 1, 1 } }, // vcvtph2ps+vcvtps2pd
2556 { ISD::FP_ROUND, MVT::v8f32, MVT::v8f64, { 1, 1, 1, 1 } },
2557 { ISD::FP_ROUND, MVT::v16f16, MVT::v16f32, { 1, 1, 1, 1 } }, // vcvtps2ph
2558
2559 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i8, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
2560 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i8, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
2561 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i8, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
2562 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i8, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
2563 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i16, { 3, 1, 1, 1 } }, // sext+vpsllq+vptestmq
2564 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i16, { 3, 1, 1, 1 } }, // sext+vpsllq+vptestmq
2565 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i16, { 3, 1, 1, 1 } }, // sext+vpsllq+vptestmq
2566 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i16, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
2567 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i32, { 2, 1, 1, 1 } }, // zmm vpslld+vptestmd
2568 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i32, { 2, 1, 1, 1 } }, // zmm vpslld+vptestmd
2569 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i32, { 2, 1, 1, 1 } }, // zmm vpslld+vptestmd
2570 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i32, { 2, 1, 1, 1 } }, // vpslld+vptestmd
2571 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i64, { 2, 1, 1, 1 } }, // zmm vpsllq+vptestmq
2572 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i64, { 2, 1, 1, 1 } }, // zmm vpsllq+vptestmq
2573 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i64, { 2, 1, 1, 1 } }, // vpsllq+vptestmq
2574 { ISD::TRUNCATE, MVT::v2i8, MVT::v2i32, { 2, 1, 1, 1 } }, // vpmovdb
2575 { ISD::TRUNCATE, MVT::v4i8, MVT::v4i32, { 2, 1, 1, 1 } }, // vpmovdb
2576 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i32, { 2, 1, 1, 1 } }, // vpmovdb
2577 { ISD::TRUNCATE, MVT::v32i8, MVT::v16i32, { 2, 1, 1, 1 } }, // vpmovdb
2578 { ISD::TRUNCATE, MVT::v64i8, MVT::v16i32, { 2, 1, 1, 1 } }, // vpmovdb
2579 { ISD::TRUNCATE, MVT::v16i16, MVT::v16i32, { 2, 1, 1, 1 } }, // vpmovdw
2580 { ISD::TRUNCATE, MVT::v32i16, MVT::v16i32, { 2, 1, 1, 1 } }, // vpmovdw
2581 { ISD::TRUNCATE, MVT::v2i8, MVT::v2i64, { 2, 1, 1, 1 } }, // vpmovqb
2582 { ISD::TRUNCATE, MVT::v2i16, MVT::v2i64, { 1, 1, 1, 1 } }, // vpshufb
2583 { ISD::TRUNCATE, MVT::v8i8, MVT::v8i64, { 2, 1, 1, 1 } }, // vpmovqb
2584 { ISD::TRUNCATE, MVT::v16i8, MVT::v8i64, { 2, 1, 1, 1 } }, // vpmovqb
2585 { ISD::TRUNCATE, MVT::v32i8, MVT::v8i64, { 2, 1, 1, 1 } }, // vpmovqb
2586 { ISD::TRUNCATE, MVT::v64i8, MVT::v8i64, { 2, 1, 1, 1 } }, // vpmovqb
2587 { ISD::TRUNCATE, MVT::v8i16, MVT::v8i64, { 2, 1, 1, 1 } }, // vpmovqw
2588 { ISD::TRUNCATE, MVT::v16i16, MVT::v8i64, { 2, 1, 1, 1 } }, // vpmovqw
2589 { ISD::TRUNCATE, MVT::v32i16, MVT::v8i64, { 2, 1, 1, 1 } }, // vpmovqw
2590 { ISD::TRUNCATE, MVT::v8i32, MVT::v8i64, { 1, 1, 1, 1 } }, // vpmovqd
2591 { ISD::TRUNCATE, MVT::v4i32, MVT::v4i64, { 1, 1, 1, 1 } }, // zmm vpmovqd
2592 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i64, { 5, 1, 1, 1 } },// 2*vpmovqd+concat+vpmovdb
2593
2594 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i16, { 3, 1, 1, 1 } }, // extend to v16i32
2595 { ISD::TRUNCATE, MVT::v32i8, MVT::v32i16, { 8, 1, 1, 1 } },
2596 { ISD::TRUNCATE, MVT::v64i8, MVT::v32i16, { 8, 1, 1, 1 } },
2597
2598 // Sign extend is zmm vpternlogd+vptruncdb.
2599 // Zero extend is zmm broadcast load+vptruncdw.
2600 { ISD::SIGN_EXTEND, MVT::v2i8, MVT::v2i1, { 3, 1, 1, 1 } },
2601 { ISD::ZERO_EXTEND, MVT::v2i8, MVT::v2i1, { 4, 1, 1, 1 } },
2602 { ISD::SIGN_EXTEND, MVT::v4i8, MVT::v4i1, { 3, 1, 1, 1 } },
2603 { ISD::ZERO_EXTEND, MVT::v4i8, MVT::v4i1, { 4, 1, 1, 1 } },
2604 { ISD::SIGN_EXTEND, MVT::v8i8, MVT::v8i1, { 3, 1, 1, 1 } },
2605 { ISD::ZERO_EXTEND, MVT::v8i8, MVT::v8i1, { 4, 1, 1, 1 } },
2606 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v16i1, { 3, 1, 1, 1 } },
2607 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v16i1, { 4, 1, 1, 1 } },
2608
2609 // Sign extend is zmm vpternlogd+vptruncdw.
2610 // Zero extend is zmm vpternlogd+vptruncdw+vpsrlw.
2611 { ISD::SIGN_EXTEND, MVT::v2i16, MVT::v2i1, { 3, 1, 1, 1 } },
2612 { ISD::ZERO_EXTEND, MVT::v2i16, MVT::v2i1, { 4, 1, 1, 1 } },
2613 { ISD::SIGN_EXTEND, MVT::v4i16, MVT::v4i1, { 3, 1, 1, 1 } },
2614 { ISD::ZERO_EXTEND, MVT::v4i16, MVT::v4i1, { 4, 1, 1, 1 } },
2615 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v8i1, { 3, 1, 1, 1 } },
2616 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v8i1, { 4, 1, 1, 1 } },
2617 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i1, { 3, 1, 1, 1 } },
2618 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i1, { 4, 1, 1, 1 } },
2619
2620 { ISD::SIGN_EXTEND, MVT::v2i32, MVT::v2i1, { 1, 1, 1, 1 } }, // zmm vpternlogd
2621 { ISD::ZERO_EXTEND, MVT::v2i32, MVT::v2i1, { 2, 1, 1, 1 } }, // zmm vpternlogd+psrld
2622 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v4i1, { 1, 1, 1, 1 } }, // zmm vpternlogd
2623 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v4i1, { 2, 1, 1, 1 } }, // zmm vpternlogd+psrld
2624 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i1, { 1, 1, 1, 1 } }, // zmm vpternlogd
2625 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i1, { 2, 1, 1, 1 } }, // zmm vpternlogd+psrld
2626 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v2i1, { 1, 1, 1, 1 } }, // zmm vpternlogq
2627 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v2i1, { 2, 1, 1, 1 } }, // zmm vpternlogq+psrlq
2628 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i1, { 1, 1, 1, 1 } }, // zmm vpternlogq
2629 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i1, { 2, 1, 1, 1 } }, // zmm vpternlogq+psrlq
2630
2631 { ISD::SIGN_EXTEND, MVT::v16i32, MVT::v16i1, { 1, 1, 1, 1 } }, // vpternlogd
2632 { ISD::ZERO_EXTEND, MVT::v16i32, MVT::v16i1, { 2, 1, 1, 1 } }, // vpternlogd+psrld
2633 { ISD::SIGN_EXTEND, MVT::v8i64, MVT::v8i1, { 1, 1, 1, 1 } }, // vpternlogq
2634 { ISD::ZERO_EXTEND, MVT::v8i64, MVT::v8i1, { 2, 1, 1, 1 } }, // vpternlogq+psrlq
2635
2636 { ISD::SIGN_EXTEND, MVT::v16i32, MVT::v16i8, { 1, 1, 1, 1 } },
2637 { ISD::ZERO_EXTEND, MVT::v16i32, MVT::v16i8, { 1, 1, 1, 1 } },
2638 { ISD::SIGN_EXTEND, MVT::v16i32, MVT::v16i16, { 1, 1, 1, 1 } },
2639 { ISD::ZERO_EXTEND, MVT::v16i32, MVT::v16i16, { 1, 1, 1, 1 } },
2640 { ISD::SIGN_EXTEND, MVT::v8i64, MVT::v8i8, { 1, 1, 1, 1 } },
2641 { ISD::ZERO_EXTEND, MVT::v8i64, MVT::v8i8, { 1, 1, 1, 1 } },
2642 { ISD::SIGN_EXTEND, MVT::v8i64, MVT::v8i16, { 1, 1, 1, 1 } },
2643 { ISD::ZERO_EXTEND, MVT::v8i64, MVT::v8i16, { 1, 1, 1, 1 } },
2644 { ISD::SIGN_EXTEND, MVT::v8i64, MVT::v8i32, { 1, 1, 1, 1 } },
2645 { ISD::ZERO_EXTEND, MVT::v8i64, MVT::v8i32, { 1, 1, 1, 1 } },
2646
2647 { ISD::SIGN_EXTEND, MVT::v32i16, MVT::v32i8, { 3, 1, 1, 1 } }, // FIXME: May not be right
2648 { ISD::ZERO_EXTEND, MVT::v32i16, MVT::v32i8, { 3, 1, 1, 1 } }, // FIXME: May not be right
2649
2650 { ISD::SINT_TO_FP, MVT::v8f64, MVT::v8i1, { 4, 1, 1, 1 } },
2651 { ISD::SINT_TO_FP, MVT::v16f32, MVT::v16i1, { 3, 1, 1, 1 } },
2652 { ISD::SINT_TO_FP, MVT::v8f64, MVT::v16i8, { 2, 1, 1, 1 } },
2653 { ISD::SINT_TO_FP, MVT::v16f32, MVT::v16i8, { 1, 1, 1, 1 } },
2654 { ISD::SINT_TO_FP, MVT::v8f64, MVT::v8i16, { 2, 1, 1, 1 } },
2655 { ISD::SINT_TO_FP, MVT::v16f32, MVT::v16i16, { 1, 1, 1, 1 } },
2656 { ISD::SINT_TO_FP, MVT::v8f64, MVT::v8i32, { 1, 1, 1, 1 } },
2657 { ISD::SINT_TO_FP, MVT::v16f32, MVT::v16i32, { 1, 1, 1, 1 } },
2658
2659 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i1, { 4, 1, 1, 1 } },
2660 { ISD::UINT_TO_FP, MVT::v16f32, MVT::v16i1, { 3, 1, 1, 1 } },
2661 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v16i8, { 2, 1, 1, 1 } },
2662 { ISD::UINT_TO_FP, MVT::v16f32, MVT::v16i8, { 1, 1, 1, 1 } },
2663 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i16, { 2, 1, 1, 1 } },
2664 { ISD::UINT_TO_FP, MVT::v16f32, MVT::v16i16, { 1, 1, 1, 1 } },
2665 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i32, { 1, 1, 1, 1 } },
2666 { ISD::UINT_TO_FP, MVT::v16f32, MVT::v16i32, { 1, 1, 1, 1 } },
2667 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i64, {26, 1, 1, 1 } },
2668 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i64, { 5, 1, 1, 1 } },
2669
2670 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v16f32, { 2, 1, 1, 1 } },
2671 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v16f64, { 7, 1, 1, 1 } },
2672 { ISD::FP_TO_SINT, MVT::v32i8, MVT::v32f64, {15, 1, 1, 1 } },
2673 { ISD::FP_TO_SINT, MVT::v64i8, MVT::v64f32, {11, 1, 1, 1 } },
2674 { ISD::FP_TO_SINT, MVT::v64i8, MVT::v64f64, {31, 1, 1, 1 } },
2675 { ISD::FP_TO_SINT, MVT::v8i16, MVT::v8f64, { 3, 1, 1, 1 } },
2676 { ISD::FP_TO_SINT, MVT::v16i16, MVT::v16f64, { 7, 1, 1, 1 } },
2677 { ISD::FP_TO_SINT, MVT::v32i16, MVT::v32f32, { 5, 1, 1, 1 } },
2678 { ISD::FP_TO_SINT, MVT::v32i16, MVT::v32f64, {15, 1, 1, 1 } },
2679 { ISD::FP_TO_SINT, MVT::v8i32, MVT::v8f64, { 1, 1, 1, 1 } },
2680 { ISD::FP_TO_SINT, MVT::v16i32, MVT::v16f64, { 3, 1, 1, 1 } },
2681
2682 { ISD::FP_TO_UINT, MVT::v8i32, MVT::v8f64, { 1, 1, 1, 1 } },
2683 { ISD::FP_TO_UINT, MVT::v8i16, MVT::v8f64, { 3, 1, 1, 1 } },
2684 { ISD::FP_TO_UINT, MVT::v8i8, MVT::v8f64, { 3, 1, 1, 1 } },
2685 { ISD::FP_TO_UINT, MVT::v16i32, MVT::v16f32, { 1, 1, 1, 1 } },
2686 { ISD::FP_TO_UINT, MVT::v16i16, MVT::v16f32, { 3, 1, 1, 1 } },
2687 { ISD::FP_TO_UINT, MVT::v16i8, MVT::v16f32, { 3, 1, 1, 1 } },
2688 };
2689
2690 static const TypeConversionCostKindTblEntry AVX512BWVLConversionTbl[] {
2691 // Mask sign extend has an instruction.
2692 { ISD::SIGN_EXTEND, MVT::v2i8, MVT::v2i1, { 1, 1, 1, 1 } },
2693 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v2i1, { 1, 1, 1, 1 } },
2694 { ISD::SIGN_EXTEND, MVT::v2i16, MVT::v2i1, { 1, 1, 1, 1 } },
2695 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v2i1, { 1, 1, 1, 1 } },
2696 { ISD::SIGN_EXTEND, MVT::v4i16, MVT::v4i1, { 1, 1, 1, 1 } },
2697 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v4i1, { 1, 1, 1, 1 } },
2698 { ISD::SIGN_EXTEND, MVT::v4i8, MVT::v4i1, { 1, 1, 1, 1 } },
2699 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v4i1, { 1, 1, 1, 1 } },
2700 { ISD::SIGN_EXTEND, MVT::v8i8, MVT::v8i1, { 1, 1, 1, 1 } },
2701 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v8i1, { 1, 1, 1, 1 } },
2702 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v8i1, { 1, 1, 1, 1 } },
2703 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v16i1, { 1, 1, 1, 1 } },
2704 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i1, { 1, 1, 1, 1 } },
2705 { ISD::SIGN_EXTEND, MVT::v32i8, MVT::v32i1, { 1, 1, 1, 1 } },
2706 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v32i1, { 1, 1, 1, 1 } },
2707 { ISD::SIGN_EXTEND, MVT::v32i8, MVT::v64i1, { 1, 1, 1, 1 } },
2708 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v64i1, { 1, 1, 1, 1 } },
2709
2710 // Mask zero extend is a sext + shift.
2711 { ISD::ZERO_EXTEND, MVT::v2i8, MVT::v2i1, { 2, 1, 1, 1 } },
2712 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v2i1, { 2, 1, 1, 1 } },
2713 { ISD::ZERO_EXTEND, MVT::v2i16, MVT::v2i1, { 2, 1, 1, 1 } },
2714 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v2i1, { 2, 1, 1, 1 } },
2715 { ISD::ZERO_EXTEND, MVT::v4i8, MVT::v4i1, { 2, 1, 1, 1 } },
2716 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v4i1, { 2, 1, 1, 1 } },
2717 { ISD::ZERO_EXTEND, MVT::v4i16, MVT::v4i1, { 2, 1, 1, 1 } },
2718 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v4i1, { 2, 1, 1, 1 } },
2719 { ISD::ZERO_EXTEND, MVT::v8i8, MVT::v8i1, { 2, 1, 1, 1 } },
2720 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v8i1, { 2, 1, 1, 1 } },
2721 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v8i1, { 2, 1, 1, 1 } },
2722 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v16i1, { 2, 1, 1, 1 } },
2723 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i1, { 2, 1, 1, 1 } },
2724 { ISD::ZERO_EXTEND, MVT::v32i8, MVT::v32i1, { 2, 1, 1, 1 } },
2725 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v32i1, { 2, 1, 1, 1 } },
2726 { ISD::ZERO_EXTEND, MVT::v32i8, MVT::v64i1, { 2, 1, 1, 1 } },
2727 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v64i1, { 2, 1, 1, 1 } },
2728
2729 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i8, { 2, 1, 1, 1 } },
2730 { ISD::TRUNCATE, MVT::v2i1, MVT::v16i8, { 2, 1, 1, 1 } },
2731 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i16, { 2, 1, 1, 1 } },
2732 { ISD::TRUNCATE, MVT::v2i1, MVT::v8i16, { 2, 1, 1, 1 } },
2733 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i8, { 2, 1, 1, 1 } },
2734 { ISD::TRUNCATE, MVT::v4i1, MVT::v16i8, { 2, 1, 1, 1 } },
2735 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i16, { 2, 1, 1, 1 } },
2736 { ISD::TRUNCATE, MVT::v4i1, MVT::v8i16, { 2, 1, 1, 1 } },
2737 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i8, { 2, 1, 1, 1 } },
2738 { ISD::TRUNCATE, MVT::v8i1, MVT::v16i8, { 2, 1, 1, 1 } },
2739 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i16, { 2, 1, 1, 1 } },
2740 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i8, { 2, 1, 1, 1 } },
2741 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i16, { 2, 1, 1, 1 } },
2742 { ISD::TRUNCATE, MVT::v32i1, MVT::v32i8, { 2, 1, 1, 1 } },
2743 { ISD::TRUNCATE, MVT::v32i1, MVT::v16i16, { 2, 1, 1, 1 } },
2744 { ISD::TRUNCATE, MVT::v64i1, MVT::v32i8, { 2, 1, 1, 1 } },
2745 { ISD::TRUNCATE, MVT::v64i1, MVT::v16i16, { 2, 1, 1, 1 } },
2746
2747 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i16, { 2, 1, 1, 1 } },
2748 };
2749
2750 static const TypeConversionCostKindTblEntry AVX512DQVLConversionTbl[] = {
2751 // Mask sign extend has an instruction.
2752 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v2i1, { 1, 1, 1, 1 } },
2753 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v2i1, { 1, 1, 1, 1 } },
2754 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v4i1, { 1, 1, 1, 1 } },
2755 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v16i1, { 1, 1, 1, 1 } },
2756 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i1, { 1, 1, 1, 1 } },
2757 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v8i1, { 1, 1, 1, 1 } },
2758 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v16i1, { 1, 1, 1, 1 } },
2759 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i1, { 1, 1, 1, 1 } },
2760
2761 // Mask zero extend is a sext + shift.
2762 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v2i1, { 2, 1, 1, 1 } },
2763 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v2i1, { 2, 1, 1, 1 } },
2764 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v4i1, { 2, 1, 1, 1 } },
2765 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v16i1, { 2, 1, 1, 1 } },
2766 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i1, { 2, 1, 1, 1 } },
2767 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v8i1, { 2, 1, 1, 1 } },
2768 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v16i1, { 2, 1, 1, 1 } },
2769 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i1, { 2, 1, 1, 1 } },
2770
2771 { ISD::TRUNCATE, MVT::v16i1, MVT::v4i64, { 2, 1, 1, 1 } },
2772 { ISD::TRUNCATE, MVT::v16i1, MVT::v8i32, { 2, 1, 1, 1 } },
2773 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i64, { 2, 1, 1, 1 } },
2774 { ISD::TRUNCATE, MVT::v2i1, MVT::v4i32, { 2, 1, 1, 1 } },
2775 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i32, { 2, 1, 1, 1 } },
2776 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i64, { 2, 1, 1, 1 } },
2777 { ISD::TRUNCATE, MVT::v8i1, MVT::v4i64, { 2, 1, 1, 1 } },
2778 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i32, { 2, 1, 1, 1 } },
2779
2780 { ISD::SINT_TO_FP, MVT::v2f32, MVT::v2i64, { 1, 1, 1, 1 } },
2781 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v2i64, { 1, 1, 1, 1 } },
2782 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v4i64, { 1, 1, 1, 1 } },
2783 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v4i64, { 1, 1, 1, 1 } },
2784
2785 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i64, { 1, 1, 1, 1 } },
2786 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i64, { 1, 1, 1, 1 } },
2787 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i64, { 1, 1, 1, 1 } },
2788 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i64, { 1, 1, 1, 1 } },
2789
2790 { ISD::FP_TO_SINT, MVT::v2i64, MVT::v4f32, { 1, 1, 1, 1 } },
2791 { ISD::FP_TO_SINT, MVT::v4i64, MVT::v4f32, { 1, 1, 1, 1 } },
2792 { ISD::FP_TO_SINT, MVT::v2i64, MVT::v2f64, { 1, 1, 1, 1 } },
2793 { ISD::FP_TO_SINT, MVT::v4i64, MVT::v4f64, { 1, 1, 1, 1 } },
2794
2795 { ISD::FP_TO_UINT, MVT::v2i64, MVT::v4f32, { 1, 1, 1, 1 } },
2796 { ISD::FP_TO_UINT, MVT::v4i64, MVT::v4f32, { 1, 1, 1, 1 } },
2797 { ISD::FP_TO_UINT, MVT::v2i64, MVT::v2f64, { 1, 1, 1, 1 } },
2798 { ISD::FP_TO_UINT, MVT::v4i64, MVT::v4f64, { 1, 1, 1, 1 } },
2799 };
2800
2801 static const TypeConversionCostKindTblEntry AVX512VLConversionTbl[] = {
2802 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i8, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
2803 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i8, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
2804 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i8, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
2805 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i8, { 8, 1, 1, 1 } }, // split+2*v8i8
2806 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i16, { 3, 1, 1, 1 } }, // sext+vpsllq+vptestmq
2807 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i16, { 3, 1, 1, 1 } }, // sext+vpsllq+vptestmq
2808 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i16, { 3, 1, 1, 1 } }, // sext+vpsllq+vptestmq
2809 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i16, { 8, 1, 1, 1 } }, // split+2*v8i16
2810 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i32, { 2, 1, 1, 1 } }, // vpslld+vptestmd
2811 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i32, { 2, 1, 1, 1 } }, // vpslld+vptestmd
2812 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i32, { 2, 1, 1, 1 } }, // vpslld+vptestmd
2813 { ISD::TRUNCATE, MVT::v16i1, MVT::v8i32, { 2, 1, 1, 1 } }, // vpslld+vptestmd
2814 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i64, { 2, 1, 1, 1 } }, // vpsllq+vptestmq
2815 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i64, { 2, 1, 1, 1 } }, // vpsllq+vptestmq
2816 { ISD::TRUNCATE, MVT::v4i32, MVT::v4i64, { 1, 1, 1, 1 } }, // vpmovqd
2817 { ISD::TRUNCATE, MVT::v4i8, MVT::v4i64, { 2, 1, 1, 1 } }, // vpmovqb
2818 { ISD::TRUNCATE, MVT::v4i16, MVT::v4i64, { 2, 1, 1, 1 } }, // vpmovqw
2819 { ISD::TRUNCATE, MVT::v8i8, MVT::v8i32, { 2, 1, 1, 1 } }, // vpmovwb
2820
2821 // sign extend is vpcmpeq+maskedmove+vpmovdw+vpacksswb
2822 // zero extend is vpcmpeq+maskedmove+vpmovdw+vpsrlw+vpackuswb
2823 { ISD::SIGN_EXTEND, MVT::v2i8, MVT::v2i1, { 5, 1, 1, 1 } },
2824 { ISD::ZERO_EXTEND, MVT::v2i8, MVT::v2i1, { 6, 1, 1, 1 } },
2825 { ISD::SIGN_EXTEND, MVT::v4i8, MVT::v4i1, { 5, 1, 1, 1 } },
2826 { ISD::ZERO_EXTEND, MVT::v4i8, MVT::v4i1, { 6, 1, 1, 1 } },
2827 { ISD::SIGN_EXTEND, MVT::v8i8, MVT::v8i1, { 5, 1, 1, 1 } },
2828 { ISD::ZERO_EXTEND, MVT::v8i8, MVT::v8i1, { 6, 1, 1, 1 } },
2829 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v16i1, {10, 1, 1, 1 } },
2830 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v16i1, {12, 1, 1, 1 } },
2831
2832 // sign extend is vpcmpeq+maskedmove+vpmovdw
2833 // zero extend is vpcmpeq+maskedmove+vpmovdw+vpsrlw
2834 { ISD::SIGN_EXTEND, MVT::v2i16, MVT::v2i1, { 4, 1, 1, 1 } },
2835 { ISD::ZERO_EXTEND, MVT::v2i16, MVT::v2i1, { 5, 1, 1, 1 } },
2836 { ISD::SIGN_EXTEND, MVT::v4i16, MVT::v4i1, { 4, 1, 1, 1 } },
2837 { ISD::ZERO_EXTEND, MVT::v4i16, MVT::v4i1, { 5, 1, 1, 1 } },
2838 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v8i1, { 4, 1, 1, 1 } },
2839 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v8i1, { 5, 1, 1, 1 } },
2840 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i1, {10, 1, 1, 1 } },
2841 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i1, {12, 1, 1, 1 } },
2842
2843 { ISD::SIGN_EXTEND, MVT::v2i32, MVT::v2i1, { 1, 1, 1, 1 } }, // vpternlogd
2844 { ISD::ZERO_EXTEND, MVT::v2i32, MVT::v2i1, { 2, 1, 1, 1 } }, // vpternlogd+psrld
2845 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v4i1, { 1, 1, 1, 1 } }, // vpternlogd
2846 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v4i1, { 2, 1, 1, 1 } }, // vpternlogd+psrld
2847 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i1, { 1, 1, 1, 1 } }, // vpternlogd
2848 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i1, { 2, 1, 1, 1 } }, // vpternlogd+psrld
2849 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v16i1, { 1, 1, 1, 1 } }, // vpternlogd
2850 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v16i1, { 2, 1, 1, 1 } }, // vpternlogd+psrld
2851
2852 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v2i1, { 1, 1, 1, 1 } }, // vpternlogq
2853 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v2i1, { 2, 1, 1, 1 } }, // vpternlogq+psrlq
2854 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i1, { 1, 1, 1, 1 } }, // vpternlogq
2855 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i1, { 2, 1, 1, 1 } }, // vpternlogq+psrlq
2856
2857 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v16i8, { 1, 1, 1, 1 } },
2858 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v16i8, { 1, 1, 1, 1 } },
2859 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v16i8, { 1, 1, 1, 1 } },
2860 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v16i8, { 1, 1, 1, 1 } },
2861 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i8, { 1, 1, 1, 1 } },
2862 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i8, { 1, 1, 1, 1 } },
2863 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v8i16, { 1, 1, 1, 1 } },
2864 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v8i16, { 1, 1, 1, 1 } },
2865 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i16, { 1, 1, 1, 1 } },
2866 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i16, { 1, 1, 1, 1 } },
2867 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i32, { 1, 1, 1, 1 } },
2868 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i32, { 1, 1, 1, 1 } },
2869
2870 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v16i8, { 1, 1, 1, 1 } },
2871 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v16i8, { 1, 1, 1, 1 } },
2872 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v8i16, { 1, 1, 1, 1 } },
2873 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v8i16, { 1, 1, 1, 1 } },
2874
2875 { ISD::UINT_TO_FP, MVT::f32, MVT::i64, { 1, 1, 1, 1 } },
2876 { ISD::UINT_TO_FP, MVT::f64, MVT::i64, { 1, 1, 1, 1 } },
2877 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v16i8, { 1, 1, 1, 1 } },
2878 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v16i8, { 1, 1, 1, 1 } },
2879 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v8i16, { 1, 1, 1, 1 } },
2880 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i16, { 1, 1, 1, 1 } },
2881 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i32, { 1, 1, 1, 1 } },
2882 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i32, { 1, 1, 1, 1 } },
2883 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i32, { 1, 1, 1, 1 } },
2884 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i32, { 1, 1, 1, 1 } },
2885 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i64, { 5, 1, 1, 1 } },
2886 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i64, { 5, 1, 1, 1 } },
2887 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i64, { 5, 1, 1, 1 } },
2888
2889 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v8f32, { 2, 1, 1, 1 } },
2890 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v16f32, { 2, 1, 1, 1 } },
2891 { ISD::FP_TO_SINT, MVT::v32i8, MVT::v32f32, { 5, 1, 1, 1 } },
2892
2893 { ISD::FP_TO_UINT, MVT::i64, MVT::f32, { 1, 1, 1, 1 } },
2894 { ISD::FP_TO_UINT, MVT::i64, MVT::f64, { 1, 1, 1, 1 } },
2895 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f32, { 1, 1, 1, 1 } },
2896 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v2f64, { 1, 1, 1, 1 } },
2897 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f64, { 1, 1, 1, 1 } },
2898 { ISD::FP_TO_UINT, MVT::v8i32, MVT::v8f32, { 1, 1, 1, 1 } },
2899 { ISD::FP_TO_UINT, MVT::v8i32, MVT::v8f64, { 1, 1, 1, 1 } },
2900 };
2901
2902 static const TypeConversionCostKindTblEntry AVX2ConversionTbl[] = {
2903 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i1, { 3, 1, 1, 1 } },
2904 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i1, { 3, 1, 1, 1 } },
2905 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i1, { 3, 1, 1, 1 } },
2906 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i1, { 3, 1, 1, 1 } },
2907 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i1, { 1, 1, 1, 1 } },
2908 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i1, { 1, 1, 1, 1 } },
2909
2910 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v16i8, { 2, 1, 1, 1 } },
2911 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v16i8, { 2, 1, 1, 1 } },
2912 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v16i8, { 2, 1, 1, 1 } },
2913 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v16i8, { 2, 1, 1, 1 } },
2914 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i8, { 2, 1, 1, 1 } },
2915 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i8, { 2, 1, 1, 1 } },
2916 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v8i16, { 2, 1, 1, 1 } },
2917 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v8i16, { 2, 1, 1, 1 } },
2918 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i16, { 2, 1, 1, 1 } },
2919 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i16, { 2, 1, 1, 1 } },
2920 { ISD::ZERO_EXTEND, MVT::v16i32, MVT::v16i16, { 3, 1, 1, 1 } },
2921 { ISD::SIGN_EXTEND, MVT::v16i32, MVT::v16i16, { 3, 1, 1, 1 } },
2922 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i32, { 2, 1, 1, 1 } },
2923 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i32, { 2, 1, 1, 1 } },
2924
2925 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i32, { 2, 1, 1, 1 } },
2926
2927 { ISD::TRUNCATE, MVT::v16i16, MVT::v16i32, { 4, 1, 1, 1 } },
2928 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i32, { 4, 1, 1, 1 } },
2929 { ISD::TRUNCATE, MVT::v16i8, MVT::v8i16, { 1, 1, 1, 1 } },
2930 { ISD::TRUNCATE, MVT::v16i8, MVT::v4i32, { 1, 1, 1, 1 } },
2931 { ISD::TRUNCATE, MVT::v16i8, MVT::v2i64, { 1, 1, 1, 1 } },
2932 { ISD::TRUNCATE, MVT::v16i8, MVT::v8i32, { 4, 1, 1, 1 } },
2933 { ISD::TRUNCATE, MVT::v16i8, MVT::v4i64, { 4, 1, 1, 1 } },
2934 { ISD::TRUNCATE, MVT::v8i16, MVT::v4i32, { 1, 1, 1, 1 } },
2935 { ISD::TRUNCATE, MVT::v8i16, MVT::v2i64, { 1, 1, 1, 1 } },
2936 { ISD::TRUNCATE, MVT::v8i16, MVT::v4i64, { 5, 1, 1, 1 } },
2937 { ISD::TRUNCATE, MVT::v4i32, MVT::v4i64, { 1, 1, 1, 1 } },
2938 { ISD::TRUNCATE, MVT::v8i16, MVT::v8i32, { 2, 1, 1, 1 } },
2939
2940 { ISD::FP_EXTEND, MVT::v8f64, MVT::v8f32, { 3, 1, 1, 1 } },
2941 { ISD::FP_ROUND, MVT::v8f32, MVT::v8f64, { 3, 1, 1, 1 } },
2942
2943 { ISD::FP_TO_SINT, MVT::v16i16, MVT::v8f32, { 1, 1, 1, 1 } },
2944 { ISD::FP_TO_SINT, MVT::v4i32, MVT::v4f64, { 1, 1, 1, 1 } },
2945 { ISD::FP_TO_SINT, MVT::v8i32, MVT::v8f32, { 1, 1, 1, 1 } },
2946 { ISD::FP_TO_SINT, MVT::v8i32, MVT::v8f64, { 3, 1, 1, 1 } },
2947
2948 { ISD::FP_TO_UINT, MVT::i64, MVT::f32, { 3, 1, 1, 1 } },
2949 { ISD::FP_TO_UINT, MVT::i64, MVT::f64, { 3, 1, 1, 1 } },
2950 { ISD::FP_TO_UINT, MVT::v16i16, MVT::v8f32, { 1, 1, 1, 1 } },
2951 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f32, { 3, 1, 1, 1 } },
2952 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v2f64, { 4, 1, 1, 1 } },
2953 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f64, { 4, 1, 1, 1 } },
2954 { ISD::FP_TO_UINT, MVT::v8i32, MVT::v8f32, { 3, 1, 1, 1 } },
2955 { ISD::FP_TO_UINT, MVT::v8i32, MVT::v4f64, { 4, 1, 1, 1 } },
2956
2957 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v16i8, { 2, 1, 1, 1 } },
2958 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v16i8, { 2, 1, 1, 1 } },
2959 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v8i16, { 2, 1, 1, 1 } },
2960 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v8i16, { 2, 1, 1, 1 } },
2961 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v4i32, { 1, 1, 1, 1 } },
2962 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v8i32, { 1, 1, 1, 1 } },
2963 { ISD::SINT_TO_FP, MVT::v8f64, MVT::v8i32, { 3, 1, 1, 1 } },
2964
2965 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v16i8, { 2, 1, 1, 1 } },
2966 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v16i8, { 2, 1, 1, 1 } },
2967 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v8i16, { 2, 1, 1, 1 } },
2968 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i16, { 2, 1, 1, 1 } },
2969 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i32, { 2, 1, 1, 1 } },
2970 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i32, { 1, 1, 1, 1 } },
2971 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i32, { 2, 1, 1, 1 } },
2972 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i32, { 2, 1, 1, 1 } },
2973 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i32, { 2, 1, 1, 1 } },
2974 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i32, { 4, 1, 1, 1 } },
2975 };
2976
2977 static const TypeConversionCostKindTblEntry AVXConversionTbl[] = {
2978 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i1, { 4, 1, 1, 1 } },
2979 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i1, { 4, 1, 1, 1 } },
2980 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i1, { 4, 1, 1, 1 } },
2981 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i1, { 4, 1, 1, 1 } },
2982 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i1, { 4, 1, 1, 1 } },
2983 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i1, { 4, 1, 1, 1 } },
2984
2985 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v16i8, { 3, 1, 1, 1 } },
2986 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v16i8, { 3, 1, 1, 1 } },
2987 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v16i8, { 3, 1, 1, 1 } },
2988 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v16i8, { 3, 1, 1, 1 } },
2989 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i8, { 3, 1, 1, 1 } },
2990 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i8, { 3, 1, 1, 1 } },
2991 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v8i16, { 3, 1, 1, 1 } },
2992 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v8i16, { 3, 1, 1, 1 } },
2993 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i16, { 3, 1, 1, 1 } },
2994 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i16, { 3, 1, 1, 1 } },
2995 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i32, { 3, 1, 1, 1 } },
2996 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i32, { 3, 1, 1, 1 } },
2997
2998 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i64, { 4, 1, 1, 1 } },
2999 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i32, { 5, 1, 1, 1 } },
3000 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i16, { 4, 1, 1, 1 } },
3001 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i64, { 9, 1, 1, 1 } },
3002 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i64, {11, 1, 1, 1 } },
3003
3004 { ISD::TRUNCATE, MVT::v16i16, MVT::v16i32, { 6, 1, 1, 1 } },
3005 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i32, { 6, 1, 1, 1 } },
3006 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i16, { 2, 1, 1, 1 } }, // and+extract+packuswb
3007 { ISD::TRUNCATE, MVT::v16i8, MVT::v8i32, { 5, 1, 1, 1 } },
3008 { ISD::TRUNCATE, MVT::v8i16, MVT::v8i32, { 5, 1, 1, 1 } },
3009 { ISD::TRUNCATE, MVT::v16i8, MVT::v4i64, { 5, 1, 1, 1 } },
3010 { ISD::TRUNCATE, MVT::v8i16, MVT::v4i64, { 3, 1, 1, 1 } }, // and+extract+2*packusdw
3011 { ISD::TRUNCATE, MVT::v4i32, MVT::v4i64, { 2, 1, 1, 1 } },
3012
3013 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v4i1, { 3, 1, 1, 1 } },
3014 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v4i1, { 3, 1, 1, 1 } },
3015 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v8i1, { 8, 1, 1, 1 } },
3016 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v16i8, { 4, 1, 1, 1 } },
3017 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v16i8, { 2, 1, 1, 1 } },
3018 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v8i16, { 4, 1, 1, 1 } },
3019 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v8i16, { 2, 1, 1, 1 } },
3020 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v4i32, { 2, 1, 1, 1 } },
3021 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v8i32, { 2, 1, 1, 1 } },
3022 { ISD::SINT_TO_FP, MVT::v8f64, MVT::v8i32, { 4, 1, 1, 1 } },
3023 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v2i64, { 5, 1, 1, 1 } },
3024 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v4i64, { 8, 1, 1, 1 } },
3025
3026 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i1, { 7, 1, 1, 1 } },
3027 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i1, { 7, 1, 1, 1 } },
3028 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i1, { 6, 1, 1, 1 } },
3029 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v16i8, { 4, 1, 1, 1 } },
3030 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v16i8, { 2, 1, 1, 1 } },
3031 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i16, { 4, 1, 1, 1 } },
3032 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v8i16, { 2, 1, 1, 1 } },
3033 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i32, { 4, 1, 1, 1 } },
3034 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i32, { 4, 1, 1, 1 } },
3035 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i32, { 5, 1, 1, 1 } },
3036 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i32, { 6, 1, 1, 1 } },
3037 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i32, { 8, 1, 1, 1 } },
3038 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i32, {10, 1, 1, 1 } },
3039 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i64, {10, 1, 1, 1 } },
3040 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i64, {18, 1, 1, 1 } },
3041 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i64, { 5, 1, 1, 1 } },
3042 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i64, {10, 1, 1, 1 } },
3043
3044 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v8f32, { 2, 1, 1, 1 } },
3045 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v4f64, { 2, 1, 1, 1 } },
3046 { ISD::FP_TO_SINT, MVT::v32i8, MVT::v8f32, { 2, 1, 1, 1 } },
3047 { ISD::FP_TO_SINT, MVT::v32i8, MVT::v4f64, { 2, 1, 1, 1 } },
3048 { ISD::FP_TO_SINT, MVT::v8i16, MVT::v8f32, { 2, 1, 1, 1 } },
3049 { ISD::FP_TO_SINT, MVT::v8i16, MVT::v4f64, { 2, 1, 1, 1 } },
3050 { ISD::FP_TO_SINT, MVT::v16i16, MVT::v8f32, { 2, 1, 1, 1 } },
3051 { ISD::FP_TO_SINT, MVT::v16i16, MVT::v4f64, { 2, 1, 1, 1 } },
3052 { ISD::FP_TO_SINT, MVT::v4i32, MVT::v4f64, { 2, 1, 1, 1 } },
3053 { ISD::FP_TO_SINT, MVT::v8i32, MVT::v8f32, { 2, 1, 1, 1 } },
3054 { ISD::FP_TO_SINT, MVT::v8i32, MVT::v8f64, { 5, 1, 1, 1 } },
3055
3056 { ISD::FP_TO_UINT, MVT::v16i8, MVT::v8f32, { 2, 1, 1, 1 } },
3057 { ISD::FP_TO_UINT, MVT::v16i8, MVT::v4f64, { 2, 1, 1, 1 } },
3058 { ISD::FP_TO_UINT, MVT::v32i8, MVT::v8f32, { 2, 1, 1, 1 } },
3059 { ISD::FP_TO_UINT, MVT::v32i8, MVT::v4f64, { 2, 1, 1, 1 } },
3060 { ISD::FP_TO_UINT, MVT::v8i16, MVT::v8f32, { 2, 1, 1, 1 } },
3061 { ISD::FP_TO_UINT, MVT::v8i16, MVT::v4f64, { 2, 1, 1, 1 } },
3062 { ISD::FP_TO_UINT, MVT::v16i16, MVT::v8f32, { 2, 1, 1, 1 } },
3063 { ISD::FP_TO_UINT, MVT::v16i16, MVT::v4f64, { 2, 1, 1, 1 } },
3064 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f32, { 3, 1, 1, 1 } },
3065 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v2f64, { 4, 1, 1, 1 } },
3066 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f64, { 6, 1, 1, 1 } },
3067 { ISD::FP_TO_UINT, MVT::v8i32, MVT::v8f32, { 7, 1, 1, 1 } },
3068 { ISD::FP_TO_UINT, MVT::v8i32, MVT::v4f64, { 7, 1, 1, 1 } },
3069
3070 { ISD::FP_EXTEND, MVT::v4f64, MVT::v4f32, { 1, 1, 1, 1 } },
3071 { ISD::FP_ROUND, MVT::v4f32, MVT::v4f64, { 1, 1, 1, 1 } },
3072 };
3073
3074 static const TypeConversionCostKindTblEntry SSE41ConversionTbl[] = {
3075 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v16i8, { 1, 1, 1, 1 } },
3076 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v16i8, { 1, 1, 1, 1 } },
3077 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v16i8, { 1, 1, 1, 1 } },
3078 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v16i8, { 1, 1, 1, 1 } },
3079 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v16i8, { 1, 1, 1, 1 } },
3080 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v16i8, { 1, 1, 1, 1 } },
3081 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v8i16, { 1, 1, 1, 1 } },
3082 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v8i16, { 1, 1, 1, 1 } },
3083 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v8i16, { 1, 1, 1, 1 } },
3084 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v8i16, { 1, 1, 1, 1 } },
3085 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v4i32, { 1, 1, 1, 1 } },
3086 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v4i32, { 1, 1, 1, 1 } },
3087
3088 // These truncates end up widening elements.
3089 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i8, { 1, 1, 1, 1 } }, // PMOVXZBQ
3090 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i16, { 1, 1, 1, 1 } }, // PMOVXZWQ
3091 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i8, { 1, 1, 1, 1 } }, // PMOVXZBD
3092
3093 { ISD::TRUNCATE, MVT::v16i8, MVT::v4i32, { 2, 1, 1, 1 } },
3094 { ISD::TRUNCATE, MVT::v8i16, MVT::v4i32, { 2, 1, 1, 1 } },
3095 { ISD::TRUNCATE, MVT::v16i8, MVT::v2i64, { 2, 1, 1, 1 } },
3096
3097 { ISD::SINT_TO_FP, MVT::f32, MVT::i32, { 1, 1, 1, 1 } },
3098 { ISD::SINT_TO_FP, MVT::f64, MVT::i32, { 1, 1, 1, 1 } },
3099 { ISD::SINT_TO_FP, MVT::f32, MVT::i64, { 1, 1, 1, 1 } },
3100 { ISD::SINT_TO_FP, MVT::f64, MVT::i64, { 1, 1, 1, 1 } },
3101 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v16i8, { 1, 1, 1, 1 } },
3102 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v16i8, { 1, 1, 1, 1 } },
3103 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v8i16, { 1, 1, 1, 1 } },
3104 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v8i16, { 1, 1, 1, 1 } },
3105 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v4i32, { 1, 1, 1, 1 } },
3106 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v4i32, { 1, 1, 1, 1 } },
3107 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v4i32, { 2, 1, 1, 1 } },
3108
3109 { ISD::UINT_TO_FP, MVT::f32, MVT::i32, { 1, 1, 1, 1 } },
3110 { ISD::UINT_TO_FP, MVT::f64, MVT::i32, { 1, 1, 1, 1 } },
3111 { ISD::UINT_TO_FP, MVT::f32, MVT::i64, { 4, 1, 1, 1 } },
3112 { ISD::UINT_TO_FP, MVT::f64, MVT::i64, { 4, 1, 1, 1 } },
3113 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v16i8, { 1, 1, 1, 1 } },
3114 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v16i8, { 1, 1, 1, 1 } },
3115 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v8i16, { 1, 1, 1, 1 } },
3116 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v8i16, { 1, 1, 1, 1 } },
3117 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i32, { 3, 1, 1, 1 } },
3118 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i32, { 3, 1, 1, 1 } },
3119 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v4i32, { 2, 1, 1, 1 } },
3120 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v2i64, {12, 1, 1, 1 } },
3121 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i64, {22, 1, 1, 1 } },
3122 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i64, { 4, 1, 1, 1 } },
3123
3124 { ISD::FP_TO_SINT, MVT::i32, MVT::f32, { 1, 1, 1, 1 } },
3125 { ISD::FP_TO_SINT, MVT::i64, MVT::f32, { 1, 1, 1, 1 } },
3126 { ISD::FP_TO_SINT, MVT::i32, MVT::f64, { 1, 1, 1, 1 } },
3127 { ISD::FP_TO_SINT, MVT::i64, MVT::f64, { 1, 1, 1, 1 } },
3128 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v4f32, { 2, 1, 1, 1 } },
3129 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v2f64, { 2, 1, 1, 1 } },
3130 { ISD::FP_TO_SINT, MVT::v8i16, MVT::v4f32, { 1, 1, 1, 1 } },
3131 { ISD::FP_TO_SINT, MVT::v8i16, MVT::v2f64, { 1, 1, 1, 1 } },
3132 { ISD::FP_TO_SINT, MVT::v4i32, MVT::v4f32, { 1, 1, 1, 1 } },
3133 { ISD::FP_TO_SINT, MVT::v4i32, MVT::v2f64, { 1, 1, 1, 1 } },
3134
3135 { ISD::FP_TO_UINT, MVT::i32, MVT::f32, { 1, 1, 1, 1 } },
3136 { ISD::FP_TO_UINT, MVT::i64, MVT::f32, { 4, 1, 1, 1 } },
3137 { ISD::FP_TO_UINT, MVT::i32, MVT::f64, { 1, 1, 1, 1 } },
3138 { ISD::FP_TO_UINT, MVT::i64, MVT::f64, { 4, 1, 1, 1 } },
3139 { ISD::FP_TO_UINT, MVT::v16i8, MVT::v4f32, { 2, 1, 1, 1 } },
3140 { ISD::FP_TO_UINT, MVT::v16i8, MVT::v2f64, { 2, 1, 1, 1 } },
3141 { ISD::FP_TO_UINT, MVT::v8i16, MVT::v4f32, { 1, 1, 1, 1 } },
3142 { ISD::FP_TO_UINT, MVT::v8i16, MVT::v2f64, { 1, 1, 1, 1 } },
3143 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f32, { 4, 1, 1, 1 } },
3144 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v2f64, { 4, 1, 1, 1 } },
3145 };
3146
3147 static const TypeConversionCostKindTblEntry SSE2ConversionTbl[] = {
3148 // These are somewhat magic numbers justified by comparing the
3149 // output of llvm-mca for our various supported scheduler models
3150 // and basing it off the worst case scenario.
3151 { ISD::SINT_TO_FP, MVT::f32, MVT::i32, { 3, 1, 1, 1 } },
3152 { ISD::SINT_TO_FP, MVT::f64, MVT::i32, { 3, 1, 1, 1 } },
3153 { ISD::SINT_TO_FP, MVT::f32, MVT::i64, { 3, 1, 1, 1 } },
3154 { ISD::SINT_TO_FP, MVT::f64, MVT::i64, { 3, 1, 1, 1 } },
3155 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v16i8, { 3, 1, 1, 1 } },
3156 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v16i8, { 4, 1, 1, 1 } },
3157 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v8i16, { 3, 1, 1, 1 } },
3158 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v8i16, { 4, 1, 1, 1 } },
3159 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v4i32, { 3, 1, 1, 1 } },
3160 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v4i32, { 4, 1, 1, 1 } },
3161 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v2i64, { 8, 1, 1, 1 } },
3162 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v2i64, { 8, 1, 1, 1 } },
3163
3164 { ISD::UINT_TO_FP, MVT::f32, MVT::i32, { 3, 1, 1, 1 } },
3165 { ISD::UINT_TO_FP, MVT::f64, MVT::i32, { 3, 1, 1, 1 } },
3166 { ISD::UINT_TO_FP, MVT::f32, MVT::i64, { 8, 1, 1, 1 } },
3167 { ISD::UINT_TO_FP, MVT::f64, MVT::i64, { 9, 1, 1, 1 } },
3168 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v16i8, { 4, 1, 1, 1 } },
3169 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v16i8, { 4, 1, 1, 1 } },
3170 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v8i16, { 4, 1, 1, 1 } },
3171 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v8i16, { 4, 1, 1, 1 } },
3172 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i32, { 7, 1, 1, 1 } },
3173 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v4i32, { 7, 1, 1, 1 } },
3174 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i32, { 5, 1, 1, 1 } },
3175 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i64, {15, 1, 1, 1 } },
3176 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v2i64, {18, 1, 1, 1 } },
3177
3178 { ISD::FP_TO_SINT, MVT::i32, MVT::f32, { 4, 1, 1, 1 } },
3179 { ISD::FP_TO_SINT, MVT::i64, MVT::f32, { 4, 1, 1, 1 } },
3180 { ISD::FP_TO_SINT, MVT::i32, MVT::f64, { 4, 1, 1, 1 } },
3181 { ISD::FP_TO_SINT, MVT::i64, MVT::f64, { 4, 1, 1, 1 } },
3182 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v4f32, { 6, 1, 1, 1 } },
3183 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v2f64, { 6, 1, 1, 1 } },
3184 { ISD::FP_TO_SINT, MVT::v8i16, MVT::v4f32, { 5, 1, 1, 1 } },
3185 { ISD::FP_TO_SINT, MVT::v8i16, MVT::v2f64, { 5, 1, 1, 1 } },
3186 { ISD::FP_TO_SINT, MVT::v4i32, MVT::v4f32, { 4, 1, 1, 1 } },
3187 { ISD::FP_TO_SINT, MVT::v4i32, MVT::v2f64, { 4, 1, 1, 1 } },
3188
3189 { ISD::FP_TO_UINT, MVT::i32, MVT::f32, { 4, 1, 1, 1 } },
3190 { ISD::FP_TO_UINT, MVT::i64, MVT::f32, { 4, 1, 1, 1 } },
3191 { ISD::FP_TO_UINT, MVT::i32, MVT::f64, { 4, 1, 1, 1 } },
3192 { ISD::FP_TO_UINT, MVT::i64, MVT::f64, {15, 1, 1, 1 } },
3193 { ISD::FP_TO_UINT, MVT::v16i8, MVT::v4f32, { 6, 1, 1, 1 } },
3194 { ISD::FP_TO_UINT, MVT::v16i8, MVT::v2f64, { 6, 1, 1, 1 } },
3195 { ISD::FP_TO_UINT, MVT::v8i16, MVT::v4f32, { 5, 1, 1, 1 } },
3196 { ISD::FP_TO_UINT, MVT::v8i16, MVT::v2f64, { 5, 1, 1, 1 } },
3197 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f32, { 8, 1, 1, 1 } },
3198 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v2f64, { 8, 1, 1, 1 } },
3199
3200 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v16i8, { 4, 1, 1, 1 } },
3201 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v16i8, { 4, 1, 1, 1 } },
3202 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v16i8, { 2, 1, 1, 1 } },
3203 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v16i8, { 3, 1, 1, 1 } },
3204 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v16i8, { 1, 1, 1, 1 } },
3205 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v16i8, { 2, 1, 1, 1 } },
3206 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v8i16, { 2, 1, 1, 1 } },
3207 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v8i16, { 3, 1, 1, 1 } },
3208 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v8i16, { 1, 1, 1, 1 } },
3209 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v8i16, { 2, 1, 1, 1 } },
3210 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v4i32, { 1, 1, 1, 1 } },
3211 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v4i32, { 2, 1, 1, 1 } },
3212
3213 // These truncates are really widening elements.
3214 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i32, { 1, 1, 1, 1 } }, // PSHUFD
3215 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i16, { 2, 1, 1, 1 } }, // PUNPCKLWD+DQ
3216 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i8, { 3, 1, 1, 1 } }, // PUNPCKLBW+WD+PSHUFD
3217 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i16, { 1, 1, 1, 1 } }, // PUNPCKLWD
3218 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i8, { 2, 1, 1, 1 } }, // PUNPCKLBW+WD
3219 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i8, { 1, 1, 1, 1 } }, // PUNPCKLBW
3220
3221 { ISD::TRUNCATE, MVT::v16i8, MVT::v8i16, { 2, 1, 1, 1 } }, // PAND+PACKUSWB
3222 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i16, { 3, 1, 1, 1 } },
3223 { ISD::TRUNCATE, MVT::v16i8, MVT::v4i32, { 3, 1, 1, 1 } }, // PAND+2*PACKUSWB
3224 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i32, { 7, 1, 1, 1 } },
3225 { ISD::TRUNCATE, MVT::v2i16, MVT::v2i32, { 1, 1, 1, 1 } },
3226 { ISD::TRUNCATE, MVT::v8i16, MVT::v4i32, { 3, 1, 1, 1 } },
3227 { ISD::TRUNCATE, MVT::v8i16, MVT::v8i32, { 5, 1, 1, 1 } },
3228 { ISD::TRUNCATE, MVT::v16i16, MVT::v16i32, {10, 1, 1, 1 } },
3229 { ISD::TRUNCATE, MVT::v16i8, MVT::v2i64, { 4, 1, 1, 1 } }, // PAND+3*PACKUSWB
3230 { ISD::TRUNCATE, MVT::v8i16, MVT::v2i64, { 2, 1, 1, 1 } }, // PSHUFD+PSHUFLW
3231 { ISD::TRUNCATE, MVT::v4i32, MVT::v2i64, { 1, 1, 1, 1 } }, // PSHUFD
3232 };
3233
3234 static const TypeConversionCostKindTblEntry F16ConversionTbl[] = {
3235 { ISD::FP_ROUND, MVT::f16, MVT::f32, { 1, 1, 1, 1 } },
3236 { ISD::FP_ROUND, MVT::v8f16, MVT::v8f32, { 1, 1, 1, 1 } },
3237 { ISD::FP_ROUND, MVT::v4f16, MVT::v4f32, { 1, 1, 1, 1 } },
3238 { ISD::FP_EXTEND, MVT::f32, MVT::f16, { 1, 1, 1, 1 } },
3239 { ISD::FP_EXTEND, MVT::f64, MVT::f16, { 2, 1, 1, 1 } }, // vcvtph2ps+vcvtps2pd
3240 { ISD::FP_EXTEND, MVT::v8f32, MVT::v8f16, { 1, 1, 1, 1 } },
3241 { ISD::FP_EXTEND, MVT::v4f32, MVT::v4f16, { 1, 1, 1, 1 } },
3242 { ISD::FP_EXTEND, MVT::v4f64, MVT::v4f16, { 2, 1, 1, 1 } }, // vcvtph2ps+vcvtps2pd
3243 };
3244
3245 // Attempt to map directly to (simple) MVT types to let us match custom entries.
3246 EVT SrcTy = TLI->getValueType(DL, Src);
3247 EVT DstTy = TLI->getValueType(DL, Dst);
3248
3249 // If we're sign-extending a vector comparison result back to the comparison
3250 // width, this will be free without AVX512 (or for 8/16-bit types without
3251 // BWI).
3252 if (!ST->hasAVX512() || (!ST->hasBWI() && DstTy.getScalarSizeInBits() < 32)) {
3253 if (I && Opcode == Instruction::CastOps::SExt &&
3254 SrcTy.isFixedLengthVectorOf(MVT::i1)) {
3255 if (auto *CmpI = dyn_cast<CmpInst>(I->getOperand(0))) {
3256 Type *CmpTy = CmpI->getOperand(0)->getType();
3257 if (CmpTy->getScalarSizeInBits() == DstTy.getScalarSizeInBits())
3258 return TTI::TCC_Free;
3259 }
3260 }
3261 }
3262
3263 // The function getSimpleVT only handles simple value types.
3264 if (SrcTy.isSimple() && DstTy.isSimple()) {
3265 MVT SimpleSrcTy = SrcTy.getSimpleVT();
3266 MVT SimpleDstTy = DstTy.getSimpleVT();
3267
3268 if (ST->useAVX512Regs()) {
3269 if (ST->hasBWI())
3270 if (const auto *Entry = ConvertCostTableLookup(
3271 AVX512BWConversionTbl, ISD, SimpleDstTy, SimpleSrcTy))
3272 if (auto KindCost = Entry->Cost[CostKind])
3273 return *KindCost;
3274
3275 if (ST->hasDQI())
3276 if (const auto *Entry = ConvertCostTableLookup(
3277 AVX512DQConversionTbl, ISD, SimpleDstTy, SimpleSrcTy))
3278 if (auto KindCost = Entry->Cost[CostKind])
3279 return *KindCost;
3280
3281 if (ST->hasAVX512())
3282 if (const auto *Entry = ConvertCostTableLookup(
3283 AVX512FConversionTbl, ISD, SimpleDstTy, SimpleSrcTy))
3284 if (auto KindCost = Entry->Cost[CostKind])
3285 return *KindCost;
3286 }
3287
3288 if (ST->hasBWI())
3289 if (const auto *Entry = ConvertCostTableLookup(
3290 AVX512BWVLConversionTbl, ISD, SimpleDstTy, SimpleSrcTy))
3291 if (auto KindCost = Entry->Cost[CostKind])
3292 return *KindCost;
3293
3294 if (ST->hasDQI())
3295 if (const auto *Entry = ConvertCostTableLookup(
3296 AVX512DQVLConversionTbl, ISD, SimpleDstTy, SimpleSrcTy))
3297 if (auto KindCost = Entry->Cost[CostKind])
3298 return *KindCost;
3299
3300 if (ST->hasAVX512())
3301 if (const auto *Entry = ConvertCostTableLookup(AVX512VLConversionTbl, ISD,
3302 SimpleDstTy, SimpleSrcTy))
3303 if (auto KindCost = Entry->Cost[CostKind])
3304 return *KindCost;
3305
3306 if (ST->hasAVX2()) {
3307 if (const auto *Entry = ConvertCostTableLookup(AVX2ConversionTbl, ISD,
3308 SimpleDstTy, SimpleSrcTy))
3309 if (auto KindCost = Entry->Cost[CostKind])
3310 return *KindCost;
3311 }
3312
3313 if (ST->hasAVX()) {
3314 if (const auto *Entry = ConvertCostTableLookup(AVXConversionTbl, ISD,
3315 SimpleDstTy, SimpleSrcTy))
3316 if (auto KindCost = Entry->Cost[CostKind])
3317 return *KindCost;
3318 }
3319
3320 if (ST->hasF16C()) {
3321 if (const auto *Entry = ConvertCostTableLookup(F16ConversionTbl, ISD,
3322 SimpleDstTy, SimpleSrcTy))
3323 if (auto KindCost = Entry->Cost[CostKind])
3324 return *KindCost;
3325 }
3326
3327 if (ST->hasSSE41()) {
3328 if (const auto *Entry = ConvertCostTableLookup(SSE41ConversionTbl, ISD,
3329 SimpleDstTy, SimpleSrcTy))
3330 if (auto KindCost = Entry->Cost[CostKind])
3331 return *KindCost;
3332 }
3333
3334 if (ST->hasSSE2()) {
3335 if (const auto *Entry = ConvertCostTableLookup(SSE2ConversionTbl, ISD,
3336 SimpleDstTy, SimpleSrcTy))
3337 if (auto KindCost = Entry->Cost[CostKind])
3338 return *KindCost;
3339 }
3340
3341 if ((ISD == ISD::FP_ROUND && SimpleDstTy == MVT::f16) ||
3342 (ISD == ISD::FP_EXTEND && SimpleSrcTy == MVT::f16)) {
3343 // fp16 conversions not covered by any table entries require a libcall.
3344 // Return a large (arbitrary) number to model this.
3345 return InstructionCost(64);
3346 }
3347 }
3348
3349 // Fall back to legalized types.
3350 std::pair<InstructionCost, MVT> LTSrc = getTypeLegalizationCost(Src);
3351 std::pair<InstructionCost, MVT> LTDest = getTypeLegalizationCost(Dst);
3352
3353 // If we're truncating to the same legalized type - just assume its free.
3354 if (ISD == ISD::TRUNCATE && LTSrc.second == LTDest.second)
3355 return TTI::TCC_Free;
3356
3357 if (ST->useAVX512Regs()) {
3358 if (ST->hasBWI())
3359 if (const auto *Entry = ConvertCostTableLookup(
3360 AVX512BWConversionTbl, ISD, LTDest.second, LTSrc.second))
3361 if (auto KindCost = Entry->Cost[CostKind])
3362 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3363
3364 if (ST->hasDQI())
3365 if (const auto *Entry = ConvertCostTableLookup(
3366 AVX512DQConversionTbl, ISD, LTDest.second, LTSrc.second))
3367 if (auto KindCost = Entry->Cost[CostKind])
3368 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3369
3370 if (ST->hasAVX512())
3371 if (const auto *Entry = ConvertCostTableLookup(
3372 AVX512FConversionTbl, ISD, LTDest.second, LTSrc.second))
3373 if (auto KindCost = Entry->Cost[CostKind])
3374 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3375 }
3376
3377 if (ST->hasBWI())
3378 if (const auto *Entry = ConvertCostTableLookup(AVX512BWVLConversionTbl, ISD,
3379 LTDest.second, LTSrc.second))
3380 if (auto KindCost = Entry->Cost[CostKind])
3381 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3382
3383 if (ST->hasDQI())
3384 if (const auto *Entry = ConvertCostTableLookup(AVX512DQVLConversionTbl, ISD,
3385 LTDest.second, LTSrc.second))
3386 if (auto KindCost = Entry->Cost[CostKind])
3387 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3388
3389 if (ST->hasAVX512())
3390 if (const auto *Entry = ConvertCostTableLookup(AVX512VLConversionTbl, ISD,
3391 LTDest.second, LTSrc.second))
3392 if (auto KindCost = Entry->Cost[CostKind])
3393 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3394
3395 if (ST->hasAVX2())
3396 if (const auto *Entry = ConvertCostTableLookup(AVX2ConversionTbl, ISD,
3397 LTDest.second, LTSrc.second))
3398 if (auto KindCost = Entry->Cost[CostKind])
3399 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3400
3401 if (ST->hasAVX())
3402 if (const auto *Entry = ConvertCostTableLookup(AVXConversionTbl, ISD,
3403 LTDest.second, LTSrc.second))
3404 if (auto KindCost = Entry->Cost[CostKind])
3405 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3406
3407 if (ST->hasF16C()) {
3408 if (const auto *Entry = ConvertCostTableLookup(F16ConversionTbl, ISD,
3409 LTDest.second, LTSrc.second))
3410 if (auto KindCost = Entry->Cost[CostKind])
3411 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3412 }
3413
3414 if (ST->hasSSE41())
3415 if (const auto *Entry = ConvertCostTableLookup(SSE41ConversionTbl, ISD,
3416 LTDest.second, LTSrc.second))
3417 if (auto KindCost = Entry->Cost[CostKind])
3418 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3419
3420 if (ST->hasSSE2())
3421 if (const auto *Entry = ConvertCostTableLookup(SSE2ConversionTbl, ISD,
3422 LTDest.second, LTSrc.second))
3423 if (auto KindCost = Entry->Cost[CostKind])
3424 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3425
3426 // Fallback, for i8/i16 sitofp/uitofp cases we need to extend to i32 for
3427 // sitofp.
3428 if ((ISD == ISD::SINT_TO_FP || ISD == ISD::UINT_TO_FP) &&
3429 1 < Src->getScalarSizeInBits() && Src->getScalarSizeInBits() < 32) {
3430 Type *ExtSrc = Src->getWithNewBitWidth(32);
3431 unsigned ExtOpc =
3432 (ISD == ISD::SINT_TO_FP) ? Instruction::SExt : Instruction::ZExt;
3433
3434 // For scalar loads the extend would be free.
3435 InstructionCost ExtCost = 0;
3436 if (!(Src->isIntegerTy() && I && isa<LoadInst>(I->getOperand(0))))
3437 ExtCost = getCastInstrCost(ExtOpc, ExtSrc, Src, CCH, CostKind);
3438
3439 return ExtCost + getCastInstrCost(Instruction::SIToFP, Dst, ExtSrc,
3441 }
3442
3443 // Fallback for fptosi/fptoui i8/i16 cases we need to truncate from fptosi
3444 // i32.
3445 if ((ISD == ISD::FP_TO_SINT || ISD == ISD::FP_TO_UINT) &&
3446 1 < Dst->getScalarSizeInBits() && Dst->getScalarSizeInBits() < 32) {
3447 Type *TruncDst = Dst->getWithNewBitWidth(32);
3448 return getCastInstrCost(Instruction::FPToSI, TruncDst, Src, CCH, CostKind) +
3449 getCastInstrCost(Instruction::Trunc, Dst, TruncDst,
3451 }
3452
3453 // TODO: Allow non-throughput costs that aren't binary.
3454 auto AdjustCost = [&CostKind](InstructionCost Cost,
3457 return Cost == 0 ? 0 : N;
3458 return Cost * N;
3459 };
3460 return AdjustCost(
3461 BaseT::getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I));
3462}
3463
3465 unsigned Opcode, Type *ValTy, Type *CondTy, CmpInst::Predicate VecPred,
3467 TTI::OperandValueInfo Op2Info, const Instruction *I) const {
3468 // Early out if this type isn't scalar/vector integer/float.
3469 if (!(ValTy->isIntOrIntVectorTy() || ValTy->isFPOrFPVectorTy()))
3470 return BaseT::getCmpSelInstrCost(Opcode, ValTy, CondTy, VecPred, CostKind,
3471 Op1Info, Op2Info, I);
3472
3473 // Legalize the type.
3474 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(ValTy);
3475
3476 MVT MTy = LT.second;
3477
3478 int ISD = TLI->InstructionOpcodeToISD(Opcode);
3479 assert(ISD && "Invalid opcode");
3480
3481 InstructionCost ExtraCost = 0;
3482 if (Opcode == Instruction::ICmp || Opcode == Instruction::FCmp) {
3483 // Some vector comparison predicates cost extra instructions.
3484 // TODO: Adjust ExtraCost based on CostKind?
3485 // TODO: Should we invert this and assume worst case cmp costs
3486 // and reduce for particular predicates?
3487 if (MTy.isVector() &&
3488 !((ST->hasXOP() && (!ST->hasAVX2() || MTy.is128BitVector())) ||
3489 (ST->hasAVX512() && 32 <= MTy.getScalarSizeInBits()) ||
3490 ST->hasBWI())) {
3491 // Fallback to I if a specific predicate wasn't specified.
3492 CmpInst::Predicate Pred = VecPred;
3493 if (I && (Pred == CmpInst::BAD_ICMP_PREDICATE ||
3495 Pred = cast<CmpInst>(I)->getPredicate();
3496
3497 bool CmpWithConstant = false;
3498 if (auto *CmpInstr = dyn_cast_or_null<CmpInst>(I))
3499 CmpWithConstant = isa<Constant>(CmpInstr->getOperand(1));
3500
3501 switch (Pred) {
3503 // xor(cmpeq(x,y),-1)
3504 ExtraCost = CmpWithConstant ? 0 : 1;
3505 break;
3508 // xor(cmpgt(x,y),-1)
3509 ExtraCost = CmpWithConstant ? 0 : 1;
3510 break;
3513 // cmpgt(xor(x,signbit),xor(y,signbit))
3514 // xor(cmpeq(pmaxu(x,y),x),-1)
3515 ExtraCost = CmpWithConstant ? 1 : 2;
3516 break;
3519 if ((ST->hasSSE41() && MTy.getScalarSizeInBits() == 32) ||
3520 (ST->hasSSE2() && MTy.getScalarSizeInBits() < 32)) {
3521 // cmpeq(psubus(x,y),0)
3522 // cmpeq(pminu(x,y),x)
3523 ExtraCost = 1;
3524 } else {
3525 // xor(cmpgt(xor(x,signbit),xor(y,signbit)),-1)
3526 ExtraCost = CmpWithConstant ? 2 : 3;
3527 }
3528 break;
3531 // Without AVX we need to expand FCMP_ONE/FCMP_UEQ cases.
3532 // Use FCMP_UEQ expansion - FCMP_ONE should be the same.
3533 if (CondTy && !ST->hasAVX())
3534 return getCmpSelInstrCost(Opcode, ValTy, CondTy,
3536 Op1Info, Op2Info) +
3537 getCmpSelInstrCost(Opcode, ValTy, CondTy,
3539 Op1Info, Op2Info) +
3540 getArithmeticInstrCost(Instruction::Or, CondTy, CostKind);
3541
3542 break;
3545 // Assume worst case scenario and add the maximum extra cost.
3546 ExtraCost = 3;
3547 break;
3548 default:
3549 break;
3550 }
3551 }
3552 }
3553
3554 static const CostKindTblEntry SLMCostTbl[] = {
3555 // slm pcmpeq/pcmpgt throughput is 2
3556 { ISD::SETCC, MVT::v2i64, { 2, 5, 1, 2 } },
3557 // slm pblendvb/blendvpd/blendvps throughput is 4
3558 { ISD::SELECT, MVT::v2f64, { 4, 4, 1, 3 } }, // vblendvpd
3559 { ISD::SELECT, MVT::v4f32, { 4, 4, 1, 3 } }, // vblendvps
3560 { ISD::SELECT, MVT::v2i64, { 4, 4, 1, 3 } }, // pblendvb
3561 { ISD::SELECT, MVT::v8i32, { 4, 4, 1, 3 } }, // pblendvb
3562 { ISD::SELECT, MVT::v8i16, { 4, 4, 1, 3 } }, // pblendvb
3563 { ISD::SELECT, MVT::v16i8, { 4, 4, 1, 3 } }, // pblendvb
3564 };
3565
3566 static const CostKindTblEntry AVX512BWCostTbl[] = {
3567 { ISD::SETCC, MVT::v32i16, { 1, 1, 1, 1 } },
3568 { ISD::SETCC, MVT::v16i16, { 1, 1, 1, 1 } },
3569 { ISD::SETCC, MVT::v64i8, { 1, 1, 1, 1 } },
3570 { ISD::SETCC, MVT::v32i8, { 1, 1, 1, 1 } },
3571
3572 { ISD::SELECT, MVT::v32i16, { 1, 1, 1, 1 } },
3573 { ISD::SELECT, MVT::v64i8, { 1, 1, 1, 1 } },
3574 };
3575
3576 static const CostKindTblEntry AVX512CostTbl[] = {
3577 { ISD::SETCC, MVT::v8f64, { 1, 4, 1, 1 } },
3578 { ISD::SETCC, MVT::v4f64, { 1, 4, 1, 1 } },
3579 { ISD::SETCC, MVT::v16f32, { 1, 4, 1, 1 } },
3580 { ISD::SETCC, MVT::v8f32, { 1, 4, 1, 1 } },
3581
3582 { ISD::SETCC, MVT::v8i64, { 1, 1, 1, 1 } },
3583 { ISD::SETCC, MVT::v4i64, { 1, 1, 1, 1 } },
3584 { ISD::SETCC, MVT::v2i64, { 1, 1, 1, 1 } },
3585 { ISD::SETCC, MVT::v16i32, { 1, 1, 1, 1 } },
3586 { ISD::SETCC, MVT::v8i32, { 1, 1, 1, 1 } },
3587 { ISD::SETCC, MVT::v32i16, { 3, 7, 5, 5 } },
3588 { ISD::SETCC, MVT::v64i8, { 3, 7, 5, 5 } },
3589
3590 { ISD::SELECT, MVT::v8i64, { 1, 1, 1, 1 } },
3591 { ISD::SELECT, MVT::v4i64, { 1, 1, 1, 1 } },
3592 { ISD::SELECT, MVT::v2i64, { 1, 1, 1, 1 } },
3593 { ISD::SELECT, MVT::v16i32, { 1, 1, 1, 1 } },
3594 { ISD::SELECT, MVT::v8i32, { 1, 1, 1, 1 } },
3595 { ISD::SELECT, MVT::v4i32, { 1, 1, 1, 1 } },
3596 { ISD::SELECT, MVT::v8f64, { 1, 1, 1, 1 } },
3597 { ISD::SELECT, MVT::v4f64, { 1, 1, 1, 1 } },
3598 { ISD::SELECT, MVT::v2f64, { 1, 1, 1, 1 } },
3599 { ISD::SELECT, MVT::f64, { 1, 1, 1, 1 } },
3600 { ISD::SELECT, MVT::v16f32, { 1, 1, 1, 1 } },
3601 { ISD::SELECT, MVT::v8f32 , { 1, 1, 1, 1 } },
3602 { ISD::SELECT, MVT::v4f32, { 1, 1, 1, 1 } },
3603 { ISD::SELECT, MVT::f32 , { 1, 1, 1, 1 } },
3604
3605 { ISD::SELECT, MVT::v32i16, { 2, 2, 4, 4 } },
3606 { ISD::SELECT, MVT::v16i16, { 1, 1, 1, 1 } },
3607 { ISD::SELECT, MVT::v8i16, { 1, 1, 1, 1 } },
3608 { ISD::SELECT, MVT::v64i8, { 2, 2, 4, 4 } },
3609 { ISD::SELECT, MVT::v32i8, { 1, 1, 1, 1 } },
3610 { ISD::SELECT, MVT::v16i8, { 1, 1, 1, 1 } },
3611 };
3612
3613 static const CostKindTblEntry AVX2CostTbl[] = {
3614 { ISD::SETCC, MVT::v4f64, { 1, 4, 1, 2 } },
3615 { ISD::SETCC, MVT::v2f64, { 1, 4, 1, 1 } },
3616 { ISD::SETCC, MVT::f64, { 1, 4, 1, 1 } },
3617 { ISD::SETCC, MVT::v8f32, { 1, 4, 1, 2 } },
3618 { ISD::SETCC, MVT::v4f32, { 1, 4, 1, 1 } },
3619 { ISD::SETCC, MVT::f32, { 1, 4, 1, 1 } },
3620
3621 { ISD::SETCC, MVT::v4i64, { 1, 1, 1, 2 } },
3622 { ISD::SETCC, MVT::v8i32, { 1, 1, 1, 2 } },
3623 { ISD::SETCC, MVT::v16i16, { 1, 1, 1, 2 } },
3624 { ISD::SETCC, MVT::v32i8, { 1, 1, 1, 2 } },
3625
3626 { ISD::SELECT, MVT::v4f64, { 2, 2, 1, 2 } }, // vblendvpd
3627 { ISD::SELECT, MVT::v8f32, { 2, 2, 1, 2 } }, // vblendvps
3628 { ISD::SELECT, MVT::v4i64, { 2, 2, 1, 2 } }, // pblendvb
3629 { ISD::SELECT, MVT::v8i32, { 2, 2, 1, 2 } }, // pblendvb
3630 { ISD::SELECT, MVT::v16i16, { 2, 2, 1, 2 } }, // pblendvb
3631 { ISD::SELECT, MVT::v32i8, { 2, 2, 1, 2 } }, // pblendvb
3632 };
3633
3634 static const CostKindTblEntry XOPCostTbl[] = {
3635 { ISD::SETCC, MVT::v4i64, { 4, 2, 5, 6 } },
3636 { ISD::SETCC, MVT::v2i64, { 1, 1, 1, 1 } },
3637 };
3638
3639 static const CostKindTblEntry AVX1CostTbl[] = {
3640 { ISD::SETCC, MVT::v4f64, { 2, 3, 1, 2 } },
3641 { ISD::SETCC, MVT::v2f64, { 1, 3, 1, 1 } },
3642 { ISD::SETCC, MVT::f64, { 1, 3, 1, 1 } },
3643 { ISD::SETCC, MVT::v8f32, { 2, 3, 1, 2 } },
3644 { ISD::SETCC, MVT::v4f32, { 1, 3, 1, 1 } },
3645 { ISD::SETCC, MVT::f32, { 1, 3, 1, 1 } },
3646
3647 // AVX1 does not support 8-wide integer compare.
3648 { ISD::SETCC, MVT::v4i64, { 4, 2, 5, 6 } },
3649 { ISD::SETCC, MVT::v8i32, { 4, 2, 5, 6 } },
3650 { ISD::SETCC, MVT::v16i16, { 4, 2, 5, 6 } },
3651 { ISD::SETCC, MVT::v32i8, { 4, 2, 5, 6 } },
3652
3653 { ISD::SELECT, MVT::v4f64, { 3, 3, 1, 2 } }, // vblendvpd
3654 { ISD::SELECT, MVT::v8f32, { 3, 3, 1, 2 } }, // vblendvps
3655 { ISD::SELECT, MVT::v4i64, { 3, 3, 1, 2 } }, // vblendvpd
3656 { ISD::SELECT, MVT::v8i32, { 3, 3, 1, 2 } }, // vblendvps
3657 { ISD::SELECT, MVT::v16i16, { 3, 3, 3, 3 } }, // vandps + vandnps + vorps
3658 { ISD::SELECT, MVT::v32i8, { 3, 3, 3, 3 } }, // vandps + vandnps + vorps
3659 };
3660
3661 static const CostKindTblEntry SSE42CostTbl[] = {
3662 { ISD::SETCC, MVT::v2i64, { 1, 2, 1, 2 } },
3663 };
3664
3665 static const CostKindTblEntry SSE41CostTbl[] = {
3666 { ISD::SETCC, MVT::v2f64, { 1, 5, 1, 1 } },
3667 { ISD::SETCC, MVT::v4f32, { 1, 5, 1, 1 } },
3668
3669 { ISD::SELECT, MVT::v2f64, { 2, 2, 1, 2 } }, // blendvpd
3670 { ISD::SELECT, MVT::f64, { 2, 2, 1, 2 } }, // blendvpd
3671 { ISD::SELECT, MVT::v4f32, { 2, 2, 1, 2 } }, // blendvps
3672 { ISD::SELECT, MVT::f32 , { 2, 2, 1, 2 } }, // blendvps
3673 { ISD::SELECT, MVT::v2i64, { 2, 2, 1, 2 } }, // pblendvb
3674 { ISD::SELECT, MVT::v4i32, { 2, 2, 1, 2 } }, // pblendvb
3675 { ISD::SELECT, MVT::v8i16, { 2, 2, 1, 2 } }, // pblendvb
3676 { ISD::SELECT, MVT::v16i8, { 2, 2, 1, 2 } }, // pblendvb
3677 };
3678
3679 static const CostKindTblEntry SSE2CostTbl[] = {
3680 { ISD::SETCC, MVT::v2f64, { 2, 5, 1, 1 } },
3681 { ISD::SETCC, MVT::f64, { 1, 5, 1, 1 } },
3682
3683 { ISD::SETCC, MVT::v2i64, { 5, 4, 5, 5 } }, // pcmpeqd/pcmpgtd expansion
3684 { ISD::SETCC, MVT::v4i32, { 1, 1, 1, 1 } },
3685 { ISD::SETCC, MVT::v8i16, { 1, 1, 1, 1 } },
3686 { ISD::SETCC, MVT::v16i8, { 1, 1, 1, 1 } },
3687
3688 { ISD::SELECT, MVT::v2f64, { 2, 2, 3, 3 } }, // andpd + andnpd + orpd
3689 { ISD::SELECT, MVT::f64, { 2, 2, 3, 3 } }, // andpd + andnpd + orpd
3690 { ISD::SELECT, MVT::v2i64, { 2, 2, 3, 3 } }, // pand + pandn + por
3691 { ISD::SELECT, MVT::v4i32, { 2, 2, 3, 3 } }, // pand + pandn + por
3692 { ISD::SELECT, MVT::v8i16, { 2, 2, 3, 3 } }, // pand + pandn + por
3693 { ISD::SELECT, MVT::v16i8, { 2, 2, 3, 3 } }, // pand + pandn + por
3694 };
3695
3696 static const CostKindTblEntry SSE1CostTbl[] = {
3697 { ISD::SETCC, MVT::v4f32, { 2, 5, 1, 1 } },
3698 { ISD::SETCC, MVT::f32, { 1, 5, 1, 1 } },
3699
3700 { ISD::SELECT, MVT::v4f32, { 2, 2, 3, 3 } }, // andps + andnps + orps
3701 { ISD::SELECT, MVT::f32, { 2, 2, 3, 3 } }, // andps + andnps + orps
3702 };
3703
3704 if (ST->useSLMArithCosts())
3705 if (const auto *Entry = CostTableLookup(SLMCostTbl, ISD, MTy))
3706 if (auto KindCost = Entry->Cost[CostKind])
3707 return LT.first * (ExtraCost + *KindCost);
3708
3709 if (ST->hasBWI())
3710 if (const auto *Entry = CostTableLookup(AVX512BWCostTbl, ISD, MTy))
3711 if (auto KindCost = Entry->Cost[CostKind])
3712 return LT.first * (ExtraCost + *KindCost);
3713
3714 if (ST->hasAVX512())
3715 if (const auto *Entry = CostTableLookup(AVX512CostTbl, ISD, MTy))
3716 if (auto KindCost = Entry->Cost[CostKind])
3717 return LT.first * (ExtraCost + *KindCost);
3718
3719 if (ST->hasAVX2())
3720 if (const auto *Entry = CostTableLookup(AVX2CostTbl, ISD, MTy))
3721 if (auto KindCost = Entry->Cost[CostKind])
3722 return LT.first * (ExtraCost + *KindCost);
3723
3724 if (ST->hasXOP())
3725 if (const auto *Entry = CostTableLookup(XOPCostTbl, ISD, MTy))
3726 if (auto KindCost = Entry->Cost[CostKind])
3727 return LT.first * (ExtraCost + *KindCost);
3728
3729 if (ST->hasAVX())
3730 if (const auto *Entry = CostTableLookup(AVX1CostTbl, ISD, MTy))
3731 if (auto KindCost = Entry->Cost[CostKind])
3732 return LT.first * (ExtraCost + *KindCost);
3733
3734 if (ST->hasSSE42())
3735 if (const auto *Entry = CostTableLookup(SSE42CostTbl, ISD, MTy))
3736 if (auto KindCost = Entry->Cost[CostKind])
3737 return LT.first * (ExtraCost + *KindCost);
3738
3739 if (ST->hasSSE41())
3740 if (const auto *Entry = CostTableLookup(SSE41CostTbl, ISD, MTy))
3741 if (auto KindCost = Entry->Cost[CostKind])
3742 return LT.first * (ExtraCost + *KindCost);
3743
3744 if (ST->hasSSE2())
3745 if (const auto *Entry = CostTableLookup(SSE2CostTbl, ISD, MTy))
3746 if (auto KindCost = Entry->Cost[CostKind])
3747 return LT.first * (ExtraCost + *KindCost);
3748
3749 if (ST->hasSSE1())
3750 if (const auto *Entry = CostTableLookup(SSE1CostTbl, ISD, MTy))
3751 if (auto KindCost = Entry->Cost[CostKind])
3752 return LT.first * (ExtraCost + *KindCost);
3753
3754 // Assume a 3cy latency for fp select ops.
3755 if (CostKind == TTI::TCK_Latency && Opcode == Instruction::Select)
3756 if (ValTy->getScalarType()->isFloatingPointTy())
3757 return 3;
3758
3759 return BaseT::getCmpSelInstrCost(Opcode, ValTy, CondTy, VecPred, CostKind,
3760 Op1Info, Op2Info, I);
3761}
3762
3764
3768 // Costs should match the codegen from:
3769 // BITREVERSE: llvm\test\CodeGen\X86\vector-bitreverse.ll
3770 // BSWAP: llvm\test\CodeGen\X86\bswap-vector.ll
3771 // CTLZ: llvm\test\CodeGen\X86\vector-lzcnt-*.ll
3772 // CTPOP: llvm\test\CodeGen\X86\vector-popcnt-*.ll
3773 // CTTZ: llvm\test\CodeGen\X86\vector-tzcnt-*.ll
3774
3775 // TODO: Overflow intrinsics (*ADDO, *SUBO, *MULO) with vector types are not
3776 // specialized in these tables yet.
3777 static const CostKindTblEntry AVX512VBMI2CostTbl[] = {
3778 { ISD::FSHL, MVT::v8i64, { 1, 1, 1, 1 } },
3779 { ISD::FSHL, MVT::v4i64, { 1, 1, 1, 1 } },
3780 { ISD::FSHL, MVT::v2i64, { 1, 1, 1, 1 } },
3781 { ISD::FSHL, MVT::v16i32, { 1, 1, 1, 1 } },
3782 { ISD::FSHL, MVT::v8i32, { 1, 1, 1, 1 } },
3783 { ISD::FSHL, MVT::v4i32, { 1, 1, 1, 1 } },
3784 { ISD::FSHL, MVT::v32i16, { 1, 1, 1, 1 } },
3785 { ISD::FSHL, MVT::v16i16, { 1, 1, 1, 1 } },
3786 { ISD::FSHL, MVT::v8i16, { 1, 1, 1, 1 } },
3787 { ISD::ROTL, MVT::v32i16, { 1, 1, 1, 1 } },
3788 { ISD::ROTL, MVT::v16i16, { 1, 1, 1, 1 } },
3789 { ISD::ROTL, MVT::v8i16, { 1, 1, 1, 1 } },
3790 { ISD::ROTR, MVT::v32i16, { 1, 1, 1, 1 } },
3791 { ISD::ROTR, MVT::v16i16, { 1, 1, 1, 1 } },
3792 { ISD::ROTR, MVT::v8i16, { 1, 1, 1, 1 } },
3793 { X86ISD::VROTLI, MVT::v32i16, { 1, 1, 1, 1 } },
3794 { X86ISD::VROTLI, MVT::v16i16, { 1, 1, 1, 1 } },
3795 { X86ISD::VROTLI, MVT::v8i16, { 1, 1, 1, 1 } },
3796 };
3797 static const CostKindTblEntry AVX512BITALGCostTbl[] = {
3798 { ISD::CTPOP, MVT::v32i16, { 1, 1, 1, 1 } },
3799 { ISD::CTPOP, MVT::v64i8, { 1, 1, 1, 1 } },
3800 { ISD::CTPOP, MVT::v16i16, { 1, 1, 1, 1 } },
3801 { ISD::CTPOP, MVT::v32i8, { 1, 1, 1, 1 } },
3802 { ISD::CTPOP, MVT::v8i16, { 1, 1, 1, 1 } },
3803 { ISD::CTPOP, MVT::v16i8, { 1, 1, 1, 1 } },
3804 };
3805 static const CostKindTblEntry AVX512VPOPCNTDQCostTbl[] = {
3806 { ISD::CTPOP, MVT::v8i64, { 1, 1, 1, 1 } },
3807 { ISD::CTPOP, MVT::v16i32, { 1, 1, 1, 1 } },
3808 { ISD::CTPOP, MVT::v4i64, { 1, 1, 1, 1 } },
3809 { ISD::CTPOP, MVT::v8i32, { 1, 1, 1, 1 } },
3810 { ISD::CTPOP, MVT::v2i64, { 1, 1, 1, 1 } },
3811 { ISD::CTPOP, MVT::v4i32, { 1, 1, 1, 1 } },
3812 };
3813 static const CostKindTblEntry AVX512CDCostTbl[] = {
3814 { ISD::CTLZ, MVT::v8i64, { 1, 5, 1, 1 } },
3815 { ISD::CTLZ, MVT::v16i32, { 1, 5, 1, 1 } },
3816 { ISD::CTLZ, MVT::v32i16, { 18, 27, 23, 27 } },
3817 { ISD::CTLZ, MVT::v64i8, { 3, 16, 9, 11 } },
3818 { ISD::CTLZ, MVT::v4i64, { 1, 5, 1, 1 } },
3819 { ISD::CTLZ, MVT::v8i32, { 1, 5, 1, 1 } },
3820 { ISD::CTLZ, MVT::v16i16, { 8, 19, 11, 13 } },
3821 { ISD::CTLZ, MVT::v32i8, { 2, 11, 9, 10 } },
3822 { ISD::CTLZ, MVT::v2i64, { 1, 5, 1, 1 } },
3823 { ISD::CTLZ, MVT::v4i32, { 1, 5, 1, 1 } },
3824 { ISD::CTLZ, MVT::v8i16, { 3, 15, 4, 6 } },
3825 { ISD::CTLZ, MVT::v16i8, { 2, 10, 9, 10 } },
3826
3827 { ISD::CTTZ, MVT::v8i64, { 2, 8, 6, 7 } },
3828 { ISD::CTTZ, MVT::v16i32, { 2, 8, 6, 7 } },
3829 { ISD::CTTZ, MVT::v4i64, { 1, 8, 6, 6 } },
3830 { ISD::CTTZ, MVT::v8i32, { 1, 8, 6, 6 } },
3831 { ISD::CTTZ, MVT::v2i64, { 1, 8, 6, 6 } },
3832 { ISD::CTTZ, MVT::v4i32, { 1, 8, 6, 6 } },
3833 };
3834 static const CostKindTblEntry AVX512BWCostTbl[] = {
3835 { ISD::ABS, MVT::v32i16, { 1, 1, 1, 1 } },
3836 { ISD::ABS, MVT::v64i8, { 1, 1, 1, 1 } },
3837 { ISD::BITREVERSE, MVT::v2i64, { 3, 10, 10, 11 } },
3838 { ISD::BITREVERSE, MVT::v4i64, { 3, 11, 10, 11 } },
3839 { ISD::BITREVERSE, MVT::v8i64, { 3, 12, 10, 14 } },
3840 { ISD::BITREVERSE, MVT::v4i32, { 3, 10, 10, 11 } },
3841 { ISD::BITREVERSE, MVT::v8i32, { 3, 11, 10, 11 } },
3842 { ISD::BITREVERSE, MVT::v16i32, { 3, 12, 10, 14 } },
3843 { ISD::BITREVERSE, MVT::v8i16, { 3, 10, 10, 11 } },
3844 { ISD::BITREVERSE, MVT::v16i16, { 3, 11, 10, 11 } },
3845 { ISD::BITREVERSE, MVT::v32i16, { 3, 12, 10, 14 } },
3846 { ISD::BITREVERSE, MVT::v16i8, { 2, 5, 9, 9 } },
3847 { ISD::BITREVERSE, MVT::v32i8, { 2, 5, 9, 9 } },
3848 { ISD::BITREVERSE, MVT::v64i8, { 2, 5, 9, 12 } },
3849 { ISD::BSWAP, MVT::v2i64, { 1, 1, 1, 2 } },
3850 { ISD::BSWAP, MVT::v4i64, { 1, 1, 1, 2 } },
3851 { ISD::BSWAP, MVT::v8i64, { 1, 1, 1, 2 } },
3852 { ISD::BSWAP, MVT::v4i32, { 1, 1, 1, 2 } },
3853 { ISD::BSWAP, MVT::v8i32, { 1, 1, 1, 2 } },
3854 { ISD::BSWAP, MVT::v16i32, { 1, 1, 1, 2 } },
3855 { ISD::BSWAP, MVT::v8i16, { 1, 1, 1, 2 } },
3856 { ISD::BSWAP, MVT::v16i16, { 1, 1, 1, 2 } },
3857 { ISD::BSWAP, MVT::v32i16, { 1, 1, 1, 2 } },
3858 { ISD::CTLZ, MVT::v8i64, { 8, 22, 23, 23 } },
3859 { ISD::CTLZ, MVT::v16i32, { 8, 23, 25, 25 } },
3860 { ISD::CTLZ, MVT::v32i16, { 4, 15, 15, 16 } },
3861 { ISD::CTLZ, MVT::v64i8, { 3, 12, 10, 9 } },
3862 { ISD::CTPOP, MVT::v2i64, { 3, 7, 10, 10 } },
3863 { ISD::CTPOP, MVT::v4i64, { 3, 7, 10, 10 } },
3864 { ISD::CTPOP, MVT::v8i64, { 3, 8, 10, 12 } },
3865 { ISD::CTPOP, MVT::v4i32, { 7, 11, 14, 14 } },
3866 { ISD::CTPOP, MVT::v8i32, { 7, 11, 14, 14 } },
3867 { ISD::CTPOP, MVT::v16i32, { 7, 12, 14, 16 } },
3868 { ISD::CTPOP, MVT::v8i16, { 2, 7, 11, 11 } },
3869 { ISD::CTPOP, MVT::v16i16, { 2, 7, 11, 11 } },
3870 { ISD::CTPOP, MVT::v32i16, { 3, 7, 11, 13 } },
3871 { ISD::CTPOP, MVT::v16i8, { 2, 4, 8, 8 } },
3872 { ISD::CTPOP, MVT::v32i8, { 2, 4, 8, 8 } },
3873 { ISD::CTPOP, MVT::v64i8, { 2, 5, 8, 10 } },
3874 { ISD::CTTZ, MVT::v8i16, { 3, 9, 14, 14 } },
3875 { ISD::CTTZ, MVT::v16i16, { 3, 9, 14, 14 } },
3876 { ISD::CTTZ, MVT::v32i16, { 3, 10, 14, 16 } },
3877 { ISD::CTTZ, MVT::v16i8, { 2, 6, 11, 11 } },
3878 { ISD::CTTZ, MVT::v32i8, { 2, 6, 11, 11 } },
3879 { ISD::CTTZ, MVT::v64i8, { 3, 7, 11, 13 } },
3880 { ISD::ROTL, MVT::v32i16, { 2, 8, 6, 8 } },
3881 { ISD::ROTL, MVT::v16i16, { 2, 8, 6, 7 } },
3882 { ISD::ROTL, MVT::v8i16, { 2, 7, 6, 7 } },
3883 { ISD::ROTL, MVT::v64i8, { 5, 6, 11, 12 } },
3884 { ISD::ROTL, MVT::v32i8, { 5, 15, 7, 10 } },
3885 { ISD::ROTL, MVT::v16i8, { 5, 15, 7, 10 } },
3886 { ISD::ROTR, MVT::v32i16, { 2, 8, 6, 8 } },
3887 { ISD::ROTR, MVT::v16i16, { 2, 8, 6, 7 } },
3888 { ISD::ROTR, MVT::v8i16, { 2, 7, 6, 7 } },
3889 { ISD::ROTR, MVT::v64i8, { 5, 6, 12, 14 } },
3890 { ISD::ROTR, MVT::v32i8, { 5, 14, 6, 9 } },
3891 { ISD::ROTR, MVT::v16i8, { 5, 14, 6, 9 } },
3892 { X86ISD::VROTLI, MVT::v32i16, { 2, 5, 3, 3 } },
3893 { X86ISD::VROTLI, MVT::v16i16, { 1, 5, 3, 3 } },
3894 { X86ISD::VROTLI, MVT::v8i16, { 1, 5, 3, 3 } },
3895 { X86ISD::VROTLI, MVT::v64i8, { 2, 9, 3, 4 } },
3896 { X86ISD::VROTLI, MVT::v32i8, { 1, 9, 3, 4 } },
3897 { X86ISD::VROTLI, MVT::v16i8, { 1, 8, 3, 4 } },
3898 { ISD::SADDSAT, MVT::v32i16, { 1, 1, 1, 1 } },
3899 { ISD::SADDSAT, MVT::v64i8, { 1, 1, 1, 1 } },
3900 { ISD::SMAX, MVT::v32i16, { 1, 1, 1, 1 } },
3901 { ISD::SMAX, MVT::v64i8, { 1, 1, 1, 1 } },
3902 { ISD::SMIN, MVT::v32i16, { 1, 1, 1, 1 } },
3903 { ISD::SMIN, MVT::v64i8, { 1, 1, 1, 1 } },
3904 { ISD::SMULO, MVT::v32i16, { 3, 6, 4, 4 } },
3905 { ISD::SMULO, MVT::v64i8, { 8, 21, 17, 18 } },
3906 { ISD::UMULO, MVT::v32i16, { 2, 5, 3, 3 } },
3907 { ISD::UMULO, MVT::v64i8, { 8, 15, 15, 16 } },
3908 { ISD::SSUBSAT, MVT::v32i16, { 1, 1, 1, 1 } },
3909 { ISD::SSUBSAT, MVT::v64i8, { 1, 1, 1, 1 } },
3910 { ISD::UADDSAT, MVT::v32i16, { 1, 1, 1, 1 } },
3911 { ISD::UADDSAT, MVT::v64i8, { 1, 1, 1, 1 } },
3912 { ISD::UMAX, MVT::v32i16, { 1, 1, 1, 1 } },
3913 { ISD::UMAX, MVT::v64i8, { 1, 1, 1, 1 } },
3914 { ISD::UMIN, MVT::v32i16, { 1, 1, 1, 1 } },
3915 { ISD::UMIN, MVT::v64i8, { 1, 1, 1, 1 } },
3916 { ISD::USUBSAT, MVT::v32i16, { 1, 1, 1, 1 } },
3917 { ISD::USUBSAT, MVT::v64i8, { 1, 1, 1, 1 } },
3918 };
3919 static const CostKindTblEntry AVX512CostTbl[] = {
3920 { ISD::ABS, MVT::v8i64, { 1, 1, 1, 1 } },
3921 { ISD::ABS, MVT::v4i64, { 1, 1, 1, 1 } },
3922 { ISD::ABS, MVT::v2i64, { 1, 1, 1, 1 } },
3923 { ISD::ABS, MVT::v16i32, { 1, 1, 1, 1 } },
3924 { ISD::ABS, MVT::v8i32, { 1, 1, 1, 1 } },
3925 { ISD::ABS, MVT::v32i16, { 2, 7, 4, 4 } },
3926 { ISD::ABS, MVT::v16i16, { 1, 1, 1, 1 } },
3927 { ISD::ABS, MVT::v64i8, { 2, 7, 4, 4 } },
3928 { ISD::ABS, MVT::v32i8, { 1, 1, 1, 1 } },
3929 { ISD::BITREVERSE, MVT::v8i64, { 9, 13, 20, 20 } },
3930 { ISD::BITREVERSE, MVT::v16i32, { 9, 13, 20, 20 } },
3931 { ISD::BITREVERSE, MVT::v32i16, { 9, 13, 20, 20 } },
3932 { ISD::BITREVERSE, MVT::v64i8, { 6, 11, 17, 17 } },
3933 { ISD::BSWAP, MVT::v8i64, { 4, 7, 5, 5 } },
3934 { ISD::BSWAP, MVT::v16i32, { 4, 7, 5, 5 } },
3935 { ISD::BSWAP, MVT::v32i16, { 4, 7, 5, 5 } },
3936 { ISD::CTLZ, MVT::v8i64, { 10, 28, 32, 32 } },
3937 { ISD::CTLZ, MVT::v16i32, { 12, 30, 38, 38 } },
3938 { ISD::CTLZ, MVT::v32i16, { 8, 15, 29, 29 } },
3939 { ISD::CTLZ, MVT::v64i8, { 6, 11, 19, 19 } },
3940 { ISD::CTPOP, MVT::v8i64, { 16, 16, 19, 19 } },
3941 { ISD::CTPOP, MVT::v16i32, { 24, 19, 27, 27 } },
3942 { ISD::CTPOP, MVT::v32i16, { 18, 15, 22, 22 } },
3943 { ISD::CTPOP, MVT::v64i8, { 12, 11, 16, 16 } },
3944 { ISD::CTTZ, MVT::v8i64, { 2, 8, 6, 7 } },
3945 { ISD::CTTZ, MVT::v16i32, { 2, 8, 6, 7 } },
3946 { ISD::CTTZ, MVT::v32i16, { 7, 17, 27, 27 } },
3947 { ISD::CTTZ, MVT::v64i8, { 6, 13, 21, 21 } },
3948 { ISD::ROTL, MVT::v8i64, { 1, 1, 1, 1 } },
3949 { ISD::ROTL, MVT::v4i64, { 1, 1, 1, 1 } },
3950 { ISD::ROTL, MVT::v2i64, { 1, 1, 1, 1 } },
3951 { ISD::ROTL, MVT::v16i32, { 1, 1, 1, 1 } },
3952 { ISD::ROTL, MVT::v8i32, { 1, 1, 1, 1 } },
3953 { ISD::ROTL, MVT::v4i32, { 1, 1, 1, 1 } },
3954 { ISD::ROTR, MVT::v8i64, { 1, 1, 1, 1 } },
3955 { ISD::ROTR, MVT::v4i64, { 1, 1, 1, 1 } },
3956 { ISD::ROTR, MVT::v2i64, { 1, 1, 1, 1 } },
3957 { ISD::ROTR, MVT::v16i32, { 1, 1, 1, 1 } },
3958 { ISD::ROTR, MVT::v8i32, { 1, 1, 1, 1 } },
3959 { ISD::ROTR, MVT::v4i32, { 1, 1, 1, 1 } },
3960 { X86ISD::VROTLI, MVT::v8i64, { 1, 1, 1, 1 } },
3961 { X86ISD::VROTLI, MVT::v4i64, { 1, 1, 1, 1 } },
3962 { X86ISD::VROTLI, MVT::v2i64, { 1, 1, 1, 1 } },
3963 { X86ISD::VROTLI, MVT::v16i32, { 1, 1, 1, 1 } },
3964 { X86ISD::VROTLI, MVT::v8i32, { 1, 1, 1, 1 } },
3965 { X86ISD::VROTLI, MVT::v4i32, { 1, 1, 1, 1 } },
3966 { ISD::SADDSAT, MVT::v2i64, { 3, 3, 8, 9 } },
3967 { ISD::SADDSAT, MVT::v4i64, { 2, 2, 6, 7 } },
3968 { ISD::SADDSAT, MVT::v8i64, { 3, 3, 6, 7 } },
3969 { ISD::SADDSAT, MVT::v4i32, { 2, 2, 6, 7 } },
3970 { ISD::SADDSAT, MVT::v8i32, { 2, 2, 6, 7 } },
3971 { ISD::SADDSAT, MVT::v16i32, { 3, 3, 6, 7 } },
3972 { ISD::SADDSAT, MVT::v32i16, { 2, 2, 2, 2 } },
3973 { ISD::SADDSAT, MVT::v64i8, { 2, 2, 2, 2 } },
3974 { ISD::SMAX, MVT::v8i64, { 1, 3, 1, 1 } },
3975 { ISD::SMAX, MVT::v16i32, { 1, 1, 1, 1 } },
3976 { ISD::SMAX, MVT::v32i16, { 3, 7, 5, 5 } },
3977 { ISD::SMAX, MVT::v64i8, { 3, 7, 5, 5 } },
3978 { ISD::SMAX, MVT::v4i64, { 1, 3, 1, 1 } },
3979 { ISD::SMAX, MVT::v2i64, { 1, 3, 1, 1 } },
3980 { ISD::SMIN, MVT::v8i64, { 1, 3, 1, 1 } },
3981 { ISD::SMIN, MVT::v16i32, { 1, 1, 1, 1 } },
3982 { ISD::SMIN, MVT::v32i16, { 3, 7, 5, 5 } },
3983 { ISD::SMIN, MVT::v64i8, { 3, 7, 5, 5 } },
3984 { ISD::SMIN, MVT::v4i64, { 1, 3, 1, 1 } },
3985 { ISD::SMIN, MVT::v2i64, { 1, 3, 1, 1 } },
3986 { ISD::SMULO, MVT::v8i64, { 44, 44, 81, 93 } },
3987 { ISD::SMULO, MVT::v16i32, { 5, 12, 9, 11 } },
3988 { ISD::SMULO, MVT::v32i16, { 6, 12, 17, 17 } },
3989 { ISD::SMULO, MVT::v64i8, { 22, 28, 42, 42 } },
3990 { ISD::SSUBSAT, MVT::v2i64, { 2, 13, 9, 10 } },
3991 { ISD::SSUBSAT, MVT::v4i64, { 2, 15, 7, 8 } },
3992 { ISD::SSUBSAT, MVT::v8i64, { 2, 14, 7, 8 } },
3993 { ISD::SSUBSAT, MVT::v4i32, { 2, 14, 7, 8 } },
3994 { ISD::SSUBSAT, MVT::v8i32, { 2, 15, 7, 8 } },
3995 { ISD::SSUBSAT, MVT::v16i32, { 2, 14, 7, 8 } },
3996 { ISD::SSUBSAT, MVT::v32i16, { 2, 2, 2, 2 } },
3997 { ISD::SSUBSAT, MVT::v64i8, { 2, 2, 2, 2 } },
3998 { ISD::UMAX, MVT::v8i64, { 1, 3, 1, 1 } },
3999 { ISD::UMAX, MVT::v16i32, { 1, 1, 1, 1 } },
4000 { ISD::UMAX, MVT::v32i16, { 3, 7, 5, 5 } },
4001 { ISD::UMAX, MVT::v64i8, { 3, 7, 5, 5 } },
4002 { ISD::UMAX, MVT::v4i64, { 1, 3, 1, 1 } },
4003 { ISD::UMAX, MVT::v2i64, { 1, 3, 1, 1 } },
4004 { ISD::UMIN, MVT::v8i64, { 1, 3, 1, 1 } },
4005 { ISD::UMIN, MVT::v16i32, { 1, 1, 1, 1 } },
4006 { ISD::UMIN, MVT::v32i16, { 3, 7, 5, 5 } },
4007 { ISD::UMIN, MVT::v64i8, { 3, 7, 5, 5 } },
4008 { ISD::UMIN, MVT::v4i64, { 1, 3, 1, 1 } },
4009 { ISD::UMIN, MVT::v2i64, { 1, 3, 1, 1 } },
4010 { ISD::UMULO, MVT::v8i64, { 52, 52, 95, 104} },
4011 { ISD::UMULO, MVT::v16i32, { 5, 12, 8, 10 } },
4012 { ISD::UMULO, MVT::v32i16, { 5, 13, 16, 16 } },
4013 { ISD::UMULO, MVT::v64i8, { 18, 24, 30, 30 } },
4014 { ISD::UADDSAT, MVT::v2i64, { 1, 4, 4, 4 } },
4015 { ISD::UADDSAT, MVT::v4i64, { 1, 4, 4, 4 } },
4016 { ISD::UADDSAT, MVT::v8i64, { 1, 4, 4, 4 } },
4017 { ISD::UADDSAT, MVT::v4i32, { 1, 2, 4, 4 } },
4018 { ISD::UADDSAT, MVT::v8i32, { 1, 2, 4, 4 } },
4019 { ISD::UADDSAT, MVT::v16i32, { 2, 2, 4, 4 } },
4020 { ISD::UADDSAT, MVT::v32i16, { 2, 2, 2, 2 } },
4021 { ISD::UADDSAT, MVT::v64i8, { 2, 2, 2, 2 } },
4022 { ISD::USUBSAT, MVT::v2i64, { 1, 4, 2, 2 } },
4023 { ISD::USUBSAT, MVT::v4i64, { 1, 4, 2, 2 } },
4024 { ISD::USUBSAT, MVT::v8i64, { 1, 4, 2, 2 } },
4025 { ISD::USUBSAT, MVT::v8i32, { 1, 2, 2, 2 } },
4026 { ISD::USUBSAT, MVT::v16i32, { 1, 2, 2, 2 } },
4027 { ISD::USUBSAT, MVT::v32i16, { 2, 2, 2, 2 } },
4028 { ISD::USUBSAT, MVT::v64i8, { 2, 2, 2, 2 } },
4029 { ISD::FMAXNUM, MVT::f32, { 2, 2, 3, 3 } },
4030 { ISD::FMAXNUM, MVT::v4f32, { 1, 1, 3, 3 } },
4031 { ISD::FMAXNUM, MVT::v8f32, { 2, 2, 3, 3 } },
4032 { ISD::FMAXNUM, MVT::v16f32, { 4, 4, 3, 3 } },
4033 { ISD::FMAXNUM, MVT::f64, { 2, 2, 3, 3 } },
4034 { ISD::FMAXNUM, MVT::v2f64, { 1, 1, 3, 3 } },
4035 { ISD::FMAXNUM, MVT::v4f64, { 2, 2, 3, 3 } },
4036 { ISD::FMAXNUM, MVT::v8f64, { 3, 3, 3, 3 } },
4037 { ISD::FSQRT, MVT::f32, { 3, 12, 1, 1 } }, // Skylake from http://www.agner.org/
4038 { ISD::FSQRT, MVT::v4f32, { 3, 12, 1, 1 } }, // Skylake from http://www.agner.org/
4039 { ISD::FSQRT, MVT::v8f32, { 6, 12, 1, 1 } }, // Skylake from http://www.agner.org/
4040 { ISD::FSQRT, MVT::v16f32, { 12, 20, 1, 3 } }, // Skylake from http://www.agner.org/
4041 { ISD::FSQRT, MVT::f64, { 6, 18, 1, 1 } }, // Skylake from http://www.agner.org/
4042 { ISD::FSQRT, MVT::v2f64, { 6, 18, 1, 1 } }, // Skylake from http://www.agner.org/
4043 { ISD::FSQRT, MVT::v4f64, { 12, 18, 1, 1 } }, // Skylake from http://www.agner.org/
4044 { ISD::FSQRT, MVT::v8f64, { 24, 32, 1, 3 } }, // Skylake from http://www.agner.org/
4045 };
4046 static const CostKindTblEntry XOPCostTbl[] = {
4047 { ISD::BITREVERSE, MVT::v4i64, { 3, 6, 5, 6 } },
4048 { ISD::BITREVERSE, MVT::v8i32, { 3, 6, 5, 6 } },
4049 { ISD::BITREVERSE, MVT::v16i16, { 3, 6, 5, 6 } },
4050 { ISD::BITREVERSE, MVT::v32i8, { 3, 6, 5, 6 } },
4051 { ISD::BITREVERSE, MVT::v2i64, { 2, 7, 1, 1 } },
4052 { ISD::BITREVERSE, MVT::v4i32, { 2, 7, 1, 1 } },
4053 { ISD::BITREVERSE, MVT::v8i16, { 2, 7, 1, 1 } },
4054 { ISD::BITREVERSE, MVT::v16i8, { 2, 7, 1, 1 } },
4055 { ISD::BITREVERSE, MVT::i64, { 2, 2, 3, 4 } },
4056 { ISD::BITREVERSE, MVT::i32, { 2, 2, 3, 4 } },
4057 { ISD::BITREVERSE, MVT::i16, { 2, 2, 3, 4 } },
4058 { ISD::BITREVERSE, MVT::i8, { 2, 2, 3, 4 } },
4059 // XOP: ROTL = VPROT(X,Y), ROTR = VPROT(X,SUB(0,Y))
4060 { ISD::ROTL, MVT::v4i64, { 4, 7, 5, 6 } },
4061 { ISD::ROTL, MVT::v8i32, { 4, 7, 5, 6 } },
4062 { ISD::ROTL, MVT::v16i16, { 4, 7, 5, 6 } },
4063 { ISD::ROTL, MVT::v32i8, { 4, 7, 5, 6 } },
4064 { ISD::ROTL, MVT::v2i64, { 1, 3, 1, 1 } },
4065 { ISD::ROTL, MVT::v4i32, { 1, 3, 1, 1 } },
4066 { ISD::ROTL, MVT::v8i16, { 1, 3, 1, 1 } },
4067 { ISD::ROTL, MVT::v16i8, { 1, 3, 1, 1 } },
4068 { ISD::ROTR, MVT::v4i64, { 4, 7, 8, 9 } },
4069 { ISD::ROTR, MVT::v8i32, { 4, 7, 8, 9 } },
4070 { ISD::ROTR, MVT::v16i16, { 4, 7, 8, 9 } },
4071 { ISD::ROTR, MVT::v32i8, { 4, 7, 8, 9 } },
4072 { ISD::ROTR, MVT::v2i64, { 1, 3, 3, 3 } },
4073 { ISD::ROTR, MVT::v4i32, { 1, 3, 3, 3 } },
4074 { ISD::ROTR, MVT::v8i16, { 1, 3, 3, 3 } },
4075 { ISD::ROTR, MVT::v16i8, { 1, 3, 3, 3 } },
4076 { X86ISD::VROTLI, MVT::v4i64, { 4, 7, 5, 6 } },
4077 { X86ISD::VROTLI, MVT::v8i32, { 4, 7, 5, 6 } },
4078 { X86ISD::VROTLI, MVT::v16i16, { 4, 7, 5, 6 } },
4079 { X86ISD::VROTLI, MVT::v32i8, { 4, 7, 5, 6 } },
4080 { X86ISD::VROTLI, MVT::v2i64, { 1, 3, 1, 1 } },
4081 { X86ISD::VROTLI, MVT::v4i32, { 1, 3, 1, 1 } },
4082 { X86ISD::VROTLI, MVT::v8i16, { 1, 3, 1, 1 } },
4083 { X86ISD::VROTLI, MVT::v16i8, { 1, 3, 1, 1 } },
4084 };
4085 static const CostKindTblEntry AVX2CostTbl[] = {
4086 { ISD::ABS, MVT::v2i64, { 2, 4, 3, 5 } }, // VBLENDVPD(X,VPSUBQ(0,X),X)
4087 { ISD::ABS, MVT::v4i64, { 2, 4, 3, 5 } }, // VBLENDVPD(X,VPSUBQ(0,X),X)
4088 { ISD::ABS, MVT::v4i32, { 1, 1, 1, 1 } },
4089 { ISD::ABS, MVT::v8i32, { 1, 1, 1, 2 } },
4090 { ISD::ABS, MVT::v8i16, { 1, 1, 1, 1 } },
4091 { ISD::ABS, MVT::v16i16, { 1, 1, 1, 2 } },
4092 { ISD::ABS, MVT::v16i8, { 1, 1, 1, 1 } },
4093 { ISD::ABS, MVT::v32i8, { 1, 1, 1, 2 } },
4094 { ISD::BITREVERSE, MVT::v2i64, { 3, 11, 10, 11 } },
4095 { ISD::BITREVERSE, MVT::v4i64, { 5, 11, 10, 17 } },
4096 { ISD::BITREVERSE, MVT::v4i32, { 3, 11, 10, 11 } },
4097 { ISD::BITREVERSE, MVT::v8i32, { 5, 11, 10, 17 } },
4098 { ISD::BITREVERSE, MVT::v8i16, { 3, 11, 10, 11 } },
4099 { ISD::BITREVERSE, MVT::v16i16, { 5, 11, 10, 17 } },
4100 { ISD::BITREVERSE, MVT::v16i8, { 3, 6, 9, 9 } },
4101 { ISD::BITREVERSE, MVT::v32i8, { 4, 5, 9, 15 } },
4102 { ISD::BSWAP, MVT::v2i64, { 1, 2, 1, 2 } },
4103 { ISD::BSWAP, MVT::v4i64, { 1, 3, 1, 2 } },
4104 { ISD::BSWAP, MVT::v4i32, { 1, 2, 1, 2 } },
4105 { ISD::BSWAP, MVT::v8i32, { 1, 3, 1, 2 } },
4106 { ISD::BSWAP, MVT::v8i16, { 1, 2, 1, 2 } },
4107 { ISD::BSWAP, MVT::v16i16, { 1, 3, 1, 2 } },
4108 { ISD::CTLZ, MVT::v2i64, { 7, 18, 24, 25 } },
4109 { ISD::CTLZ, MVT::v4i64, { 14, 18, 24, 44 } },
4110 { ISD::CTLZ, MVT::v4i32, { 5, 16, 19, 20 } },
4111 { ISD::CTLZ, MVT::v8i32, { 10, 16, 19, 34 } },
4112 { ISD::CTLZ, MVT::v8i16, { 4, 13, 14, 15 } },
4113 { ISD::CTLZ, MVT::v16i16, { 6, 14, 14, 24 } },
4114 { ISD::CTLZ, MVT::v16i8, { 3, 12, 9, 10 } },
4115 { ISD::CTLZ, MVT::v32i8, { 4, 12, 9, 14 } },
4116 { ISD::CTPOP, MVT::v2i64, { 3, 9, 10, 10 } },
4117 { ISD::CTPOP, MVT::v4i64, { 4, 9, 10, 14 } },
4118 { ISD::CTPOP, MVT::v4i32, { 7, 12, 14, 14 } },
4119 { ISD::CTPOP, MVT::v8i32, { 7, 12, 14, 18 } },
4120 { ISD::CTPOP, MVT::v8i16, { 3, 7, 11, 11 } },
4121 { ISD::CTPOP, MVT::v16i16, { 6, 8, 11, 18 } },
4122 { ISD::CTPOP, MVT::v16i8, { 2, 5, 8, 8 } },
4123 { ISD::CTPOP, MVT::v32i8, { 3, 5, 8, 12 } },
4124 { ISD::CTTZ, MVT::v2i64, { 4, 11, 13, 13 } },
4125 { ISD::CTTZ, MVT::v4i64, { 5, 11, 13, 20 } },
4126 { ISD::CTTZ, MVT::v4i32, { 7, 14, 17, 17 } },
4127 { ISD::CTTZ, MVT::v8i32, { 7, 15, 17, 24 } },
4128 { ISD::CTTZ, MVT::v8i16, { 4, 9, 14, 14 } },
4129 { ISD::CTTZ, MVT::v16i16, { 6, 9, 14, 24 } },
4130 { ISD::CTTZ, MVT::v16i8, { 3, 7, 11, 11 } },
4131 { ISD::CTTZ, MVT::v32i8, { 5, 7, 11, 18 } },
4132 { ISD::SADDSAT, MVT::v2i64, { 4, 13, 8, 11 } },
4133 { ISD::SADDSAT, MVT::v4i64, { 3, 10, 8, 12 } },
4134 { ISD::SADDSAT, MVT::v4i32, { 2, 6, 7, 9 } },
4135 { ISD::SADDSAT, MVT::v8i32, { 4, 6, 7, 13 } },
4136 { ISD::SADDSAT, MVT::v16i16, { 1, 1, 1, 2 } },
4137 { ISD::SADDSAT, MVT::v32i8, { 1, 1, 1, 2 } },
4138 { ISD::SMAX, MVT::v2i64, { 2, 7, 2, 3 } },
4139 { ISD::SMAX, MVT::v4i64, { 2, 7, 2, 3 } },
4140 { ISD::SMAX, MVT::v8i32, { 1, 1, 1, 2 } },
4141 { ISD::SMAX, MVT::v16i16, { 1, 1, 1, 2 } },
4142 { ISD::SMAX, MVT::v32i8, { 1, 1, 1, 2 } },
4143 { ISD::SMIN, MVT::v2i64, { 2, 7, 2, 3 } },
4144 { ISD::SMIN, MVT::v4i64, { 2, 7, 2, 3 } },
4145 { ISD::SMIN, MVT::v8i32, { 1, 1, 1, 2 } },
4146 { ISD::SMIN, MVT::v16i16, { 1, 1, 1, 2 } },
4147 { ISD::SMIN, MVT::v32i8, { 1, 1, 1, 2 } },
4148 { ISD::SMULO, MVT::v4i64, { 20, 20, 33, 37 } },
4149 { ISD::SMULO, MVT::v2i64, { 8, 8, 13, 15 } },
4150 { ISD::SMULO, MVT::v8i32, { 8, 20, 13, 24 } },
4151 { ISD::SMULO, MVT::v4i32, { 5, 15, 11, 12 } },
4152 { ISD::SMULO, MVT::v16i16, { 4, 14, 8, 14 } },
4153 { ISD::SMULO, MVT::v8i16, { 3, 9, 6, 6 } },
4154 { ISD::SMULO, MVT::v32i8, { 9, 15, 18, 35 } },
4155 { ISD::SMULO, MVT::v16i8, { 6, 22, 14, 21 } },
4156 { ISD::SSUBSAT, MVT::v2i64, { 4, 13, 9, 13 } },
4157 { ISD::SSUBSAT, MVT::v4i64, { 4, 15, 9, 13 } },
4158 { ISD::SSUBSAT, MVT::v4i32, { 3, 14, 9, 11 } },
4159 { ISD::SSUBSAT, MVT::v8i32, { 4, 15, 9, 16 } },
4160 { ISD::SSUBSAT, MVT::v16i16, { 1, 1, 1, 2 } },
4161 { ISD::SSUBSAT, MVT::v32i8, { 1, 1, 1, 2 } },
4162 { ISD::UADDSAT, MVT::v2i64, { 2, 8, 6, 6 } },
4163 { ISD::UADDSAT, MVT::v4i64, { 3, 8, 6, 10 } },
4164 { ISD::UADDSAT, MVT::v8i32, { 2, 2, 4, 8 } },
4165 { ISD::UADDSAT, MVT::v16i16, { 1, 1, 1, 2 } },
4166 { ISD::UADDSAT, MVT::v32i8, { 1, 1, 1, 2 } },
4167 { ISD::UMAX, MVT::v2i64, { 2, 8, 5, 6 } },
4168 { ISD::UMAX, MVT::v4i64, { 2, 8, 5, 8 } },
4169 { ISD::UMAX, MVT::v8i32, { 1, 1, 1, 2 } },
4170 { ISD::UMAX, MVT::v16i16, { 1, 1, 1, 2 } },
4171 { ISD::UMAX, MVT::v32i8, { 1, 1, 1, 2 } },
4172 { ISD::UMIN, MVT::v2i64, { 2, 8, 5, 6 } },
4173 { ISD::UMIN, MVT::v4i64, { 2, 8, 5, 8 } },
4174 { ISD::UMIN, MVT::v8i32, { 1, 1, 1, 2 } },
4175 { ISD::UMIN, MVT::v16i16, { 1, 1, 1, 2 } },
4176 { ISD::UMIN, MVT::v32i8, { 1, 1, 1, 2 } },
4177 { ISD::UMULO, MVT::v4i64, { 24, 24, 39, 43 } },
4178 { ISD::UMULO, MVT::v2i64, { 10, 10, 15, 19 } },
4179 { ISD::UMULO, MVT::v8i32, { 8, 11, 13, 23 } },
4180 { ISD::UMULO, MVT::v4i32, { 5, 12, 11, 12 } },
4181 { ISD::UMULO, MVT::v16i16, { 4, 6, 8, 13 } },
4182 { ISD::UMULO, MVT::v8i16, { 2, 8, 6, 6 } },
4183 { ISD::UMULO, MVT::v32i8, { 9, 13, 17, 33 } },
4184 { ISD::UMULO, MVT::v16i8, { 6, 19, 13, 20 } },
4185 { ISD::USUBSAT, MVT::v2i64, { 2, 7, 6, 6 } },
4186 { ISD::USUBSAT, MVT::v4i64, { 3, 7, 6, 10 } },
4187 { ISD::USUBSAT, MVT::v8i32, { 2, 2, 2, 4 } },
4188 { ISD::USUBSAT, MVT::v16i16, { 1, 1, 1, 2 } },
4189 { ISD::USUBSAT, MVT::v32i8, { 1, 1, 1, 2 } },
4190 { ISD::FMAXNUM, MVT::f32, { 2, 7, 3, 5 } }, // MAXSS + CMPUNORDSS + BLENDVPS
4191 { ISD::FMAXNUM, MVT::v4f32, { 2, 7, 3, 5 } }, // MAXPS + CMPUNORDPS + BLENDVPS
4192 { ISD::FMAXNUM, MVT::v8f32, { 3, 7, 3, 6 } }, // MAXPS + CMPUNORDPS + BLENDVPS
4193 { ISD::FMAXNUM, MVT::f64, { 2, 7, 3, 5 } }, // MAXSD + CMPUNORDSD + BLENDVPD
4194 { ISD::FMAXNUM, MVT::v2f64, { 2, 7, 3, 5 } }, // MAXPD + CMPUNORDPD + BLENDVPD
4195 { ISD::FMAXNUM, MVT::v4f64, { 3, 7, 3, 6 } }, // MAXPD + CMPUNORDPD + BLENDVPD
4196 { ISD::FSQRT, MVT::f32, { 7, 15, 1, 1 } }, // vsqrtss
4197 { ISD::FSQRT, MVT::v4f32, { 7, 15, 1, 1 } }, // vsqrtps
4198 { ISD::FSQRT, MVT::v8f32, { 14, 21, 1, 3 } }, // vsqrtps
4199 { ISD::FSQRT, MVT::f64, { 14, 21, 1, 1 } }, // vsqrtsd
4200 { ISD::FSQRT, MVT::v2f64, { 14, 21, 1, 1 } }, // vsqrtpd
4201 { ISD::FSQRT, MVT::v4f64, { 28, 35, 1, 3 } }, // vsqrtpd
4202 };
4203 static const CostKindTblEntry AVX1CostTbl[] = {
4204 { ISD::ABS, MVT::v4i64, { 6, 8, 6, 12 } }, // VBLENDVPD(X,VPSUBQ(0,X),X)
4205 { ISD::ABS, MVT::v8i32, { 3, 6, 4, 5 } },
4206 { ISD::ABS, MVT::v16i16, { 3, 6, 4, 5 } },
4207 { ISD::ABS, MVT::v32i8, { 3, 6, 4, 5 } },
4208 { ISD::BITREVERSE, MVT::v4i64, { 17, 20, 20, 33 } }, // 2 x 128-bit Op + extract/insert
4209 { ISD::BITREVERSE, MVT::v2i64, { 8, 13, 10, 16 } },
4210 { ISD::BITREVERSE, MVT::v8i32, { 17, 20, 20, 33 } }, // 2 x 128-bit Op + extract/insert
4211 { ISD::BITREVERSE, MVT::v4i32, { 8, 13, 10, 16 } },
4212 { ISD::BITREVERSE, MVT::v16i16, { 17, 20, 20, 33 } }, // 2 x 128-bit Op + extract/insert
4213 { ISD::BITREVERSE, MVT::v8i16, { 8, 13, 10, 16 } },
4214 { ISD::BITREVERSE, MVT::v32i8, { 13, 15, 17, 26 } }, // 2 x 128-bit Op + extract/insert
4215 { ISD::BITREVERSE, MVT::v16i8, { 7, 7, 9, 13 } },
4216 { ISD::BSWAP, MVT::v4i64, { 5, 6, 5, 10 } },
4217 { ISD::BSWAP, MVT::v2i64, { 2, 2, 1, 3 } },
4218 { ISD::BSWAP, MVT::v8i32, { 5, 6, 5, 10 } },
4219 { ISD::BSWAP, MVT::v4i32, { 2, 2, 1, 3 } },
4220 { ISD::BSWAP, MVT::v16i16, { 5, 6, 5, 10 } },
4221 { ISD::BSWAP, MVT::v8i16, { 2, 2, 1, 3 } },
4222 { ISD::CTLZ, MVT::v4i64, { 29, 33, 49, 58 } }, // 2 x 128-bit Op + extract/insert
4223 { ISD::CTLZ, MVT::v2i64, { 14, 24, 24, 28 } },
4224 { ISD::CTLZ, MVT::v8i32, { 24, 28, 39, 48 } }, // 2 x 128-bit Op + extract/insert
4225 { ISD::CTLZ, MVT::v4i32, { 12, 20, 19, 23 } },
4226 { ISD::CTLZ, MVT::v16i16, { 19, 22, 29, 38 } }, // 2 x 128-bit Op + extract/insert
4227 { ISD::CTLZ, MVT::v8i16, { 9, 16, 14, 18 } },
4228 { ISD::CTLZ, MVT::v32i8, { 14, 15, 19, 28 } }, // 2 x 128-bit Op + extract/insert
4229 { ISD::CTLZ, MVT::v16i8, { 7, 12, 9, 13 } },
4230 { ISD::CTPOP, MVT::v4i64, { 14, 18, 19, 28 } }, // 2 x 128-bit Op + extract/insert
4231 { ISD::CTPOP, MVT::v2i64, { 7, 14, 10, 14 } },
4232 { ISD::CTPOP, MVT::v8i32, { 18, 24, 27, 36 } }, // 2 x 128-bit Op + extract/insert
4233 { ISD::CTPOP, MVT::v4i32, { 9, 20, 14, 18 } },
4234 { ISD::CTPOP, MVT::v16i16, { 16, 21, 22, 31 } }, // 2 x 128-bit Op + extract/insert
4235 { ISD::CTPOP, MVT::v8i16, { 8, 18, 11, 15 } },
4236 { ISD::CTPOP, MVT::v32i8, { 13, 15, 16, 25 } }, // 2 x 128-bit Op + extract/insert
4237 { ISD::CTPOP, MVT::v16i8, { 6, 12, 8, 12 } },
4238 { ISD::CTTZ, MVT::v4i64, { 17, 22, 24, 33 } }, // 2 x 128-bit Op + extract/insert
4239 { ISD::CTTZ, MVT::v2i64, { 9, 19, 13, 17 } },
4240 { ISD::CTTZ, MVT::v8i32, { 21, 27, 32, 41 } }, // 2 x 128-bit Op + extract/insert
4241 { ISD::CTTZ, MVT::v4i32, { 11, 24, 17, 21 } },
4242 { ISD::CTTZ, MVT::v16i16, { 18, 24, 27, 36 } }, // 2 x 128-bit Op + extract/insert
4243 { ISD::CTTZ, MVT::v8i16, { 9, 21, 14, 18 } },
4244 { ISD::CTTZ, MVT::v32i8, { 15, 18, 21, 30 } }, // 2 x 128-bit Op + extract/insert
4245 { ISD::CTTZ, MVT::v16i8, { 8, 16, 11, 15 } },
4246 { ISD::SADDSAT, MVT::v2i64, { 6, 13, 8, 11 } },
4247 { ISD::SADDSAT, MVT::v4i64, { 13, 20, 15, 25 } }, // 2 x 128-bit Op + extract/insert
4248 { ISD::SADDSAT, MVT::v8i32, { 12, 18, 14, 24 } }, // 2 x 128-bit Op + extract/insert
4249 { ISD::SADDSAT, MVT::v16i16, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4250 { ISD::SADDSAT, MVT::v32i8, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4251 { ISD::SMAX, MVT::v4i64, { 6, 9, 6, 12 } }, // 2 x 128-bit Op + extract/insert
4252 { ISD::SMAX, MVT::v2i64, { 3, 7, 2, 4 } },
4253 { ISD::SMAX, MVT::v8i32, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4254 { ISD::SMAX, MVT::v16i16, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4255 { ISD::SMAX, MVT::v32i8, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4256 { ISD::SMIN, MVT::v4i64, { 6, 9, 6, 12 } }, // 2 x 128-bit Op + extract/insert
4257 { ISD::SMIN, MVT::v2i64, { 3, 7, 2, 3 } },
4258 { ISD::SMIN, MVT::v8i32, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4259 { ISD::SMIN, MVT::v16i16, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4260 { ISD::SMIN, MVT::v32i8, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4261 { ISD::SMULO, MVT::v4i64, { 20, 20, 33, 37 } },
4262 { ISD::SMULO, MVT::v2i64, { 9, 9, 13, 17 } },
4263 { ISD::SMULO, MVT::v8i32, { 15, 20, 24, 29 } },
4264 { ISD::SMULO, MVT::v4i32, { 7, 15, 11, 13 } },
4265 { ISD::SMULO, MVT::v16i16, { 8, 14, 14, 15 } },
4266 { ISD::SMULO, MVT::v8i16, { 3, 9, 6, 6 } },
4267 { ISD::SMULO, MVT::v32i8, { 20, 20, 37, 39 } },
4268 { ISD::SMULO, MVT::v16i8, { 9, 22, 18, 21 } },
4269 { ISD::SSUBSAT, MVT::v2i64, { 7, 13, 9, 13 } },
4270 { ISD::SSUBSAT, MVT::v4i64, { 15, 21, 18, 29 } }, // 2 x 128-bit Op + extract/insert
4271 { ISD::SSUBSAT, MVT::v8i32, { 15, 19, 18, 29 } }, // 2 x 128-bit Op + extract/insert
4272 { ISD::SSUBSAT, MVT::v16i16, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4273 { ISD::SSUBSAT, MVT::v32i8, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4274 { ISD::UADDSAT, MVT::v2i64, { 3, 8, 6, 6 } },
4275 { ISD::UADDSAT, MVT::v4i64, { 8, 11, 14, 15 } }, // 2 x 128-bit Op + extract/insert
4276 { ISD::UADDSAT, MVT::v8i32, { 6, 6, 10, 11 } }, // 2 x 128-bit Op + extract/insert
4277 { ISD::UADDSAT, MVT::v16i16, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4278 { ISD::UADDSAT, MVT::v32i8, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4279 { ISD::UMAX, MVT::v4i64, { 9, 10, 11, 17 } }, // 2 x 128-bit Op + extract/insert
4280 { ISD::UMAX, MVT::v2i64, { 4, 8, 5, 7 } },
4281 { ISD::UMAX, MVT::v8i32, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4282 { ISD::UMAX, MVT::v16i16, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4283 { ISD::UMAX, MVT::v32i8, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4284 { ISD::UMIN, MVT::v4i64, { 9, 10, 11, 17 } }, // 2 x 128-bit Op + extract/insert
4285 { ISD::UMIN, MVT::v2i64, { 4, 8, 5, 7 } },
4286 { ISD::UMIN, MVT::v8i32, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4287 { ISD::UMIN, MVT::v16i16, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4288 { ISD::UMIN, MVT::v32i8, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4289 { ISD::UMULO, MVT::v4i64, { 24, 26, 39, 45 } },
4290 { ISD::UMULO, MVT::v2i64, { 10, 12, 15, 20 } },
4291 { ISD::UMULO, MVT::v8i32, { 14, 15, 23, 28 } },
4292 { ISD::UMULO, MVT::v4i32, { 7, 12, 11, 13 } },
4293 { ISD::UMULO, MVT::v16i16, { 7, 11, 13, 14 } },
4294 { ISD::UMULO, MVT::v8i16, { 3, 8, 6, 6 } },
4295 { ISD::UMULO, MVT::v32i8, { 19, 19, 35, 37 } },
4296 { ISD::UMULO, MVT::v16i8, { 9, 19, 17, 20 } },
4297 { ISD::USUBSAT, MVT::v2i64, { 3, 7, 6, 6 } },
4298 { ISD::USUBSAT, MVT::v4i64, { 8, 10, 14, 15 } }, // 2 x 128-bit Op + extract/insert
4299 { ISD::USUBSAT, MVT::v8i32, { 4, 4, 7, 8 } }, // 2 x 128-bit Op + extract/insert
4300 { ISD::USUBSAT, MVT::v8i32, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4301 { ISD::USUBSAT, MVT::v16i16, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4302 { ISD::USUBSAT, MVT::v32i8, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4303 { ISD::FMAXNUM, MVT::f32, { 3, 6, 3, 5 } }, // MAXSS + CMPUNORDSS + BLENDVPS
4304 { ISD::FMAXNUM, MVT::v4f32, { 3, 6, 3, 5 } }, // MAXPS + CMPUNORDPS + BLENDVPS
4305 { ISD::FMAXNUM, MVT::v8f32, { 5, 7, 3, 10 } }, // MAXPS + CMPUNORDPS + BLENDVPS
4306 { ISD::FMAXNUM, MVT::f64, { 3, 6, 3, 5 } }, // MAXSD + CMPUNORDSD + BLENDVPD
4307 { ISD::FMAXNUM, MVT::v2f64, { 3, 6, 3, 5 } }, // MAXPD + CMPUNORDPD + BLENDVPD
4308 { ISD::FMAXNUM, MVT::v4f64, { 5, 7, 3, 10 } }, // MAXPD + CMPUNORDPD + BLENDVPD
4309 { ISD::FSQRT, MVT::f32, { 21, 21, 1, 1 } }, // vsqrtss
4310 { ISD::FSQRT, MVT::v4f32, { 21, 21, 1, 1 } }, // vsqrtps
4311 { ISD::FSQRT, MVT::v8f32, { 42, 42, 1, 3 } }, // vsqrtps
4312 { ISD::FSQRT, MVT::f64, { 27, 27, 1, 1 } }, // vsqrtsd
4313 { ISD::FSQRT, MVT::v2f64, { 27, 27, 1, 1 } }, // vsqrtpd
4314 { ISD::FSQRT, MVT::v4f64, { 54, 54, 1, 3 } }, // vsqrtpd
4315 };
4316 static const CostKindTblEntry GFNICostTbl[] = {
4317 { ISD::BITREVERSE, MVT::i8, { 3, 3, 3, 4 } }, // gf2p8affineqb
4318 { ISD::BITREVERSE, MVT::i16, { 3, 3, 4, 6 } }, // gf2p8affineqb
4319 { ISD::BITREVERSE, MVT::i32, { 3, 3, 4, 5 } }, // gf2p8affineqb
4320 { ISD::BITREVERSE, MVT::i64, { 3, 3, 4, 6 } }, // gf2p8affineqb
4321 { ISD::BITREVERSE, MVT::v16i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
4322 { ISD::BITREVERSE, MVT::v32i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
4323 { ISD::BITREVERSE, MVT::v64i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
4324 { ISD::BITREVERSE, MVT::v8i16, { 1, 8, 2, 4 } }, // gf2p8affineqb
4325 { ISD::BITREVERSE, MVT::v16i16, { 1, 9, 2, 4 } }, // gf2p8affineqb
4326 { ISD::BITREVERSE, MVT::v32i16, { 1, 9, 2, 4 } }, // gf2p8affineqb
4327 { ISD::BITREVERSE, MVT::v4i32, { 1, 8, 2, 4 } }, // gf2p8affineqb
4328 { ISD::BITREVERSE, MVT::v8i32, { 1, 9, 2, 4 } }, // gf2p8affineqb
4329 { ISD::BITREVERSE, MVT::v16i32, { 1, 9, 2, 4 } }, // gf2p8affineqb
4330 { ISD::BITREVERSE, MVT::v2i64, { 1, 8, 2, 4 } }, // gf2p8affineqb
4331 { ISD::BITREVERSE, MVT::v4i64, { 1, 9, 2, 4 } }, // gf2p8affineqb
4332 { ISD::BITREVERSE, MVT::v8i64, { 1, 9, 2, 4 } }, // gf2p8affineqb
4333 { X86ISD::VROTLI, MVT::v16i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
4334 { X86ISD::VROTLI, MVT::v32i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
4335 { X86ISD::VROTLI, MVT::v64i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
4336 };
4337 static const CostKindTblEntry GLMCostTbl[] = {
4338 { ISD::FSQRT, MVT::f32, { 19, 20, 1, 1 } }, // sqrtss
4339 { ISD::FSQRT, MVT::v4f32, { 37, 41, 1, 5 } }, // sqrtps
4340 { ISD::FSQRT, MVT::f64, { 34, 35, 1, 1 } }, // sqrtsd
4341 { ISD::FSQRT, MVT::v2f64, { 67, 71, 1, 5 } }, // sqrtpd
4342 };
4343 static const CostKindTblEntry SLMCostTbl[] = {
4344 { ISD::BSWAP, MVT::v2i64, { 5, 5, 1, 5 } },
4345 { ISD::BSWAP, MVT::v4i32, { 5, 5, 1, 5 } },
4346 { ISD::BSWAP, MVT::v8i16, { 5, 5, 1, 5 } },
4347 { ISD::FSQRT, MVT::f32, { 20, 20, 1, 1 } }, // sqrtss
4348 { ISD::FSQRT, MVT::v4f32, { 40, 41, 1, 5 } }, // sqrtps
4349 { ISD::FSQRT, MVT::f64, { 35, 35, 1, 1 } }, // sqrtsd
4350 { ISD::FSQRT, MVT::v2f64, { 70, 71, 1, 5 } }, // sqrtpd
4351 };
4352 static const CostKindTblEntry SSE42CostTbl[] = {
4353 { ISD::FMAXNUM, MVT::f32, { 5, 5, 7, 7 } }, // MAXSS + CMPUNORDSS + BLENDVPS
4354 { ISD::FMAXNUM, MVT::v4f32, { 4, 4, 4, 5 } }, // MAXPS + CMPUNORDPS + BLENDVPS
4355 { ISD::FMAXNUM, MVT::f64, { 5, 5, 7, 7 } }, // MAXSD + CMPUNORDSD + BLENDVPD
4356 { ISD::FMAXNUM, MVT::v2f64, { 4, 4, 4, 5 } }, // MAXPD + CMPUNORDPD + BLENDVPD
4357 { ISD::FSQRT, MVT::f32, { 18, 18, 1, 1 } }, // Nehalem from http://www.agner.org/
4358 { ISD::FSQRT, MVT::v4f32, { 18, 18, 1, 1 } }, // Nehalem from http://www.agner.org/
4359 };
4360 static const CostKindTblEntry SSE41CostTbl[] = {
4361 { ISD::ABS, MVT::v2i64, { 3, 4, 3, 5 } }, // BLENDVPD(X,PSUBQ(0,X),X)
4362 { ISD::SADDSAT, MVT::v2i64, { 10, 14, 17, 21 } },
4363 { ISD::SADDSAT, MVT::v4i32, { 5, 11, 8, 10 } },
4364 { ISD::SSUBSAT, MVT::v2i64, { 12, 19, 25, 29 } },
4365 { ISD::SSUBSAT, MVT::v4i32, { 6, 14, 10, 12 } },
4366 { ISD::SMAX, MVT::v2i64, { 3, 7, 2, 3 } },
4367 { ISD::SMAX, MVT::v4i32, { 1, 1, 1, 1 } },
4368 { ISD::SMAX, MVT::v16i8, { 1, 1, 1, 1 } },
4369 { ISD::SMIN, MVT::v2i64, { 3, 7, 2, 3 } },
4370 { ISD::SMIN, MVT::v4i32, { 1, 1, 1, 1 } },
4371 { ISD::SMIN, MVT::v16i8, { 1, 1, 1, 1 } },
4372 { ISD::SMULO, MVT::v2i64, { 9, 11, 13, 17 } },
4373 { ISD::SMULO, MVT::v4i32, { 20, 24, 13, 19 } },
4374 { ISD::SMULO, MVT::v8i16, { 5, 9, 8, 8 } },
4375 { ISD::SMULO, MVT::v16i8, { 13, 22, 24, 25 } },
4376 { ISD::UADDSAT, MVT::v2i64, { 6, 13, 14, 14 } },
4377 { ISD::UADDSAT, MVT::v4i32, { 2, 2, 4, 4 } },
4378 { ISD::USUBSAT, MVT::v2i64, { 6, 10, 14, 14 } },
4379 { ISD::USUBSAT, MVT::v4i32, { 1, 2, 2, 2 } },
4380 { ISD::UMAX, MVT::v2i64, { 2, 11, 6, 7 } },
4381 { ISD::UMAX, MVT::v4i32, { 1, 1, 1, 1 } },
4382 { ISD::UMAX, MVT::v8i16, { 1, 1, 1, 1 } },
4383 { ISD::UMIN, MVT::v2i64, { 2, 11, 6, 7 } },
4384 { ISD::UMIN, MVT::v4i32, { 1, 1, 1, 1 } },
4385 { ISD::UMIN, MVT::v8i16, { 1, 1, 1, 1 } },
4386 { ISD::UMULO, MVT::v2i64, { 14, 20, 15, 20 } },
4387 { ISD::UMULO, MVT::v4i32, { 19, 22, 12, 18 } },
4388 { ISD::UMULO, MVT::v8i16, { 4, 9, 7, 7 } },
4389 { ISD::UMULO, MVT::v16i8, { 13, 19, 18, 20 } },
4390 };
4391 static const CostKindTblEntry SSSE3CostTbl[] = {
4392 { ISD::ABS, MVT::v4i32, { 1, 2, 1, 1 } },
4393 { ISD::ABS, MVT::v8i16, { 1, 2, 1, 1 } },
4394 { ISD::ABS, MVT::v16i8, { 1, 2, 1, 1 } },
4395 { ISD::BITREVERSE, MVT::v2i64, { 16, 20, 11, 21 } },
4396 { ISD::BITREVERSE, MVT::v4i32, { 16, 20, 11, 21 } },
4397 { ISD::BITREVERSE, MVT::v8i16, { 16, 20, 11, 21 } },
4398 { ISD::BITREVERSE, MVT::v16i8, { 11, 12, 10, 16 } },
4399 { ISD::BSWAP, MVT::v2i64, { 2, 3, 1, 5 } },
4400 { ISD::BSWAP, MVT::v4i32, { 2, 3, 1, 5 } },
4401 { ISD::BSWAP, MVT::v8i16, { 2, 3, 1, 5 } },
4402 { ISD::CTLZ, MVT::v2i64, { 18, 28, 28, 35 } },
4403 { ISD::CTLZ, MVT::v4i32, { 15, 20, 22, 28 } },
4404 { ISD::CTLZ, MVT::v8i16, { 13, 17, 16, 22 } },
4405 { ISD::CTLZ, MVT::v16i8, { 11, 15, 10, 16 } },
4406 { ISD::CTPOP, MVT::v2i64, { 13, 19, 12, 18 } },
4407 { ISD::CTPOP, MVT::v4i32, { 18, 24, 16, 22 } },
4408 { ISD::CTPOP, MVT::v8i16, { 13, 18, 14, 20 } },
4409 { ISD::CTPOP, MVT::v16i8, { 11, 12, 10, 16 } },
4410 { ISD::CTTZ, MVT::v2i64, { 13, 25, 15, 22 } },
4411 { ISD::CTTZ, MVT::v4i32, { 18, 26, 19, 25 } },
4412 { ISD::CTTZ, MVT::v8i16, { 13, 20, 17, 23 } },
4413 { ISD::CTTZ, MVT::v16i8, { 11, 16, 13, 19 } }
4414 };
4415 static const CostKindTblEntry SSE2CostTbl[] = {
4416 { ISD::ABS, MVT::v2i64, { 3, 6, 5, 5 } },
4417 { ISD::ABS, MVT::v4i32, { 1, 4, 4, 4 } },
4418 { ISD::ABS, MVT::v8i16, { 1, 2, 3, 3 } },
4419 { ISD::ABS, MVT::v16i8, { 1, 2, 3, 3 } },
4420 { ISD::BITREVERSE, MVT::v2i64, { 16, 20, 32, 32 } },
4421 { ISD::BITREVERSE, MVT::v4i32, { 16, 20, 30, 30 } },
4422 { ISD::BITREVERSE, MVT::v8i16, { 16, 20, 25, 25 } },
4423 { ISD::BITREVERSE, MVT::v16i8, { 11, 12, 21, 21 } },
4424 { ISD::BSWAP, MVT::v2i64, { 5, 6, 11, 11 } },
4425 { ISD::BSWAP, MVT::v4i32, { 5, 5, 9, 9 } },
4426 { ISD::BSWAP, MVT::v8i16, { 5, 5, 4, 5 } },
4427 { ISD::CTLZ, MVT::v2i64, { 10, 45, 36, 38 } },
4428 { ISD::CTLZ, MVT::v4i32, { 10, 45, 38, 40 } },
4429 { ISD::CTLZ, MVT::v8i16, { 9, 38, 32, 34 } },
4430 { ISD::CTLZ, MVT::v16i8, { 8, 39, 29, 32 } },
4431 { ISD::CTPOP, MVT::v2i64, { 12, 26, 16, 18 } },
4432 { ISD::CTPOP, MVT::v4i32, { 15, 29, 21, 23 } },
4433 { ISD::CTPOP, MVT::v8i16, { 13, 25, 18, 20 } },
4434 { ISD::CTPOP, MVT::v16i8, { 10, 21, 14, 16 } },
4435 { ISD::CTTZ, MVT::v2i64, { 14, 28, 19, 21 } },
4436 { ISD::CTTZ, MVT::v4i32, { 18, 31, 24, 26 } },
4437 { ISD::CTTZ, MVT::v8i16, { 16, 27, 21, 23 } },
4438 { ISD::CTTZ, MVT::v16i8, { 13, 23, 17, 19 } },
4439 { ISD::SADDSAT, MVT::v2i64, { 12, 14, 24, 24 } },
4440 { ISD::SADDSAT, MVT::v4i32, { 6, 11, 11, 12 } },
4441 { ISD::SADDSAT, MVT::v8i16, { 1, 2, 1, 1 } },
4442 { ISD::SADDSAT, MVT::v16i8, { 1, 2, 1, 1 } },
4443 { ISD::SMAX, MVT::v2i64, { 4, 8, 15, 15 } },
4444 { ISD::SMAX, MVT::v4i32, { 2, 4, 5, 5 } },
4445 { ISD::SMAX, MVT::v8i16, { 1, 1, 1, 1 } },
4446 { ISD::SMAX, MVT::v16i8, { 2, 4, 5, 5 } },
4447 { ISD::SMIN, MVT::v2i64, { 4, 8, 15, 15 } },
4448 { ISD::SMIN, MVT::v4i32, { 2, 4, 5, 5 } },
4449 { ISD::SMIN, MVT::v8i16, { 1, 1, 1, 1 } },
4450 { ISD::SMIN, MVT::v16i8, { 2, 4, 5, 5 } },
4451 { ISD::SMULO, MVT::v2i64, { 30, 33, 13, 23 } },
4452 { ISD::SMULO, MVT::v4i32, { 20, 24, 23, 23 } },
4453 { ISD::SMULO, MVT::v8i16, { 5, 10, 8, 8 } },
4454 { ISD::SMULO, MVT::v16i8, { 13, 23, 24, 25 } },
4455 { ISD::SSUBSAT, MVT::v2i64, { 16, 19, 31, 31 } },
4456 { ISD::SSUBSAT, MVT::v4i32, { 6, 14, 12, 13 } },
4457 { ISD::SSUBSAT, MVT::v8i16, { 1, 2, 1, 1 } },
4458 { ISD::SSUBSAT, MVT::v16i8, { 1, 2, 1, 1 } },
4459 { ISD::UADDSAT, MVT::v2i64, { 7, 13, 14, 14 } },
4460 { ISD::UADDSAT, MVT::v4i32, { 4, 5, 7, 7 } },
4461 { ISD::UADDSAT, MVT::v8i16, { 1, 2, 1, 1 } },
4462 { ISD::UADDSAT, MVT::v16i8, { 1, 2, 1, 1 } },
4463 { ISD::UMAX, MVT::v2i64, { 4, 8, 15, 15 } },
4464 { ISD::UMAX, MVT::v4i32, { 2, 5, 8, 8 } },
4465 { ISD::UMAX, MVT::v8i16, { 1, 3, 3, 3 } },
4466 { ISD::UMAX, MVT::v16i8, { 1, 1, 1, 1 } },
4467 { ISD::UMIN, MVT::v2i64, { 4, 8, 15, 15 } },
4468 { ISD::UMIN, MVT::v4i32, { 2, 5, 8, 8 } },
4469 { ISD::UMIN, MVT::v8i16, { 1, 3, 3, 3 } },
4470 { ISD::UMIN, MVT::v16i8, { 1, 1, 1, 1 } },
4471 { ISD::UMULO, MVT::v2i64, { 30, 33, 15, 29 } },
4472 { ISD::UMULO, MVT::v4i32, { 19, 22, 14, 18 } },
4473 { ISD::UMULO, MVT::v8i16, { 4, 9, 7, 7 } },
4474 { ISD::UMULO, MVT::v16i8, { 13, 19, 20, 20 } },
4475 { ISD::USUBSAT, MVT::v2i64, { 7, 10, 14, 14 } },
4476 { ISD::USUBSAT, MVT::v4i32, { 4, 4, 7, 7 } },
4477 { ISD::USUBSAT, MVT::v8i16, { 1, 2, 1, 1 } },
4478 { ISD::USUBSAT, MVT::v16i8, { 1, 2, 1, 1 } },
4479 { ISD::FMAXNUM, MVT::f64, { 5, 5, 7, 7 } },
4480 { ISD::FMAXNUM, MVT::v2f64, { 4, 6, 6, 6 } },
4481 { ISD::FSQRT, MVT::f64, { 32, 32, 1, 1 } }, // Nehalem from http://www.agner.org/
4482 { ISD::FSQRT, MVT::v2f64, { 32, 32, 1, 1 } }, // Nehalem from http://www.agner.org/
4483 };
4484 static const CostKindTblEntry SSE1CostTbl[] = {
4485 { ISD::FMAXNUM, MVT::f32, { 5, 5, 7, 7 } },
4486 { ISD::FMAXNUM, MVT::v4f32, { 4, 6, 6, 6 } },
4487 { ISD::FSQRT, MVT::f32, { 28, 30, 1, 2 } }, // Pentium III from http://www.agner.org/
4488 { ISD::FSQRT, MVT::v4f32, { 56, 56, 1, 2 } }, // Pentium III from http://www.agner.org/
4489 };
4490 static const CostKindTblEntry BMI64CostTbl[] = { // 64-bit targets
4491 { ISD::CTTZ, MVT::i64, { 1, 1, 1, 1 } },
4492 };
4493 static const CostKindTblEntry BMI32CostTbl[] = { // 32 or 64-bit targets
4494 { ISD::CTTZ, MVT::i32, { 1, 1, 1, 1 } },
4495 { ISD::CTTZ, MVT::i16, { 2, 1, 1, 1 } },
4496 { ISD::CTTZ, MVT::i8, { 2, 1, 1, 1 } },
4497 };
4498 static const CostKindTblEntry LZCNT64CostTbl[] = { // 64-bit targets
4499 { ISD::CTLZ, MVT::i64, { 1, 1, 1, 1 } },
4500 };
4501 static const CostKindTblEntry LZCNT32CostTbl[] = { // 32 or 64-bit targets
4502 { ISD::CTLZ, MVT::i32, { 1, 1, 1, 1 } },
4503 { ISD::CTLZ, MVT::i16, { 2, 1, 1, 1 } },
4504 { ISD::CTLZ, MVT::i8, { 2, 1, 1, 1 } },
4505 };
4506 static const CostKindTblEntry POPCNT64CostTbl[] = { // 64-bit targets
4507 { ISD::CTPOP, MVT::i64, { 1, 1, 1, 1 } }, // popcnt
4508 };
4509 static const CostKindTblEntry POPCNT32CostTbl[] = { // 32 or 64-bit targets
4510 { ISD::CTPOP, MVT::i32, { 1, 1, 1, 1 } }, // popcnt
4511 { ISD::CTPOP, MVT::i16, { 1, 1, 2, 2 } }, // popcnt(zext())
4512 { ISD::CTPOP, MVT::i8, { 1, 1, 2, 2 } }, // popcnt(zext())
4513 };
4514 static const CostKindTblEntry PCLMULCostTbl[] = {
4515 { ISD::CLMUL, MVT::v2i64, { 3, 12, 4, 8 } }, // MOV+2xPCLMUL+unpack
4516 { ISD::CLMUL, MVT::v4i32, { 8, 18, 12, 16 } }, // MOV+4xPCLMUL+unpack
4517 { ISD::CLMUL, MVT::i64, { 3, 12, 4, 8 } }, // MOV+PCLMUL+MOV
4518 { ISD::CLMUL, MVT::i32, { 3, 12, 4, 8 } }, // MOV+PCLMUL+MOV
4519 { ISD::CLMUL, MVT::i16, { 3, 12, 4, 8 } }, // MOV+PCLMUL+MOV
4520 { ISD::CLMUL, MVT::i8, { 3, 12, 4, 8 } }, // MOV+PCLMUL+MOV
4521 };
4522 static const CostKindTblEntry X64CostTbl[] = { // 64-bit targets
4523 { ISD::ABS, MVT::i64, { 1, 2, 3, 3 } }, // SUB+CMOV
4524 { ISD::BITREVERSE, MVT::i64, { 10, 12, 20, 22 } },
4525 { ISD::BSWAP, MVT::i64, { 1, 2, 1, 2 } },
4526 { ISD::CTLZ, MVT::i64, { 1, 2, 3, 3 } }, // MOV+BSR+XOR
4527 { ISD::CTLZ, MVT::i32, { 1, 2, 3, 3 } }, // MOV+BSR+XOR
4528 { ISD::CTLZ, MVT::i16, { 2, 2, 3, 3 } }, // MOV+BSR+XOR
4529 { ISD::CTLZ, MVT::i8, { 2, 2, 4, 3 } }, // MOV+BSR+XOR
4530 { ISD::CTLZ_ZERO_POISON,MVT::i64,{ 1, 2, 2, 2 } }, // BSR+XOR
4531 { ISD::CTTZ, MVT::i64, { 1, 2, 2, 2 } }, // MOV+BSF
4532 { ISD::CTTZ, MVT::i32, { 1, 2, 2, 2 } }, // MOV+BSF
4533 { ISD::CTTZ, MVT::i16, { 2, 2, 2, 2 } }, // MOV+BSF
4534 { ISD::CTTZ, MVT::i8, { 2, 2, 2, 2 } }, // MOV+BSF
4535 { ISD::CTTZ_ZERO_POISON,MVT::i64,{ 1, 2, 1, 2 } }, // BSF
4536 { ISD::CTPOP, MVT::i64, { 10, 6, 19, 19 } },
4537 { ISD::ROTL, MVT::i64, { 2, 3, 1, 3 } },
4538 { ISD::ROTR, MVT::i64, { 2, 3, 1, 3 } },
4539 { X86ISD::VROTLI, MVT::i64, { 1, 1, 1, 1 } },
4540 { ISD::FSHL, MVT::i64, { 4, 4, 1, 4 } },
4541 { ISD::SADDSAT, MVT::i64, { 4, 4, 7, 10 } },
4542 { ISD::SSUBSAT, MVT::i64, { 4, 5, 8, 11 } },
4543 { ISD::UADDSAT, MVT::i64, { 2, 3, 4, 7 } },
4544 { ISD::USUBSAT, MVT::i64, { 2, 3, 4, 7 } },
4545 { ISD::SMAX, MVT::i64, { 1, 3, 2, 3 } },
4546 { ISD::SMIN, MVT::i64, { 1, 3, 2, 3 } },
4547 { ISD::UMAX, MVT::i64, { 1, 3, 2, 3 } },
4548 { ISD::UMIN, MVT::i64, { 1, 3, 2, 3 } },
4549 { ISD::SADDO, MVT::i64, { 2, 2, 4, 6 } },
4550 { ISD::UADDO, MVT::i64, { 2, 2, 4, 6 } },
4551 { ISD::SMULO, MVT::i64, { 4, 4, 4, 6 } },
4552 { ISD::UMULO, MVT::i64, { 8, 8, 4, 7 } },
4553 };
4554 static const CostKindTblEntry X86CostTbl[] = { // 32 or 64-bit targets
4555 { ISD::ABS, MVT::i32, { 1, 2, 3, 3 } }, // SUB+XOR+SRA or SUB+CMOV
4556 { ISD::ABS, MVT::i16, { 2, 2, 3, 3 } }, // SUB+XOR+SRA or SUB+CMOV
4557 { ISD::ABS, MVT::i8, { 2, 4, 4, 3 } }, // SUB+XOR+SRA
4558 { ISD::BITREVERSE, MVT::i32, { 9, 12, 17, 19 } },
4559 { ISD::BITREVERSE, MVT::i16, { 9, 12, 17, 19 } },
4560 { ISD::BITREVERSE, MVT::i8, { 7, 9, 13, 14 } },
4561 { ISD::BSWAP, MVT::i32, { 1, 1, 1, 1 } },
4562 { ISD::BSWAP, MVT::i16, { 1, 2, 1, 2 } }, // ROL
4563 { ISD::CTLZ, MVT::i32, { 2, 2, 4, 5 } }, // BSR+XOR or BSR+XOR+CMOV
4564 { ISD::CTLZ, MVT::i16, { 2, 2, 4, 5 } }, // BSR+XOR or BSR+XOR+CMOV
4565 { ISD::CTLZ, MVT::i8, { 2, 2, 5, 6 } }, // BSR+XOR or BSR+XOR+CMOV
4566 { ISD::CTLZ_ZERO_POISON,MVT::i32,{ 1, 2, 2, 2 } }, // BSR+XOR
4567 { ISD::CTLZ_ZERO_POISON,MVT::i16,{ 2, 2, 2, 2 } }, // BSR+XOR
4568 { ISD::CTLZ_ZERO_POISON,MVT::i8, { 2, 2, 3, 3 } }, // BSR+XOR
4569 { ISD::CTTZ, MVT::i32, { 2, 2, 3, 3 } }, // TEST+BSF+CMOV/BRANCH
4570 { ISD::CTTZ, MVT::i16, { 2, 2, 2, 3 } }, // TEST+BSF+CMOV/BRANCH
4571 { ISD::CTTZ, MVT::i8, { 2, 2, 2, 3 } }, // TEST+BSF+CMOV/BRANCH
4572 { ISD::CTTZ_ZERO_POISON,MVT::i32,{ 1, 2, 1, 2 } }, // BSF
4573 { ISD::CTTZ_ZERO_POISON,MVT::i16,{ 2, 2, 1, 2 } }, // BSF
4574 { ISD::CTTZ_ZERO_POISON,MVT::i8, { 2, 2, 1, 2 } }, // BSF
4575 { ISD::CTPOP, MVT::i32, { 8, 7, 15, 15 } },
4576 { ISD::CTPOP, MVT::i16, { 9, 8, 17, 17 } },
4577 { ISD::CTPOP, MVT::i8, { 7, 6, 6, 6 } },
4578 { ISD::ROTL, MVT::i32, { 2, 3, 1, 3 } },
4579 { ISD::ROTL, MVT::i16, { 2, 3, 1, 3 } },
4580 { ISD::ROTL, MVT::i8, { 2, 3, 1, 3 } },
4581 { ISD::ROTR, MVT::i32, { 2, 3, 1, 3 } },
4582 { ISD::ROTR, MVT::i16, { 2, 3, 1, 3 } },
4583 { ISD::ROTR, MVT::i8, { 2, 3, 1, 3 } },
4584 { X86ISD::VROTLI, MVT::i32, { 1, 1, 1, 1 } },
4585 { X86ISD::VROTLI, MVT::i16, { 1, 1, 1, 1 } },
4586 { X86ISD::VROTLI, MVT::i8, { 1, 1, 1, 1 } },
4587 { ISD::FSHL, MVT::i32, { 4, 4, 1, 4 } },
4588 { ISD::FSHL, MVT::i16, { 4, 4, 2, 5 } },
4589 { ISD::FSHL, MVT::i8, { 4, 4, 2, 5 } },
4590 { ISD::SADDSAT, MVT::i32, { 3, 4, 6, 9 } },
4591 { ISD::SADDSAT, MVT::i16, { 4, 4, 7, 10 } },
4592 { ISD::SADDSAT, MVT::i8, { 4, 5, 8, 11 } },
4593 { ISD::SSUBSAT, MVT::i32, { 4, 4, 7, 10 } },
4594 { ISD::SSUBSAT, MVT::i16, { 4, 4, 7, 10 } },
4595 { ISD::SSUBSAT, MVT::i8, { 4, 5, 8, 11 } },
4596 { ISD::UADDSAT, MVT::i32, { 2, 3, 4, 7 } },
4597 { ISD::UADDSAT, MVT::i16, { 2, 3, 4, 7 } },
4598 { ISD::UADDSAT, MVT::i8, { 3, 3, 5, 8 } },
4599 { ISD::USUBSAT, MVT::i32, { 2, 3, 4, 7 } },
4600 { ISD::USUBSAT, MVT::i16, { 2, 3, 4, 7 } },
4601 { ISD::USUBSAT, MVT::i8, { 3, 3, 5, 8 } },
4602 { ISD::SMAX, MVT::i32, { 1, 2, 2, 3 } },
4603 { ISD::SMAX, MVT::i16, { 1, 4, 2, 4 } },
4604 { ISD::SMAX, MVT::i8, { 1, 4, 2, 4 } },
4605 { ISD::SMIN, MVT::i32, { 1, 2, 2, 3 } },
4606 { ISD::SMIN, MVT::i16, { 1, 4, 2, 4 } },
4607 { ISD::SMIN, MVT::i8, { 1, 4, 2, 4 } },
4608 { ISD::UMAX, MVT::i32, { 1, 2, 2, 3 } },
4609 { ISD::UMAX, MVT::i16, { 1, 4, 2, 4 } },
4610 { ISD::UMAX, MVT::i8, { 1, 4, 2, 4 } },
4611 { ISD::UMIN, MVT::i32, { 1, 2, 2, 3 } },
4612 { ISD::UMIN, MVT::i16, { 1, 4, 2, 4 } },
4613 { ISD::UMIN, MVT::i8, { 1, 4, 2, 4 } },
4614 { ISD::SADDO, MVT::i32, { 2, 2, 4, 6 } },
4615 { ISD::SADDO, MVT::i16, { 2, 2, 4, 6 } },
4616 { ISD::SADDO, MVT::i8, { 2, 2, 4, 6 } },
4617 { ISD::UADDO, MVT::i32, { 2, 2, 4, 6 } },
4618 { ISD::UADDO, MVT::i16, { 2, 2, 4, 6 } },
4619 { ISD::UADDO, MVT::i8, { 2, 2, 4, 6 } },
4620 { ISD::SMULO, MVT::i32, { 2, 2, 4, 6 } },
4621 { ISD::SMULO, MVT::i16, { 5, 5, 4, 6 } },
4622 { ISD::SMULO, MVT::i8, { 6, 6, 4, 6 } },
4623 { ISD::UMULO, MVT::i32, { 6, 6, 4, 8 } },
4624 { ISD::UMULO, MVT::i16, { 6, 6, 4, 9 } },
4625 { ISD::UMULO, MVT::i8, { 6, 6, 4, 6 } },
4626 };
4627
4628 Type *RetTy = ICA.getReturnType();
4629 Type *OpTy = RetTy;
4630 Intrinsic::ID IID = ICA.getID();
4631 unsigned ISD = ISD::DELETED_NODE;
4632 switch (IID) {
4633 default:
4634 break;
4635 case Intrinsic::abs:
4636 ISD = ISD::ABS;
4637 break;
4638 case Intrinsic::bitreverse:
4640 break;
4641 case Intrinsic::bswap:
4642 ISD = ISD::BSWAP;
4643 break;
4644 case Intrinsic::ctlz:
4645 ISD = ISD::CTLZ;
4646 break;
4647 case Intrinsic::ctpop:
4648 ISD = ISD::CTPOP;
4649 break;
4650 case Intrinsic::cttz:
4651 ISD = ISD::CTTZ;
4652 break;
4653 case Intrinsic::fshl:
4654 ISD = ISD::FSHL;
4655 if (!ICA.isTypeBasedOnly()) {
4656 const SmallVectorImpl<const Value *> &Args = ICA.getArgs();
4657 if (Args[0] == Args[1]) {
4658 ISD = ISD::ROTL;
4659 // Handle uniform constant rotation amounts.
4660 // TODO: Handle funnel-shift cases.
4661 const APInt *Amt;
4662 if (Args[2] &&
4664 ISD = X86ISD::VROTLI;
4665 }
4666 }
4667 break;
4668 case Intrinsic::fshr:
4669 // FSHR has same costs so don't duplicate.
4670 ISD = ISD::FSHL;
4671 if (!ICA.isTypeBasedOnly()) {
4672 const SmallVectorImpl<const Value *> &Args = ICA.getArgs();
4673 if (Args[0] == Args[1]) {
4674 ISD = ISD::ROTR;
4675 // Handle uniform constant rotation amount.
4676 // TODO: Handle funnel-shift cases.
4677 const APInt *Amt;
4678 if (Args[2] &&
4680 ISD = X86ISD::VROTLI;
4681 }
4682 }
4683 break;
4684 case Intrinsic::lrint:
4685 case Intrinsic::llrint: {
4686 // X86 can use the CVTP2SI instructions to lower lrint/llrint calls, which
4687 // have the same costs as the CVTTP2SI (fptosi) instructions
4688 const SmallVectorImpl<Type *> &ArgTys = ICA.getArgTypes();
4689 return getCastInstrCost(Instruction::FPToSI, RetTy, ArgTys[0],
4691 }
4692 case Intrinsic::maxnum:
4693 case Intrinsic::minnum:
4694 // FMINNUM has same costs so don't duplicate.
4695 ISD = ISD::FMAXNUM;
4696 break;
4697 case Intrinsic::sadd_sat:
4698 ISD = ISD::SADDSAT;
4699 break;
4700 case Intrinsic::smax:
4701 ISD = ISD::SMAX;
4702 break;
4703 case Intrinsic::smin:
4704 ISD = ISD::SMIN;
4705 break;
4706 case Intrinsic::ssub_sat:
4707 ISD = ISD::SSUBSAT;
4708 break;
4709 case Intrinsic::uadd_sat:
4710 ISD = ISD::UADDSAT;
4711 break;
4712 case Intrinsic::umax:
4713 ISD = ISD::UMAX;
4714 break;
4715 case Intrinsic::umin:
4716 ISD = ISD::UMIN;
4717 break;
4718 case Intrinsic::usub_sat:
4719 ISD = ISD::USUBSAT;
4720 break;
4721 case Intrinsic::sqrt:
4722 ISD = ISD::FSQRT;
4723 break;
4724 case Intrinsic::sadd_with_overflow:
4725 case Intrinsic::ssub_with_overflow:
4726 // SSUBO has same costs so don't duplicate.
4727 ISD = ISD::SADDO;
4728 OpTy = RetTy->getContainedType(0);
4729 break;
4730 case Intrinsic::uadd_with_overflow:
4731 case Intrinsic::usub_with_overflow:
4732 // USUBO has same costs so don't duplicate.
4733 ISD = ISD::UADDO;
4734 OpTy = RetTy->getContainedType(0);
4735 break;
4736 case Intrinsic::smul_with_overflow:
4737 ISD = ISD::SMULO;
4738 OpTy = RetTy->getContainedType(0);
4739 break;
4740 case Intrinsic::umul_with_overflow:
4741 ISD = ISD::UMULO;
4742 OpTy = RetTy->getContainedType(0);
4743 break;
4744 case Intrinsic::clmul:
4745 ISD = ISD::CLMUL;
4746 break;
4747 }
4748
4749 if (ISD != ISD::DELETED_NODE) {
4750 auto adjustTableCost = [&](int ISD, unsigned Cost,
4751 std::pair<InstructionCost, MVT> LT,
4753 InstructionCost LegalizationCost = LT.first;
4754 MVT MTy = LT.second;
4755
4756 // If there are no NANs to deal with, then these are reduced to a
4757 // single MIN** or MAX** instruction instead of the MIN/CMP/SELECT that we
4758 // assume is used in the non-fast case.
4759 if (ISD == ISD::FMAXNUM || ISD == ISD::FMINNUM) {
4760 if (FMF.noNaNs())
4761 return LegalizationCost * 1;
4762 }
4763
4764 // For cases where some ops can be folded into a load/store, assume free.
4765 if (MTy.isScalarInteger()) {
4766 if (ISD == ISD::BSWAP && ST->hasMOVBE() && ST->hasFastMOVBE()) {
4767 if (const Instruction *II = ICA.getInst()) {
4768 if (II->hasOneUse() && isa<StoreInst>(II->user_back()))
4769 return TTI::TCC_Free;
4770 if (auto *LI = dyn_cast<LoadInst>(II->getOperand(0))) {
4771 if (LI->hasOneUse())
4772 return TTI::TCC_Free;
4773 }
4774 }
4775 }
4776 }
4777
4778 return LegalizationCost * (int)Cost;
4779 };
4780
4781 // Legalize the type.
4782 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(OpTy);
4783 MVT MTy = LT.second;
4784
4785 // Without BMI/LZCNT see if we're only looking for a *_ZERO_POISON cost.
4786 if (((ISD == ISD::CTTZ && !ST->hasBMI()) ||
4787 (ISD == ISD::CTLZ && !ST->hasLZCNT())) &&
4788 !MTy.isVector() && !ICA.isTypeBasedOnly()) {
4789 const SmallVectorImpl<const Value *> &Args = ICA.getArgs();
4790 if (auto *Cst = dyn_cast<ConstantInt>(Args[1]))
4791 if (Cst->isAllOnesValue())
4792 ISD =
4794 }
4795
4796 // FSQRT is a single instruction.
4798 return LT.first;
4799
4800 if (ST->useGLMDivSqrtCosts())
4801 if (const auto *Entry = CostTableLookup(GLMCostTbl, ISD, MTy))
4802 if (auto KindCost = Entry->Cost[CostKind])
4803 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4804
4805 if (ST->useSLMArithCosts())
4806 if (const auto *Entry = CostTableLookup(SLMCostTbl, ISD, MTy))
4807 if (auto KindCost = Entry->Cost[CostKind])
4808 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4809
4810 if (ST->hasVBMI2())
4811 if (const auto *Entry = CostTableLookup(AVX512VBMI2CostTbl, ISD, MTy))
4812 if (auto KindCost = Entry->Cost[CostKind])
4813 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4814
4815 if (ST->hasBITALG())
4816 if (const auto *Entry = CostTableLookup(AVX512BITALGCostTbl, ISD, MTy))
4817 if (auto KindCost = Entry->Cost[CostKind])
4818 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4819
4820 if (ST->hasVPOPCNTDQ())
4821 if (const auto *Entry = CostTableLookup(AVX512VPOPCNTDQCostTbl, ISD, MTy))
4822 if (auto KindCost = Entry->Cost[CostKind])
4823 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4824
4825 if (ST->hasGFNI())
4826 if (const auto *Entry = CostTableLookup(GFNICostTbl, ISD, MTy))
4827 if (auto KindCost = Entry->Cost[CostKind])
4828 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4829
4830 if (ST->hasCDI())
4831 if (const auto *Entry = CostTableLookup(AVX512CDCostTbl, ISD, MTy))
4832 if (auto KindCost = Entry->Cost[CostKind])
4833 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4834
4835 if (ST->hasBWI())
4836 if (const auto *Entry = CostTableLookup(AVX512BWCostTbl, ISD, MTy))
4837 if (auto KindCost = Entry->Cost[CostKind])
4838 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4839
4840 if (ST->hasAVX512())
4841 if (const auto *Entry = CostTableLookup(AVX512CostTbl, ISD, MTy))
4842 if (auto KindCost = Entry->Cost[CostKind])
4843 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4844
4845 if (ST->hasXOP())
4846 if (const auto *Entry = CostTableLookup(XOPCostTbl, ISD, MTy))
4847 if (auto KindCost = Entry->Cost[CostKind])
4848 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4849
4850 if (ST->hasAVX2())
4851 if (const auto *Entry = CostTableLookup(AVX2CostTbl, ISD, MTy))
4852 if (auto KindCost = Entry->Cost[CostKind])
4853 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4854
4855 if (ST->hasAVX())
4856 if (const auto *Entry = CostTableLookup(AVX1CostTbl, ISD, MTy))
4857 if (auto KindCost = Entry->Cost[CostKind])
4858 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4859
4860 if (ST->hasSSE42())
4861 if (const auto *Entry = CostTableLookup(SSE42CostTbl, ISD, MTy))
4862 if (auto KindCost = Entry->Cost[CostKind])
4863 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4864
4865 if (ST->hasSSE41())
4866 if (const auto *Entry = CostTableLookup(SSE41CostTbl, ISD, MTy))
4867 if (auto KindCost = Entry->Cost[CostKind])
4868 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4869
4870 if (ST->hasSSSE3())
4871 if (const auto *Entry = CostTableLookup(SSSE3CostTbl, ISD, MTy))
4872 if (auto KindCost = Entry->Cost[CostKind])
4873 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4874
4875 if (ST->hasSSE2())
4876 if (const auto *Entry = CostTableLookup(SSE2CostTbl, ISD, MTy))
4877 if (auto KindCost = Entry->Cost[CostKind])
4878 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4879
4880 if (ST->hasSSE1())
4881 if (const auto *Entry = CostTableLookup(SSE1CostTbl, ISD, MTy))
4882 if (auto KindCost = Entry->Cost[CostKind])
4883 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4884
4885 if (ST->hasBMI()) {
4886 if (ST->is64Bit())
4887 if (const auto *Entry = CostTableLookup(BMI64CostTbl, ISD, MTy))
4888 if (auto KindCost = Entry->Cost[CostKind])
4889 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4890
4891 if (const auto *Entry = CostTableLookup(BMI32CostTbl, ISD, MTy))
4892 if (auto KindCost = Entry->Cost[CostKind])
4893 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4894 }
4895
4896 if (ST->hasLZCNT()) {
4897 if (ST->is64Bit())
4898 if (const auto *Entry = CostTableLookup(LZCNT64CostTbl, ISD, MTy))
4899 if (auto KindCost = Entry->Cost[CostKind])
4900 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4901
4902 if (const auto *Entry = CostTableLookup(LZCNT32CostTbl, ISD, MTy))
4903 if (auto KindCost = Entry->Cost[CostKind])
4904 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4905 }
4906
4907 if (ST->hasPOPCNT()) {
4908 if (ST->is64Bit())
4909 if (const auto *Entry = CostTableLookup(POPCNT64CostTbl, ISD, MTy))
4910 if (auto KindCost = Entry->Cost[CostKind])
4911 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4912
4913 if (const auto *Entry = CostTableLookup(POPCNT32CostTbl, ISD, MTy))
4914 if (auto KindCost = Entry->Cost[CostKind])
4915 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4916 }
4917
4918 // FIXME: PCLMUL w/ AVX/AVX512 and VPCLMULQDQ are not handled properly.
4919 if (ST->hasPCLMUL())
4920 if (const auto *Entry = CostTableLookup(PCLMULCostTbl, ISD, MTy))
4921 if (auto KindCost = Entry->Cost[CostKind])
4922 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4923
4924 if (ST->is64Bit())
4925 if (const auto *Entry = CostTableLookup(X64CostTbl, ISD, MTy))
4926 if (auto KindCost = Entry->Cost[CostKind])
4927 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4928
4929 if (const auto *Entry = CostTableLookup(X86CostTbl, ISD, MTy))
4930 if (auto KindCost = Entry->Cost[CostKind])
4931 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4932
4933 // Without arg data, we need to compute the expanded costs of custom lowered
4934 // intrinsics to prevent use of the (very low) default costs.
4935 if (ICA.isTypeBasedOnly() &&
4936 (IID == Intrinsic::fshl || IID == Intrinsic::fshr)) {
4937 Type *CondTy = RetTy->getWithNewBitWidth(1);
4939 Cost += getArithmeticInstrCost(BinaryOperator::Or, RetTy, CostKind);
4940 Cost += getArithmeticInstrCost(BinaryOperator::Sub, RetTy, CostKind);
4941 Cost += getArithmeticInstrCost(BinaryOperator::Shl, RetTy, CostKind);
4942 Cost += getArithmeticInstrCost(BinaryOperator::LShr, RetTy, CostKind);
4943 Cost += getArithmeticInstrCost(BinaryOperator::And, RetTy, CostKind);
4944 Cost += getCmpSelInstrCost(BinaryOperator::ICmp, RetTy, CondTy,
4946 Cost += getCmpSelInstrCost(BinaryOperator::Select, RetTy, CondTy,
4948 return Cost;
4949 }
4950 }
4951
4953}
4954
4956 unsigned Opcode, Type *Val, TTI::TargetCostKind CostKind, unsigned Index,
4957 const Value *Op0, const Value *Op1, TTI::VectorInstrContext VIC) const {
4958 static const CostTblEntry SLMCostTbl[] = {
4959 { ISD::EXTRACT_VECTOR_ELT, MVT::i8, 4 },
4960 { ISD::EXTRACT_VECTOR_ELT, MVT::i16, 4 },
4961 { ISD::EXTRACT_VECTOR_ELT, MVT::i32, 4 },
4962 { ISD::EXTRACT_VECTOR_ELT, MVT::i64, 7 }
4963 };
4964
4965 assert(Val->isVectorTy() && "This must be a vector type");
4966 auto *VT = cast<VectorType>(Val);
4967 if (VT->isScalableTy())
4969
4970 Type *ScalarType = Val->getScalarType();
4971 InstructionCost RegisterFileMoveCost = 0;
4972
4973 // Non-immediate extraction/insertion can be handled as a sequence of
4974 // aliased loads+stores via the stack.
4975 if (Index == -1U && (Opcode == Instruction::ExtractElement ||
4976 Opcode == Instruction::InsertElement)) {
4977 // TODO: On some SSE41+ targets, we expand to cmp+splat+select patterns:
4978 // inselt N0, N1, N2 --> select (SplatN2 == {0,1,2...}) ? SplatN1 : N0.
4979
4980 // TODO: Move this to BasicTTIImpl.h? We'd need better gep + index handling.
4981 assert(isa<FixedVectorType>(Val) && "Fixed vector type expected");
4982 Align VecAlign = DL.getPrefTypeAlign(Val);
4983 Align SclAlign = DL.getPrefTypeAlign(ScalarType);
4984
4985 // Extract - store vector to stack, load scalar.
4986 if (Opcode == Instruction::ExtractElement) {
4987 return getMemoryOpCost(Instruction::Store, Val, VecAlign, 0, CostKind) +
4988 getMemoryOpCost(Instruction::Load, ScalarType, SclAlign, 0,
4989 CostKind);
4990 }
4991 // Insert - store vector to stack, store scalar, load vector.
4992 if (Opcode == Instruction::InsertElement) {
4993 return getMemoryOpCost(Instruction::Store, Val, VecAlign, 0, CostKind) +
4994 getMemoryOpCost(Instruction::Store, ScalarType, SclAlign, 0,
4995 CostKind) +
4996 getMemoryOpCost(Instruction::Load, Val, VecAlign, 0, CostKind);
4997 }
4998 }
4999
5000 if (Index != -1U && (Opcode == Instruction::ExtractElement ||
5001 Opcode == Instruction::InsertElement)) {
5002 // Extraction of vXi1 elements are now efficiently handled by MOVMSK.
5003 if (Opcode == Instruction::ExtractElement &&
5004 ScalarType->getScalarSizeInBits() == 1 &&
5005 cast<FixedVectorType>(Val)->getNumElements() > 1)
5006 return 1;
5007
5008 // Legalize the type.
5009 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Val);
5010
5011 // This type is legalized to a scalar type.
5012 if (!LT.second.isVector())
5013 return TTI::TCC_Free;
5014
5015 // The type may be split. Normalize the index to the new type.
5016 unsigned SizeInBits = LT.second.getSizeInBits();
5017 unsigned NumElts = LT.second.getVectorNumElements();
5018 unsigned SubNumElts = NumElts;
5019 Index = Index % NumElts;
5020
5021 // For >128-bit vectors, we need to extract higher 128-bit subvectors.
5022 // For inserts, we also need to insert the subvector back.
5023 if (SizeInBits > 128) {
5024 assert((SizeInBits % 128) == 0 && "Illegal vector");
5025 unsigned NumSubVecs = SizeInBits / 128;
5026 SubNumElts = NumElts / NumSubVecs;
5027 if (SubNumElts <= Index) {
5028 RegisterFileMoveCost += (Opcode == Instruction::InsertElement ? 2 : 1);
5029 Index %= SubNumElts;
5030 }
5031 }
5032
5033 MVT MScalarTy = LT.second.getScalarType();
5034 auto IsCheapPInsrPExtrInsertPS = [&]() {
5035 // Assume pinsr/pextr XMM <-> GPR is relatively cheap on all targets.
5036 // Inserting f32 into index0 is just movss.
5037 // Also, assume insertps is relatively cheap on all >= SSE41 targets.
5038 return (MScalarTy == MVT::i16 && ST->hasSSE2()) ||
5039 (MScalarTy.isInteger() && ST->hasSSE41()) ||
5040 (MScalarTy == MVT::f32 && ST->hasSSE1() && Index == 0 &&
5041 Opcode == Instruction::InsertElement) ||
5042 (MScalarTy == MVT::f32 && ST->hasSSE41() &&
5043 Opcode == Instruction::InsertElement);
5044 };
5045
5046 if (Index == 0) {
5047 // Floating point scalars are already located in index #0.
5048 // Many insertions to #0 can fold away for scalar fp-ops, so let's assume
5049 // true for all.
5050 if (ScalarType->isFloatingPointTy() &&
5051 (Opcode != Instruction::InsertElement || !Op0 ||
5052 isa<UndefValue>(Op0)))
5053 return RegisterFileMoveCost;
5054
5055 if (Opcode == Instruction::InsertElement &&
5057 // Consider the gather cost to be cheap.
5059 return RegisterFileMoveCost;
5060 if (!IsCheapPInsrPExtrInsertPS()) {
5061 // mov constant-to-GPR + movd/movq GPR -> XMM.
5062 if (isa_and_nonnull<Constant>(Op1) && Op1->getType()->isIntegerTy())
5063 return 2 + RegisterFileMoveCost;
5064 // Assume movd/movq GPR -> XMM is relatively cheap on all targets.
5065 return 1 + RegisterFileMoveCost;
5066 }
5067 }
5068
5069 // Assume movd/movq XMM -> GPR is relatively cheap on all targets.
5070 if (ScalarType->isIntegerTy() && Opcode == Instruction::ExtractElement)
5071 return 1 + RegisterFileMoveCost;
5072 }
5073
5074 int ISD = TLI->InstructionOpcodeToISD(Opcode);
5075 assert(ISD && "Unexpected vector opcode");
5076 if (ST->useSLMArithCosts())
5077 if (auto *Entry = CostTableLookup(SLMCostTbl, ISD, MScalarTy))
5078 return Entry->Cost + RegisterFileMoveCost;
5079
5080 // Consider cheap cases.
5081 if (IsCheapPInsrPExtrInsertPS())
5082 return 1 + RegisterFileMoveCost;
5083
5084 // For extractions we just need to shuffle the element to index 0, which
5085 // should be very cheap (assume cost = 1). For insertions we need to shuffle
5086 // the elements to its destination. In both cases we must handle the
5087 // subvector move(s).
5088 // If the vector type is already less than 128-bits then don't reduce it.
5089 // TODO: Under what circumstances should we shuffle using the full width?
5090 InstructionCost ShuffleCost = 1;
5091 if (Opcode == Instruction::InsertElement) {
5092 auto *SubTy = cast<VectorType>(Val);
5093 EVT VT = TLI->getValueType(DL, Val);
5094 if (VT.getScalarType() != MScalarTy || VT.getSizeInBits() >= 128)
5095 SubTy = FixedVectorType::get(ScalarType, SubNumElts);
5096 ShuffleCost = getShuffleCost(TTI::SK_PermuteTwoSrc, SubTy, SubTy, {},
5097 CostKind, 0, SubTy);
5098 }
5099 int IntOrFpCost = ScalarType->isFloatingPointTy() ? 0 : 1;
5100 return ShuffleCost + IntOrFpCost + RegisterFileMoveCost;
5101 }
5102
5103 return BaseT::getVectorInstrCost(Opcode, Val, CostKind, Index, Op0, Op1,
5104 VIC) +
5105 RegisterFileMoveCost;
5106}
5107
5109 VectorType *Ty, const APInt &DemandedElts, bool Insert, bool Extract,
5110 TTI::TargetCostKind CostKind, bool ForPoisonSrc, ArrayRef<Value *> VL,
5111 TTI::VectorInstrContext VIC) const {
5112 assert(DemandedElts.getBitWidth() ==
5113 cast<FixedVectorType>(Ty)->getNumElements() &&
5114 "Vector size mismatch");
5115
5116 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Ty);
5117 MVT MScalarTy = LT.second.getScalarType();
5118 unsigned LegalVectorBitWidth = LT.second.getSizeInBits();
5120
5121 constexpr unsigned LaneBitWidth = 128;
5122 assert((LegalVectorBitWidth < LaneBitWidth ||
5123 (LegalVectorBitWidth % LaneBitWidth) == 0) &&
5124 "Illegal vector");
5125
5126 const int NumLegalVectors = LT.first.getValue();
5127 assert(NumLegalVectors >= 0 && "Negative cost!");
5128
5129 // For insertions, a ISD::BUILD_VECTOR style vector initialization can be much
5130 // cheaper than an accumulation of ISD::INSERT_VECTOR_ELT. SLPVectorizer has
5131 // a special heuristic regarding poison input which is passed here in
5132 // ForPoisonSrc.
5133 if (Insert && !ForPoisonSrc) {
5134 // This is nearly identical to BaseT::getScalarizationOverhead(), except
5135 // it is passing nullptr to getVectorInstrCost() for Op0 (instead of
5136 // Constant::getNullValue()), which makes the X86TTIImpl
5137 // getVectorInstrCost() return 0 instead of 1.
5138 for (unsigned I : seq(DemandedElts.getBitWidth())) {
5139 if (!DemandedElts[I])
5140 continue;
5141 Cost += getVectorInstrCost(Instruction::InsertElement, Ty, CostKind, I,
5143 VL.empty() ? nullptr : VL[I],
5145 }
5146 return Cost;
5147 }
5148
5149 if (Insert) {
5150 if ((MScalarTy == MVT::i16 && ST->hasSSE2()) ||
5151 (MScalarTy.isInteger() && ST->hasSSE41()) ||
5152 (MScalarTy == MVT::f32 && ST->hasSSE41())) {
5153 // For types we can insert directly, insertion into 128-bit sub vectors is
5154 // cheap, followed by a cheap chain of concatenations.
5155 if (LegalVectorBitWidth <= LaneBitWidth) {
5156 Cost += BaseT::getScalarizationOverhead(Ty, DemandedElts, Insert,
5157 /*Extract*/ false, CostKind);
5158 } else {
5159 // In each 128-lane, if at least one index is demanded but not all
5160 // indices are demanded and this 128-lane is not the first 128-lane of
5161 // the legalized-vector, then this 128-lane needs a extracti128; If in
5162 // each 128-lane, there is at least one demanded index, this 128-lane
5163 // needs a inserti128.
5164
5165 // The following cases will help you build a better understanding:
5166 // Assume we insert several elements into a v8i32 vector in avx2,
5167 // Case#1: inserting into 1th index needs vpinsrd + inserti128.
5168 // Case#2: inserting into 5th index needs extracti128 + vpinsrd +
5169 // inserti128.
5170 // Case#3: inserting into 4,5,6,7 index needs 4*vpinsrd + inserti128.
5171 assert((LegalVectorBitWidth % LaneBitWidth) == 0 && "Illegal vector");
5172 unsigned NumLegalLanes = LegalVectorBitWidth / LaneBitWidth;
5173 unsigned NumLanesTotal = NumLegalLanes * NumLegalVectors;
5174 unsigned NumLegalElts =
5175 LT.second.getVectorNumElements() * NumLegalVectors;
5176 assert(NumLegalElts >= DemandedElts.getBitWidth() &&
5177 "Vector has been legalized to smaller element count");
5178 assert((NumLegalElts % NumLanesTotal) == 0 &&
5179 "Unexpected elts per lane");
5180 unsigned NumEltsPerLane = NumLegalElts / NumLanesTotal;
5181
5182 APInt WidenedDemandedElts = DemandedElts.zext(NumLegalElts);
5183 auto *LaneTy =
5184 FixedVectorType::get(Ty->getElementType(), NumEltsPerLane);
5185
5186 for (unsigned I = 0; I != NumLanesTotal; ++I) {
5187 APInt LaneEltMask = WidenedDemandedElts.extractBits(
5188 NumEltsPerLane, NumEltsPerLane * I);
5189 if (LaneEltMask.isZero())
5190 continue;
5191 // FIXME: we don't need to extract if all non-demanded elements
5192 // are legalization-inserted padding.
5193 if (!LaneEltMask.isAllOnes())
5195 CostKind, I * NumEltsPerLane, LaneTy);
5196 Cost += BaseT::getScalarizationOverhead(LaneTy, LaneEltMask, Insert,
5197 /*Extract*/ false, CostKind);
5198 }
5199
5200 APInt AffectedLanes =
5201 APIntOps::ScaleBitMask(WidenedDemandedElts, NumLanesTotal);
5202 APInt FullyAffectedLegalVectors = APIntOps::ScaleBitMask(
5203 AffectedLanes, NumLegalVectors, /*MatchAllBits=*/true);
5204 for (int LegalVec = 0; LegalVec != NumLegalVectors; ++LegalVec) {
5205 for (unsigned Lane = 0; Lane != NumLegalLanes; ++Lane) {
5206 unsigned I = NumLegalLanes * LegalVec + Lane;
5207 // No need to insert unaffected lane; or lane 0 of each legal vector
5208 // iff ALL lanes of that vector were affected and will be inserted.
5209 if (!AffectedLanes[I] ||
5210 (Lane == 0 && FullyAffectedLegalVectors[LegalVec]))
5211 continue;
5213 CostKind, I * NumEltsPerLane, LaneTy);
5214 }
5215 }
5216 }
5217 } else if (LT.second.isVector()) {
5218 // Without fast insertion, we need to use MOVD/MOVQ to pass each demanded
5219 // integer element as a SCALAR_TO_VECTOR, then we build the vector as a
5220 // series of UNPCK followed by CONCAT_VECTORS - all of these can be
5221 // considered cheap.
5222 if (Ty->isIntOrIntVectorTy())
5223 Cost += DemandedElts.popcount();
5224
5225 // Get the smaller of the legalized or original pow2-extended number of
5226 // vector elements, which represents the number of unpacks we'll end up
5227 // performing.
5228 unsigned NumElts = LT.second.getVectorNumElements();
5229 unsigned Pow2Elts =
5230 PowerOf2Ceil(cast<FixedVectorType>(Ty)->getNumElements());
5231 Cost += (std::min<unsigned>(NumElts, Pow2Elts) - 1) * LT.first;
5232 }
5233 }
5234
5235 if (Extract) {
5236 // vXi1 can be efficiently extracted with MOVMSK.
5237 // TODO: AVX512 predicate mask handling.
5238 // NOTE: This doesn't work well for roundtrip scalarization.
5239 if (!Insert && Ty->getScalarSizeInBits() == 1 && !ST->hasAVX512()) {
5240 unsigned NumElts = cast<FixedVectorType>(Ty)->getNumElements();
5241 unsigned MaxElts = ST->hasAVX2() ? 32 : 16;
5242 unsigned MOVMSKCost = (NumElts + MaxElts - 1) / MaxElts;
5243 return MOVMSKCost;
5244 }
5245
5246 if (LT.second.isVector()) {
5247 unsigned NumLegalElts =
5248 LT.second.getVectorNumElements() * NumLegalVectors;
5249 assert(NumLegalElts >= DemandedElts.getBitWidth() &&
5250 "Vector has been legalized to smaller element count");
5251
5252 // If we're extracting elements from a 128-bit subvector lane,
5253 // we only need to extract each lane once, not for every element.
5254 if (LegalVectorBitWidth > LaneBitWidth) {
5255 unsigned NumLegalLanes = LegalVectorBitWidth / LaneBitWidth;
5256 unsigned NumLanesTotal = NumLegalLanes * NumLegalVectors;
5257 assert((NumLegalElts % NumLanesTotal) == 0 &&
5258 "Unexpected elts per lane");
5259 unsigned NumEltsPerLane = NumLegalElts / NumLanesTotal;
5260
5261 // Add cost for each demanded 128-bit subvector extraction.
5262 // Luckily this is a lot easier than for insertion.
5263 APInt WidenedDemandedElts = DemandedElts.zext(NumLegalElts);
5264 auto *LaneTy =
5265 FixedVectorType::get(Ty->getElementType(), NumEltsPerLane);
5266
5267 for (unsigned I = 0; I != NumLanesTotal; ++I) {
5268 APInt LaneEltMask = WidenedDemandedElts.extractBits(
5269 NumEltsPerLane, I * NumEltsPerLane);
5270 if (LaneEltMask.isZero())
5271 continue;
5273 I * NumEltsPerLane, LaneTy);
5275 LaneTy, LaneEltMask, /*Insert*/ false, Extract, CostKind);
5276 }
5277
5278 return Cost;
5279 }
5280 }
5281
5282 // Fallback to default extraction.
5283 Cost += BaseT::getScalarizationOverhead(Ty, DemandedElts, /*Insert*/ false,
5284 Extract, CostKind);
5285 }
5286
5287 return Cost;
5288}
5289
5291X86TTIImpl::getReplicationShuffleCost(Type *EltTy, int ReplicationFactor,
5292 int VF, const APInt &DemandedDstElts,
5294 const unsigned EltTyBits = DL.getTypeSizeInBits(EltTy);
5295 // We don't differentiate element types here, only element bit width.
5296 EltTy = IntegerType::getIntNTy(EltTy->getContext(), EltTyBits);
5297
5298 auto bailout = [&]() {
5299 return BaseT::getReplicationShuffleCost(EltTy, ReplicationFactor, VF,
5300 DemandedDstElts, CostKind);
5301 };
5302
5303 // For now, only deal with AVX512 cases.
5304 if (!ST->hasAVX512())
5305 return bailout();
5306
5307 // Do we have a native shuffle for this element type, or should we promote?
5308 unsigned PromEltTyBits = EltTyBits;
5309 switch (EltTyBits) {
5310 case 32:
5311 case 64:
5312 break; // AVX512F.
5313 case 16:
5314 if (!ST->hasBWI())
5315 PromEltTyBits = 32; // promote to i32, AVX512F.
5316 break; // AVX512BW
5317 case 8:
5318 if (!ST->hasVBMI())
5319 PromEltTyBits = 32; // promote to i32, AVX512F.
5320 break; // AVX512VBMI
5321 case 1:
5322 // There is no support for shuffling i1 elements. We *must* promote.
5323 if (ST->hasBWI()) {
5324 if (ST->hasVBMI())
5325 PromEltTyBits = 8; // promote to i8, AVX512VBMI.
5326 else
5327 PromEltTyBits = 16; // promote to i16, AVX512BW.
5328 break;
5329 }
5330 PromEltTyBits = 32; // promote to i32, AVX512F.
5331 break;
5332 default:
5333 return bailout();
5334 }
5335 auto *PromEltTy = IntegerType::getIntNTy(EltTy->getContext(), PromEltTyBits);
5336
5337 auto *SrcVecTy = FixedVectorType::get(EltTy, VF);
5338 auto *PromSrcVecTy = FixedVectorType::get(PromEltTy, VF);
5339
5340 int NumDstElements = VF * ReplicationFactor;
5341 auto *PromDstVecTy = FixedVectorType::get(PromEltTy, NumDstElements);
5342 auto *DstVecTy = FixedVectorType::get(EltTy, NumDstElements);
5343
5344 // Legalize the types.
5345 MVT LegalSrcVecTy = getTypeLegalizationCost(SrcVecTy).second;
5346 MVT LegalPromSrcVecTy = getTypeLegalizationCost(PromSrcVecTy).second;
5347 MVT LegalPromDstVecTy = getTypeLegalizationCost(PromDstVecTy).second;
5348 MVT LegalDstVecTy = getTypeLegalizationCost(DstVecTy).second;
5349 // They should have legalized into vector types.
5350 if (!LegalSrcVecTy.isVector() || !LegalPromSrcVecTy.isVector() ||
5351 !LegalPromDstVecTy.isVector() || !LegalDstVecTy.isVector())
5352 return bailout();
5353
5354 if (PromEltTyBits != EltTyBits) {
5355 // If we have to perform the shuffle with wider elt type than our data type,
5356 // then we will first need to anyext (we don't care about the new bits)
5357 // the source elements, and then truncate Dst elements.
5358 InstructionCost PromotionCost;
5359 PromotionCost += getCastInstrCost(
5360 Instruction::SExt, /*Dst=*/PromSrcVecTy, /*Src=*/SrcVecTy,
5362 PromotionCost +=
5363 getCastInstrCost(Instruction::Trunc, /*Dst=*/DstVecTy,
5364 /*Src=*/PromDstVecTy,
5366 return PromotionCost + getReplicationShuffleCost(PromEltTy,
5367 ReplicationFactor, VF,
5368 DemandedDstElts, CostKind);
5369 }
5370
5371 assert(LegalSrcVecTy.getScalarSizeInBits() == EltTyBits &&
5372 LegalSrcVecTy.getScalarType() == LegalDstVecTy.getScalarType() &&
5373 "We expect that the legalization doesn't affect the element width, "
5374 "doesn't coalesce/split elements.");
5375
5376 unsigned NumEltsPerDstVec = LegalDstVecTy.getVectorNumElements();
5377 unsigned NumDstVectors =
5378 divideCeil(DstVecTy->getNumElements(), NumEltsPerDstVec);
5379
5380 auto *SingleDstVecTy = FixedVectorType::get(EltTy, NumEltsPerDstVec);
5381
5382 // Not all the produced Dst elements may be demanded. In our case,
5383 // given that a single Dst vector is formed by a single shuffle,
5384 // if all elements that will form a single Dst vector aren't demanded,
5385 // then we won't need to do that shuffle, so adjust the cost accordingly.
5386 APInt DemandedDstVectors = APIntOps::ScaleBitMask(
5387 DemandedDstElts.zext(NumDstVectors * NumEltsPerDstVec), NumDstVectors);
5388 unsigned NumDstVectorsDemanded = DemandedDstVectors.popcount();
5389
5390 InstructionCost SingleShuffleCost =
5391 getShuffleCost(TTI::SK_PermuteSingleSrc, SingleDstVecTy, SingleDstVecTy,
5392 /*Mask=*/{}, CostKind,
5393 /*Index=*/0, /*SubTp=*/nullptr);
5394 return NumDstVectorsDemanded * SingleShuffleCost;
5395}
5396
5398 Align Alignment,
5399 unsigned AddressSpace,
5401 TTI::OperandValueInfo OpInfo,
5402 const Instruction *I) const {
5403 // FIXME: Load latency isn't handled here
5404 if (Opcode == Instruction::Load && CostKind == TTI::TCK_Latency)
5405 return BaseT::getMemoryOpCost(Opcode, Src, Alignment, AddressSpace,
5406 CostKind, OpInfo, I);
5407
5408 // TODO: Handle other cost kinds.
5410 if (auto *SI = dyn_cast_or_null<StoreInst>(I)) {
5411 // Store instruction with index and scale costs 2 Uops.
5412 // Check the preceding GEP to identify non-const indices.
5413 if (auto *GEP = dyn_cast<GetElementPtrInst>(SI->getPointerOperand())) {
5414 if (!all_of(GEP->indices(), [](Value *V) { return isa<Constant>(V); }))
5415 return TTI::TCC_Basic * 2;
5416 }
5417 }
5418 return TTI::TCC_Basic;
5419 }
5420
5421 assert((Opcode == Instruction::Load || Opcode == Instruction::Store) &&
5422 "Invalid Opcode");
5423 // Type legalization can't handle structs
5424 if (TLI->getValueType(DL, Src, true) == MVT::Other)
5425 return BaseT::getMemoryOpCost(Opcode, Src, Alignment, AddressSpace,
5426 CostKind, OpInfo, I);
5427
5428 // Legalize the type.
5429 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Src);
5430
5431 auto *VTy = dyn_cast<FixedVectorType>(Src);
5432
5434
5435 // Add a cost for constant load to vector.
5436 if (Opcode == Instruction::Store && OpInfo.isConstant())
5437 Cost += getMemoryOpCost(Instruction::Load, Src, DL.getABITypeAlign(Src),
5438 /*AddressSpace=*/0, CostKind, OpInfo);
5439
5440 // Handle the simple case of non-vectors.
5441 // NOTE: this assumes that legalization never creates vector from scalars!
5442 if (!VTy || !LT.second.isVector()) {
5443 // Each load/store unit costs 1.
5444 return (LT.second.isFloatingPoint() ? Cost : 0) + LT.first * 1;
5445 }
5446
5447 bool IsLoad = Opcode == Instruction::Load;
5448
5449 Type *EltTy = VTy->getElementType();
5450
5451 const int EltTyBits = DL.getTypeSizeInBits(EltTy);
5452
5453 // Source of truth: how many elements were there in the original IR vector?
5454 const unsigned SrcNumElt = VTy->getNumElements();
5455
5456 // How far have we gotten?
5457 int NumEltRemaining = SrcNumElt;
5458 // Note that we intentionally capture by-reference, NumEltRemaining changes.
5459 auto NumEltDone = [&]() { return SrcNumElt - NumEltRemaining; };
5460
5461 const int MaxLegalOpSizeBytes = divideCeil(LT.second.getSizeInBits(), 8);
5462
5463 // Note that even if we can store 64 bits of an XMM, we still operate on XMM.
5464 const unsigned XMMBits = 128;
5465 if (XMMBits % EltTyBits != 0)
5466 // Vector size must be a multiple of the element size. I.e. no padding.
5467 return BaseT::getMemoryOpCost(Opcode, Src, Alignment, AddressSpace,
5468 CostKind, OpInfo, I);
5469 const int NumEltPerXMM = XMMBits / EltTyBits;
5470
5471 auto *XMMVecTy = FixedVectorType::get(EltTy, NumEltPerXMM);
5472
5473 for (int CurrOpSizeBytes = MaxLegalOpSizeBytes, SubVecEltsLeft = 0;
5474 NumEltRemaining > 0; CurrOpSizeBytes /= 2) {
5475 // How many elements would a single op deal with at once?
5476 if ((8 * CurrOpSizeBytes) % EltTyBits != 0)
5477 // Vector size must be a multiple of the element size. I.e. no padding.
5478 return BaseT::getMemoryOpCost(Opcode, Src, Alignment, AddressSpace,
5479 CostKind, OpInfo, I);
5480 int CurrNumEltPerOp = (8 * CurrOpSizeBytes) / EltTyBits;
5481
5482 assert(CurrOpSizeBytes > 0 && CurrNumEltPerOp > 0 && "How'd we get here?");
5483 assert((((NumEltRemaining * EltTyBits) < (2 * 8 * CurrOpSizeBytes)) ||
5484 (CurrOpSizeBytes == MaxLegalOpSizeBytes)) &&
5485 "Unless we haven't halved the op size yet, "
5486 "we have less than two op's sized units of work left.");
5487
5488 auto *CurrVecTy = CurrNumEltPerOp > NumEltPerXMM
5489 ? FixedVectorType::get(EltTy, CurrNumEltPerOp)
5490 : XMMVecTy;
5491
5492 assert(CurrVecTy->getNumElements() % CurrNumEltPerOp == 0 &&
5493 "After halving sizes, the vector elt count is no longer a multiple "
5494 "of number of elements per operation?");
5495 auto *CoalescedVecTy =
5496 CurrNumEltPerOp == 1
5497 ? CurrVecTy
5499 IntegerType::get(Src->getContext(),
5500 EltTyBits * CurrNumEltPerOp),
5501 CurrVecTy->getNumElements() / CurrNumEltPerOp);
5502 assert(DL.getTypeSizeInBits(CoalescedVecTy) ==
5503 DL.getTypeSizeInBits(CurrVecTy) &&
5504 "coalesciing elements doesn't change vector width.");
5505
5506 while (NumEltRemaining > 0) {
5507 assert(SubVecEltsLeft >= 0 && "Subreg element count overconsumtion?");
5508
5509 // Can we use this vector size, as per the remaining element count?
5510 // Iff the vector is naturally aligned, we can do a wide load regardless.
5511 if (NumEltRemaining < CurrNumEltPerOp &&
5512 (!IsLoad || Alignment < CurrOpSizeBytes) && CurrOpSizeBytes != 1)
5513 break; // Try smalled vector size.
5514
5515 // This isn't exactly right. We're using slow unaligned 32-byte accesses
5516 // as a proxy for a double-pumped AVX memory interface such as on
5517 // Sandybridge.
5518 // Sub-32-bit loads/stores will be slower either with PINSR*/PEXTR* or
5519 // will be scalarized.
5520 if (CurrOpSizeBytes == 32 && ST->isUnalignedMem32Slow())
5521 Cost += 2;
5522 else if (CurrOpSizeBytes < 4)
5523 Cost += 2;
5524 else
5525 Cost += 1;
5526
5527 // If we're loading a uniform value, then we don't need to split the load,
5528 // loading just a single (widest) vector can be reused by all splits.
5529 if (IsLoad && OpInfo.isUniform())
5530 return Cost;
5531
5532 bool Is0thSubVec = (NumEltDone() % LT.second.getVectorNumElements()) == 0;
5533
5534 // If we have fully processed the previous reg, we need to replenish it.
5535 if (SubVecEltsLeft == 0) {
5536 SubVecEltsLeft += CurrVecTy->getNumElements();
5537 // And that's free only for the 0'th subvector of a legalized vector.
5538 if (!Is0thSubVec)
5539 Cost +=
5542 VTy, VTy, {}, CostKind, NumEltDone(), CurrVecTy);
5543 }
5544
5545 // While we can directly load/store ZMM, YMM, and 64-bit halves of XMM,
5546 // for smaller widths (32/16/8) we have to insert/extract them separately.
5547 // Again, it's free for the 0'th subreg (if op is 32/64 bit wide,
5548 // but let's pretend that it is also true for 16/8 bit wide ops...)
5549 if (CurrOpSizeBytes <= 32 / 8 && !Is0thSubVec) {
5550 int NumEltDoneInCurrXMM = NumEltDone() % NumEltPerXMM;
5551 assert(NumEltDoneInCurrXMM % CurrNumEltPerOp == 0 && "");
5552 int CoalescedVecEltIdx = NumEltDoneInCurrXMM / CurrNumEltPerOp;
5553 APInt DemandedElts =
5554 APInt::getBitsSet(CoalescedVecTy->getNumElements(),
5555 CoalescedVecEltIdx, CoalescedVecEltIdx + 1);
5556 assert(DemandedElts.popcount() == 1 && "Inserting single value");
5557 Cost += getScalarizationOverhead(CoalescedVecTy, DemandedElts, IsLoad,
5558 !IsLoad, CostKind);
5559 }
5560
5561 SubVecEltsLeft -= CurrNumEltPerOp;
5562 NumEltRemaining -= CurrNumEltPerOp;
5563 Alignment = commonAlignment(Alignment, CurrOpSizeBytes);
5564 }
5565 }
5566
5567 assert(NumEltRemaining <= 0 && "Should have processed all the elements.");
5568
5569 return Cost;
5570}
5571
5575 switch (MICA.getID()) {
5576 case Intrinsic::masked_scatter:
5577 case Intrinsic::masked_gather:
5578 return getGatherScatterOpCost(MICA, CostKind);
5579 case Intrinsic::masked_load:
5580 case Intrinsic::masked_store:
5581 return getMaskedMemoryOpCost(MICA, CostKind);
5582 }
5584}
5585
5589 unsigned Opcode = MICA.getID() == Intrinsic::masked_load ? Instruction::Load
5590 : Instruction::Store;
5591 Type *SrcTy = MICA.getDataType();
5592 Align Alignment = MICA.getAlignment();
5593 unsigned AddressSpace = MICA.getAddressSpace();
5594
5595 bool IsLoad = (Instruction::Load == Opcode);
5596 bool IsStore = (Instruction::Store == Opcode);
5597
5598 auto *SrcVTy = dyn_cast<FixedVectorType>(SrcTy);
5599 if (!SrcVTy)
5600 // To calculate scalar take the regular cost, without mask
5601 return getMemoryOpCost(Opcode, SrcTy, Alignment, AddressSpace, CostKind);
5602
5603 unsigned NumElem = SrcVTy->getNumElements();
5604 auto *MaskTy =
5605 FixedVectorType::get(Type::getInt8Ty(SrcVTy->getContext()), NumElem);
5606 if ((IsLoad && !isLegalMaskedLoad(SrcVTy, Alignment, AddressSpace)) ||
5607 (IsStore && !isLegalMaskedStore(SrcVTy, Alignment, AddressSpace))) {
5608 // Scalarization
5609 APInt DemandedElts = APInt::getAllOnes(NumElem);
5611 MaskTy, DemandedElts, /*Insert*/ false, /*Extract*/ true, CostKind);
5612 InstructionCost ScalarCompareCost = getCmpSelInstrCost(
5613 Instruction::ICmp, Type::getInt8Ty(SrcVTy->getContext()), nullptr,
5615 InstructionCost BranchCost = getCFInstrCost(Instruction::CondBr, CostKind);
5616 InstructionCost MaskCmpCost = NumElem * (BranchCost + ScalarCompareCost);
5618 SrcVTy, DemandedElts, IsLoad, IsStore, CostKind);
5619 InstructionCost MemopCost =
5620 NumElem * BaseT::getMemoryOpCost(Opcode, SrcVTy->getScalarType(),
5621 Alignment, AddressSpace, CostKind);
5622 return MemopCost + ValueSplitCost + MaskSplitCost + MaskCmpCost;
5623 }
5624
5625 // Legalize the type.
5626 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(SrcVTy);
5627 auto VT = TLI->getValueType(DL, SrcVTy);
5629 MVT Ty = LT.second;
5630 if (Ty == MVT::i16 || Ty == MVT::i32 || Ty == MVT::i64)
5631 // APX masked load/store for scalar is cheap.
5632 return Cost + LT.first;
5633
5634 if (VT.isSimple() && Ty != VT.getSimpleVT() &&
5635 LT.second.getVectorNumElements() == NumElem)
5636 // Promotion requires extend/truncate for data and a shuffle for mask.
5637 Cost += getShuffleCost(TTI::SK_PermuteTwoSrc, SrcVTy, SrcVTy, {}, CostKind,
5638 0, nullptr) +
5639 getShuffleCost(TTI::SK_PermuteTwoSrc, MaskTy, MaskTy, {}, CostKind,
5640 0, nullptr);
5641
5642 else if (LT.first * Ty.getVectorNumElements() > NumElem) {
5643 auto *NewMaskTy = FixedVectorType::get(MaskTy->getElementType(),
5644 (unsigned)LT.first.getValue() *
5645 Ty.getVectorNumElements());
5646 // Expanding requires fill mask with zeroes
5647 Cost += getShuffleCost(TTI::SK_InsertSubvector, NewMaskTy, NewMaskTy, {},
5648 CostKind, 0, MaskTy);
5649 }
5650
5651 // Pre-AVX512 - each maskmov load costs 2 + store costs ~8.
5652 if (!ST->hasAVX512())
5653 return Cost + LT.first * (IsLoad ? 2 : 8);
5654
5655 // AVX-512 masked load/store is cheaper
5656 return Cost + LT.first;
5657}
5658
5660 ArrayRef<const Value *> Ptrs, const Value *Base,
5661 const TTI::PointersChainInfo &Info, Type *AccessTy,
5663 if (Info.isSameBase() && Info.isKnownStride()) {
5664 // If all the pointers have known stride all the differences are translated
5665 // into constants. X86 memory addressing allows encoding it into
5666 // displacement. So we just need to take the base GEP cost.
5667 if (const auto *BaseGEP = dyn_cast<GetElementPtrInst>(Base)) {
5668 SmallVector<const Value *> Indices(BaseGEP->indices());
5669 return getGEPCost(BaseGEP->getSourceElementType(),
5670 BaseGEP->getPointerOperand(), Indices, nullptr,
5671 CostKind);
5672 }
5673 return TTI::TCC_Free;
5674 }
5675 return BaseT::getPointersChainCost(Ptrs, Base, Info, AccessTy, CostKind);
5676}
5677
5680 const SCEV *Ptr,
5682 // Address computations in vectorized code with non-consecutive addresses will
5683 // likely result in more instructions compared to scalar code where the
5684 // computation can more often be merged into the index mode. The resulting
5685 // extra micro-ops can significantly decrease throughput.
5686 const unsigned NumVectorInstToHideOverhead = 10;
5687
5688 // Cost modeling of Strided Access Computation is hidden by the indexing
5689 // modes of X86 regardless of the stride value. We dont believe that there
5690 // is a difference between constant strided access in gerenal and constant
5691 // strided value which is less than or equal to 64.
5692 // Even in the case of (loop invariant) stride whose value is not known at
5693 // compile time, the address computation will not incur more than one extra
5694 // ADD instruction.
5695 if (PtrTy->isVectorTy() && SE && !ST->hasAVX2()) {
5696 // TODO: AVX2 is the current cut-off because we don't have correct
5697 // interleaving costs for prior ISA's.
5698 if (!BaseT::isStridedAccess(Ptr))
5699 return NumVectorInstToHideOverhead;
5700 if (!BaseT::getConstantStrideStep(SE, Ptr))
5701 return 1;
5702 }
5703
5704 return BaseT::getAddressComputationCost(PtrTy, SE, Ptr, CostKind);
5705}
5706
5709 std::optional<FastMathFlags> FMF,
5712 return BaseT::getArithmeticReductionCost(Opcode, ValTy, FMF, CostKind);
5713
5714 // We use llvm-mca across all supported CPUs to measure the logic cost stats.
5715 // We use the Intel Architecture Code Analyzer(IACA) to measure the throughput
5716 // and make it as the cost. TODO: Update old IACA numbers to llvm-mca.
5717
5718 static const CostKindTblEntry SLMCostTbl[] = {
5719 { ISD::FADD, MVT::v2f64, {3, 3, 3, 3} },
5720 { ISD::ADD, MVT::v2i64, {5, 5, 5, 5} },
5721 };
5722
5723 static const CostKindTblEntry SSE2CostTbl[] = {
5724 { ISD::FADD, MVT::v2f64, {2, 2, 2, 2} },
5725 { ISD::FADD, MVT::v2f32, {2, 2, 2, 2} },
5726 { ISD::FADD, MVT::v4f32, {4, 4, 4, 4} },
5727 { ISD::ADD, MVT::v2i64, {2, 2, 2, 2} }, // The data reported by the IACA tool is "1.6".
5728 { ISD::ADD, MVT::v2i32, {2, 2, 2, 2} }, // FIXME: chosen to be less than v4i32
5729 { ISD::ADD, MVT::v4i32, {3, 3, 3, 3} }, // The data reported by the IACA tool is "3.3".
5730 { ISD::ADD, MVT::v2i16, {2, 2, 2, 2} }, // The data reported by the IACA tool is "4.3".
5731 { ISD::ADD, MVT::v4i16, {3, 3, 3, 3} }, // The data reported by the IACA tool is "4.3".
5732 { ISD::ADD, MVT::v8i16, {4, 4, 4, 4} }, // The data reported by the IACA tool is "4.3".
5733 { ISD::ADD, MVT::v2i8, {2, 2, 2, 2} },
5734 { ISD::ADD, MVT::v4i8, {2, 2, 2, 2} },
5735 { ISD::ADD, MVT::v8i8, {2, 2, 2, 2} },
5736 { ISD::ADD, MVT::v16i8, {3, 3, 3, 3} },
5737
5738 { ISD::AND, MVT::v2i64, {2, 2, 3, 3} },
5739 { ISD::AND, MVT::v4i32, {3, 4, 5, 5} },
5740 { ISD::AND, MVT::v8i16, {4, 7, 8, 8} },
5741 { ISD::AND, MVT::v16i8, {6,10,11,11} },
5742 { ISD::OR, MVT::v2i64, {2, 2, 3, 3} },
5743 { ISD::OR, MVT::v4i32, {3, 4, 5, 5} },
5744 { ISD::OR, MVT::v8i16, {4, 7, 8, 8} },
5745 { ISD::OR, MVT::v16i8, {6,10,11,11} },
5746 { ISD::XOR, MVT::v2i64, {2, 2, 3, 3} },
5747 { ISD::XOR, MVT::v4i32, {3, 4, 5, 5} },
5748 { ISD::XOR, MVT::v8i16, {4, 7, 8, 8} },
5749 { ISD::XOR, MVT::v16i8, {6,10,11,11} },
5750 };
5751
5752 static const CostKindTblEntry AVX1CostTbl[] = {
5753 { ISD::FADD, MVT::v4f64, {3, 3, 3, 3} },
5754 { ISD::FADD, MVT::v4f32, {3, 3, 3, 3} },
5755 { ISD::FADD, MVT::v8f32, {4, 4, 4, 4} },
5756 { ISD::ADD, MVT::v2i64, {1, 1, 1, 1} }, // The data reported by the IACA tool is "1.5".
5757 { ISD::ADD, MVT::v4i64, {3, 3, 3, 3} },
5758 { ISD::ADD, MVT::v8i32, {5, 5, 5, 5} },
5759 { ISD::ADD, MVT::v16i16, {5, 5, 5, 5} },
5760 { ISD::ADD, MVT::v32i8, {4, 4, 4, 4} },
5761
5762 { ISD::AND, MVT::v4i64, {3, 7, 5, 5} },
5763 { ISD::AND, MVT::v8i32, {4, 9, 7, 7} },
5764 { ISD::AND, MVT::v16i16, {5,11, 9, 9} },
5765 { ISD::AND, MVT::v8i16, {4, 7, 7, 7} },
5766 { ISD::AND, MVT::v32i8, {6,13,11,11} },
5767 { ISD::AND, MVT::v16i8, {5,10, 9, 9} },
5768 { ISD::OR, MVT::v4i64, {3, 7, 5, 5} },
5769 { ISD::OR, MVT::v8i32, {4, 9, 7, 7} },
5770 { ISD::OR, MVT::v16i16, {5,11, 9, 9} },
5771 { ISD::OR, MVT::v8i16, {4, 7, 7, 7} },
5772 { ISD::OR, MVT::v32i8, {6,13,11,11} },
5773 { ISD::OR, MVT::v16i8, {5,10, 9, 9} },
5774 { ISD::XOR, MVT::v4i64, {3, 7, 5, 5} },
5775 { ISD::XOR, MVT::v8i32, {4, 9, 7, 7} },
5776 { ISD::XOR, MVT::v16i16, {5,11, 9, 9} },
5777 { ISD::XOR, MVT::v8i16, {4, 7, 7, 7} },
5778 { ISD::XOR, MVT::v32i8, {6,13,11,11} },
5779 { ISD::XOR, MVT::v16i8, {5,10, 9, 9} },
5780 };
5781
5782 static const CostKindTblEntry AVX2CostTbl[] = {
5783 { ISD::AND, MVT::v4i64, {2, 7, 5, 5} },
5784 { ISD::AND, MVT::v2i64, {1, 2, 3, 3} },
5785 { ISD::AND, MVT::v8i32, {3, 9, 7, 7} },
5786 { ISD::AND, MVT::v4i32, {2, 4, 5, 5} },
5787 { ISD::AND, MVT::v16i16, {3,11, 9, 9} },
5788 { ISD::AND, MVT::v8i16, {2, 6, 7, 7} },
5789 { ISD::AND, MVT::v32i8, {3,13,11,11} },
5790 { ISD::AND, MVT::v16i8, {3, 8, 9, 9} },
5791 { ISD::OR, MVT::v4i64, {2, 7, 5, 5} },
5792 { ISD::OR, MVT::v2i64, {1, 2, 3, 3} },
5793 { ISD::OR, MVT::v8i32, {3, 9, 7, 7} },
5794 { ISD::OR, MVT::v4i32, {2, 4, 5, 5} },
5795 { ISD::OR, MVT::v16i16, {3,11, 9, 9} },
5796 { ISD::OR, MVT::v8i16, {2, 6, 7, 7} },
5797 { ISD::OR, MVT::v32i8, {3,13,11,11} },
5798 { ISD::OR, MVT::v16i8, {3, 8, 9, 9} },
5799 { ISD::XOR, MVT::v4i64, {2, 7, 5, 5} },
5800 { ISD::XOR, MVT::v2i64, {1, 2, 3, 3} },
5801 { ISD::XOR, MVT::v8i32, {3, 9, 7, 7} },
5802 { ISD::XOR, MVT::v4i32, {2, 4, 5, 5} },
5803 { ISD::XOR, MVT::v16i16, {3,11, 9, 9} },
5804 { ISD::XOR, MVT::v8i16, {2, 6, 7, 7} },
5805 { ISD::XOR, MVT::v32i8, {3,13,11,11} },
5806 { ISD::XOR, MVT::v16i8, {3, 8, 9, 9} },
5807 };
5808
5809 static const CostKindTblEntry AVX512FCostTbl[] = {
5810 { ISD::FADD, MVT::v8f64, {4, 4, 4, 4} },
5811 { ISD::FADD, MVT::v16f32, {5, 5, 5, 5} },
5812 { ISD::ADD, MVT::v8i64, {4, 4, 4, 4} },
5813 { ISD::ADD, MVT::v16i32, {6, 6, 6, 6} },
5814
5815 { ISD::AND, MVT::v8i64, {3,10, 7, 7} },
5816 { ISD::AND, MVT::v16i32, {4,12, 9, 9} },
5817 { ISD::AND, MVT::v32i16, {4,14,11,11} },
5818 { ISD::AND, MVT::v64i8, {4,16,13,13} },
5819 { ISD::AND, MVT::v16i8, {2, 8, 9, 9} },
5820 { ISD::OR, MVT::v8i64, {3,10, 7, 7} },
5821 { ISD::OR, MVT::v16i32, {4,12, 9, 9} },
5822 { ISD::OR, MVT::v32i16, {4,14,11,11} },
5823 { ISD::OR, MVT::v64i8, {4,16,13,13} },
5824 { ISD::OR, MVT::v16i8, {2, 8, 9, 9} },
5825 { ISD::XOR, MVT::v8i64, {3,10, 7, 7} },
5826 { ISD::XOR, MVT::v16i32, {4,12, 9, 9} },
5827 { ISD::XOR, MVT::v32i16, {4,14,11,11} },
5828 { ISD::XOR, MVT::v64i8, {4,16,13,13} },
5829 { ISD::XOR, MVT::v16i8, {2, 8, 9, 9} },
5830 };
5831
5832 static const CostKindTblEntry AVX512BWCostTbl[] = {
5833 { ISD::ADD, MVT::v32i16, {7, 7, 7, 7} },
5834 { ISD::ADD, MVT::v64i8, {4, 4, 4, 4} },
5835 };
5836
5837 int ISD = TLI->InstructionOpcodeToISD(Opcode);
5838 assert(ISD && "Invalid opcode");
5839
5840 // Before legalizing the type, give a chance to look up illegal narrow types
5841 // in the table.
5842 // FIXME: Is there a better way to do this?
5843 EVT VT = TLI->getValueType(DL, ValTy);
5844 if (VT.isSimple()) {
5845 MVT MTy = VT.getSimpleVT();
5846 if (ST->useSLMArithCosts())
5847 if (const auto *Entry = CostTableLookup(SLMCostTbl, ISD, MTy))
5848 if (auto KindCost = Entry->Cost[CostKind])
5849 return *KindCost;
5850
5851 if (ST->hasBWI())
5852 if (const auto *Entry = CostTableLookup(AVX512BWCostTbl, ISD, MTy))
5853 if (auto KindCost = Entry->Cost[CostKind])
5854 return *KindCost;
5855
5856 if (ST->hasAVX512())
5857 if (const auto *Entry = CostTableLookup(AVX512FCostTbl, ISD, MTy))
5858 if (auto KindCost = Entry->Cost[CostKind])
5859 return *KindCost;
5860
5861 if (ST->hasAVX2())
5862 if (const auto *Entry = CostTableLookup(AVX2CostTbl, ISD, MTy))
5863 if (auto KindCost = Entry->Cost[CostKind])
5864 return *KindCost;
5865
5866 if (ST->hasAVX())
5867 if (const auto *Entry = CostTableLookup(AVX1CostTbl, ISD, MTy))
5868 if (auto KindCost = Entry->Cost[CostKind])
5869 return *KindCost;
5870
5871 if (ST->hasSSE2())
5872 if (const auto *Entry = CostTableLookup(SSE2CostTbl, ISD, MTy))
5873 if (auto KindCost = Entry->Cost[CostKind])
5874 return *KindCost;
5875 }
5876
5877 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(ValTy);
5878
5879 MVT MTy = LT.second;
5880
5881 auto *ValVTy = cast<FixedVectorType>(ValTy);
5882
5883 InstructionCost ArithmeticCost = 0;
5884 if (LT.first != 1 && MTy.isVector() &&
5885 MTy.getVectorNumElements() < ValVTy->getNumElements()) {
5886 // Type needs to be split. We need LT.first - 1 arithmetic ops.
5887 auto *SingleOpTy = FixedVectorType::get(ValVTy->getElementType(),
5888 MTy.getVectorNumElements());
5889 ArithmeticCost = getArithmeticInstrCost(Opcode, SingleOpTy, CostKind);
5890 ArithmeticCost *= LT.first - 1;
5891 }
5892
5893 // FIXME: These assume a naive kshift+binop lowering, which is probably
5894 // conservative in most cases.
5895 static const CostKindTblEntry AVX512BoolReduction[] = {
5896 { ISD::AND, MVT::v2i1, { 3, 3, 3, 3} },
5897 { ISD::AND, MVT::v4i1, { 5, 5, 5, 5} },
5898 { ISD::AND, MVT::v8i1, { 7, 7, 7, 7} },
5899 { ISD::AND, MVT::v16i1, { 9, 9, 9, 9} },
5900 { ISD::AND, MVT::v32i1, {11,11,11,11} },
5901 { ISD::AND, MVT::v64i1, {13,13,13,13} },
5902 { ISD::OR, MVT::v2i1, { 3, 3, 3, 3} },
5903 { ISD::OR, MVT::v4i1, { 5, 5, 5, 5} },
5904 { ISD::OR, MVT::v8i1, { 7, 7, 7, 7} },
5905 { ISD::OR, MVT::v16i1, { 9, 9, 9, 9} },
5906 { ISD::OR, MVT::v32i1, {11,11,11,11} },
5907 { ISD::OR, MVT::v64i1, {13,13,13,13} },
5908 };
5909
5910 static const CostKindTblEntry AVX2BoolReduction[] = {
5911 { ISD::AND, MVT::v16i16, { 2, 2, 2, 2} }, // vpmovmskb + cmp
5912 { ISD::AND, MVT::v32i8, { 2, 2, 2, 2} }, // vpmovmskb + cmp
5913 { ISD::OR, MVT::v16i16, { 2, 2, 2, 2} }, // vpmovmskb + cmp
5914 { ISD::OR, MVT::v32i8, { 2, 2, 2, 2} }, // vpmovmskb + cmp
5915 };
5916
5917 static const CostKindTblEntry AVX1BoolReduction[] = {
5918 { ISD::AND, MVT::v4i64, {2, 2, 2, 2} }, // vmovmskpd + cmp
5919 { ISD::AND, MVT::v8i32, {2, 2, 2, 2} }, // vmovmskps + cmp
5920 { ISD::AND, MVT::v16i16, {4, 4, 4, 4} }, // vextractf128 + vpand + vpmovmskb + cmp
5921 { ISD::AND, MVT::v32i8, {4, 4, 4, 4} }, // vextractf128 + vpand + vpmovmskb + cmp
5922 { ISD::OR, MVT::v4i64, {2, 2, 2, 2} }, // vmovmskpd + cmp
5923 { ISD::OR, MVT::v8i32, {2, 2, 2, 2} }, // vmovmskps + cmp
5924 { ISD::OR, MVT::v16i16, {4, 4, 4, 4} }, // vextractf128 + vpor + vpmovmskb + cmp
5925 { ISD::OR, MVT::v32i8, {4, 4, 4, 4} }, // vextractf128 + vpor + vpmovmskb + cmp
5926 };
5927
5928 static const CostKindTblEntry SSE2BoolReduction[] = {
5929 { ISD::AND, MVT::v2i64, {2, 2, 2, 2} }, // movmskpd + cmp
5930 { ISD::AND, MVT::v4i32, {2, 2, 2, 2} }, // movmskps + cmp
5931 { ISD::AND, MVT::v8i16, {2, 2, 2, 2} }, // pmovmskb + cmp
5932 { ISD::AND, MVT::v16i8, {2, 2, 2, 2} }, // pmovmskb + cmp
5933 { ISD::OR, MVT::v2i64, {2, 2, 2, 2} }, // movmskpd + cmp
5934 { ISD::OR, MVT::v4i32, {2, 2, 2, 2} }, // movmskps + cmp
5935 { ISD::OR, MVT::v8i16, {2, 2, 2, 2} }, // pmovmskb + cmp
5936 { ISD::OR, MVT::v16i8, {2, 2, 2, 2} }, // pmovmskb + cmp
5937 };
5938
5939 // Handle bool allof/anyof vXi1 patterns before we check legal types.
5940 if (ValVTy->getElementType()->isIntegerTy(1)) {
5941 if (ISD == ISD::ADD) {
5942 // vXi1 addition reduction will bitcast to scalar and perform a popcount.
5943 auto *IntTy = IntegerType::getIntNTy(ValVTy->getContext(),
5944 ValVTy->getNumElements());
5945 IntrinsicCostAttributes ICA(Intrinsic::ctpop, IntTy, {IntTy});
5946 return getCastInstrCost(Instruction::BitCast, IntTy, ValVTy,
5948 CostKind) +
5950 }
5951
5952 if (ST->hasAVX512())
5953 if (const auto *Entry = CostTableLookup(AVX512BoolReduction, ISD, MTy))
5954 if (auto KindCost = Entry->Cost[CostKind])
5955 return ArithmeticCost + *KindCost;
5956 if (ST->hasAVX2())
5957 if (const auto *Entry = CostTableLookup(AVX2BoolReduction, ISD, MTy))
5958 if (auto KindCost = Entry->Cost[CostKind])
5959 return ArithmeticCost + *KindCost;
5960 if (ST->hasAVX())
5961 if (const auto *Entry = CostTableLookup(AVX1BoolReduction, ISD, MTy))
5962 if (auto KindCost = Entry->Cost[CostKind])
5963 return ArithmeticCost + *KindCost;
5964 if (ST->hasSSE2())
5965 if (const auto *Entry = CostTableLookup(SSE2BoolReduction, ISD, MTy))
5966 if (auto KindCost = Entry->Cost[CostKind])
5967 return ArithmeticCost + *KindCost;
5968
5969 return BaseT::getArithmeticReductionCost(Opcode, ValVTy, FMF, CostKind);
5970 }
5971
5972 // Special case: vXi8 mul reductions are performed as vXi16.
5973 if (ISD == ISD::MUL && MTy.getScalarType() == MVT::i8) {
5974 auto *WideSclTy = IntegerType::get(ValVTy->getContext(), 16);
5975 auto *WideVecTy = FixedVectorType::get(WideSclTy, ValVTy->getNumElements());
5976 return getCastInstrCost(Instruction::ZExt, WideVecTy, ValTy,
5978 CostKind) +
5979 getArithmeticReductionCost(Opcode, WideVecTy, FMF, CostKind);
5980 }
5981
5982 if (ST->useSLMArithCosts())
5983 if (const auto *Entry = CostTableLookup(SLMCostTbl, ISD, MTy))
5984 if (auto KindCost = Entry->Cost[CostKind])
5985 return ArithmeticCost + *KindCost;
5986
5987 if (ST->hasBWI())
5988 if (const auto *Entry = CostTableLookup(AVX512BWCostTbl, ISD, MTy))
5989 if (auto KindCost = Entry->Cost[CostKind])
5990 return ArithmeticCost + *KindCost;
5991
5992 if (ST->hasAVX512())
5993 if (const auto *Entry = CostTableLookup(AVX512FCostTbl, ISD, MTy))
5994 if (auto KindCost = Entry->Cost[CostKind])
5995 return ArithmeticCost + *KindCost;
5996
5997 if (ST->hasAVX2())
5998 if (const auto *Entry = CostTableLookup(AVX2CostTbl, ISD, MTy))
5999 if (auto KindCost = Entry->Cost[CostKind])
6000 return ArithmeticCost + *KindCost;
6001
6002 if (ST->hasAVX())
6003 if (const auto *Entry = CostTableLookup(AVX1CostTbl, ISD, MTy))
6004 if (auto KindCost = Entry->Cost[CostKind])
6005 return ArithmeticCost + *KindCost;
6006
6007 if (ST->hasSSE2())
6008 if (const auto *Entry = CostTableLookup(SSE2CostTbl, ISD, MTy))
6009 if (auto KindCost = Entry->Cost[CostKind])
6010 return ArithmeticCost + *KindCost;
6011
6012 unsigned NumVecElts = ValVTy->getNumElements();
6013 unsigned ScalarSize = ValVTy->getScalarSizeInBits();
6014
6015 // Special case power of 2 reductions where the scalar type isn't changed
6016 // by type legalization.
6017 if (!isPowerOf2_32(NumVecElts) || ScalarSize != MTy.getScalarSizeInBits())
6018 return BaseT::getArithmeticReductionCost(Opcode, ValVTy, FMF, CostKind);
6019
6020 InstructionCost ReductionCost = 0;
6021
6022 auto *Ty = ValVTy;
6023 if (LT.first != 1 && MTy.isVector() &&
6024 MTy.getVectorNumElements() < ValVTy->getNumElements()) {
6025 // Type needs to be split. We need LT.first - 1 arithmetic ops.
6026 Ty = FixedVectorType::get(ValVTy->getElementType(),
6027 MTy.getVectorNumElements());
6028 ReductionCost = getArithmeticInstrCost(Opcode, Ty, CostKind);
6029 ReductionCost *= LT.first - 1;
6030 NumVecElts = MTy.getVectorNumElements();
6031 }
6032
6033 // Now handle reduction with the legal type, taking into account size changes
6034 // at each level.
6035 while (NumVecElts > 1) {
6036 // Determine the size of the remaining vector we need to reduce.
6037 unsigned Size = NumVecElts * ScalarSize;
6038 NumVecElts /= 2;
6039 // If we're reducing from 256/512 bits, use an extract_subvector.
6040 if (Size > 128) {
6041 auto *SubTy = FixedVectorType::get(ValVTy->getElementType(), NumVecElts);
6042 ReductionCost += getShuffleCost(TTI::SK_ExtractSubvector, Ty, Ty, {},
6043 CostKind, NumVecElts, SubTy);
6044 Ty = SubTy;
6045 } else if (Size == 128) {
6046 // Reducing from 128 bits is a permute of v2f64/v2i64.
6047 FixedVectorType *ShufTy;
6048 if (ValVTy->isFloatingPointTy())
6049 ShufTy =
6050 FixedVectorType::get(Type::getDoubleTy(ValVTy->getContext()), 2);
6051 else
6052 ShufTy =
6053 FixedVectorType::get(Type::getInt64Ty(ValVTy->getContext()), 2);
6054 ReductionCost += getShuffleCost(TTI::SK_PermuteSingleSrc, ShufTy, ShufTy,
6055 {}, CostKind, 0, nullptr);
6056 } else if (Size == 64) {
6057 // Reducing from 64 bits is a shuffle of v4f32/v4i32.
6058 FixedVectorType *ShufTy;
6059 if (ValVTy->isFloatingPointTy())
6060 ShufTy =
6061 FixedVectorType::get(Type::getFloatTy(ValVTy->getContext()), 4);
6062 else
6063 ShufTy =
6064 FixedVectorType::get(Type::getInt32Ty(ValVTy->getContext()), 4);
6065 ReductionCost += getShuffleCost(TTI::SK_PermuteSingleSrc, ShufTy, ShufTy,
6066 {}, CostKind, 0, nullptr);
6067 } else {
6068 // Reducing from smaller size is a shift by immediate.
6069 auto *ShiftTy = FixedVectorType::get(
6070 Type::getIntNTy(ValVTy->getContext(), Size), 128 / Size);
6071 ReductionCost += getArithmeticInstrCost(
6072 Instruction::LShr, ShiftTy, CostKind,
6075 }
6076
6077 // Add the arithmetic op for this level.
6078 ReductionCost += getArithmeticInstrCost(Opcode, Ty, CostKind);
6079 }
6080
6081 // Add the final extract element to the cost.
6082 return ReductionCost + getVectorInstrCost(Instruction::ExtractElement, Ty,
6083 CostKind, 0, nullptr, nullptr,
6085}
6086
6089 FastMathFlags FMF) const {
6090 IntrinsicCostAttributes ICA(IID, Ty, {Ty, Ty}, FMF);
6091 return getIntrinsicInstrCost(ICA, CostKind);
6092}
6093
6096 FastMathFlags FMF,
6098 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(ValTy);
6099
6100 MVT MTy = LT.second;
6101
6103 if (ValTy->isIntOrIntVectorTy()) {
6104 ISD = (IID == Intrinsic::umin || IID == Intrinsic::umax) ? ISD::UMIN
6105 : ISD::SMIN;
6106 } else {
6107 assert(ValTy->isFPOrFPVectorTy() &&
6108 "Expected float point or integer vector type.");
6109 ISD = (IID == Intrinsic::minnum || IID == Intrinsic::maxnum)
6110 ? ISD::FMINNUM
6111 : ISD::FMINIMUM;
6112 }
6113
6114 // We use llvm-mca across all supported CPUs to measure the cost stats.
6115 static const CostKindTblEntry SSE2CostTbl[] = {
6116 {ISD::SMIN, MVT::v2i64, {3, 4, 5, 6}},
6117 {ISD::UMIN, MVT::v2i64, {3, 4, 5, 6}},
6118 {ISD::SMIN, MVT::v2i32, {2, 2, 5, 6}},
6119 {ISD::UMIN, MVT::v2i32, {2, 2, 5, 6}},
6120 {ISD::SMIN, MVT::v4i32, {3, 7,11,12}},
6121 {ISD::UMIN, MVT::v4i32, {4, 7,14,15}},
6122 {ISD::SMIN, MVT::v2i16, {2, 3, 4, 4}},
6123 {ISD::UMIN, MVT::v2i16, {2, 3, 4, 6}},
6124 {ISD::SMIN, MVT::v4i16, {3, 5, 6, 6}},
6125 {ISD::UMIN, MVT::v4i16, {3, 5, 8, 10}},
6126 {ISD::SMIN, MVT::v8i16, {3, 8, 8, 8}},
6127 {ISD::UMIN, MVT::v8i16, {4, 8,12,14}},
6128 {ISD::SMIN, MVT::v2i8, {2, 3, 5, 6}},
6129 {ISD::UMIN, MVT::v2i8, {2, 3, 4, 4}},
6130 {ISD::SMIN, MVT::v4i8, {4, 6,12,13}},
6131 {ISD::UMIN, MVT::v4i8, {3, 6, 7, 7}},
6132 {ISD::SMIN, MVT::v8i8, {5, 9,18,19}},
6133 {ISD::UMIN, MVT::v8i8, {4, 8, 9, 9}},
6134 {ISD::SMIN, MVT::v16i8, {7,13,24,25}},
6135 {ISD::UMIN, MVT::v16i8, {3,10,11,11}},
6136 };
6137
6138 static const CostKindTblEntry SSE41CostTbl[] = {
6139 {ISD::SMIN, MVT::v2i64, {3, 4, 4, 6}},
6140 {ISD::UMIN, MVT::v2i64, {3, 4, 4, 6}},
6141 {ISD::SMIN, MVT::v2i32, {2, 2, 3, 3}},
6142 {ISD::UMIN, MVT::v2i32, {2, 2, 3, 3}},
6143 {ISD::SMIN, MVT::v4i32, {3, 4, 5, 5}},
6144 {ISD::UMIN, MVT::v4i32, {3, 4, 5, 5}},
6145 {ISD::UMIN, MVT::v2i16, {2, 3, 4, 4}},
6146 {ISD::SMIN, MVT::v4i16, {3, 5, 6, 6}},
6147 {ISD::UMIN, MVT::v4i16, {3, 5, 6, 6}},
6148 {ISD::SMIN, MVT::v8i16, {2, 8, 4, 5}},
6149 {ISD::UMIN, MVT::v8i16, {2, 5, 2, 2}},
6150 {ISD::SMIN, MVT::v2i8, {2, 3, 4, 4}},
6151 {ISD::SMIN, MVT::v4i8, {3, 6, 7, 7}},
6152 {ISD::SMIN, MVT::v8i8, {4, 8, 9, 9}},
6153 {ISD::SMIN, MVT::v16i8, {3,10, 7, 8}},
6154 {ISD::UMIN, MVT::v16i8, {3, 8, 5, 5}},
6155 };
6156
6157 static const CostKindTblEntry AVX1CostTbl[] = {
6158 {ISD::SMIN, MVT::v4i64, {5,11, 7,10}},
6159 {ISD::UMIN, MVT::v4i64, {6,12,10,13}},
6160 {ISD::SMIN, MVT::v8i32, {4, 9, 7, 7}},
6161 {ISD::UMIN, MVT::v8i32, {4, 9, 7, 7}},
6162 {ISD::SMIN, MVT::v16i16, {3,15, 6, 7}},
6163 {ISD::UMIN, MVT::v16i16, {2, 9, 4, 4}},
6164 {ISD::SMIN, MVT::v32i8, {4,17, 8, 9}},
6165 {ISD::UMIN, MVT::v32i8, {3,11, 6, 6}},
6166 };
6167
6168 static const CostKindTblEntry AVX2CostTbl[] = {
6169 {ISD::SMIN, MVT::v4i64, {4,11, 7,10}},
6170 {ISD::UMIN, MVT::v4i64, {4,12,10,13}},
6171 {ISD::SMIN, MVT::v2i32, {1, 2, 3, 3}},
6172 {ISD::UMIN, MVT::v2i32, {1, 2, 3, 3}},
6173 {ISD::UMIN, MVT::v4i32, {2, 4, 5, 5}},
6174 {ISD::SMIN, MVT::v4i32, {2, 4, 5, 5}},
6175 {ISD::SMIN, MVT::v8i32, {3, 9, 7, 7}},
6176 {ISD::UMIN, MVT::v8i32, {3, 9, 7, 7}},
6177 {ISD::SMIN, MVT::v4i16, {2, 4, 5, 5}},
6178 {ISD::UMIN, MVT::v4i16, {2, 4, 5, 5}},
6179 {ISD::SMIN, MVT::v16i16, {2,15, 6, 7}},
6180 {ISD::SMIN, MVT::v8i8, {3, 6, 7, 7}},
6181 {ISD::UMIN, MVT::v8i8, {3, 6, 7, 7}},
6182 {ISD::SMIN, MVT::v32i8, {3,17, 8, 9}},
6183 };
6184
6185 static const CostKindTblEntry AVX512FCostTbl[] = {
6186 {ISD::SMIN, MVT::v2i64, {2, 4, 3, 3}},
6187 {ISD::UMIN, MVT::v2i64, {2, 4, 3, 3}},
6188 {ISD::SMIN, MVT::v4i64, {3,10, 5, 5}},
6189 {ISD::UMIN, MVT::v4i64, {3,10, 5, 5}},
6190 {ISD::SMIN, MVT::v8i64, {5,16, 7, 7}},
6191 {ISD::UMIN, MVT::v8i64, {5,16, 7, 7}},
6192 {ISD::SMIN, MVT::v16i32, {4,12, 9, 9}},
6193 {ISD::UMIN, MVT::v16i32, {4,12, 9, 9}},
6194 };
6195
6196 static const CostKindTblEntry AVX512BWCostTbl[] = {
6197 {ISD::SMIN, MVT::v2i16, {1, 2, 3, 3}},
6198 {ISD::UMIN, MVT::v2i16, {1, 2, 3, 3}},
6199 {ISD::SMIN, MVT::v32i16, {2,19, 8, 9}},
6200 {ISD::UMIN, MVT::v32i16, {2,12, 6, 6}},
6201 {ISD::SMIN, MVT::v2i8, {1, 2, 3, 3}},
6202 {ISD::UMIN, MVT::v2i8, {1, 2, 3, 3}},
6203 {ISD::SMIN, MVT::v4i8, {2, 4, 5, 5}},
6204 {ISD::UMIN, MVT::v4i8, {2, 4, 5, 5}},
6205 {ISD::SMIN, MVT::v16i8, {2,10, 6, 7}},
6206 {ISD::UMIN, MVT::v16i8, {2, 6, 4, 4}},
6207 {ISD::SMIN, MVT::v32i8, {2,17, 8, 9}},
6208 {ISD::UMIN, MVT::v32i8, {2,10, 6, 6}},
6209 {ISD::SMIN, MVT::v64i8, {2,21,10,11}},
6210 {ISD::UMIN, MVT::v64i8, {2,14, 8, 8}},
6211 };
6212
6213 // Before legalizing the type, give a chance to look up illegal narrow types
6214 // in the table.
6215 // FIXME: Is there a better way to do this?
6216 EVT VT = TLI->getValueType(DL, ValTy);
6217 if (VT.isSimple()) {
6218 MVT MTy = VT.getSimpleVT();
6219 if (ST->hasBWI())
6220 if (const auto *Entry = CostTableLookup(AVX512BWCostTbl, ISD, MTy))
6221 if (auto KindCost = Entry->Cost[CostKind])
6222 return *KindCost;
6223
6224 if (ST->hasAVX512())
6225 if (const auto *Entry = CostTableLookup(AVX512FCostTbl, ISD, MTy))
6226 if (auto KindCost = Entry->Cost[CostKind])
6227 return *KindCost;
6228
6229 if (ST->hasAVX2())
6230 if (const auto *Entry = CostTableLookup(AVX2CostTbl, ISD, MTy))
6231 if (auto KindCost = Entry->Cost[CostKind])
6232 return *KindCost;
6233
6234 if (ST->hasAVX())
6235 if (const auto *Entry = CostTableLookup(AVX1CostTbl, ISD, MTy))
6236 if (auto KindCost = Entry->Cost[CostKind])
6237 return *KindCost;
6238
6239 if (ST->hasSSE41())
6240 if (const auto *Entry = CostTableLookup(SSE41CostTbl, ISD, MTy))
6241 if (auto KindCost = Entry->Cost[CostKind])
6242 return *KindCost;
6243
6244 if (ST->hasSSE2())
6245 if (const auto *Entry = CostTableLookup(SSE2CostTbl, ISD, MTy))
6246 if (auto KindCost = Entry->Cost[CostKind])
6247 return *KindCost;
6248 }
6249
6250 auto *ValVTy = cast<FixedVectorType>(ValTy);
6251 unsigned NumVecElts = ValVTy->getNumElements();
6252
6253 auto *Ty = ValVTy;
6254 InstructionCost MinMaxCost = 0;
6255 if (LT.first != 1 && MTy.isVector() &&
6256 MTy.getVectorNumElements() < ValVTy->getNumElements()) {
6257 // Type needs to be split. We need LT.first - 1 operations ops.
6258 Ty = FixedVectorType::get(ValVTy->getElementType(),
6259 MTy.getVectorNumElements());
6260 MinMaxCost = getMinMaxCost(IID, Ty, CostKind, FMF);
6261 MinMaxCost *= LT.first - 1;
6262 NumVecElts = MTy.getVectorNumElements();
6263 }
6264
6265 if (ST->hasBWI())
6266 if (const auto *Entry = CostTableLookup(AVX512BWCostTbl, ISD, MTy))
6267 if (auto KindCost = Entry->Cost[CostKind])
6268 return MinMaxCost + *KindCost;
6269
6270 if (ST->hasAVX512())
6271 if (const auto *Entry = CostTableLookup(AVX512FCostTbl, ISD, MTy))
6272 if (auto KindCost = Entry->Cost[CostKind])
6273 return MinMaxCost + *KindCost;
6274
6275 if (ST->hasAVX2())
6276 if (const auto *Entry = CostTableLookup(AVX2CostTbl, ISD, MTy))
6277 if (auto KindCost = Entry->Cost[CostKind])
6278 return MinMaxCost + *KindCost;
6279
6280 if (ST->hasAVX())
6281 if (const auto *Entry = CostTableLookup(AVX1CostTbl, ISD, MTy))
6282 if (auto KindCost = Entry->Cost[CostKind])
6283 return MinMaxCost + *KindCost;
6284
6285 if (ST->hasSSE41())
6286 if (const auto *Entry = CostTableLookup(SSE41CostTbl, ISD, MTy))
6287 if (auto KindCost = Entry->Cost[CostKind])
6288 return MinMaxCost + *KindCost;
6289
6290 if (ST->hasSSE2())
6291 if (const auto *Entry = CostTableLookup(SSE2CostTbl, ISD, MTy))
6292 if (auto KindCost = Entry->Cost[CostKind])
6293 return MinMaxCost + *KindCost;
6294
6295 unsigned ScalarSize = ValTy->getScalarSizeInBits();
6296
6297 // Special case power of 2 reductions where the scalar type isn't changed
6298 // by type legalization.
6299 if (!isPowerOf2_32(ValVTy->getNumElements()) ||
6300 ScalarSize != MTy.getScalarSizeInBits())
6301 return BaseT::getMinMaxReductionCost(IID, ValTy, FMF, CostKind);
6302
6303 // Now handle reduction with the legal type, taking into account size changes
6304 // at each level.
6305 while (NumVecElts > 1) {
6306 // Determine the size of the remaining vector we need to reduce.
6307 unsigned Size = NumVecElts * ScalarSize;
6308 NumVecElts /= 2;
6309 // If we're reducing from 256/512 bits, use an extract_subvector.
6310 if (Size > 128) {
6311 auto *SubTy = FixedVectorType::get(ValVTy->getElementType(), NumVecElts);
6312 MinMaxCost += getShuffleCost(TTI::SK_ExtractSubvector, Ty, Ty, {},
6313 CostKind, NumVecElts, SubTy);
6314 Ty = SubTy;
6315 } else if (Size == 128) {
6316 // Reducing from 128 bits is a permute of v2f64/v2i64.
6317 VectorType *ShufTy;
6318 if (ValTy->isFloatingPointTy())
6319 ShufTy =
6321 else
6322 ShufTy = FixedVectorType::get(Type::getInt64Ty(ValTy->getContext()), 2);
6323 MinMaxCost += getShuffleCost(TTI::SK_PermuteSingleSrc, ShufTy, ShufTy, {},
6324 CostKind, 0, nullptr);
6325 } else if (Size == 64) {
6326 // Reducing from 64 bits is a shuffle of v4f32/v4i32.
6327 FixedVectorType *ShufTy;
6328 if (ValTy->isFloatingPointTy())
6329 ShufTy = FixedVectorType::get(Type::getFloatTy(ValTy->getContext()), 4);
6330 else
6331 ShufTy = FixedVectorType::get(Type::getInt32Ty(ValTy->getContext()), 4);
6332 MinMaxCost += getShuffleCost(TTI::SK_PermuteSingleSrc, ShufTy, ShufTy, {},
6333 CostKind, 0, nullptr);
6334 } else {
6335 // Reducing from smaller size is a shift by immediate.
6336 auto *ShiftTy = FixedVectorType::get(
6337 Type::getIntNTy(ValTy->getContext(), Size), 128 / Size);
6338 MinMaxCost += getArithmeticInstrCost(
6339 Instruction::LShr, ShiftTy, TTI::TCK_RecipThroughput,
6342 }
6343
6344 // Add the arithmetic op for this level.
6345 MinMaxCost += getMinMaxCost(IID, Ty, CostKind, FMF);
6346 }
6347
6348 // Add the final extract element to the cost.
6349 return MinMaxCost + getVectorInstrCost(Instruction::ExtractElement, Ty,
6350 CostKind, 0, nullptr, nullptr,
6352}
6353
6354/// Calculate the cost of materializing a 64-bit value. This helper
6355/// method might only calculate a fraction of a larger immediate. Therefore it
6356/// is valid to return a cost of ZERO.
6358 if (Val == 0)
6359 return TTI::TCC_Free;
6360
6361 if (isInt<32>(Val))
6362 return TTI::TCC_Basic;
6363
6364 return 2 * TTI::TCC_Basic;
6365}
6366
6369 assert(Ty->isIntegerTy());
6370
6371 unsigned BitSize = Ty->getPrimitiveSizeInBits();
6372 if (BitSize == 0)
6373 return ~0U;
6374
6375 // Never hoist constants larger than 128bit, because this might lead to
6376 // incorrect code generation or assertions in codegen.
6377 // Fixme: Create a cost model for types larger than i128 once the codegen
6378 // issues have been fixed.
6379 if (BitSize > 128)
6380 return TTI::TCC_Free;
6381
6382 if (Imm == 0)
6383 return TTI::TCC_Free;
6384
6385 // Sign-extend all constants to a multiple of 64-bit.
6386 APInt ImmVal = Imm;
6387 if (BitSize % 64 != 0)
6388 ImmVal = Imm.sext(alignTo(BitSize, 64));
6389
6390 // Split the constant into 64-bit chunks and calculate the cost for each
6391 // chunk.
6393 for (unsigned ShiftVal = 0; ShiftVal < BitSize; ShiftVal += 64) {
6394 APInt Tmp = ImmVal.ashr(ShiftVal).sextOrTrunc(64);
6395 int64_t Val = Tmp.getSExtValue();
6396 Cost += getIntImmCost(Val);
6397 }
6398 // We need at least one instruction to materialize the constant.
6399 return std::max<InstructionCost>(1, Cost);
6400}
6401
6403 const APInt &Imm, Type *Ty,
6405 Instruction *Inst) const {
6406 assert(Ty->isIntegerTy());
6407
6408 unsigned BitSize = Ty->getPrimitiveSizeInBits();
6409 unsigned ImmBitWidth = Imm.getBitWidth();
6410
6411 // There is no cost model for constants with a bit size of 0. Return TCC_Free
6412 // here, so that constant hoisting will ignore this constant.
6413 if (BitSize == 0)
6414 return TTI::TCC_Free;
6415
6416 unsigned ImmIdx = ~0U;
6417 switch (Opcode) {
6418 default:
6419 return TTI::TCC_Free;
6420 case Instruction::GetElementPtr:
6421 // Always hoist the base address of a GetElementPtr. This prevents the
6422 // creation of new constants for every base constant that gets constant
6423 // folded with the offset.
6424 if (Idx == 0)
6425 return 2 * TTI::TCC_Basic;
6426 return TTI::TCC_Free;
6427 case Instruction::Store:
6428 ImmIdx = 0;
6429 break;
6430 case Instruction::ICmp:
6431 // This is an imperfect hack to prevent constant hoisting of
6432 // compares that might be trying to check if a 64-bit value fits in
6433 // 32-bits. The backend can optimize these cases using a right shift by 32.
6434 // There are other predicates and immediates the backend can use shifts for.
6435 if (Idx == 1 && ImmBitWidth == 64) {
6436 uint64_t ImmVal = Imm.getZExtValue();
6437 if (ImmVal == 0x100000000ULL || ImmVal == 0xffffffff)
6438 return TTI::TCC_Free;
6439
6440 if (auto *Cmp = dyn_cast_or_null<CmpInst>(Inst)) {
6441 if (Cmp->isEquality()) {
6442 KnownBits Known = computeKnownBits(Cmp->getOperand(0), DL);
6443 if (Known.countMinTrailingZeros() >= 32)
6444 return TTI::TCC_Free;
6445 }
6446 }
6447 }
6448 ImmIdx = 1;
6449 break;
6450 case Instruction::And:
6451 // We support 64-bit ANDs with immediates with 32-bits of leading zeroes
6452 // by using a 32-bit operation with implicit zero extension. Detect such
6453 // immediates here as the normal path expects bit 31 to be sign extended.
6454 if (Idx == 1 && ImmBitWidth == 64 && Imm.isIntN(32))
6455 return TTI::TCC_Free;
6456 // If we have BMI then we can use BEXTR/BZHI to mask out upper i64 bits.
6457 if (Idx == 1 && ImmBitWidth == 64 && ST->is64Bit() && ST->hasBMI() &&
6458 Imm.isMask())
6459 return X86TTIImpl::getIntImmCost(ST->hasBMI2() ? 255 : 65535);
6460 ImmIdx = 1;
6461 break;
6462 case Instruction::Add:
6463 case Instruction::Sub:
6464 // For add/sub, we can use the opposite instruction for INT32_MIN.
6465 if (Idx == 1 && ImmBitWidth == 64 && Imm.getZExtValue() == 0x80000000)
6466 return TTI::TCC_Free;
6467 ImmIdx = 1;
6468 break;
6469 case Instruction::UDiv:
6470 case Instruction::SDiv:
6471 case Instruction::URem:
6472 case Instruction::SRem:
6473 // Division by constant is typically expanded later into a different
6474 // instruction sequence. This completely changes the constants.
6475 // Report them as "free" to stop ConstantHoist from marking them as opaque.
6476 return TTI::TCC_Free;
6477 case Instruction::Mul:
6478 case Instruction::Or:
6479 case Instruction::Xor:
6480 ImmIdx = 1;
6481 break;
6482 // Always return TCC_Free for the shift value of a shift instruction.
6483 case Instruction::Shl:
6484 case Instruction::LShr:
6485 case Instruction::AShr:
6486 if (Idx == 1)
6487 return TTI::TCC_Free;
6488 break;
6489 case Instruction::Trunc:
6490 case Instruction::ZExt:
6491 case Instruction::SExt:
6492 case Instruction::IntToPtr:
6493 case Instruction::PtrToInt:
6494 case Instruction::BitCast:
6495 case Instruction::PHI:
6496 case Instruction::Call:
6497 case Instruction::Select:
6498 case Instruction::Ret:
6499 case Instruction::Load:
6500 break;
6501 }
6502
6503 if (Idx == ImmIdx) {
6504 uint64_t NumConstants = divideCeil(BitSize, 64);
6506 return (Cost <= NumConstants * TTI::TCC_Basic)
6507 ? static_cast<int>(TTI::TCC_Free)
6508 : Cost;
6509 }
6510
6511 return X86TTIImpl::getIntImmCost(Imm, Ty, CostKind);
6512}
6513
6516 const APInt &Imm, Type *Ty,
6518 assert(Ty->isIntegerTy());
6519
6520 unsigned BitSize = Ty->getPrimitiveSizeInBits();
6521 // There is no cost model for constants with a bit size of 0. Return TCC_Free
6522 // here, so that constant hoisting will ignore this constant.
6523 if (BitSize == 0)
6524 return TTI::TCC_Free;
6525
6526 switch (IID) {
6527 default:
6528 return TTI::TCC_Free;
6529 case Intrinsic::sadd_with_overflow:
6530 case Intrinsic::uadd_with_overflow:
6531 case Intrinsic::ssub_with_overflow:
6532 case Intrinsic::usub_with_overflow:
6533 case Intrinsic::smul_with_overflow:
6534 case Intrinsic::umul_with_overflow:
6535 if ((Idx == 1) && Imm.getBitWidth() <= 64 && Imm.isSignedIntN(32))
6536 return TTI::TCC_Free;
6537 break;
6538 case Intrinsic::experimental_stackmap:
6539 if ((Idx < 2) || (Imm.getBitWidth() <= 64 && Imm.isSignedIntN(64)))
6540 return TTI::TCC_Free;
6541 break;
6542 case Intrinsic::experimental_patchpoint_void:
6543 case Intrinsic::experimental_patchpoint:
6544 if ((Idx < 4) || (Imm.getBitWidth() <= 64 && Imm.isSignedIntN(64)))
6545 return TTI::TCC_Free;
6546 break;
6547 }
6548 return X86TTIImpl::getIntImmCost(Imm, Ty, CostKind);
6549}
6550
6553 const Instruction *I) const {
6555 return Opcode == Instruction::PHI ? TTI::TCC_Free : TTI::TCC_Basic;
6556 // Branches are assumed to be predicted.
6557 return TTI::TCC_Free;
6558}
6559
6560int X86TTIImpl::getGatherOverhead() const {
6561 // Some CPUs have more overhead for gather. The specified overhead is relative
6562 // to the Load operation. "2" is the number provided by Intel architects. This
6563 // parameter is used for cost estimation of Gather Op and comparison with
6564 // other alternatives.
6565 // TODO: Remove the explicit hasAVX512()?, That would mean we would only
6566 // enable gather with a -march.
6567 if (ST->hasAVX512() || (ST->hasAVX2() && ST->hasFastGather()))
6568 return 2;
6569
6570 return 1024;
6571}
6572
6573int X86TTIImpl::getScatterOverhead() const {
6574 if (ST->hasAVX512())
6575 return 2;
6576
6577 return 1024;
6578}
6579
6580// Return an average cost of Gather / Scatter instruction, maybe improved later.
6581InstructionCost X86TTIImpl::getGSVectorCost(unsigned Opcode,
6583 Type *SrcVTy, const Value *Ptr,
6584 Align Alignment,
6585 unsigned AddressSpace) const {
6586
6587 assert(isa<VectorType>(SrcVTy) && "Unexpected type in getGSVectorCost");
6588 unsigned VF = cast<FixedVectorType>(SrcVTy)->getNumElements();
6589
6590 // Try to reduce index size from 64 bit (default for GEP)
6591 // to 32. It is essential for VF 16. If the index can't be reduced to 32, the
6592 // operation will use 16 x 64 indices which do not fit in a zmm and needs
6593 // to split. Also check that the base pointer is the same for all lanes,
6594 // and that there's at most one variable index.
6595 auto getIndexSizeInBits = [](const Value *Ptr, const DataLayout &DL) {
6596 unsigned IndexSize = DL.getPointerSizeInBits();
6597 const GetElementPtrInst *GEP = dyn_cast_or_null<GetElementPtrInst>(Ptr);
6598 if (IndexSize < 64 || !GEP)
6599 return IndexSize;
6600
6601 unsigned NumOfVarIndices = 0;
6602 const Value *Ptrs = GEP->getPointerOperand();
6603 if (Ptrs->getType()->isVectorTy() && !getSplatValue(Ptrs))
6604 return IndexSize;
6605 for (unsigned I = 1, E = GEP->getNumOperands(); I != E; ++I) {
6606 if (isa<Constant>(GEP->getOperand(I)))
6607 continue;
6608 Type *IndxTy = GEP->getOperand(I)->getType();
6609 if (auto *IndexVTy = dyn_cast<VectorType>(IndxTy))
6610 IndxTy = IndexVTy->getElementType();
6611 if ((IndxTy->getPrimitiveSizeInBits() == 64 &&
6612 !isa<SExtInst>(GEP->getOperand(I))) ||
6613 ++NumOfVarIndices > 1)
6614 return IndexSize; // 64
6615 }
6616 return (unsigned)32;
6617 };
6618
6619 // Trying to reduce IndexSize to 32 bits for vector 16.
6620 // By default the IndexSize is equal to pointer size.
6621 unsigned IndexSize = (ST->hasAVX512() && VF >= 16)
6622 ? getIndexSizeInBits(Ptr, DL)
6623 : DL.getPointerSizeInBits();
6624
6625 auto *IndexVTy = FixedVectorType::get(
6626 IntegerType::get(SrcVTy->getContext(), IndexSize), VF);
6627 std::pair<InstructionCost, MVT> IdxsLT = getTypeLegalizationCost(IndexVTy);
6628 std::pair<InstructionCost, MVT> SrcLT = getTypeLegalizationCost(SrcVTy);
6629 InstructionCost::CostType SplitFactor =
6630 std::max(IdxsLT.first, SrcLT.first).getValue();
6631 if (SplitFactor > 1) {
6632 // Handle splitting of vector of pointers
6633 auto *SplitSrcTy =
6634 FixedVectorType::get(SrcVTy->getScalarType(), VF / SplitFactor);
6635 return SplitFactor * getGSVectorCost(Opcode, CostKind, SplitSrcTy, Ptr,
6636 Alignment, AddressSpace);
6637 }
6638
6639 // If we didn't split, this will be a single gather/scatter instruction.
6641 return 1;
6642
6643 // The gather / scatter cost is given by Intel architects. It is a rough
6644 // number since we are looking at one instruction in a time.
6645 const int GSOverhead = (Opcode == Instruction::Load) ? getGatherOverhead()
6646 : getScatterOverhead();
6647 return GSOverhead + VF * getMemoryOpCost(Opcode, SrcVTy->getScalarType(),
6648 Alignment, AddressSpace, CostKind);
6649}
6650
6651/// Calculate the cost of Gather / Scatter operation
6655 bool IsLoad = MICA.getID() == Intrinsic::masked_gather ||
6656 MICA.getID() == Intrinsic::vp_gather;
6657 unsigned Opcode = IsLoad ? Instruction::Load : Instruction::Store;
6658 Type *SrcVTy = MICA.getDataType();
6659 const Value *Ptr = MICA.getPointer();
6660 Align Alignment = MICA.getAlignment();
6661 if ((Opcode == Instruction::Load &&
6662 (!isLegalMaskedGather(SrcVTy, Align(Alignment)) ||
6664 Align(Alignment)))) ||
6665 (Opcode == Instruction::Store &&
6666 (!isLegalMaskedScatter(SrcVTy, Align(Alignment)) ||
6668 Align(Alignment)))))
6670
6671 assert(SrcVTy->isVectorTy() && "Unexpected data type for Gather/Scatter");
6672 unsigned AddressSpace = MICA.getAddressSpace();
6673 return getGSVectorCost(Opcode, CostKind, SrcVTy, Ptr, Alignment,
6674 AddressSpace);
6675}
6676
6678 const TargetTransformInfo::LSRCost &C2) const {
6679 // X86 specific here are "instruction number 1st priority".
6680 return std::tie(C1.Insns, C1.NumRegs, C1.AddRecCost, C1.NumIVMuls,
6681 C1.NumBaseAdds, C1.ScaleCost, C1.ImmCost, C1.SetupCost) <
6682 std::tie(C2.Insns, C2.NumRegs, C2.AddRecCost, C2.NumIVMuls,
6683 C2.NumBaseAdds, C2.ScaleCost, C2.ImmCost, C2.SetupCost);
6684}
6685
6687 return ST->hasMacroFusion() || ST->hasBranchFusion();
6688}
6689
6690static bool isLegalMaskedLoadStore(Type *ScalarTy, const X86Subtarget *ST) {
6691 if (!ST->hasAVX())
6692 return false;
6693
6694 if (ScalarTy->isPointerTy())
6695 return true;
6696
6697 if (ScalarTy->isFloatTy() || ScalarTy->isDoubleTy())
6698 return true;
6699
6700 if (ScalarTy->isHalfTy() && ST->hasBWI())
6701 return true;
6702
6703 if (ScalarTy->isBFloatTy() && ST->hasBF16())
6704 return true;
6705
6706 if (!ScalarTy->isIntegerTy())
6707 return false;
6708
6709 unsigned IntWidth = ScalarTy->getIntegerBitWidth();
6710 return IntWidth == 32 || IntWidth == 64 ||
6711 ((IntWidth == 8 || IntWidth == 16) && ST->hasBWI());
6712}
6713
6715 unsigned AddressSpace,
6716 TTI::MaskKind MaskKind) const {
6717 Type *ScalarTy = DataTy->getScalarType();
6718
6719 // The backend can't handle a single element vector w/o CFCMOV.
6720 if (isa<VectorType>(DataTy) &&
6721 cast<FixedVectorType>(DataTy)->getNumElements() == 1)
6722 return ST->hasCF() &&
6723 hasConditionalLoadStoreForType(ScalarTy, /*IsStore=*/false);
6724
6725 return isLegalMaskedLoadStore(ScalarTy, ST);
6726}
6727
6729 unsigned AddressSpace,
6730 TTI::MaskKind MaskKind) const {
6731 Type *ScalarTy = DataTy->getScalarType();
6732
6733 // The backend can't handle a single element vector w/o CFCMOV.
6734 if (isa<VectorType>(DataTy) &&
6735 cast<FixedVectorType>(DataTy)->getNumElements() == 1)
6736 return ST->hasCF() &&
6737 hasConditionalLoadStoreForType(ScalarTy, /*IsStore=*/true);
6738
6739 return isLegalMaskedLoadStore(ScalarTy, ST);
6740}
6741
6742bool X86TTIImpl::isLegalNTLoad(Type *DataType, Align Alignment) const {
6743 unsigned DataSize = DL.getTypeStoreSize(DataType);
6744 // The only supported nontemporal loads are for aligned vectors of 16 or 32
6745 // bytes. Note that 32-byte nontemporal vector loads are supported by AVX2
6746 // (the equivalent stores only require AVX).
6747 if (Alignment >= DataSize && (DataSize == 16 || DataSize == 32))
6748 return DataSize == 16 ? ST->hasSSE1() : ST->hasAVX2();
6749
6750 return false;
6751}
6752
6753bool X86TTIImpl::isLegalNTStore(Type *DataType, Align Alignment) const {
6754 unsigned DataSize = DL.getTypeStoreSize(DataType);
6755
6756 // SSE4A supports nontemporal stores of float and double at arbitrary
6757 // alignment.
6758 if (ST->hasSSE4A() && (DataType->isFloatTy() || DataType->isDoubleTy()))
6759 return true;
6760
6761 // Besides the SSE4A subtarget exception above, only aligned stores are
6762 // available nontemporaly on any other subtarget. And only stores with a size
6763 // of 4..32 bytes (powers of 2, only) are permitted.
6764 if (Alignment < DataSize || DataSize < 4 || DataSize > 32 ||
6765 !isPowerOf2_32(DataSize))
6766 return false;
6767
6768 // 32-byte vector nontemporal stores are supported by AVX (the equivalent
6769 // loads require AVX2).
6770 if (DataSize == 32)
6771 return ST->hasAVX();
6772 if (DataSize == 16)
6773 return ST->hasSSE1();
6774 return true;
6775}
6776
6778 ElementCount NumElements) const {
6779 // movddup
6780 return ST->hasSSE3() && !NumElements.isScalable() &&
6781 NumElements.getFixedValue() == 2 &&
6782 ElementTy == Type::getDoubleTy(ElementTy->getContext());
6783}
6784
6785bool X86TTIImpl::isLegalMaskedExpandLoad(Type *DataTy, Align Alignment) const {
6786 if (!isa<VectorType>(DataTy))
6787 return false;
6788
6789 if (!ST->hasAVX512())
6790 return false;
6791
6792 // The backend can't handle a single element vector.
6793 if (cast<FixedVectorType>(DataTy)->getNumElements() == 1)
6794 return false;
6795
6796 Type *ScalarTy = cast<VectorType>(DataTy)->getElementType();
6797
6798 if (ScalarTy->isFloatTy() || ScalarTy->isDoubleTy())
6799 return true;
6800
6801 if (!ScalarTy->isIntegerTy())
6802 return false;
6803
6804 unsigned IntWidth = ScalarTy->getIntegerBitWidth();
6805 return IntWidth == 32 || IntWidth == 64 ||
6806 ((IntWidth == 8 || IntWidth == 16) && ST->hasVBMI2());
6807}
6808
6810 Align Alignment) const {
6811 return isLegalMaskedExpandLoad(DataTy, Alignment);
6812}
6813
6814bool X86TTIImpl::supportsGather() const {
6815 // Some CPUs have better gather performance than others.
6816 // TODO: Remove the explicit ST->hasAVX512()?, That would mean we would only
6817 // enable gather with a -march.
6818 return ST->hasAVX512() || (ST->hasFastGather() && ST->hasAVX2());
6819}
6820
6822 Align Alignment) const {
6823 // Gather / Scatter for vector 2 is not profitable on KNL / SKX
6824 // Vector-4 of gather/scatter instruction does not exist on KNL. We can extend
6825 // it to 8 elements, but zeroing upper bits of the mask vector will add more
6826 // instructions. Right now we give the scalar cost of vector-4 for KNL. TODO:
6827 // Check, maybe the gather/scatter instruction is better in the VariableMask
6828 // case.
6829 unsigned NumElts = cast<FixedVectorType>(VTy)->getNumElements();
6830 return NumElts == 1 ||
6831 (ST->hasAVX512() && (NumElts == 2 || (NumElts == 4 && !ST->hasVLX())));
6832}
6833
6835 Align Alignment) const {
6836 Type *ScalarTy = DataTy->getScalarType();
6837 if (ScalarTy->isPointerTy())
6838 return true;
6839
6840 if (ScalarTy->isFloatTy() || ScalarTy->isDoubleTy())
6841 return true;
6842
6843 if (!ScalarTy->isIntegerTy())
6844 return false;
6845
6846 unsigned IntWidth = ScalarTy->getIntegerBitWidth();
6847 return IntWidth == 32 || IntWidth == 64;
6848}
6849
6850bool X86TTIImpl::isLegalMaskedGather(Type *DataTy, Align Alignment) const {
6851 if (!supportsGather() || !ST->preferGather())
6852 return false;
6853 return isLegalMaskedGatherScatter(DataTy, Alignment);
6854}
6855
6856bool X86TTIImpl::isLegalAltInstr(VectorType *VecTy, unsigned Opcode0,
6857 unsigned Opcode1,
6858 const SmallBitVector &OpcodeMask) const {
6859 // ADDSUBPS 4xf32 SSE3
6860 // VADDSUBPS 4xf32 AVX
6861 // VADDSUBPS 8xf32 AVX2
6862 // ADDSUBPD 2xf64 SSE3
6863 // VADDSUBPD 2xf64 AVX
6864 // VADDSUBPD 4xf64 AVX2
6865
6866 unsigned NumElements = cast<FixedVectorType>(VecTy)->getNumElements();
6867 assert(OpcodeMask.size() == NumElements && "Mask and VecTy are incompatible");
6868 if (!isPowerOf2_32(NumElements))
6869 return false;
6870 // Check the opcode pattern. We apply the mask on the opcode arguments and
6871 // then check if it is what we expect.
6872 for (int Lane : seq<int>(0, NumElements)) {
6873 unsigned Opc = OpcodeMask.test(Lane) ? Opcode1 : Opcode0;
6874 // We expect FSub for even lanes and FAdd for odd lanes.
6875 if (Lane % 2 == 0 && Opc != Instruction::FSub)
6876 return false;
6877 if (Lane % 2 == 1 && Opc != Instruction::FAdd)
6878 return false;
6879 }
6880 // Now check that the pattern is supported by the target ISA.
6881 Type *ElemTy = cast<VectorType>(VecTy)->getElementType();
6882 if (ElemTy->isFloatTy())
6883 return ST->hasSSE3() && NumElements % 4 == 0;
6884 if (ElemTy->isDoubleTy())
6885 return ST->hasSSE3() && NumElements % 2 == 0;
6886 return false;
6887}
6888
6889bool X86TTIImpl::isLegalMaskedScatter(Type *DataType, Align Alignment) const {
6890 // AVX2 doesn't support scatter
6891 if (!ST->hasAVX512() || !ST->preferScatter())
6892 return false;
6893 return isLegalMaskedGatherScatter(DataType, Alignment);
6894}
6895
6896bool X86TTIImpl::hasDivRemOp(Type *DataType, bool IsSigned) const {
6897 EVT VT = TLI->getValueType(DL, DataType);
6898 return TLI->isOperationLegal(IsSigned ? ISD::SDIVREM : ISD::UDIVREM, VT);
6899}
6900
6902 // FDIV is always expensive, even if it has a very low uop count.
6903 // TODO: Still necessary for recent CPUs with low latency/throughput fdiv?
6904 if (I->getOpcode() == Instruction::FDiv)
6905 return true;
6906
6908}
6909
6910bool X86TTIImpl::isFCmpOrdCheaperThanFCmpZero(Type *Ty) const { return false; }
6911
6913 const Function *Callee) const {
6914 const TargetMachine &TM = getTLI()->getTargetMachine();
6915
6916 // Work this as a subsetting of subtarget features.
6917 const X86Subtarget &CallerSubtarget = TM.getSubtarget<X86Subtarget>(*Caller);
6918 const X86Subtarget &CalleeSubtarget = TM.getSubtarget<X86Subtarget>(*Callee);
6919 const FeatureBitset &CallerBits = CallerSubtarget.getFeatureBits();
6920 const FeatureBitset &CalleeBits = CalleeSubtarget.getFeatureBits();
6921
6922 // Check whether callee features are a subset of caller features
6923 // (apart from the ignore list).
6924 const FeatureBitset &InlineIgnoreFeatures =
6925 CallerSubtarget.getInlineIgnoreFeatures();
6926 FeatureBitset RealCallerBits = CallerBits & ~InlineIgnoreFeatures;
6927 FeatureBitset RealCalleeBits = CalleeBits & ~InlineIgnoreFeatures;
6928 if ((RealCallerBits & RealCalleeBits) != RealCalleeBits)
6929 return false;
6930
6931 // If the features are not exactly the same (or there is a difference in
6932 // AVX512 register usage), we need to additionally check for calls
6933 // that may become ABI-incompatible as a result of inlining.
6934 if (RealCallerBits == RealCalleeBits &&
6935 CallerSubtarget.useAVX512Regs() == CalleeSubtarget.useAVX512Regs())
6936 return true;
6937
6938 for (const Instruction &I : instructions(Callee)) {
6939 if (const auto *CB = dyn_cast<CallBase>(&I)) {
6940 // Having more target features is fine for inline ASM and intrinsics.
6941 if (CB->isInlineAsm() || CB->getIntrinsicID() != Intrinsic::not_intrinsic)
6942 continue;
6943
6945 for (Value *Arg : CB->args())
6946 Types.push_back(Arg->getType());
6947 if (!CB->getType()->isVoidTy())
6948 Types.push_back(CB->getType());
6949
6950 // Simple types are always ABI compatible.
6951 auto IsSimpleTy = [](Type *Ty) {
6952 return !Ty->isVectorTy() && !Ty->isAggregateType();
6953 };
6954 if (all_of(Types, IsSimpleTy))
6955 continue;
6956
6957 // Do a precise compatibility check.
6958 if (!areTypesABICompatible(Caller, Callee, Types))
6959 return false;
6960 }
6961 }
6962 return true;
6963}
6964
6966 const Function *Callee,
6967 ArrayRef<Type *> Types) const {
6968 const TargetMachine &TM = getTLI()->getTargetMachine();
6969 const TargetLowering *CallerTLI =
6970 TM.getSubtargetImpl(*Caller)->getTargetLowering();
6971 const TargetLowering *CalleeTLI =
6972 TM.getSubtargetImpl(*Callee)->getTargetLowering();
6973
6974 LLVMContext &Ctx = Caller->getContext();
6975 const DataLayout &DL = Caller->getDataLayout();
6976 CallingConv::ID CC = Callee->getCallingConv();
6977 return all_of(Types, [&](Type *Ty) {
6978 SmallVector<EVT> VTs;
6979 ComputeValueVTs(*CallerTLI, DL, Ty, VTs);
6980 return all_of(VTs, [&](EVT VT) {
6981 return CallerTLI->getRegisterTypeForCallingConv(Ctx, CC, VT) ==
6982 CalleeTLI->getRegisterTypeForCallingConv(Ctx, CC, VT);
6983 });
6984 });
6985}
6986
6988X86TTIImpl::enableMemCmpExpansion(bool OptSize, bool IsZeroCmp) const {
6990 Options.MaxNumLoads = TLI->getMaxExpandSizeMemcmp(OptSize);
6991 Options.NumLoadsPerBlock = 2;
6992 // All GPR and vector loads can be unaligned.
6993 Options.AllowOverlappingLoads = true;
6994 if (IsZeroCmp) {
6995 // Only enable vector loads for equality comparison. Right now the vector
6996 // version is not as fast for three way compare (see #33329).
6997 const unsigned PreferredWidth = ST->getPreferVectorWidth();
6998 if (PreferredWidth >= 512 && ST->hasAVX512())
6999 Options.LoadSizes.push_back(64);
7000 if (PreferredWidth >= 256 && ST->hasAVX()) Options.LoadSizes.push_back(32);
7001 if (PreferredWidth >= 128 && ST->hasSSE2()) Options.LoadSizes.push_back(16);
7002 }
7003 if (ST->is64Bit()) {
7004 Options.LoadSizes.push_back(8);
7005 }
7006 Options.LoadSizes.push_back(4);
7007 Options.LoadSizes.push_back(2);
7008 Options.LoadSizes.push_back(1);
7009 return Options;
7010}
7011
7013 return supportsGather();
7014}
7015
7017 return false;
7018}
7019
7021 // TODO: We expect this to be beneficial regardless of arch,
7022 // but there are currently some unexplained performance artifacts on Atom.
7023 // As a temporary solution, disable on Atom.
7024 return !(ST->isAtom());
7025}
7026
7028 switch (II->getIntrinsicID()) {
7029 default:
7030 return true;
7031 case Intrinsic::vector_reduce_and:
7032 case Intrinsic::vector_reduce_or:
7033 case Intrinsic::vector_reduce_xor:
7034 case Intrinsic::vector_reduce_mul:
7035 case Intrinsic::vector_reduce_smax:
7036 case Intrinsic::vector_reduce_smin:
7037 case Intrinsic::vector_reduce_umax:
7038 case Intrinsic::vector_reduce_umin:
7039 return false;
7040 }
7041}
7042
7043// Get estimation for interleaved load/store operations and strided load.
7044// \p Indices contains indices for strided load.
7045// \p Factor - the factor of interleaving.
7046// AVX-512 provides 3-src shuffles that significantly reduces the cost.
7048 unsigned Opcode, FixedVectorType *VecTy, unsigned Factor,
7049 ArrayRef<unsigned> Indices, Align Alignment, unsigned AddressSpace,
7050 TTI::TargetCostKind CostKind, bool UseMaskForCond,
7051 bool UseMaskForGaps) const {
7052 // VecTy for interleave memop is <VF*Factor x Elt>.
7053 // So, for VF=4, Interleave Factor = 3, Element type = i32 we have
7054 // VecTy = <12 x i32>.
7055
7056 // Calculate the number of memory operations (NumOfMemOps), required
7057 // for load/store the VecTy.
7058 MVT LegalVT = getTypeLegalizationCost(VecTy).second;
7059 unsigned VecTySize = DL.getTypeStoreSize(VecTy);
7060 unsigned LegalVTSize = LegalVT.getStoreSize();
7061 unsigned NumOfMemOps = (VecTySize + LegalVTSize - 1) / LegalVTSize;
7062
7063 // Get the cost of one memory operation.
7064 auto *SingleMemOpTy = FixedVectorType::get(VecTy->getElementType(),
7065 LegalVT.getVectorNumElements());
7066 InstructionCost MemOpCost;
7067 bool UseMaskedMemOp = UseMaskForCond || UseMaskForGaps;
7068 if (UseMaskedMemOp) {
7069 unsigned IID = Opcode == Instruction::Load ? Intrinsic::masked_load
7070 : Intrinsic::masked_store;
7071 MemOpCost = getMaskedMemoryOpCost(
7072 {IID, SingleMemOpTy, Alignment, AddressSpace}, CostKind);
7073 } else
7074 MemOpCost = getMemoryOpCost(Opcode, SingleMemOpTy, Alignment, AddressSpace,
7075 CostKind);
7076
7077 unsigned VF = VecTy->getNumElements() / Factor;
7078 MVT VT =
7079 MVT::getVectorVT(TLI->getSimpleValueType(DL, VecTy->getScalarType()), VF);
7080
7081 InstructionCost MaskCost;
7082 if (UseMaskedMemOp) {
7083 APInt DemandedLoadStoreElts = APInt::getZero(VecTy->getNumElements());
7084 for (unsigned Index : Indices) {
7085 assert(Index < Factor && "Invalid index for interleaved memory op");
7086 for (unsigned Elm = 0; Elm < VF; Elm++)
7087 DemandedLoadStoreElts.setBit(Index + Elm * Factor);
7088 }
7089
7090 Type *I1Type = Type::getInt1Ty(VecTy->getContext());
7091
7092 MaskCost = getReplicationShuffleCost(
7093 I1Type, Factor, VF,
7094 UseMaskForGaps ? DemandedLoadStoreElts
7096 CostKind);
7097
7098 // The Gaps mask is invariant and created outside the loop, therefore the
7099 // cost of creating it is not accounted for here. However if we have both
7100 // a MaskForGaps and some other mask that guards the execution of the
7101 // memory access, we need to account for the cost of And-ing the two masks
7102 // inside the loop.
7103 if (UseMaskForGaps) {
7104 auto *MaskVT = FixedVectorType::get(I1Type, VecTy->getNumElements());
7105 MaskCost += getArithmeticInstrCost(BinaryOperator::And, MaskVT, CostKind);
7106 }
7107 }
7108
7109 if (Opcode == Instruction::Load) {
7110 // The tables (AVX512InterleavedLoadTbl and AVX512InterleavedStoreTbl)
7111 // contain the cost of the optimized shuffle sequence that the
7112 // X86InterleavedAccess pass will generate.
7113 // The cost of loads and stores are computed separately from the table.
7114
7115 // X86InterleavedAccess support only the following interleaved-access group.
7116 static const CostTblEntry AVX512InterleavedLoadTbl[] = {
7117 {3, MVT::v16i8, 12}, //(load 48i8 and) deinterleave into 3 x 16i8
7118 {3, MVT::v32i8, 14}, //(load 96i8 and) deinterleave into 3 x 32i8
7119 {3, MVT::v64i8, 22}, //(load 96i8 and) deinterleave into 3 x 32i8
7120 };
7121
7122 if (const auto *Entry =
7123 CostTableLookup(AVX512InterleavedLoadTbl, Factor, VT))
7124 return MaskCost + NumOfMemOps * MemOpCost + Entry->Cost;
7125 //If an entry does not exist, fallback to the default implementation.
7126
7127 // Kind of shuffle depends on number of loaded values.
7128 // If we load the entire data in one register, we can use a 1-src shuffle.
7129 // Otherwise, we'll merge 2 sources in each operation.
7130 TTI::ShuffleKind ShuffleKind =
7131 (NumOfMemOps > 1) ? TTI::SK_PermuteTwoSrc : TTI::SK_PermuteSingleSrc;
7132
7133 InstructionCost ShuffleCost = getShuffleCost(
7134 ShuffleKind, SingleMemOpTy, SingleMemOpTy, {}, CostKind, 0, nullptr);
7135
7136 unsigned NumOfLoadsInInterleaveGrp =
7137 Indices.size() ? Indices.size() : Factor;
7138 auto *ResultTy = FixedVectorType::get(VecTy->getElementType(),
7139 VecTy->getNumElements() / Factor);
7140 InstructionCost NumOfResults =
7141 getTypeLegalizationCost(ResultTy).first * NumOfLoadsInInterleaveGrp;
7142
7143 // About a half of the loads may be folded in shuffles when we have only
7144 // one result. If we have more than one result, or the loads are masked,
7145 // we do not fold loads at all.
7146 unsigned NumOfUnfoldedLoads =
7147 UseMaskedMemOp || NumOfResults > 1 ? NumOfMemOps : NumOfMemOps / 2;
7148
7149 // Get a number of shuffle operations per result.
7150 unsigned NumOfShufflesPerResult =
7151 std::max((unsigned)1, (unsigned)(NumOfMemOps - 1));
7152
7153 // The SK_MergeTwoSrc shuffle clobbers one of src operands.
7154 // When we have more than one destination, we need additional instructions
7155 // to keep sources.
7156 InstructionCost NumOfMoves = 0;
7157 if (NumOfResults > 1 && ShuffleKind == TTI::SK_PermuteTwoSrc)
7158 NumOfMoves = NumOfResults * NumOfShufflesPerResult / 2;
7159
7160 InstructionCost Cost = NumOfResults * NumOfShufflesPerResult * ShuffleCost +
7161 MaskCost + NumOfUnfoldedLoads * MemOpCost +
7162 NumOfMoves;
7163
7164 return Cost;
7165 }
7166
7167 // Store.
7168 assert(Opcode == Instruction::Store &&
7169 "Expected Store Instruction at this point");
7170 // X86InterleavedAccess support only the following interleaved-access group.
7171 static const CostTblEntry AVX512InterleavedStoreTbl[] = {
7172 {3, MVT::v16i8, 12}, // interleave 3 x 16i8 into 48i8 (and store)
7173 {3, MVT::v32i8, 14}, // interleave 3 x 32i8 into 96i8 (and store)
7174 {3, MVT::v64i8, 26}, // interleave 3 x 64i8 into 96i8 (and store)
7175
7176 {4, MVT::v8i8, 10}, // interleave 4 x 8i8 into 32i8 (and store)
7177 {4, MVT::v16i8, 11}, // interleave 4 x 16i8 into 64i8 (and store)
7178 {4, MVT::v32i8, 14}, // interleave 4 x 32i8 into 128i8 (and store)
7179 {4, MVT::v64i8, 24} // interleave 4 x 32i8 into 256i8 (and store)
7180 };
7181
7182 if (const auto *Entry =
7183 CostTableLookup(AVX512InterleavedStoreTbl, Factor, VT))
7184 return MaskCost + NumOfMemOps * MemOpCost + Entry->Cost;
7185 //If an entry does not exist, fallback to the default implementation.
7186
7187 // There is no strided stores meanwhile. And store can't be folded in
7188 // shuffle.
7189 unsigned NumOfSources = Factor; // The number of values to be merged.
7190 InstructionCost ShuffleCost =
7191 getShuffleCost(TTI::SK_PermuteTwoSrc, SingleMemOpTy, SingleMemOpTy, {},
7192 CostKind, 0, nullptr);
7193 unsigned NumOfShufflesPerStore = NumOfSources - 1;
7194
7195 // The SK_MergeTwoSrc shuffle clobbers one of src operands.
7196 // We need additional instructions to keep sources.
7197 unsigned NumOfMoves = NumOfMemOps * NumOfShufflesPerStore / 2;
7199 MaskCost +
7200 NumOfMemOps * (MemOpCost + NumOfShufflesPerStore * ShuffleCost) +
7201 NumOfMoves;
7202 return Cost;
7203}
7204
7206 unsigned Opcode, Type *BaseTy, unsigned Factor, ArrayRef<unsigned> Indices,
7207 Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind,
7208 bool UseMaskForCond, bool UseMaskForGaps) const {
7209 auto *VecTy = cast<FixedVectorType>(BaseTy);
7210
7211 auto isSupportedOnAVX512 = [&](Type *VecTy) {
7212 Type *EltTy = cast<VectorType>(VecTy)->getElementType();
7213 if (EltTy->isFloatTy() || EltTy->isDoubleTy() || EltTy->isIntegerTy(64) ||
7214 EltTy->isIntegerTy(32) || EltTy->isPointerTy())
7215 return true;
7216 if (EltTy->isIntegerTy(16) || EltTy->isIntegerTy(8) || EltTy->isHalfTy())
7217 return ST->hasBWI();
7218 if (EltTy->isBFloatTy())
7219 return ST->hasBF16();
7220 return false;
7221 };
7222 if (ST->hasAVX512() && isSupportedOnAVX512(VecTy))
7224 Opcode, VecTy, Factor, Indices, Alignment,
7225 AddressSpace, CostKind, UseMaskForCond, UseMaskForGaps);
7226
7227 if (UseMaskForCond || UseMaskForGaps)
7228 return BaseT::getInterleavedMemoryOpCost(Opcode, VecTy, Factor, Indices,
7229 Alignment, AddressSpace, CostKind,
7230 UseMaskForCond, UseMaskForGaps);
7231
7232 // Get estimation for interleaved load/store operations for SSE-AVX2.
7233 // As opposed to AVX-512, SSE-AVX2 do not have generic shuffles that allow
7234 // computing the cost using a generic formula as a function of generic
7235 // shuffles. We therefore use a lookup table instead, filled according to
7236 // the instruction sequences that codegen currently generates.
7237
7238 // VecTy for interleave memop is <VF*Factor x Elt>.
7239 // So, for VF=4, Interleave Factor = 3, Element type = i32 we have
7240 // VecTy = <12 x i32>.
7241 MVT LegalVT = getTypeLegalizationCost(VecTy).second;
7242
7243 // This function can be called with VecTy=<6xi128>, Factor=3, in which case
7244 // the VF=2, while v2i128 is an unsupported MVT vector type
7245 // (see MachineValueType.h::getVectorVT()).
7246 if (!LegalVT.isVector())
7247 return BaseT::getInterleavedMemoryOpCost(Opcode, VecTy, Factor, Indices,
7248 Alignment, AddressSpace, CostKind);
7249
7250 unsigned VF = VecTy->getNumElements() / Factor;
7251 Type *ScalarTy = VecTy->getElementType();
7252 // Deduplicate entries, model floats/pointers as appropriately-sized integers.
7253 if (!ScalarTy->isIntegerTy())
7254 ScalarTy =
7255 Type::getIntNTy(ScalarTy->getContext(), DL.getTypeSizeInBits(ScalarTy));
7256
7257 // Get the cost of all the memory operations.
7258 // FIXME: discount dead loads.
7259 InstructionCost MemOpCosts =
7260 getMemoryOpCost(Opcode, VecTy, Alignment, AddressSpace, CostKind);
7261
7262 auto *VT = FixedVectorType::get(ScalarTy, VF);
7263 EVT ETy = TLI->getValueType(DL, VT);
7264 if (!ETy.isSimple())
7265 return BaseT::getInterleavedMemoryOpCost(Opcode, VecTy, Factor, Indices,
7266 Alignment, AddressSpace, CostKind);
7267
7268 // TODO: Complete for other data-types and strides.
7269 // Each combination of Stride, element bit width and VF results in a different
7270 // sequence; The cost tables are therefore accessed with:
7271 // Factor (stride) and VectorType=VFxiN.
7272 // The Cost accounts only for the shuffle sequence;
7273 // The cost of the loads/stores is accounted for separately.
7274 //
7275 static const CostTblEntry AVX2InterleavedLoadTbl[] = {
7276 {2, MVT::v2i8, 2}, // (load 4i8 and) deinterleave into 2 x 2i8
7277 {2, MVT::v4i8, 2}, // (load 8i8 and) deinterleave into 2 x 4i8
7278 {2, MVT::v8i8, 2}, // (load 16i8 and) deinterleave into 2 x 8i8
7279 {2, MVT::v16i8, 4}, // (load 32i8 and) deinterleave into 2 x 16i8
7280 {2, MVT::v32i8, 6}, // (load 64i8 and) deinterleave into 2 x 32i8
7281
7282 {2, MVT::v8i16, 6}, // (load 16i16 and) deinterleave into 2 x 8i16
7283 {2, MVT::v16i16, 9}, // (load 32i16 and) deinterleave into 2 x 16i16
7284 {2, MVT::v32i16, 18}, // (load 64i16 and) deinterleave into 2 x 32i16
7285
7286 {2, MVT::v8i32, 4}, // (load 16i32 and) deinterleave into 2 x 8i32
7287 {2, MVT::v16i32, 8}, // (load 32i32 and) deinterleave into 2 x 16i32
7288 {2, MVT::v32i32, 16}, // (load 64i32 and) deinterleave into 2 x 32i32
7289
7290 {2, MVT::v4i64, 4}, // (load 8i64 and) deinterleave into 2 x 4i64
7291 {2, MVT::v8i64, 8}, // (load 16i64 and) deinterleave into 2 x 8i64
7292 {2, MVT::v16i64, 16}, // (load 32i64 and) deinterleave into 2 x 16i64
7293 {2, MVT::v32i64, 32}, // (load 64i64 and) deinterleave into 2 x 32i64
7294
7295 {3, MVT::v2i8, 3}, // (load 6i8 and) deinterleave into 3 x 2i8
7296 {3, MVT::v4i8, 3}, // (load 12i8 and) deinterleave into 3 x 4i8
7297 {3, MVT::v8i8, 6}, // (load 24i8 and) deinterleave into 3 x 8i8
7298 {3, MVT::v16i8, 11}, // (load 48i8 and) deinterleave into 3 x 16i8
7299 {3, MVT::v32i8, 14}, // (load 96i8 and) deinterleave into 3 x 32i8
7300
7301 {3, MVT::v2i16, 5}, // (load 6i16 and) deinterleave into 3 x 2i16
7302 {3, MVT::v4i16, 7}, // (load 12i16 and) deinterleave into 3 x 4i16
7303 {3, MVT::v8i16, 9}, // (load 24i16 and) deinterleave into 3 x 8i16
7304 {3, MVT::v16i16, 28}, // (load 48i16 and) deinterleave into 3 x 16i16
7305 {3, MVT::v32i16, 56}, // (load 96i16 and) deinterleave into 3 x 32i16
7306
7307 {3, MVT::v2i32, 3}, // (load 6i32 and) deinterleave into 3 x 2i32
7308 {3, MVT::v4i32, 3}, // (load 12i32 and) deinterleave into 3 x 4i32
7309 {3, MVT::v8i32, 7}, // (load 24i32 and) deinterleave into 3 x 8i32
7310 {3, MVT::v16i32, 14}, // (load 48i32 and) deinterleave into 3 x 16i32
7311 {3, MVT::v32i32, 32}, // (load 96i32 and) deinterleave into 3 x 32i32
7312
7313 {3, MVT::v2i64, 1}, // (load 6i64 and) deinterleave into 3 x 2i64
7314 {3, MVT::v4i64, 5}, // (load 12i64 and) deinterleave into 3 x 4i64
7315 {3, MVT::v8i64, 10}, // (load 24i64 and) deinterleave into 3 x 8i64
7316 {3, MVT::v16i64, 20}, // (load 48i64 and) deinterleave into 3 x 16i64
7317
7318 {4, MVT::v2i8, 4}, // (load 8i8 and) deinterleave into 4 x 2i8
7319 {4, MVT::v4i8, 4}, // (load 16i8 and) deinterleave into 4 x 4i8
7320 {4, MVT::v8i8, 12}, // (load 32i8 and) deinterleave into 4 x 8i8
7321 {4, MVT::v16i8, 24}, // (load 64i8 and) deinterleave into 4 x 16i8
7322 {4, MVT::v32i8, 56}, // (load 128i8 and) deinterleave into 4 x 32i8
7323
7324 {4, MVT::v2i16, 6}, // (load 8i16 and) deinterleave into 4 x 2i16
7325 {4, MVT::v4i16, 17}, // (load 16i16 and) deinterleave into 4 x 4i16
7326 {4, MVT::v8i16, 33}, // (load 32i16 and) deinterleave into 4 x 8i16
7327 {4, MVT::v16i16, 75}, // (load 64i16 and) deinterleave into 4 x 16i16
7328 {4, MVT::v32i16, 150}, // (load 128i16 and) deinterleave into 4 x 32i16
7329
7330 {4, MVT::v2i32, 4}, // (load 8i32 and) deinterleave into 4 x 2i32
7331 {4, MVT::v4i32, 8}, // (load 16i32 and) deinterleave into 4 x 4i32
7332 {4, MVT::v8i32, 16}, // (load 32i32 and) deinterleave into 4 x 8i32
7333 {4, MVT::v16i32, 32}, // (load 64i32 and) deinterleave into 4 x 16i32
7334 {4, MVT::v32i32, 68}, // (load 128i32 and) deinterleave into 4 x 32i32
7335
7336 {4, MVT::v2i64, 6}, // (load 8i64 and) deinterleave into 4 x 2i64
7337 {4, MVT::v4i64, 8}, // (load 16i64 and) deinterleave into 4 x 4i64
7338 {4, MVT::v8i64, 20}, // (load 32i64 and) deinterleave into 4 x 8i64
7339 {4, MVT::v16i64, 40}, // (load 64i64 and) deinterleave into 4 x 16i64
7340
7341 {6, MVT::v2i8, 6}, // (load 12i8 and) deinterleave into 6 x 2i8
7342 {6, MVT::v4i8, 14}, // (load 24i8 and) deinterleave into 6 x 4i8
7343 {6, MVT::v8i8, 18}, // (load 48i8 and) deinterleave into 6 x 8i8
7344 {6, MVT::v16i8, 43}, // (load 96i8 and) deinterleave into 6 x 16i8
7345 {6, MVT::v32i8, 82}, // (load 192i8 and) deinterleave into 6 x 32i8
7346
7347 {6, MVT::v2i16, 13}, // (load 12i16 and) deinterleave into 6 x 2i16
7348 {6, MVT::v4i16, 9}, // (load 24i16 and) deinterleave into 6 x 4i16
7349 {6, MVT::v8i16, 39}, // (load 48i16 and) deinterleave into 6 x 8i16
7350 {6, MVT::v16i16, 106}, // (load 96i16 and) deinterleave into 6 x 16i16
7351 {6, MVT::v32i16, 212}, // (load 192i16 and) deinterleave into 6 x 32i16
7352
7353 {6, MVT::v2i32, 6}, // (load 12i32 and) deinterleave into 6 x 2i32
7354 {6, MVT::v4i32, 15}, // (load 24i32 and) deinterleave into 6 x 4i32
7355 {6, MVT::v8i32, 31}, // (load 48i32 and) deinterleave into 6 x 8i32
7356 {6, MVT::v16i32, 64}, // (load 96i32 and) deinterleave into 6 x 16i32
7357
7358 {6, MVT::v2i64, 6}, // (load 12i64 and) deinterleave into 6 x 2i64
7359 {6, MVT::v4i64, 18}, // (load 24i64 and) deinterleave into 6 x 4i64
7360 {6, MVT::v8i64, 36}, // (load 48i64 and) deinterleave into 6 x 8i64
7361
7362 {8, MVT::v8i32, 40} // (load 64i32 and) deinterleave into 8 x 8i32
7363 };
7364
7365 static const CostTblEntry SSSE3InterleavedLoadTbl[] = {
7366 {2, MVT::v4i16, 2}, // (load 8i16 and) deinterleave into 2 x 4i16
7367 };
7368
7369 static const CostTblEntry SSE2InterleavedLoadTbl[] = {
7370 {2, MVT::v2i16, 2}, // (load 4i16 and) deinterleave into 2 x 2i16
7371 {2, MVT::v4i16, 7}, // (load 8i16 and) deinterleave into 2 x 4i16
7372
7373 {2, MVT::v2i32, 2}, // (load 4i32 and) deinterleave into 2 x 2i32
7374 {2, MVT::v4i32, 2}, // (load 8i32 and) deinterleave into 2 x 4i32
7375
7376 {2, MVT::v2i64, 2}, // (load 4i64 and) deinterleave into 2 x 2i64
7377 };
7378
7379 static const CostTblEntry AVX2InterleavedStoreTbl[] = {
7380 {2, MVT::v16i8, 3}, // interleave 2 x 16i8 into 32i8 (and store)
7381 {2, MVT::v32i8, 4}, // interleave 2 x 32i8 into 64i8 (and store)
7382
7383 {2, MVT::v8i16, 3}, // interleave 2 x 8i16 into 16i16 (and store)
7384 {2, MVT::v16i16, 4}, // interleave 2 x 16i16 into 32i16 (and store)
7385 {2, MVT::v32i16, 8}, // interleave 2 x 32i16 into 64i16 (and store)
7386
7387 {2, MVT::v4i32, 2}, // interleave 2 x 4i32 into 8i32 (and store)
7388 {2, MVT::v8i32, 4}, // interleave 2 x 8i32 into 16i32 (and store)
7389 {2, MVT::v16i32, 8}, // interleave 2 x 16i32 into 32i32 (and store)
7390 {2, MVT::v32i32, 16}, // interleave 2 x 32i32 into 64i32 (and store)
7391
7392 {2, MVT::v2i64, 2}, // interleave 2 x 2i64 into 4i64 (and store)
7393 {2, MVT::v4i64, 4}, // interleave 2 x 4i64 into 8i64 (and store)
7394 {2, MVT::v8i64, 8}, // interleave 2 x 8i64 into 16i64 (and store)
7395 {2, MVT::v16i64, 16}, // interleave 2 x 16i64 into 32i64 (and store)
7396 {2, MVT::v32i64, 32}, // interleave 2 x 32i64 into 64i64 (and store)
7397
7398 {3, MVT::v2i8, 4}, // interleave 3 x 2i8 into 6i8 (and store)
7399 {3, MVT::v4i8, 4}, // interleave 3 x 4i8 into 12i8 (and store)
7400 {3, MVT::v8i8, 6}, // interleave 3 x 8i8 into 24i8 (and store)
7401 {3, MVT::v16i8, 11}, // interleave 3 x 16i8 into 48i8 (and store)
7402 {3, MVT::v32i8, 13}, // interleave 3 x 32i8 into 96i8 (and store)
7403
7404 {3, MVT::v2i16, 4}, // interleave 3 x 2i16 into 6i16 (and store)
7405 {3, MVT::v4i16, 6}, // interleave 3 x 4i16 into 12i16 (and store)
7406 {3, MVT::v8i16, 12}, // interleave 3 x 8i16 into 24i16 (and store)
7407 {3, MVT::v16i16, 27}, // interleave 3 x 16i16 into 48i16 (and store)
7408 {3, MVT::v32i16, 54}, // interleave 3 x 32i16 into 96i16 (and store)
7409
7410 {3, MVT::v2i32, 4}, // interleave 3 x 2i32 into 6i32 (and store)
7411 {3, MVT::v4i32, 5}, // interleave 3 x 4i32 into 12i32 (and store)
7412 {3, MVT::v8i32, 11}, // interleave 3 x 8i32 into 24i32 (and store)
7413 {3, MVT::v16i32, 22}, // interleave 3 x 16i32 into 48i32 (and store)
7414 {3, MVT::v32i32, 48}, // interleave 3 x 32i32 into 96i32 (and store)
7415
7416 {3, MVT::v2i64, 4}, // interleave 3 x 2i64 into 6i64 (and store)
7417 {3, MVT::v4i64, 6}, // interleave 3 x 4i64 into 12i64 (and store)
7418 {3, MVT::v8i64, 12}, // interleave 3 x 8i64 into 24i64 (and store)
7419 {3, MVT::v16i64, 24}, // interleave 3 x 16i64 into 48i64 (and store)
7420
7421 {4, MVT::v2i8, 4}, // interleave 4 x 2i8 into 8i8 (and store)
7422 {4, MVT::v4i8, 4}, // interleave 4 x 4i8 into 16i8 (and store)
7423 {4, MVT::v8i8, 4}, // interleave 4 x 8i8 into 32i8 (and store)
7424 {4, MVT::v16i8, 8}, // interleave 4 x 16i8 into 64i8 (and store)
7425 {4, MVT::v32i8, 12}, // interleave 4 x 32i8 into 128i8 (and store)
7426
7427 {4, MVT::v2i16, 2}, // interleave 4 x 2i16 into 8i16 (and store)
7428 {4, MVT::v4i16, 6}, // interleave 4 x 4i16 into 16i16 (and store)
7429 {4, MVT::v8i16, 10}, // interleave 4 x 8i16 into 32i16 (and store)
7430 {4, MVT::v16i16, 32}, // interleave 4 x 16i16 into 64i16 (and store)
7431 {4, MVT::v32i16, 64}, // interleave 4 x 32i16 into 128i16 (and store)
7432
7433 {4, MVT::v2i32, 5}, // interleave 4 x 2i32 into 8i32 (and store)
7434 {4, MVT::v4i32, 6}, // interleave 4 x 4i32 into 16i32 (and store)
7435 {4, MVT::v8i32, 16}, // interleave 4 x 8i32 into 32i32 (and store)
7436 {4, MVT::v16i32, 32}, // interleave 4 x 16i32 into 64i32 (and store)
7437 {4, MVT::v32i32, 64}, // interleave 4 x 32i32 into 128i32 (and store)
7438
7439 {4, MVT::v2i64, 6}, // interleave 4 x 2i64 into 8i64 (and store)
7440 {4, MVT::v4i64, 8}, // interleave 4 x 4i64 into 16i64 (and store)
7441 {4, MVT::v8i64, 20}, // interleave 4 x 8i64 into 32i64 (and store)
7442 {4, MVT::v16i64, 40}, // interleave 4 x 16i64 into 64i64 (and store)
7443
7444 {6, MVT::v2i8, 7}, // interleave 6 x 2i8 into 12i8 (and store)
7445 {6, MVT::v4i8, 9}, // interleave 6 x 4i8 into 24i8 (and store)
7446 {6, MVT::v8i8, 16}, // interleave 6 x 8i8 into 48i8 (and store)
7447 {6, MVT::v16i8, 27}, // interleave 6 x 16i8 into 96i8 (and store)
7448 {6, MVT::v32i8, 90}, // interleave 6 x 32i8 into 192i8 (and store)
7449
7450 {6, MVT::v2i16, 10}, // interleave 6 x 2i16 into 12i16 (and store)
7451 {6, MVT::v4i16, 15}, // interleave 6 x 4i16 into 24i16 (and store)
7452 {6, MVT::v8i16, 21}, // interleave 6 x 8i16 into 48i16 (and store)
7453 {6, MVT::v16i16, 58}, // interleave 6 x 16i16 into 96i16 (and store)
7454 {6, MVT::v32i16, 90}, // interleave 6 x 32i16 into 192i16 (and store)
7455
7456 {6, MVT::v2i32, 9}, // interleave 6 x 2i32 into 12i32 (and store)
7457 {6, MVT::v4i32, 12}, // interleave 6 x 4i32 into 24i32 (and store)
7458 {6, MVT::v8i32, 33}, // interleave 6 x 8i32 into 48i32 (and store)
7459 {6, MVT::v16i32, 66}, // interleave 6 x 16i32 into 96i32 (and store)
7460
7461 {6, MVT::v2i64, 8}, // interleave 6 x 2i64 into 12i64 (and store)
7462 {6, MVT::v4i64, 15}, // interleave 6 x 4i64 into 24i64 (and store)
7463 {6, MVT::v8i64, 30}, // interleave 6 x 8i64 into 48i64 (and store)
7464 };
7465
7466 static const CostTblEntry SSE2InterleavedStoreTbl[] = {
7467 {2, MVT::v2i8, 1}, // interleave 2 x 2i8 into 4i8 (and store)
7468 {2, MVT::v4i8, 1}, // interleave 2 x 4i8 into 8i8 (and store)
7469 {2, MVT::v8i8, 1}, // interleave 2 x 8i8 into 16i8 (and store)
7470
7471 {2, MVT::v2i16, 1}, // interleave 2 x 2i16 into 4i16 (and store)
7472 {2, MVT::v4i16, 1}, // interleave 2 x 4i16 into 8i16 (and store)
7473
7474 {2, MVT::v2i32, 1}, // interleave 2 x 2i32 into 4i32 (and store)
7475 };
7476
7477 if (Opcode == Instruction::Load) {
7478 auto GetDiscountedCost = [Factor, NumMembers = Indices.size(),
7479 MemOpCosts](const CostTblEntry *Entry) {
7480 // NOTE: this is just an approximation!
7481 // It can over/under -estimate the cost!
7482 return MemOpCosts + divideCeil(NumMembers * Entry->Cost, Factor);
7483 };
7484
7485 if (ST->hasAVX2())
7486 if (const auto *Entry = CostTableLookup(AVX2InterleavedLoadTbl, Factor,
7487 ETy.getSimpleVT()))
7488 return GetDiscountedCost(Entry);
7489
7490 if (ST->hasSSSE3())
7491 if (const auto *Entry = CostTableLookup(SSSE3InterleavedLoadTbl, Factor,
7492 ETy.getSimpleVT()))
7493 return GetDiscountedCost(Entry);
7494
7495 if (ST->hasSSE2())
7496 if (const auto *Entry = CostTableLookup(SSE2InterleavedLoadTbl, Factor,
7497 ETy.getSimpleVT()))
7498 return GetDiscountedCost(Entry);
7499 } else {
7500 assert(Opcode == Instruction::Store &&
7501 "Expected Store Instruction at this point");
7502 assert((!Indices.size() || Indices.size() == Factor) &&
7503 "Interleaved store only supports fully-interleaved groups.");
7504 if (ST->hasAVX2())
7505 if (const auto *Entry = CostTableLookup(AVX2InterleavedStoreTbl, Factor,
7506 ETy.getSimpleVT()))
7507 return MemOpCosts + Entry->Cost;
7508
7509 if (ST->hasSSE2())
7510 if (const auto *Entry = CostTableLookup(SSE2InterleavedStoreTbl, Factor,
7511 ETy.getSimpleVT()))
7512 return MemOpCosts + Entry->Cost;
7513 }
7514
7515 return BaseT::getInterleavedMemoryOpCost(Opcode, VecTy, Factor, Indices,
7516 Alignment, AddressSpace, CostKind,
7517 UseMaskForCond, UseMaskForGaps);
7518}
7519
7521 StackOffset BaseOffset,
7522 bool HasBaseReg, int64_t Scale,
7523 unsigned AddrSpace) const {
7524 // Scaling factors are not free at all.
7525 // An indexed folded instruction, i.e., inst (reg1, reg2, scale),
7526 // will take 2 allocations in the out of order engine instead of 1
7527 // for plain addressing mode, i.e. inst (reg1).
7528 // E.g.,
7529 // vaddps (%rsi,%rdx), %ymm0, %ymm1
7530 // Requires two allocations (one for the load, one for the computation)
7531 // whereas:
7532 // vaddps (%rsi), %ymm0, %ymm1
7533 // Requires just 1 allocation, i.e., freeing allocations for other operations
7534 // and having less micro operations to execute.
7535 //
7536 // For some X86 architectures, this is even worse because for instance for
7537 // stores, the complex addressing mode forces the instruction to use the
7538 // "load" ports instead of the dedicated "store" port.
7539 // E.g., on Haswell:
7540 // vmovaps %ymm1, (%r8, %rdi) can use port 2 or 3.
7541 // vmovaps %ymm1, (%r8) can use port 2, 3, or 7.
7543 AM.BaseGV = BaseGV;
7544 AM.BaseOffs = BaseOffset.getFixed();
7545 AM.HasBaseReg = HasBaseReg;
7546 AM.Scale = Scale;
7547 AM.ScalableOffset = BaseOffset.getScalable();
7548 if (getTLI()->isLegalAddressingMode(DL, AM, Ty, AddrSpace))
7549 // Scale represents reg2 * scale, thus account for 1
7550 // as soon as we use a second register.
7551 return AM.Scale != 0;
7553}
7554
7556 // TODO: Hook MispredictPenalty of SchedMachineModel into this.
7557 return 14;
7558}
7559
7561 unsigned Bits = Ty->getScalarSizeInBits();
7562
7563 // XOP has v16i8/v8i16/v4i32/v2i64 variable vector shifts.
7564 // Splitting for v32i8/v16i16 on XOP+AVX2 targets is still preferred.
7565 if (ST->hasXOP() && (Bits == 8 || Bits == 16 || Bits == 32 || Bits == 64))
7566 return false;
7567
7568 // AVX2 has vpsllv[dq] instructions (and other shifts) that make variable
7569 // shifts just as cheap as scalar ones.
7570 if (ST->hasAVX2() && (Bits == 32 || Bits == 64))
7571 return false;
7572
7573 // AVX512BW has shifts such as vpsllvw.
7574 if (ST->hasBWI() && Bits == 16)
7575 return false;
7576
7577 // Otherwise, it's significantly cheaper to shift by a scalar amount than by a
7578 // fully general vector.
7579 return true;
7580}
7581
7582unsigned X86TTIImpl::getStoreMinimumVF(unsigned VF, Type *ScalarMemTy,
7583 Type *ScalarValTy, Align Alignment,
7584 unsigned AddrSpace) const {
7585 if (ST->hasF16C() && ScalarMemTy->isHalfTy()) {
7586 return 4;
7587 }
7588 return BaseT::getStoreMinimumVF(VF, ScalarMemTy, ScalarValTy, Alignment,
7589 AddrSpace);
7590}
7591
7593 SmallVectorImpl<Use *> &Ops) const {
7594 using namespace llvm::PatternMatch;
7595
7596 if (I->getOpcode() == Instruction::And &&
7597 (ST->hasBMI() || (I->getType()->isVectorTy() && ST->hasSSE2()))) {
7598 for (auto &Op : I->operands()) {
7599 // (and X, (not Y)) -> (andn X, Y)
7600 if (match(Op.get(), m_Not(m_Value())) && !I->getType()->isIntegerTy(8)) {
7601 Ops.push_back(&Op);
7602 return true;
7603 }
7604 // (and X, (splat (not Y))) -> (andn X, (splat Y))
7605 if (match(Op.get(),
7607 m_Value(), m_ZeroMask()))) {
7608 Use &InsertElt = cast<Instruction>(Op)->getOperandUse(0);
7609 Use &Not = cast<Instruction>(InsertElt)->getOperandUse(1);
7610 Ops.push_back(&Not);
7611 Ops.push_back(&InsertElt);
7612 Ops.push_back(&Op);
7613 return true;
7614 }
7615 }
7616 }
7617
7618 FixedVectorType *VTy = dyn_cast<FixedVectorType>(I->getType());
7619 if (!VTy)
7620 return false;
7621
7622 if (I->getOpcode() == Instruction::Mul &&
7623 VTy->getElementType()->isIntegerTy(64)) {
7624 for (auto &Op : I->operands()) {
7625 // Make sure we are not already sinking this operand
7626 if (any_of(Ops, [&](Use *U) { return U->get() == Op; }))
7627 continue;
7628
7629 // Look for PMULDQ pattern where the input is a sext_inreg from vXi32 or
7630 // the PMULUDQ pattern where the input is a zext_inreg from vXi32.
7631 if (ST->hasSSE41() &&
7632 match(Op.get(), m_AShr(m_Shl(m_Value(), m_SpecificInt(32)),
7633 m_SpecificInt(32)))) {
7634 Ops.push_back(&cast<Instruction>(Op)->getOperandUse(0));
7635 Ops.push_back(&Op);
7636 } else if (ST->hasSSE2() &&
7637 match(Op.get(),
7638 m_And(m_Value(), m_SpecificInt(UINT64_C(0xffffffff))))) {
7639 Ops.push_back(&Op);
7640 }
7641 }
7642
7643 return !Ops.empty();
7644 }
7645
7646 // A uniform shift amount in a vector shift or funnel shift may be much
7647 // cheaper than a generic variable vector shift, so make that pattern visible
7648 // to SDAG by sinking the shuffle instruction next to the shift.
7649 int ShiftAmountOpNum = -1;
7650 if (I->isShift())
7651 ShiftAmountOpNum = 1;
7652 else if (auto *II = dyn_cast<IntrinsicInst>(I)) {
7653 if (II->getIntrinsicID() == Intrinsic::fshl ||
7654 II->getIntrinsicID() == Intrinsic::fshr)
7655 ShiftAmountOpNum = 2;
7656 }
7657
7658 if (ShiftAmountOpNum == -1)
7659 return false;
7660
7661 auto *Shuf = dyn_cast<ShuffleVectorInst>(I->getOperand(ShiftAmountOpNum));
7662 if (Shuf && getSplatIndex(Shuf->getShuffleMask()) >= 0 &&
7663 isVectorShiftByScalarCheap(I->getType())) {
7664 Ops.push_back(&I->getOperandUse(ShiftAmountOpNum));
7665 return true;
7666 }
7667
7668 return false;
7669}
7670
7672 bool HasEGPR = ST->hasEGPR();
7673 const TargetMachine &TM = getTLI()->getTargetMachine();
7674
7675 for (User *U : F.users()) {
7677 if (!CB || CB->getCalledOperand() != &F)
7678 continue;
7679 Function *CallerFunc = CB->getFunction();
7680 if (TM.getSubtarget<X86Subtarget>(*CallerFunc).hasEGPR() != HasEGPR)
7681 return false;
7682 }
7683
7684 return true;
7685}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Expand Atomic instructions
This file provides a helper that implements much of the TTI interface in terms of the target-independ...
#define X(NUM, ENUM, NAME)
Definition ELF.h:856
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static cl::opt< OutputCostKind > CostKind("cost-kind", cl::desc("Target cost kind"), cl::init(OutputCostKind::RecipThroughput), cl::values(clEnumValN(OutputCostKind::RecipThroughput, "throughput", "Reciprocal throughput"), clEnumValN(OutputCostKind::Latency, "latency", "Instruction latency"), clEnumValN(OutputCostKind::CodeSize, "code-size", "Code size"), clEnumValN(OutputCostKind::SizeAndLatency, "size-latency", "Code size and latency"), clEnumValN(OutputCostKind::All, "all", "Print all cost kinds")))
Cost tables and simple lookup functions.
Hexagon Common GEP
iv users
Definition IVUsers.cpp:48
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static LVOptions Options
Definition LVOptions.cpp:25
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
uint64_t IntrinsicInst * II
#define P(N)
This file implements the SmallBitVector class.
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
This file describes how to lower LLVM code to machine code.
This pass exposes codegen information to IR-level passes.
static unsigned getBitWidth(Type *Ty, const DataLayout &DL)
Returns the bitwidth of the given scalar or pointer type.
CostTblEntryT< CostKindCosts > CostKindTblEntry
static bool isLegalMaskedLoadStore(Type *ScalarTy, const X86Subtarget *ST)
TypeConversionCostTblEntryT< CostKindCosts > TypeConversionCostKindTblEntry
This file a TargetTransformInfoImplBase conforming object specific to the X86 target machine.
Class for arbitrary precision integers.
Definition APInt.h:78
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
Definition APInt.h:235
LLVM_ABI APInt zext(unsigned width) const
Zero extend to a new width.
Definition APInt.cpp:1055
unsigned popcount() const
Count the number of bits set.
Definition APInt.h:1695
void setBit(unsigned BitPosition)
Set the given bit to 1 whose position is given as "bitPosition".
Definition APInt.h:1355
bool isAllOnes() const
Determine if all bits are set. This is true for zero-width values.
Definition APInt.h:372
static APInt getBitsSet(unsigned numBits, unsigned loBit, unsigned hiBit)
Get a value with a block of bits set.
Definition APInt.h:259
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
Definition APInt.h:381
unsigned getBitWidth() const
Return the number of bits in the APInt.
Definition APInt.h:1513
LLVM_ABI APInt sextOrTrunc(unsigned width) const
Sign extend or truncate to width.
Definition APInt.cpp:1084
APInt ashr(unsigned ShiftAmt) const
Arithmetic right-shift function.
Definition APInt.h:834
static APInt getZero(unsigned numBits)
Get the '0' value for the specified bit-width.
Definition APInt.h:201
LLVM_ABI APInt extractBits(unsigned numBits, unsigned bitPosition) const
Return an APInt with the extracted bits [bitPosition,bitPosition+numBits).
Definition APInt.cpp:483
int64_t getSExtValue() const
Get sign extended value.
Definition APInt.h:1587
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
size_t size() const
Get the array size.
Definition ArrayRef.h:141
bool empty() const
Check if the array is empty.
Definition ArrayRef.h:136
InstructionCost getInterleavedMemoryOpCost(unsigned Opcode, Type *VecTy, unsigned Factor, ArrayRef< unsigned > Indices, Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind, bool UseMaskForCond=false, bool UseMaskForGaps=false) const override
InstructionCost getArithmeticInstrCost(unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind, TTI::OperandValueInfo Opd1Info={TTI::OK_AnyValue, TTI::OP_None}, TTI::OperandValueInfo Opd2Info={TTI::OK_AnyValue, TTI::OP_None}, ArrayRef< const Value * > Args={}, const Instruction *CxtI=nullptr) const override
InstructionCost getMinMaxReductionCost(Intrinsic::ID IID, VectorType *Ty, FastMathFlags FMF, TTI::TargetCostKind CostKind) const override
InstructionCost getGEPCost(Type *PointeeType, const Value *Ptr, ArrayRef< const Value * > Operands, Type *AccessType, TTI::TargetCostKind CostKind) const override
TTI::ShuffleKind improveShuffleKindFromMask(TTI::ShuffleKind Kind, ArrayRef< int > Mask, VectorType *SrcTy, int &Index, VectorType *&SubTy) const
bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset, bool HasBaseReg, int64_t Scale, unsigned AddrSpace, Instruction *I=nullptr, int64_t ScalableOffset=0) const override
InstructionCost getShuffleCost(TTI::ShuffleKind Kind, VectorType *DstTy, VectorType *SrcTy, ArrayRef< int > Mask, TTI::TargetCostKind CostKind, int Index, VectorType *SubTp, ArrayRef< const Value * > Args={}, const Instruction *CxtI=nullptr) const override
unsigned getStoreMinimumVF(unsigned VF, Type *ScalarMemTy, Type *ScalarValTy, Align Alignment, unsigned AddrSpace) const override
InstructionCost getScalarizationOverhead(VectorType *InTy, const APInt &DemandedElts, bool Insert, bool Extract, TTI::TargetCostKind CostKind, bool ForPoisonSrc=true, ArrayRef< Value * > VL={}, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const override
InstructionCost getArithmeticReductionCost(unsigned Opcode, VectorType *Ty, std::optional< FastMathFlags > FMF, TTI::TargetCostKind CostKind) const override
InstructionCost getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy, CmpInst::Predicate VecPred, TTI::TargetCostKind CostKind, TTI::OperandValueInfo Op1Info={TTI::OK_AnyValue, TTI::OP_None}, TTI::OperandValueInfo Op2Info={TTI::OK_AnyValue, TTI::OP_None}, const Instruction *I=nullptr) const override
InstructionCost getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src, TTI::CastContextHint CCH, TTI::TargetCostKind CostKind, const Instruction *I=nullptr) const override
std::pair< InstructionCost, MVT > getTypeLegalizationCost(Type *Ty) const
InstructionCost getReplicationShuffleCost(Type *EltTy, int ReplicationFactor, int VF, const APInt &DemandedDstElts, TTI::TargetCostKind CostKind) const override
InstructionCost getVectorInstrCost(unsigned Opcode, Type *Val, TTI::TargetCostKind CostKind, unsigned Index, const Value *Op0, const Value *Op1, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const override
InstructionCost getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA, TTI::TargetCostKind CostKind) const override
InstructionCost getAddressComputationCost(Type *PtrTy, ScalarEvolution *, const SCEV *, TTI::TargetCostKind) const override
InstructionCost getMemIntrinsicInstrCost(const MemIntrinsicCostAttributes &MICA, TTI::TargetCostKind CostKind) const override
InstructionCost getMemoryOpCost(unsigned Opcode, Type *Src, Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind, TTI::OperandValueInfo OpInfo={TTI::OK_AnyValue, TTI::OP_None}, const Instruction *I=nullptr) const override
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Value * getCalledOperand() const
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition InstrTypes.h:740
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
Definition InstrTypes.h:743
@ ICMP_SLE
signed less or equal
Definition InstrTypes.h:770
@ ICMP_UGE
unsigned greater or equal
Definition InstrTypes.h:764
@ ICMP_UGT
unsigned greater than
Definition InstrTypes.h:763
@ FCMP_ONE
0 1 1 0 True if ordered and operands are unequal
Definition InstrTypes.h:748
@ FCMP_UEQ
1 0 0 1 True if unordered or equal
Definition InstrTypes.h:751
@ ICMP_ULT
unsigned less than
Definition InstrTypes.h:765
@ ICMP_NE
not equal
Definition InstrTypes.h:762
@ ICMP_SGE
signed greater or equal
Definition InstrTypes.h:768
@ ICMP_ULE
unsigned less or equal
Definition InstrTypes.h:766
@ FCMP_UNO
1 0 0 0 True if unordered: isnan(X) | isnan(Y)
Definition InstrTypes.h:750
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
constexpr bool isScalar() const
Exactly one element.
Definition TypeSize.h:320
Convenience struct for specifying and reasoning about fast-math flags.
Definition FMF.h:23
Container class for subtarget features.
Class to represent fixed width SIMD vectors.
unsigned getNumElements() const
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
Definition Type.cpp:867
static InstructionCost getInvalid(CostType Val=0)
CostType getValue() const
This function is intended to be used as sparingly as possible, since the class provides the full rang...
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
Definition Type.cpp:348
const SmallVectorImpl< Type * > & getArgTypes() const
const SmallVectorImpl< const Value * > & getArgs() const
const IntrinsicInst * getInst() const
A wrapper class for inspecting calls to intrinsic functions.
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
Machine Value Type.
bool is128BitVector() const
Return true if this is a 128-bit vector type.
uint64_t getScalarSizeInBits() const
unsigned getVectorNumElements() const
bool isVector() const
Return true if this is a vector value type.
bool isInteger() const
Return true if this is an integer or a vector integer type.
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
bool isScalarInteger() const
Return true if this is an integer, not including vectors.
static MVT getVectorVT(MVT VT, unsigned NumElements)
MVT getVectorElementType() const
MVT getScalarType() const
If this is a vector, return the element type, otherwise return this.
Information for memory intrinsic cost model.
This class represents an analyzed expression in the program.
The main scalar evolution driver.
static LLVM_ABI bool isIdentityMask(ArrayRef< int > Mask, int NumSrcElts)
Return true if this shuffle mask chooses elements from exactly one source vector without lane crossin...
This is a 'bitvector' (really, a variable-sized bit array), optimized for the case when the array is ...
bool test(unsigned Idx) const
Returns true if bit Idx is set.
size_type size() const
Returns the number of bits in this bitvector.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StackOffset holds a fixed and a scalable offset in bytes.
Definition TypeSize.h:30
static StackOffset getScalable(int64_t Scalable)
Definition TypeSize.h:40
static StackOffset getFixed(int64_t Fixed)
Definition TypeSize.h:39
virtual MVT getRegisterTypeForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const
Certain combinations of ABIs, Targets and features require that types are legal for some operations a...
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
Primary interface to the complete machine description for the target machine.
const STC & getSubtarget(const Function &F) const
This method returns a pointer to the specified type of TargetSubtargetInfo.
virtual const TargetSubtargetInfo * getSubtargetImpl(const Function &) const
Virtual method implemented by subclasses that returns a reference to that target's TargetSubtargetInf...
virtual const TargetLowering * getTargetLowering() const
virtual InstructionCost getPointersChainCost(ArrayRef< const Value * > Ptrs, const Value *Base, const TTI::PointersChainInfo &Info, Type *AccessTy, TTI::TargetCostKind CostKind) const
bool isStridedAccess(const SCEV *Ptr) const
unsigned minRequiredElementSize(const Value *Val, bool &isSigned) const
const SCEVConstant * getConstantStrideStep(ScalarEvolution *SE, const SCEV *Ptr) const
virtual bool isExpensiveToSpeculativelyExecute(const Instruction *I) const
MaskKind
Some targets only support masked load/store with a constant mask.
TargetCostKind
The kind of cost model.
@ TCK_RecipThroughput
Reciprocal throughput.
@ TCK_CodeSize
Instruction code size.
@ TCK_SizeAndLatency
The weighted sum of size and latency.
@ TCK_Latency
The latency of instruction.
static bool requiresOrderedReduction(std::optional< FastMathFlags > FMF)
A helper function to determine the type of reduction algorithm used for a given Opcode and set of Fas...
PopcntSupportKind
Flags indicating the kind of support for population count.
llvm::VectorInstrContext VectorInstrContext
@ TCC_Free
Expected to fold away in lowering.
@ TCC_Basic
The cost of a typical 'add' instruction.
ShuffleKind
The various kinds of shuffle patterns for vector queries.
@ SK_InsertSubvector
InsertSubvector. Index indicates start offset.
@ SK_Select
Selects elements from the corresponding lane of either source operand.
@ SK_PermuteSingleSrc
Shuffle elements of single source vector with any shuffle mask.
@ SK_Transpose
Transpose two vectors.
@ SK_Splice
Concatenates elements from the first input vector with elements of the second input vector.
@ SK_Broadcast
Broadcast element 0 to all other elements.
@ SK_PermuteTwoSrc
Merge elements from two source vectors into one with any shuffle mask.
@ SK_Reverse
Reverse the order of the vector.
@ SK_ExtractSubvector
ExtractSubvector Index indicates start offset.
CastContextHint
Represents a hint about the context in which a cast is used.
@ None
The cast is not used with a load/store of any kind.
CacheLevel
The possible cache levels.
static constexpr TypeSize getFixed(ScalarTy ExactSize)
Definition TypeSize.h:343
static constexpr TypeSize getScalable(ScalarTy MinimumSize)
Definition TypeSize.h:346
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
Definition Type.cpp:310
LLVM_ABI unsigned getIntegerBitWidth() const
bool isVectorTy() const
True if this is an instance of VectorType.
Definition Type.h:288
LLVM_ABI bool isScalableTy(SmallPtrSetImpl< const Type * > &Visited) const
Return true if this is a type whose size is a known multiple of vscale.
Definition Type.cpp:61
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
Definition Type.cpp:309
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
Definition Type.h:263
bool isPointerTy() const
True if this is an instance of PointerType.
Definition Type.h:282
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
Definition Type.h:155
bool isBFloatTy() const
Return true if this is 'bfloat', a 16-bit bfloat type.
Definition Type.h:147
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
Definition Type.cpp:307
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Definition Type.h:368
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
Definition Type.cpp:197
LLVM_ABI Type * getWithNewBitWidth(unsigned NewBitWidth) const
Given an integer or vector type, change the lane bitwidth to NewBitwidth, whilst keeping the old numb...
bool isHalfTy() const
Return true if this is 'half', a 16-bit IEEE fp type.
Definition Type.h:144
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
Definition Type.h:130
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
Definition Type.cpp:232
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
Definition Type.h:158
static LLVM_ABI IntegerType * getInt1Ty(LLVMContext &C)
Definition Type.cpp:306
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
Definition Type.h:186
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:257
static LLVM_ABI IntegerType * getIntNTy(LLVMContext &C, unsigned N)
Definition Type.cpp:313
static LLVM_ABI Type * getDoubleTy(LLVMContext &C)
Definition Type.cpp:287
bool isFPOrFPVectorTy() const
Return true if this is a FP type or a vector of FP.
Definition Type.h:227
Type * getContainedType(unsigned i) const
This method is used to implement the type iterator (defined at the end of the file).
Definition Type.h:397
static LLVM_ABI Type * getFloatTy(LLVMContext &C)
Definition Type.cpp:286
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:255
Base class of all SIMD vector types.
static VectorType * getExtendedElementVectorType(VectorType *VTy)
This static method is like getInteger except that the element types are twice as wide as the elements...
ElementCount getElementCount() const
Return an ElementCount instance to represent the (possibly scalable) number of elements in the vector...
static VectorType * getDoubleElementsVectorType(VectorType *VTy)
This static method returns a VectorType with twice as many elements as the input type and the same el...
Type * getElementType() const
bool useAVX512Regs() const
bool hasAVX512() const
bool hasAVX2() const
bool useFastCCForInternalCall(Function &F) const override
InstructionCost getReplicationShuffleCost(Type *EltTy, int ReplicationFactor, int VF, const APInt &DemandedDstElts, TTI::TargetCostKind CostKind) const override
bool isLegalNTLoad(Type *DataType, Align Alignment) const override
std::optional< unsigned > getCacheAssociativity(TargetTransformInfo::CacheLevel Level) const override
InstructionCost getMinMaxReductionCost(Intrinsic::ID IID, VectorType *Ty, FastMathFlags FMF, TTI::TargetCostKind CostKind) const override
Try to calculate op costs for min/max reduction operations.
bool isLegalBroadcastLoad(Type *ElementTy, ElementCount NumElements) const override
unsigned getRegisterClassForType(bool Vector, Type *Ty) const override
InstructionCost getMemIntrinsicInstrCost(const MemIntrinsicCostAttributes &MICA, TTI::TargetCostKind CostKind) const override
Get memory intrinsic cost based on arguments.
unsigned getMaxInterleaveFactor(ElementCount VF, bool HasUnorderedReductions) const override
InstructionCost getShuffleCost(TTI::ShuffleKind Kind, VectorType *DstTy, VectorType *SrcTy, ArrayRef< int > Mask, TTI::TargetCostKind CostKind, int Index, VectorType *SubTp, ArrayRef< const Value * > Args={}, const Instruction *CxtI=nullptr) const override
bool isLegalNTStore(Type *DataType, Align Alignment) const override
InstructionCost getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src, TTI::CastContextHint CCH, TTI::TargetCostKind CostKind, const Instruction *I=nullptr) const override
InstructionCost getInterleavedMemoryOpCostAVX512(unsigned Opcode, FixedVectorType *VecTy, unsigned Factor, ArrayRef< unsigned > Indices, Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind, bool UseMaskForCond=false, bool UseMaskForGaps=false) const
bool isLegalAltInstr(VectorType *VecTy, unsigned Opcode0, unsigned Opcode1, const SmallBitVector &OpcodeMask) const override
TypeSize getRegisterBitWidth(TargetTransformInfo::RegisterKind K) const override
bool isVectorShiftByScalarCheap(Type *Ty) const override
bool isLegalMaskedGather(Type *DataType, Align Alignment) const override
bool shouldExpandReduction(const IntrinsicInst *II) const override
InstructionCost getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, StackOffset BaseOffset, bool HasBaseReg, int64_t Scale, unsigned AddrSpace) const override
Return the cost of the scaling factor used in the addressing mode represented by AM for this target,...
unsigned getAtomicMemIntrinsicMaxElementSize() const override
InstructionCost getPointersChainCost(ArrayRef< const Value * > Ptrs, const Value *Base, const TTI::PointersChainInfo &Info, Type *AccessTy, TTI::TargetCostKind CostKind) const override
bool forceScalarizeMaskedGather(VectorType *VTy, Align Alignment) const override
InstructionCost getBranchMispredictPenalty() const override
bool isExpensiveToSpeculativelyExecute(const Instruction *I) const override
bool hasConditionalLoadStoreForType(Type *Ty, bool IsStore) const override
bool isLegalMaskedStore(Type *DataType, Align Alignment, unsigned AddressSpace, TTI::MaskKind MaskKind=TTI::MaskKind::VariableOrConstantMask) const override
std::optional< unsigned > getCacheSize(TargetTransformInfo::CacheLevel Level) const override
InstructionCost getArithmeticInstrCost(unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind, TTI::OperandValueInfo Op1Info={TTI::OK_AnyValue, TTI::OP_None}, TTI::OperandValueInfo Op2Info={TTI::OK_AnyValue, TTI::OP_None}, ArrayRef< const Value * > Args={}, const Instruction *CxtI=nullptr) const override
bool isLegalMaskedGatherScatter(Type *DataType, Align Alignment) const
bool isLegalMaskedLoad(Type *DataType, Align Alignment, unsigned AddressSpace, TTI::MaskKind MaskKind=TTI::MaskKind::VariableOrConstantMask) const override
bool enableInterleavedAccessVectorization() const override
unsigned getLoadStoreVecRegBitWidth(unsigned AS) const override
unsigned getNumberOfRegisters(unsigned ClassID) const override
InstructionCost getVectorInstrCost(unsigned Opcode, Type *Val, TTI::TargetCostKind CostKind, unsigned Index, const Value *Op0, const Value *Op1, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const override
bool isLegalMaskedScatter(Type *DataType, Align Alignment) const override
unsigned getStoreMinimumVF(unsigned VF, Type *ScalarMemTy, Type *ScalarValTy, Align Alignment, unsigned AddrSpace) const override
bool hasDivRemOp(Type *DataType, bool IsSigned) const override
bool isLegalMaskedCompressStore(Type *DataType, Align Alignment) const override
InstructionCost getIntImmCostIntrin(Intrinsic::ID IID, unsigned Idx, const APInt &Imm, Type *Ty, TTI::TargetCostKind CostKind) const override
bool supportsEfficientVectorElementLoadStore() const override
InstructionCost getIntImmCostInst(unsigned Opcode, unsigned Idx, const APInt &Imm, Type *Ty, TTI::TargetCostKind CostKind, Instruction *Inst=nullptr) const override
bool isLegalMaskedExpandLoad(Type *DataType, Align Alignment) const override
TTI::PopcntSupportKind getPopcntSupport(unsigned TyWidth) const override
bool isFCmpOrdCheaperThanFCmpZero(Type *Ty) const override
TTI::MemCmpExpansionOptions enableMemCmpExpansion(bool OptSize, bool IsZeroCmp) const override
InstructionCost getIntImmCost(int64_t) const
Calculate the cost of materializing a 64-bit value.
InstructionCost getMinMaxCost(Intrinsic::ID IID, Type *Ty, TTI::TargetCostKind CostKind, FastMathFlags FMF) const
InstructionCost getCFInstrCost(unsigned Opcode, TTI::TargetCostKind CostKind, const Instruction *I=nullptr) const override
InstructionCost getInterleavedMemoryOpCost(unsigned Opcode, Type *VecTy, unsigned Factor, ArrayRef< unsigned > Indices, Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind, bool UseMaskForCond=false, bool UseMaskForGaps=false) const override
bool canMacroFuseCmp() const override
bool areInlineCompatible(const Function *Caller, const Function *Callee) const override
InstructionCost getMaskedMemoryOpCost(const MemIntrinsicCostAttributes &MICA, TTI::TargetCostKind CostKind) const
bool prefersVectorizedAddressing() const override
bool areTypesABICompatible(const Function *Caller, const Function *Callee, ArrayRef< Type * > Type) const override
InstructionCost getAltInstrCost(VectorType *VecTy, unsigned Opcode0, unsigned Opcode1, const SmallBitVector &OpcodeMask, TTI::TargetCostKind CostKind) const override
bool forceScalarizeMaskedScatter(VectorType *VTy, Align Alignment) const override
InstructionCost getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA, TTI::TargetCostKind CostKind) const override
Get intrinsic cost based on arguments.
bool isProfitableToSinkOperands(Instruction *I, SmallVectorImpl< Use * > &Ops) const override
InstructionCost getScalarizationOverhead(VectorType *Ty, const APInt &DemandedElts, bool Insert, bool Extract, TTI::TargetCostKind CostKind, bool ForPoisonSrc=true, ArrayRef< Value * > VL={}, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const override
Estimate the overhead of scalarizing an instruction.
InstructionCost getArithmeticReductionCost(unsigned Opcode, VectorType *Ty, std::optional< FastMathFlags > FMF, TTI::TargetCostKind CostKind) const override
InstructionCost getGatherScatterOpCost(const MemIntrinsicCostAttributes &MICA, TTI::TargetCostKind CostKind) const
Calculate the cost of Gather / Scatter operation.
InstructionCost getMemoryOpCost(unsigned Opcode, Type *Src, Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind, TTI::OperandValueInfo OpInfo={TTI::OK_AnyValue, TTI::OP_None}, const Instruction *I=nullptr) const override
InstructionCost getAddressComputationCost(Type *PtrTy, ScalarEvolution *SE, const SCEV *Ptr, TTI::TargetCostKind CostKind) const override
InstructionCost getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy, CmpInst::Predicate VecPred, TTI::TargetCostKind CostKind, TTI::OperandValueInfo Op1Info={TTI::OK_AnyValue, TTI::OP_None}, TTI::OperandValueInfo Op2Info={TTI::OK_AnyValue, TTI::OP_None}, const Instruction *I=nullptr) const override
bool isLSRCostLess(const TargetTransformInfo::LSRCost &C1, const TargetTransformInfo::LSRCost &C2) const override
constexpr ScalarTy getFixedValue() const
Definition TypeSize.h:200
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
Definition TypeSize.h:168
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
Definition TypeSize.h:165
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
LLVM_ABI APInt ScaleBitMask(const APInt &A, unsigned NewBitWidth, bool MatchAllBits=false)
Splat/Merge neighboring bits to widen/narrow the bitmask represented by.
Definition APInt.cpp:3040
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
ISD namespace - This namespace contains an enum which represents all of the SelectionDAG node types a...
Definition ISDOpcodes.h:24
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
Definition ISDOpcodes.h:41
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
Definition ISDOpcodes.h:829
@ DELETED_NODE
DELETED_NODE - This is an illegal value that is used to catch errors.
Definition ISDOpcodes.h:45
@ BSWAP
Byte Swap and Counting operators.
Definition ISDOpcodes.h:789
@ ADD
Simple integer binary arithmetic operators.
Definition ISDOpcodes.h:264
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
Definition ISDOpcodes.h:890
@ FADD
Simple binary floating point operators.
Definition ISDOpcodes.h:417
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
Definition ISDOpcodes.h:749
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
Definition ISDOpcodes.h:280
@ CLMUL
Carry-less multiplication operations.
Definition ISDOpcodes.h:780
@ CTLZ_ZERO_POISON
Definition ISDOpcodes.h:798
@ SIGN_EXTEND
Conversion operators.
Definition ISDOpcodes.h:854
@ FNEG
Perform various unary floating-point operations inspired by libm.
@ SSUBSAT
RESULT = [US]SUBSAT(LHS, RHS) - Perform saturation subtraction on 2 integers with the same bit width ...
Definition ISDOpcodes.h:374
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
Definition ISDOpcodes.h:806
@ SADDO
RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
Definition ISDOpcodes.h:348
@ SHL
Shift and rotation operations.
Definition ISDOpcodes.h:771
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
Definition ISDOpcodes.h:578
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
Definition ISDOpcodes.h:860
@ FMINNUM
FMINNUM/FMAXNUM - Perform floating-point minimum maximum on two values, following IEEE-754 definition...
@ SMULO
Same for multiplication.
Definition ISDOpcodes.h:356
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
Definition ISDOpcodes.h:729
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
Definition ISDOpcodes.h:988
@ FMINIMUM
FMINIMUM/FMAXIMUM - NaN-propagating minimum/maximum that also treat -0.0 as less than 0....
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
Definition ISDOpcodes.h:936
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition ISDOpcodes.h:741
@ CTTZ_ZERO_POISON
Bit counting operators with a poisoned result for zero inputs.
Definition ISDOpcodes.h:797
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
Definition ISDOpcodes.h:969
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
Definition ISDOpcodes.h:866
@ SADDSAT
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
Definition ISDOpcodes.h:365
SpecificConstantMatch m_ZeroInt()
Convenience matchers for specific integer values.
BinaryOp_match< SrcTy, SpecificConstantMatch, TargetOpcode::G_XOR, true > m_Not(const SrcTy &&Src)
Matches a register not-ed by a G_XOR.
OneUse_match< SubPat > m_OneUse(const SubPat &SP)
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::AShr > m_AShr(const LHS &L, const RHS &R)
ap_match< APInt > m_APIntAllowPoison(const APInt *&Res)
Match APInt while allowing poison in splat vector constants.
specific_intval< false > m_SpecificInt(const APInt &V)
Match a specific integer value or vector with all elements equal to the value.
bool match(Val *V, const Pattern &P)
auto m_Value()
Match an arbitrary value and ignore it.
TwoOps_match< V1_t, V2_t, Instruction::ShuffleVector > m_Shuffle(const V1_t &v1, const V2_t &v2)
Matches ShuffleVectorInst independently of mask value.
OneOps_match< OpTy, Instruction::Load > m_Load(const OpTy &Op)
Matches LoadInst.
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
ThreeOps_match< Val_t, Elt_t, Idx_t, Instruction::InsertElement > m_InsertElt(const Val_t &Val, const Elt_t &Elt, const Idx_t &Idx)
Matches InsertElementInst.
This is an optimization pass for GlobalISel generic memory operations.
constexpr auto not_equal_to(T &&Arg)
Functor variant of std::not_equal_to that can be used as a UnaryPredicate in functional algorithms li...
Definition STLExtras.h:2180
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1739
const CostTblEntryT< CostType > * CostTableLookup(ArrayRef< CostTblEntryT< CostType > > Tbl, int ISD, MVT Ty)
Find in cost table.
Definition CostTable.h:36
InstructionCost Cost
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Definition MathExtras.h:166
@ Known
Known to have no common set bits.
LLVM_ABI void ComputeValueVTs(const TargetLowering &TLI, const DataLayout &DL, Type *Ty, SmallVectorImpl< EVT > &ValueVTs, SmallVectorImpl< EVT > *MemVTs=nullptr, SmallVectorImpl< TypeSize > *Offsets=nullptr, TypeSize StartingOffset=TypeSize::getZero())
ComputeValueVTs - Given an LLVM IR type, compute a sequence of EVTs that represent all the individual...
Definition Analysis.cpp:119
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
Definition STLExtras.h:2554
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
constexpr T alignDown(U Value, V Align, W Skew=0)
Returns the largest unsigned integer less than or equal to Value and is Skew mod Align.
Definition MathExtras.h:547
LLVM_ABI Value * getSplatValue(const Value *V)
Get splat value if the input is a splat vector or return nullptr.
bool isa_and_nonnull(const Y &Val)
Definition Casting.h:676
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
uint64_t PowerOf2Ceil(uint64_t A)
Returns the power of two which is greater than or equal to the given value.
Definition MathExtras.h:386
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1746
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition MathExtras.h:280
LLVM_ABI void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true, unsigned Depth=0)
Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition Alignment.h:144
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
constexpr int PoisonMaskElem
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
Definition MathExtras.h:395
DWARFExpression::Operation Op
OutputIt copy(R &&Range, OutputIt Out)
Definition STLExtras.h:1885
CostTblEntryT< uint16_t > CostTblEntry
Definition CostTable.h:31
auto count_if(R &&Range, UnaryPredicate P)
Wrapper function around std::count_if to count the number of times an element satisfying a given pred...
Definition STLExtras.h:2019
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
constexpr auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
Definition Sequence.h:341
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
Definition Alignment.h:201
LLVM_ABI void processShuffleMasks(ArrayRef< int > Mask, unsigned NumOfSrcRegs, unsigned NumOfDestRegs, unsigned NumOfUsedRegs, function_ref< void()> NoInputAction, function_ref< void(ArrayRef< int >, unsigned, unsigned)> SingleInputAction, function_ref< void(ArrayRef< int >, unsigned, unsigned, bool)> ManyInputsAction)
Splits and processes shuffle mask depending on the number of input and output registers.
const TypeConversionCostTblEntryT< CostType > * ConvertCostTableLookup(ArrayRef< TypeConversionCostTblEntryT< CostType > > Tbl, int ISD, MVT Dst, MVT Src)
Find in type conversion cost table.
Definition CostTable.h:67
LLVM_ABI int getSplatIndex(ArrayRef< int > Mask)
If all non-negative Mask elements are the same value, return that value.
#define N
std::optional< unsigned > operator[](TargetTransformInfo::TargetCostKind Kind) const
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
Cost Table Entry.
Definition CostTable.h:26
Extended Value Type.
Definition ValueTypes.h:35
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
Definition ValueTypes.h:145
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition ValueTypes.h:396
uint64_t getScalarSizeInBits() const
Definition ValueTypes.h:408
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition ValueTypes.h:339
bool isVector() const
Return true if this is a vector value type.
Definition ValueTypes.h:176
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
Definition ValueTypes.h:346
This represents an addressing mode of: BaseGV + BaseOffs + BaseReg + Scale*ScaleReg + ScalableOffset*...
unsigned Insns
TODO: Some of these could be merged.
Returns options for expansion of memcmp. IsZeroCmp is.
Describe known properties for a set of pointers.
Type Conversion Cost Table.
Definition CostTable.h:56