LLVM 23.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 static const CostKindTblEntry GFNIUniformConstCostTable[] = {
383 { ISD::SHL, MVT::v16i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
384 { ISD::SRL, MVT::v16i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
385 { ISD::SRA, MVT::v16i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
386 { ISD::SHL, MVT::v32i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
387 { ISD::SRL, MVT::v32i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
388 { ISD::SRA, MVT::v32i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
389 { ISD::SHL, MVT::v64i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
390 { ISD::SRL, MVT::v64i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
391 { ISD::SRA, MVT::v64i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
392 };
393
394 if (Op2Info.isUniform() && Op2Info.isConstant() && ST->hasGFNI())
395 if (const auto *Entry =
396 CostTableLookup(GFNIUniformConstCostTable, ISD, LT.second))
397 if (auto KindCost = Entry->Cost[CostKind])
398 return LT.first * *KindCost;
399
400 static const CostKindTblEntry AVX512BWUniformConstCostTable[] = {
401 { ISD::SHL, MVT::v16i8, { 1, 7, 2, 3 } }, // psllw + pand.
402 { ISD::SRL, MVT::v16i8, { 1, 7, 2, 3 } }, // psrlw + pand.
403 { ISD::SRA, MVT::v16i8, { 1, 8, 4, 5 } }, // psrlw, pand, pxor, psubb.
404 { ISD::SHL, MVT::v32i8, { 1, 8, 2, 3 } }, // psllw + pand.
405 { ISD::SRL, MVT::v32i8, { 1, 8, 2, 3 } }, // psrlw + pand.
406 { ISD::SRA, MVT::v32i8, { 1, 9, 4, 5 } }, // psrlw, pand, pxor, psubb.
407 { ISD::SHL, MVT::v64i8, { 1, 8, 2, 3 } }, // psllw + pand.
408 { ISD::SRL, MVT::v64i8, { 1, 8, 2, 3 } }, // psrlw + pand.
409 { ISD::SRA, MVT::v64i8, { 1, 9, 4, 6 } }, // psrlw, pand, pxor, psubb.
410
411 { ISD::SHL, MVT::v16i16, { 1, 1, 1, 1 } }, // psllw
412 { ISD::SRL, MVT::v16i16, { 1, 1, 1, 1 } }, // psrlw
413 { ISD::SRA, MVT::v16i16, { 1, 1, 1, 1 } }, // psrlw
414 { ISD::SHL, MVT::v32i16, { 1, 1, 1, 1 } }, // psllw
415 { ISD::SRL, MVT::v32i16, { 1, 1, 1, 1 } }, // psrlw
416 { ISD::SRA, MVT::v32i16, { 1, 1, 1, 1 } }, // psrlw
417 };
418
419 if (Op2Info.isUniform() && Op2Info.isConstant() && ST->hasBWI())
420 if (const auto *Entry =
421 CostTableLookup(AVX512BWUniformConstCostTable, ISD, LT.second))
422 if (auto KindCost = Entry->Cost[CostKind])
423 return LT.first * *KindCost;
424
425 static const CostKindTblEntry AVX512DQUniformConstCostTable[] = {
426 { ISD::SDIV, MVT::v4i64, { 9 } }, // vpmullq-based MULHS sequence
427 { ISD::SREM, MVT::v4i64, { 17 } }, // vpmullq-based MULHS+mul+sub sequence
428 { ISD::SDIV, MVT::v8i64, { 9 } }, // vpmullq-based MULHS sequence
429 { ISD::SREM, MVT::v8i64, { 17 } }, // vpmullq-based MULHS+mul+sub sequence
430 // The remainder's multiply-back is a single vpmullq with DQ, just like the
431 // pmulld the vXi32 entries above rely on. Without DQ it is another
432 // vpmuludq schoolbook, so the AVX512/AVX2 tables charge more.
433 { ISD::UREM, MVT::v4i64, { 17 } }, // MULHU + vpmullq + sub sequence
434 { ISD::UREM, MVT::v8i64, { 17 } }, // MULHU + vpmullq + sub sequence
435 };
436
437 if (Op2Info.isUniform() && Op2Info.isConstant() && ST->hasDQI())
438 if (const auto *Entry =
439 CostTableLookup(AVX512DQUniformConstCostTable, ISD, LT.second))
440 if (auto KindCost = Entry->Cost[CostKind])
441 return LT.first * *KindCost;
442
443 static const CostKindTblEntry AVX512UniformConstCostTable[] = {
444 { ISD::SHL, MVT::v64i8, { 2, 12, 5, 6 } }, // psllw + pand.
445 { ISD::SRL, MVT::v64i8, { 2, 12, 5, 6 } }, // psrlw + pand.
446 { ISD::SRA, MVT::v64i8, { 3, 10, 12, 12 } }, // psrlw, pand, pxor, psubb.
447
448 { ISD::SHL, MVT::v16i16, { 2, 7, 4, 4 } }, // psllw + split.
449 { ISD::SRL, MVT::v16i16, { 2, 7, 4, 4 } }, // psrlw + split.
450 { ISD::SRA, MVT::v16i16, { 2, 7, 4, 4 } }, // psraw + split.
451
452 { ISD::SHL, MVT::v8i32, { 1, 1, 1, 1 } }, // pslld
453 { ISD::SRL, MVT::v8i32, { 1, 1, 1, 1 } }, // psrld
454 { ISD::SRA, MVT::v8i32, { 1, 1, 1, 1 } }, // psrad
455 { ISD::SHL, MVT::v16i32, { 1, 1, 1, 1 } }, // pslld
456 { ISD::SRL, MVT::v16i32, { 1, 1, 1, 1 } }, // psrld
457 { ISD::SRA, MVT::v16i32, { 1, 1, 1, 1 } }, // psrad
458
459 { ISD::SRA, MVT::v2i64, { 1, 1, 1, 1 } }, // psraq
460 { ISD::SHL, MVT::v4i64, { 1, 1, 1, 1 } }, // psllq
461 { ISD::SRL, MVT::v4i64, { 1, 1, 1, 1 } }, // psrlq
462 { ISD::SRA, MVT::v4i64, { 1, 1, 1, 1 } }, // psraq
463 { ISD::SHL, MVT::v8i64, { 1, 1, 1, 1 } }, // psllq
464 { ISD::SRL, MVT::v8i64, { 1, 1, 1, 1 } }, // psrlq
465 { ISD::SRA, MVT::v8i64, { 1, 1, 1, 1 } }, // psraq
466
467 { ISD::SDIV, MVT::v16i32, { 6 } }, // pmuludq sequence
468 { ISD::SREM, MVT::v16i32, { 8 } }, // pmuludq+mul+sub sequence
469 { ISD::UDIV, MVT::v16i32, { 5 } }, // pmuludq sequence
470 { ISD::UREM, MVT::v16i32, { 7 } }, // pmuludq+mul+sub sequence
471
472 { ISD::UDIV, MVT::v8i64, { 9 } }, // pmuludq-based MULHU sequence
473 { ISD::UREM, MVT::v8i64, { 21 } }, // pmuludq-based MULHU+mul+sub sequence
474 };
475
476 if (Op2Info.isUniform() && Op2Info.isConstant() && ST->hasAVX512())
477 if (const auto *Entry =
478 CostTableLookup(AVX512UniformConstCostTable, ISD, LT.second))
479 if (auto KindCost = Entry->Cost[CostKind])
480 return LT.first * *KindCost;
481
482 static const CostKindTblEntry AVX2UniformConstCostTable[] = {
483 { ISD::SHL, MVT::v16i8, { 1, 8, 2, 3 } }, // psllw + pand.
484 { ISD::SRL, MVT::v16i8, { 1, 8, 2, 3 } }, // psrlw + pand.
485 { ISD::SRA, MVT::v16i8, { 2, 10, 5, 6 } }, // psrlw, pand, pxor, psubb.
486 { ISD::SHL, MVT::v32i8, { 2, 8, 2, 4 } }, // psllw + pand.
487 { ISD::SRL, MVT::v32i8, { 2, 8, 2, 4 } }, // psrlw + pand.
488 { ISD::SRA, MVT::v32i8, { 3, 10, 5, 9 } }, // psrlw, pand, pxor, psubb.
489
490 { ISD::SHL, MVT::v8i16, { 1, 1, 1, 1 } }, // psllw
491 { ISD::SRL, MVT::v8i16, { 1, 1, 1, 1 } }, // psrlw
492 { ISD::SRA, MVT::v8i16, { 1, 1, 1, 1 } }, // psraw
493 { ISD::SHL, MVT::v16i16,{ 2, 2, 1, 2 } }, // psllw
494 { ISD::SRL, MVT::v16i16,{ 2, 2, 1, 2 } }, // psrlw
495 { ISD::SRA, MVT::v16i16,{ 2, 2, 1, 2 } }, // psraw
496
497 { ISD::SHL, MVT::v4i32, { 1, 1, 1, 1 } }, // pslld
498 { ISD::SRL, MVT::v4i32, { 1, 1, 1, 1 } }, // psrld
499 { ISD::SRA, MVT::v4i32, { 1, 1, 1, 1 } }, // psrad
500 { ISD::SHL, MVT::v8i32, { 2, 2, 1, 2 } }, // pslld
501 { ISD::SRL, MVT::v8i32, { 2, 2, 1, 2 } }, // psrld
502 { ISD::SRA, MVT::v8i32, { 2, 2, 1, 2 } }, // psrad
503
504 { ISD::SHL, MVT::v2i64, { 1, 1, 1, 1 } }, // psllq
505 { ISD::SRL, MVT::v2i64, { 1, 1, 1, 1 } }, // psrlq
506 { ISD::SRA, MVT::v2i64, { 2, 3, 3, 3 } }, // psrad + shuffle.
507 { ISD::SHL, MVT::v4i64, { 2, 2, 1, 2 } }, // psllq
508 { ISD::SRL, MVT::v4i64, { 2, 2, 1, 2 } }, // psrlq
509 { ISD::SRA, MVT::v4i64, { 4, 4, 3, 6 } }, // psrad + shuffle + split.
510
511 { ISD::SDIV, MVT::v8i32, { 6 } }, // pmuludq sequence
512 { ISD::SREM, MVT::v8i32, { 8 } }, // pmuludq+mul+sub sequence
513 { ISD::UDIV, MVT::v8i32, { 5 } }, // pmuludq sequence
514 { ISD::UREM, MVT::v8i32, { 7 } }, // pmuludq+mul+sub sequence
515
516 { ISD::UDIV, MVT::v4i64, { 9 } }, // pmuludq-based MULHU sequence
517 { ISD::UREM, MVT::v4i64, { 21 } }, // pmuludq-based MULHU+mul+sub sequence
518 };
519
520 if (Op2Info.isUniform() && Op2Info.isConstant() && ST->hasAVX2())
521 if (const auto *Entry =
522 CostTableLookup(AVX2UniformConstCostTable, ISD, LT.second))
523 if (auto KindCost = Entry->Cost[CostKind])
524 return LT.first * *KindCost;
525
526 static const CostKindTblEntry AVXUniformConstCostTable[] = {
527 { ISD::SHL, MVT::v16i8, { 2, 7, 2, 3 } }, // psllw + pand.
528 { ISD::SRL, MVT::v16i8, { 2, 7, 2, 3 } }, // psrlw + pand.
529 { ISD::SRA, MVT::v16i8, { 3, 9, 5, 6 } }, // psrlw, pand, pxor, psubb.
530 { ISD::SHL, MVT::v32i8, { 4, 7, 7, 8 } }, // 2*(psllw + pand) + split.
531 { ISD::SRL, MVT::v32i8, { 4, 7, 7, 8 } }, // 2*(psrlw + pand) + split.
532 { ISD::SRA, MVT::v32i8, { 7, 7, 12, 13 } }, // 2*(psrlw, pand, pxor, psubb) + split.
533
534 { ISD::SHL, MVT::v8i16, { 1, 2, 1, 1 } }, // psllw.
535 { ISD::SRL, MVT::v8i16, { 1, 2, 1, 1 } }, // psrlw.
536 { ISD::SRA, MVT::v8i16, { 1, 2, 1, 1 } }, // psraw.
537 { ISD::SHL, MVT::v16i16,{ 3, 6, 4, 5 } }, // psllw + split.
538 { ISD::SRL, MVT::v16i16,{ 3, 6, 4, 5 } }, // psrlw + split.
539 { ISD::SRA, MVT::v16i16,{ 3, 6, 4, 5 } }, // psraw + split.
540
541 { ISD::SHL, MVT::v4i32, { 1, 2, 1, 1 } }, // pslld.
542 { ISD::SRL, MVT::v4i32, { 1, 2, 1, 1 } }, // psrld.
543 { ISD::SRA, MVT::v4i32, { 1, 2, 1, 1 } }, // psrad.
544 { ISD::SHL, MVT::v8i32, { 3, 6, 4, 5 } }, // pslld + split.
545 { ISD::SRL, MVT::v8i32, { 3, 6, 4, 5 } }, // psrld + split.
546 { ISD::SRA, MVT::v8i32, { 3, 6, 4, 5 } }, // psrad + split.
547
548 { ISD::SHL, MVT::v2i64, { 1, 2, 1, 1 } }, // psllq.
549 { ISD::SRL, MVT::v2i64, { 1, 2, 1, 1 } }, // psrlq.
550 { ISD::SRA, MVT::v2i64, { 2, 3, 3, 3 } }, // psrad + shuffle.
551 { ISD::SHL, MVT::v4i64, { 3, 6, 4, 5 } }, // 2 x psllq + split.
552 { ISD::SRL, MVT::v4i64, { 3, 6, 4, 5 } }, // 2 x psllq + split.
553 { ISD::SRA, MVT::v4i64, { 5, 7, 8, 9 } }, // 2 x psrad + shuffle + split.
554
555 { ISD::SDIV, MVT::v8i32, { 14 } }, // 2*pmuludq sequence + split.
556 { ISD::SREM, MVT::v8i32, { 18 } }, // 2*pmuludq+mul+sub sequence + split.
557 { ISD::UDIV, MVT::v8i32, { 12 } }, // 2*pmuludq sequence + split.
558 { ISD::UREM, MVT::v8i32, { 16 } }, // 2*pmuludq+mul+sub sequence + split.
559 };
560
561 // XOP has faster vXi8 shifts.
562 if (Op2Info.isUniform() && Op2Info.isConstant() && ST->hasAVX() &&
563 (!ST->hasXOP() || LT.second.getScalarSizeInBits() != 8))
564 if (const auto *Entry =
565 CostTableLookup(AVXUniformConstCostTable, ISD, LT.second))
566 if (auto KindCost = Entry->Cost[CostKind])
567 return LT.first * *KindCost;
568
569 static const CostKindTblEntry SSE2UniformConstCostTable[] = {
570 { ISD::SHL, MVT::v16i8, { 1, 7, 2, 3 } }, // psllw + pand.
571 { ISD::SRL, MVT::v16i8, { 1, 7, 2, 3 } }, // psrlw + pand.
572 { ISD::SRA, MVT::v16i8, { 3, 9, 5, 6 } }, // psrlw, pand, pxor, psubb.
573
574 { ISD::SHL, MVT::v8i16, { 1, 1, 1, 1 } }, // psllw.
575 { ISD::SRL, MVT::v8i16, { 1, 1, 1, 1 } }, // psrlw.
576 { ISD::SRA, MVT::v8i16, { 1, 1, 1, 1 } }, // psraw.
577
578 { ISD::SHL, MVT::v4i32, { 1, 1, 1, 1 } }, // pslld
579 { ISD::SRL, MVT::v4i32, { 1, 1, 1, 1 } }, // psrld.
580 { ISD::SRA, MVT::v4i32, { 1, 1, 1, 1 } }, // psrad.
581
582 { ISD::SHL, MVT::v2i64, { 1, 1, 1, 1 } }, // psllq.
583 { ISD::SRL, MVT::v2i64, { 1, 1, 1, 1 } }, // psrlq.
584 { ISD::SRA, MVT::v2i64, { 3, 5, 6, 6 } }, // 2 x psrad + shuffle.
585
586 { ISD::SDIV, MVT::v4i32, { 6 } }, // pmuludq sequence
587 { ISD::SREM, MVT::v4i32, { 8 } }, // pmuludq+mul+sub sequence
588 { ISD::UDIV, MVT::v4i32, { 5 } }, // pmuludq sequence
589 { ISD::UREM, MVT::v4i32, { 7 } }, // pmuludq+mul+sub sequence
590 };
591
592 // XOP has faster vXi8 shifts.
593 if (Op2Info.isUniform() && Op2Info.isConstant() && ST->hasSSE2() &&
594 (!ST->hasXOP() || LT.second.getScalarSizeInBits() != 8))
595 if (const auto *Entry =
596 CostTableLookup(SSE2UniformConstCostTable, ISD, LT.second))
597 if (auto KindCost = Entry->Cost[CostKind])
598 return LT.first * *KindCost;
599
600 static const CostKindTblEntry AVX512BWConstCostTable[] = {
601 { ISD::SDIV, MVT::v64i8, { 14 } }, // 2*ext+2*pmulhw sequence
602 { ISD::SREM, MVT::v64i8, { 16 } }, // 2*ext+2*pmulhw+mul+sub sequence
603 { ISD::UDIV, MVT::v64i8, { 14 } }, // 2*ext+2*pmulhw sequence
604 { ISD::UREM, MVT::v64i8, { 16 } }, // 2*ext+2*pmulhw+mul+sub sequence
605
606 { ISD::SDIV, MVT::v32i16, { 6 } }, // vpmulhw sequence
607 { ISD::SREM, MVT::v32i16, { 8 } }, // vpmulhw+mul+sub sequence
608 { ISD::UDIV, MVT::v32i16, { 6 } }, // vpmulhuw sequence
609 { ISD::UREM, MVT::v32i16, { 8 } }, // vpmulhuw+mul+sub sequence
610 };
611
612 if (Op2Info.isConstant() && ST->hasBWI())
613 if (const auto *Entry =
614 CostTableLookup(AVX512BWConstCostTable, ISD, LT.second))
615 if (auto KindCost = Entry->Cost[CostKind])
616 return LT.first * *KindCost;
617
618 static const CostKindTblEntry AVX512DQConstCostTable[] = {
619 { ISD::SDIV, MVT::v4i64, { 9 } }, // vpmullq-based MULHS sequence
620 { ISD::SREM, MVT::v4i64, { 21 } }, // vpmullq-based MULHS+mul+sub sequence
621 { ISD::SDIV, MVT::v8i64, { 9 } }, // vpmullq-based MULHS sequence
622 { ISD::SREM, MVT::v8i64, { 21 } }, // vpmullq-based MULHS+mul+sub sequence
623 // The remainder's multiply-back is a single vpmullq with DQ, whereas the
624 // AVX512/AVX2 tables have to charge for another vpmuludq schoolbook.
625 { ISD::UREM, MVT::v4i64, { 24 } }, // MULHU + vpmullq + sub sequence
626 { ISD::UREM, MVT::v8i64, { 24 } }, // MULHU + vpmullq + sub sequence
627 };
628
629 if (Op2Info.isConstant() && ST->hasDQI())
630 if (const auto *Entry =
631 CostTableLookup(AVX512DQConstCostTable, ISD, LT.second))
632 if (auto KindCost = Entry->Cost[CostKind])
633 return LT.first * *KindCost;
634
635 static const CostKindTblEntry AVX512ConstCostTable[] = {
636 { ISD::SDIV, MVT::v64i8, { 28 } }, // 4*ext+4*pmulhw sequence
637 { ISD::SREM, MVT::v64i8, { 32 } }, // 4*ext+4*pmulhw+mul+sub sequence
638 { ISD::UDIV, MVT::v64i8, { 28 } }, // 4*ext+4*pmulhw sequence
639 { ISD::UREM, MVT::v64i8, { 32 } }, // 4*ext+4*pmulhw+mul+sub sequence
640
641 { ISD::SDIV, MVT::v32i16, { 12 } }, // 2*vpmulhw sequence
642 { ISD::SREM, MVT::v32i16, { 16 } }, // 2*vpmulhw+mul+sub sequence
643 { ISD::UDIV, MVT::v32i16, { 12 } }, // 2*vpmulhuw sequence
644 { ISD::UREM, MVT::v32i16, { 16 } }, // 2*vpmulhuw+mul+sub sequence
645
646 { ISD::SDIV, MVT::v16i32, { 15 } }, // vpmuldq sequence
647 { ISD::SREM, MVT::v16i32, { 17 } }, // vpmuldq+mul+sub sequence
648 { ISD::UDIV, MVT::v16i32, { 15 } }, // vpmuludq sequence
649 { ISD::UREM, MVT::v16i32, { 17 } }, // vpmuludq+mul+sub sequence
650
651 { ISD::UDIV, MVT::v8i64, { 9 } }, // vpmuludq-based MULHU sequence
652 { ISD::UREM, MVT::v8i64, { 28 } }, // vpmuludq-based MULHU+mul+sub sequence
653 };
654
655 if (Op2Info.isConstant() && ST->hasAVX512())
656 if (const auto *Entry =
657 CostTableLookup(AVX512ConstCostTable, ISD, LT.second))
658 if (auto KindCost = Entry->Cost[CostKind])
659 return LT.first * *KindCost;
660
661 static const CostKindTblEntry AVX2ConstCostTable[] = {
662 { ISD::SDIV, MVT::v32i8, { 14 } }, // 2*ext+2*pmulhw sequence
663 { ISD::SREM, MVT::v32i8, { 16 } }, // 2*ext+2*pmulhw+mul+sub sequence
664 { ISD::UDIV, MVT::v32i8, { 14 } }, // 2*ext+2*pmulhw sequence
665 { ISD::UREM, MVT::v32i8, { 16 } }, // 2*ext+2*pmulhw+mul+sub sequence
666
667 { ISD::SDIV, MVT::v16i16, { 6 } }, // vpmulhw sequence
668 { ISD::SREM, MVT::v16i16, { 8 } }, // vpmulhw+mul+sub sequence
669 { ISD::UDIV, MVT::v16i16, { 6 } }, // vpmulhuw sequence
670 { ISD::UREM, MVT::v16i16, { 8 } }, // vpmulhuw+mul+sub sequence
671
672 { ISD::SDIV, MVT::v8i32, { 15 } }, // vpmuldq sequence
673 { ISD::SREM, MVT::v8i32, { 19 } }, // vpmuldq+mul+sub sequence
674 { ISD::UDIV, MVT::v8i32, { 15 } }, // vpmuludq sequence
675 { ISD::UREM, MVT::v8i32, { 19 } }, // vpmuludq+mul+sub sequence
676
677 { ISD::UDIV, MVT::v4i64, { 9 } }, // vpmuludq-based MULHU sequence
678 { ISD::UREM, MVT::v4i64, { 28 } }, // vpmuludq-based MULHU+mul+sub sequence
679 };
680
681 if (Op2Info.isConstant() && ST->hasAVX2())
682 if (const auto *Entry = CostTableLookup(AVX2ConstCostTable, ISD, LT.second))
683 if (auto KindCost = Entry->Cost[CostKind])
684 return LT.first * *KindCost;
685
686 static const CostKindTblEntry AVXConstCostTable[] = {
687 { ISD::SDIV, MVT::v32i8, { 30 } }, // 4*ext+4*pmulhw sequence + split.
688 { ISD::SREM, MVT::v32i8, { 34 } }, // 4*ext+4*pmulhw+mul+sub sequence + split.
689 { ISD::UDIV, MVT::v32i8, { 30 } }, // 4*ext+4*pmulhw sequence + split.
690 { ISD::UREM, MVT::v32i8, { 34 } }, // 4*ext+4*pmulhw+mul+sub sequence + split.
691
692 { ISD::SDIV, MVT::v16i16, { 14 } }, // 2*pmulhw sequence + split.
693 { ISD::SREM, MVT::v16i16, { 18 } }, // 2*pmulhw+mul+sub sequence + split.
694 { ISD::UDIV, MVT::v16i16, { 14 } }, // 2*pmulhuw sequence + split.
695 { ISD::UREM, MVT::v16i16, { 18 } }, // 2*pmulhuw+mul+sub sequence + split.
696
697 { ISD::SDIV, MVT::v8i32, { 32 } }, // vpmuludq sequence
698 { ISD::SREM, MVT::v8i32, { 38 } }, // vpmuludq+mul+sub sequence
699 { ISD::UDIV, MVT::v8i32, { 32 } }, // 2*pmuludq sequence + split.
700 { ISD::UREM, MVT::v8i32, { 42 } }, // 2*pmuludq+mul+sub sequence + split.
701 };
702
703 if (Op2Info.isConstant() && ST->hasAVX())
704 if (const auto *Entry = CostTableLookup(AVXConstCostTable, ISD, LT.second))
705 if (auto KindCost = Entry->Cost[CostKind])
706 return LT.first * *KindCost;
707
708 static const CostKindTblEntry SSE41ConstCostTable[] = {
709 { ISD::SDIV, MVT::v4i32, { 15 } }, // vpmuludq sequence
710 { ISD::SREM, MVT::v4i32, { 20 } }, // vpmuludq+mul+sub sequence
711 };
712
713 if (Op2Info.isConstant() && ST->hasSSE41())
714 if (const auto *Entry =
715 CostTableLookup(SSE41ConstCostTable, ISD, LT.second))
716 if (auto KindCost = Entry->Cost[CostKind])
717 return LT.first * *KindCost;
718
719 static const CostKindTblEntry SSE2ConstCostTable[] = {
720 { ISD::SDIV, MVT::v16i8, { 14 } }, // 2*ext+2*pmulhw sequence
721 { ISD::SREM, MVT::v16i8, { 16 } }, // 2*ext+2*pmulhw+mul+sub sequence
722 { ISD::UDIV, MVT::v16i8, { 14 } }, // 2*ext+2*pmulhw sequence
723 { ISD::UREM, MVT::v16i8, { 16 } }, // 2*ext+2*pmulhw+mul+sub sequence
724
725 { ISD::SDIV, MVT::v8i16, { 6 } }, // pmulhw sequence
726 { ISD::SREM, MVT::v8i16, { 8 } }, // pmulhw+mul+sub sequence
727 { ISD::UDIV, MVT::v8i16, { 6 } }, // pmulhuw sequence
728 { ISD::UREM, MVT::v8i16, { 8 } }, // pmulhuw+mul+sub sequence
729
730 { ISD::SDIV, MVT::v4i32, { 19 } }, // pmuludq sequence
731 { ISD::SREM, MVT::v4i32, { 24 } }, // pmuludq+mul+sub sequence
732 { ISD::UDIV, MVT::v4i32, { 15 } }, // pmuludq sequence
733 { ISD::UREM, MVT::v4i32, { 20 } }, // pmuludq+mul+sub sequence
734 };
735
736 if (Op2Info.isConstant() && ST->hasSSE2())
737 if (const auto *Entry = CostTableLookup(SSE2ConstCostTable, ISD, LT.second))
738 if (auto KindCost = Entry->Cost[CostKind])
739 return LT.first * *KindCost;
740
741 static const CostKindTblEntry AVX512BWUniformCostTable[] = {
742 { ISD::SHL, MVT::v16i8, { 3, 5, 5, 7 } }, // psllw + pand.
743 { ISD::SRL, MVT::v16i8, { 3,10, 5, 8 } }, // psrlw + pand.
744 { ISD::SRA, MVT::v16i8, { 4,12, 8,12 } }, // psrlw, pand, pxor, psubb.
745 { ISD::SHL, MVT::v32i8, { 4, 7, 6, 8 } }, // psllw + pand.
746 { ISD::SRL, MVT::v32i8, { 4, 8, 7, 9 } }, // psrlw + pand.
747 { ISD::SRA, MVT::v32i8, { 5,10,10,13 } }, // psrlw, pand, pxor, psubb.
748 { ISD::SHL, MVT::v64i8, { 4, 7, 6, 8 } }, // psllw + pand.
749 { ISD::SRL, MVT::v64i8, { 4, 8, 7,10 } }, // psrlw + pand.
750 { ISD::SRA, MVT::v64i8, { 5,10,10,15 } }, // psrlw, pand, pxor, psubb.
751
752 { ISD::SHL, MVT::v32i16, { 2, 4, 2, 3 } }, // psllw
753 { ISD::SRL, MVT::v32i16, { 2, 4, 2, 3 } }, // psrlw
754 { ISD::SRA, MVT::v32i16, { 2, 4, 2, 3 } }, // psrqw
755 };
756
757 if (ST->hasBWI() && Op2Info.isUniform())
758 if (const auto *Entry =
759 CostTableLookup(AVX512BWUniformCostTable, ISD, LT.second))
760 if (auto KindCost = Entry->Cost[CostKind])
761 return LT.first * *KindCost;
762
763 static const CostKindTblEntry AVX512UniformCostTable[] = {
764 { ISD::SHL, MVT::v32i16, { 5,10, 5, 7 } }, // psllw + split.
765 { ISD::SRL, MVT::v32i16, { 5,10, 5, 7 } }, // psrlw + split.
766 { ISD::SRA, MVT::v32i16, { 5,10, 5, 7 } }, // psraw + split.
767
768 { ISD::SHL, MVT::v16i32, { 2, 4, 2, 3 } }, // pslld
769 { ISD::SRL, MVT::v16i32, { 2, 4, 2, 3 } }, // psrld
770 { ISD::SRA, MVT::v16i32, { 2, 4, 2, 3 } }, // psrad
771
772 { ISD::SRA, MVT::v2i64, { 1, 2, 1, 2 } }, // psraq
773 { ISD::SHL, MVT::v4i64, { 1, 4, 1, 2 } }, // psllq
774 { ISD::SRL, MVT::v4i64, { 1, 4, 1, 2 } }, // psrlq
775 { ISD::SRA, MVT::v4i64, { 1, 4, 1, 2 } }, // psraq
776 { ISD::SHL, MVT::v8i64, { 1, 4, 1, 2 } }, // psllq
777 { ISD::SRL, MVT::v8i64, { 1, 4, 1, 2 } }, // psrlq
778 { ISD::SRA, MVT::v8i64, { 1, 4, 1, 2 } }, // psraq
779 };
780
781 if (ST->hasAVX512() && Op2Info.isUniform())
782 if (const auto *Entry =
783 CostTableLookup(AVX512UniformCostTable, ISD, LT.second))
784 if (auto KindCost = Entry->Cost[CostKind])
785 return LT.first * *KindCost;
786
787 static const CostKindTblEntry AVX2UniformCostTable[] = {
788 // Uniform splats are cheaper for the following instructions.
789 { ISD::SHL, MVT::v16i8, { 3, 5, 5, 7 } }, // psllw + pand.
790 { ISD::SRL, MVT::v16i8, { 3, 9, 5, 8 } }, // psrlw + pand.
791 { ISD::SRA, MVT::v16i8, { 4, 5, 9,13 } }, // psrlw, pand, pxor, psubb.
792 { ISD::SHL, MVT::v32i8, { 4, 7, 6, 8 } }, // psllw + pand.
793 { ISD::SRL, MVT::v32i8, { 4, 8, 7, 9 } }, // psrlw + pand.
794 { ISD::SRA, MVT::v32i8, { 6, 9,11,16 } }, // psrlw, pand, pxor, psubb.
795
796 { ISD::SHL, MVT::v8i16, { 1, 2, 1, 2 } }, // psllw.
797 { ISD::SRL, MVT::v8i16, { 1, 2, 1, 2 } }, // psrlw.
798 { ISD::SRA, MVT::v8i16, { 1, 2, 1, 2 } }, // psraw.
799 { ISD::SHL, MVT::v16i16, { 2, 4, 2, 3 } }, // psllw.
800 { ISD::SRL, MVT::v16i16, { 2, 4, 2, 3 } }, // psrlw.
801 { ISD::SRA, MVT::v16i16, { 2, 4, 2, 3 } }, // psraw.
802
803 { ISD::SHL, MVT::v4i32, { 1, 2, 1, 2 } }, // pslld
804 { ISD::SRL, MVT::v4i32, { 1, 2, 1, 2 } }, // psrld
805 { ISD::SRA, MVT::v4i32, { 1, 2, 1, 2 } }, // psrad
806 { ISD::SHL, MVT::v8i32, { 2, 4, 2, 3 } }, // pslld
807 { ISD::SRL, MVT::v8i32, { 2, 4, 2, 3 } }, // psrld
808 { ISD::SRA, MVT::v8i32, { 2, 4, 2, 3 } }, // psrad
809
810 { ISD::SHL, MVT::v2i64, { 1, 2, 1, 2 } }, // psllq
811 { ISD::SRL, MVT::v2i64, { 1, 2, 1, 2 } }, // psrlq
812 { ISD::SRA, MVT::v2i64, { 2, 4, 5, 7 } }, // 2 x psrad + shuffle.
813 { ISD::SHL, MVT::v4i64, { 2, 4, 1, 2 } }, // psllq
814 { ISD::SRL, MVT::v4i64, { 2, 4, 1, 2 } }, // psrlq
815 { ISD::SRA, MVT::v4i64, { 4, 6, 5, 9 } }, // 2 x psrad + shuffle.
816 };
817
818 if (ST->hasAVX2() && Op2Info.isUniform())
819 if (const auto *Entry =
820 CostTableLookup(AVX2UniformCostTable, ISD, LT.second))
821 if (auto KindCost = Entry->Cost[CostKind])
822 return LT.first * *KindCost;
823
824 static const CostKindTblEntry AVXUniformCostTable[] = {
825 { ISD::SHL, MVT::v16i8, { 4, 4, 6, 8 } }, // psllw + pand.
826 { ISD::SRL, MVT::v16i8, { 4, 8, 5, 8 } }, // psrlw + pand.
827 { ISD::SRA, MVT::v16i8, { 6, 6, 9,13 } }, // psrlw, pand, pxor, psubb.
828 { ISD::SHL, MVT::v32i8, { 7, 8,11,14 } }, // psllw + pand + split.
829 { ISD::SRL, MVT::v32i8, { 7, 9,10,14 } }, // psrlw + pand + split.
830 { ISD::SRA, MVT::v32i8, { 10,11,16,21 } }, // psrlw, pand, pxor, psubb + split.
831
832 { ISD::SHL, MVT::v8i16, { 1, 3, 1, 2 } }, // psllw.
833 { ISD::SRL, MVT::v8i16, { 1, 3, 1, 2 } }, // psrlw.
834 { ISD::SRA, MVT::v8i16, { 1, 3, 1, 2 } }, // psraw.
835 { ISD::SHL, MVT::v16i16, { 3, 7, 5, 7 } }, // psllw + split.
836 { ISD::SRL, MVT::v16i16, { 3, 7, 5, 7 } }, // psrlw + split.
837 { ISD::SRA, MVT::v16i16, { 3, 7, 5, 7 } }, // psraw + split.
838
839 { ISD::SHL, MVT::v4i32, { 1, 3, 1, 2 } }, // pslld.
840 { ISD::SRL, MVT::v4i32, { 1, 3, 1, 2 } }, // psrld.
841 { ISD::SRA, MVT::v4i32, { 1, 3, 1, 2 } }, // psrad.
842 { ISD::SHL, MVT::v8i32, { 3, 7, 5, 7 } }, // pslld + split.
843 { ISD::SRL, MVT::v8i32, { 3, 7, 5, 7 } }, // psrld + split.
844 { ISD::SRA, MVT::v8i32, { 3, 7, 5, 7 } }, // psrad + split.
845
846 { ISD::SHL, MVT::v2i64, { 1, 3, 1, 2 } }, // psllq.
847 { ISD::SRL, MVT::v2i64, { 1, 3, 1, 2 } }, // psrlq.
848 { ISD::SRA, MVT::v2i64, { 3, 4, 5, 7 } }, // 2 x psrad + shuffle.
849 { ISD::SHL, MVT::v4i64, { 3, 7, 4, 6 } }, // psllq + split.
850 { ISD::SRL, MVT::v4i64, { 3, 7, 4, 6 } }, // psrlq + split.
851 { ISD::SRA, MVT::v4i64, { 6, 7,10,13 } }, // 2 x (2 x psrad + shuffle) + split.
852 };
853
854 // XOP has faster vXi8 shifts.
855 if (ST->hasAVX() && Op2Info.isUniform() &&
856 (!ST->hasXOP() || LT.second.getScalarSizeInBits() != 8))
857 if (const auto *Entry =
858 CostTableLookup(AVXUniformCostTable, ISD, LT.second))
859 if (auto KindCost = Entry->Cost[CostKind])
860 return LT.first * *KindCost;
861
862 static const CostKindTblEntry SSE2UniformCostTable[] = {
863 // Uniform splats are cheaper for the following instructions.
864 { ISD::SHL, MVT::v16i8, { 9, 10, 6, 9 } }, // psllw + pand.
865 { ISD::SRL, MVT::v16i8, { 9, 13, 5, 9 } }, // psrlw + pand.
866 { ISD::SRA, MVT::v16i8, { 11, 15, 9,13 } }, // pcmpgtb sequence.
867
868 { ISD::SHL, MVT::v8i16, { 2, 2, 1, 2 } }, // psllw.
869 { ISD::SRL, MVT::v8i16, { 2, 2, 1, 2 } }, // psrlw.
870 { ISD::SRA, MVT::v8i16, { 2, 2, 1, 2 } }, // psraw.
871
872 { ISD::SHL, MVT::v4i32, { 2, 2, 1, 2 } }, // pslld
873 { ISD::SRL, MVT::v4i32, { 2, 2, 1, 2 } }, // psrld.
874 { ISD::SRA, MVT::v4i32, { 2, 2, 1, 2 } }, // psrad.
875
876 { ISD::SHL, MVT::v2i64, { 2, 2, 1, 2 } }, // psllq.
877 { ISD::SRL, MVT::v2i64, { 2, 2, 1, 2 } }, // psrlq.
878 { ISD::SRA, MVT::v2i64, { 5, 9, 5, 7 } }, // 2*psrlq + xor + sub.
879 };
880
881 if (ST->hasSSE2() && Op2Info.isUniform() &&
882 (!ST->hasXOP() || LT.second.getScalarSizeInBits() != 8))
883 if (const auto *Entry =
884 CostTableLookup(SSE2UniformCostTable, ISD, LT.second))
885 if (auto KindCost = Entry->Cost[CostKind])
886 return LT.first * *KindCost;
887
888 static const CostKindTblEntry AVX512DQCostTable[] = {
889 { ISD::MUL, MVT::v2i64, { 2, 15, 1, 3 } }, // pmullq
890 { ISD::MUL, MVT::v4i64, { 2, 15, 1, 3 } }, // pmullq
891 { ISD::MUL, MVT::v8i64, { 3, 15, 1, 3 } } // pmullq
892 };
893
894 // Look for AVX512DQ lowering tricks for custom cases.
895 if (ST->hasDQI())
896 if (const auto *Entry = CostTableLookup(AVX512DQCostTable, ISD, LT.second))
897 if (auto KindCost = Entry->Cost[CostKind])
898 return LT.first * *KindCost;
899
900 static const CostKindTblEntry AVX512BWCostTable[] = {
901 { ISD::SHL, MVT::v16i8, { 4, 8, 4, 5 } }, // extend/vpsllvw/pack sequence.
902 { ISD::SRL, MVT::v16i8, { 4, 8, 4, 5 } }, // extend/vpsrlvw/pack sequence.
903 { ISD::SRA, MVT::v16i8, { 4, 8, 4, 5 } }, // extend/vpsravw/pack sequence.
904 { ISD::SHL, MVT::v32i8, { 4, 23,11,16 } }, // extend/vpsllvw/pack sequence.
905 { ISD::SRL, MVT::v32i8, { 4, 30,12,18 } }, // extend/vpsrlvw/pack sequence.
906 { ISD::SRA, MVT::v32i8, { 6, 13,24,30 } }, // extend/vpsravw/pack sequence.
907 { ISD::SHL, MVT::v64i8, { 6, 19,13,15 } }, // extend/vpsllvw/pack sequence.
908 { ISD::SRL, MVT::v64i8, { 7, 27,15,18 } }, // extend/vpsrlvw/pack sequence.
909 { ISD::SRA, MVT::v64i8, { 15, 15,30,30 } }, // extend/vpsravw/pack sequence.
910
911 { ISD::SHL, MVT::v8i16, { 1, 1, 1, 1 } }, // vpsllvw
912 { ISD::SRL, MVT::v8i16, { 1, 1, 1, 1 } }, // vpsrlvw
913 { ISD::SRA, MVT::v8i16, { 1, 1, 1, 1 } }, // vpsravw
914 { ISD::SHL, MVT::v16i16, { 1, 1, 1, 1 } }, // vpsllvw
915 { ISD::SRL, MVT::v16i16, { 1, 1, 1, 1 } }, // vpsrlvw
916 { ISD::SRA, MVT::v16i16, { 1, 1, 1, 1 } }, // vpsravw
917 { ISD::SHL, MVT::v32i16, { 1, 1, 1, 1 } }, // vpsllvw
918 { ISD::SRL, MVT::v32i16, { 1, 1, 1, 1 } }, // vpsrlvw
919 { ISD::SRA, MVT::v32i16, { 1, 1, 1, 1 } }, // vpsravw
920
921 { ISD::ADD, MVT::v64i8, { 1, 1, 1, 1 } }, // paddb
922 { ISD::ADD, MVT::v32i16, { 1, 1, 1, 1 } }, // paddw
923
924 { ISD::ADD, MVT::v32i8, { 1, 1, 1, 1 } }, // paddb
925 { ISD::ADD, MVT::v16i16, { 1, 1, 1, 1 } }, // paddw
926 { ISD::ADD, MVT::v8i32, { 1, 1, 1, 1 } }, // paddd
927 { ISD::ADD, MVT::v4i64, { 1, 1, 1, 1 } }, // paddq
928
929 { ISD::SUB, MVT::v64i8, { 1, 1, 1, 1 } }, // psubb
930 { ISD::SUB, MVT::v32i16, { 1, 1, 1, 1 } }, // psubw
931
932 { ISD::MUL, MVT::v16i8, { 4, 12, 4, 5 } }, // extend/pmullw/trunc
933 { ISD::MUL, MVT::v32i8, { 3, 10, 7,10 } }, // pmaddubsw
934 { ISD::MUL, MVT::v64i8, { 3, 11, 7,10 } }, // pmaddubsw
935 { ISD::MUL, MVT::v32i16, { 1, 5, 1, 1 } }, // pmullw
936
937 { ISD::SUB, MVT::v32i8, { 1, 1, 1, 1 } }, // psubb
938 { ISD::SUB, MVT::v16i16, { 1, 1, 1, 1 } }, // psubw
939 { ISD::SUB, MVT::v8i32, { 1, 1, 1, 1 } }, // psubd
940 { ISD::SUB, MVT::v4i64, { 1, 1, 1, 1 } }, // psubq
941 };
942
943 // Look for AVX512BW lowering tricks for custom cases.
944 if (ST->hasBWI())
945 if (const auto *Entry = CostTableLookup(AVX512BWCostTable, ISD, LT.second))
946 if (auto KindCost = Entry->Cost[CostKind])
947 return LT.first * *KindCost;
948
949 static const CostKindTblEntry AVX512CostTable[] = {
950 { ISD::SHL, MVT::v64i8, { 15, 19,27,33 } }, // vpblendv+split sequence.
951 { ISD::SRL, MVT::v64i8, { 15, 19,30,36 } }, // vpblendv+split sequence.
952 { ISD::SRA, MVT::v64i8, { 37, 37,51,63 } }, // vpblendv+split sequence.
953
954 { ISD::SHL, MVT::v32i16, { 11, 16,11,15 } }, // 2*extend/vpsrlvd/pack sequence.
955 { ISD::SRL, MVT::v32i16, { 11, 16,11,15 } }, // 2*extend/vpsrlvd/pack sequence.
956 { ISD::SRA, MVT::v32i16, { 11, 16,11,15 } }, // 2*extend/vpsravd/pack sequence.
957
958 { ISD::SHL, MVT::v4i32, { 1, 1, 1, 1 } },
959 { ISD::SRL, MVT::v4i32, { 1, 1, 1, 1 } },
960 { ISD::SRA, MVT::v4i32, { 1, 1, 1, 1 } },
961 { ISD::SHL, MVT::v8i32, { 1, 1, 1, 1 } },
962 { ISD::SRL, MVT::v8i32, { 1, 1, 1, 1 } },
963 { ISD::SRA, MVT::v8i32, { 1, 1, 1, 1 } },
964 { ISD::SHL, MVT::v16i32, { 1, 1, 1, 1 } },
965 { ISD::SRL, MVT::v16i32, { 1, 1, 1, 1 } },
966 { ISD::SRA, MVT::v16i32, { 1, 1, 1, 1 } },
967
968 { ISD::SHL, MVT::v2i64, { 1, 1, 1, 1 } },
969 { ISD::SRL, MVT::v2i64, { 1, 1, 1, 1 } },
970 { ISD::SRA, MVT::v2i64, { 1, 1, 1, 1 } },
971 { ISD::SHL, MVT::v4i64, { 1, 1, 1, 1 } },
972 { ISD::SRL, MVT::v4i64, { 1, 1, 1, 1 } },
973 { ISD::SRA, MVT::v4i64, { 1, 1, 1, 1 } },
974 { ISD::SHL, MVT::v8i64, { 1, 1, 1, 1 } },
975 { ISD::SRL, MVT::v8i64, { 1, 1, 1, 1 } },
976 { ISD::SRA, MVT::v8i64, { 1, 1, 1, 1 } },
977
978 { ISD::ADD, MVT::v64i8, { 3, 7, 5, 5 } }, // 2*paddb + split
979 { ISD::ADD, MVT::v32i16, { 3, 7, 5, 5 } }, // 2*paddw + split
980
981 { ISD::SUB, MVT::v64i8, { 3, 7, 5, 5 } }, // 2*psubb + split
982 { ISD::SUB, MVT::v32i16, { 3, 7, 5, 5 } }, // 2*psubw + split
983
984 { ISD::AND, MVT::v32i8, { 1, 1, 1, 1 } },
985 { ISD::AND, MVT::v16i16, { 1, 1, 1, 1 } },
986 { ISD::AND, MVT::v8i32, { 1, 1, 1, 1 } },
987 { ISD::AND, MVT::v4i64, { 1, 1, 1, 1 } },
988
989 { ISD::OR, MVT::v32i8, { 1, 1, 1, 1 } },
990 { ISD::OR, MVT::v16i16, { 1, 1, 1, 1 } },
991 { ISD::OR, MVT::v8i32, { 1, 1, 1, 1 } },
992 { ISD::OR, MVT::v4i64, { 1, 1, 1, 1 } },
993
994 { ISD::XOR, MVT::v32i8, { 1, 1, 1, 1 } },
995 { ISD::XOR, MVT::v16i16, { 1, 1, 1, 1 } },
996 { ISD::XOR, MVT::v8i32, { 1, 1, 1, 1 } },
997 { ISD::XOR, MVT::v4i64, { 1, 1, 1, 1 } },
998
999 { ISD::MUL, MVT::v16i32, { 1, 10, 1, 2 } }, // pmulld (Skylake from agner.org)
1000 { ISD::MUL, MVT::v8i32, { 1, 10, 1, 2 } }, // pmulld (Skylake from agner.org)
1001 { ISD::MUL, MVT::v4i32, { 1, 10, 1, 2 } }, // pmulld (Skylake from agner.org)
1002 { ISD::MUL, MVT::v8i64, { 6, 9, 8, 8 } }, // 3*pmuludq/3*shift/2*add
1003 { ISD::MUL, MVT::i64, { 1 } }, // Skylake from http://www.agner.org/
1004
1005 { X86ISD::PMULUDQ, MVT::v8i64, { 1, 5, 1, 1 } },
1006
1007 { ISD::FNEG, MVT::v8f64, { 1, 1, 1, 2 } }, // Skylake from http://www.agner.org/
1008 { ISD::FADD, MVT::v8f64, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1009 { ISD::FADD, MVT::v4f64, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1010 { ISD::FSUB, MVT::v8f64, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1011 { ISD::FSUB, MVT::v4f64, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1012 { ISD::FMUL, MVT::v8f64, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1013 { ISD::FMUL, MVT::v4f64, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1014 { ISD::FMUL, MVT::v2f64, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1015 { ISD::FMUL, MVT::f64, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1016
1017 { ISD::FDIV, MVT::f64, { 4, 14, 1, 1 } }, // Skylake from http://www.agner.org/
1018 { ISD::FDIV, MVT::v2f64, { 4, 14, 1, 1 } }, // Skylake from http://www.agner.org/
1019 { ISD::FDIV, MVT::v4f64, { 8, 14, 1, 1 } }, // Skylake from http://www.agner.org/
1020 { ISD::FDIV, MVT::v8f64, { 16, 23, 1, 3 } }, // Skylake from http://www.agner.org/
1021
1022 { ISD::FNEG, MVT::v16f32, { 1, 1, 1, 2 } }, // Skylake from http://www.agner.org/
1023 { ISD::FADD, MVT::v16f32, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1024 { ISD::FADD, MVT::v8f32, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1025 { ISD::FSUB, MVT::v16f32, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1026 { ISD::FSUB, MVT::v8f32, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1027 { ISD::FMUL, MVT::v16f32, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1028 { ISD::FMUL, MVT::v8f32, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1029 { ISD::FMUL, MVT::v4f32, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1030 { ISD::FMUL, MVT::f32, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1031
1032 { ISD::FDIV, MVT::f32, { 3, 11, 1, 1 } }, // Skylake from http://www.agner.org/
1033 { ISD::FDIV, MVT::v4f32, { 3, 11, 1, 1 } }, // Skylake from http://www.agner.org/
1034 { ISD::FDIV, MVT::v8f32, { 5, 11, 1, 1 } }, // Skylake from http://www.agner.org/
1035 { ISD::FDIV, MVT::v16f32, { 10, 18, 1, 3 } }, // Skylake from http://www.agner.org/
1036 };
1037
1038 if (ST->hasAVX512())
1039 if (const auto *Entry = CostTableLookup(AVX512CostTable, ISD, LT.second))
1040 if (auto KindCost = Entry->Cost[CostKind])
1041 return LT.first * *KindCost;
1042
1043 static const CostKindTblEntry AVX2ShiftCostTable[] = {
1044 // Shifts on vXi64/vXi32 on AVX2 is legal even though we declare to
1045 // customize them to detect the cases where shift amount is a scalar one.
1046 { ISD::SHL, MVT::v4i32, { 2, 3, 1, 3 } }, // vpsllvd (Haswell from agner.org)
1047 { ISD::SRL, MVT::v4i32, { 2, 3, 1, 3 } }, // vpsrlvd (Haswell from agner.org)
1048 { ISD::SRA, MVT::v4i32, { 2, 3, 1, 3 } }, // vpsravd (Haswell from agner.org)
1049 { ISD::SHL, MVT::v8i32, { 4, 4, 1, 3 } }, // vpsllvd (Haswell from agner.org)
1050 { ISD::SRL, MVT::v8i32, { 4, 4, 1, 3 } }, // vpsrlvd (Haswell from agner.org)
1051 { ISD::SRA, MVT::v8i32, { 4, 4, 1, 3 } }, // vpsravd (Haswell from agner.org)
1052 { ISD::SHL, MVT::v2i64, { 2, 3, 1, 1 } }, // vpsllvq (Haswell from agner.org)
1053 { ISD::SRL, MVT::v2i64, { 2, 3, 1, 1 } }, // vpsrlvq (Haswell from agner.org)
1054 { ISD::SHL, MVT::v4i64, { 4, 4, 1, 2 } }, // vpsllvq (Haswell from agner.org)
1055 { ISD::SRL, MVT::v4i64, { 4, 4, 1, 2 } }, // vpsrlvq (Haswell from agner.org)
1056 };
1057
1058 if (ST->hasAVX512()) {
1059 if (ISD == ISD::SHL && LT.second == MVT::v32i16 && Op2Info.isConstant())
1060 // On AVX512, a packed v32i16 shift left by a constant build_vector
1061 // is lowered into a vector multiply (vpmullw).
1062 return getArithmeticInstrCost(Instruction::Mul, Ty, CostKind,
1063 Op1Info.getNoProps(), Op2Info.getNoProps());
1064 }
1065
1066 // Look for AVX2 lowering tricks (XOP is always better at v4i32 shifts).
1067 if (ST->hasAVX2() && !(ST->hasXOP() && LT.second == MVT::v4i32)) {
1068 if (ISD == ISD::SHL && LT.second == MVT::v16i16 &&
1069 Op2Info.isConstant())
1070 // On AVX2, a packed v16i16 shift left by a constant build_vector
1071 // is lowered into a vector multiply (vpmullw).
1072 return getArithmeticInstrCost(Instruction::Mul, Ty, CostKind,
1073 Op1Info.getNoProps(), Op2Info.getNoProps());
1074
1075 if (const auto *Entry = CostTableLookup(AVX2ShiftCostTable, ISD, LT.second))
1076 if (auto KindCost = Entry->Cost[CostKind])
1077 return LT.first * *KindCost;
1078 }
1079
1080 static const CostKindTblEntry XOPShiftCostTable[] = {
1081 // 128bit shifts take 1cy, but right shifts require negation beforehand.
1082 { ISD::SHL, MVT::v16i8, { 1, 3, 1, 1 } },
1083 { ISD::SRL, MVT::v16i8, { 2, 3, 1, 1 } },
1084 { ISD::SRA, MVT::v16i8, { 2, 3, 1, 1 } },
1085 { ISD::SHL, MVT::v8i16, { 1, 3, 1, 1 } },
1086 { ISD::SRL, MVT::v8i16, { 2, 3, 1, 1 } },
1087 { ISD::SRA, MVT::v8i16, { 2, 3, 1, 1 } },
1088 { ISD::SHL, MVT::v4i32, { 1, 3, 1, 1 } },
1089 { ISD::SRL, MVT::v4i32, { 2, 3, 1, 1 } },
1090 { ISD::SRA, MVT::v4i32, { 2, 3, 1, 1 } },
1091 { ISD::SHL, MVT::v2i64, { 1, 3, 1, 1 } },
1092 { ISD::SRL, MVT::v2i64, { 2, 3, 1, 1 } },
1093 { ISD::SRA, MVT::v2i64, { 2, 3, 1, 1 } },
1094 // 256bit shifts require splitting if AVX2 didn't catch them above.
1095 { ISD::SHL, MVT::v32i8, { 4, 7, 5, 6 } },
1096 { ISD::SRL, MVT::v32i8, { 6, 7, 5, 6 } },
1097 { ISD::SRA, MVT::v32i8, { 6, 7, 5, 6 } },
1098 { ISD::SHL, MVT::v16i16, { 4, 7, 5, 6 } },
1099 { ISD::SRL, MVT::v16i16, { 6, 7, 5, 6 } },
1100 { ISD::SRA, MVT::v16i16, { 6, 7, 5, 6 } },
1101 { ISD::SHL, MVT::v8i32, { 4, 7, 5, 6 } },
1102 { ISD::SRL, MVT::v8i32, { 6, 7, 5, 6 } },
1103 { ISD::SRA, MVT::v8i32, { 6, 7, 5, 6 } },
1104 { ISD::SHL, MVT::v4i64, { 4, 7, 5, 6 } },
1105 { ISD::SRL, MVT::v4i64, { 6, 7, 5, 6 } },
1106 { ISD::SRA, MVT::v4i64, { 6, 7, 5, 6 } },
1107 };
1108
1109 // Look for XOP lowering tricks.
1110 if (ST->hasXOP()) {
1111 // If the right shift is constant then we'll fold the negation so
1112 // it's as cheap as a left shift.
1113 int ShiftISD = ISD;
1114 if ((ShiftISD == ISD::SRL || ShiftISD == ISD::SRA) && Op2Info.isConstant())
1115 ShiftISD = ISD::SHL;
1116 if (const auto *Entry =
1117 CostTableLookup(XOPShiftCostTable, ShiftISD, LT.second))
1118 if (auto KindCost = Entry->Cost[CostKind])
1119 return LT.first * *KindCost;
1120 }
1121
1122 if (ISD == ISD::SHL && !Op2Info.isUniform() && Op2Info.isConstant()) {
1123 MVT VT = LT.second;
1124 // Vector shift left by non uniform constant can be lowered
1125 // into vector multiply.
1126 if (((VT == MVT::v8i16 || VT == MVT::v4i32) && ST->hasSSE2()) ||
1127 ((VT == MVT::v16i16 || VT == MVT::v8i32) && ST->hasAVX()))
1128 ISD = ISD::MUL;
1129 }
1130
1131 static const CostKindTblEntry GLMCostTable[] = {
1132 { ISD::FDIV, MVT::f32, { 18, 19, 1, 1 } }, // divss
1133 { ISD::FDIV, MVT::v4f32, { 35, 36, 1, 1 } }, // divps
1134 { ISD::FDIV, MVT::f64, { 33, 34, 1, 1 } }, // divsd
1135 { ISD::FDIV, MVT::v2f64, { 65, 66, 1, 1 } }, // divpd
1136 };
1137
1138 if (ST->useGLMDivSqrtCosts())
1139 if (const auto *Entry = CostTableLookup(GLMCostTable, ISD, LT.second))
1140 if (auto KindCost = Entry->Cost[CostKind])
1141 return LT.first * *KindCost;
1142
1143 static const CostKindTblEntry SLMCostTable[] = {
1144 { ISD::MUL, MVT::v4i32, { 11, 11, 1, 7 } }, // pmulld
1145 { ISD::MUL, MVT::v8i16, { 2, 5, 1, 1 } }, // pmullw
1146 { ISD::FMUL, MVT::f64, { 2, 5, 1, 1 } }, // mulsd
1147 { ISD::FMUL, MVT::f32, { 1, 4, 1, 1 } }, // mulss
1148 { ISD::FMUL, MVT::v2f64, { 4, 7, 1, 1 } }, // mulpd
1149 { ISD::FMUL, MVT::v4f32, { 2, 5, 1, 1 } }, // mulps
1150 { ISD::FDIV, MVT::f32, { 17, 19, 1, 1 } }, // divss
1151 { ISD::FDIV, MVT::v4f32, { 39, 39, 1, 6 } }, // divps
1152 { ISD::FDIV, MVT::f64, { 32, 34, 1, 1 } }, // divsd
1153 { ISD::FDIV, MVT::v2f64, { 69, 69, 1, 6 } }, // divpd
1154 { ISD::FADD, MVT::v2f64, { 2, 4, 1, 1 } }, // addpd
1155 { ISD::FSUB, MVT::v2f64, { 2, 4, 1, 1 } }, // subpd
1156 // v2i64/v4i64 mul is custom lowered as a series of long:
1157 // multiplies(3), shifts(3) and adds(2)
1158 // slm muldq version throughput is 2 and addq throughput 4
1159 // thus: 3X2 (muldq throughput) + 3X1 (shift throughput) +
1160 // 3X4 (addq throughput) = 17
1161 { ISD::MUL, MVT::v2i64, { 17, 22, 9, 9 } },
1162 // slm addq\subq throughput is 4
1163 { ISD::ADD, MVT::v2i64, { 4, 2, 1, 2 } },
1164 { ISD::SUB, MVT::v2i64, { 4, 2, 1, 2 } },
1165 };
1166
1167 if (ST->useSLMArithCosts())
1168 if (const auto *Entry = CostTableLookup(SLMCostTable, ISD, LT.second))
1169 if (auto KindCost = Entry->Cost[CostKind])
1170 return LT.first * *KindCost;
1171
1172 static const CostKindTblEntry AVX2CostTable[] = {
1173 { ISD::SHL, MVT::v16i8, { 6, 21,11,16 } }, // vpblendvb sequence.
1174 { ISD::SHL, MVT::v32i8, { 6, 23,11,22 } }, // vpblendvb sequence.
1175 { ISD::SHL, MVT::v8i16, { 5, 18, 5,10 } }, // extend/vpsrlvd/pack sequence.
1176 { ISD::SHL, MVT::v16i16, { 8, 10,10,14 } }, // extend/vpsrlvd/pack sequence.
1177
1178 { ISD::SRL, MVT::v16i8, { 6, 27,12,18 } }, // vpblendvb sequence.
1179 { ISD::SRL, MVT::v32i8, { 8, 30,12,24 } }, // vpblendvb sequence.
1180 { ISD::SRL, MVT::v8i16, { 5, 11, 5,10 } }, // extend/vpsrlvd/pack sequence.
1181 { ISD::SRL, MVT::v16i16, { 8, 10,10,14 } }, // extend/vpsrlvd/pack sequence.
1182
1183 { ISD::SRA, MVT::v16i8, { 17, 17,24,30 } }, // vpblendvb sequence.
1184 { ISD::SRA, MVT::v32i8, { 18, 20,24,43 } }, // vpblendvb sequence.
1185 { ISD::SRA, MVT::v8i16, { 5, 11, 5,10 } }, // extend/vpsravd/pack sequence.
1186 { ISD::SRA, MVT::v16i16, { 8, 10,10,14 } }, // extend/vpsravd/pack sequence.
1187 { ISD::SRA, MVT::v2i64, { 4, 5, 5, 5 } }, // srl/xor/sub sequence.
1188 { ISD::SRA, MVT::v4i64, { 8, 8, 5, 9 } }, // srl/xor/sub sequence.
1189
1190 { ISD::SUB, MVT::v32i8, { 1, 1, 1, 2 } }, // psubb
1191 { ISD::ADD, MVT::v32i8, { 1, 1, 1, 2 } }, // paddb
1192 { ISD::SUB, MVT::v16i16, { 1, 1, 1, 2 } }, // psubw
1193 { ISD::ADD, MVT::v16i16, { 1, 1, 1, 2 } }, // paddw
1194 { ISD::SUB, MVT::v8i32, { 1, 1, 1, 2 } }, // psubd
1195 { ISD::ADD, MVT::v8i32, { 1, 1, 1, 2 } }, // paddd
1196 { ISD::SUB, MVT::v4i64, { 1, 1, 1, 2 } }, // psubq
1197 { ISD::ADD, MVT::v4i64, { 1, 1, 1, 2 } }, // paddq
1198
1199 { ISD::MUL, MVT::v16i8, { 5, 18, 6,12 } }, // extend/pmullw/pack
1200 { ISD::MUL, MVT::v32i8, { 4, 8, 8,16 } }, // pmaddubsw
1201 { ISD::MUL, MVT::v16i16, { 2, 5, 1, 2 } }, // pmullw
1202 { ISD::MUL, MVT::v8i32, { 4, 10, 1, 2 } }, // pmulld
1203 { ISD::MUL, MVT::v4i32, { 2, 10, 1, 2 } }, // pmulld
1204 { ISD::MUL, MVT::v4i64, { 6, 10, 8,13 } }, // 3*pmuludq/3*shift/2*add
1205 { ISD::MUL, MVT::v2i64, { 6, 10, 8, 8 } }, // 3*pmuludq/3*shift/2*add
1206
1207 { X86ISD::PMULUDQ, MVT::v4i64, { 1, 5, 1, 1 } },
1208
1209 { ISD::FNEG, MVT::v4f64, { 1, 1, 1, 2 } }, // vxorpd
1210 { ISD::FNEG, MVT::v8f32, { 1, 1, 1, 2 } }, // vxorps
1211
1212 { ISD::FADD, MVT::f64, { 1, 4, 1, 1 } }, // vaddsd
1213 { ISD::FADD, MVT::f32, { 1, 4, 1, 1 } }, // vaddss
1214 { ISD::FADD, MVT::v2f64, { 1, 4, 1, 1 } }, // vaddpd
1215 { ISD::FADD, MVT::v4f32, { 1, 4, 1, 1 } }, // vaddps
1216 { ISD::FADD, MVT::v4f64, { 1, 4, 1, 2 } }, // vaddpd
1217 { ISD::FADD, MVT::v8f32, { 1, 4, 1, 2 } }, // vaddps
1218
1219 { ISD::FSUB, MVT::f64, { 1, 4, 1, 1 } }, // vsubsd
1220 { ISD::FSUB, MVT::f32, { 1, 4, 1, 1 } }, // vsubss
1221 { ISD::FSUB, MVT::v2f64, { 1, 4, 1, 1 } }, // vsubpd
1222 { ISD::FSUB, MVT::v4f32, { 1, 4, 1, 1 } }, // vsubps
1223 { ISD::FSUB, MVT::v4f64, { 1, 4, 1, 2 } }, // vsubpd
1224 { ISD::FSUB, MVT::v8f32, { 1, 4, 1, 2 } }, // vsubps
1225
1226 { ISD::FMUL, MVT::f64, { 1, 5, 1, 1 } }, // vmulsd
1227 { ISD::FMUL, MVT::f32, { 1, 5, 1, 1 } }, // vmulss
1228 { ISD::FMUL, MVT::v2f64, { 1, 5, 1, 1 } }, // vmulpd
1229 { ISD::FMUL, MVT::v4f32, { 1, 5, 1, 1 } }, // vmulps
1230 { ISD::FMUL, MVT::v4f64, { 1, 5, 1, 2 } }, // vmulpd
1231 { ISD::FMUL, MVT::v8f32, { 1, 5, 1, 2 } }, // vmulps
1232
1233 { ISD::FDIV, MVT::f32, { 7, 13, 1, 1 } }, // vdivss
1234 { ISD::FDIV, MVT::v4f32, { 7, 13, 1, 1 } }, // vdivps
1235 { ISD::FDIV, MVT::v8f32, { 14, 21, 1, 3 } }, // vdivps
1236 { ISD::FDIV, MVT::f64, { 14, 20, 1, 1 } }, // vdivsd
1237 { ISD::FDIV, MVT::v2f64, { 14, 20, 1, 1 } }, // vdivpd
1238 { ISD::FDIV, MVT::v4f64, { 28, 35, 1, 3 } }, // vdivpd
1239 };
1240
1241 // Look for AVX2 lowering tricks for custom cases.
1242 if (ST->hasAVX2())
1243 if (const auto *Entry = CostTableLookup(AVX2CostTable, ISD, LT.second))
1244 if (auto KindCost = Entry->Cost[CostKind])
1245 return LT.first * *KindCost;
1246
1247 static const CostKindTblEntry AVX1CostTable[] = {
1248 // We don't have to scalarize unsupported ops. We can issue two half-sized
1249 // operations and we only need to extract the upper YMM half.
1250 // Two ops + 1 extract + 1 insert = 4.
1251 { ISD::MUL, MVT::v32i8, { 10, 11, 18, 19 } }, // pmaddubsw + split
1252 { ISD::MUL, MVT::v16i8, { 5, 6, 8, 12 } }, // 2*pmaddubsw/3*and/psllw/or
1253 { ISD::MUL, MVT::v16i16, { 4, 8, 5, 6 } }, // pmullw + split
1254 { ISD::MUL, MVT::v8i32, { 5, 8, 5, 10 } }, // pmulld + split
1255 { ISD::MUL, MVT::v4i32, { 2, 5, 1, 3 } }, // pmulld
1256 { ISD::MUL, MVT::v4i64, { 12, 15, 19, 20 } },
1257
1258 { X86ISD::PMULUDQ, MVT::v4i64, { 3, 5, 5, 6 } }, // pmuludq + split
1259
1260 { ISD::AND, MVT::v32i8, { 1, 1, 1, 2 } }, // vandps
1261 { ISD::AND, MVT::v16i16, { 1, 1, 1, 2 } }, // vandps
1262 { ISD::AND, MVT::v8i32, { 1, 1, 1, 2 } }, // vandps
1263 { ISD::AND, MVT::v4i64, { 1, 1, 1, 2 } }, // vandps
1264
1265 { ISD::OR, MVT::v32i8, { 1, 1, 1, 2 } }, // vorps
1266 { ISD::OR, MVT::v16i16, { 1, 1, 1, 2 } }, // vorps
1267 { ISD::OR, MVT::v8i32, { 1, 1, 1, 2 } }, // vorps
1268 { ISD::OR, MVT::v4i64, { 1, 1, 1, 2 } }, // vorps
1269
1270 { ISD::XOR, MVT::v32i8, { 1, 1, 1, 2 } }, // vxorps
1271 { ISD::XOR, MVT::v16i16, { 1, 1, 1, 2 } }, // vxorps
1272 { ISD::XOR, MVT::v8i32, { 1, 1, 1, 2 } }, // vxorps
1273 { ISD::XOR, MVT::v4i64, { 1, 1, 1, 2 } }, // vxorps
1274
1275 { ISD::SUB, MVT::v32i8, { 4, 2, 5, 6 } }, // psubb + split
1276 { ISD::ADD, MVT::v32i8, { 4, 2, 5, 6 } }, // paddb + split
1277 { ISD::SUB, MVT::v16i16, { 4, 2, 5, 6 } }, // psubw + split
1278 { ISD::ADD, MVT::v16i16, { 4, 2, 5, 6 } }, // paddw + split
1279 { ISD::SUB, MVT::v8i32, { 4, 2, 5, 6 } }, // psubd + split
1280 { ISD::ADD, MVT::v8i32, { 4, 2, 5, 6 } }, // paddd + split
1281 { ISD::SUB, MVT::v4i64, { 4, 2, 5, 6 } }, // psubq + split
1282 { ISD::ADD, MVT::v4i64, { 4, 2, 5, 6 } }, // paddq + split
1283 { ISD::SUB, MVT::v2i64, { 1, 1, 1, 1 } }, // psubq
1284 { ISD::ADD, MVT::v2i64, { 1, 1, 1, 1 } }, // paddq
1285
1286 { ISD::SHL, MVT::v16i8, { 10, 21,11,17 } }, // pblendvb sequence.
1287 { ISD::SHL, MVT::v32i8, { 22, 22,27,40 } }, // pblendvb sequence + split.
1288 { ISD::SHL, MVT::v8i16, { 6, 9,11,11 } }, // pblendvb sequence.
1289 { ISD::SHL, MVT::v16i16, { 13, 16,24,25 } }, // pblendvb sequence + split.
1290 { ISD::SHL, MVT::v4i32, { 3, 11, 4, 6 } }, // pslld/paddd/cvttps2dq/pmulld
1291 { ISD::SHL, MVT::v8i32, { 9, 11,12,17 } }, // pslld/paddd/cvttps2dq/pmulld + split
1292 { ISD::SHL, MVT::v2i64, { 2, 4, 4, 6 } }, // Shift each lane + blend.
1293 { ISD::SHL, MVT::v4i64, { 6, 7,11,15 } }, // Shift each lane + blend + split.
1294
1295 { ISD::SRL, MVT::v16i8, { 11, 27,12,18 } }, // pblendvb sequence.
1296 { ISD::SRL, MVT::v32i8, { 23, 23,30,43 } }, // pblendvb sequence + split.
1297 { ISD::SRL, MVT::v8i16, { 13, 16,14,22 } }, // pblendvb sequence.
1298 { ISD::SRL, MVT::v16i16, { 28, 30,31,48 } }, // pblendvb sequence + split.
1299 { ISD::SRL, MVT::v4i32, { 6, 7,12,16 } }, // Shift each lane + blend.
1300 { ISD::SRL, MVT::v8i32, { 14, 14,26,34 } }, // Shift each lane + blend + split.
1301 { ISD::SRL, MVT::v2i64, { 2, 4, 4, 6 } }, // Shift each lane + blend.
1302 { ISD::SRL, MVT::v4i64, { 6, 7,11,15 } }, // Shift each lane + blend + split.
1303
1304 { ISD::SRA, MVT::v16i8, { 21, 22,24,36 } }, // pblendvb sequence.
1305 { ISD::SRA, MVT::v32i8, { 44, 45,51,76 } }, // pblendvb sequence + split.
1306 { ISD::SRA, MVT::v8i16, { 13, 16,14,22 } }, // pblendvb sequence.
1307 { ISD::SRA, MVT::v16i16, { 28, 30,31,48 } }, // pblendvb sequence + split.
1308 { ISD::SRA, MVT::v4i32, { 6, 7,12,16 } }, // Shift each lane + blend.
1309 { ISD::SRA, MVT::v8i32, { 14, 14,26,34 } }, // Shift each lane + blend + split.
1310 { ISD::SRA, MVT::v2i64, { 5, 6,10,14 } }, // Shift each lane + blend.
1311 { ISD::SRA, MVT::v4i64, { 12, 12,22,30 } }, // Shift each lane + blend + split.
1312
1313 { ISD::FNEG, MVT::v4f64, { 2, 2, 1, 2 } }, // BTVER2 from http://www.agner.org/
1314 { ISD::FNEG, MVT::v8f32, { 2, 2, 1, 2 } }, // BTVER2 from http://www.agner.org/
1315
1316 { ISD::FADD, MVT::f64, { 1, 5, 1, 1 } }, // BDVER2 from http://www.agner.org/
1317 { ISD::FADD, MVT::f32, { 1, 5, 1, 1 } }, // BDVER2 from http://www.agner.org/
1318 { ISD::FADD, MVT::v2f64, { 1, 5, 1, 1 } }, // BDVER2 from http://www.agner.org/
1319 { ISD::FADD, MVT::v4f32, { 1, 5, 1, 1 } }, // BDVER2 from http://www.agner.org/
1320 { ISD::FADD, MVT::v4f64, { 2, 5, 1, 2 } }, // BDVER2 from http://www.agner.org/
1321 { ISD::FADD, MVT::v8f32, { 2, 5, 1, 2 } }, // BDVER2 from http://www.agner.org/
1322
1323 { ISD::FSUB, MVT::f64, { 1, 5, 1, 1 } }, // BDVER2 from http://www.agner.org/
1324 { ISD::FSUB, MVT::f32, { 1, 5, 1, 1 } }, // BDVER2 from http://www.agner.org/
1325 { ISD::FSUB, MVT::v2f64, { 1, 5, 1, 1 } }, // BDVER2 from http://www.agner.org/
1326 { ISD::FSUB, MVT::v4f32, { 1, 5, 1, 1 } }, // BDVER2 from http://www.agner.org/
1327 { ISD::FSUB, MVT::v4f64, { 2, 5, 1, 2 } }, // BDVER2 from http://www.agner.org/
1328 { ISD::FSUB, MVT::v8f32, { 2, 5, 1, 2 } }, // BDVER2 from http://www.agner.org/
1329
1330 { ISD::FMUL, MVT::f64, { 2, 5, 1, 1 } }, // BTVER2 from http://www.agner.org/
1331 { ISD::FMUL, MVT::f32, { 1, 5, 1, 1 } }, // BTVER2 from http://www.agner.org/
1332 { ISD::FMUL, MVT::v2f64, { 2, 5, 1, 1 } }, // BTVER2 from http://www.agner.org/
1333 { ISD::FMUL, MVT::v4f32, { 1, 5, 1, 1 } }, // BTVER2 from http://www.agner.org/
1334 { ISD::FMUL, MVT::v4f64, { 4, 5, 1, 2 } }, // BTVER2 from http://www.agner.org/
1335 { ISD::FMUL, MVT::v8f32, { 2, 5, 1, 2 } }, // BTVER2 from http://www.agner.org/
1336
1337 { ISD::FDIV, MVT::f32, { 14, 14, 1, 1 } }, // SNB from http://www.agner.org/
1338 { ISD::FDIV, MVT::v4f32, { 14, 14, 1, 1 } }, // SNB from http://www.agner.org/
1339 { ISD::FDIV, MVT::v8f32, { 28, 29, 1, 3 } }, // SNB from http://www.agner.org/
1340 { ISD::FDIV, MVT::f64, { 22, 22, 1, 1 } }, // SNB from http://www.agner.org/
1341 { ISD::FDIV, MVT::v2f64, { 22, 22, 1, 1 } }, // SNB from http://www.agner.org/
1342 { ISD::FDIV, MVT::v4f64, { 44, 45, 1, 3 } }, // SNB from http://www.agner.org/
1343 };
1344
1345 if (ST->hasAVX())
1346 if (const auto *Entry = CostTableLookup(AVX1CostTable, ISD, LT.second))
1347 if (auto KindCost = Entry->Cost[CostKind])
1348 return LT.first * *KindCost;
1349
1350 static const CostKindTblEntry SSE42CostTable[] = {
1351 { ISD::FADD, MVT::f64, { 1, 3, 1, 1 } }, // Nehalem from http://www.agner.org/
1352 { ISD::FADD, MVT::f32, { 1, 3, 1, 1 } }, // Nehalem from http://www.agner.org/
1353 { ISD::FADD, MVT::v2f64, { 1, 3, 1, 1 } }, // Nehalem from http://www.agner.org/
1354 { ISD::FADD, MVT::v4f32, { 1, 3, 1, 1 } }, // Nehalem from http://www.agner.org/
1355
1356 { ISD::FSUB, MVT::f64, { 1, 3, 1, 1 } }, // Nehalem from http://www.agner.org/
1357 { ISD::FSUB, MVT::f32 , { 1, 3, 1, 1 } }, // Nehalem from http://www.agner.org/
1358 { ISD::FSUB, MVT::v2f64, { 1, 3, 1, 1 } }, // Nehalem from http://www.agner.org/
1359 { ISD::FSUB, MVT::v4f32, { 1, 3, 1, 1 } }, // Nehalem from http://www.agner.org/
1360
1361 { ISD::FMUL, MVT::f64, { 1, 5, 1, 1 } }, // Nehalem from http://www.agner.org/
1362 { ISD::FMUL, MVT::f32, { 1, 5, 1, 1 } }, // Nehalem from http://www.agner.org/
1363 { ISD::FMUL, MVT::v2f64, { 1, 5, 1, 1 } }, // Nehalem from http://www.agner.org/
1364 { ISD::FMUL, MVT::v4f32, { 1, 5, 1, 1 } }, // Nehalem from http://www.agner.org/
1365
1366 { ISD::FDIV, MVT::f32, { 14, 14, 1, 1 } }, // Nehalem from http://www.agner.org/
1367 { ISD::FDIV, MVT::v4f32, { 14, 14, 1, 1 } }, // Nehalem from http://www.agner.org/
1368 { ISD::FDIV, MVT::f64, { 22, 22, 1, 1 } }, // Nehalem from http://www.agner.org/
1369 { ISD::FDIV, MVT::v2f64, { 22, 22, 1, 1 } }, // Nehalem from http://www.agner.org/
1370
1371 { ISD::MUL, MVT::v2i64, { 6, 10,10,10 } } // 3*pmuludq/3*shift/2*add
1372 };
1373
1374 if (ST->hasSSE42())
1375 if (const auto *Entry = CostTableLookup(SSE42CostTable, ISD, LT.second))
1376 if (auto KindCost = Entry->Cost[CostKind])
1377 return LT.first * *KindCost;
1378
1379 static const CostKindTblEntry SSE41CostTable[] = {
1380 { ISD::SHL, MVT::v16i8, { 15, 24,17,22 } }, // pblendvb sequence.
1381 { ISD::SHL, MVT::v8i16, { 11, 14,11,11 } }, // pblendvb sequence.
1382 { ISD::SHL, MVT::v4i32, { 14, 20, 4,10 } }, // pslld/paddd/cvttps2dq/pmulld
1383
1384 { ISD::SRL, MVT::v16i8, { 16, 27,18,24 } }, // pblendvb sequence.
1385 { ISD::SRL, MVT::v8i16, { 22, 26,23,27 } }, // pblendvb sequence.
1386 { ISD::SRL, MVT::v4i32, { 16, 17,15,19 } }, // Shift each lane + blend.
1387 { ISD::SRL, MVT::v2i64, { 4, 6, 5, 7 } }, // splat+shuffle sequence.
1388
1389 { ISD::SRA, MVT::v16i8, { 38, 41,30,36 } }, // pblendvb sequence.
1390 { ISD::SRA, MVT::v8i16, { 22, 26,23,27 } }, // pblendvb sequence.
1391 { ISD::SRA, MVT::v4i32, { 16, 17,15,19 } }, // Shift each lane + blend.
1392 { ISD::SRA, MVT::v2i64, { 8, 17, 5, 7 } }, // splat+shuffle sequence.
1393
1394 { ISD::MUL, MVT::v4i32, { 2, 11, 1, 1 } } // pmulld (Nehalem from agner.org)
1395 };
1396
1397 if (ST->hasSSE41())
1398 if (const auto *Entry = CostTableLookup(SSE41CostTable, ISD, LT.second))
1399 if (auto KindCost = Entry->Cost[CostKind])
1400 return LT.first * *KindCost;
1401
1402 static const CostKindTblEntry SSSE3CostTable[] = {
1403 { ISD::MUL, MVT::v16i8, { 5, 18,10,12 } }, // 2*pmaddubsw/3*and/psllw/or
1404 };
1405
1406 if (ST->hasSSSE3())
1407 if (const auto *Entry = CostTableLookup(SSSE3CostTable, ISD, LT.second))
1408 if (auto KindCost = Entry->Cost[CostKind])
1409 return LT.first * *KindCost;
1410
1411 static const CostKindTblEntry SSE2CostTable[] = {
1412 // We don't correctly identify costs of casts because they are marked as
1413 // custom.
1414 { ISD::SHL, MVT::v16i8, { 13, 21,26,28 } }, // cmpgtb sequence.
1415 { ISD::SHL, MVT::v8i16, { 24, 27,16,20 } }, // cmpgtw sequence.
1416 { ISD::SHL, MVT::v4i32, { 17, 19,10,12 } }, // pslld/paddd/cvttps2dq/pmuludq.
1417 { ISD::SHL, MVT::v2i64, { 4, 6, 5, 7 } }, // splat+shuffle sequence.
1418
1419 { ISD::SRL, MVT::v16i8, { 14, 28,27,30 } }, // cmpgtb sequence.
1420 { ISD::SRL, MVT::v8i16, { 16, 19,31,31 } }, // cmpgtw sequence.
1421 { ISD::SRL, MVT::v4i32, { 12, 12,15,19 } }, // Shift each lane + blend.
1422 { ISD::SRL, MVT::v2i64, { 4, 6, 5, 7 } }, // splat+shuffle sequence.
1423
1424 { ISD::SRA, MVT::v16i8, { 27, 30,54,54 } }, // unpacked cmpgtb sequence.
1425 { ISD::SRA, MVT::v8i16, { 16, 19,31,31 } }, // cmpgtw sequence.
1426 { ISD::SRA, MVT::v4i32, { 12, 12,15,19 } }, // Shift each lane + blend.
1427 { ISD::SRA, MVT::v2i64, { 8, 11,12,16 } }, // srl/xor/sub splat+shuffle sequence.
1428
1429 { ISD::AND, MVT::v16i8, { 1, 1, 1, 1 } }, // pand
1430 { ISD::AND, MVT::v8i16, { 1, 1, 1, 1 } }, // pand
1431 { ISD::AND, MVT::v4i32, { 1, 1, 1, 1 } }, // pand
1432 { ISD::AND, MVT::v2i64, { 1, 1, 1, 1 } }, // pand
1433
1434 { ISD::OR, MVT::v16i8, { 1, 1, 1, 1 } }, // por
1435 { ISD::OR, MVT::v8i16, { 1, 1, 1, 1 } }, // por
1436 { ISD::OR, MVT::v4i32, { 1, 1, 1, 1 } }, // por
1437 { ISD::OR, MVT::v2i64, { 1, 1, 1, 1 } }, // por
1438
1439 { ISD::XOR, MVT::v16i8, { 1, 1, 1, 1 } }, // pxor
1440 { ISD::XOR, MVT::v8i16, { 1, 1, 1, 1 } }, // pxor
1441 { ISD::XOR, MVT::v4i32, { 1, 1, 1, 1 } }, // pxor
1442 { ISD::XOR, MVT::v2i64, { 1, 1, 1, 1 } }, // pxor
1443
1444 { ISD::ADD, MVT::v2i64, { 1, 2, 1, 2 } }, // paddq
1445 { ISD::SUB, MVT::v2i64, { 1, 2, 1, 2 } }, // psubq
1446
1447 { ISD::MUL, MVT::v16i8, { 6, 18,12,12 } }, // 2*unpack/2*pmullw/2*and/pack
1448 { ISD::MUL, MVT::v8i16, { 1, 5, 1, 1 } }, // pmullw
1449 { ISD::MUL, MVT::v4i32, { 6, 8, 7, 7 } }, // 3*pmuludq/4*shuffle
1450 { ISD::MUL, MVT::v2i64, { 7, 10,10,10 } }, // 3*pmuludq/3*shift/2*add
1451
1452 { X86ISD::PMULUDQ, MVT::v2i64, { 1, 5, 1, 1 } },
1453
1454 { ISD::FDIV, MVT::f32, { 23, 23, 1, 1 } }, // Pentium IV from http://www.agner.org/
1455 { ISD::FDIV, MVT::v4f32, { 39, 39, 1, 1 } }, // Pentium IV from http://www.agner.org/
1456 { ISD::FDIV, MVT::f64, { 38, 38, 1, 1 } }, // Pentium IV from http://www.agner.org/
1457 { ISD::FDIV, MVT::v2f64, { 69, 69, 1, 1 } }, // Pentium IV from http://www.agner.org/
1458
1459 { ISD::FNEG, MVT::f32, { 1, 1, 1, 1 } }, // Pentium IV from http://www.agner.org/
1460 { ISD::FNEG, MVT::f64, { 1, 1, 1, 1 } }, // Pentium IV from http://www.agner.org/
1461 { ISD::FNEG, MVT::v4f32, { 1, 1, 1, 1 } }, // Pentium IV from http://www.agner.org/
1462 { ISD::FNEG, MVT::v2f64, { 1, 1, 1, 1 } }, // Pentium IV from http://www.agner.org/
1463
1464 { ISD::FADD, MVT::f32, { 2, 3, 1, 1 } }, // Pentium IV from http://www.agner.org/
1465 { ISD::FADD, MVT::f64, { 2, 3, 1, 1 } }, // Pentium IV from http://www.agner.org/
1466 { ISD::FADD, MVT::v2f64, { 2, 3, 1, 1 } }, // Pentium IV from http://www.agner.org/
1467
1468 { ISD::FSUB, MVT::f32, { 2, 3, 1, 1 } }, // Pentium IV from http://www.agner.org/
1469 { ISD::FSUB, MVT::f64, { 2, 3, 1, 1 } }, // Pentium IV from http://www.agner.org/
1470 { ISD::FSUB, MVT::v2f64, { 2, 3, 1, 1 } }, // Pentium IV from http://www.agner.org/
1471
1472 { ISD::FMUL, MVT::f64, { 2, 5, 1, 1 } }, // Pentium IV from http://www.agner.org/
1473 { ISD::FMUL, MVT::v2f64, { 2, 5, 1, 1 } }, // Pentium IV from http://www.agner.org/
1474 };
1475
1476 if (ST->hasSSE2())
1477 if (const auto *Entry = CostTableLookup(SSE2CostTable, ISD, LT.second))
1478 if (auto KindCost = Entry->Cost[CostKind])
1479 return LT.first * *KindCost;
1480
1481 static const CostKindTblEntry SSE1CostTable[] = {
1482 { ISD::FDIV, MVT::f32, { 17, 18, 1, 1 } }, // Pentium III from http://www.agner.org/
1483 { ISD::FDIV, MVT::v4f32, { 34, 48, 1, 1 } }, // Pentium III from http://www.agner.org/
1484
1485 { ISD::FNEG, MVT::f32, { 2, 2, 1, 2 } }, // Pentium III from http://www.agner.org/
1486 { ISD::FNEG, MVT::v4f32, { 2, 2, 1, 2 } }, // Pentium III from http://www.agner.org/
1487
1488 { ISD::FADD, MVT::f32, { 1, 3, 1, 1 } }, // Pentium III from http://www.agner.org/
1489 { ISD::FADD, MVT::v4f32, { 2, 3, 1, 1 } }, // Pentium III from http://www.agner.org/
1490
1491 { ISD::FSUB, MVT::f32, { 1, 3, 1, 1 } }, // Pentium III from http://www.agner.org/
1492 { ISD::FSUB, MVT::v4f32, { 2, 3, 1, 1 } }, // Pentium III from http://www.agner.org/
1493
1494 { ISD::FMUL, MVT::f32, { 2, 5, 1, 1 } }, // Pentium III from http://www.agner.org/
1495 { ISD::FMUL, MVT::v4f32, { 2, 5, 1, 1 } }, // Pentium III from http://www.agner.org/
1496 };
1497
1498 if (ST->hasSSE1())
1499 if (const auto *Entry = CostTableLookup(SSE1CostTable, ISD, LT.second))
1500 if (auto KindCost = Entry->Cost[CostKind])
1501 return LT.first * *KindCost;
1502
1503 static const CostKindTblEntry X64CostTbl[] = { // 64-bit targets
1504 { ISD::ADD, MVT::i64, { 1 } }, // Core (Merom) from http://www.agner.org/
1505 { ISD::SUB, MVT::i64, { 1 } }, // Core (Merom) from http://www.agner.org/
1506 { ISD::MUL, MVT::i64, { 2, 6, 1, 2 } },
1507 };
1508
1509 if (ST->is64Bit())
1510 if (const auto *Entry = CostTableLookup(X64CostTbl, ISD, LT.second))
1511 if (auto KindCost = Entry->Cost[CostKind])
1512 return LT.first * *KindCost;
1513
1514 static const CostKindTblEntry X86CostTbl[] = { // 32 or 64-bit targets
1515 { ISD::ADD, MVT::i8, { 1 } }, // Pentium III from http://www.agner.org/
1516 { ISD::ADD, MVT::i16, { 1 } }, // Pentium III from http://www.agner.org/
1517 { ISD::ADD, MVT::i32, { 1 } }, // Pentium III from http://www.agner.org/
1518
1519 { ISD::SUB, MVT::i8, { 1 } }, // Pentium III from http://www.agner.org/
1520 { ISD::SUB, MVT::i16, { 1 } }, // Pentium III from http://www.agner.org/
1521 { ISD::SUB, MVT::i32, { 1 } }, // Pentium III from http://www.agner.org/
1522
1523 { ISD::MUL, MVT::i8, { 3, 4, 1, 1 } },
1524 { ISD::MUL, MVT::i16, { 2, 4, 1, 1 } },
1525 { ISD::MUL, MVT::i32, { 1, 4, 1, 1 } },
1526
1527 { ISD::FNEG, MVT::f64, { 2, 2, 1, 3 } }, // (x87)
1528 { ISD::FADD, MVT::f64, { 2, 3, 1, 1 } }, // (x87)
1529 { ISD::FSUB, MVT::f64, { 2, 3, 1, 1 } }, // (x87)
1530 { ISD::FMUL, MVT::f64, { 2, 5, 1, 1 } }, // (x87)
1531 { ISD::FDIV, MVT::f64, { 38, 38, 1, 1 } }, // (x87)
1532 };
1533
1534 if (const auto *Entry = CostTableLookup(X86CostTbl, ISD, LT.second))
1535 if (auto KindCost = Entry->Cost[CostKind])
1536 return LT.first * *KindCost;
1537
1538 // It is not a good idea to vectorize division. We have to scalarize it and
1539 // in the process we will often end up having to spilling regular
1540 // registers. The overhead of division is going to dominate most kernels
1541 // anyways so try hard to prevent vectorization of division - it is
1542 // generally a bad idea. Assume somewhat arbitrarily that we have to be able
1543 // to hide "20 cycles" for each lane.
1544 if (CostKind == TTI::TCK_RecipThroughput && LT.second.isVector() &&
1545 (ISD == ISD::SDIV || ISD == ISD::SREM || ISD == ISD::UDIV ||
1546 ISD == ISD::UREM)) {
1547 InstructionCost ScalarCost =
1548 getArithmeticInstrCost(Opcode, Ty->getScalarType(), CostKind,
1549 Op1Info.getNoProps(), Op2Info.getNoProps());
1550 return 20 * LT.first * LT.second.getVectorNumElements() * ScalarCost;
1551 }
1552
1553 // Handle some basic single instruction code size cases.
1554 if (CostKind == TTI::TCK_CodeSize) {
1555 switch (ISD) {
1556 case ISD::FADD:
1557 case ISD::FSUB:
1558 case ISD::FMUL:
1559 case ISD::FDIV:
1560 case ISD::FNEG:
1561 case ISD::AND:
1562 case ISD::OR:
1563 case ISD::XOR:
1564 return LT.first;
1565 break;
1566 }
1567 }
1568
1569 // Fallback to the default implementation.
1570 return BaseT::getArithmeticInstrCost(Opcode, Ty, CostKind, Op1Info, Op2Info,
1571 Args, CxtI);
1572}
1573
1576 unsigned Opcode1, const SmallBitVector &OpcodeMask,
1578 if (isLegalAltInstr(VecTy, Opcode0, Opcode1, OpcodeMask))
1579 return TTI::TCC_Basic;
1581}
1582
1584 VectorType *DstTy, VectorType *SrcTy,
1585 ArrayRef<int> Mask,
1587 int Index, VectorType *SubTp,
1589 const Instruction *CxtI) const {
1590 assert((Mask.empty() || DstTy->isScalableTy() ||
1591 Mask.size() == DstTy->getElementCount().getKnownMinValue()) &&
1592 "Expected the Mask to match the return size if given");
1593 assert(SrcTy->getScalarType() == DstTy->getScalarType() &&
1594 "Expected the same scalar types");
1595
1596 // 64-bit packed float vectors (v2f32) are widened to type v4f32.
1597 // 64-bit packed integer vectors (v2i32) are widened to type v4i32.
1598 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(SrcTy);
1599
1600 Kind = improveShuffleKindFromMask(Kind, Mask, SrcTy, Index, SubTp);
1601
1602 // If all args are constant than this will be constant folded away.
1603 if (!Args.empty() &&
1604 all_of(Args, [](const Value *Arg) { return isa<Constant>(Arg); }))
1605 return TTI::TCC_Free;
1606
1607 // Recognize a basic concat_vector shuffle.
1608 if (Kind == TTI::SK_PermuteTwoSrc &&
1609 Mask.size() == (2 * SrcTy->getElementCount().getKnownMinValue()) &&
1610 ShuffleVectorInst::isIdentityMask(Mask, Mask.size()))
1614 CostKind, Mask.size() / 2, SrcTy);
1615
1616 // Treat Transpose as 2-op shuffles - there's no difference in lowering.
1617 if (Kind == TTI::SK_Transpose)
1618 if (LT.second != MVT::v4f64 && LT.second != MVT::v4i64)
1619 Kind = TTI::SK_PermuteTwoSrc;
1620
1621 if (Kind == TTI::SK_Broadcast) {
1622 // For Broadcasts we are splatting the first element from the first input
1623 // register, so only need to reference that input and all the output
1624 // registers are the same.
1625 LT.first = 1;
1626
1627 // If we're broadcasting a load then AVX/AVX2 can do this for free.
1628 // If many-used-load whose every use is one of a small set of operations
1629 // that SLP can rewrite into a single vector lane, codegen can fold it into
1630 // the free broadcast.
1631 using namespace PatternMatch;
1632 auto IsBroadcastLoadFoldUser = [&](const User *U) {
1633 if (isa<InsertElementInst>(U) && U->getOperand(1) == Args[0])
1634 return true;
1635 if (U->getType()->isVectorTy())
1636 return false;
1637 // Terminators (return/branch/switch/indirectbr/resume/invoke EH)
1638 // and phis carry the value across control flow.
1639 if (const auto *I = dyn_cast<Instruction>(U))
1640 if (I->isTerminator() ||
1642 return false;
1643 // Only pure calls can be folded.
1644 if (const auto *CB = dyn_cast<CallBase>(U))
1645 return CB->doesNotAccessMemory() && !CB->mayHaveSideEffects();
1646 return true;
1647 };
1648 auto IsFoldableSLPBroadcastLoad = [&]() {
1649 if (!match(Args[0], m_Load(m_Value())))
1650 return false;
1651 auto *FVT = dyn_cast<FixedVectorType>(DstTy);
1652 if (!FVT)
1653 return false;
1654 // getNumUses() counts each Use, matching the per-lane broadcast
1655 // accounting (a use like `op %x, %x` consumes two broadcast lanes).
1656 if (Args[0]->getNumUses() != FVT->getNumElements())
1657 return false;
1658 return all_of(Args[0]->users(), IsBroadcastLoadFoldUser);
1659 };
1660 if (!Args.empty() &&
1661 (match(Args[0], m_OneUse(m_Load(m_Value()))) ||
1662 IsFoldableSLPBroadcastLoad()) &&
1663 (ST->hasAVX2() ||
1664 (ST->hasAVX() && LT.second.getScalarSizeInBits() >= 32)))
1665 return TTI::TCC_Free;
1666 }
1667
1668 // Attempt to detect a cheaper inlane shuffle, avoiding 128-bit subvector
1669 // permutation.
1670 // Attempt to detect a shuffle mask with a single defined element.
1671 bool IsInLaneShuffle = false;
1672 bool IsSingleElementMask = false;
1673 if (SrcTy->getPrimitiveSizeInBits() > 0 &&
1674 (SrcTy->getPrimitiveSizeInBits() % 128) == 0 &&
1675 SrcTy->getScalarSizeInBits() == LT.second.getScalarSizeInBits() &&
1676 Mask.size() == SrcTy->getElementCount().getKnownMinValue()) {
1677 unsigned NumLanes = SrcTy->getPrimitiveSizeInBits() / 128;
1678 unsigned NumEltsPerLane = Mask.size() / NumLanes;
1679 if ((Mask.size() % NumLanes) == 0) {
1680 IsInLaneShuffle = all_of(enumerate(Mask), [&](const auto &P) {
1681 return P.value() == PoisonMaskElem ||
1682 ((P.value() % Mask.size()) / NumEltsPerLane) ==
1683 (P.index() / NumEltsPerLane);
1684 });
1685 IsSingleElementMask =
1686 (Mask.size() - 1) == static_cast<unsigned>(count_if(Mask, [](int M) {
1687 return M == PoisonMaskElem;
1688 }));
1689 }
1690 }
1691
1692 // Treat <X x bfloat> shuffles as <X x half>.
1693 if (LT.second.isVectorOf(MVT::bf16))
1694 LT.second = LT.second.changeVectorElementType(MVT::f16);
1695
1696 // Subvector extractions are free if they start at the beginning of a
1697 // vector and cheap if the subvectors are aligned.
1698 if (Kind == TTI::SK_ExtractSubvector && LT.second.isVector()) {
1699 int NumElts = LT.second.getVectorNumElements();
1700 if ((Index % NumElts) == 0)
1701 return TTI::TCC_Free;
1702 std::pair<InstructionCost, MVT> SubLT = getTypeLegalizationCost(SubTp);
1703 if (SubLT.second.isVector()) {
1704 int NumSubElts = SubLT.second.getVectorNumElements();
1705 if ((Index % NumSubElts) == 0 && (NumElts % NumSubElts) == 0)
1706 return SubLT.first;
1707 // Handle some cases for widening legalization. For now we only handle
1708 // cases where the original subvector was naturally aligned and evenly
1709 // fit in its legalized subvector type.
1710 // FIXME: Remove some of the alignment restrictions.
1711 // FIXME: We can use permq for 64-bit or larger extracts from 256-bit
1712 // vectors.
1713 int OrigSubElts = cast<FixedVectorType>(SubTp)->getNumElements();
1714 if (NumSubElts > OrigSubElts && (Index % OrigSubElts) == 0 &&
1715 (NumSubElts % OrigSubElts) == 0 &&
1716 LT.second.getVectorElementType() ==
1717 SubLT.second.getVectorElementType() &&
1718 LT.second.getVectorElementType().getSizeInBits() ==
1719 SrcTy->getElementType()->getPrimitiveSizeInBits()) {
1720 assert(NumElts >= NumSubElts && NumElts > OrigSubElts &&
1721 "Unexpected number of elements!");
1722 auto *VecTy = FixedVectorType::get(SrcTy->getElementType(),
1723 LT.second.getVectorNumElements());
1724 auto *SubTy = FixedVectorType::get(SrcTy->getElementType(),
1725 SubLT.second.getVectorNumElements());
1726 int ExtractIndex = alignDown((Index % NumElts), NumSubElts);
1727 InstructionCost ExtractCost =
1729 ExtractIndex, SubTy);
1730
1731 // If the original size is 32-bits or more, we can use pshufd. Otherwise
1732 // if we have SSSE3 we can use pshufb.
1733 if (SubTp->getPrimitiveSizeInBits() >= 32 || ST->hasSSSE3())
1734 return ExtractCost + 1; // pshufd or pshufb
1735
1736 assert(SubTp->getPrimitiveSizeInBits() == 16 &&
1737 "Unexpected vector size");
1738
1739 return ExtractCost + 2; // worst case pshufhw + pshufd
1740 }
1741 }
1742 // If the extract subvector is not optimal, treat it as single op shuffle.
1744 }
1745
1746 // Subvector insertions are cheap if the subvectors are aligned.
1747 // Note that in general, the insertion starting at the beginning of a vector
1748 // isn't free, because we need to preserve the rest of the wide vector,
1749 // but if the destination vector legalizes to the same width as the subvector
1750 // then the insertion will simplify to a (free) register copy.
1751 if (Kind == TTI::SK_InsertSubvector && LT.second.isVector()) {
1752 std::pair<InstructionCost, MVT> DstLT = getTypeLegalizationCost(DstTy);
1753 int NumElts = DstLT.second.getVectorNumElements();
1754 std::pair<InstructionCost, MVT> SubLT = getTypeLegalizationCost(SubTp);
1755 if (SubLT.second.isVector()) {
1756 int NumSubElts = SubLT.second.getVectorNumElements();
1757 bool MatchingTypes =
1758 NumElts == NumSubElts &&
1759 (SubTp->getElementCount().getKnownMinValue() % NumSubElts) == 0;
1760 if ((Index % NumSubElts) == 0 && (NumElts % NumSubElts) == 0)
1761 return MatchingTypes ? TTI::TCC_Free : SubLT.first;
1762 }
1763
1764 // Attempt to match MOVSS (Idx == 0) or INSERTPS pattern. This will have
1765 // been matched by improveShuffleKindFromMask as a SK_InsertSubvector of
1766 // v1f32 (legalised to f32) into a v4f32.
1767 if (LT.first == 1 && LT.second == MVT::v4f32 && SubLT.first == 1 &&
1768 SubLT.second == MVT::f32 && (Index == 0 || ST->hasSSE41()))
1769 return 1;
1770
1771 // If the insertion is the lowest subvector then it will be blended
1772 // otherwise treat it like a 2-op shuffle.
1773 Kind =
1774 (Index == 0 && LT.first == 1) ? TTI::SK_Select : TTI::SK_PermuteTwoSrc;
1775 }
1776
1777 // Handle some common (illegal) sub-vector types as they are often very cheap
1778 // to shuffle even on targets without PSHUFB.
1779 EVT VT = TLI->getValueType(DL, SrcTy);
1780 if (VT.isSimple() && VT.isVector() && VT.getSizeInBits() < 128 &&
1781 !ST->hasSSSE3()) {
1782 static const CostKindTblEntry SSE2SubVectorShuffleTbl[] = {
1783 {TTI::SK_Broadcast, MVT::v4i16, {1,1,1,1}}, // pshuflw
1784 {TTI::SK_Broadcast, MVT::v2i16, {1,1,1,1}}, // pshuflw
1785 {TTI::SK_Broadcast, MVT::v8i8, {2,2,2,2}}, // punpck/pshuflw
1786 {TTI::SK_Broadcast, MVT::v4i8, {2,2,2,2}}, // punpck/pshuflw
1787 {TTI::SK_Broadcast, MVT::v2i8, {1,1,1,1}}, // punpck
1788
1789 {TTI::SK_Reverse, MVT::v4i16, {1,1,1,1}}, // pshuflw
1790 {TTI::SK_Reverse, MVT::v2i16, {1,1,1,1}}, // pshuflw
1791 {TTI::SK_Reverse, MVT::v4i8, {3,3,3,3}}, // punpck/pshuflw/packus
1792 {TTI::SK_Reverse, MVT::v2i8, {1,1,1,1}}, // punpck
1793
1794 {TTI::SK_Splice, MVT::v4i16, {2,2,2,2}}, // punpck+psrldq
1795 {TTI::SK_Splice, MVT::v2i16, {2,2,2,2}}, // punpck+psrldq
1796 {TTI::SK_Splice, MVT::v4i8, {2,2,2,2}}, // punpck+psrldq
1797 {TTI::SK_Splice, MVT::v2i8, {2,2,2,2}}, // punpck+psrldq
1798
1799 {TTI::SK_PermuteTwoSrc, MVT::v4i16, {2,2,2,2}}, // punpck/pshuflw
1800 {TTI::SK_PermuteTwoSrc, MVT::v2i16, {2,2,2,2}}, // punpck/pshuflw
1801 {TTI::SK_PermuteTwoSrc, MVT::v8i8, {7,7,7,7}}, // punpck/pshuflw
1802 {TTI::SK_PermuteTwoSrc, MVT::v4i8, {4,4,4,4}}, // punpck/pshuflw
1803 {TTI::SK_PermuteTwoSrc, MVT::v2i8, {2,2,2,2}}, // punpck
1804
1805 {TTI::SK_PermuteSingleSrc, MVT::v4i16, {1,1,1,1}}, // pshuflw
1806 {TTI::SK_PermuteSingleSrc, MVT::v2i16, {1,1,1,1}}, // pshuflw
1807 {TTI::SK_PermuteSingleSrc, MVT::v8i8, {5,5,5,5}}, // punpck/pshuflw
1808 {TTI::SK_PermuteSingleSrc, MVT::v4i8, {3,3,3,3}}, // punpck/pshuflw
1809 {TTI::SK_PermuteSingleSrc, MVT::v2i8, {1,1,1,1}}, // punpck
1810 };
1811
1812 if (ST->hasSSE2())
1813 if (const auto *Entry =
1814 CostTableLookup(SSE2SubVectorShuffleTbl, Kind, VT.getSimpleVT()))
1815 if (auto KindCost = Entry->Cost[CostKind])
1816 return LT.first * *KindCost;
1817 }
1818
1819 // We are going to permute multiple sources and the result will be in multiple
1820 // destinations. Providing an accurate cost only for splits where the element
1821 // type remains the same.
1822 if (LT.first != 1) {
1823 MVT LegalVT = LT.second;
1824 if (LegalVT.isVector() &&
1825 LegalVT.getVectorElementType().getSizeInBits() ==
1826 SrcTy->getElementType()->getPrimitiveSizeInBits() &&
1827 LegalVT.getVectorNumElements() <
1828 cast<FixedVectorType>(SrcTy)->getNumElements()) {
1829 unsigned VecTySize = DL.getTypeStoreSize(SrcTy);
1830 unsigned LegalVTSize = LegalVT.getStoreSize();
1831 // Number of source vectors after legalization:
1832 unsigned NumOfSrcs = (VecTySize + LegalVTSize - 1) / LegalVTSize;
1833 // Number of destination vectors after legalization:
1834 InstructionCost NumOfDests = LT.first;
1835
1836 auto *SingleOpTy = FixedVectorType::get(SrcTy->getElementType(),
1837 LegalVT.getVectorNumElements());
1838
1839 if (!Mask.empty() && NumOfDests.isValid()) {
1840 // Try to perform better estimation of the permutation.
1841 // 1. Split the source/destination vectors into real registers.
1842 // 2. Do the mask analysis to identify which real registers are
1843 // permuted. If more than 1 source registers are used for the
1844 // destination register building, the cost for this destination register
1845 // is (Number_of_source_register - 1) * Cost_PermuteTwoSrc. If only one
1846 // source register is used, build mask and calculate the cost as a cost
1847 // of PermuteSingleSrc.
1848 // Also, for the single register permute we try to identify if the
1849 // destination register is just a copy of the source register or the
1850 // copy of the previous destination register (the cost is
1851 // TTI::TCC_Basic). If the source register is just reused, the cost for
1852 // this operation is TTI::TCC_Free.
1853 NumOfDests =
1855 FixedVectorType::get(SrcTy->getElementType(), Mask.size()))
1856 .first;
1857 unsigned E = NumOfDests.getValue();
1858 unsigned NormalizedVF =
1859 LegalVT.getVectorNumElements() * std::max(NumOfSrcs, E);
1860 unsigned NumOfSrcRegs = NormalizedVF / LegalVT.getVectorNumElements();
1861 unsigned NumOfDestRegs = NormalizedVF / LegalVT.getVectorNumElements();
1862 SmallVector<int> NormalizedMask(NormalizedVF, PoisonMaskElem);
1863 copy(Mask, NormalizedMask.begin());
1864 unsigned PrevSrcReg = 0;
1865 ArrayRef<int> PrevRegMask;
1868 NormalizedMask, NumOfSrcRegs, NumOfDestRegs, NumOfDestRegs, []() {},
1869 [this, SingleOpTy, CostKind, &PrevSrcReg, &PrevRegMask,
1870 &Cost](ArrayRef<int> RegMask, unsigned SrcReg, unsigned DestReg) {
1871 if (!ShuffleVectorInst::isIdentityMask(RegMask, RegMask.size())) {
1872 // Check if the previous register can be just copied to the next
1873 // one.
1874 if (PrevRegMask.empty() || PrevSrcReg != SrcReg ||
1875 PrevRegMask != RegMask)
1876 Cost +=
1878 SingleOpTy, RegMask, CostKind, 0, nullptr);
1879 else
1880 // Just a copy of previous destination register.
1882 return;
1883 }
1884 if (SrcReg != DestReg &&
1885 any_of(RegMask, not_equal_to(PoisonMaskElem))) {
1886 // Just a copy of the source register.
1888 }
1889 PrevSrcReg = SrcReg;
1890 PrevRegMask = RegMask;
1891 },
1892 [this, SingleOpTy, CostKind,
1893 &Cost](ArrayRef<int> RegMask, unsigned /*Unused*/,
1894 unsigned /*Unused*/, bool /*Unused*/) {
1896 SingleOpTy, RegMask, CostKind, 0, nullptr);
1897 });
1898 return Cost;
1899 }
1900
1901 InstructionCost NumOfShuffles = (NumOfSrcs - 1) * NumOfDests;
1902 return NumOfShuffles * getShuffleCost(TTI::SK_PermuteTwoSrc, SingleOpTy,
1903 SingleOpTy, {}, CostKind, 0,
1904 nullptr);
1905 }
1906
1907 return BaseT::getShuffleCost(Kind, DstTy, SrcTy, Mask, CostKind, Index,
1908 SubTp);
1909 }
1910
1911 // If we're just moving a single element around (probably as an alternative to
1912 // extracting it), we can assume this is cheap.
1913 if (LT.first == 1 && IsInLaneShuffle && IsSingleElementMask)
1914 return TTI::TCC_Basic;
1915
1916 static const CostKindTblEntry AVX512VBMIShuffleTbl[] = {
1917 { TTI::SK_Reverse, MVT::v64i8, { 1, 1, 1, 1 } }, // vpermb
1918 { TTI::SK_Reverse, MVT::v32i8, { 1, 1, 1, 1 } }, // vpermb
1919 { TTI::SK_PermuteSingleSrc, MVT::v64i8, { 1, 1, 1, 1 } }, // vpermb
1920 { TTI::SK_PermuteSingleSrc, MVT::v32i8, { 1, 1, 1, 1 } }, // vpermb
1921 { TTI::SK_PermuteTwoSrc, MVT::v64i8, { 2, 2, 2, 2 } }, // vpermt2b
1922 { TTI::SK_PermuteTwoSrc, MVT::v32i8, { 2, 2, 2, 2 } }, // vpermt2b
1923 { TTI::SK_PermuteTwoSrc, MVT::v16i8, { 2, 2, 2, 2 } } // vpermt2b
1924 };
1925
1926 if (ST->hasVBMI())
1927 if (const auto *Entry =
1928 CostTableLookup(AVX512VBMIShuffleTbl, Kind, LT.second))
1929 if (auto KindCost = Entry->Cost[CostKind])
1930 return LT.first * *KindCost;
1931
1932 static const CostKindTblEntry AVX512BWShuffleTbl[] = {
1933 { TTI::SK_Broadcast, MVT::v32i16, { 1, 3, 1, 1 } }, // vpbroadcastw
1934 { TTI::SK_Broadcast, MVT::v32f16, { 1, 3, 1, 1 } }, // vpbroadcastw
1935 { TTI::SK_Broadcast, MVT::v64i8, { 1, 3, 1, 1 } }, // vpbroadcastb
1936
1937 { TTI::SK_Reverse, MVT::v32i16, { 2, 6, 2, 4 } }, // vpermw
1938 { TTI::SK_Reverse, MVT::v32f16, { 2, 6, 2, 4 } }, // vpermw
1939 { TTI::SK_Reverse, MVT::v16i16, { 2, 2, 2, 2 } }, // vpermw
1940 { TTI::SK_Reverse, MVT::v16f16, { 2, 2, 2, 2 } }, // vpermw
1941 { TTI::SK_Reverse, MVT::v64i8, { 2, 9, 2, 3 } }, // pshufb + vshufi64x2
1942
1943 { TTI::SK_PermuteSingleSrc, MVT::v32i16, { 2, 2, 2, 2 } }, // vpermw
1944 { TTI::SK_PermuteSingleSrc, MVT::v32f16, { 2, 2, 2, 2 } }, // vpermw
1945 { TTI::SK_PermuteSingleSrc, MVT::v16i16, { 2, 2, 2, 2 } }, // vpermw
1946 { TTI::SK_PermuteSingleSrc, MVT::v16f16, { 2, 2, 2, 2 } }, // vpermw
1947 { TTI::SK_PermuteSingleSrc, MVT::v64i8, { 8, 8, 8, 8 } }, // extend to v32i16
1948
1949 { TTI::SK_PermuteTwoSrc, MVT::v32i16,{ 2, 2, 2, 2 } }, // vpermt2w
1950 { TTI::SK_PermuteTwoSrc, MVT::v32f16,{ 2, 2, 2, 2 } }, // vpermt2w
1951 { TTI::SK_PermuteTwoSrc, MVT::v16i16,{ 2, 2, 2, 2 } }, // vpermt2w
1952 { TTI::SK_PermuteTwoSrc, MVT::v8i16, { 2, 2, 2, 2 } }, // vpermt2w
1953 { TTI::SK_PermuteTwoSrc, MVT::v64i8, { 19, 19, 19, 19 } }, // 6 * v32i8 + 1
1954
1955 { TTI::SK_Select, MVT::v32i16, { 1, 1, 1, 1 } }, // vblendmw
1956 { TTI::SK_Select, MVT::v64i8, { 1, 1, 1, 1 } }, // vblendmb
1957
1958 { TTI::SK_Splice, MVT::v32i16, { 2, 2, 2, 2 } }, // vshufi64x2 + palignr
1959 { TTI::SK_Splice, MVT::v32f16, { 2, 2, 2, 2 } }, // vshufi64x2 + palignr
1960 { TTI::SK_Splice, MVT::v64i8, { 2, 2, 2, 2 } }, // vshufi64x2 + palignr
1961 };
1962
1963 if (ST->hasBWI())
1964 if (const auto *Entry =
1965 CostTableLookup(AVX512BWShuffleTbl, Kind, LT.second))
1966 if (auto KindCost = Entry->Cost[CostKind])
1967 return LT.first * *KindCost;
1968
1969 static const CostKindTblEntry AVX512InLaneShuffleTbl[] = {
1970 {TTI::SK_PermuteTwoSrc, MVT::v8f64, { 1, 3, 1, 1 } },
1971 {TTI::SK_PermuteTwoSrc, MVT::v16f32, { 1, 3, 1, 1 } },
1972 {TTI::SK_PermuteTwoSrc, MVT::v8i64, { 1, 3, 1, 1 } },
1973 {TTI::SK_PermuteTwoSrc, MVT::v16i32, { 1, 3, 1, 1 } },
1974 {TTI::SK_PermuteTwoSrc, MVT::v4f64, { 1, 3, 1, 1 } },
1975 {TTI::SK_PermuteTwoSrc, MVT::v8f32, { 1, 3, 1, 1 } },
1976 {TTI::SK_PermuteTwoSrc, MVT::v4i64, { 1, 3, 1, 1 } },
1977 {TTI::SK_PermuteTwoSrc, MVT::v8i32, { 1, 3, 1, 1 } },
1978 };
1979
1980 if (IsInLaneShuffle && ST->hasAVX512())
1981 if (const auto *Entry =
1982 CostTableLookup(AVX512InLaneShuffleTbl, Kind, LT.second))
1983 if (auto KindCost = Entry->Cost[CostKind])
1984 return LT.first * *KindCost;
1985
1986 static const CostKindTblEntry AVX512ShuffleTbl[] = {
1987 {TTI::SK_Broadcast, MVT::v8f64, { 1, 3, 1, 1 } }, // vbroadcastsd
1988 {TTI::SK_Broadcast, MVT::v4f64, { 1, 3, 1, 1 } }, // vbroadcastsd
1989 {TTI::SK_Broadcast, MVT::v16f32, { 1, 3, 1, 1 } }, // vbroadcastss
1990 {TTI::SK_Broadcast, MVT::v8f32, { 1, 3, 1, 1 } }, // vbroadcastss
1991 {TTI::SK_Broadcast, MVT::v8i64, { 1, 3, 1, 1 } }, // vpbroadcastq
1992 {TTI::SK_Broadcast, MVT::v4i64, { 1, 3, 1, 1 } }, // vpbroadcastq
1993 {TTI::SK_Broadcast, MVT::v16i32, { 1, 3, 1, 1 } }, // vpbroadcastd
1994 {TTI::SK_Broadcast, MVT::v8i32, { 1, 3, 1, 1 } }, // vpbroadcastd
1995 {TTI::SK_Broadcast, MVT::v32i16, { 1, 3, 1, 1 } }, // vpbroadcastw
1996 {TTI::SK_Broadcast, MVT::v16i16, { 1, 3, 1, 1 } }, // vpbroadcastw
1997 {TTI::SK_Broadcast, MVT::v32f16, { 1, 3, 1, 1 } }, // vpbroadcastw
1998 {TTI::SK_Broadcast, MVT::v16f16, { 1, 3, 1, 1 } }, // vpbroadcastw
1999 {TTI::SK_Broadcast, MVT::v64i8, { 1, 3, 1, 1 } }, // vpbroadcastb
2000 {TTI::SK_Broadcast, MVT::v32i8, { 1, 3, 1, 1 }}, // vpbroadcastb
2001
2002 {TTI::SK_Reverse, MVT::v8f64, { 1, 5, 2, 3 } }, // vpermpd
2003 {TTI::SK_Reverse, MVT::v16f32, { 1, 3, 2, 3 } }, // vpermps
2004 {TTI::SK_Reverse, MVT::v8i64, { 1, 5, 2, 3 } }, // vpermq
2005 {TTI::SK_Reverse, MVT::v16i32, { 1, 3, 2, 3 } }, // vpermd
2006 {TTI::SK_Reverse, MVT::v32i16, { 7, 7, 7, 7 } }, // per mca
2007 {TTI::SK_Reverse, MVT::v32f16, { 7, 7, 7, 7 } }, // per mca
2008 {TTI::SK_Reverse, MVT::v64i8, { 7, 7, 7, 7 } }, // per mca
2009
2010 {TTI::SK_Splice, MVT::v8f64, { 1, 1, 1, 1 } }, // vpalignd
2011 {TTI::SK_Splice, MVT::v4f64, { 1, 1, 1, 1 } }, // vpalignd
2012 {TTI::SK_Splice, MVT::v16f32, { 1, 1, 1, 1 } }, // vpalignd
2013 {TTI::SK_Splice, MVT::v8f32, { 1, 1, 1, 1 } }, // vpalignd
2014 {TTI::SK_Splice, MVT::v8i64, { 1, 1, 1, 1 } }, // vpalignd
2015 {TTI::SK_Splice, MVT::v4i64, { 1, 1, 1, 1 } }, // vpalignd
2016 {TTI::SK_Splice, MVT::v16i32, { 1, 1, 1, 1 } }, // vpalignd
2017 {TTI::SK_Splice, MVT::v8i32, { 1, 1, 1, 1 } }, // vpalignd
2018 {TTI::SK_Splice, MVT::v32i16, { 4, 4, 4, 4 } }, // split + palignr
2019 {TTI::SK_Splice, MVT::v32f16, { 4, 4, 4, 4 } }, // split + palignr
2020 {TTI::SK_Splice, MVT::v64i8, { 4, 4, 4, 4 } }, // split + palignr
2021
2022 {TTI::SK_PermuteSingleSrc, MVT::v8f64, { 1, 3, 1, 1 } }, // vpermpd
2023 {TTI::SK_PermuteSingleSrc, MVT::v4f64, { 1, 3, 1, 1 } }, // vpermpd
2024 {TTI::SK_PermuteSingleSrc, MVT::v2f64, { 1, 3, 1, 1 } }, // vpermpd
2025 {TTI::SK_PermuteSingleSrc, MVT::v16f32, { 1, 3, 1, 1 } }, // vpermps
2026 {TTI::SK_PermuteSingleSrc, MVT::v8f32, { 1, 3, 1, 1 } }, // vpermps
2027 {TTI::SK_PermuteSingleSrc, MVT::v4f32, { 1, 3, 1, 1 } }, // vpermps
2028 {TTI::SK_PermuteSingleSrc, MVT::v8i64, { 1, 3, 1, 1 } }, // vpermq
2029 {TTI::SK_PermuteSingleSrc, MVT::v4i64, { 1, 3, 1, 1 } }, // vpermq
2030 {TTI::SK_PermuteSingleSrc, MVT::v2i64, { 1, 3, 1, 1 } }, // vpermq
2031 {TTI::SK_PermuteSingleSrc, MVT::v16i32, { 1, 3, 1, 1 } }, // vpermd
2032 {TTI::SK_PermuteSingleSrc, MVT::v8i32, { 1, 3, 1, 1 } }, // vpermd
2033 {TTI::SK_PermuteSingleSrc, MVT::v4i32, { 1, 3, 1, 1 } }, // vpermd
2034 {TTI::SK_PermuteSingleSrc, MVT::v16i8, { 1, 3, 1, 1 } }, // pshufb
2035
2036 {TTI::SK_PermuteTwoSrc, MVT::v8f64, { 2, 3, 1, 1 } }, // vpermt2pd
2037 {TTI::SK_PermuteTwoSrc, MVT::v16f32, { 2, 3, 1, 1 } }, // vpermt2ps
2038 {TTI::SK_PermuteTwoSrc, MVT::v8i64, { 2, 3, 1, 1 } }, // vpermt2q
2039 {TTI::SK_PermuteTwoSrc, MVT::v16i32, { 2, 3, 1, 1 } }, // vpermt2d
2040 {TTI::SK_PermuteTwoSrc, MVT::v4f64, { 2, 3, 1, 1 } }, // vpermt2pd
2041 {TTI::SK_PermuteTwoSrc, MVT::v8f32, { 2, 3, 1, 1 } }, // vpermt2ps
2042 {TTI::SK_PermuteTwoSrc, MVT::v4i64, { 2, 3, 1, 1 } }, // vpermt2q
2043 {TTI::SK_PermuteTwoSrc, MVT::v8i32, { 2, 3, 1, 1 } }, // vpermt2d
2044 {TTI::SK_PermuteTwoSrc, MVT::v2f64, { 1, 3, 1, 1 } },
2045 {TTI::SK_PermuteTwoSrc, MVT::v4f32, { 1, 3, 1, 1 } },
2046 {TTI::SK_PermuteTwoSrc, MVT::v2i64, { 1, 3, 1, 1 } },
2047 {TTI::SK_PermuteTwoSrc, MVT::v4i32, { 1, 3, 1, 1 } },
2048
2049 // FIXME: This just applies the type legalization cost rules above
2050 // assuming these completely split.
2051 {TTI::SK_PermuteSingleSrc, MVT::v32i16, { 14, 14, 14, 14 } },
2052 {TTI::SK_PermuteSingleSrc, MVT::v32f16, { 14, 14, 14, 14 } },
2053 {TTI::SK_PermuteSingleSrc, MVT::v64i8, { 14, 14, 14, 14 } },
2054 {TTI::SK_PermuteTwoSrc, MVT::v32i16, { 42, 42, 42, 42 } },
2055 {TTI::SK_PermuteTwoSrc, MVT::v32f16, { 42, 42, 42, 42 } },
2056 {TTI::SK_PermuteTwoSrc, MVT::v64i8, { 42, 42, 42, 42 } },
2057
2058 {TTI::SK_Select, MVT::v32i16, { 1, 1, 1, 1 } }, // vpternlogq
2059 {TTI::SK_Select, MVT::v32f16, { 1, 1, 1, 1 } }, // vpternlogq
2060 {TTI::SK_Select, MVT::v64i8, { 1, 1, 1, 1 } }, // vpternlogq
2061 {TTI::SK_Select, MVT::v8f64, { 1, 1, 1, 1 } }, // vblendmpd
2062 {TTI::SK_Select, MVT::v16f32, { 1, 1, 1, 1 } }, // vblendmps
2063 {TTI::SK_Select, MVT::v8i64, { 1, 1, 1, 1 } }, // vblendmq
2064 {TTI::SK_Select, MVT::v16i32, { 1, 1, 1, 1 } }, // vblendmd
2065 };
2066
2067 if (ST->hasAVX512())
2068 if (const auto *Entry = CostTableLookup(AVX512ShuffleTbl, Kind, LT.second))
2069 if (auto KindCost = Entry->Cost[CostKind])
2070 return LT.first * *KindCost;
2071
2072 static const CostKindTblEntry AVX2InLaneShuffleTbl[] = {
2073 { TTI::SK_PermuteSingleSrc, MVT::v16i16, { 1, 1, 1, 1 } }, // vpshufb
2074 { TTI::SK_PermuteSingleSrc, MVT::v16f16, { 1, 1, 1, 1 } }, // vpshufb
2075 { TTI::SK_PermuteSingleSrc, MVT::v32i8, { 1, 1, 1, 1 } }, // vpshufb
2076
2077 { TTI::SK_Transpose, MVT::v4f64, { 1, 1, 1, 1 } }, // vshufpd/vunpck
2078 { TTI::SK_Transpose, MVT::v4i64, { 1, 1, 1, 1 } }, // vshufpd/vunpck
2079
2080 { TTI::SK_PermuteTwoSrc, MVT::v4f64, { 2, 2, 2, 2 } }, // 2*vshufpd + vblendpd
2081 { TTI::SK_PermuteTwoSrc, MVT::v8f32, { 2, 2, 2, 2 } }, // 2*vshufps + vblendps
2082 { TTI::SK_PermuteTwoSrc, MVT::v4i64, { 2, 2, 2, 2 } }, // 2*vpshufd + vpblendd
2083 { TTI::SK_PermuteTwoSrc, MVT::v8i32, { 2, 2, 2, 2 } }, // 2*vpshufd + vpblendd
2084 { TTI::SK_PermuteTwoSrc, MVT::v16i16, { 2, 2, 2, 2 } }, // 2*vpshufb + vpor
2085 { TTI::SK_PermuteTwoSrc, MVT::v16f16, { 2, 2, 2, 2 } }, // 2*vpshufb + vpor
2086 { TTI::SK_PermuteTwoSrc, MVT::v32i8, { 2, 2, 2, 2 } }, // 2*vpshufb + vpor
2087 };
2088
2089 if (IsInLaneShuffle && ST->hasAVX2())
2090 if (const auto *Entry =
2091 CostTableLookup(AVX2InLaneShuffleTbl, Kind, LT.second))
2092 if (auto KindCost = Entry->Cost[CostKind])
2093 return LT.first * *KindCost;
2094
2095 static const CostKindTblEntry AVX2ShuffleTbl[] = {
2096 { TTI::SK_Broadcast, MVT::v4f64, { 1, 3, 1, 2 } }, // vbroadcastpd
2097 { TTI::SK_Broadcast, MVT::v8f32, { 1, 3, 1, 2 } }, // vbroadcastps
2098 { TTI::SK_Broadcast, MVT::v4i64, { 1, 3, 1, 2 } }, // vpbroadcastq
2099 { TTI::SK_Broadcast, MVT::v8i32, { 1, 3, 1, 2 } }, // vpbroadcastd
2100 { TTI::SK_Broadcast, MVT::v16i16, { 1, 3, 1, 2 } }, // vpbroadcastw
2101 { TTI::SK_Broadcast, MVT::v8i16, { 1, 3, 1, 1 } }, // vpbroadcastw
2102 { TTI::SK_Broadcast, MVT::v16f16, { 1, 3, 1, 2 } }, // vpbroadcastw
2103 { TTI::SK_Broadcast, MVT::v8f16, { 1, 3, 1, 1 } }, // vpbroadcastw
2104 { TTI::SK_Broadcast, MVT::v32i8, { 1, 3, 1, 2 } }, // vpbroadcastb
2105 { TTI::SK_Broadcast, MVT::v16i8, { 1, 3, 1, 1 } }, // vpbroadcastb
2106
2107 { TTI::SK_Reverse, MVT::v4f64, { 1, 6, 1, 2 } }, // vpermpd
2108 { TTI::SK_Reverse, MVT::v8f32, { 2, 7, 2, 4 } }, // vpermps
2109 { TTI::SK_Reverse, MVT::v4i64, { 1, 6, 1, 2 } }, // vpermq
2110 { TTI::SK_Reverse, MVT::v8i32, { 2, 7, 2, 4 } }, // vpermd
2111 { TTI::SK_Reverse, MVT::v16i16, { 2, 9, 2, 4 } }, // vperm2i128 + pshufb
2112 { TTI::SK_Reverse, MVT::v16f16, { 2, 9, 2, 4 } }, // vperm2i128 + pshufb
2113 { TTI::SK_Reverse, MVT::v32i8, { 2, 9, 2, 4 } }, // vperm2i128 + pshufb
2114
2115 { TTI::SK_Select, MVT::v16i16, { 1, 1, 1, 1 } }, // vpblendvb
2116 { TTI::SK_Select, MVT::v16f16, { 1, 1, 1, 1 } }, // vpblendvb
2117 { TTI::SK_Select, MVT::v32i8, { 1, 1, 1, 1 } }, // vpblendvb
2118
2119 { TTI::SK_Splice, MVT::v8i32, { 2, 2, 2, 2 } }, // vperm2i128 + vpalignr
2120 { TTI::SK_Splice, MVT::v8f32, { 2, 2, 2, 2 } }, // vperm2i128 + vpalignr
2121 { TTI::SK_Splice, MVT::v16i16, { 2, 2, 2, 2 } }, // vperm2i128 + vpalignr
2122 { TTI::SK_Splice, MVT::v16f16, { 2, 2, 2, 2 } }, // vperm2i128 + vpalignr
2123 { TTI::SK_Splice, MVT::v32i8, { 2, 2, 2, 2 } }, // vperm2i128 + vpalignr
2124
2125 { TTI::SK_PermuteSingleSrc, MVT::v4f64, { 1, 1, 1, 1 } }, // vpermpd
2126 { TTI::SK_PermuteSingleSrc, MVT::v8f32, { 1, 1, 1, 1 } }, // vpermps
2127 { TTI::SK_PermuteSingleSrc, MVT::v4i64, { 1, 1, 1, 1 } }, // vpermq
2128 { TTI::SK_PermuteSingleSrc, MVT::v8i32, { 1, 1, 1, 1 } }, // vpermd
2129 { TTI::SK_PermuteSingleSrc, MVT::v16i16, { 4, 4, 4, 4 } },
2130 { TTI::SK_PermuteSingleSrc, MVT::v16f16, { 4, 4, 4, 4 } },
2131 { TTI::SK_PermuteSingleSrc, MVT::v32i8, { 4, 4, 4, 4 } },
2132
2133 { TTI::SK_PermuteTwoSrc, MVT::v4f64, { 3, 3, 3, 3 } }, // 2*vpermpd + vblendpd
2134 { TTI::SK_PermuteTwoSrc, MVT::v8f32, { 3, 3, 3, 3 } }, // 2*vpermps + vblendps
2135 { TTI::SK_PermuteTwoSrc, MVT::v4i64, { 3, 3, 3, 3 } }, // 2*vpermq + vpblendd
2136 { TTI::SK_PermuteTwoSrc, MVT::v8i32, { 3, 3, 3, 3 } }, // 2*vpermd + vpblendd
2137 { TTI::SK_PermuteTwoSrc, MVT::v16i16, { 7, 7, 7, 7 } },
2138 { TTI::SK_PermuteTwoSrc, MVT::v16f16, { 7, 7, 7, 7 } },
2139 { TTI::SK_PermuteTwoSrc, MVT::v32i8, { 7, 7, 7, 7 } },
2140 };
2141
2142 if (ST->hasAVX2())
2143 if (const auto *Entry = CostTableLookup(AVX2ShuffleTbl, Kind, LT.second))
2144 if (auto KindCost = Entry->Cost[CostKind])
2145 return LT.first * *KindCost;
2146
2147 static const CostKindTblEntry XOPShuffleTbl[] = {
2148 { TTI::SK_PermuteSingleSrc, MVT::v4f64, { 2, 2, 2, 2 } }, // vperm2f128 + vpermil2pd
2149 { TTI::SK_PermuteSingleSrc, MVT::v8f32, { 2, 2, 2, 2 } }, // vperm2f128 + vpermil2ps
2150 { TTI::SK_PermuteSingleSrc, MVT::v4i64, { 2, 2, 2, 2 } }, // vperm2f128 + vpermil2pd
2151 { TTI::SK_PermuteSingleSrc, MVT::v8i32, { 2, 2, 2, 2 } }, // vperm2f128 + vpermil2ps
2152 { TTI::SK_PermuteSingleSrc, MVT::v16i16,{ 4, 4, 4, 4 } }, // vextractf128 + 2*vpperm
2153 // + vinsertf128
2154 { TTI::SK_PermuteSingleSrc, MVT::v32i8, { 4, 4, 4, 4 } }, // vextractf128 + 2*vpperm
2155 // + vinsertf128
2156
2157 { TTI::SK_PermuteTwoSrc, MVT::v16i16, { 9, 9, 9, 9 } }, // 2*vextractf128 + 6*vpperm
2158 // + vinsertf128
2159
2160 { TTI::SK_PermuteTwoSrc, MVT::v8i16, { 1, 1, 1, 1 } }, // vpperm
2161 { TTI::SK_PermuteTwoSrc, MVT::v32i8, { 9, 9, 9, 9 } }, // 2*vextractf128 + 6*vpperm
2162 // + vinsertf128
2163 { TTI::SK_PermuteTwoSrc, MVT::v16i8, { 1, 1, 1, 1 } }, // vpperm
2164 };
2165
2166 if (ST->hasXOP())
2167 if (const auto *Entry = CostTableLookup(XOPShuffleTbl, Kind, LT.second))
2168 if (auto KindCost = Entry->Cost[CostKind])
2169 return LT.first * *KindCost;
2170
2171 static const CostKindTblEntry AVX1InLaneShuffleTbl[] = {
2172 { TTI::SK_PermuteSingleSrc, MVT::v4f64, { 1, 1, 1, 1 } }, // vpermilpd
2173 { TTI::SK_PermuteSingleSrc, MVT::v4i64, { 1, 1, 1, 1 } }, // vpermilpd
2174 { TTI::SK_PermuteSingleSrc, MVT::v8f32, { 1, 1, 1, 1 } }, // vpermilps
2175 { TTI::SK_PermuteSingleSrc, MVT::v8i32, { 1, 1, 1, 1 } }, // vpermilps
2176
2177 { TTI::SK_PermuteSingleSrc, MVT::v16i16, { 4, 4, 4, 4 } }, // vextractf128 + 2*pshufb
2178 // + vpor + vinsertf128
2179 { TTI::SK_PermuteSingleSrc, MVT::v16f16, { 4, 4, 4, 4 } }, // vextractf128 + 2*pshufb
2180 // + vpor + vinsertf128
2181 { TTI::SK_PermuteSingleSrc, MVT::v32i8, { 4, 4, 4, 4 } }, // vextractf128 + 2*pshufb
2182 // + vpor + vinsertf128
2183
2184 { TTI::SK_Transpose, MVT::v4f64, { 1, 1, 1, 1 } }, // vshufpd/vunpck
2185 { TTI::SK_Transpose, MVT::v4i64, { 1, 1, 1, 1 } }, // vshufpd/vunpck
2186
2187 { TTI::SK_PermuteTwoSrc, MVT::v4f64, { 2, 2, 2, 2 } }, // 2*vshufpd + vblendpd
2188 { TTI::SK_PermuteTwoSrc, MVT::v8f32, { 2, 2, 2, 2 } }, // 2*vshufps + vblendps
2189 { TTI::SK_PermuteTwoSrc, MVT::v4i64, { 2, 2, 2, 2 } }, // 2*vpermilpd + vblendpd
2190 { TTI::SK_PermuteTwoSrc, MVT::v8i32, { 2, 2, 2, 2 } }, // 2*vpermilps + vblendps
2191 { TTI::SK_PermuteTwoSrc, MVT::v16i16, { 9, 9, 9, 9 } }, // 2*vextractf128 + 4*pshufb
2192 // + 2*vpor + vinsertf128
2193 { TTI::SK_PermuteTwoSrc, MVT::v16f16, { 9, 9, 9, 9 } }, // 2*vextractf128 + 4*pshufb
2194 // + 2*vpor + vinsertf128
2195 { TTI::SK_PermuteTwoSrc, MVT::v32i8, { 9, 9, 9, 9 } }, // 2*vextractf128 + 4*pshufb
2196 // + 2*vpor + vinsertf128
2197 };
2198
2199 if (IsInLaneShuffle && ST->hasAVX())
2200 if (const auto *Entry =
2201 CostTableLookup(AVX1InLaneShuffleTbl, Kind, LT.second))
2202 if (auto KindCost = Entry->Cost[CostKind])
2203 return LT.first * *KindCost;
2204
2205 static const CostKindTblEntry AVX1ShuffleTbl[] = {
2206 {TTI::SK_Broadcast, MVT::v4f64, {2,3,2,3}}, // vperm2f128 + vpermilpd
2207 {TTI::SK_Broadcast, MVT::v8f32, {2,3,2,3}}, // vperm2f128 + vpermilps
2208 {TTI::SK_Broadcast, MVT::v4i64, {2,3,2,3}}, // vperm2f128 + vpermilpd
2209 {TTI::SK_Broadcast, MVT::v8i32, {2,3,2,3}}, // vperm2f128 + vpermilps
2210 {TTI::SK_Broadcast, MVT::v16i16, {2,3,3,4}}, // vpshuflw + vpshufd + vinsertf128
2211 {TTI::SK_Broadcast, MVT::v16f16, {2,3,3,4}}, // vpshuflw + vpshufd + vinsertf128
2212 {TTI::SK_Broadcast, MVT::v32i8, {3,4,3,6}}, // vpshufb + vinsertf128
2213
2214 {TTI::SK_Reverse, MVT::v4f64, {2,6,2,2}}, // vperm2f128 + vpermilpd
2215 {TTI::SK_Reverse, MVT::v8f32, {2,7,2,4}}, // vperm2f128 + vpermilps
2216 {TTI::SK_Reverse, MVT::v4i64, {2,6,2,2}}, // vperm2f128 + vpermilpd
2217 {TTI::SK_Reverse, MVT::v8i32, {2,7,2,4}}, // vperm2f128 + vpermilps
2218 {TTI::SK_Reverse, MVT::v16i16, {2,9,5,5}}, // vextractf128 + 2*pshufb
2219 // + vinsertf128
2220 {TTI::SK_Reverse, MVT::v16f16, {2,9,5,5}}, // vextractf128 + 2*pshufb
2221 // + vinsertf128
2222 {TTI::SK_Reverse, MVT::v32i8, {2,9,5,5}}, // vextractf128 + 2*pshufb
2223 // + vinsertf128
2224
2225 {TTI::SK_Select, MVT::v4i64, {1,1,1,1}}, // vblendpd
2226 {TTI::SK_Select, MVT::v4f64, {1,1,1,1}}, // vblendpd
2227 {TTI::SK_Select, MVT::v8i32, {1,1,1,1}}, // vblendps
2228 {TTI::SK_Select, MVT::v8f32, {1,1,1,1}}, // vblendps
2229 {TTI::SK_Select, MVT::v16i16, {3,3,3,3}}, // vpand + vpandn + vpor
2230 {TTI::SK_Select, MVT::v16f16, {3,3,3,3}}, // vpand + vpandn + vpor
2231 {TTI::SK_Select, MVT::v32i8, {3,3,3,3}}, // vpand + vpandn + vpor
2232
2233 {TTI::SK_Splice, MVT::v4i64, {2,2,2,2}}, // vperm2f128 + shufpd
2234 {TTI::SK_Splice, MVT::v4f64, {2,2,2,2}}, // vperm2f128 + shufpd
2235 {TTI::SK_Splice, MVT::v8i32, {4,4,4,4}}, // 2*vperm2f128 + 2*vshufps
2236 {TTI::SK_Splice, MVT::v8f32, {4,4,4,4}}, // 2*vperm2f128 + 2*vshufps
2237 {TTI::SK_Splice, MVT::v16i16, {5,5,5,5}}, // 2*vperm2f128 + 2*vpalignr + vinsertf128
2238 {TTI::SK_Splice, MVT::v16f16, {5,5,5,5}}, // 2*vperm2f128 + 2*vpalignr + vinsertf128
2239 {TTI::SK_Splice, MVT::v32i8, {5,5,5,5}}, // 2*vperm2f128 + 2*vpalignr + vinsertf128
2240
2241 {TTI::SK_PermuteSingleSrc, MVT::v4f64, {2,2,2,2}}, // vperm2f128 + vshufpd
2242 {TTI::SK_PermuteSingleSrc, MVT::v4i64, {2,2,2,2}}, // vperm2f128 + vshufpd
2243 {TTI::SK_PermuteSingleSrc, MVT::v8f32, {4,4,4,4}}, // 2*vperm2f128 + 2*vshufps
2244 {TTI::SK_PermuteSingleSrc, MVT::v8i32, {4,4,4,4}}, // 2*vperm2f128 + 2*vshufps
2245 {TTI::SK_PermuteSingleSrc, MVT::v16i16,{8,8,8,8}}, // vextractf128 + 4*pshufb
2246 // + 2*por + vinsertf128
2247 {TTI::SK_PermuteSingleSrc, MVT::v16f16,{8,8,8,8}}, // vextractf128 + 4*pshufb
2248 // + 2*por + vinsertf128
2249 {TTI::SK_PermuteSingleSrc, MVT::v32i8, {8,8,8,8}}, // vextractf128 + 4*pshufb
2250 // + 2*por + vinsertf128
2251
2252 {TTI::SK_PermuteTwoSrc, MVT::v4f64, {3,3,3,3}}, // 2*vperm2f128 + vshufpd
2253 {TTI::SK_PermuteTwoSrc, MVT::v4i64, {3,3,3,3}}, // 2*vperm2f128 + vshufpd
2254 {TTI::SK_PermuteTwoSrc, MVT::v8f32, {4,4,4,4}}, // 2*vperm2f128 + 2*vshufps
2255 {TTI::SK_PermuteTwoSrc, MVT::v8i32, {4,4,4,4}}, // 2*vperm2f128 + 2*vshufps
2256 {TTI::SK_PermuteTwoSrc, MVT::v16i16,{15,15,15,15}}, // 2*vextractf128 + 8*pshufb
2257 // + 4*por + vinsertf128
2258 {TTI::SK_PermuteTwoSrc, MVT::v16f16,{15,15,15,15}}, // 2*vextractf128 + 8*pshufb
2259 // + 4*por + vinsertf128
2260 {TTI::SK_PermuteTwoSrc, MVT::v32i8, {15,15,15,15}}, // 2*vextractf128 + 8*pshufb
2261 // + 4*por + vinsertf128
2262 };
2263
2264 if (ST->hasAVX())
2265 if (const auto *Entry = CostTableLookup(AVX1ShuffleTbl, Kind, LT.second))
2266 if (auto KindCost = Entry->Cost[CostKind])
2267 return LT.first * *KindCost;
2268
2269 static const CostKindTblEntry SSE41ShuffleTbl[] = {
2270 {TTI::SK_Select, MVT::v2i64, {1,1,1,1}}, // pblendw
2271 {TTI::SK_Select, MVT::v2f64, {1,1,1,1}}, // movsd
2272 {TTI::SK_Select, MVT::v4i32, {1,1,1,1}}, // pblendw
2273 {TTI::SK_Select, MVT::v4f32, {1,1,1,1}}, // blendps
2274 {TTI::SK_Select, MVT::v8i16, {1,1,1,1}}, // pblendw
2275 {TTI::SK_Select, MVT::v8f16, {1,1,1,1}}, // pblendw
2276 {TTI::SK_Select, MVT::v16i8, {1,1,1,1}} // pblendvb
2277 };
2278
2279 if (ST->hasSSE41())
2280 if (const auto *Entry = CostTableLookup(SSE41ShuffleTbl, Kind, LT.second))
2281 if (auto KindCost = Entry->Cost[CostKind])
2282 return LT.first * *KindCost;
2283
2284 static const CostKindTblEntry SSSE3ShuffleTbl[] = {
2285 {TTI::SK_Broadcast, MVT::v8i16, {1, 3, 2, 2}}, // pshufb
2286 {TTI::SK_Broadcast, MVT::v8f16, {1, 3, 2, 2}}, // pshufb
2287 {TTI::SK_Broadcast, MVT::v16i8, {1, 3, 2, 2}}, // pshufb
2288
2289 {TTI::SK_Reverse, MVT::v8i16, {1, 2, 1, 2}}, // pshufb
2290 {TTI::SK_Reverse, MVT::v8f16, {1, 2, 1, 2}}, // pshufb
2291 {TTI::SK_Reverse, MVT::v16i8, {1, 2, 1, 2}}, // pshufb
2292
2293 {TTI::SK_Splice, MVT::v4i32, {1, 1, 1, 1}}, // palignr
2294 {TTI::SK_Splice, MVT::v4f32, {1, 1, 1, 1}}, // palignr
2295 {TTI::SK_Splice, MVT::v8i16, {1, 1, 1, 1}}, // palignr
2296 {TTI::SK_Splice, MVT::v8f16, {1, 1, 1, 1}}, // palignr
2297 {TTI::SK_Splice, MVT::v16i8, {1, 1, 1, 1}}, // palignr
2298
2299 {TTI::SK_PermuteSingleSrc, MVT::v8i16, {1, 1, 1, 1}}, // pshufb
2300 {TTI::SK_PermuteSingleSrc, MVT::v8f16, {1, 1, 1, 1}}, // pshufb
2301 {TTI::SK_PermuteSingleSrc, MVT::v16i8, {1, 1, 1, 1}}, // pshufb
2302
2303 {TTI::SK_PermuteTwoSrc, MVT::v8i16, {3, 3, 3, 3}}, // 2*pshufb + por
2304 {TTI::SK_PermuteTwoSrc, MVT::v8f16, {3, 3, 3, 3}}, // 2*pshufb + por
2305 {TTI::SK_PermuteTwoSrc, MVT::v16i8, {3, 3, 3, 3}}, // 2*pshufb + por
2306 };
2307
2308 if (ST->hasSSSE3())
2309 if (const auto *Entry = CostTableLookup(SSSE3ShuffleTbl, Kind, LT.second))
2310 if (auto KindCost = Entry->Cost[CostKind])
2311 return LT.first * *KindCost;
2312
2313 static const CostKindTblEntry SSE2ShuffleTbl[] = {
2314 {TTI::SK_Broadcast, MVT::v2f64, {1, 1, 1, 1}}, // shufpd
2315 {TTI::SK_Broadcast, MVT::v2i64, {1, 1, 1, 1}}, // pshufd
2316 {TTI::SK_Broadcast, MVT::v4i32, {1, 1, 1, 1}}, // pshufd
2317 {TTI::SK_Broadcast, MVT::v8i16, {1, 2, 2, 2}}, // pshuflw + pshufd
2318 {TTI::SK_Broadcast, MVT::v8f16, {1, 2, 2, 2}}, // pshuflw + pshufd
2319 {TTI::SK_Broadcast, MVT::v16i8, {2, 3, 3, 4}}, // unpck + pshuflw + pshufd
2320
2321 {TTI::SK_Reverse, MVT::v2f64, {1, 1, 1, 1}}, // shufpd
2322 {TTI::SK_Reverse, MVT::v2i64, {1, 1, 1, 1}}, // pshufd
2323 {TTI::SK_Reverse, MVT::v4i32, {1, 1, 1, 1}}, // pshufd
2324 {TTI::SK_Reverse, MVT::v8i16, {2, 3, 3, 3}}, // pshuflw + pshufhw + pshufd
2325 {TTI::SK_Reverse, MVT::v8f16, {2, 3, 3, 3}}, // pshuflw + pshufhw + pshufd
2326 {TTI::SK_Reverse, MVT::v16i8, {5, 6,11,11}}, // 2*pshuflw + 2*pshufhw
2327 // + 2*pshufd + 2*unpck + packus
2328
2329 {TTI::SK_Select, MVT::v2i64, {1, 1, 1, 1}}, // movsd
2330 {TTI::SK_Select, MVT::v2f64, {1, 1, 1, 1}}, // movsd
2331 {TTI::SK_Select, MVT::v4i32, {2, 2, 2, 2}}, // 2*shufps
2332 {TTI::SK_Select, MVT::v8i16, {2, 2, 3, 3}}, // pand + pandn + por
2333 {TTI::SK_Select, MVT::v8f16, {2, 2, 3, 3}}, // pand + pandn + por
2334 {TTI::SK_Select, MVT::v16i8, {2, 2, 3, 3}}, // pand + pandn + por
2335
2336 {TTI::SK_Splice, MVT::v2i64, {1, 1, 1, 1}}, // shufpd
2337 {TTI::SK_Splice, MVT::v2f64, {1, 1, 1, 1}}, // shufpd
2338 {TTI::SK_Splice, MVT::v4i32, {2, 2, 2, 2}}, // 2*{unpck,movsd,pshufd}
2339 {TTI::SK_Splice, MVT::v8i16, {3, 3, 3, 3}}, // psrldq + psrlldq + por
2340 {TTI::SK_Splice, MVT::v8f16, {3, 3, 3, 3}}, // psrldq + psrlldq + por
2341 {TTI::SK_Splice, MVT::v16i8, {3, 3, 3, 3}}, // psrldq + psrlldq + por
2342
2343 {TTI::SK_PermuteSingleSrc, MVT::v2f64, {1, 1, 1, 1}}, // shufpd
2344 {TTI::SK_PermuteSingleSrc, MVT::v2i64, {1, 1, 1, 1}}, // pshufd
2345 {TTI::SK_PermuteSingleSrc, MVT::v4i32, {1, 1, 1, 1}}, // pshufd
2346 {TTI::SK_PermuteSingleSrc, MVT::v8i16, {3, 5, 5, 5}}, // 2*pshuflw + 2*pshufhw
2347 // + pshufd/unpck
2348 {TTI::SK_PermuteSingleSrc, MVT::v8f16, {3, 5, 5, 5}}, // 2*pshuflw + 2*pshufhw
2349 // + pshufd/unpck
2350 {TTI::SK_PermuteSingleSrc, MVT::v16i8, {8, 10, 10, 10}}, // 2*pshuflw + 2*pshufhw
2351 // + 2*pshufd + 2*unpck + 2*packus
2352
2353 {TTI::SK_PermuteTwoSrc, MVT::v2f64, {1, 1, 1, 1}}, // shufpd
2354 {TTI::SK_PermuteTwoSrc, MVT::v2i64, {1, 1, 1, 1}}, // shufpd
2355 {TTI::SK_PermuteTwoSrc, MVT::v4i32, {2, 2, 2, 2}}, // 2*{unpck,movsd,pshufd}
2356 {TTI::SK_PermuteTwoSrc, MVT::v8i16, {6, 8, 8, 8}}, // blend+permute
2357 {TTI::SK_PermuteTwoSrc, MVT::v8f16, {6, 8, 8, 8}}, // blend+permute
2358 {TTI::SK_PermuteTwoSrc, MVT::v16i8, {11, 13, 13, 13}}, // blend+permute
2359 };
2360
2361 static const CostTblEntry SSE3BroadcastLoadTbl[] = {
2362 {TTI::SK_Broadcast, MVT::v2f64, 0}, // broadcast handled by movddup
2363 };
2364
2365 if (ST->hasSSE2()) {
2366 bool IsLoad =
2367 llvm::any_of(Args, [](const auto &V) { return isa<LoadInst>(V); });
2368 if (ST->hasSSE3() && IsLoad)
2369 if (const auto *Entry =
2370 CostTableLookup(SSE3BroadcastLoadTbl, Kind, LT.second)) {
2371 assert(isLegalBroadcastLoad(SrcTy->getElementType(),
2372 LT.second.getVectorElementCount()) &&
2373 "Table entry missing from isLegalBroadcastLoad()");
2374 return LT.first * Entry->Cost;
2375 }
2376
2377 if (const auto *Entry = CostTableLookup(SSE2ShuffleTbl, Kind, LT.second))
2378 if (auto KindCost = Entry->Cost[CostKind])
2379 return LT.first * *KindCost;
2380 }
2381
2382 static const CostKindTblEntry SSE1ShuffleTbl[] = {
2383 { TTI::SK_Broadcast, MVT::v4f32, {1,1,1,1} }, // shufps
2384 { TTI::SK_Reverse, MVT::v4f32, {1,1,1,1} }, // shufps
2385 { TTI::SK_Select, MVT::v4f32, {2,2,2,2} }, // 2*shufps
2386 { TTI::SK_Splice, MVT::v4f32, {2,2,2,2} }, // 2*shufps
2387 { TTI::SK_PermuteSingleSrc, MVT::v4f32, {1,1,1,1} }, // shufps
2388 { TTI::SK_PermuteTwoSrc, MVT::v4f32, {2,2,2,2} }, // 2*shufps
2389 };
2390
2391 if (ST->hasSSE1()) {
2392 if (LT.first == 1 && LT.second == MVT::v4f32 && Mask.size() == 4) {
2393 // SHUFPS: both pairs must come from the same source register.
2394 auto MatchSHUFPS = [](int X, int Y) {
2395 return X < 0 || Y < 0 || ((X & 4) == (Y & 4));
2396 };
2397 if (MatchSHUFPS(Mask[0], Mask[1]) && MatchSHUFPS(Mask[2], Mask[3]))
2398 return 1;
2399 }
2400 if (const auto *Entry = CostTableLookup(SSE1ShuffleTbl, Kind, LT.second))
2401 if (auto KindCost = Entry->Cost[CostKind])
2402 return LT.first * *KindCost;
2403 }
2404
2405 return BaseT::getShuffleCost(Kind, DstTy, SrcTy, Mask, CostKind, Index,
2406 SubTp);
2407}
2408
2410 Type *Src,
2413 const Instruction *I) const {
2414 int ISD = TLI->InstructionOpcodeToISD(Opcode);
2415 assert(ISD && "Invalid opcode");
2416
2417 // The cost tables include both specific, custom (non-legal) src/dst type
2418 // conversions and generic, legalized types. We test for customs first, before
2419 // falling back to legalization.
2420 // FIXME: Need a better design of the cost table to handle non-simple types of
2421 // potential massive combinations (elem_num x src_type x dst_type).
2422 static const TypeConversionCostKindTblEntry AVX512BWConversionTbl[]{
2423 { ISD::SIGN_EXTEND, MVT::v32i16, MVT::v32i8, { 1, 1, 1, 1 } },
2424 { ISD::ZERO_EXTEND, MVT::v32i16, MVT::v32i8, { 1, 1, 1, 1 } },
2425
2426 // Mask sign extend has an instruction.
2427 { ISD::SIGN_EXTEND, MVT::v2i8, MVT::v2i1, { 1, 1, 1, 1 } },
2428 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v2i1, { 1, 1, 1, 1 } },
2429 { ISD::SIGN_EXTEND, MVT::v2i16, MVT::v2i1, { 1, 1, 1, 1 } },
2430 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v2i1, { 1, 1, 1, 1 } },
2431 { ISD::SIGN_EXTEND, MVT::v4i8, MVT::v4i1, { 1, 1, 1, 1 } },
2432 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v4i1, { 1, 1, 1, 1 } },
2433 { ISD::SIGN_EXTEND, MVT::v4i16, MVT::v4i1, { 1, 1, 1, 1 } },
2434 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v4i1, { 1, 1, 1, 1 } },
2435 { ISD::SIGN_EXTEND, MVT::v8i8, MVT::v8i1, { 1, 1, 1, 1 } },
2436 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v8i1, { 1, 1, 1, 1 } },
2437 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v8i1, { 1, 1, 1, 1 } },
2438 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v16i1, { 1, 1, 1, 1 } },
2439 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i1, { 1, 1, 1, 1 } },
2440 { ISD::SIGN_EXTEND, MVT::v32i8, MVT::v32i1, { 1, 1, 1, 1 } },
2441 { ISD::SIGN_EXTEND, MVT::v32i16, MVT::v32i1, { 1, 1, 1, 1 } },
2442 { ISD::SIGN_EXTEND, MVT::v64i8, MVT::v64i1, { 1, 1, 1, 1 } },
2443 { ISD::SIGN_EXTEND, MVT::v32i16, MVT::v64i1, { 1, 1, 1, 1 } },
2444
2445 // Mask zero extend is a sext + shift.
2446 { ISD::ZERO_EXTEND, MVT::v2i8, MVT::v2i1, { 2, 1, 1, 1 } },
2447 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v2i1, { 2, 1, 1, 1 } },
2448 { ISD::ZERO_EXTEND, MVT::v2i16, MVT::v2i1, { 2, 1, 1, 1 } },
2449 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v2i1, { 2, 1, 1, 1 } },
2450 { ISD::ZERO_EXTEND, MVT::v4i8, MVT::v4i1, { 2, 1, 1, 1 } },
2451 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v4i1, { 2, 1, 1, 1 } },
2452 { ISD::ZERO_EXTEND, MVT::v4i16, MVT::v4i1, { 2, 1, 1, 1 } },
2453 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v4i1, { 2, 1, 1, 1 } },
2454 { ISD::ZERO_EXTEND, MVT::v8i8, MVT::v8i1, { 2, 1, 1, 1 } },
2455 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v8i1, { 2, 1, 1, 1 } },
2456 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v8i1, { 2, 1, 1, 1 } },
2457 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v16i1, { 2, 1, 1, 1 } },
2458 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i1, { 2, 1, 1, 1 } },
2459 { ISD::ZERO_EXTEND, MVT::v32i8, MVT::v32i1, { 2, 1, 1, 1 } },
2460 { ISD::ZERO_EXTEND, MVT::v32i16, MVT::v32i1, { 2, 1, 1, 1 } },
2461 { ISD::ZERO_EXTEND, MVT::v64i8, MVT::v64i1, { 2, 1, 1, 1 } },
2462 { ISD::ZERO_EXTEND, MVT::v32i16, MVT::v64i1, { 2, 1, 1, 1 } },
2463
2464 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i8, { 2, 1, 1, 1 } },
2465 { ISD::TRUNCATE, MVT::v2i1, MVT::v16i8, { 2, 1, 1, 1 } },
2466 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i16, { 2, 1, 1, 1 } },
2467 { ISD::TRUNCATE, MVT::v2i1, MVT::v8i16, { 2, 1, 1, 1 } },
2468 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i8, { 2, 1, 1, 1 } },
2469 { ISD::TRUNCATE, MVT::v4i1, MVT::v16i8, { 2, 1, 1, 1 } },
2470 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i16, { 2, 1, 1, 1 } },
2471 { ISD::TRUNCATE, MVT::v4i1, MVT::v8i16, { 2, 1, 1, 1 } },
2472 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i8, { 2, 1, 1, 1 } },
2473 { ISD::TRUNCATE, MVT::v8i1, MVT::v16i8, { 2, 1, 1, 1 } },
2474 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i16, { 2, 1, 1, 1 } },
2475 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i8, { 2, 1, 1, 1 } },
2476 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i16, { 2, 1, 1, 1 } },
2477 { ISD::TRUNCATE, MVT::v32i1, MVT::v32i8, { 2, 1, 1, 1 } },
2478 { ISD::TRUNCATE, MVT::v32i1, MVT::v32i16, { 2, 1, 1, 1 } },
2479 { ISD::TRUNCATE, MVT::v64i1, MVT::v64i8, { 2, 1, 1, 1 } },
2480 { ISD::TRUNCATE, MVT::v64i1, MVT::v32i16, { 2, 1, 1, 1 } },
2481
2482 { ISD::TRUNCATE, MVT::v32i8, MVT::v32i16, { 2, 1, 1, 1 } },
2483 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i16, { 2, 1, 1, 1 } }, // widen to zmm
2484 { ISD::TRUNCATE, MVT::v2i8, MVT::v2i16, { 2, 1, 1, 1 } }, // vpmovwb
2485 { ISD::TRUNCATE, MVT::v4i8, MVT::v4i16, { 2, 1, 1, 1 } }, // vpmovwb
2486 { ISD::TRUNCATE, MVT::v8i8, MVT::v8i16, { 2, 1, 1, 1 } }, // vpmovwb
2487 };
2488
2489 static const TypeConversionCostKindTblEntry AVX512DQConversionTbl[] = {
2490 // Mask sign extend has an instruction.
2491 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v2i1, { 1, 1, 1, 1 } },
2492 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v2i1, { 1, 1, 1, 1 } },
2493 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v4i1, { 1, 1, 1, 1 } },
2494 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i1, { 1, 1, 1, 1 } },
2495 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i1, { 1, 1, 1, 1 } },
2496 { ISD::SIGN_EXTEND, MVT::v8i64, MVT::v16i1, { 1, 1, 1, 1 } },
2497 { ISD::SIGN_EXTEND, MVT::v8i64, MVT::v8i1, { 1, 1, 1, 1 } },
2498 { ISD::SIGN_EXTEND, MVT::v16i32, MVT::v16i1, { 1, 1, 1, 1 } },
2499
2500 // Mask zero extend is a sext + shift.
2501 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v2i1, { 2, 1, 1, 1, } },
2502 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v2i1, { 2, 1, 1, 1, } },
2503 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v4i1, { 2, 1, 1, 1, } },
2504 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i1, { 2, 1, 1, 1, } },
2505 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i1, { 2, 1, 1, 1, } },
2506 { ISD::ZERO_EXTEND, MVT::v8i64, MVT::v16i1, { 2, 1, 1, 1, } },
2507 { ISD::ZERO_EXTEND, MVT::v8i64, MVT::v8i1, { 2, 1, 1, 1, } },
2508 { ISD::ZERO_EXTEND, MVT::v16i32, MVT::v16i1, { 2, 1, 1, 1, } },
2509
2510 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i64, { 2, 1, 1, 1 } },
2511 { ISD::TRUNCATE, MVT::v2i1, MVT::v4i32, { 2, 1, 1, 1 } },
2512 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i32, { 2, 1, 1, 1 } },
2513 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i64, { 2, 1, 1, 1 } },
2514 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i32, { 2, 1, 1, 1 } },
2515 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i64, { 2, 1, 1, 1 } },
2516 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i32, { 2, 1, 1, 1 } },
2517 { ISD::TRUNCATE, MVT::v16i1, MVT::v8i64, { 2, 1, 1, 1 } },
2518
2519 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v8i64, { 1, 1, 1, 1 } },
2520 { ISD::SINT_TO_FP, MVT::v8f64, MVT::v8i64, { 1, 1, 1, 1 } },
2521
2522 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i64, { 1, 1, 1, 1 } },
2523 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i64, { 1, 1, 1, 1 } },
2524
2525 { ISD::FP_TO_SINT, MVT::v8i64, MVT::v8f32, { 1, 1, 1, 1 } },
2526 { ISD::FP_TO_SINT, MVT::v8i64, MVT::v8f64, { 1, 1, 1, 1 } },
2527
2528 { ISD::FP_TO_UINT, MVT::v8i64, MVT::v8f32, { 1, 1, 1, 1 } },
2529 { ISD::FP_TO_UINT, MVT::v8i64, MVT::v8f64, { 1, 1, 1, 1 } },
2530 };
2531
2532 // TODO: For AVX512DQ + AVX512VL, we also have cheap casts for 128-bit and
2533 // 256-bit wide vectors.
2534
2535 static const TypeConversionCostKindTblEntry AVX512FConversionTbl[] = {
2536 { ISD::FP_EXTEND, MVT::v8f64, MVT::v8f32, { 1, 1, 1, 1 } },
2537 { ISD::FP_EXTEND, MVT::v8f64, MVT::v16f32, { 3, 1, 1, 1 } },
2538 { ISD::FP_EXTEND, MVT::v16f64, MVT::v16f32, { 4, 1, 1, 1 } }, // 2*vcvtps2pd+vextractf64x4
2539 { ISD::FP_EXTEND, MVT::v16f32, MVT::v16f16, { 1, 1, 1, 1 } }, // vcvtph2ps
2540 { ISD::FP_EXTEND, MVT::v8f64, MVT::v8f16, { 2, 1, 1, 1 } }, // vcvtph2ps+vcvtps2pd
2541 { ISD::FP_ROUND, MVT::v8f32, MVT::v8f64, { 1, 1, 1, 1 } },
2542 { ISD::FP_ROUND, MVT::v16f16, MVT::v16f32, { 1, 1, 1, 1 } }, // vcvtps2ph
2543
2544 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i8, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
2545 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i8, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
2546 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i8, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
2547 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i8, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
2548 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i16, { 3, 1, 1, 1 } }, // sext+vpsllq+vptestmq
2549 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i16, { 3, 1, 1, 1 } }, // sext+vpsllq+vptestmq
2550 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i16, { 3, 1, 1, 1 } }, // sext+vpsllq+vptestmq
2551 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i16, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
2552 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i32, { 2, 1, 1, 1 } }, // zmm vpslld+vptestmd
2553 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i32, { 2, 1, 1, 1 } }, // zmm vpslld+vptestmd
2554 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i32, { 2, 1, 1, 1 } }, // zmm vpslld+vptestmd
2555 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i32, { 2, 1, 1, 1 } }, // vpslld+vptestmd
2556 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i64, { 2, 1, 1, 1 } }, // zmm vpsllq+vptestmq
2557 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i64, { 2, 1, 1, 1 } }, // zmm vpsllq+vptestmq
2558 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i64, { 2, 1, 1, 1 } }, // vpsllq+vptestmq
2559 { ISD::TRUNCATE, MVT::v2i8, MVT::v2i32, { 2, 1, 1, 1 } }, // vpmovdb
2560 { ISD::TRUNCATE, MVT::v4i8, MVT::v4i32, { 2, 1, 1, 1 } }, // vpmovdb
2561 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i32, { 2, 1, 1, 1 } }, // vpmovdb
2562 { ISD::TRUNCATE, MVT::v32i8, MVT::v16i32, { 2, 1, 1, 1 } }, // vpmovdb
2563 { ISD::TRUNCATE, MVT::v64i8, MVT::v16i32, { 2, 1, 1, 1 } }, // vpmovdb
2564 { ISD::TRUNCATE, MVT::v16i16, MVT::v16i32, { 2, 1, 1, 1 } }, // vpmovdw
2565 { ISD::TRUNCATE, MVT::v32i16, MVT::v16i32, { 2, 1, 1, 1 } }, // vpmovdw
2566 { ISD::TRUNCATE, MVT::v2i8, MVT::v2i64, { 2, 1, 1, 1 } }, // vpmovqb
2567 { ISD::TRUNCATE, MVT::v2i16, MVT::v2i64, { 1, 1, 1, 1 } }, // vpshufb
2568 { ISD::TRUNCATE, MVT::v8i8, MVT::v8i64, { 2, 1, 1, 1 } }, // vpmovqb
2569 { ISD::TRUNCATE, MVT::v16i8, MVT::v8i64, { 2, 1, 1, 1 } }, // vpmovqb
2570 { ISD::TRUNCATE, MVT::v32i8, MVT::v8i64, { 2, 1, 1, 1 } }, // vpmovqb
2571 { ISD::TRUNCATE, MVT::v64i8, MVT::v8i64, { 2, 1, 1, 1 } }, // vpmovqb
2572 { ISD::TRUNCATE, MVT::v8i16, MVT::v8i64, { 2, 1, 1, 1 } }, // vpmovqw
2573 { ISD::TRUNCATE, MVT::v16i16, MVT::v8i64, { 2, 1, 1, 1 } }, // vpmovqw
2574 { ISD::TRUNCATE, MVT::v32i16, MVT::v8i64, { 2, 1, 1, 1 } }, // vpmovqw
2575 { ISD::TRUNCATE, MVT::v8i32, MVT::v8i64, { 1, 1, 1, 1 } }, // vpmovqd
2576 { ISD::TRUNCATE, MVT::v4i32, MVT::v4i64, { 1, 1, 1, 1 } }, // zmm vpmovqd
2577 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i64, { 5, 1, 1, 1 } },// 2*vpmovqd+concat+vpmovdb
2578
2579 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i16, { 3, 1, 1, 1 } }, // extend to v16i32
2580 { ISD::TRUNCATE, MVT::v32i8, MVT::v32i16, { 8, 1, 1, 1 } },
2581 { ISD::TRUNCATE, MVT::v64i8, MVT::v32i16, { 8, 1, 1, 1 } },
2582
2583 // Sign extend is zmm vpternlogd+vptruncdb.
2584 // Zero extend is zmm broadcast load+vptruncdw.
2585 { ISD::SIGN_EXTEND, MVT::v2i8, MVT::v2i1, { 3, 1, 1, 1 } },
2586 { ISD::ZERO_EXTEND, MVT::v2i8, MVT::v2i1, { 4, 1, 1, 1 } },
2587 { ISD::SIGN_EXTEND, MVT::v4i8, MVT::v4i1, { 3, 1, 1, 1 } },
2588 { ISD::ZERO_EXTEND, MVT::v4i8, MVT::v4i1, { 4, 1, 1, 1 } },
2589 { ISD::SIGN_EXTEND, MVT::v8i8, MVT::v8i1, { 3, 1, 1, 1 } },
2590 { ISD::ZERO_EXTEND, MVT::v8i8, MVT::v8i1, { 4, 1, 1, 1 } },
2591 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v16i1, { 3, 1, 1, 1 } },
2592 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v16i1, { 4, 1, 1, 1 } },
2593
2594 // Sign extend is zmm vpternlogd+vptruncdw.
2595 // Zero extend is zmm vpternlogd+vptruncdw+vpsrlw.
2596 { ISD::SIGN_EXTEND, MVT::v2i16, MVT::v2i1, { 3, 1, 1, 1 } },
2597 { ISD::ZERO_EXTEND, MVT::v2i16, MVT::v2i1, { 4, 1, 1, 1 } },
2598 { ISD::SIGN_EXTEND, MVT::v4i16, MVT::v4i1, { 3, 1, 1, 1 } },
2599 { ISD::ZERO_EXTEND, MVT::v4i16, MVT::v4i1, { 4, 1, 1, 1 } },
2600 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v8i1, { 3, 1, 1, 1 } },
2601 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v8i1, { 4, 1, 1, 1 } },
2602 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i1, { 3, 1, 1, 1 } },
2603 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i1, { 4, 1, 1, 1 } },
2604
2605 { ISD::SIGN_EXTEND, MVT::v2i32, MVT::v2i1, { 1, 1, 1, 1 } }, // zmm vpternlogd
2606 { ISD::ZERO_EXTEND, MVT::v2i32, MVT::v2i1, { 2, 1, 1, 1 } }, // zmm vpternlogd+psrld
2607 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v4i1, { 1, 1, 1, 1 } }, // zmm vpternlogd
2608 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v4i1, { 2, 1, 1, 1 } }, // zmm vpternlogd+psrld
2609 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i1, { 1, 1, 1, 1 } }, // zmm vpternlogd
2610 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i1, { 2, 1, 1, 1 } }, // zmm vpternlogd+psrld
2611 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v2i1, { 1, 1, 1, 1 } }, // zmm vpternlogq
2612 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v2i1, { 2, 1, 1, 1 } }, // zmm vpternlogq+psrlq
2613 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i1, { 1, 1, 1, 1 } }, // zmm vpternlogq
2614 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i1, { 2, 1, 1, 1 } }, // zmm vpternlogq+psrlq
2615
2616 { ISD::SIGN_EXTEND, MVT::v16i32, MVT::v16i1, { 1, 1, 1, 1 } }, // vpternlogd
2617 { ISD::ZERO_EXTEND, MVT::v16i32, MVT::v16i1, { 2, 1, 1, 1 } }, // vpternlogd+psrld
2618 { ISD::SIGN_EXTEND, MVT::v8i64, MVT::v8i1, { 1, 1, 1, 1 } }, // vpternlogq
2619 { ISD::ZERO_EXTEND, MVT::v8i64, MVT::v8i1, { 2, 1, 1, 1 } }, // vpternlogq+psrlq
2620
2621 { ISD::SIGN_EXTEND, MVT::v16i32, MVT::v16i8, { 1, 1, 1, 1 } },
2622 { ISD::ZERO_EXTEND, MVT::v16i32, MVT::v16i8, { 1, 1, 1, 1 } },
2623 { ISD::SIGN_EXTEND, MVT::v16i32, MVT::v16i16, { 1, 1, 1, 1 } },
2624 { ISD::ZERO_EXTEND, MVT::v16i32, MVT::v16i16, { 1, 1, 1, 1 } },
2625 { ISD::SIGN_EXTEND, MVT::v8i64, MVT::v8i8, { 1, 1, 1, 1 } },
2626 { ISD::ZERO_EXTEND, MVT::v8i64, MVT::v8i8, { 1, 1, 1, 1 } },
2627 { ISD::SIGN_EXTEND, MVT::v8i64, MVT::v8i16, { 1, 1, 1, 1 } },
2628 { ISD::ZERO_EXTEND, MVT::v8i64, MVT::v8i16, { 1, 1, 1, 1 } },
2629 { ISD::SIGN_EXTEND, MVT::v8i64, MVT::v8i32, { 1, 1, 1, 1 } },
2630 { ISD::ZERO_EXTEND, MVT::v8i64, MVT::v8i32, { 1, 1, 1, 1 } },
2631
2632 { ISD::SIGN_EXTEND, MVT::v32i16, MVT::v32i8, { 3, 1, 1, 1 } }, // FIXME: May not be right
2633 { ISD::ZERO_EXTEND, MVT::v32i16, MVT::v32i8, { 3, 1, 1, 1 } }, // FIXME: May not be right
2634
2635 { ISD::SINT_TO_FP, MVT::v8f64, MVT::v8i1, { 4, 1, 1, 1 } },
2636 { ISD::SINT_TO_FP, MVT::v16f32, MVT::v16i1, { 3, 1, 1, 1 } },
2637 { ISD::SINT_TO_FP, MVT::v8f64, MVT::v16i8, { 2, 1, 1, 1 } },
2638 { ISD::SINT_TO_FP, MVT::v16f32, MVT::v16i8, { 1, 1, 1, 1 } },
2639 { ISD::SINT_TO_FP, MVT::v8f64, MVT::v8i16, { 2, 1, 1, 1 } },
2640 { ISD::SINT_TO_FP, MVT::v16f32, MVT::v16i16, { 1, 1, 1, 1 } },
2641 { ISD::SINT_TO_FP, MVT::v8f64, MVT::v8i32, { 1, 1, 1, 1 } },
2642 { ISD::SINT_TO_FP, MVT::v16f32, MVT::v16i32, { 1, 1, 1, 1 } },
2643
2644 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i1, { 4, 1, 1, 1 } },
2645 { ISD::UINT_TO_FP, MVT::v16f32, MVT::v16i1, { 3, 1, 1, 1 } },
2646 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v16i8, { 2, 1, 1, 1 } },
2647 { ISD::UINT_TO_FP, MVT::v16f32, MVT::v16i8, { 1, 1, 1, 1 } },
2648 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i16, { 2, 1, 1, 1 } },
2649 { ISD::UINT_TO_FP, MVT::v16f32, MVT::v16i16, { 1, 1, 1, 1 } },
2650 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i32, { 1, 1, 1, 1 } },
2651 { ISD::UINT_TO_FP, MVT::v16f32, MVT::v16i32, { 1, 1, 1, 1 } },
2652 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i64, {26, 1, 1, 1 } },
2653 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i64, { 5, 1, 1, 1 } },
2654
2655 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v16f32, { 2, 1, 1, 1 } },
2656 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v16f64, { 7, 1, 1, 1 } },
2657 { ISD::FP_TO_SINT, MVT::v32i8, MVT::v32f64, {15, 1, 1, 1 } },
2658 { ISD::FP_TO_SINT, MVT::v64i8, MVT::v64f32, {11, 1, 1, 1 } },
2659 { ISD::FP_TO_SINT, MVT::v64i8, MVT::v64f64, {31, 1, 1, 1 } },
2660 { ISD::FP_TO_SINT, MVT::v8i16, MVT::v8f64, { 3, 1, 1, 1 } },
2661 { ISD::FP_TO_SINT, MVT::v16i16, MVT::v16f64, { 7, 1, 1, 1 } },
2662 { ISD::FP_TO_SINT, MVT::v32i16, MVT::v32f32, { 5, 1, 1, 1 } },
2663 { ISD::FP_TO_SINT, MVT::v32i16, MVT::v32f64, {15, 1, 1, 1 } },
2664 { ISD::FP_TO_SINT, MVT::v8i32, MVT::v8f64, { 1, 1, 1, 1 } },
2665 { ISD::FP_TO_SINT, MVT::v16i32, MVT::v16f64, { 3, 1, 1, 1 } },
2666
2667 { ISD::FP_TO_UINT, MVT::v8i32, MVT::v8f64, { 1, 1, 1, 1 } },
2668 { ISD::FP_TO_UINT, MVT::v8i16, MVT::v8f64, { 3, 1, 1, 1 } },
2669 { ISD::FP_TO_UINT, MVT::v8i8, MVT::v8f64, { 3, 1, 1, 1 } },
2670 { ISD::FP_TO_UINT, MVT::v16i32, MVT::v16f32, { 1, 1, 1, 1 } },
2671 { ISD::FP_TO_UINT, MVT::v16i16, MVT::v16f32, { 3, 1, 1, 1 } },
2672 { ISD::FP_TO_UINT, MVT::v16i8, MVT::v16f32, { 3, 1, 1, 1 } },
2673 };
2674
2675 static const TypeConversionCostKindTblEntry AVX512BWVLConversionTbl[] {
2676 // Mask sign extend has an instruction.
2677 { ISD::SIGN_EXTEND, MVT::v2i8, MVT::v2i1, { 1, 1, 1, 1 } },
2678 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v2i1, { 1, 1, 1, 1 } },
2679 { ISD::SIGN_EXTEND, MVT::v2i16, MVT::v2i1, { 1, 1, 1, 1 } },
2680 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v2i1, { 1, 1, 1, 1 } },
2681 { ISD::SIGN_EXTEND, MVT::v4i16, MVT::v4i1, { 1, 1, 1, 1 } },
2682 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v4i1, { 1, 1, 1, 1 } },
2683 { ISD::SIGN_EXTEND, MVT::v4i8, MVT::v4i1, { 1, 1, 1, 1 } },
2684 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v4i1, { 1, 1, 1, 1 } },
2685 { ISD::SIGN_EXTEND, MVT::v8i8, MVT::v8i1, { 1, 1, 1, 1 } },
2686 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v8i1, { 1, 1, 1, 1 } },
2687 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v8i1, { 1, 1, 1, 1 } },
2688 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v16i1, { 1, 1, 1, 1 } },
2689 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i1, { 1, 1, 1, 1 } },
2690 { ISD::SIGN_EXTEND, MVT::v32i8, MVT::v32i1, { 1, 1, 1, 1 } },
2691 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v32i1, { 1, 1, 1, 1 } },
2692 { ISD::SIGN_EXTEND, MVT::v32i8, MVT::v64i1, { 1, 1, 1, 1 } },
2693 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v64i1, { 1, 1, 1, 1 } },
2694
2695 // Mask zero extend is a sext + shift.
2696 { ISD::ZERO_EXTEND, MVT::v2i8, MVT::v2i1, { 2, 1, 1, 1 } },
2697 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v2i1, { 2, 1, 1, 1 } },
2698 { ISD::ZERO_EXTEND, MVT::v2i16, MVT::v2i1, { 2, 1, 1, 1 } },
2699 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v2i1, { 2, 1, 1, 1 } },
2700 { ISD::ZERO_EXTEND, MVT::v4i8, MVT::v4i1, { 2, 1, 1, 1 } },
2701 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v4i1, { 2, 1, 1, 1 } },
2702 { ISD::ZERO_EXTEND, MVT::v4i16, MVT::v4i1, { 2, 1, 1, 1 } },
2703 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v4i1, { 2, 1, 1, 1 } },
2704 { ISD::ZERO_EXTEND, MVT::v8i8, MVT::v8i1, { 2, 1, 1, 1 } },
2705 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v8i1, { 2, 1, 1, 1 } },
2706 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v8i1, { 2, 1, 1, 1 } },
2707 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v16i1, { 2, 1, 1, 1 } },
2708 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i1, { 2, 1, 1, 1 } },
2709 { ISD::ZERO_EXTEND, MVT::v32i8, MVT::v32i1, { 2, 1, 1, 1 } },
2710 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v32i1, { 2, 1, 1, 1 } },
2711 { ISD::ZERO_EXTEND, MVT::v32i8, MVT::v64i1, { 2, 1, 1, 1 } },
2712 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v64i1, { 2, 1, 1, 1 } },
2713
2714 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i8, { 2, 1, 1, 1 } },
2715 { ISD::TRUNCATE, MVT::v2i1, MVT::v16i8, { 2, 1, 1, 1 } },
2716 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i16, { 2, 1, 1, 1 } },
2717 { ISD::TRUNCATE, MVT::v2i1, MVT::v8i16, { 2, 1, 1, 1 } },
2718 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i8, { 2, 1, 1, 1 } },
2719 { ISD::TRUNCATE, MVT::v4i1, MVT::v16i8, { 2, 1, 1, 1 } },
2720 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i16, { 2, 1, 1, 1 } },
2721 { ISD::TRUNCATE, MVT::v4i1, MVT::v8i16, { 2, 1, 1, 1 } },
2722 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i8, { 2, 1, 1, 1 } },
2723 { ISD::TRUNCATE, MVT::v8i1, MVT::v16i8, { 2, 1, 1, 1 } },
2724 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i16, { 2, 1, 1, 1 } },
2725 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i8, { 2, 1, 1, 1 } },
2726 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i16, { 2, 1, 1, 1 } },
2727 { ISD::TRUNCATE, MVT::v32i1, MVT::v32i8, { 2, 1, 1, 1 } },
2728 { ISD::TRUNCATE, MVT::v32i1, MVT::v16i16, { 2, 1, 1, 1 } },
2729 { ISD::TRUNCATE, MVT::v64i1, MVT::v32i8, { 2, 1, 1, 1 } },
2730 { ISD::TRUNCATE, MVT::v64i1, MVT::v16i16, { 2, 1, 1, 1 } },
2731
2732 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i16, { 2, 1, 1, 1 } },
2733 };
2734
2735 static const TypeConversionCostKindTblEntry AVX512DQVLConversionTbl[] = {
2736 // Mask sign extend has an instruction.
2737 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v2i1, { 1, 1, 1, 1 } },
2738 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v2i1, { 1, 1, 1, 1 } },
2739 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v4i1, { 1, 1, 1, 1 } },
2740 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v16i1, { 1, 1, 1, 1 } },
2741 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i1, { 1, 1, 1, 1 } },
2742 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v8i1, { 1, 1, 1, 1 } },
2743 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v16i1, { 1, 1, 1, 1 } },
2744 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i1, { 1, 1, 1, 1 } },
2745
2746 // Mask zero extend is a sext + shift.
2747 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v2i1, { 2, 1, 1, 1 } },
2748 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v2i1, { 2, 1, 1, 1 } },
2749 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v4i1, { 2, 1, 1, 1 } },
2750 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v16i1, { 2, 1, 1, 1 } },
2751 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i1, { 2, 1, 1, 1 } },
2752 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v8i1, { 2, 1, 1, 1 } },
2753 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v16i1, { 2, 1, 1, 1 } },
2754 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i1, { 2, 1, 1, 1 } },
2755
2756 { ISD::TRUNCATE, MVT::v16i1, MVT::v4i64, { 2, 1, 1, 1 } },
2757 { ISD::TRUNCATE, MVT::v16i1, MVT::v8i32, { 2, 1, 1, 1 } },
2758 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i64, { 2, 1, 1, 1 } },
2759 { ISD::TRUNCATE, MVT::v2i1, MVT::v4i32, { 2, 1, 1, 1 } },
2760 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i32, { 2, 1, 1, 1 } },
2761 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i64, { 2, 1, 1, 1 } },
2762 { ISD::TRUNCATE, MVT::v8i1, MVT::v4i64, { 2, 1, 1, 1 } },
2763 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i32, { 2, 1, 1, 1 } },
2764
2765 { ISD::SINT_TO_FP, MVT::v2f32, MVT::v2i64, { 1, 1, 1, 1 } },
2766 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v2i64, { 1, 1, 1, 1 } },
2767 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v4i64, { 1, 1, 1, 1 } },
2768 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v4i64, { 1, 1, 1, 1 } },
2769
2770 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i64, { 1, 1, 1, 1 } },
2771 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i64, { 1, 1, 1, 1 } },
2772 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i64, { 1, 1, 1, 1 } },
2773 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i64, { 1, 1, 1, 1 } },
2774
2775 { ISD::FP_TO_SINT, MVT::v2i64, MVT::v4f32, { 1, 1, 1, 1 } },
2776 { ISD::FP_TO_SINT, MVT::v4i64, MVT::v4f32, { 1, 1, 1, 1 } },
2777 { ISD::FP_TO_SINT, MVT::v2i64, MVT::v2f64, { 1, 1, 1, 1 } },
2778 { ISD::FP_TO_SINT, MVT::v4i64, MVT::v4f64, { 1, 1, 1, 1 } },
2779
2780 { ISD::FP_TO_UINT, MVT::v2i64, MVT::v4f32, { 1, 1, 1, 1 } },
2781 { ISD::FP_TO_UINT, MVT::v4i64, MVT::v4f32, { 1, 1, 1, 1 } },
2782 { ISD::FP_TO_UINT, MVT::v2i64, MVT::v2f64, { 1, 1, 1, 1 } },
2783 { ISD::FP_TO_UINT, MVT::v4i64, MVT::v4f64, { 1, 1, 1, 1 } },
2784 };
2785
2786 static const TypeConversionCostKindTblEntry AVX512VLConversionTbl[] = {
2787 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i8, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
2788 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i8, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
2789 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i8, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
2790 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i8, { 8, 1, 1, 1 } }, // split+2*v8i8
2791 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i16, { 3, 1, 1, 1 } }, // sext+vpsllq+vptestmq
2792 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i16, { 3, 1, 1, 1 } }, // sext+vpsllq+vptestmq
2793 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i16, { 3, 1, 1, 1 } }, // sext+vpsllq+vptestmq
2794 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i16, { 8, 1, 1, 1 } }, // split+2*v8i16
2795 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i32, { 2, 1, 1, 1 } }, // vpslld+vptestmd
2796 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i32, { 2, 1, 1, 1 } }, // vpslld+vptestmd
2797 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i32, { 2, 1, 1, 1 } }, // vpslld+vptestmd
2798 { ISD::TRUNCATE, MVT::v16i1, MVT::v8i32, { 2, 1, 1, 1 } }, // vpslld+vptestmd
2799 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i64, { 2, 1, 1, 1 } }, // vpsllq+vptestmq
2800 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i64, { 2, 1, 1, 1 } }, // vpsllq+vptestmq
2801 { ISD::TRUNCATE, MVT::v4i32, MVT::v4i64, { 1, 1, 1, 1 } }, // vpmovqd
2802 { ISD::TRUNCATE, MVT::v4i8, MVT::v4i64, { 2, 1, 1, 1 } }, // vpmovqb
2803 { ISD::TRUNCATE, MVT::v4i16, MVT::v4i64, { 2, 1, 1, 1 } }, // vpmovqw
2804 { ISD::TRUNCATE, MVT::v8i8, MVT::v8i32, { 2, 1, 1, 1 } }, // vpmovwb
2805
2806 // sign extend is vpcmpeq+maskedmove+vpmovdw+vpacksswb
2807 // zero extend is vpcmpeq+maskedmove+vpmovdw+vpsrlw+vpackuswb
2808 { ISD::SIGN_EXTEND, MVT::v2i8, MVT::v2i1, { 5, 1, 1, 1 } },
2809 { ISD::ZERO_EXTEND, MVT::v2i8, MVT::v2i1, { 6, 1, 1, 1 } },
2810 { ISD::SIGN_EXTEND, MVT::v4i8, MVT::v4i1, { 5, 1, 1, 1 } },
2811 { ISD::ZERO_EXTEND, MVT::v4i8, MVT::v4i1, { 6, 1, 1, 1 } },
2812 { ISD::SIGN_EXTEND, MVT::v8i8, MVT::v8i1, { 5, 1, 1, 1 } },
2813 { ISD::ZERO_EXTEND, MVT::v8i8, MVT::v8i1, { 6, 1, 1, 1 } },
2814 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v16i1, {10, 1, 1, 1 } },
2815 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v16i1, {12, 1, 1, 1 } },
2816
2817 // sign extend is vpcmpeq+maskedmove+vpmovdw
2818 // zero extend is vpcmpeq+maskedmove+vpmovdw+vpsrlw
2819 { ISD::SIGN_EXTEND, MVT::v2i16, MVT::v2i1, { 4, 1, 1, 1 } },
2820 { ISD::ZERO_EXTEND, MVT::v2i16, MVT::v2i1, { 5, 1, 1, 1 } },
2821 { ISD::SIGN_EXTEND, MVT::v4i16, MVT::v4i1, { 4, 1, 1, 1 } },
2822 { ISD::ZERO_EXTEND, MVT::v4i16, MVT::v4i1, { 5, 1, 1, 1 } },
2823 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v8i1, { 4, 1, 1, 1 } },
2824 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v8i1, { 5, 1, 1, 1 } },
2825 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i1, {10, 1, 1, 1 } },
2826 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i1, {12, 1, 1, 1 } },
2827
2828 { ISD::SIGN_EXTEND, MVT::v2i32, MVT::v2i1, { 1, 1, 1, 1 } }, // vpternlogd
2829 { ISD::ZERO_EXTEND, MVT::v2i32, MVT::v2i1, { 2, 1, 1, 1 } }, // vpternlogd+psrld
2830 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v4i1, { 1, 1, 1, 1 } }, // vpternlogd
2831 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v4i1, { 2, 1, 1, 1 } }, // vpternlogd+psrld
2832 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i1, { 1, 1, 1, 1 } }, // vpternlogd
2833 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i1, { 2, 1, 1, 1 } }, // vpternlogd+psrld
2834 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v16i1, { 1, 1, 1, 1 } }, // vpternlogd
2835 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v16i1, { 2, 1, 1, 1 } }, // vpternlogd+psrld
2836
2837 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v2i1, { 1, 1, 1, 1 } }, // vpternlogq
2838 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v2i1, { 2, 1, 1, 1 } }, // vpternlogq+psrlq
2839 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i1, { 1, 1, 1, 1 } }, // vpternlogq
2840 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i1, { 2, 1, 1, 1 } }, // vpternlogq+psrlq
2841
2842 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v16i8, { 1, 1, 1, 1 } },
2843 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v16i8, { 1, 1, 1, 1 } },
2844 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v16i8, { 1, 1, 1, 1 } },
2845 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v16i8, { 1, 1, 1, 1 } },
2846 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i8, { 1, 1, 1, 1 } },
2847 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i8, { 1, 1, 1, 1 } },
2848 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v8i16, { 1, 1, 1, 1 } },
2849 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v8i16, { 1, 1, 1, 1 } },
2850 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i16, { 1, 1, 1, 1 } },
2851 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i16, { 1, 1, 1, 1 } },
2852 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i32, { 1, 1, 1, 1 } },
2853 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i32, { 1, 1, 1, 1 } },
2854
2855 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v16i8, { 1, 1, 1, 1 } },
2856 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v16i8, { 1, 1, 1, 1 } },
2857 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v8i16, { 1, 1, 1, 1 } },
2858 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v8i16, { 1, 1, 1, 1 } },
2859
2860 { ISD::UINT_TO_FP, MVT::f32, MVT::i64, { 1, 1, 1, 1 } },
2861 { ISD::UINT_TO_FP, MVT::f64, MVT::i64, { 1, 1, 1, 1 } },
2862 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v16i8, { 1, 1, 1, 1 } },
2863 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v16i8, { 1, 1, 1, 1 } },
2864 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v8i16, { 1, 1, 1, 1 } },
2865 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i16, { 1, 1, 1, 1 } },
2866 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i32, { 1, 1, 1, 1 } },
2867 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i32, { 1, 1, 1, 1 } },
2868 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i32, { 1, 1, 1, 1 } },
2869 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i32, { 1, 1, 1, 1 } },
2870 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i64, { 5, 1, 1, 1 } },
2871 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i64, { 5, 1, 1, 1 } },
2872 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i64, { 5, 1, 1, 1 } },
2873
2874 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v8f32, { 2, 1, 1, 1 } },
2875 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v16f32, { 2, 1, 1, 1 } },
2876 { ISD::FP_TO_SINT, MVT::v32i8, MVT::v32f32, { 5, 1, 1, 1 } },
2877
2878 { ISD::FP_TO_UINT, MVT::i64, MVT::f32, { 1, 1, 1, 1 } },
2879 { ISD::FP_TO_UINT, MVT::i64, MVT::f64, { 1, 1, 1, 1 } },
2880 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f32, { 1, 1, 1, 1 } },
2881 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v2f64, { 1, 1, 1, 1 } },
2882 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f64, { 1, 1, 1, 1 } },
2883 { ISD::FP_TO_UINT, MVT::v8i32, MVT::v8f32, { 1, 1, 1, 1 } },
2884 { ISD::FP_TO_UINT, MVT::v8i32, MVT::v8f64, { 1, 1, 1, 1 } },
2885 };
2886
2887 static const TypeConversionCostKindTblEntry AVX2ConversionTbl[] = {
2888 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i1, { 3, 1, 1, 1 } },
2889 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i1, { 3, 1, 1, 1 } },
2890 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i1, { 3, 1, 1, 1 } },
2891 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i1, { 3, 1, 1, 1 } },
2892 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i1, { 1, 1, 1, 1 } },
2893 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i1, { 1, 1, 1, 1 } },
2894
2895 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v16i8, { 2, 1, 1, 1 } },
2896 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v16i8, { 2, 1, 1, 1 } },
2897 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v16i8, { 2, 1, 1, 1 } },
2898 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v16i8, { 2, 1, 1, 1 } },
2899 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i8, { 2, 1, 1, 1 } },
2900 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i8, { 2, 1, 1, 1 } },
2901 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v8i16, { 2, 1, 1, 1 } },
2902 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v8i16, { 2, 1, 1, 1 } },
2903 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i16, { 2, 1, 1, 1 } },
2904 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i16, { 2, 1, 1, 1 } },
2905 { ISD::ZERO_EXTEND, MVT::v16i32, MVT::v16i16, { 3, 1, 1, 1 } },
2906 { ISD::SIGN_EXTEND, MVT::v16i32, MVT::v16i16, { 3, 1, 1, 1 } },
2907 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i32, { 2, 1, 1, 1 } },
2908 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i32, { 2, 1, 1, 1 } },
2909
2910 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i32, { 2, 1, 1, 1 } },
2911
2912 { ISD::TRUNCATE, MVT::v16i16, MVT::v16i32, { 4, 1, 1, 1 } },
2913 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i32, { 4, 1, 1, 1 } },
2914 { ISD::TRUNCATE, MVT::v16i8, MVT::v8i16, { 1, 1, 1, 1 } },
2915 { ISD::TRUNCATE, MVT::v16i8, MVT::v4i32, { 1, 1, 1, 1 } },
2916 { ISD::TRUNCATE, MVT::v16i8, MVT::v2i64, { 1, 1, 1, 1 } },
2917 { ISD::TRUNCATE, MVT::v16i8, MVT::v8i32, { 4, 1, 1, 1 } },
2918 { ISD::TRUNCATE, MVT::v16i8, MVT::v4i64, { 4, 1, 1, 1 } },
2919 { ISD::TRUNCATE, MVT::v8i16, MVT::v4i32, { 1, 1, 1, 1 } },
2920 { ISD::TRUNCATE, MVT::v8i16, MVT::v2i64, { 1, 1, 1, 1 } },
2921 { ISD::TRUNCATE, MVT::v8i16, MVT::v4i64, { 5, 1, 1, 1 } },
2922 { ISD::TRUNCATE, MVT::v4i32, MVT::v4i64, { 1, 1, 1, 1 } },
2923 { ISD::TRUNCATE, MVT::v8i16, MVT::v8i32, { 2, 1, 1, 1 } },
2924
2925 { ISD::FP_EXTEND, MVT::v8f64, MVT::v8f32, { 3, 1, 1, 1 } },
2926 { ISD::FP_ROUND, MVT::v8f32, MVT::v8f64, { 3, 1, 1, 1 } },
2927
2928 { ISD::FP_TO_SINT, MVT::v16i16, MVT::v8f32, { 1, 1, 1, 1 } },
2929 { ISD::FP_TO_SINT, MVT::v4i32, MVT::v4f64, { 1, 1, 1, 1 } },
2930 { ISD::FP_TO_SINT, MVT::v8i32, MVT::v8f32, { 1, 1, 1, 1 } },
2931 { ISD::FP_TO_SINT, MVT::v8i32, MVT::v8f64, { 3, 1, 1, 1 } },
2932
2933 { ISD::FP_TO_UINT, MVT::i64, MVT::f32, { 3, 1, 1, 1 } },
2934 { ISD::FP_TO_UINT, MVT::i64, MVT::f64, { 3, 1, 1, 1 } },
2935 { ISD::FP_TO_UINT, MVT::v16i16, MVT::v8f32, { 1, 1, 1, 1 } },
2936 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f32, { 3, 1, 1, 1 } },
2937 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v2f64, { 4, 1, 1, 1 } },
2938 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f64, { 4, 1, 1, 1 } },
2939 { ISD::FP_TO_UINT, MVT::v8i32, MVT::v8f32, { 3, 1, 1, 1 } },
2940 { ISD::FP_TO_UINT, MVT::v8i32, MVT::v4f64, { 4, 1, 1, 1 } },
2941
2942 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v16i8, { 2, 1, 1, 1 } },
2943 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v16i8, { 2, 1, 1, 1 } },
2944 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v8i16, { 2, 1, 1, 1 } },
2945 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v8i16, { 2, 1, 1, 1 } },
2946 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v4i32, { 1, 1, 1, 1 } },
2947 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v8i32, { 1, 1, 1, 1 } },
2948 { ISD::SINT_TO_FP, MVT::v8f64, MVT::v8i32, { 3, 1, 1, 1 } },
2949
2950 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v16i8, { 2, 1, 1, 1 } },
2951 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v16i8, { 2, 1, 1, 1 } },
2952 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v8i16, { 2, 1, 1, 1 } },
2953 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i16, { 2, 1, 1, 1 } },
2954 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i32, { 2, 1, 1, 1 } },
2955 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i32, { 1, 1, 1, 1 } },
2956 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i32, { 2, 1, 1, 1 } },
2957 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i32, { 2, 1, 1, 1 } },
2958 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i32, { 2, 1, 1, 1 } },
2959 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i32, { 4, 1, 1, 1 } },
2960 };
2961
2962 static const TypeConversionCostKindTblEntry AVXConversionTbl[] = {
2963 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i1, { 4, 1, 1, 1 } },
2964 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i1, { 4, 1, 1, 1 } },
2965 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i1, { 4, 1, 1, 1 } },
2966 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i1, { 4, 1, 1, 1 } },
2967 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i1, { 4, 1, 1, 1 } },
2968 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i1, { 4, 1, 1, 1 } },
2969
2970 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v16i8, { 3, 1, 1, 1 } },
2971 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v16i8, { 3, 1, 1, 1 } },
2972 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v16i8, { 3, 1, 1, 1 } },
2973 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v16i8, { 3, 1, 1, 1 } },
2974 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i8, { 3, 1, 1, 1 } },
2975 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i8, { 3, 1, 1, 1 } },
2976 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v8i16, { 3, 1, 1, 1 } },
2977 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v8i16, { 3, 1, 1, 1 } },
2978 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i16, { 3, 1, 1, 1 } },
2979 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i16, { 3, 1, 1, 1 } },
2980 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i32, { 3, 1, 1, 1 } },
2981 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i32, { 3, 1, 1, 1 } },
2982
2983 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i64, { 4, 1, 1, 1 } },
2984 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i32, { 5, 1, 1, 1 } },
2985 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i16, { 4, 1, 1, 1 } },
2986 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i64, { 9, 1, 1, 1 } },
2987 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i64, {11, 1, 1, 1 } },
2988
2989 { ISD::TRUNCATE, MVT::v16i16, MVT::v16i32, { 6, 1, 1, 1 } },
2990 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i32, { 6, 1, 1, 1 } },
2991 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i16, { 2, 1, 1, 1 } }, // and+extract+packuswb
2992 { ISD::TRUNCATE, MVT::v16i8, MVT::v8i32, { 5, 1, 1, 1 } },
2993 { ISD::TRUNCATE, MVT::v8i16, MVT::v8i32, { 5, 1, 1, 1 } },
2994 { ISD::TRUNCATE, MVT::v16i8, MVT::v4i64, { 5, 1, 1, 1 } },
2995 { ISD::TRUNCATE, MVT::v8i16, MVT::v4i64, { 3, 1, 1, 1 } }, // and+extract+2*packusdw
2996 { ISD::TRUNCATE, MVT::v4i32, MVT::v4i64, { 2, 1, 1, 1 } },
2997
2998 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v4i1, { 3, 1, 1, 1 } },
2999 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v4i1, { 3, 1, 1, 1 } },
3000 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v8i1, { 8, 1, 1, 1 } },
3001 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v16i8, { 4, 1, 1, 1 } },
3002 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v16i8, { 2, 1, 1, 1 } },
3003 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v8i16, { 4, 1, 1, 1 } },
3004 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v8i16, { 2, 1, 1, 1 } },
3005 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v4i32, { 2, 1, 1, 1 } },
3006 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v8i32, { 2, 1, 1, 1 } },
3007 { ISD::SINT_TO_FP, MVT::v8f64, MVT::v8i32, { 4, 1, 1, 1 } },
3008 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v2i64, { 5, 1, 1, 1 } },
3009 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v4i64, { 8, 1, 1, 1 } },
3010
3011 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i1, { 7, 1, 1, 1 } },
3012 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i1, { 7, 1, 1, 1 } },
3013 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i1, { 6, 1, 1, 1 } },
3014 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v16i8, { 4, 1, 1, 1 } },
3015 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v16i8, { 2, 1, 1, 1 } },
3016 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i16, { 4, 1, 1, 1 } },
3017 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v8i16, { 2, 1, 1, 1 } },
3018 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i32, { 4, 1, 1, 1 } },
3019 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i32, { 4, 1, 1, 1 } },
3020 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i32, { 5, 1, 1, 1 } },
3021 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i32, { 6, 1, 1, 1 } },
3022 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i32, { 8, 1, 1, 1 } },
3023 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i32, {10, 1, 1, 1 } },
3024 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i64, {10, 1, 1, 1 } },
3025 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i64, {18, 1, 1, 1 } },
3026 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i64, { 5, 1, 1, 1 } },
3027 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i64, {10, 1, 1, 1 } },
3028
3029 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v8f32, { 2, 1, 1, 1 } },
3030 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v4f64, { 2, 1, 1, 1 } },
3031 { ISD::FP_TO_SINT, MVT::v32i8, MVT::v8f32, { 2, 1, 1, 1 } },
3032 { ISD::FP_TO_SINT, MVT::v32i8, MVT::v4f64, { 2, 1, 1, 1 } },
3033 { ISD::FP_TO_SINT, MVT::v8i16, MVT::v8f32, { 2, 1, 1, 1 } },
3034 { ISD::FP_TO_SINT, MVT::v8i16, MVT::v4f64, { 2, 1, 1, 1 } },
3035 { ISD::FP_TO_SINT, MVT::v16i16, MVT::v8f32, { 2, 1, 1, 1 } },
3036 { ISD::FP_TO_SINT, MVT::v16i16, MVT::v4f64, { 2, 1, 1, 1 } },
3037 { ISD::FP_TO_SINT, MVT::v4i32, MVT::v4f64, { 2, 1, 1, 1 } },
3038 { ISD::FP_TO_SINT, MVT::v8i32, MVT::v8f32, { 2, 1, 1, 1 } },
3039 { ISD::FP_TO_SINT, MVT::v8i32, MVT::v8f64, { 5, 1, 1, 1 } },
3040
3041 { ISD::FP_TO_UINT, MVT::v16i8, MVT::v8f32, { 2, 1, 1, 1 } },
3042 { ISD::FP_TO_UINT, MVT::v16i8, MVT::v4f64, { 2, 1, 1, 1 } },
3043 { ISD::FP_TO_UINT, MVT::v32i8, MVT::v8f32, { 2, 1, 1, 1 } },
3044 { ISD::FP_TO_UINT, MVT::v32i8, MVT::v4f64, { 2, 1, 1, 1 } },
3045 { ISD::FP_TO_UINT, MVT::v8i16, MVT::v8f32, { 2, 1, 1, 1 } },
3046 { ISD::FP_TO_UINT, MVT::v8i16, MVT::v4f64, { 2, 1, 1, 1 } },
3047 { ISD::FP_TO_UINT, MVT::v16i16, MVT::v8f32, { 2, 1, 1, 1 } },
3048 { ISD::FP_TO_UINT, MVT::v16i16, MVT::v4f64, { 2, 1, 1, 1 } },
3049 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f32, { 3, 1, 1, 1 } },
3050 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v2f64, { 4, 1, 1, 1 } },
3051 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f64, { 6, 1, 1, 1 } },
3052 { ISD::FP_TO_UINT, MVT::v8i32, MVT::v8f32, { 7, 1, 1, 1 } },
3053 { ISD::FP_TO_UINT, MVT::v8i32, MVT::v4f64, { 7, 1, 1, 1 } },
3054
3055 { ISD::FP_EXTEND, MVT::v4f64, MVT::v4f32, { 1, 1, 1, 1 } },
3056 { ISD::FP_ROUND, MVT::v4f32, MVT::v4f64, { 1, 1, 1, 1 } },
3057 };
3058
3059 static const TypeConversionCostKindTblEntry SSE41ConversionTbl[] = {
3060 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v16i8, { 1, 1, 1, 1 } },
3061 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v16i8, { 1, 1, 1, 1 } },
3062 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v16i8, { 1, 1, 1, 1 } },
3063 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v16i8, { 1, 1, 1, 1 } },
3064 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v16i8, { 1, 1, 1, 1 } },
3065 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v16i8, { 1, 1, 1, 1 } },
3066 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v8i16, { 1, 1, 1, 1 } },
3067 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v8i16, { 1, 1, 1, 1 } },
3068 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v8i16, { 1, 1, 1, 1 } },
3069 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v8i16, { 1, 1, 1, 1 } },
3070 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v4i32, { 1, 1, 1, 1 } },
3071 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v4i32, { 1, 1, 1, 1 } },
3072
3073 // These truncates end up widening elements.
3074 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i8, { 1, 1, 1, 1 } }, // PMOVXZBQ
3075 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i16, { 1, 1, 1, 1 } }, // PMOVXZWQ
3076 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i8, { 1, 1, 1, 1 } }, // PMOVXZBD
3077
3078 { ISD::TRUNCATE, MVT::v16i8, MVT::v4i32, { 2, 1, 1, 1 } },
3079 { ISD::TRUNCATE, MVT::v8i16, MVT::v4i32, { 2, 1, 1, 1 } },
3080 { ISD::TRUNCATE, MVT::v16i8, MVT::v2i64, { 2, 1, 1, 1 } },
3081
3082 { ISD::SINT_TO_FP, MVT::f32, MVT::i32, { 1, 1, 1, 1 } },
3083 { ISD::SINT_TO_FP, MVT::f64, MVT::i32, { 1, 1, 1, 1 } },
3084 { ISD::SINT_TO_FP, MVT::f32, MVT::i64, { 1, 1, 1, 1 } },
3085 { ISD::SINT_TO_FP, MVT::f64, MVT::i64, { 1, 1, 1, 1 } },
3086 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v16i8, { 1, 1, 1, 1 } },
3087 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v16i8, { 1, 1, 1, 1 } },
3088 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v8i16, { 1, 1, 1, 1 } },
3089 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v8i16, { 1, 1, 1, 1 } },
3090 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v4i32, { 1, 1, 1, 1 } },
3091 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v4i32, { 1, 1, 1, 1 } },
3092 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v4i32, { 2, 1, 1, 1 } },
3093
3094 { ISD::UINT_TO_FP, MVT::f32, MVT::i32, { 1, 1, 1, 1 } },
3095 { ISD::UINT_TO_FP, MVT::f64, MVT::i32, { 1, 1, 1, 1 } },
3096 { ISD::UINT_TO_FP, MVT::f32, MVT::i64, { 4, 1, 1, 1 } },
3097 { ISD::UINT_TO_FP, MVT::f64, MVT::i64, { 4, 1, 1, 1 } },
3098 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v16i8, { 1, 1, 1, 1 } },
3099 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v16i8, { 1, 1, 1, 1 } },
3100 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v8i16, { 1, 1, 1, 1 } },
3101 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v8i16, { 1, 1, 1, 1 } },
3102 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i32, { 3, 1, 1, 1 } },
3103 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i32, { 3, 1, 1, 1 } },
3104 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v4i32, { 2, 1, 1, 1 } },
3105 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v2i64, {12, 1, 1, 1 } },
3106 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i64, {22, 1, 1, 1 } },
3107 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i64, { 4, 1, 1, 1 } },
3108
3109 { ISD::FP_TO_SINT, MVT::i32, MVT::f32, { 1, 1, 1, 1 } },
3110 { ISD::FP_TO_SINT, MVT::i64, MVT::f32, { 1, 1, 1, 1 } },
3111 { ISD::FP_TO_SINT, MVT::i32, MVT::f64, { 1, 1, 1, 1 } },
3112 { ISD::FP_TO_SINT, MVT::i64, MVT::f64, { 1, 1, 1, 1 } },
3113 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v4f32, { 2, 1, 1, 1 } },
3114 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v2f64, { 2, 1, 1, 1 } },
3115 { ISD::FP_TO_SINT, MVT::v8i16, MVT::v4f32, { 1, 1, 1, 1 } },
3116 { ISD::FP_TO_SINT, MVT::v8i16, MVT::v2f64, { 1, 1, 1, 1 } },
3117 { ISD::FP_TO_SINT, MVT::v4i32, MVT::v4f32, { 1, 1, 1, 1 } },
3118 { ISD::FP_TO_SINT, MVT::v4i32, MVT::v2f64, { 1, 1, 1, 1 } },
3119
3120 { ISD::FP_TO_UINT, MVT::i32, MVT::f32, { 1, 1, 1, 1 } },
3121 { ISD::FP_TO_UINT, MVT::i64, MVT::f32, { 4, 1, 1, 1 } },
3122 { ISD::FP_TO_UINT, MVT::i32, MVT::f64, { 1, 1, 1, 1 } },
3123 { ISD::FP_TO_UINT, MVT::i64, MVT::f64, { 4, 1, 1, 1 } },
3124 { ISD::FP_TO_UINT, MVT::v16i8, MVT::v4f32, { 2, 1, 1, 1 } },
3125 { ISD::FP_TO_UINT, MVT::v16i8, MVT::v2f64, { 2, 1, 1, 1 } },
3126 { ISD::FP_TO_UINT, MVT::v8i16, MVT::v4f32, { 1, 1, 1, 1 } },
3127 { ISD::FP_TO_UINT, MVT::v8i16, MVT::v2f64, { 1, 1, 1, 1 } },
3128 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f32, { 4, 1, 1, 1 } },
3129 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v2f64, { 4, 1, 1, 1 } },
3130 };
3131
3132 static const TypeConversionCostKindTblEntry SSE2ConversionTbl[] = {
3133 // These are somewhat magic numbers justified by comparing the
3134 // output of llvm-mca for our various supported scheduler models
3135 // and basing it off the worst case scenario.
3136 { ISD::SINT_TO_FP, MVT::f32, MVT::i32, { 3, 1, 1, 1 } },
3137 { ISD::SINT_TO_FP, MVT::f64, MVT::i32, { 3, 1, 1, 1 } },
3138 { ISD::SINT_TO_FP, MVT::f32, MVT::i64, { 3, 1, 1, 1 } },
3139 { ISD::SINT_TO_FP, MVT::f64, MVT::i64, { 3, 1, 1, 1 } },
3140 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v16i8, { 3, 1, 1, 1 } },
3141 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v16i8, { 4, 1, 1, 1 } },
3142 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v8i16, { 3, 1, 1, 1 } },
3143 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v8i16, { 4, 1, 1, 1 } },
3144 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v4i32, { 3, 1, 1, 1 } },
3145 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v4i32, { 4, 1, 1, 1 } },
3146 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v2i64, { 8, 1, 1, 1 } },
3147 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v2i64, { 8, 1, 1, 1 } },
3148
3149 { ISD::UINT_TO_FP, MVT::f32, MVT::i32, { 3, 1, 1, 1 } },
3150 { ISD::UINT_TO_FP, MVT::f64, MVT::i32, { 3, 1, 1, 1 } },
3151 { ISD::UINT_TO_FP, MVT::f32, MVT::i64, { 8, 1, 1, 1 } },
3152 { ISD::UINT_TO_FP, MVT::f64, MVT::i64, { 9, 1, 1, 1 } },
3153 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v16i8, { 4, 1, 1, 1 } },
3154 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v16i8, { 4, 1, 1, 1 } },
3155 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v8i16, { 4, 1, 1, 1 } },
3156 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v8i16, { 4, 1, 1, 1 } },
3157 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i32, { 7, 1, 1, 1 } },
3158 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v4i32, { 7, 1, 1, 1 } },
3159 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i32, { 5, 1, 1, 1 } },
3160 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i64, {15, 1, 1, 1 } },
3161 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v2i64, {18, 1, 1, 1 } },
3162
3163 { ISD::FP_TO_SINT, MVT::i32, MVT::f32, { 4, 1, 1, 1 } },
3164 { ISD::FP_TO_SINT, MVT::i64, MVT::f32, { 4, 1, 1, 1 } },
3165 { ISD::FP_TO_SINT, MVT::i32, MVT::f64, { 4, 1, 1, 1 } },
3166 { ISD::FP_TO_SINT, MVT::i64, MVT::f64, { 4, 1, 1, 1 } },
3167 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v4f32, { 6, 1, 1, 1 } },
3168 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v2f64, { 6, 1, 1, 1 } },
3169 { ISD::FP_TO_SINT, MVT::v8i16, MVT::v4f32, { 5, 1, 1, 1 } },
3170 { ISD::FP_TO_SINT, MVT::v8i16, MVT::v2f64, { 5, 1, 1, 1 } },
3171 { ISD::FP_TO_SINT, MVT::v4i32, MVT::v4f32, { 4, 1, 1, 1 } },
3172 { ISD::FP_TO_SINT, MVT::v4i32, MVT::v2f64, { 4, 1, 1, 1 } },
3173
3174 { ISD::FP_TO_UINT, MVT::i32, MVT::f32, { 4, 1, 1, 1 } },
3175 { ISD::FP_TO_UINT, MVT::i64, MVT::f32, { 4, 1, 1, 1 } },
3176 { ISD::FP_TO_UINT, MVT::i32, MVT::f64, { 4, 1, 1, 1 } },
3177 { ISD::FP_TO_UINT, MVT::i64, MVT::f64, {15, 1, 1, 1 } },
3178 { ISD::FP_TO_UINT, MVT::v16i8, MVT::v4f32, { 6, 1, 1, 1 } },
3179 { ISD::FP_TO_UINT, MVT::v16i8, MVT::v2f64, { 6, 1, 1, 1 } },
3180 { ISD::FP_TO_UINT, MVT::v8i16, MVT::v4f32, { 5, 1, 1, 1 } },
3181 { ISD::FP_TO_UINT, MVT::v8i16, MVT::v2f64, { 5, 1, 1, 1 } },
3182 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f32, { 8, 1, 1, 1 } },
3183 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v2f64, { 8, 1, 1, 1 } },
3184
3185 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v16i8, { 4, 1, 1, 1 } },
3186 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v16i8, { 4, 1, 1, 1 } },
3187 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v16i8, { 2, 1, 1, 1 } },
3188 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v16i8, { 3, 1, 1, 1 } },
3189 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v16i8, { 1, 1, 1, 1 } },
3190 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v16i8, { 2, 1, 1, 1 } },
3191 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v8i16, { 2, 1, 1, 1 } },
3192 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v8i16, { 3, 1, 1, 1 } },
3193 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v8i16, { 1, 1, 1, 1 } },
3194 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v8i16, { 2, 1, 1, 1 } },
3195 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v4i32, { 1, 1, 1, 1 } },
3196 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v4i32, { 2, 1, 1, 1 } },
3197
3198 // These truncates are really widening elements.
3199 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i32, { 1, 1, 1, 1 } }, // PSHUFD
3200 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i16, { 2, 1, 1, 1 } }, // PUNPCKLWD+DQ
3201 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i8, { 3, 1, 1, 1 } }, // PUNPCKLBW+WD+PSHUFD
3202 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i16, { 1, 1, 1, 1 } }, // PUNPCKLWD
3203 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i8, { 2, 1, 1, 1 } }, // PUNPCKLBW+WD
3204 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i8, { 1, 1, 1, 1 } }, // PUNPCKLBW
3205
3206 { ISD::TRUNCATE, MVT::v16i8, MVT::v8i16, { 2, 1, 1, 1 } }, // PAND+PACKUSWB
3207 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i16, { 3, 1, 1, 1 } },
3208 { ISD::TRUNCATE, MVT::v16i8, MVT::v4i32, { 3, 1, 1, 1 } }, // PAND+2*PACKUSWB
3209 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i32, { 7, 1, 1, 1 } },
3210 { ISD::TRUNCATE, MVT::v2i16, MVT::v2i32, { 1, 1, 1, 1 } },
3211 { ISD::TRUNCATE, MVT::v8i16, MVT::v4i32, { 3, 1, 1, 1 } },
3212 { ISD::TRUNCATE, MVT::v8i16, MVT::v8i32, { 5, 1, 1, 1 } },
3213 { ISD::TRUNCATE, MVT::v16i16, MVT::v16i32, {10, 1, 1, 1 } },
3214 { ISD::TRUNCATE, MVT::v16i8, MVT::v2i64, { 4, 1, 1, 1 } }, // PAND+3*PACKUSWB
3215 { ISD::TRUNCATE, MVT::v8i16, MVT::v2i64, { 2, 1, 1, 1 } }, // PSHUFD+PSHUFLW
3216 { ISD::TRUNCATE, MVT::v4i32, MVT::v2i64, { 1, 1, 1, 1 } }, // PSHUFD
3217 };
3218
3219 static const TypeConversionCostKindTblEntry F16ConversionTbl[] = {
3220 { ISD::FP_ROUND, MVT::f16, MVT::f32, { 1, 1, 1, 1 } },
3221 { ISD::FP_ROUND, MVT::v8f16, MVT::v8f32, { 1, 1, 1, 1 } },
3222 { ISD::FP_ROUND, MVT::v4f16, MVT::v4f32, { 1, 1, 1, 1 } },
3223 { ISD::FP_EXTEND, MVT::f32, MVT::f16, { 1, 1, 1, 1 } },
3224 { ISD::FP_EXTEND, MVT::f64, MVT::f16, { 2, 1, 1, 1 } }, // vcvtph2ps+vcvtps2pd
3225 { ISD::FP_EXTEND, MVT::v8f32, MVT::v8f16, { 1, 1, 1, 1 } },
3226 { ISD::FP_EXTEND, MVT::v4f32, MVT::v4f16, { 1, 1, 1, 1 } },
3227 { ISD::FP_EXTEND, MVT::v4f64, MVT::v4f16, { 2, 1, 1, 1 } }, // vcvtph2ps+vcvtps2pd
3228 };
3229
3230 // Attempt to map directly to (simple) MVT types to let us match custom entries.
3231 EVT SrcTy = TLI->getValueType(DL, Src);
3232 EVT DstTy = TLI->getValueType(DL, Dst);
3233
3234 // If we're sign-extending a vector comparison result back to the comparison
3235 // width, this will be free without AVX512 (or for 8/16-bit types without
3236 // BWI).
3237 if (!ST->hasAVX512() || (!ST->hasBWI() && DstTy.getScalarSizeInBits() < 32)) {
3238 if (I && Opcode == Instruction::CastOps::SExt &&
3239 SrcTy.isFixedLengthVectorOf(MVT::i1)) {
3240 if (auto *CmpI = dyn_cast<CmpInst>(I->getOperand(0))) {
3241 Type *CmpTy = CmpI->getOperand(0)->getType();
3242 if (CmpTy->getScalarSizeInBits() == DstTy.getScalarSizeInBits())
3243 return TTI::TCC_Free;
3244 }
3245 }
3246 }
3247
3248 // The function getSimpleVT only handles simple value types.
3249 if (SrcTy.isSimple() && DstTy.isSimple()) {
3250 MVT SimpleSrcTy = SrcTy.getSimpleVT();
3251 MVT SimpleDstTy = DstTy.getSimpleVT();
3252
3253 if (ST->useAVX512Regs()) {
3254 if (ST->hasBWI())
3255 if (const auto *Entry = ConvertCostTableLookup(
3256 AVX512BWConversionTbl, ISD, SimpleDstTy, SimpleSrcTy))
3257 if (auto KindCost = Entry->Cost[CostKind])
3258 return *KindCost;
3259
3260 if (ST->hasDQI())
3261 if (const auto *Entry = ConvertCostTableLookup(
3262 AVX512DQConversionTbl, ISD, SimpleDstTy, SimpleSrcTy))
3263 if (auto KindCost = Entry->Cost[CostKind])
3264 return *KindCost;
3265
3266 if (ST->hasAVX512())
3267 if (const auto *Entry = ConvertCostTableLookup(
3268 AVX512FConversionTbl, ISD, SimpleDstTy, SimpleSrcTy))
3269 if (auto KindCost = Entry->Cost[CostKind])
3270 return *KindCost;
3271 }
3272
3273 if (ST->hasBWI())
3274 if (const auto *Entry = ConvertCostTableLookup(
3275 AVX512BWVLConversionTbl, ISD, SimpleDstTy, SimpleSrcTy))
3276 if (auto KindCost = Entry->Cost[CostKind])
3277 return *KindCost;
3278
3279 if (ST->hasDQI())
3280 if (const auto *Entry = ConvertCostTableLookup(
3281 AVX512DQVLConversionTbl, ISD, SimpleDstTy, SimpleSrcTy))
3282 if (auto KindCost = Entry->Cost[CostKind])
3283 return *KindCost;
3284
3285 if (ST->hasAVX512())
3286 if (const auto *Entry = ConvertCostTableLookup(AVX512VLConversionTbl, ISD,
3287 SimpleDstTy, SimpleSrcTy))
3288 if (auto KindCost = Entry->Cost[CostKind])
3289 return *KindCost;
3290
3291 if (ST->hasAVX2()) {
3292 if (const auto *Entry = ConvertCostTableLookup(AVX2ConversionTbl, ISD,
3293 SimpleDstTy, SimpleSrcTy))
3294 if (auto KindCost = Entry->Cost[CostKind])
3295 return *KindCost;
3296 }
3297
3298 if (ST->hasAVX()) {
3299 if (const auto *Entry = ConvertCostTableLookup(AVXConversionTbl, ISD,
3300 SimpleDstTy, SimpleSrcTy))
3301 if (auto KindCost = Entry->Cost[CostKind])
3302 return *KindCost;
3303 }
3304
3305 if (ST->hasF16C()) {
3306 if (const auto *Entry = ConvertCostTableLookup(F16ConversionTbl, ISD,
3307 SimpleDstTy, SimpleSrcTy))
3308 if (auto KindCost = Entry->Cost[CostKind])
3309 return *KindCost;
3310 }
3311
3312 if (ST->hasSSE41()) {
3313 if (const auto *Entry = ConvertCostTableLookup(SSE41ConversionTbl, ISD,
3314 SimpleDstTy, SimpleSrcTy))
3315 if (auto KindCost = Entry->Cost[CostKind])
3316 return *KindCost;
3317 }
3318
3319 if (ST->hasSSE2()) {
3320 if (const auto *Entry = ConvertCostTableLookup(SSE2ConversionTbl, ISD,
3321 SimpleDstTy, SimpleSrcTy))
3322 if (auto KindCost = Entry->Cost[CostKind])
3323 return *KindCost;
3324 }
3325
3326 if ((ISD == ISD::FP_ROUND && SimpleDstTy == MVT::f16) ||
3327 (ISD == ISD::FP_EXTEND && SimpleSrcTy == MVT::f16)) {
3328 // fp16 conversions not covered by any table entries require a libcall.
3329 // Return a large (arbitrary) number to model this.
3330 return InstructionCost(64);
3331 }
3332 }
3333
3334 // Fall back to legalized types.
3335 std::pair<InstructionCost, MVT> LTSrc = getTypeLegalizationCost(Src);
3336 std::pair<InstructionCost, MVT> LTDest = getTypeLegalizationCost(Dst);
3337
3338 // If we're truncating to the same legalized type - just assume its free.
3339 if (ISD == ISD::TRUNCATE && LTSrc.second == LTDest.second)
3340 return TTI::TCC_Free;
3341
3342 if (ST->useAVX512Regs()) {
3343 if (ST->hasBWI())
3344 if (const auto *Entry = ConvertCostTableLookup(
3345 AVX512BWConversionTbl, ISD, LTDest.second, LTSrc.second))
3346 if (auto KindCost = Entry->Cost[CostKind])
3347 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3348
3349 if (ST->hasDQI())
3350 if (const auto *Entry = ConvertCostTableLookup(
3351 AVX512DQConversionTbl, ISD, LTDest.second, LTSrc.second))
3352 if (auto KindCost = Entry->Cost[CostKind])
3353 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3354
3355 if (ST->hasAVX512())
3356 if (const auto *Entry = ConvertCostTableLookup(
3357 AVX512FConversionTbl, ISD, LTDest.second, LTSrc.second))
3358 if (auto KindCost = Entry->Cost[CostKind])
3359 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3360 }
3361
3362 if (ST->hasBWI())
3363 if (const auto *Entry = ConvertCostTableLookup(AVX512BWVLConversionTbl, ISD,
3364 LTDest.second, LTSrc.second))
3365 if (auto KindCost = Entry->Cost[CostKind])
3366 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3367
3368 if (ST->hasDQI())
3369 if (const auto *Entry = ConvertCostTableLookup(AVX512DQVLConversionTbl, ISD,
3370 LTDest.second, LTSrc.second))
3371 if (auto KindCost = Entry->Cost[CostKind])
3372 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3373
3374 if (ST->hasAVX512())
3375 if (const auto *Entry = ConvertCostTableLookup(AVX512VLConversionTbl, ISD,
3376 LTDest.second, LTSrc.second))
3377 if (auto KindCost = Entry->Cost[CostKind])
3378 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3379
3380 if (ST->hasAVX2())
3381 if (const auto *Entry = ConvertCostTableLookup(AVX2ConversionTbl, ISD,
3382 LTDest.second, LTSrc.second))
3383 if (auto KindCost = Entry->Cost[CostKind])
3384 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3385
3386 if (ST->hasAVX())
3387 if (const auto *Entry = ConvertCostTableLookup(AVXConversionTbl, ISD,
3388 LTDest.second, LTSrc.second))
3389 if (auto KindCost = Entry->Cost[CostKind])
3390 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3391
3392 if (ST->hasF16C()) {
3393 if (const auto *Entry = ConvertCostTableLookup(F16ConversionTbl, ISD,
3394 LTDest.second, LTSrc.second))
3395 if (auto KindCost = Entry->Cost[CostKind])
3396 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3397 }
3398
3399 if (ST->hasSSE41())
3400 if (const auto *Entry = ConvertCostTableLookup(SSE41ConversionTbl, ISD,
3401 LTDest.second, LTSrc.second))
3402 if (auto KindCost = Entry->Cost[CostKind])
3403 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3404
3405 if (ST->hasSSE2())
3406 if (const auto *Entry = ConvertCostTableLookup(SSE2ConversionTbl, ISD,
3407 LTDest.second, LTSrc.second))
3408 if (auto KindCost = Entry->Cost[CostKind])
3409 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3410
3411 // Fallback, for i8/i16 sitofp/uitofp cases we need to extend to i32 for
3412 // sitofp.
3413 if ((ISD == ISD::SINT_TO_FP || ISD == ISD::UINT_TO_FP) &&
3414 1 < Src->getScalarSizeInBits() && Src->getScalarSizeInBits() < 32) {
3415 Type *ExtSrc = Src->getWithNewBitWidth(32);
3416 unsigned ExtOpc =
3417 (ISD == ISD::SINT_TO_FP) ? Instruction::SExt : Instruction::ZExt;
3418
3419 // For scalar loads the extend would be free.
3420 InstructionCost ExtCost = 0;
3421 if (!(Src->isIntegerTy() && I && isa<LoadInst>(I->getOperand(0))))
3422 ExtCost = getCastInstrCost(ExtOpc, ExtSrc, Src, CCH, CostKind);
3423
3424 return ExtCost + getCastInstrCost(Instruction::SIToFP, Dst, ExtSrc,
3426 }
3427
3428 // Fallback for fptosi/fptoui i8/i16 cases we need to truncate from fptosi
3429 // i32.
3430 if ((ISD == ISD::FP_TO_SINT || ISD == ISD::FP_TO_UINT) &&
3431 1 < Dst->getScalarSizeInBits() && Dst->getScalarSizeInBits() < 32) {
3432 Type *TruncDst = Dst->getWithNewBitWidth(32);
3433 return getCastInstrCost(Instruction::FPToSI, TruncDst, Src, CCH, CostKind) +
3434 getCastInstrCost(Instruction::Trunc, Dst, TruncDst,
3436 }
3437
3438 // TODO: Allow non-throughput costs that aren't binary.
3439 auto AdjustCost = [&CostKind](InstructionCost Cost,
3442 return Cost == 0 ? 0 : N;
3443 return Cost * N;
3444 };
3445 return AdjustCost(
3446 BaseT::getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I));
3447}
3448
3450 unsigned Opcode, Type *ValTy, Type *CondTy, CmpInst::Predicate VecPred,
3452 TTI::OperandValueInfo Op2Info, const Instruction *I) const {
3453 // Early out if this type isn't scalar/vector integer/float.
3454 if (!(ValTy->isIntOrIntVectorTy() || ValTy->isFPOrFPVectorTy()))
3455 return BaseT::getCmpSelInstrCost(Opcode, ValTy, CondTy, VecPred, CostKind,
3456 Op1Info, Op2Info, I);
3457
3458 // Legalize the type.
3459 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(ValTy);
3460
3461 MVT MTy = LT.second;
3462
3463 int ISD = TLI->InstructionOpcodeToISD(Opcode);
3464 assert(ISD && "Invalid opcode");
3465
3466 InstructionCost ExtraCost = 0;
3467 if (Opcode == Instruction::ICmp || Opcode == Instruction::FCmp) {
3468 // Some vector comparison predicates cost extra instructions.
3469 // TODO: Adjust ExtraCost based on CostKind?
3470 // TODO: Should we invert this and assume worst case cmp costs
3471 // and reduce for particular predicates?
3472 if (MTy.isVector() &&
3473 !((ST->hasXOP() && (!ST->hasAVX2() || MTy.is128BitVector())) ||
3474 (ST->hasAVX512() && 32 <= MTy.getScalarSizeInBits()) ||
3475 ST->hasBWI())) {
3476 // Fallback to I if a specific predicate wasn't specified.
3477 CmpInst::Predicate Pred = VecPred;
3478 if (I && (Pred == CmpInst::BAD_ICMP_PREDICATE ||
3480 Pred = cast<CmpInst>(I)->getPredicate();
3481
3482 bool CmpWithConstant = false;
3483 if (auto *CmpInstr = dyn_cast_or_null<CmpInst>(I))
3484 CmpWithConstant = isa<Constant>(CmpInstr->getOperand(1));
3485
3486 switch (Pred) {
3488 // xor(cmpeq(x,y),-1)
3489 ExtraCost = CmpWithConstant ? 0 : 1;
3490 break;
3493 // xor(cmpgt(x,y),-1)
3494 ExtraCost = CmpWithConstant ? 0 : 1;
3495 break;
3498 // cmpgt(xor(x,signbit),xor(y,signbit))
3499 // xor(cmpeq(pmaxu(x,y),x),-1)
3500 ExtraCost = CmpWithConstant ? 1 : 2;
3501 break;
3504 if ((ST->hasSSE41() && MTy.getScalarSizeInBits() == 32) ||
3505 (ST->hasSSE2() && MTy.getScalarSizeInBits() < 32)) {
3506 // cmpeq(psubus(x,y),0)
3507 // cmpeq(pminu(x,y),x)
3508 ExtraCost = 1;
3509 } else {
3510 // xor(cmpgt(xor(x,signbit),xor(y,signbit)),-1)
3511 ExtraCost = CmpWithConstant ? 2 : 3;
3512 }
3513 break;
3516 // Without AVX we need to expand FCMP_ONE/FCMP_UEQ cases.
3517 // Use FCMP_UEQ expansion - FCMP_ONE should be the same.
3518 if (CondTy && !ST->hasAVX())
3519 return getCmpSelInstrCost(Opcode, ValTy, CondTy,
3521 Op1Info, Op2Info) +
3522 getCmpSelInstrCost(Opcode, ValTy, CondTy,
3524 Op1Info, Op2Info) +
3525 getArithmeticInstrCost(Instruction::Or, CondTy, CostKind);
3526
3527 break;
3530 // Assume worst case scenario and add the maximum extra cost.
3531 ExtraCost = 3;
3532 break;
3533 default:
3534 break;
3535 }
3536 }
3537 }
3538
3539 static const CostKindTblEntry SLMCostTbl[] = {
3540 // slm pcmpeq/pcmpgt throughput is 2
3541 { ISD::SETCC, MVT::v2i64, { 2, 5, 1, 2 } },
3542 // slm pblendvb/blendvpd/blendvps throughput is 4
3543 { ISD::SELECT, MVT::v2f64, { 4, 4, 1, 3 } }, // vblendvpd
3544 { ISD::SELECT, MVT::v4f32, { 4, 4, 1, 3 } }, // vblendvps
3545 { ISD::SELECT, MVT::v2i64, { 4, 4, 1, 3 } }, // pblendvb
3546 { ISD::SELECT, MVT::v8i32, { 4, 4, 1, 3 } }, // pblendvb
3547 { ISD::SELECT, MVT::v8i16, { 4, 4, 1, 3 } }, // pblendvb
3548 { ISD::SELECT, MVT::v16i8, { 4, 4, 1, 3 } }, // pblendvb
3549 };
3550
3551 static const CostKindTblEntry AVX512BWCostTbl[] = {
3552 { ISD::SETCC, MVT::v32i16, { 1, 1, 1, 1 } },
3553 { ISD::SETCC, MVT::v16i16, { 1, 1, 1, 1 } },
3554 { ISD::SETCC, MVT::v64i8, { 1, 1, 1, 1 } },
3555 { ISD::SETCC, MVT::v32i8, { 1, 1, 1, 1 } },
3556
3557 { ISD::SELECT, MVT::v32i16, { 1, 1, 1, 1 } },
3558 { ISD::SELECT, MVT::v64i8, { 1, 1, 1, 1 } },
3559 };
3560
3561 static const CostKindTblEntry AVX512CostTbl[] = {
3562 { ISD::SETCC, MVT::v8f64, { 1, 4, 1, 1 } },
3563 { ISD::SETCC, MVT::v4f64, { 1, 4, 1, 1 } },
3564 { ISD::SETCC, MVT::v16f32, { 1, 4, 1, 1 } },
3565 { ISD::SETCC, MVT::v8f32, { 1, 4, 1, 1 } },
3566
3567 { ISD::SETCC, MVT::v8i64, { 1, 1, 1, 1 } },
3568 { ISD::SETCC, MVT::v4i64, { 1, 1, 1, 1 } },
3569 { ISD::SETCC, MVT::v2i64, { 1, 1, 1, 1 } },
3570 { ISD::SETCC, MVT::v16i32, { 1, 1, 1, 1 } },
3571 { ISD::SETCC, MVT::v8i32, { 1, 1, 1, 1 } },
3572 { ISD::SETCC, MVT::v32i16, { 3, 7, 5, 5 } },
3573 { ISD::SETCC, MVT::v64i8, { 3, 7, 5, 5 } },
3574
3575 { ISD::SELECT, MVT::v8i64, { 1, 1, 1, 1 } },
3576 { ISD::SELECT, MVT::v4i64, { 1, 1, 1, 1 } },
3577 { ISD::SELECT, MVT::v2i64, { 1, 1, 1, 1 } },
3578 { ISD::SELECT, MVT::v16i32, { 1, 1, 1, 1 } },
3579 { ISD::SELECT, MVT::v8i32, { 1, 1, 1, 1 } },
3580 { ISD::SELECT, MVT::v4i32, { 1, 1, 1, 1 } },
3581 { ISD::SELECT, MVT::v8f64, { 1, 1, 1, 1 } },
3582 { ISD::SELECT, MVT::v4f64, { 1, 1, 1, 1 } },
3583 { ISD::SELECT, MVT::v2f64, { 1, 1, 1, 1 } },
3584 { ISD::SELECT, MVT::f64, { 1, 1, 1, 1 } },
3585 { ISD::SELECT, MVT::v16f32, { 1, 1, 1, 1 } },
3586 { ISD::SELECT, MVT::v8f32 , { 1, 1, 1, 1 } },
3587 { ISD::SELECT, MVT::v4f32, { 1, 1, 1, 1 } },
3588 { ISD::SELECT, MVT::f32 , { 1, 1, 1, 1 } },
3589
3590 { ISD::SELECT, MVT::v32i16, { 2, 2, 4, 4 } },
3591 { ISD::SELECT, MVT::v16i16, { 1, 1, 1, 1 } },
3592 { ISD::SELECT, MVT::v8i16, { 1, 1, 1, 1 } },
3593 { ISD::SELECT, MVT::v64i8, { 2, 2, 4, 4 } },
3594 { ISD::SELECT, MVT::v32i8, { 1, 1, 1, 1 } },
3595 { ISD::SELECT, MVT::v16i8, { 1, 1, 1, 1 } },
3596 };
3597
3598 static const CostKindTblEntry AVX2CostTbl[] = {
3599 { ISD::SETCC, MVT::v4f64, { 1, 4, 1, 2 } },
3600 { ISD::SETCC, MVT::v2f64, { 1, 4, 1, 1 } },
3601 { ISD::SETCC, MVT::f64, { 1, 4, 1, 1 } },
3602 { ISD::SETCC, MVT::v8f32, { 1, 4, 1, 2 } },
3603 { ISD::SETCC, MVT::v4f32, { 1, 4, 1, 1 } },
3604 { ISD::SETCC, MVT::f32, { 1, 4, 1, 1 } },
3605
3606 { ISD::SETCC, MVT::v4i64, { 1, 1, 1, 2 } },
3607 { ISD::SETCC, MVT::v8i32, { 1, 1, 1, 2 } },
3608 { ISD::SETCC, MVT::v16i16, { 1, 1, 1, 2 } },
3609 { ISD::SETCC, MVT::v32i8, { 1, 1, 1, 2 } },
3610
3611 { ISD::SELECT, MVT::v4f64, { 2, 2, 1, 2 } }, // vblendvpd
3612 { ISD::SELECT, MVT::v8f32, { 2, 2, 1, 2 } }, // vblendvps
3613 { ISD::SELECT, MVT::v4i64, { 2, 2, 1, 2 } }, // pblendvb
3614 { ISD::SELECT, MVT::v8i32, { 2, 2, 1, 2 } }, // pblendvb
3615 { ISD::SELECT, MVT::v16i16, { 2, 2, 1, 2 } }, // pblendvb
3616 { ISD::SELECT, MVT::v32i8, { 2, 2, 1, 2 } }, // pblendvb
3617 };
3618
3619 static const CostKindTblEntry XOPCostTbl[] = {
3620 { ISD::SETCC, MVT::v4i64, { 4, 2, 5, 6 } },
3621 { ISD::SETCC, MVT::v2i64, { 1, 1, 1, 1 } },
3622 };
3623
3624 static const CostKindTblEntry AVX1CostTbl[] = {
3625 { ISD::SETCC, MVT::v4f64, { 2, 3, 1, 2 } },
3626 { ISD::SETCC, MVT::v2f64, { 1, 3, 1, 1 } },
3627 { ISD::SETCC, MVT::f64, { 1, 3, 1, 1 } },
3628 { ISD::SETCC, MVT::v8f32, { 2, 3, 1, 2 } },
3629 { ISD::SETCC, MVT::v4f32, { 1, 3, 1, 1 } },
3630 { ISD::SETCC, MVT::f32, { 1, 3, 1, 1 } },
3631
3632 // AVX1 does not support 8-wide integer compare.
3633 { ISD::SETCC, MVT::v4i64, { 4, 2, 5, 6 } },
3634 { ISD::SETCC, MVT::v8i32, { 4, 2, 5, 6 } },
3635 { ISD::SETCC, MVT::v16i16, { 4, 2, 5, 6 } },
3636 { ISD::SETCC, MVT::v32i8, { 4, 2, 5, 6 } },
3637
3638 { ISD::SELECT, MVT::v4f64, { 3, 3, 1, 2 } }, // vblendvpd
3639 { ISD::SELECT, MVT::v8f32, { 3, 3, 1, 2 } }, // vblendvps
3640 { ISD::SELECT, MVT::v4i64, { 3, 3, 1, 2 } }, // vblendvpd
3641 { ISD::SELECT, MVT::v8i32, { 3, 3, 1, 2 } }, // vblendvps
3642 { ISD::SELECT, MVT::v16i16, { 3, 3, 3, 3 } }, // vandps + vandnps + vorps
3643 { ISD::SELECT, MVT::v32i8, { 3, 3, 3, 3 } }, // vandps + vandnps + vorps
3644 };
3645
3646 static const CostKindTblEntry SSE42CostTbl[] = {
3647 { ISD::SETCC, MVT::v2i64, { 1, 2, 1, 2 } },
3648 };
3649
3650 static const CostKindTblEntry SSE41CostTbl[] = {
3651 { ISD::SETCC, MVT::v2f64, { 1, 5, 1, 1 } },
3652 { ISD::SETCC, MVT::v4f32, { 1, 5, 1, 1 } },
3653
3654 { ISD::SELECT, MVT::v2f64, { 2, 2, 1, 2 } }, // blendvpd
3655 { ISD::SELECT, MVT::f64, { 2, 2, 1, 2 } }, // blendvpd
3656 { ISD::SELECT, MVT::v4f32, { 2, 2, 1, 2 } }, // blendvps
3657 { ISD::SELECT, MVT::f32 , { 2, 2, 1, 2 } }, // blendvps
3658 { ISD::SELECT, MVT::v2i64, { 2, 2, 1, 2 } }, // pblendvb
3659 { ISD::SELECT, MVT::v4i32, { 2, 2, 1, 2 } }, // pblendvb
3660 { ISD::SELECT, MVT::v8i16, { 2, 2, 1, 2 } }, // pblendvb
3661 { ISD::SELECT, MVT::v16i8, { 2, 2, 1, 2 } }, // pblendvb
3662 };
3663
3664 static const CostKindTblEntry SSE2CostTbl[] = {
3665 { ISD::SETCC, MVT::v2f64, { 2, 5, 1, 1 } },
3666 { ISD::SETCC, MVT::f64, { 1, 5, 1, 1 } },
3667
3668 { ISD::SETCC, MVT::v2i64, { 5, 4, 5, 5 } }, // pcmpeqd/pcmpgtd expansion
3669 { ISD::SETCC, MVT::v4i32, { 1, 1, 1, 1 } },
3670 { ISD::SETCC, MVT::v8i16, { 1, 1, 1, 1 } },
3671 { ISD::SETCC, MVT::v16i8, { 1, 1, 1, 1 } },
3672
3673 { ISD::SELECT, MVT::v2f64, { 2, 2, 3, 3 } }, // andpd + andnpd + orpd
3674 { ISD::SELECT, MVT::f64, { 2, 2, 3, 3 } }, // andpd + andnpd + orpd
3675 { ISD::SELECT, MVT::v2i64, { 2, 2, 3, 3 } }, // pand + pandn + por
3676 { ISD::SELECT, MVT::v4i32, { 2, 2, 3, 3 } }, // pand + pandn + por
3677 { ISD::SELECT, MVT::v8i16, { 2, 2, 3, 3 } }, // pand + pandn + por
3678 { ISD::SELECT, MVT::v16i8, { 2, 2, 3, 3 } }, // pand + pandn + por
3679 };
3680
3681 static const CostKindTblEntry SSE1CostTbl[] = {
3682 { ISD::SETCC, MVT::v4f32, { 2, 5, 1, 1 } },
3683 { ISD::SETCC, MVT::f32, { 1, 5, 1, 1 } },
3684
3685 { ISD::SELECT, MVT::v4f32, { 2, 2, 3, 3 } }, // andps + andnps + orps
3686 { ISD::SELECT, MVT::f32, { 2, 2, 3, 3 } }, // andps + andnps + orps
3687 };
3688
3689 if (ST->useSLMArithCosts())
3690 if (const auto *Entry = CostTableLookup(SLMCostTbl, ISD, MTy))
3691 if (auto KindCost = Entry->Cost[CostKind])
3692 return LT.first * (ExtraCost + *KindCost);
3693
3694 if (ST->hasBWI())
3695 if (const auto *Entry = CostTableLookup(AVX512BWCostTbl, ISD, MTy))
3696 if (auto KindCost = Entry->Cost[CostKind])
3697 return LT.first * (ExtraCost + *KindCost);
3698
3699 if (ST->hasAVX512())
3700 if (const auto *Entry = CostTableLookup(AVX512CostTbl, ISD, MTy))
3701 if (auto KindCost = Entry->Cost[CostKind])
3702 return LT.first * (ExtraCost + *KindCost);
3703
3704 if (ST->hasAVX2())
3705 if (const auto *Entry = CostTableLookup(AVX2CostTbl, ISD, MTy))
3706 if (auto KindCost = Entry->Cost[CostKind])
3707 return LT.first * (ExtraCost + *KindCost);
3708
3709 if (ST->hasXOP())
3710 if (const auto *Entry = CostTableLookup(XOPCostTbl, ISD, MTy))
3711 if (auto KindCost = Entry->Cost[CostKind])
3712 return LT.first * (ExtraCost + *KindCost);
3713
3714 if (ST->hasAVX())
3715 if (const auto *Entry = CostTableLookup(AVX1CostTbl, ISD, MTy))
3716 if (auto KindCost = Entry->Cost[CostKind])
3717 return LT.first * (ExtraCost + *KindCost);
3718
3719 if (ST->hasSSE42())
3720 if (const auto *Entry = CostTableLookup(SSE42CostTbl, ISD, MTy))
3721 if (auto KindCost = Entry->Cost[CostKind])
3722 return LT.first * (ExtraCost + *KindCost);
3723
3724 if (ST->hasSSE41())
3725 if (const auto *Entry = CostTableLookup(SSE41CostTbl, ISD, MTy))
3726 if (auto KindCost = Entry->Cost[CostKind])
3727 return LT.first * (ExtraCost + *KindCost);
3728
3729 if (ST->hasSSE2())
3730 if (const auto *Entry = CostTableLookup(SSE2CostTbl, ISD, MTy))
3731 if (auto KindCost = Entry->Cost[CostKind])
3732 return LT.first * (ExtraCost + *KindCost);
3733
3734 if (ST->hasSSE1())
3735 if (const auto *Entry = CostTableLookup(SSE1CostTbl, ISD, MTy))
3736 if (auto KindCost = Entry->Cost[CostKind])
3737 return LT.first * (ExtraCost + *KindCost);
3738
3739 // Assume a 3cy latency for fp select ops.
3740 if (CostKind == TTI::TCK_Latency && Opcode == Instruction::Select)
3741 if (ValTy->getScalarType()->isFloatingPointTy())
3742 return 3;
3743
3744 return BaseT::getCmpSelInstrCost(Opcode, ValTy, CondTy, VecPred, CostKind,
3745 Op1Info, Op2Info, I);
3746}
3747
3749
3753 // Costs should match the codegen from:
3754 // BITREVERSE: llvm\test\CodeGen\X86\vector-bitreverse.ll
3755 // BSWAP: llvm\test\CodeGen\X86\bswap-vector.ll
3756 // CTLZ: llvm\test\CodeGen\X86\vector-lzcnt-*.ll
3757 // CTPOP: llvm\test\CodeGen\X86\vector-popcnt-*.ll
3758 // CTTZ: llvm\test\CodeGen\X86\vector-tzcnt-*.ll
3759
3760 // TODO: Overflow intrinsics (*ADDO, *SUBO, *MULO) with vector types are not
3761 // specialized in these tables yet.
3762 static const CostKindTblEntry AVX512VBMI2CostTbl[] = {
3763 { ISD::FSHL, MVT::v8i64, { 1, 1, 1, 1 } },
3764 { ISD::FSHL, MVT::v4i64, { 1, 1, 1, 1 } },
3765 { ISD::FSHL, MVT::v2i64, { 1, 1, 1, 1 } },
3766 { ISD::FSHL, MVT::v16i32, { 1, 1, 1, 1 } },
3767 { ISD::FSHL, MVT::v8i32, { 1, 1, 1, 1 } },
3768 { ISD::FSHL, MVT::v4i32, { 1, 1, 1, 1 } },
3769 { ISD::FSHL, MVT::v32i16, { 1, 1, 1, 1 } },
3770 { ISD::FSHL, MVT::v16i16, { 1, 1, 1, 1 } },
3771 { ISD::FSHL, MVT::v8i16, { 1, 1, 1, 1 } },
3772 { ISD::ROTL, MVT::v32i16, { 1, 1, 1, 1 } },
3773 { ISD::ROTL, MVT::v16i16, { 1, 1, 1, 1 } },
3774 { ISD::ROTL, MVT::v8i16, { 1, 1, 1, 1 } },
3775 { ISD::ROTR, MVT::v32i16, { 1, 1, 1, 1 } },
3776 { ISD::ROTR, MVT::v16i16, { 1, 1, 1, 1 } },
3777 { ISD::ROTR, MVT::v8i16, { 1, 1, 1, 1 } },
3778 { X86ISD::VROTLI, MVT::v32i16, { 1, 1, 1, 1 } },
3779 { X86ISD::VROTLI, MVT::v16i16, { 1, 1, 1, 1 } },
3780 { X86ISD::VROTLI, MVT::v8i16, { 1, 1, 1, 1 } },
3781 };
3782 static const CostKindTblEntry AVX512BITALGCostTbl[] = {
3783 { ISD::CTPOP, MVT::v32i16, { 1, 1, 1, 1 } },
3784 { ISD::CTPOP, MVT::v64i8, { 1, 1, 1, 1 } },
3785 { ISD::CTPOP, MVT::v16i16, { 1, 1, 1, 1 } },
3786 { ISD::CTPOP, MVT::v32i8, { 1, 1, 1, 1 } },
3787 { ISD::CTPOP, MVT::v8i16, { 1, 1, 1, 1 } },
3788 { ISD::CTPOP, MVT::v16i8, { 1, 1, 1, 1 } },
3789 };
3790 static const CostKindTblEntry AVX512VPOPCNTDQCostTbl[] = {
3791 { ISD::CTPOP, MVT::v8i64, { 1, 1, 1, 1 } },
3792 { ISD::CTPOP, MVT::v16i32, { 1, 1, 1, 1 } },
3793 { ISD::CTPOP, MVT::v4i64, { 1, 1, 1, 1 } },
3794 { ISD::CTPOP, MVT::v8i32, { 1, 1, 1, 1 } },
3795 { ISD::CTPOP, MVT::v2i64, { 1, 1, 1, 1 } },
3796 { ISD::CTPOP, MVT::v4i32, { 1, 1, 1, 1 } },
3797 };
3798 static const CostKindTblEntry AVX512CDCostTbl[] = {
3799 { ISD::CTLZ, MVT::v8i64, { 1, 5, 1, 1 } },
3800 { ISD::CTLZ, MVT::v16i32, { 1, 5, 1, 1 } },
3801 { ISD::CTLZ, MVT::v32i16, { 18, 27, 23, 27 } },
3802 { ISD::CTLZ, MVT::v64i8, { 3, 16, 9, 11 } },
3803 { ISD::CTLZ, MVT::v4i64, { 1, 5, 1, 1 } },
3804 { ISD::CTLZ, MVT::v8i32, { 1, 5, 1, 1 } },
3805 { ISD::CTLZ, MVT::v16i16, { 8, 19, 11, 13 } },
3806 { ISD::CTLZ, MVT::v32i8, { 2, 11, 9, 10 } },
3807 { ISD::CTLZ, MVT::v2i64, { 1, 5, 1, 1 } },
3808 { ISD::CTLZ, MVT::v4i32, { 1, 5, 1, 1 } },
3809 { ISD::CTLZ, MVT::v8i16, { 3, 15, 4, 6 } },
3810 { ISD::CTLZ, MVT::v16i8, { 2, 10, 9, 10 } },
3811
3812 { ISD::CTTZ, MVT::v8i64, { 2, 8, 6, 7 } },
3813 { ISD::CTTZ, MVT::v16i32, { 2, 8, 6, 7 } },
3814 { ISD::CTTZ, MVT::v4i64, { 1, 8, 6, 6 } },
3815 { ISD::CTTZ, MVT::v8i32, { 1, 8, 6, 6 } },
3816 { ISD::CTTZ, MVT::v2i64, { 1, 8, 6, 6 } },
3817 { ISD::CTTZ, MVT::v4i32, { 1, 8, 6, 6 } },
3818 };
3819 static const CostKindTblEntry AVX512BWCostTbl[] = {
3820 { ISD::ABS, MVT::v32i16, { 1, 1, 1, 1 } },
3821 { ISD::ABS, MVT::v64i8, { 1, 1, 1, 1 } },
3822 { ISD::BITREVERSE, MVT::v2i64, { 3, 10, 10, 11 } },
3823 { ISD::BITREVERSE, MVT::v4i64, { 3, 11, 10, 11 } },
3824 { ISD::BITREVERSE, MVT::v8i64, { 3, 12, 10, 14 } },
3825 { ISD::BITREVERSE, MVT::v4i32, { 3, 10, 10, 11 } },
3826 { ISD::BITREVERSE, MVT::v8i32, { 3, 11, 10, 11 } },
3827 { ISD::BITREVERSE, MVT::v16i32, { 3, 12, 10, 14 } },
3828 { ISD::BITREVERSE, MVT::v8i16, { 3, 10, 10, 11 } },
3829 { ISD::BITREVERSE, MVT::v16i16, { 3, 11, 10, 11 } },
3830 { ISD::BITREVERSE, MVT::v32i16, { 3, 12, 10, 14 } },
3831 { ISD::BITREVERSE, MVT::v16i8, { 2, 5, 9, 9 } },
3832 { ISD::BITREVERSE, MVT::v32i8, { 2, 5, 9, 9 } },
3833 { ISD::BITREVERSE, MVT::v64i8, { 2, 5, 9, 12 } },
3834 { ISD::BSWAP, MVT::v2i64, { 1, 1, 1, 2 } },
3835 { ISD::BSWAP, MVT::v4i64, { 1, 1, 1, 2 } },
3836 { ISD::BSWAP, MVT::v8i64, { 1, 1, 1, 2 } },
3837 { ISD::BSWAP, MVT::v4i32, { 1, 1, 1, 2 } },
3838 { ISD::BSWAP, MVT::v8i32, { 1, 1, 1, 2 } },
3839 { ISD::BSWAP, MVT::v16i32, { 1, 1, 1, 2 } },
3840 { ISD::BSWAP, MVT::v8i16, { 1, 1, 1, 2 } },
3841 { ISD::BSWAP, MVT::v16i16, { 1, 1, 1, 2 } },
3842 { ISD::BSWAP, MVT::v32i16, { 1, 1, 1, 2 } },
3843 { ISD::CTLZ, MVT::v8i64, { 8, 22, 23, 23 } },
3844 { ISD::CTLZ, MVT::v16i32, { 8, 23, 25, 25 } },
3845 { ISD::CTLZ, MVT::v32i16, { 4, 15, 15, 16 } },
3846 { ISD::CTLZ, MVT::v64i8, { 3, 12, 10, 9 } },
3847 { ISD::CTPOP, MVT::v2i64, { 3, 7, 10, 10 } },
3848 { ISD::CTPOP, MVT::v4i64, { 3, 7, 10, 10 } },
3849 { ISD::CTPOP, MVT::v8i64, { 3, 8, 10, 12 } },
3850 { ISD::CTPOP, MVT::v4i32, { 7, 11, 14, 14 } },
3851 { ISD::CTPOP, MVT::v8i32, { 7, 11, 14, 14 } },
3852 { ISD::CTPOP, MVT::v16i32, { 7, 12, 14, 16 } },
3853 { ISD::CTPOP, MVT::v8i16, { 2, 7, 11, 11 } },
3854 { ISD::CTPOP, MVT::v16i16, { 2, 7, 11, 11 } },
3855 { ISD::CTPOP, MVT::v32i16, { 3, 7, 11, 13 } },
3856 { ISD::CTPOP, MVT::v16i8, { 2, 4, 8, 8 } },
3857 { ISD::CTPOP, MVT::v32i8, { 2, 4, 8, 8 } },
3858 { ISD::CTPOP, MVT::v64i8, { 2, 5, 8, 10 } },
3859 { ISD::CTTZ, MVT::v8i16, { 3, 9, 14, 14 } },
3860 { ISD::CTTZ, MVT::v16i16, { 3, 9, 14, 14 } },
3861 { ISD::CTTZ, MVT::v32i16, { 3, 10, 14, 16 } },
3862 { ISD::CTTZ, MVT::v16i8, { 2, 6, 11, 11 } },
3863 { ISD::CTTZ, MVT::v32i8, { 2, 6, 11, 11 } },
3864 { ISD::CTTZ, MVT::v64i8, { 3, 7, 11, 13 } },
3865 { ISD::ROTL, MVT::v32i16, { 2, 8, 6, 8 } },
3866 { ISD::ROTL, MVT::v16i16, { 2, 8, 6, 7 } },
3867 { ISD::ROTL, MVT::v8i16, { 2, 7, 6, 7 } },
3868 { ISD::ROTL, MVT::v64i8, { 5, 6, 11, 12 } },
3869 { ISD::ROTL, MVT::v32i8, { 5, 15, 7, 10 } },
3870 { ISD::ROTL, MVT::v16i8, { 5, 15, 7, 10 } },
3871 { ISD::ROTR, MVT::v32i16, { 2, 8, 6, 8 } },
3872 { ISD::ROTR, MVT::v16i16, { 2, 8, 6, 7 } },
3873 { ISD::ROTR, MVT::v8i16, { 2, 7, 6, 7 } },
3874 { ISD::ROTR, MVT::v64i8, { 5, 6, 12, 14 } },
3875 { ISD::ROTR, MVT::v32i8, { 5, 14, 6, 9 } },
3876 { ISD::ROTR, MVT::v16i8, { 5, 14, 6, 9 } },
3877 { X86ISD::VROTLI, MVT::v32i16, { 2, 5, 3, 3 } },
3878 { X86ISD::VROTLI, MVT::v16i16, { 1, 5, 3, 3 } },
3879 { X86ISD::VROTLI, MVT::v8i16, { 1, 5, 3, 3 } },
3880 { X86ISD::VROTLI, MVT::v64i8, { 2, 9, 3, 4 } },
3881 { X86ISD::VROTLI, MVT::v32i8, { 1, 9, 3, 4 } },
3882 { X86ISD::VROTLI, MVT::v16i8, { 1, 8, 3, 4 } },
3883 { ISD::SADDSAT, MVT::v32i16, { 1, 1, 1, 1 } },
3884 { ISD::SADDSAT, MVT::v64i8, { 1, 1, 1, 1 } },
3885 { ISD::SMAX, MVT::v32i16, { 1, 1, 1, 1 } },
3886 { ISD::SMAX, MVT::v64i8, { 1, 1, 1, 1 } },
3887 { ISD::SMIN, MVT::v32i16, { 1, 1, 1, 1 } },
3888 { ISD::SMIN, MVT::v64i8, { 1, 1, 1, 1 } },
3889 { ISD::SMULO, MVT::v32i16, { 3, 6, 4, 4 } },
3890 { ISD::SMULO, MVT::v64i8, { 8, 21, 17, 18 } },
3891 { ISD::UMULO, MVT::v32i16, { 2, 5, 3, 3 } },
3892 { ISD::UMULO, MVT::v64i8, { 8, 15, 15, 16 } },
3893 { ISD::SSUBSAT, MVT::v32i16, { 1, 1, 1, 1 } },
3894 { ISD::SSUBSAT, MVT::v64i8, { 1, 1, 1, 1 } },
3895 { ISD::UADDSAT, MVT::v32i16, { 1, 1, 1, 1 } },
3896 { ISD::UADDSAT, MVT::v64i8, { 1, 1, 1, 1 } },
3897 { ISD::UMAX, MVT::v32i16, { 1, 1, 1, 1 } },
3898 { ISD::UMAX, MVT::v64i8, { 1, 1, 1, 1 } },
3899 { ISD::UMIN, MVT::v32i16, { 1, 1, 1, 1 } },
3900 { ISD::UMIN, MVT::v64i8, { 1, 1, 1, 1 } },
3901 { ISD::USUBSAT, MVT::v32i16, { 1, 1, 1, 1 } },
3902 { ISD::USUBSAT, MVT::v64i8, { 1, 1, 1, 1 } },
3903 };
3904 static const CostKindTblEntry AVX512CostTbl[] = {
3905 { ISD::ABS, MVT::v8i64, { 1, 1, 1, 1 } },
3906 { ISD::ABS, MVT::v4i64, { 1, 1, 1, 1 } },
3907 { ISD::ABS, MVT::v2i64, { 1, 1, 1, 1 } },
3908 { ISD::ABS, MVT::v16i32, { 1, 1, 1, 1 } },
3909 { ISD::ABS, MVT::v8i32, { 1, 1, 1, 1 } },
3910 { ISD::ABS, MVT::v32i16, { 2, 7, 4, 4 } },
3911 { ISD::ABS, MVT::v16i16, { 1, 1, 1, 1 } },
3912 { ISD::ABS, MVT::v64i8, { 2, 7, 4, 4 } },
3913 { ISD::ABS, MVT::v32i8, { 1, 1, 1, 1 } },
3914 { ISD::BITREVERSE, MVT::v8i64, { 9, 13, 20, 20 } },
3915 { ISD::BITREVERSE, MVT::v16i32, { 9, 13, 20, 20 } },
3916 { ISD::BITREVERSE, MVT::v32i16, { 9, 13, 20, 20 } },
3917 { ISD::BITREVERSE, MVT::v64i8, { 6, 11, 17, 17 } },
3918 { ISD::BSWAP, MVT::v8i64, { 4, 7, 5, 5 } },
3919 { ISD::BSWAP, MVT::v16i32, { 4, 7, 5, 5 } },
3920 { ISD::BSWAP, MVT::v32i16, { 4, 7, 5, 5 } },
3921 { ISD::CTLZ, MVT::v8i64, { 10, 28, 32, 32 } },
3922 { ISD::CTLZ, MVT::v16i32, { 12, 30, 38, 38 } },
3923 { ISD::CTLZ, MVT::v32i16, { 8, 15, 29, 29 } },
3924 { ISD::CTLZ, MVT::v64i8, { 6, 11, 19, 19 } },
3925 { ISD::CTPOP, MVT::v8i64, { 16, 16, 19, 19 } },
3926 { ISD::CTPOP, MVT::v16i32, { 24, 19, 27, 27 } },
3927 { ISD::CTPOP, MVT::v32i16, { 18, 15, 22, 22 } },
3928 { ISD::CTPOP, MVT::v64i8, { 12, 11, 16, 16 } },
3929 { ISD::CTTZ, MVT::v8i64, { 2, 8, 6, 7 } },
3930 { ISD::CTTZ, MVT::v16i32, { 2, 8, 6, 7 } },
3931 { ISD::CTTZ, MVT::v32i16, { 7, 17, 27, 27 } },
3932 { ISD::CTTZ, MVT::v64i8, { 6, 13, 21, 21 } },
3933 { ISD::ROTL, MVT::v8i64, { 1, 1, 1, 1 } },
3934 { ISD::ROTL, MVT::v4i64, { 1, 1, 1, 1 } },
3935 { ISD::ROTL, MVT::v2i64, { 1, 1, 1, 1 } },
3936 { ISD::ROTL, MVT::v16i32, { 1, 1, 1, 1 } },
3937 { ISD::ROTL, MVT::v8i32, { 1, 1, 1, 1 } },
3938 { ISD::ROTL, MVT::v4i32, { 1, 1, 1, 1 } },
3939 { ISD::ROTR, MVT::v8i64, { 1, 1, 1, 1 } },
3940 { ISD::ROTR, MVT::v4i64, { 1, 1, 1, 1 } },
3941 { ISD::ROTR, MVT::v2i64, { 1, 1, 1, 1 } },
3942 { ISD::ROTR, MVT::v16i32, { 1, 1, 1, 1 } },
3943 { ISD::ROTR, MVT::v8i32, { 1, 1, 1, 1 } },
3944 { ISD::ROTR, MVT::v4i32, { 1, 1, 1, 1 } },
3945 { X86ISD::VROTLI, MVT::v8i64, { 1, 1, 1, 1 } },
3946 { X86ISD::VROTLI, MVT::v4i64, { 1, 1, 1, 1 } },
3947 { X86ISD::VROTLI, MVT::v2i64, { 1, 1, 1, 1 } },
3948 { X86ISD::VROTLI, MVT::v16i32, { 1, 1, 1, 1 } },
3949 { X86ISD::VROTLI, MVT::v8i32, { 1, 1, 1, 1 } },
3950 { X86ISD::VROTLI, MVT::v4i32, { 1, 1, 1, 1 } },
3951 { ISD::SADDSAT, MVT::v2i64, { 3, 3, 8, 9 } },
3952 { ISD::SADDSAT, MVT::v4i64, { 2, 2, 6, 7 } },
3953 { ISD::SADDSAT, MVT::v8i64, { 3, 3, 6, 7 } },
3954 { ISD::SADDSAT, MVT::v4i32, { 2, 2, 6, 7 } },
3955 { ISD::SADDSAT, MVT::v8i32, { 2, 2, 6, 7 } },
3956 { ISD::SADDSAT, MVT::v16i32, { 3, 3, 6, 7 } },
3957 { ISD::SADDSAT, MVT::v32i16, { 2, 2, 2, 2 } },
3958 { ISD::SADDSAT, MVT::v64i8, { 2, 2, 2, 2 } },
3959 { ISD::SMAX, MVT::v8i64, { 1, 3, 1, 1 } },
3960 { ISD::SMAX, MVT::v16i32, { 1, 1, 1, 1 } },
3961 { ISD::SMAX, MVT::v32i16, { 3, 7, 5, 5 } },
3962 { ISD::SMAX, MVT::v64i8, { 3, 7, 5, 5 } },
3963 { ISD::SMAX, MVT::v4i64, { 1, 3, 1, 1 } },
3964 { ISD::SMAX, MVT::v2i64, { 1, 3, 1, 1 } },
3965 { ISD::SMIN, MVT::v8i64, { 1, 3, 1, 1 } },
3966 { ISD::SMIN, MVT::v16i32, { 1, 1, 1, 1 } },
3967 { ISD::SMIN, MVT::v32i16, { 3, 7, 5, 5 } },
3968 { ISD::SMIN, MVT::v64i8, { 3, 7, 5, 5 } },
3969 { ISD::SMIN, MVT::v4i64, { 1, 3, 1, 1 } },
3970 { ISD::SMIN, MVT::v2i64, { 1, 3, 1, 1 } },
3971 { ISD::SMULO, MVT::v8i64, { 44, 44, 81, 93 } },
3972 { ISD::SMULO, MVT::v16i32, { 5, 12, 9, 11 } },
3973 { ISD::SMULO, MVT::v32i16, { 6, 12, 17, 17 } },
3974 { ISD::SMULO, MVT::v64i8, { 22, 28, 42, 42 } },
3975 { ISD::SSUBSAT, MVT::v2i64, { 2, 13, 9, 10 } },
3976 { ISD::SSUBSAT, MVT::v4i64, { 2, 15, 7, 8 } },
3977 { ISD::SSUBSAT, MVT::v8i64, { 2, 14, 7, 8 } },
3978 { ISD::SSUBSAT, MVT::v4i32, { 2, 14, 7, 8 } },
3979 { ISD::SSUBSAT, MVT::v8i32, { 2, 15, 7, 8 } },
3980 { ISD::SSUBSAT, MVT::v16i32, { 2, 14, 7, 8 } },
3981 { ISD::SSUBSAT, MVT::v32i16, { 2, 2, 2, 2 } },
3982 { ISD::SSUBSAT, MVT::v64i8, { 2, 2, 2, 2 } },
3983 { ISD::UMAX, MVT::v8i64, { 1, 3, 1, 1 } },
3984 { ISD::UMAX, MVT::v16i32, { 1, 1, 1, 1 } },
3985 { ISD::UMAX, MVT::v32i16, { 3, 7, 5, 5 } },
3986 { ISD::UMAX, MVT::v64i8, { 3, 7, 5, 5 } },
3987 { ISD::UMAX, MVT::v4i64, { 1, 3, 1, 1 } },
3988 { ISD::UMAX, MVT::v2i64, { 1, 3, 1, 1 } },
3989 { ISD::UMIN, MVT::v8i64, { 1, 3, 1, 1 } },
3990 { ISD::UMIN, MVT::v16i32, { 1, 1, 1, 1 } },
3991 { ISD::UMIN, MVT::v32i16, { 3, 7, 5, 5 } },
3992 { ISD::UMIN, MVT::v64i8, { 3, 7, 5, 5 } },
3993 { ISD::UMIN, MVT::v4i64, { 1, 3, 1, 1 } },
3994 { ISD::UMIN, MVT::v2i64, { 1, 3, 1, 1 } },
3995 { ISD::UMULO, MVT::v8i64, { 52, 52, 95, 104} },
3996 { ISD::UMULO, MVT::v16i32, { 5, 12, 8, 10 } },
3997 { ISD::UMULO, MVT::v32i16, { 5, 13, 16, 16 } },
3998 { ISD::UMULO, MVT::v64i8, { 18, 24, 30, 30 } },
3999 { ISD::UADDSAT, MVT::v2i64, { 1, 4, 4, 4 } },
4000 { ISD::UADDSAT, MVT::v4i64, { 1, 4, 4, 4 } },
4001 { ISD::UADDSAT, MVT::v8i64, { 1, 4, 4, 4 } },
4002 { ISD::UADDSAT, MVT::v4i32, { 1, 2, 4, 4 } },
4003 { ISD::UADDSAT, MVT::v8i32, { 1, 2, 4, 4 } },
4004 { ISD::UADDSAT, MVT::v16i32, { 2, 2, 4, 4 } },
4005 { ISD::UADDSAT, MVT::v32i16, { 2, 2, 2, 2 } },
4006 { ISD::UADDSAT, MVT::v64i8, { 2, 2, 2, 2 } },
4007 { ISD::USUBSAT, MVT::v2i64, { 1, 4, 2, 2 } },
4008 { ISD::USUBSAT, MVT::v4i64, { 1, 4, 2, 2 } },
4009 { ISD::USUBSAT, MVT::v8i64, { 1, 4, 2, 2 } },
4010 { ISD::USUBSAT, MVT::v8i32, { 1, 2, 2, 2 } },
4011 { ISD::USUBSAT, MVT::v16i32, { 1, 2, 2, 2 } },
4012 { ISD::USUBSAT, MVT::v32i16, { 2, 2, 2, 2 } },
4013 { ISD::USUBSAT, MVT::v64i8, { 2, 2, 2, 2 } },
4014 { ISD::FMAXNUM, MVT::f32, { 2, 2, 3, 3 } },
4015 { ISD::FMAXNUM, MVT::v4f32, { 1, 1, 3, 3 } },
4016 { ISD::FMAXNUM, MVT::v8f32, { 2, 2, 3, 3 } },
4017 { ISD::FMAXNUM, MVT::v16f32, { 4, 4, 3, 3 } },
4018 { ISD::FMAXNUM, MVT::f64, { 2, 2, 3, 3 } },
4019 { ISD::FMAXNUM, MVT::v2f64, { 1, 1, 3, 3 } },
4020 { ISD::FMAXNUM, MVT::v4f64, { 2, 2, 3, 3 } },
4021 { ISD::FMAXNUM, MVT::v8f64, { 3, 3, 3, 3 } },
4022 { ISD::FSQRT, MVT::f32, { 3, 12, 1, 1 } }, // Skylake from http://www.agner.org/
4023 { ISD::FSQRT, MVT::v4f32, { 3, 12, 1, 1 } }, // Skylake from http://www.agner.org/
4024 { ISD::FSQRT, MVT::v8f32, { 6, 12, 1, 1 } }, // Skylake from http://www.agner.org/
4025 { ISD::FSQRT, MVT::v16f32, { 12, 20, 1, 3 } }, // Skylake from http://www.agner.org/
4026 { ISD::FSQRT, MVT::f64, { 6, 18, 1, 1 } }, // Skylake from http://www.agner.org/
4027 { ISD::FSQRT, MVT::v2f64, { 6, 18, 1, 1 } }, // Skylake from http://www.agner.org/
4028 { ISD::FSQRT, MVT::v4f64, { 12, 18, 1, 1 } }, // Skylake from http://www.agner.org/
4029 { ISD::FSQRT, MVT::v8f64, { 24, 32, 1, 3 } }, // Skylake from http://www.agner.org/
4030 };
4031 static const CostKindTblEntry XOPCostTbl[] = {
4032 { ISD::BITREVERSE, MVT::v4i64, { 3, 6, 5, 6 } },
4033 { ISD::BITREVERSE, MVT::v8i32, { 3, 6, 5, 6 } },
4034 { ISD::BITREVERSE, MVT::v16i16, { 3, 6, 5, 6 } },
4035 { ISD::BITREVERSE, MVT::v32i8, { 3, 6, 5, 6 } },
4036 { ISD::BITREVERSE, MVT::v2i64, { 2, 7, 1, 1 } },
4037 { ISD::BITREVERSE, MVT::v4i32, { 2, 7, 1, 1 } },
4038 { ISD::BITREVERSE, MVT::v8i16, { 2, 7, 1, 1 } },
4039 { ISD::BITREVERSE, MVT::v16i8, { 2, 7, 1, 1 } },
4040 { ISD::BITREVERSE, MVT::i64, { 2, 2, 3, 4 } },
4041 { ISD::BITREVERSE, MVT::i32, { 2, 2, 3, 4 } },
4042 { ISD::BITREVERSE, MVT::i16, { 2, 2, 3, 4 } },
4043 { ISD::BITREVERSE, MVT::i8, { 2, 2, 3, 4 } },
4044 // XOP: ROTL = VPROT(X,Y), ROTR = VPROT(X,SUB(0,Y))
4045 { ISD::ROTL, MVT::v4i64, { 4, 7, 5, 6 } },
4046 { ISD::ROTL, MVT::v8i32, { 4, 7, 5, 6 } },
4047 { ISD::ROTL, MVT::v16i16, { 4, 7, 5, 6 } },
4048 { ISD::ROTL, MVT::v32i8, { 4, 7, 5, 6 } },
4049 { ISD::ROTL, MVT::v2i64, { 1, 3, 1, 1 } },
4050 { ISD::ROTL, MVT::v4i32, { 1, 3, 1, 1 } },
4051 { ISD::ROTL, MVT::v8i16, { 1, 3, 1, 1 } },
4052 { ISD::ROTL, MVT::v16i8, { 1, 3, 1, 1 } },
4053 { ISD::ROTR, MVT::v4i64, { 4, 7, 8, 9 } },
4054 { ISD::ROTR, MVT::v8i32, { 4, 7, 8, 9 } },
4055 { ISD::ROTR, MVT::v16i16, { 4, 7, 8, 9 } },
4056 { ISD::ROTR, MVT::v32i8, { 4, 7, 8, 9 } },
4057 { ISD::ROTR, MVT::v2i64, { 1, 3, 3, 3 } },
4058 { ISD::ROTR, MVT::v4i32, { 1, 3, 3, 3 } },
4059 { ISD::ROTR, MVT::v8i16, { 1, 3, 3, 3 } },
4060 { ISD::ROTR, MVT::v16i8, { 1, 3, 3, 3 } },
4061 { X86ISD::VROTLI, MVT::v4i64, { 4, 7, 5, 6 } },
4062 { X86ISD::VROTLI, MVT::v8i32, { 4, 7, 5, 6 } },
4063 { X86ISD::VROTLI, MVT::v16i16, { 4, 7, 5, 6 } },
4064 { X86ISD::VROTLI, MVT::v32i8, { 4, 7, 5, 6 } },
4065 { X86ISD::VROTLI, MVT::v2i64, { 1, 3, 1, 1 } },
4066 { X86ISD::VROTLI, MVT::v4i32, { 1, 3, 1, 1 } },
4067 { X86ISD::VROTLI, MVT::v8i16, { 1, 3, 1, 1 } },
4068 { X86ISD::VROTLI, MVT::v16i8, { 1, 3, 1, 1 } },
4069 };
4070 static const CostKindTblEntry AVX2CostTbl[] = {
4071 { ISD::ABS, MVT::v2i64, { 2, 4, 3, 5 } }, // VBLENDVPD(X,VPSUBQ(0,X),X)
4072 { ISD::ABS, MVT::v4i64, { 2, 4, 3, 5 } }, // VBLENDVPD(X,VPSUBQ(0,X),X)
4073 { ISD::ABS, MVT::v4i32, { 1, 1, 1, 1 } },
4074 { ISD::ABS, MVT::v8i32, { 1, 1, 1, 2 } },
4075 { ISD::ABS, MVT::v8i16, { 1, 1, 1, 1 } },
4076 { ISD::ABS, MVT::v16i16, { 1, 1, 1, 2 } },
4077 { ISD::ABS, MVT::v16i8, { 1, 1, 1, 1 } },
4078 { ISD::ABS, MVT::v32i8, { 1, 1, 1, 2 } },
4079 { ISD::BITREVERSE, MVT::v2i64, { 3, 11, 10, 11 } },
4080 { ISD::BITREVERSE, MVT::v4i64, { 5, 11, 10, 17 } },
4081 { ISD::BITREVERSE, MVT::v4i32, { 3, 11, 10, 11 } },
4082 { ISD::BITREVERSE, MVT::v8i32, { 5, 11, 10, 17 } },
4083 { ISD::BITREVERSE, MVT::v8i16, { 3, 11, 10, 11 } },
4084 { ISD::BITREVERSE, MVT::v16i16, { 5, 11, 10, 17 } },
4085 { ISD::BITREVERSE, MVT::v16i8, { 3, 6, 9, 9 } },
4086 { ISD::BITREVERSE, MVT::v32i8, { 4, 5, 9, 15 } },
4087 { ISD::BSWAP, MVT::v2i64, { 1, 2, 1, 2 } },
4088 { ISD::BSWAP, MVT::v4i64, { 1, 3, 1, 2 } },
4089 { ISD::BSWAP, MVT::v4i32, { 1, 2, 1, 2 } },
4090 { ISD::BSWAP, MVT::v8i32, { 1, 3, 1, 2 } },
4091 { ISD::BSWAP, MVT::v8i16, { 1, 2, 1, 2 } },
4092 { ISD::BSWAP, MVT::v16i16, { 1, 3, 1, 2 } },
4093 { ISD::CTLZ, MVT::v2i64, { 7, 18, 24, 25 } },
4094 { ISD::CTLZ, MVT::v4i64, { 14, 18, 24, 44 } },
4095 { ISD::CTLZ, MVT::v4i32, { 5, 16, 19, 20 } },
4096 { ISD::CTLZ, MVT::v8i32, { 10, 16, 19, 34 } },
4097 { ISD::CTLZ, MVT::v8i16, { 4, 13, 14, 15 } },
4098 { ISD::CTLZ, MVT::v16i16, { 6, 14, 14, 24 } },
4099 { ISD::CTLZ, MVT::v16i8, { 3, 12, 9, 10 } },
4100 { ISD::CTLZ, MVT::v32i8, { 4, 12, 9, 14 } },
4101 { ISD::CTPOP, MVT::v2i64, { 3, 9, 10, 10 } },
4102 { ISD::CTPOP, MVT::v4i64, { 4, 9, 10, 14 } },
4103 { ISD::CTPOP, MVT::v4i32, { 7, 12, 14, 14 } },
4104 { ISD::CTPOP, MVT::v8i32, { 7, 12, 14, 18 } },
4105 { ISD::CTPOP, MVT::v8i16, { 3, 7, 11, 11 } },
4106 { ISD::CTPOP, MVT::v16i16, { 6, 8, 11, 18 } },
4107 { ISD::CTPOP, MVT::v16i8, { 2, 5, 8, 8 } },
4108 { ISD::CTPOP, MVT::v32i8, { 3, 5, 8, 12 } },
4109 { ISD::CTTZ, MVT::v2i64, { 4, 11, 13, 13 } },
4110 { ISD::CTTZ, MVT::v4i64, { 5, 11, 13, 20 } },
4111 { ISD::CTTZ, MVT::v4i32, { 7, 14, 17, 17 } },
4112 { ISD::CTTZ, MVT::v8i32, { 7, 15, 17, 24 } },
4113 { ISD::CTTZ, MVT::v8i16, { 4, 9, 14, 14 } },
4114 { ISD::CTTZ, MVT::v16i16, { 6, 9, 14, 24 } },
4115 { ISD::CTTZ, MVT::v16i8, { 3, 7, 11, 11 } },
4116 { ISD::CTTZ, MVT::v32i8, { 5, 7, 11, 18 } },
4117 { ISD::SADDSAT, MVT::v2i64, { 4, 13, 8, 11 } },
4118 { ISD::SADDSAT, MVT::v4i64, { 3, 10, 8, 12 } },
4119 { ISD::SADDSAT, MVT::v4i32, { 2, 6, 7, 9 } },
4120 { ISD::SADDSAT, MVT::v8i32, { 4, 6, 7, 13 } },
4121 { ISD::SADDSAT, MVT::v16i16, { 1, 1, 1, 2 } },
4122 { ISD::SADDSAT, MVT::v32i8, { 1, 1, 1, 2 } },
4123 { ISD::SMAX, MVT::v2i64, { 2, 7, 2, 3 } },
4124 { ISD::SMAX, MVT::v4i64, { 2, 7, 2, 3 } },
4125 { ISD::SMAX, MVT::v8i32, { 1, 1, 1, 2 } },
4126 { ISD::SMAX, MVT::v16i16, { 1, 1, 1, 2 } },
4127 { ISD::SMAX, MVT::v32i8, { 1, 1, 1, 2 } },
4128 { ISD::SMIN, MVT::v2i64, { 2, 7, 2, 3 } },
4129 { ISD::SMIN, MVT::v4i64, { 2, 7, 2, 3 } },
4130 { ISD::SMIN, MVT::v8i32, { 1, 1, 1, 2 } },
4131 { ISD::SMIN, MVT::v16i16, { 1, 1, 1, 2 } },
4132 { ISD::SMIN, MVT::v32i8, { 1, 1, 1, 2 } },
4133 { ISD::SMULO, MVT::v4i64, { 20, 20, 33, 37 } },
4134 { ISD::SMULO, MVT::v2i64, { 8, 8, 13, 15 } },
4135 { ISD::SMULO, MVT::v8i32, { 8, 20, 13, 24 } },
4136 { ISD::SMULO, MVT::v4i32, { 5, 15, 11, 12 } },
4137 { ISD::SMULO, MVT::v16i16, { 4, 14, 8, 14 } },
4138 { ISD::SMULO, MVT::v8i16, { 3, 9, 6, 6 } },
4139 { ISD::SMULO, MVT::v32i8, { 9, 15, 18, 35 } },
4140 { ISD::SMULO, MVT::v16i8, { 6, 22, 14, 21 } },
4141 { ISD::SSUBSAT, MVT::v2i64, { 4, 13, 9, 13 } },
4142 { ISD::SSUBSAT, MVT::v4i64, { 4, 15, 9, 13 } },
4143 { ISD::SSUBSAT, MVT::v4i32, { 3, 14, 9, 11 } },
4144 { ISD::SSUBSAT, MVT::v8i32, { 4, 15, 9, 16 } },
4145 { ISD::SSUBSAT, MVT::v16i16, { 1, 1, 1, 2 } },
4146 { ISD::SSUBSAT, MVT::v32i8, { 1, 1, 1, 2 } },
4147 { ISD::UADDSAT, MVT::v2i64, { 2, 8, 6, 6 } },
4148 { ISD::UADDSAT, MVT::v4i64, { 3, 8, 6, 10 } },
4149 { ISD::UADDSAT, MVT::v8i32, { 2, 2, 4, 8 } },
4150 { ISD::UADDSAT, MVT::v16i16, { 1, 1, 1, 2 } },
4151 { ISD::UADDSAT, MVT::v32i8, { 1, 1, 1, 2 } },
4152 { ISD::UMAX, MVT::v2i64, { 2, 8, 5, 6 } },
4153 { ISD::UMAX, MVT::v4i64, { 2, 8, 5, 8 } },
4154 { ISD::UMAX, MVT::v8i32, { 1, 1, 1, 2 } },
4155 { ISD::UMAX, MVT::v16i16, { 1, 1, 1, 2 } },
4156 { ISD::UMAX, MVT::v32i8, { 1, 1, 1, 2 } },
4157 { ISD::UMIN, MVT::v2i64, { 2, 8, 5, 6 } },
4158 { ISD::UMIN, MVT::v4i64, { 2, 8, 5, 8 } },
4159 { ISD::UMIN, MVT::v8i32, { 1, 1, 1, 2 } },
4160 { ISD::UMIN, MVT::v16i16, { 1, 1, 1, 2 } },
4161 { ISD::UMIN, MVT::v32i8, { 1, 1, 1, 2 } },
4162 { ISD::UMULO, MVT::v4i64, { 24, 24, 39, 43 } },
4163 { ISD::UMULO, MVT::v2i64, { 10, 10, 15, 19 } },
4164 { ISD::UMULO, MVT::v8i32, { 8, 11, 13, 23 } },
4165 { ISD::UMULO, MVT::v4i32, { 5, 12, 11, 12 } },
4166 { ISD::UMULO, MVT::v16i16, { 4, 6, 8, 13 } },
4167 { ISD::UMULO, MVT::v8i16, { 2, 8, 6, 6 } },
4168 { ISD::UMULO, MVT::v32i8, { 9, 13, 17, 33 } },
4169 { ISD::UMULO, MVT::v16i8, { 6, 19, 13, 20 } },
4170 { ISD::USUBSAT, MVT::v2i64, { 2, 7, 6, 6 } },
4171 { ISD::USUBSAT, MVT::v4i64, { 3, 7, 6, 10 } },
4172 { ISD::USUBSAT, MVT::v8i32, { 2, 2, 2, 4 } },
4173 { ISD::USUBSAT, MVT::v16i16, { 1, 1, 1, 2 } },
4174 { ISD::USUBSAT, MVT::v32i8, { 1, 1, 1, 2 } },
4175 { ISD::FMAXNUM, MVT::f32, { 2, 7, 3, 5 } }, // MAXSS + CMPUNORDSS + BLENDVPS
4176 { ISD::FMAXNUM, MVT::v4f32, { 2, 7, 3, 5 } }, // MAXPS + CMPUNORDPS + BLENDVPS
4177 { ISD::FMAXNUM, MVT::v8f32, { 3, 7, 3, 6 } }, // MAXPS + CMPUNORDPS + BLENDVPS
4178 { ISD::FMAXNUM, MVT::f64, { 2, 7, 3, 5 } }, // MAXSD + CMPUNORDSD + BLENDVPD
4179 { ISD::FMAXNUM, MVT::v2f64, { 2, 7, 3, 5 } }, // MAXPD + CMPUNORDPD + BLENDVPD
4180 { ISD::FMAXNUM, MVT::v4f64, { 3, 7, 3, 6 } }, // MAXPD + CMPUNORDPD + BLENDVPD
4181 { ISD::FSQRT, MVT::f32, { 7, 15, 1, 1 } }, // vsqrtss
4182 { ISD::FSQRT, MVT::v4f32, { 7, 15, 1, 1 } }, // vsqrtps
4183 { ISD::FSQRT, MVT::v8f32, { 14, 21, 1, 3 } }, // vsqrtps
4184 { ISD::FSQRT, MVT::f64, { 14, 21, 1, 1 } }, // vsqrtsd
4185 { ISD::FSQRT, MVT::v2f64, { 14, 21, 1, 1 } }, // vsqrtpd
4186 { ISD::FSQRT, MVT::v4f64, { 28, 35, 1, 3 } }, // vsqrtpd
4187 };
4188 static const CostKindTblEntry AVX1CostTbl[] = {
4189 { ISD::ABS, MVT::v4i64, { 6, 8, 6, 12 } }, // VBLENDVPD(X,VPSUBQ(0,X),X)
4190 { ISD::ABS, MVT::v8i32, { 3, 6, 4, 5 } },
4191 { ISD::ABS, MVT::v16i16, { 3, 6, 4, 5 } },
4192 { ISD::ABS, MVT::v32i8, { 3, 6, 4, 5 } },
4193 { ISD::BITREVERSE, MVT::v4i64, { 17, 20, 20, 33 } }, // 2 x 128-bit Op + extract/insert
4194 { ISD::BITREVERSE, MVT::v2i64, { 8, 13, 10, 16 } },
4195 { ISD::BITREVERSE, MVT::v8i32, { 17, 20, 20, 33 } }, // 2 x 128-bit Op + extract/insert
4196 { ISD::BITREVERSE, MVT::v4i32, { 8, 13, 10, 16 } },
4197 { ISD::BITREVERSE, MVT::v16i16, { 17, 20, 20, 33 } }, // 2 x 128-bit Op + extract/insert
4198 { ISD::BITREVERSE, MVT::v8i16, { 8, 13, 10, 16 } },
4199 { ISD::BITREVERSE, MVT::v32i8, { 13, 15, 17, 26 } }, // 2 x 128-bit Op + extract/insert
4200 { ISD::BITREVERSE, MVT::v16i8, { 7, 7, 9, 13 } },
4201 { ISD::BSWAP, MVT::v4i64, { 5, 6, 5, 10 } },
4202 { ISD::BSWAP, MVT::v2i64, { 2, 2, 1, 3 } },
4203 { ISD::BSWAP, MVT::v8i32, { 5, 6, 5, 10 } },
4204 { ISD::BSWAP, MVT::v4i32, { 2, 2, 1, 3 } },
4205 { ISD::BSWAP, MVT::v16i16, { 5, 6, 5, 10 } },
4206 { ISD::BSWAP, MVT::v8i16, { 2, 2, 1, 3 } },
4207 { ISD::CTLZ, MVT::v4i64, { 29, 33, 49, 58 } }, // 2 x 128-bit Op + extract/insert
4208 { ISD::CTLZ, MVT::v2i64, { 14, 24, 24, 28 } },
4209 { ISD::CTLZ, MVT::v8i32, { 24, 28, 39, 48 } }, // 2 x 128-bit Op + extract/insert
4210 { ISD::CTLZ, MVT::v4i32, { 12, 20, 19, 23 } },
4211 { ISD::CTLZ, MVT::v16i16, { 19, 22, 29, 38 } }, // 2 x 128-bit Op + extract/insert
4212 { ISD::CTLZ, MVT::v8i16, { 9, 16, 14, 18 } },
4213 { ISD::CTLZ, MVT::v32i8, { 14, 15, 19, 28 } }, // 2 x 128-bit Op + extract/insert
4214 { ISD::CTLZ, MVT::v16i8, { 7, 12, 9, 13 } },
4215 { ISD::CTPOP, MVT::v4i64, { 14, 18, 19, 28 } }, // 2 x 128-bit Op + extract/insert
4216 { ISD::CTPOP, MVT::v2i64, { 7, 14, 10, 14 } },
4217 { ISD::CTPOP, MVT::v8i32, { 18, 24, 27, 36 } }, // 2 x 128-bit Op + extract/insert
4218 { ISD::CTPOP, MVT::v4i32, { 9, 20, 14, 18 } },
4219 { ISD::CTPOP, MVT::v16i16, { 16, 21, 22, 31 } }, // 2 x 128-bit Op + extract/insert
4220 { ISD::CTPOP, MVT::v8i16, { 8, 18, 11, 15 } },
4221 { ISD::CTPOP, MVT::v32i8, { 13, 15, 16, 25 } }, // 2 x 128-bit Op + extract/insert
4222 { ISD::CTPOP, MVT::v16i8, { 6, 12, 8, 12 } },
4223 { ISD::CTTZ, MVT::v4i64, { 17, 22, 24, 33 } }, // 2 x 128-bit Op + extract/insert
4224 { ISD::CTTZ, MVT::v2i64, { 9, 19, 13, 17 } },
4225 { ISD::CTTZ, MVT::v8i32, { 21, 27, 32, 41 } }, // 2 x 128-bit Op + extract/insert
4226 { ISD::CTTZ, MVT::v4i32, { 11, 24, 17, 21 } },
4227 { ISD::CTTZ, MVT::v16i16, { 18, 24, 27, 36 } }, // 2 x 128-bit Op + extract/insert
4228 { ISD::CTTZ, MVT::v8i16, { 9, 21, 14, 18 } },
4229 { ISD::CTTZ, MVT::v32i8, { 15, 18, 21, 30 } }, // 2 x 128-bit Op + extract/insert
4230 { ISD::CTTZ, MVT::v16i8, { 8, 16, 11, 15 } },
4231 { ISD::SADDSAT, MVT::v2i64, { 6, 13, 8, 11 } },
4232 { ISD::SADDSAT, MVT::v4i64, { 13, 20, 15, 25 } }, // 2 x 128-bit Op + extract/insert
4233 { ISD::SADDSAT, MVT::v8i32, { 12, 18, 14, 24 } }, // 2 x 128-bit Op + extract/insert
4234 { ISD::SADDSAT, MVT::v16i16, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4235 { ISD::SADDSAT, MVT::v32i8, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4236 { ISD::SMAX, MVT::v4i64, { 6, 9, 6, 12 } }, // 2 x 128-bit Op + extract/insert
4237 { ISD::SMAX, MVT::v2i64, { 3, 7, 2, 4 } },
4238 { ISD::SMAX, MVT::v8i32, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4239 { ISD::SMAX, MVT::v16i16, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4240 { ISD::SMAX, MVT::v32i8, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4241 { ISD::SMIN, MVT::v4i64, { 6, 9, 6, 12 } }, // 2 x 128-bit Op + extract/insert
4242 { ISD::SMIN, MVT::v2i64, { 3, 7, 2, 3 } },
4243 { ISD::SMIN, MVT::v8i32, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4244 { ISD::SMIN, MVT::v16i16, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4245 { ISD::SMIN, MVT::v32i8, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4246 { ISD::SMULO, MVT::v4i64, { 20, 20, 33, 37 } },
4247 { ISD::SMULO, MVT::v2i64, { 9, 9, 13, 17 } },
4248 { ISD::SMULO, MVT::v8i32, { 15, 20, 24, 29 } },
4249 { ISD::SMULO, MVT::v4i32, { 7, 15, 11, 13 } },
4250 { ISD::SMULO, MVT::v16i16, { 8, 14, 14, 15 } },
4251 { ISD::SMULO, MVT::v8i16, { 3, 9, 6, 6 } },
4252 { ISD::SMULO, MVT::v32i8, { 20, 20, 37, 39 } },
4253 { ISD::SMULO, MVT::v16i8, { 9, 22, 18, 21 } },
4254 { ISD::SSUBSAT, MVT::v2i64, { 7, 13, 9, 13 } },
4255 { ISD::SSUBSAT, MVT::v4i64, { 15, 21, 18, 29 } }, // 2 x 128-bit Op + extract/insert
4256 { ISD::SSUBSAT, MVT::v8i32, { 15, 19, 18, 29 } }, // 2 x 128-bit Op + extract/insert
4257 { ISD::SSUBSAT, MVT::v16i16, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4258 { ISD::SSUBSAT, MVT::v32i8, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4259 { ISD::UADDSAT, MVT::v2i64, { 3, 8, 6, 6 } },
4260 { ISD::UADDSAT, MVT::v4i64, { 8, 11, 14, 15 } }, // 2 x 128-bit Op + extract/insert
4261 { ISD::UADDSAT, MVT::v8i32, { 6, 6, 10, 11 } }, // 2 x 128-bit Op + extract/insert
4262 { ISD::UADDSAT, MVT::v16i16, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4263 { ISD::UADDSAT, MVT::v32i8, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4264 { ISD::UMAX, MVT::v4i64, { 9, 10, 11, 17 } }, // 2 x 128-bit Op + extract/insert
4265 { ISD::UMAX, MVT::v2i64, { 4, 8, 5, 7 } },
4266 { ISD::UMAX, MVT::v8i32, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4267 { ISD::UMAX, MVT::v16i16, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4268 { ISD::UMAX, MVT::v32i8, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4269 { ISD::UMIN, MVT::v4i64, { 9, 10, 11, 17 } }, // 2 x 128-bit Op + extract/insert
4270 { ISD::UMIN, MVT::v2i64, { 4, 8, 5, 7 } },
4271 { ISD::UMIN, MVT::v8i32, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4272 { ISD::UMIN, MVT::v16i16, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4273 { ISD::UMIN, MVT::v32i8, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4274 { ISD::UMULO, MVT::v4i64, { 24, 26, 39, 45 } },
4275 { ISD::UMULO, MVT::v2i64, { 10, 12, 15, 20 } },
4276 { ISD::UMULO, MVT::v8i32, { 14, 15, 23, 28 } },
4277 { ISD::UMULO, MVT::v4i32, { 7, 12, 11, 13 } },
4278 { ISD::UMULO, MVT::v16i16, { 7, 11, 13, 14 } },
4279 { ISD::UMULO, MVT::v8i16, { 3, 8, 6, 6 } },
4280 { ISD::UMULO, MVT::v32i8, { 19, 19, 35, 37 } },
4281 { ISD::UMULO, MVT::v16i8, { 9, 19, 17, 20 } },
4282 { ISD::USUBSAT, MVT::v2i64, { 3, 7, 6, 6 } },
4283 { ISD::USUBSAT, MVT::v4i64, { 8, 10, 14, 15 } }, // 2 x 128-bit Op + extract/insert
4284 { ISD::USUBSAT, MVT::v8i32, { 4, 4, 7, 8 } }, // 2 x 128-bit Op + extract/insert
4285 { ISD::USUBSAT, MVT::v8i32, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4286 { ISD::USUBSAT, MVT::v16i16, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4287 { ISD::USUBSAT, MVT::v32i8, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4288 { ISD::FMAXNUM, MVT::f32, { 3, 6, 3, 5 } }, // MAXSS + CMPUNORDSS + BLENDVPS
4289 { ISD::FMAXNUM, MVT::v4f32, { 3, 6, 3, 5 } }, // MAXPS + CMPUNORDPS + BLENDVPS
4290 { ISD::FMAXNUM, MVT::v8f32, { 5, 7, 3, 10 } }, // MAXPS + CMPUNORDPS + BLENDVPS
4291 { ISD::FMAXNUM, MVT::f64, { 3, 6, 3, 5 } }, // MAXSD + CMPUNORDSD + BLENDVPD
4292 { ISD::FMAXNUM, MVT::v2f64, { 3, 6, 3, 5 } }, // MAXPD + CMPUNORDPD + BLENDVPD
4293 { ISD::FMAXNUM, MVT::v4f64, { 5, 7, 3, 10 } }, // MAXPD + CMPUNORDPD + BLENDVPD
4294 { ISD::FSQRT, MVT::f32, { 21, 21, 1, 1 } }, // vsqrtss
4295 { ISD::FSQRT, MVT::v4f32, { 21, 21, 1, 1 } }, // vsqrtps
4296 { ISD::FSQRT, MVT::v8f32, { 42, 42, 1, 3 } }, // vsqrtps
4297 { ISD::FSQRT, MVT::f64, { 27, 27, 1, 1 } }, // vsqrtsd
4298 { ISD::FSQRT, MVT::v2f64, { 27, 27, 1, 1 } }, // vsqrtpd
4299 { ISD::FSQRT, MVT::v4f64, { 54, 54, 1, 3 } }, // vsqrtpd
4300 };
4301 static const CostKindTblEntry GFNICostTbl[] = {
4302 { ISD::BITREVERSE, MVT::i8, { 3, 3, 3, 4 } }, // gf2p8affineqb
4303 { ISD::BITREVERSE, MVT::i16, { 3, 3, 4, 6 } }, // gf2p8affineqb
4304 { ISD::BITREVERSE, MVT::i32, { 3, 3, 4, 5 } }, // gf2p8affineqb
4305 { ISD::BITREVERSE, MVT::i64, { 3, 3, 4, 6 } }, // gf2p8affineqb
4306 { ISD::BITREVERSE, MVT::v16i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
4307 { ISD::BITREVERSE, MVT::v32i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
4308 { ISD::BITREVERSE, MVT::v64i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
4309 { ISD::BITREVERSE, MVT::v8i16, { 1, 8, 2, 4 } }, // gf2p8affineqb
4310 { ISD::BITREVERSE, MVT::v16i16, { 1, 9, 2, 4 } }, // gf2p8affineqb
4311 { ISD::BITREVERSE, MVT::v32i16, { 1, 9, 2, 4 } }, // gf2p8affineqb
4312 { ISD::BITREVERSE, MVT::v4i32, { 1, 8, 2, 4 } }, // gf2p8affineqb
4313 { ISD::BITREVERSE, MVT::v8i32, { 1, 9, 2, 4 } }, // gf2p8affineqb
4314 { ISD::BITREVERSE, MVT::v16i32, { 1, 9, 2, 4 } }, // gf2p8affineqb
4315 { ISD::BITREVERSE, MVT::v2i64, { 1, 8, 2, 4 } }, // gf2p8affineqb
4316 { ISD::BITREVERSE, MVT::v4i64, { 1, 9, 2, 4 } }, // gf2p8affineqb
4317 { ISD::BITREVERSE, MVT::v8i64, { 1, 9, 2, 4 } }, // gf2p8affineqb
4318 { X86ISD::VROTLI, MVT::v16i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
4319 { X86ISD::VROTLI, MVT::v32i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
4320 { X86ISD::VROTLI, MVT::v64i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
4321 };
4322 static const CostKindTblEntry GLMCostTbl[] = {
4323 { ISD::FSQRT, MVT::f32, { 19, 20, 1, 1 } }, // sqrtss
4324 { ISD::FSQRT, MVT::v4f32, { 37, 41, 1, 5 } }, // sqrtps
4325 { ISD::FSQRT, MVT::f64, { 34, 35, 1, 1 } }, // sqrtsd
4326 { ISD::FSQRT, MVT::v2f64, { 67, 71, 1, 5 } }, // sqrtpd
4327 };
4328 static const CostKindTblEntry SLMCostTbl[] = {
4329 { ISD::BSWAP, MVT::v2i64, { 5, 5, 1, 5 } },
4330 { ISD::BSWAP, MVT::v4i32, { 5, 5, 1, 5 } },
4331 { ISD::BSWAP, MVT::v8i16, { 5, 5, 1, 5 } },
4332 { ISD::FSQRT, MVT::f32, { 20, 20, 1, 1 } }, // sqrtss
4333 { ISD::FSQRT, MVT::v4f32, { 40, 41, 1, 5 } }, // sqrtps
4334 { ISD::FSQRT, MVT::f64, { 35, 35, 1, 1 } }, // sqrtsd
4335 { ISD::FSQRT, MVT::v2f64, { 70, 71, 1, 5 } }, // sqrtpd
4336 };
4337 static const CostKindTblEntry SSE42CostTbl[] = {
4338 { ISD::FMAXNUM, MVT::f32, { 5, 5, 7, 7 } }, // MAXSS + CMPUNORDSS + BLENDVPS
4339 { ISD::FMAXNUM, MVT::v4f32, { 4, 4, 4, 5 } }, // MAXPS + CMPUNORDPS + BLENDVPS
4340 { ISD::FMAXNUM, MVT::f64, { 5, 5, 7, 7 } }, // MAXSD + CMPUNORDSD + BLENDVPD
4341 { ISD::FMAXNUM, MVT::v2f64, { 4, 4, 4, 5 } }, // MAXPD + CMPUNORDPD + BLENDVPD
4342 { ISD::FSQRT, MVT::f32, { 18, 18, 1, 1 } }, // Nehalem from http://www.agner.org/
4343 { ISD::FSQRT, MVT::v4f32, { 18, 18, 1, 1 } }, // Nehalem from http://www.agner.org/
4344 };
4345 static const CostKindTblEntry SSE41CostTbl[] = {
4346 { ISD::ABS, MVT::v2i64, { 3, 4, 3, 5 } }, // BLENDVPD(X,PSUBQ(0,X),X)
4347 { ISD::SADDSAT, MVT::v2i64, { 10, 14, 17, 21 } },
4348 { ISD::SADDSAT, MVT::v4i32, { 5, 11, 8, 10 } },
4349 { ISD::SSUBSAT, MVT::v2i64, { 12, 19, 25, 29 } },
4350 { ISD::SSUBSAT, MVT::v4i32, { 6, 14, 10, 12 } },
4351 { ISD::SMAX, MVT::v2i64, { 3, 7, 2, 3 } },
4352 { ISD::SMAX, MVT::v4i32, { 1, 1, 1, 1 } },
4353 { ISD::SMAX, MVT::v16i8, { 1, 1, 1, 1 } },
4354 { ISD::SMIN, MVT::v2i64, { 3, 7, 2, 3 } },
4355 { ISD::SMIN, MVT::v4i32, { 1, 1, 1, 1 } },
4356 { ISD::SMIN, MVT::v16i8, { 1, 1, 1, 1 } },
4357 { ISD::SMULO, MVT::v2i64, { 9, 11, 13, 17 } },
4358 { ISD::SMULO, MVT::v4i32, { 20, 24, 13, 19 } },
4359 { ISD::SMULO, MVT::v8i16, { 5, 9, 8, 8 } },
4360 { ISD::SMULO, MVT::v16i8, { 13, 22, 24, 25 } },
4361 { ISD::UADDSAT, MVT::v2i64, { 6, 13, 14, 14 } },
4362 { ISD::UADDSAT, MVT::v4i32, { 2, 2, 4, 4 } },
4363 { ISD::USUBSAT, MVT::v2i64, { 6, 10, 14, 14 } },
4364 { ISD::USUBSAT, MVT::v4i32, { 1, 2, 2, 2 } },
4365 { ISD::UMAX, MVT::v2i64, { 2, 11, 6, 7 } },
4366 { ISD::UMAX, MVT::v4i32, { 1, 1, 1, 1 } },
4367 { ISD::UMAX, MVT::v8i16, { 1, 1, 1, 1 } },
4368 { ISD::UMIN, MVT::v2i64, { 2, 11, 6, 7 } },
4369 { ISD::UMIN, MVT::v4i32, { 1, 1, 1, 1 } },
4370 { ISD::UMIN, MVT::v8i16, { 1, 1, 1, 1 } },
4371 { ISD::UMULO, MVT::v2i64, { 14, 20, 15, 20 } },
4372 { ISD::UMULO, MVT::v4i32, { 19, 22, 12, 18 } },
4373 { ISD::UMULO, MVT::v8i16, { 4, 9, 7, 7 } },
4374 { ISD::UMULO, MVT::v16i8, { 13, 19, 18, 20 } },
4375 };
4376 static const CostKindTblEntry SSSE3CostTbl[] = {
4377 { ISD::ABS, MVT::v4i32, { 1, 2, 1, 1 } },
4378 { ISD::ABS, MVT::v8i16, { 1, 2, 1, 1 } },
4379 { ISD::ABS, MVT::v16i8, { 1, 2, 1, 1 } },
4380 { ISD::BITREVERSE, MVT::v2i64, { 16, 20, 11, 21 } },
4381 { ISD::BITREVERSE, MVT::v4i32, { 16, 20, 11, 21 } },
4382 { ISD::BITREVERSE, MVT::v8i16, { 16, 20, 11, 21 } },
4383 { ISD::BITREVERSE, MVT::v16i8, { 11, 12, 10, 16 } },
4384 { ISD::BSWAP, MVT::v2i64, { 2, 3, 1, 5 } },
4385 { ISD::BSWAP, MVT::v4i32, { 2, 3, 1, 5 } },
4386 { ISD::BSWAP, MVT::v8i16, { 2, 3, 1, 5 } },
4387 { ISD::CTLZ, MVT::v2i64, { 18, 28, 28, 35 } },
4388 { ISD::CTLZ, MVT::v4i32, { 15, 20, 22, 28 } },
4389 { ISD::CTLZ, MVT::v8i16, { 13, 17, 16, 22 } },
4390 { ISD::CTLZ, MVT::v16i8, { 11, 15, 10, 16 } },
4391 { ISD::CTPOP, MVT::v2i64, { 13, 19, 12, 18 } },
4392 { ISD::CTPOP, MVT::v4i32, { 18, 24, 16, 22 } },
4393 { ISD::CTPOP, MVT::v8i16, { 13, 18, 14, 20 } },
4394 { ISD::CTPOP, MVT::v16i8, { 11, 12, 10, 16 } },
4395 { ISD::CTTZ, MVT::v2i64, { 13, 25, 15, 22 } },
4396 { ISD::CTTZ, MVT::v4i32, { 18, 26, 19, 25 } },
4397 { ISD::CTTZ, MVT::v8i16, { 13, 20, 17, 23 } },
4398 { ISD::CTTZ, MVT::v16i8, { 11, 16, 13, 19 } }
4399 };
4400 static const CostKindTblEntry SSE2CostTbl[] = {
4401 { ISD::ABS, MVT::v2i64, { 3, 6, 5, 5 } },
4402 { ISD::ABS, MVT::v4i32, { 1, 4, 4, 4 } },
4403 { ISD::ABS, MVT::v8i16, { 1, 2, 3, 3 } },
4404 { ISD::ABS, MVT::v16i8, { 1, 2, 3, 3 } },
4405 { ISD::BITREVERSE, MVT::v2i64, { 16, 20, 32, 32 } },
4406 { ISD::BITREVERSE, MVT::v4i32, { 16, 20, 30, 30 } },
4407 { ISD::BITREVERSE, MVT::v8i16, { 16, 20, 25, 25 } },
4408 { ISD::BITREVERSE, MVT::v16i8, { 11, 12, 21, 21 } },
4409 { ISD::BSWAP, MVT::v2i64, { 5, 6, 11, 11 } },
4410 { ISD::BSWAP, MVT::v4i32, { 5, 5, 9, 9 } },
4411 { ISD::BSWAP, MVT::v8i16, { 5, 5, 4, 5 } },
4412 { ISD::CTLZ, MVT::v2i64, { 10, 45, 36, 38 } },
4413 { ISD::CTLZ, MVT::v4i32, { 10, 45, 38, 40 } },
4414 { ISD::CTLZ, MVT::v8i16, { 9, 38, 32, 34 } },
4415 { ISD::CTLZ, MVT::v16i8, { 8, 39, 29, 32 } },
4416 { ISD::CTPOP, MVT::v2i64, { 12, 26, 16, 18 } },
4417 { ISD::CTPOP, MVT::v4i32, { 15, 29, 21, 23 } },
4418 { ISD::CTPOP, MVT::v8i16, { 13, 25, 18, 20 } },
4419 { ISD::CTPOP, MVT::v16i8, { 10, 21, 14, 16 } },
4420 { ISD::CTTZ, MVT::v2i64, { 14, 28, 19, 21 } },
4421 { ISD::CTTZ, MVT::v4i32, { 18, 31, 24, 26 } },
4422 { ISD::CTTZ, MVT::v8i16, { 16, 27, 21, 23 } },
4423 { ISD::CTTZ, MVT::v16i8, { 13, 23, 17, 19 } },
4424 { ISD::SADDSAT, MVT::v2i64, { 12, 14, 24, 24 } },
4425 { ISD::SADDSAT, MVT::v4i32, { 6, 11, 11, 12 } },
4426 { ISD::SADDSAT, MVT::v8i16, { 1, 2, 1, 1 } },
4427 { ISD::SADDSAT, MVT::v16i8, { 1, 2, 1, 1 } },
4428 { ISD::SMAX, MVT::v2i64, { 4, 8, 15, 15 } },
4429 { ISD::SMAX, MVT::v4i32, { 2, 4, 5, 5 } },
4430 { ISD::SMAX, MVT::v8i16, { 1, 1, 1, 1 } },
4431 { ISD::SMAX, MVT::v16i8, { 2, 4, 5, 5 } },
4432 { ISD::SMIN, MVT::v2i64, { 4, 8, 15, 15 } },
4433 { ISD::SMIN, MVT::v4i32, { 2, 4, 5, 5 } },
4434 { ISD::SMIN, MVT::v8i16, { 1, 1, 1, 1 } },
4435 { ISD::SMIN, MVT::v16i8, { 2, 4, 5, 5 } },
4436 { ISD::SMULO, MVT::v2i64, { 30, 33, 13, 23 } },
4437 { ISD::SMULO, MVT::v4i32, { 20, 24, 23, 23 } },
4438 { ISD::SMULO, MVT::v8i16, { 5, 10, 8, 8 } },
4439 { ISD::SMULO, MVT::v16i8, { 13, 23, 24, 25 } },
4440 { ISD::SSUBSAT, MVT::v2i64, { 16, 19, 31, 31 } },
4441 { ISD::SSUBSAT, MVT::v4i32, { 6, 14, 12, 13 } },
4442 { ISD::SSUBSAT, MVT::v8i16, { 1, 2, 1, 1 } },
4443 { ISD::SSUBSAT, MVT::v16i8, { 1, 2, 1, 1 } },
4444 { ISD::UADDSAT, MVT::v2i64, { 7, 13, 14, 14 } },
4445 { ISD::UADDSAT, MVT::v4i32, { 4, 5, 7, 7 } },
4446 { ISD::UADDSAT, MVT::v8i16, { 1, 2, 1, 1 } },
4447 { ISD::UADDSAT, MVT::v16i8, { 1, 2, 1, 1 } },
4448 { ISD::UMAX, MVT::v2i64, { 4, 8, 15, 15 } },
4449 { ISD::UMAX, MVT::v4i32, { 2, 5, 8, 8 } },
4450 { ISD::UMAX, MVT::v8i16, { 1, 3, 3, 3 } },
4451 { ISD::UMAX, MVT::v16i8, { 1, 1, 1, 1 } },
4452 { ISD::UMIN, MVT::v2i64, { 4, 8, 15, 15 } },
4453 { ISD::UMIN, MVT::v4i32, { 2, 5, 8, 8 } },
4454 { ISD::UMIN, MVT::v8i16, { 1, 3, 3, 3 } },
4455 { ISD::UMIN, MVT::v16i8, { 1, 1, 1, 1 } },
4456 { ISD::UMULO, MVT::v2i64, { 30, 33, 15, 29 } },
4457 { ISD::UMULO, MVT::v4i32, { 19, 22, 14, 18 } },
4458 { ISD::UMULO, MVT::v8i16, { 4, 9, 7, 7 } },
4459 { ISD::UMULO, MVT::v16i8, { 13, 19, 20, 20 } },
4460 { ISD::USUBSAT, MVT::v2i64, { 7, 10, 14, 14 } },
4461 { ISD::USUBSAT, MVT::v4i32, { 4, 4, 7, 7 } },
4462 { ISD::USUBSAT, MVT::v8i16, { 1, 2, 1, 1 } },
4463 { ISD::USUBSAT, MVT::v16i8, { 1, 2, 1, 1 } },
4464 { ISD::FMAXNUM, MVT::f64, { 5, 5, 7, 7 } },
4465 { ISD::FMAXNUM, MVT::v2f64, { 4, 6, 6, 6 } },
4466 { ISD::FSQRT, MVT::f64, { 32, 32, 1, 1 } }, // Nehalem from http://www.agner.org/
4467 { ISD::FSQRT, MVT::v2f64, { 32, 32, 1, 1 } }, // Nehalem from http://www.agner.org/
4468 };
4469 static const CostKindTblEntry SSE1CostTbl[] = {
4470 { ISD::FMAXNUM, MVT::f32, { 5, 5, 7, 7 } },
4471 { ISD::FMAXNUM, MVT::v4f32, { 4, 6, 6, 6 } },
4472 { ISD::FSQRT, MVT::f32, { 28, 30, 1, 2 } }, // Pentium III from http://www.agner.org/
4473 { ISD::FSQRT, MVT::v4f32, { 56, 56, 1, 2 } }, // Pentium III from http://www.agner.org/
4474 };
4475 static const CostKindTblEntry BMI64CostTbl[] = { // 64-bit targets
4476 { ISD::CTTZ, MVT::i64, { 1, 1, 1, 1 } },
4477 };
4478 static const CostKindTblEntry BMI32CostTbl[] = { // 32 or 64-bit targets
4479 { ISD::CTTZ, MVT::i32, { 1, 1, 1, 1 } },
4480 { ISD::CTTZ, MVT::i16, { 2, 1, 1, 1 } },
4481 { ISD::CTTZ, MVT::i8, { 2, 1, 1, 1 } },
4482 };
4483 static const CostKindTblEntry LZCNT64CostTbl[] = { // 64-bit targets
4484 { ISD::CTLZ, MVT::i64, { 1, 1, 1, 1 } },
4485 };
4486 static const CostKindTblEntry LZCNT32CostTbl[] = { // 32 or 64-bit targets
4487 { ISD::CTLZ, MVT::i32, { 1, 1, 1, 1 } },
4488 { ISD::CTLZ, MVT::i16, { 2, 1, 1, 1 } },
4489 { ISD::CTLZ, MVT::i8, { 2, 1, 1, 1 } },
4490 };
4491 static const CostKindTblEntry POPCNT64CostTbl[] = { // 64-bit targets
4492 { ISD::CTPOP, MVT::i64, { 1, 1, 1, 1 } }, // popcnt
4493 };
4494 static const CostKindTblEntry POPCNT32CostTbl[] = { // 32 or 64-bit targets
4495 { ISD::CTPOP, MVT::i32, { 1, 1, 1, 1 } }, // popcnt
4496 { ISD::CTPOP, MVT::i16, { 1, 1, 2, 2 } }, // popcnt(zext())
4497 { ISD::CTPOP, MVT::i8, { 1, 1, 2, 2 } }, // popcnt(zext())
4498 };
4499 static const CostKindTblEntry X64CostTbl[] = { // 64-bit targets
4500 { ISD::ABS, MVT::i64, { 1, 2, 3, 3 } }, // SUB+CMOV
4501 { ISD::BITREVERSE, MVT::i64, { 10, 12, 20, 22 } },
4502 { ISD::BSWAP, MVT::i64, { 1, 2, 1, 2 } },
4503 { ISD::CTLZ, MVT::i64, { 1, 2, 3, 3 } }, // MOV+BSR+XOR
4504 { ISD::CTLZ, MVT::i32, { 1, 2, 3, 3 } }, // MOV+BSR+XOR
4505 { ISD::CTLZ, MVT::i16, { 2, 2, 3, 3 } }, // MOV+BSR+XOR
4506 { ISD::CTLZ, MVT::i8, { 2, 2, 4, 3 } }, // MOV+BSR+XOR
4507 { ISD::CTLZ_ZERO_POISON,MVT::i64,{ 1, 2, 2, 2 } }, // BSR+XOR
4508 { ISD::CTTZ, MVT::i64, { 1, 2, 2, 2 } }, // MOV+BSF
4509 { ISD::CTTZ, MVT::i32, { 1, 2, 2, 2 } }, // MOV+BSF
4510 { ISD::CTTZ, MVT::i16, { 2, 2, 2, 2 } }, // MOV+BSF
4511 { ISD::CTTZ, MVT::i8, { 2, 2, 2, 2 } }, // MOV+BSF
4512 { ISD::CTTZ_ZERO_POISON,MVT::i64,{ 1, 2, 1, 2 } }, // BSF
4513 { ISD::CTPOP, MVT::i64, { 10, 6, 19, 19 } },
4514 { ISD::ROTL, MVT::i64, { 2, 3, 1, 3 } },
4515 { ISD::ROTR, MVT::i64, { 2, 3, 1, 3 } },
4516 { X86ISD::VROTLI, MVT::i64, { 1, 1, 1, 1 } },
4517 { ISD::FSHL, MVT::i64, { 4, 4, 1, 4 } },
4518 { ISD::SADDSAT, MVT::i64, { 4, 4, 7, 10 } },
4519 { ISD::SSUBSAT, MVT::i64, { 4, 5, 8, 11 } },
4520 { ISD::UADDSAT, MVT::i64, { 2, 3, 4, 7 } },
4521 { ISD::USUBSAT, MVT::i64, { 2, 3, 4, 7 } },
4522 { ISD::SMAX, MVT::i64, { 1, 3, 2, 3 } },
4523 { ISD::SMIN, MVT::i64, { 1, 3, 2, 3 } },
4524 { ISD::UMAX, MVT::i64, { 1, 3, 2, 3 } },
4525 { ISD::UMIN, MVT::i64, { 1, 3, 2, 3 } },
4526 { ISD::SADDO, MVT::i64, { 2, 2, 4, 6 } },
4527 { ISD::UADDO, MVT::i64, { 2, 2, 4, 6 } },
4528 { ISD::SMULO, MVT::i64, { 4, 4, 4, 6 } },
4529 { ISD::UMULO, MVT::i64, { 8, 8, 4, 7 } },
4530 };
4531 static const CostKindTblEntry X86CostTbl[] = { // 32 or 64-bit targets
4532 { ISD::ABS, MVT::i32, { 1, 2, 3, 3 } }, // SUB+XOR+SRA or SUB+CMOV
4533 { ISD::ABS, MVT::i16, { 2, 2, 3, 3 } }, // SUB+XOR+SRA or SUB+CMOV
4534 { ISD::ABS, MVT::i8, { 2, 4, 4, 3 } }, // SUB+XOR+SRA
4535 { ISD::BITREVERSE, MVT::i32, { 9, 12, 17, 19 } },
4536 { ISD::BITREVERSE, MVT::i16, { 9, 12, 17, 19 } },
4537 { ISD::BITREVERSE, MVT::i8, { 7, 9, 13, 14 } },
4538 { ISD::BSWAP, MVT::i32, { 1, 1, 1, 1 } },
4539 { ISD::BSWAP, MVT::i16, { 1, 2, 1, 2 } }, // ROL
4540 { ISD::CTLZ, MVT::i32, { 2, 2, 4, 5 } }, // BSR+XOR or BSR+XOR+CMOV
4541 { ISD::CTLZ, MVT::i16, { 2, 2, 4, 5 } }, // BSR+XOR or BSR+XOR+CMOV
4542 { ISD::CTLZ, MVT::i8, { 2, 2, 5, 6 } }, // BSR+XOR or BSR+XOR+CMOV
4543 { ISD::CTLZ_ZERO_POISON,MVT::i32,{ 1, 2, 2, 2 } }, // BSR+XOR
4544 { ISD::CTLZ_ZERO_POISON,MVT::i16,{ 2, 2, 2, 2 } }, // BSR+XOR
4545 { ISD::CTLZ_ZERO_POISON,MVT::i8, { 2, 2, 3, 3 } }, // BSR+XOR
4546 { ISD::CTTZ, MVT::i32, { 2, 2, 3, 3 } }, // TEST+BSF+CMOV/BRANCH
4547 { ISD::CTTZ, MVT::i16, { 2, 2, 2, 3 } }, // TEST+BSF+CMOV/BRANCH
4548 { ISD::CTTZ, MVT::i8, { 2, 2, 2, 3 } }, // TEST+BSF+CMOV/BRANCH
4549 { ISD::CTTZ_ZERO_POISON,MVT::i32,{ 1, 2, 1, 2 } }, // BSF
4550 { ISD::CTTZ_ZERO_POISON,MVT::i16,{ 2, 2, 1, 2 } }, // BSF
4551 { ISD::CTTZ_ZERO_POISON,MVT::i8, { 2, 2, 1, 2 } }, // BSF
4552 { ISD::CTPOP, MVT::i32, { 8, 7, 15, 15 } },
4553 { ISD::CTPOP, MVT::i16, { 9, 8, 17, 17 } },
4554 { ISD::CTPOP, MVT::i8, { 7, 6, 6, 6 } },
4555 { ISD::ROTL, MVT::i32, { 2, 3, 1, 3 } },
4556 { ISD::ROTL, MVT::i16, { 2, 3, 1, 3 } },
4557 { ISD::ROTL, MVT::i8, { 2, 3, 1, 3 } },
4558 { ISD::ROTR, MVT::i32, { 2, 3, 1, 3 } },
4559 { ISD::ROTR, MVT::i16, { 2, 3, 1, 3 } },
4560 { ISD::ROTR, MVT::i8, { 2, 3, 1, 3 } },
4561 { X86ISD::VROTLI, MVT::i32, { 1, 1, 1, 1 } },
4562 { X86ISD::VROTLI, MVT::i16, { 1, 1, 1, 1 } },
4563 { X86ISD::VROTLI, MVT::i8, { 1, 1, 1, 1 } },
4564 { ISD::FSHL, MVT::i32, { 4, 4, 1, 4 } },
4565 { ISD::FSHL, MVT::i16, { 4, 4, 2, 5 } },
4566 { ISD::FSHL, MVT::i8, { 4, 4, 2, 5 } },
4567 { ISD::SADDSAT, MVT::i32, { 3, 4, 6, 9 } },
4568 { ISD::SADDSAT, MVT::i16, { 4, 4, 7, 10 } },
4569 { ISD::SADDSAT, MVT::i8, { 4, 5, 8, 11 } },
4570 { ISD::SSUBSAT, MVT::i32, { 4, 4, 7, 10 } },
4571 { ISD::SSUBSAT, MVT::i16, { 4, 4, 7, 10 } },
4572 { ISD::SSUBSAT, MVT::i8, { 4, 5, 8, 11 } },
4573 { ISD::UADDSAT, MVT::i32, { 2, 3, 4, 7 } },
4574 { ISD::UADDSAT, MVT::i16, { 2, 3, 4, 7 } },
4575 { ISD::UADDSAT, MVT::i8, { 3, 3, 5, 8 } },
4576 { ISD::USUBSAT, MVT::i32, { 2, 3, 4, 7 } },
4577 { ISD::USUBSAT, MVT::i16, { 2, 3, 4, 7 } },
4578 { ISD::USUBSAT, MVT::i8, { 3, 3, 5, 8 } },
4579 { ISD::SMAX, MVT::i32, { 1, 2, 2, 3 } },
4580 { ISD::SMAX, MVT::i16, { 1, 4, 2, 4 } },
4581 { ISD::SMAX, MVT::i8, { 1, 4, 2, 4 } },
4582 { ISD::SMIN, MVT::i32, { 1, 2, 2, 3 } },
4583 { ISD::SMIN, MVT::i16, { 1, 4, 2, 4 } },
4584 { ISD::SMIN, MVT::i8, { 1, 4, 2, 4 } },
4585 { ISD::UMAX, MVT::i32, { 1, 2, 2, 3 } },
4586 { ISD::UMAX, MVT::i16, { 1, 4, 2, 4 } },
4587 { ISD::UMAX, MVT::i8, { 1, 4, 2, 4 } },
4588 { ISD::UMIN, MVT::i32, { 1, 2, 2, 3 } },
4589 { ISD::UMIN, MVT::i16, { 1, 4, 2, 4 } },
4590 { ISD::UMIN, MVT::i8, { 1, 4, 2, 4 } },
4591 { ISD::SADDO, MVT::i32, { 2, 2, 4, 6 } },
4592 { ISD::SADDO, MVT::i16, { 2, 2, 4, 6 } },
4593 { ISD::SADDO, MVT::i8, { 2, 2, 4, 6 } },
4594 { ISD::UADDO, MVT::i32, { 2, 2, 4, 6 } },
4595 { ISD::UADDO, MVT::i16, { 2, 2, 4, 6 } },
4596 { ISD::UADDO, MVT::i8, { 2, 2, 4, 6 } },
4597 { ISD::SMULO, MVT::i32, { 2, 2, 4, 6 } },
4598 { ISD::SMULO, MVT::i16, { 5, 5, 4, 6 } },
4599 { ISD::SMULO, MVT::i8, { 6, 6, 4, 6 } },
4600 { ISD::UMULO, MVT::i32, { 6, 6, 4, 8 } },
4601 { ISD::UMULO, MVT::i16, { 6, 6, 4, 9 } },
4602 { ISD::UMULO, MVT::i8, { 6, 6, 4, 6 } },
4603 };
4604
4605 Type *RetTy = ICA.getReturnType();
4606 Type *OpTy = RetTy;
4607 Intrinsic::ID IID = ICA.getID();
4608 unsigned ISD = ISD::DELETED_NODE;
4609 switch (IID) {
4610 default:
4611 break;
4612 case Intrinsic::abs:
4613 ISD = ISD::ABS;
4614 break;
4615 case Intrinsic::bitreverse:
4617 break;
4618 case Intrinsic::bswap:
4619 ISD = ISD::BSWAP;
4620 break;
4621 case Intrinsic::ctlz:
4622 ISD = ISD::CTLZ;
4623 break;
4624 case Intrinsic::ctpop:
4625 ISD = ISD::CTPOP;
4626 break;
4627 case Intrinsic::cttz:
4628 ISD = ISD::CTTZ;
4629 break;
4630 case Intrinsic::fshl:
4631 ISD = ISD::FSHL;
4632 if (!ICA.isTypeBasedOnly()) {
4633 const SmallVectorImpl<const Value *> &Args = ICA.getArgs();
4634 if (Args[0] == Args[1]) {
4635 ISD = ISD::ROTL;
4636 // Handle uniform constant rotation amounts.
4637 // TODO: Handle funnel-shift cases.
4638 const APInt *Amt;
4639 if (Args[2] &&
4641 ISD = X86ISD::VROTLI;
4642 }
4643 }
4644 break;
4645 case Intrinsic::fshr:
4646 // FSHR has same costs so don't duplicate.
4647 ISD = ISD::FSHL;
4648 if (!ICA.isTypeBasedOnly()) {
4649 const SmallVectorImpl<const Value *> &Args = ICA.getArgs();
4650 if (Args[0] == Args[1]) {
4651 ISD = ISD::ROTR;
4652 // Handle uniform constant rotation amount.
4653 // TODO: Handle funnel-shift cases.
4654 const APInt *Amt;
4655 if (Args[2] &&
4657 ISD = X86ISD::VROTLI;
4658 }
4659 }
4660 break;
4661 case Intrinsic::lrint:
4662 case Intrinsic::llrint: {
4663 // X86 can use the CVTP2SI instructions to lower lrint/llrint calls, which
4664 // have the same costs as the CVTTP2SI (fptosi) instructions
4665 const SmallVectorImpl<Type *> &ArgTys = ICA.getArgTypes();
4666 return getCastInstrCost(Instruction::FPToSI, RetTy, ArgTys[0],
4668 }
4669 case Intrinsic::maxnum:
4670 case Intrinsic::minnum:
4671 // FMINNUM has same costs so don't duplicate.
4672 ISD = ISD::FMAXNUM;
4673 break;
4674 case Intrinsic::sadd_sat:
4675 ISD = ISD::SADDSAT;
4676 break;
4677 case Intrinsic::smax:
4678 ISD = ISD::SMAX;
4679 break;
4680 case Intrinsic::smin:
4681 ISD = ISD::SMIN;
4682 break;
4683 case Intrinsic::ssub_sat:
4684 ISD = ISD::SSUBSAT;
4685 break;
4686 case Intrinsic::uadd_sat:
4687 ISD = ISD::UADDSAT;
4688 break;
4689 case Intrinsic::umax:
4690 ISD = ISD::UMAX;
4691 break;
4692 case Intrinsic::umin:
4693 ISD = ISD::UMIN;
4694 break;
4695 case Intrinsic::usub_sat:
4696 ISD = ISD::USUBSAT;
4697 break;
4698 case Intrinsic::sqrt:
4699 ISD = ISD::FSQRT;
4700 break;
4701 case Intrinsic::sadd_with_overflow:
4702 case Intrinsic::ssub_with_overflow:
4703 // SSUBO has same costs so don't duplicate.
4704 ISD = ISD::SADDO;
4705 OpTy = RetTy->getContainedType(0);
4706 break;
4707 case Intrinsic::uadd_with_overflow:
4708 case Intrinsic::usub_with_overflow:
4709 // USUBO has same costs so don't duplicate.
4710 ISD = ISD::UADDO;
4711 OpTy = RetTy->getContainedType(0);
4712 break;
4713 case Intrinsic::smul_with_overflow:
4714 ISD = ISD::SMULO;
4715 OpTy = RetTy->getContainedType(0);
4716 break;
4717 case Intrinsic::umul_with_overflow:
4718 ISD = ISD::UMULO;
4719 OpTy = RetTy->getContainedType(0);
4720 break;
4721 }
4722
4723 if (ISD != ISD::DELETED_NODE) {
4724 auto adjustTableCost = [&](int ISD, unsigned Cost,
4725 std::pair<InstructionCost, MVT> LT,
4727 InstructionCost LegalizationCost = LT.first;
4728 MVT MTy = LT.second;
4729
4730 // If there are no NANs to deal with, then these are reduced to a
4731 // single MIN** or MAX** instruction instead of the MIN/CMP/SELECT that we
4732 // assume is used in the non-fast case.
4733 if (ISD == ISD::FMAXNUM || ISD == ISD::FMINNUM) {
4734 if (FMF.noNaNs())
4735 return LegalizationCost * 1;
4736 }
4737
4738 // For cases where some ops can be folded into a load/store, assume free.
4739 if (MTy.isScalarInteger()) {
4740 if (ISD == ISD::BSWAP && ST->hasMOVBE() && ST->hasFastMOVBE()) {
4741 if (const Instruction *II = ICA.getInst()) {
4742 if (II->hasOneUse() && isa<StoreInst>(II->user_back()))
4743 return TTI::TCC_Free;
4744 if (auto *LI = dyn_cast<LoadInst>(II->getOperand(0))) {
4745 if (LI->hasOneUse())
4746 return TTI::TCC_Free;
4747 }
4748 }
4749 }
4750 }
4751
4752 return LegalizationCost * (int)Cost;
4753 };
4754
4755 // Legalize the type.
4756 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(OpTy);
4757 MVT MTy = LT.second;
4758
4759 // Without BMI/LZCNT see if we're only looking for a *_ZERO_POISON cost.
4760 if (((ISD == ISD::CTTZ && !ST->hasBMI()) ||
4761 (ISD == ISD::CTLZ && !ST->hasLZCNT())) &&
4762 !MTy.isVector() && !ICA.isTypeBasedOnly()) {
4763 const SmallVectorImpl<const Value *> &Args = ICA.getArgs();
4764 if (auto *Cst = dyn_cast<ConstantInt>(Args[1]))
4765 if (Cst->isAllOnesValue())
4766 ISD =
4768 }
4769
4770 // FSQRT is a single instruction.
4772 return LT.first;
4773
4774 if (ST->useGLMDivSqrtCosts())
4775 if (const auto *Entry = CostTableLookup(GLMCostTbl, ISD, MTy))
4776 if (auto KindCost = Entry->Cost[CostKind])
4777 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4778
4779 if (ST->useSLMArithCosts())
4780 if (const auto *Entry = CostTableLookup(SLMCostTbl, ISD, MTy))
4781 if (auto KindCost = Entry->Cost[CostKind])
4782 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4783
4784 if (ST->hasVBMI2())
4785 if (const auto *Entry = CostTableLookup(AVX512VBMI2CostTbl, ISD, MTy))
4786 if (auto KindCost = Entry->Cost[CostKind])
4787 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4788
4789 if (ST->hasBITALG())
4790 if (const auto *Entry = CostTableLookup(AVX512BITALGCostTbl, ISD, MTy))
4791 if (auto KindCost = Entry->Cost[CostKind])
4792 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4793
4794 if (ST->hasVPOPCNTDQ())
4795 if (const auto *Entry = CostTableLookup(AVX512VPOPCNTDQCostTbl, ISD, MTy))
4796 if (auto KindCost = Entry->Cost[CostKind])
4797 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4798
4799 if (ST->hasGFNI())
4800 if (const auto *Entry = CostTableLookup(GFNICostTbl, ISD, MTy))
4801 if (auto KindCost = Entry->Cost[CostKind])
4802 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4803
4804 if (ST->hasCDI())
4805 if (const auto *Entry = CostTableLookup(AVX512CDCostTbl, ISD, MTy))
4806 if (auto KindCost = Entry->Cost[CostKind])
4807 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4808
4809 if (ST->hasBWI())
4810 if (const auto *Entry = CostTableLookup(AVX512BWCostTbl, ISD, MTy))
4811 if (auto KindCost = Entry->Cost[CostKind])
4812 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4813
4814 if (ST->hasAVX512())
4815 if (const auto *Entry = CostTableLookup(AVX512CostTbl, ISD, MTy))
4816 if (auto KindCost = Entry->Cost[CostKind])
4817 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4818
4819 if (ST->hasXOP())
4820 if (const auto *Entry = CostTableLookup(XOPCostTbl, ISD, MTy))
4821 if (auto KindCost = Entry->Cost[CostKind])
4822 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4823
4824 if (ST->hasAVX2())
4825 if (const auto *Entry = CostTableLookup(AVX2CostTbl, ISD, MTy))
4826 if (auto KindCost = Entry->Cost[CostKind])
4827 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4828
4829 if (ST->hasAVX())
4830 if (const auto *Entry = CostTableLookup(AVX1CostTbl, ISD, MTy))
4831 if (auto KindCost = Entry->Cost[CostKind])
4832 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4833
4834 if (ST->hasSSE42())
4835 if (const auto *Entry = CostTableLookup(SSE42CostTbl, ISD, MTy))
4836 if (auto KindCost = Entry->Cost[CostKind])
4837 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4838
4839 if (ST->hasSSE41())
4840 if (const auto *Entry = CostTableLookup(SSE41CostTbl, ISD, MTy))
4841 if (auto KindCost = Entry->Cost[CostKind])
4842 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4843
4844 if (ST->hasSSSE3())
4845 if (const auto *Entry = CostTableLookup(SSSE3CostTbl, ISD, MTy))
4846 if (auto KindCost = Entry->Cost[CostKind])
4847 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4848
4849 if (ST->hasSSE2())
4850 if (const auto *Entry = CostTableLookup(SSE2CostTbl, ISD, MTy))
4851 if (auto KindCost = Entry->Cost[CostKind])
4852 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4853
4854 if (ST->hasSSE1())
4855 if (const auto *Entry = CostTableLookup(SSE1CostTbl, ISD, MTy))
4856 if (auto KindCost = Entry->Cost[CostKind])
4857 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4858
4859 if (ST->hasBMI()) {
4860 if (ST->is64Bit())
4861 if (const auto *Entry = CostTableLookup(BMI64CostTbl, ISD, MTy))
4862 if (auto KindCost = Entry->Cost[CostKind])
4863 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4864
4865 if (const auto *Entry = CostTableLookup(BMI32CostTbl, ISD, MTy))
4866 if (auto KindCost = Entry->Cost[CostKind])
4867 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4868 }
4869
4870 if (ST->hasLZCNT()) {
4871 if (ST->is64Bit())
4872 if (const auto *Entry = CostTableLookup(LZCNT64CostTbl, ISD, MTy))
4873 if (auto KindCost = Entry->Cost[CostKind])
4874 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4875
4876 if (const auto *Entry = CostTableLookup(LZCNT32CostTbl, ISD, MTy))
4877 if (auto KindCost = Entry->Cost[CostKind])
4878 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4879 }
4880
4881 if (ST->hasPOPCNT()) {
4882 if (ST->is64Bit())
4883 if (const auto *Entry = CostTableLookup(POPCNT64CostTbl, ISD, MTy))
4884 if (auto KindCost = Entry->Cost[CostKind])
4885 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4886
4887 if (const auto *Entry = CostTableLookup(POPCNT32CostTbl, ISD, MTy))
4888 if (auto KindCost = Entry->Cost[CostKind])
4889 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4890 }
4891
4892 if (ST->is64Bit())
4893 if (const auto *Entry = CostTableLookup(X64CostTbl, ISD, MTy))
4894 if (auto KindCost = Entry->Cost[CostKind])
4895 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4896
4897 if (const auto *Entry = CostTableLookup(X86CostTbl, ISD, MTy))
4898 if (auto KindCost = Entry->Cost[CostKind])
4899 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4900
4901 // Without arg data, we need to compute the expanded costs of custom lowered
4902 // intrinsics to prevent use of the (very low) default costs.
4903 if (ICA.isTypeBasedOnly() &&
4904 (IID == Intrinsic::fshl || IID == Intrinsic::fshr)) {
4905 Type *CondTy = RetTy->getWithNewBitWidth(1);
4907 Cost += getArithmeticInstrCost(BinaryOperator::Or, RetTy, CostKind);
4908 Cost += getArithmeticInstrCost(BinaryOperator::Sub, RetTy, CostKind);
4909 Cost += getArithmeticInstrCost(BinaryOperator::Shl, RetTy, CostKind);
4910 Cost += getArithmeticInstrCost(BinaryOperator::LShr, RetTy, CostKind);
4911 Cost += getArithmeticInstrCost(BinaryOperator::And, RetTy, CostKind);
4912 Cost += getCmpSelInstrCost(BinaryOperator::ICmp, RetTy, CondTy,
4914 Cost += getCmpSelInstrCost(BinaryOperator::Select, RetTy, CondTy,
4916 return Cost;
4917 }
4918 }
4919
4921}
4922
4924 unsigned Opcode, Type *Val, TTI::TargetCostKind CostKind, unsigned Index,
4925 const Value *Op0, const Value *Op1, TTI::VectorInstrContext VIC) const {
4926 static const CostTblEntry SLMCostTbl[] = {
4927 { ISD::EXTRACT_VECTOR_ELT, MVT::i8, 4 },
4928 { ISD::EXTRACT_VECTOR_ELT, MVT::i16, 4 },
4929 { ISD::EXTRACT_VECTOR_ELT, MVT::i32, 4 },
4930 { ISD::EXTRACT_VECTOR_ELT, MVT::i64, 7 }
4931 };
4932
4933 assert(Val->isVectorTy() && "This must be a vector type");
4934 auto *VT = cast<VectorType>(Val);
4935 if (VT->isScalableTy())
4937
4938 Type *ScalarType = Val->getScalarType();
4939 InstructionCost RegisterFileMoveCost = 0;
4940
4941 // Non-immediate extraction/insertion can be handled as a sequence of
4942 // aliased loads+stores via the stack.
4943 if (Index == -1U && (Opcode == Instruction::ExtractElement ||
4944 Opcode == Instruction::InsertElement)) {
4945 // TODO: On some SSE41+ targets, we expand to cmp+splat+select patterns:
4946 // inselt N0, N1, N2 --> select (SplatN2 == {0,1,2...}) ? SplatN1 : N0.
4947
4948 // TODO: Move this to BasicTTIImpl.h? We'd need better gep + index handling.
4949 assert(isa<FixedVectorType>(Val) && "Fixed vector type expected");
4950 Align VecAlign = DL.getPrefTypeAlign(Val);
4951 Align SclAlign = DL.getPrefTypeAlign(ScalarType);
4952
4953 // Extract - store vector to stack, load scalar.
4954 if (Opcode == Instruction::ExtractElement) {
4955 return getMemoryOpCost(Instruction::Store, Val, VecAlign, 0, CostKind) +
4956 getMemoryOpCost(Instruction::Load, ScalarType, SclAlign, 0,
4957 CostKind);
4958 }
4959 // Insert - store vector to stack, store scalar, load vector.
4960 if (Opcode == Instruction::InsertElement) {
4961 return getMemoryOpCost(Instruction::Store, Val, VecAlign, 0, CostKind) +
4962 getMemoryOpCost(Instruction::Store, ScalarType, SclAlign, 0,
4963 CostKind) +
4964 getMemoryOpCost(Instruction::Load, Val, VecAlign, 0, CostKind);
4965 }
4966 }
4967
4968 if (Index != -1U && (Opcode == Instruction::ExtractElement ||
4969 Opcode == Instruction::InsertElement)) {
4970 // Extraction of vXi1 elements are now efficiently handled by MOVMSK.
4971 if (Opcode == Instruction::ExtractElement &&
4972 ScalarType->getScalarSizeInBits() == 1 &&
4973 cast<FixedVectorType>(Val)->getNumElements() > 1)
4974 return 1;
4975
4976 // Legalize the type.
4977 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Val);
4978
4979 // This type is legalized to a scalar type.
4980 if (!LT.second.isVector())
4981 return TTI::TCC_Free;
4982
4983 // The type may be split. Normalize the index to the new type.
4984 unsigned SizeInBits = LT.second.getSizeInBits();
4985 unsigned NumElts = LT.second.getVectorNumElements();
4986 unsigned SubNumElts = NumElts;
4987 Index = Index % NumElts;
4988
4989 // For >128-bit vectors, we need to extract higher 128-bit subvectors.
4990 // For inserts, we also need to insert the subvector back.
4991 if (SizeInBits > 128) {
4992 assert((SizeInBits % 128) == 0 && "Illegal vector");
4993 unsigned NumSubVecs = SizeInBits / 128;
4994 SubNumElts = NumElts / NumSubVecs;
4995 if (SubNumElts <= Index) {
4996 RegisterFileMoveCost += (Opcode == Instruction::InsertElement ? 2 : 1);
4997 Index %= SubNumElts;
4998 }
4999 }
5000
5001 MVT MScalarTy = LT.second.getScalarType();
5002 auto IsCheapPInsrPExtrInsertPS = [&]() {
5003 // Assume pinsr/pextr XMM <-> GPR is relatively cheap on all targets.
5004 // Inserting f32 into index0 is just movss.
5005 // Also, assume insertps is relatively cheap on all >= SSE41 targets.
5006 return (MScalarTy == MVT::i16 && ST->hasSSE2()) ||
5007 (MScalarTy.isInteger() && ST->hasSSE41()) ||
5008 (MScalarTy == MVT::f32 && ST->hasSSE1() && Index == 0 &&
5009 Opcode == Instruction::InsertElement) ||
5010 (MScalarTy == MVT::f32 && ST->hasSSE41() &&
5011 Opcode == Instruction::InsertElement);
5012 };
5013
5014 if (Index == 0) {
5015 // Floating point scalars are already located in index #0.
5016 // Many insertions to #0 can fold away for scalar fp-ops, so let's assume
5017 // true for all.
5018 if (ScalarType->isFloatingPointTy() &&
5019 (Opcode != Instruction::InsertElement || !Op0 ||
5020 isa<UndefValue>(Op0)))
5021 return RegisterFileMoveCost;
5022
5023 if (Opcode == Instruction::InsertElement &&
5025 // Consider the gather cost to be cheap.
5027 return RegisterFileMoveCost;
5028 if (!IsCheapPInsrPExtrInsertPS()) {
5029 // mov constant-to-GPR + movd/movq GPR -> XMM.
5030 if (isa_and_nonnull<Constant>(Op1) && Op1->getType()->isIntegerTy())
5031 return 2 + RegisterFileMoveCost;
5032 // Assume movd/movq GPR -> XMM is relatively cheap on all targets.
5033 return 1 + RegisterFileMoveCost;
5034 }
5035 }
5036
5037 // Assume movd/movq XMM -> GPR is relatively cheap on all targets.
5038 if (ScalarType->isIntegerTy() && Opcode == Instruction::ExtractElement)
5039 return 1 + RegisterFileMoveCost;
5040 }
5041
5042 int ISD = TLI->InstructionOpcodeToISD(Opcode);
5043 assert(ISD && "Unexpected vector opcode");
5044 if (ST->useSLMArithCosts())
5045 if (auto *Entry = CostTableLookup(SLMCostTbl, ISD, MScalarTy))
5046 return Entry->Cost + RegisterFileMoveCost;
5047
5048 // Consider cheap cases.
5049 if (IsCheapPInsrPExtrInsertPS())
5050 return 1 + RegisterFileMoveCost;
5051
5052 // For extractions we just need to shuffle the element to index 0, which
5053 // should be very cheap (assume cost = 1). For insertions we need to shuffle
5054 // the elements to its destination. In both cases we must handle the
5055 // subvector move(s).
5056 // If the vector type is already less than 128-bits then don't reduce it.
5057 // TODO: Under what circumstances should we shuffle using the full width?
5058 InstructionCost ShuffleCost = 1;
5059 if (Opcode == Instruction::InsertElement) {
5060 auto *SubTy = cast<VectorType>(Val);
5061 EVT VT = TLI->getValueType(DL, Val);
5062 if (VT.getScalarType() != MScalarTy || VT.getSizeInBits() >= 128)
5063 SubTy = FixedVectorType::get(ScalarType, SubNumElts);
5064 ShuffleCost = getShuffleCost(TTI::SK_PermuteTwoSrc, SubTy, SubTy, {},
5065 CostKind, 0, SubTy);
5066 }
5067 int IntOrFpCost = ScalarType->isFloatingPointTy() ? 0 : 1;
5068 return ShuffleCost + IntOrFpCost + RegisterFileMoveCost;
5069 }
5070
5071 return BaseT::getVectorInstrCost(Opcode, Val, CostKind, Index, Op0, Op1,
5072 VIC) +
5073 RegisterFileMoveCost;
5074}
5075
5077 VectorType *Ty, const APInt &DemandedElts, bool Insert, bool Extract,
5078 TTI::TargetCostKind CostKind, bool ForPoisonSrc, ArrayRef<Value *> VL,
5079 TTI::VectorInstrContext VIC) const {
5080 assert(DemandedElts.getBitWidth() ==
5081 cast<FixedVectorType>(Ty)->getNumElements() &&
5082 "Vector size mismatch");
5083
5084 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Ty);
5085 MVT MScalarTy = LT.second.getScalarType();
5086 unsigned LegalVectorBitWidth = LT.second.getSizeInBits();
5088
5089 constexpr unsigned LaneBitWidth = 128;
5090 assert((LegalVectorBitWidth < LaneBitWidth ||
5091 (LegalVectorBitWidth % LaneBitWidth) == 0) &&
5092 "Illegal vector");
5093
5094 const int NumLegalVectors = LT.first.getValue();
5095 assert(NumLegalVectors >= 0 && "Negative cost!");
5096
5097 // For insertions, a ISD::BUILD_VECTOR style vector initialization can be much
5098 // cheaper than an accumulation of ISD::INSERT_VECTOR_ELT. SLPVectorizer has
5099 // a special heuristic regarding poison input which is passed here in
5100 // ForPoisonSrc.
5101 if (Insert && !ForPoisonSrc) {
5102 // This is nearly identical to BaseT::getScalarizationOverhead(), except
5103 // it is passing nullptr to getVectorInstrCost() for Op0 (instead of
5104 // Constant::getNullValue()), which makes the X86TTIImpl
5105 // getVectorInstrCost() return 0 instead of 1.
5106 for (unsigned I : seq(DemandedElts.getBitWidth())) {
5107 if (!DemandedElts[I])
5108 continue;
5109 Cost += getVectorInstrCost(Instruction::InsertElement, Ty, CostKind, I,
5111 VL.empty() ? nullptr : VL[I],
5113 }
5114 return Cost;
5115 }
5116
5117 if (Insert) {
5118 if ((MScalarTy == MVT::i16 && ST->hasSSE2()) ||
5119 (MScalarTy.isInteger() && ST->hasSSE41()) ||
5120 (MScalarTy == MVT::f32 && ST->hasSSE41())) {
5121 // For types we can insert directly, insertion into 128-bit sub vectors is
5122 // cheap, followed by a cheap chain of concatenations.
5123 if (LegalVectorBitWidth <= LaneBitWidth) {
5124 Cost += BaseT::getScalarizationOverhead(Ty, DemandedElts, Insert,
5125 /*Extract*/ false, CostKind);
5126 } else {
5127 // In each 128-lane, if at least one index is demanded but not all
5128 // indices are demanded and this 128-lane is not the first 128-lane of
5129 // the legalized-vector, then this 128-lane needs a extracti128; If in
5130 // each 128-lane, there is at least one demanded index, this 128-lane
5131 // needs a inserti128.
5132
5133 // The following cases will help you build a better understanding:
5134 // Assume we insert several elements into a v8i32 vector in avx2,
5135 // Case#1: inserting into 1th index needs vpinsrd + inserti128.
5136 // Case#2: inserting into 5th index needs extracti128 + vpinsrd +
5137 // inserti128.
5138 // Case#3: inserting into 4,5,6,7 index needs 4*vpinsrd + inserti128.
5139 assert((LegalVectorBitWidth % LaneBitWidth) == 0 && "Illegal vector");
5140 unsigned NumLegalLanes = LegalVectorBitWidth / LaneBitWidth;
5141 unsigned NumLanesTotal = NumLegalLanes * NumLegalVectors;
5142 unsigned NumLegalElts =
5143 LT.second.getVectorNumElements() * NumLegalVectors;
5144 assert(NumLegalElts >= DemandedElts.getBitWidth() &&
5145 "Vector has been legalized to smaller element count");
5146 assert((NumLegalElts % NumLanesTotal) == 0 &&
5147 "Unexpected elts per lane");
5148 unsigned NumEltsPerLane = NumLegalElts / NumLanesTotal;
5149
5150 APInt WidenedDemandedElts = DemandedElts.zext(NumLegalElts);
5151 auto *LaneTy =
5152 FixedVectorType::get(Ty->getElementType(), NumEltsPerLane);
5153
5154 for (unsigned I = 0; I != NumLanesTotal; ++I) {
5155 APInt LaneEltMask = WidenedDemandedElts.extractBits(
5156 NumEltsPerLane, NumEltsPerLane * I);
5157 if (LaneEltMask.isZero())
5158 continue;
5159 // FIXME: we don't need to extract if all non-demanded elements
5160 // are legalization-inserted padding.
5161 if (!LaneEltMask.isAllOnes())
5163 CostKind, I * NumEltsPerLane, LaneTy);
5164 Cost += BaseT::getScalarizationOverhead(LaneTy, LaneEltMask, Insert,
5165 /*Extract*/ false, CostKind);
5166 }
5167
5168 APInt AffectedLanes =
5169 APIntOps::ScaleBitMask(WidenedDemandedElts, NumLanesTotal);
5170 APInt FullyAffectedLegalVectors = APIntOps::ScaleBitMask(
5171 AffectedLanes, NumLegalVectors, /*MatchAllBits=*/true);
5172 for (int LegalVec = 0; LegalVec != NumLegalVectors; ++LegalVec) {
5173 for (unsigned Lane = 0; Lane != NumLegalLanes; ++Lane) {
5174 unsigned I = NumLegalLanes * LegalVec + Lane;
5175 // No need to insert unaffected lane; or lane 0 of each legal vector
5176 // iff ALL lanes of that vector were affected and will be inserted.
5177 if (!AffectedLanes[I] ||
5178 (Lane == 0 && FullyAffectedLegalVectors[LegalVec]))
5179 continue;
5181 CostKind, I * NumEltsPerLane, LaneTy);
5182 }
5183 }
5184 }
5185 } else if (LT.second.isVector()) {
5186 // Without fast insertion, we need to use MOVD/MOVQ to pass each demanded
5187 // integer element as a SCALAR_TO_VECTOR, then we build the vector as a
5188 // series of UNPCK followed by CONCAT_VECTORS - all of these can be
5189 // considered cheap.
5190 if (Ty->isIntOrIntVectorTy())
5191 Cost += DemandedElts.popcount();
5192
5193 // Get the smaller of the legalized or original pow2-extended number of
5194 // vector elements, which represents the number of unpacks we'll end up
5195 // performing.
5196 unsigned NumElts = LT.second.getVectorNumElements();
5197 unsigned Pow2Elts =
5198 PowerOf2Ceil(cast<FixedVectorType>(Ty)->getNumElements());
5199 Cost += (std::min<unsigned>(NumElts, Pow2Elts) - 1) * LT.first;
5200 }
5201 }
5202
5203 if (Extract) {
5204 // vXi1 can be efficiently extracted with MOVMSK.
5205 // TODO: AVX512 predicate mask handling.
5206 // NOTE: This doesn't work well for roundtrip scalarization.
5207 if (!Insert && Ty->getScalarSizeInBits() == 1 && !ST->hasAVX512()) {
5208 unsigned NumElts = cast<FixedVectorType>(Ty)->getNumElements();
5209 unsigned MaxElts = ST->hasAVX2() ? 32 : 16;
5210 unsigned MOVMSKCost = (NumElts + MaxElts - 1) / MaxElts;
5211 return MOVMSKCost;
5212 }
5213
5214 if (LT.second.isVector()) {
5215 unsigned NumLegalElts =
5216 LT.second.getVectorNumElements() * NumLegalVectors;
5217 assert(NumLegalElts >= DemandedElts.getBitWidth() &&
5218 "Vector has been legalized to smaller element count");
5219
5220 // If we're extracting elements from a 128-bit subvector lane,
5221 // we only need to extract each lane once, not for every element.
5222 if (LegalVectorBitWidth > LaneBitWidth) {
5223 unsigned NumLegalLanes = LegalVectorBitWidth / LaneBitWidth;
5224 unsigned NumLanesTotal = NumLegalLanes * NumLegalVectors;
5225 assert((NumLegalElts % NumLanesTotal) == 0 &&
5226 "Unexpected elts per lane");
5227 unsigned NumEltsPerLane = NumLegalElts / NumLanesTotal;
5228
5229 // Add cost for each demanded 128-bit subvector extraction.
5230 // Luckily this is a lot easier than for insertion.
5231 APInt WidenedDemandedElts = DemandedElts.zext(NumLegalElts);
5232 auto *LaneTy =
5233 FixedVectorType::get(Ty->getElementType(), NumEltsPerLane);
5234
5235 for (unsigned I = 0; I != NumLanesTotal; ++I) {
5236 APInt LaneEltMask = WidenedDemandedElts.extractBits(
5237 NumEltsPerLane, I * NumEltsPerLane);
5238 if (LaneEltMask.isZero())
5239 continue;
5241 I * NumEltsPerLane, LaneTy);
5243 LaneTy, LaneEltMask, /*Insert*/ false, Extract, CostKind);
5244 }
5245
5246 return Cost;
5247 }
5248 }
5249
5250 // Fallback to default extraction.
5251 Cost += BaseT::getScalarizationOverhead(Ty, DemandedElts, /*Insert*/ false,
5252 Extract, CostKind);
5253 }
5254
5255 return Cost;
5256}
5257
5259X86TTIImpl::getReplicationShuffleCost(Type *EltTy, int ReplicationFactor,
5260 int VF, const APInt &DemandedDstElts,
5262 const unsigned EltTyBits = DL.getTypeSizeInBits(EltTy);
5263 // We don't differentiate element types here, only element bit width.
5264 EltTy = IntegerType::getIntNTy(EltTy->getContext(), EltTyBits);
5265
5266 auto bailout = [&]() {
5267 return BaseT::getReplicationShuffleCost(EltTy, ReplicationFactor, VF,
5268 DemandedDstElts, CostKind);
5269 };
5270
5271 // For now, only deal with AVX512 cases.
5272 if (!ST->hasAVX512())
5273 return bailout();
5274
5275 // Do we have a native shuffle for this element type, or should we promote?
5276 unsigned PromEltTyBits = EltTyBits;
5277 switch (EltTyBits) {
5278 case 32:
5279 case 64:
5280 break; // AVX512F.
5281 case 16:
5282 if (!ST->hasBWI())
5283 PromEltTyBits = 32; // promote to i32, AVX512F.
5284 break; // AVX512BW
5285 case 8:
5286 if (!ST->hasVBMI())
5287 PromEltTyBits = 32; // promote to i32, AVX512F.
5288 break; // AVX512VBMI
5289 case 1:
5290 // There is no support for shuffling i1 elements. We *must* promote.
5291 if (ST->hasBWI()) {
5292 if (ST->hasVBMI())
5293 PromEltTyBits = 8; // promote to i8, AVX512VBMI.
5294 else
5295 PromEltTyBits = 16; // promote to i16, AVX512BW.
5296 break;
5297 }
5298 PromEltTyBits = 32; // promote to i32, AVX512F.
5299 break;
5300 default:
5301 return bailout();
5302 }
5303 auto *PromEltTy = IntegerType::getIntNTy(EltTy->getContext(), PromEltTyBits);
5304
5305 auto *SrcVecTy = FixedVectorType::get(EltTy, VF);
5306 auto *PromSrcVecTy = FixedVectorType::get(PromEltTy, VF);
5307
5308 int NumDstElements = VF * ReplicationFactor;
5309 auto *PromDstVecTy = FixedVectorType::get(PromEltTy, NumDstElements);
5310 auto *DstVecTy = FixedVectorType::get(EltTy, NumDstElements);
5311
5312 // Legalize the types.
5313 MVT LegalSrcVecTy = getTypeLegalizationCost(SrcVecTy).second;
5314 MVT LegalPromSrcVecTy = getTypeLegalizationCost(PromSrcVecTy).second;
5315 MVT LegalPromDstVecTy = getTypeLegalizationCost(PromDstVecTy).second;
5316 MVT LegalDstVecTy = getTypeLegalizationCost(DstVecTy).second;
5317 // They should have legalized into vector types.
5318 if (!LegalSrcVecTy.isVector() || !LegalPromSrcVecTy.isVector() ||
5319 !LegalPromDstVecTy.isVector() || !LegalDstVecTy.isVector())
5320 return bailout();
5321
5322 if (PromEltTyBits != EltTyBits) {
5323 // If we have to perform the shuffle with wider elt type than our data type,
5324 // then we will first need to anyext (we don't care about the new bits)
5325 // the source elements, and then truncate Dst elements.
5326 InstructionCost PromotionCost;
5327 PromotionCost += getCastInstrCost(
5328 Instruction::SExt, /*Dst=*/PromSrcVecTy, /*Src=*/SrcVecTy,
5330 PromotionCost +=
5331 getCastInstrCost(Instruction::Trunc, /*Dst=*/DstVecTy,
5332 /*Src=*/PromDstVecTy,
5334 return PromotionCost + getReplicationShuffleCost(PromEltTy,
5335 ReplicationFactor, VF,
5336 DemandedDstElts, CostKind);
5337 }
5338
5339 assert(LegalSrcVecTy.getScalarSizeInBits() == EltTyBits &&
5340 LegalSrcVecTy.getScalarType() == LegalDstVecTy.getScalarType() &&
5341 "We expect that the legalization doesn't affect the element width, "
5342 "doesn't coalesce/split elements.");
5343
5344 unsigned NumEltsPerDstVec = LegalDstVecTy.getVectorNumElements();
5345 unsigned NumDstVectors =
5346 divideCeil(DstVecTy->getNumElements(), NumEltsPerDstVec);
5347
5348 auto *SingleDstVecTy = FixedVectorType::get(EltTy, NumEltsPerDstVec);
5349
5350 // Not all the produced Dst elements may be demanded. In our case,
5351 // given that a single Dst vector is formed by a single shuffle,
5352 // if all elements that will form a single Dst vector aren't demanded,
5353 // then we won't need to do that shuffle, so adjust the cost accordingly.
5354 APInt DemandedDstVectors = APIntOps::ScaleBitMask(
5355 DemandedDstElts.zext(NumDstVectors * NumEltsPerDstVec), NumDstVectors);
5356 unsigned NumDstVectorsDemanded = DemandedDstVectors.popcount();
5357
5358 InstructionCost SingleShuffleCost =
5359 getShuffleCost(TTI::SK_PermuteSingleSrc, SingleDstVecTy, SingleDstVecTy,
5360 /*Mask=*/{}, CostKind,
5361 /*Index=*/0, /*SubTp=*/nullptr);
5362 return NumDstVectorsDemanded * SingleShuffleCost;
5363}
5364
5366 Align Alignment,
5367 unsigned AddressSpace,
5369 TTI::OperandValueInfo OpInfo,
5370 const Instruction *I) const {
5371 // FIXME: Load latency isn't handled here
5372 if (Opcode == Instruction::Load && CostKind == TTI::TCK_Latency)
5373 return BaseT::getMemoryOpCost(Opcode, Src, Alignment, AddressSpace,
5374 CostKind, OpInfo, I);
5375
5376 // TODO: Handle other cost kinds.
5378 if (auto *SI = dyn_cast_or_null<StoreInst>(I)) {
5379 // Store instruction with index and scale costs 2 Uops.
5380 // Check the preceding GEP to identify non-const indices.
5381 if (auto *GEP = dyn_cast<GetElementPtrInst>(SI->getPointerOperand())) {
5382 if (!all_of(GEP->indices(), [](Value *V) { return isa<Constant>(V); }))
5383 return TTI::TCC_Basic * 2;
5384 }
5385 }
5386 return TTI::TCC_Basic;
5387 }
5388
5389 assert((Opcode == Instruction::Load || Opcode == Instruction::Store) &&
5390 "Invalid Opcode");
5391 // Type legalization can't handle structs
5392 if (TLI->getValueType(DL, Src, true) == MVT::Other)
5393 return BaseT::getMemoryOpCost(Opcode, Src, Alignment, AddressSpace,
5394 CostKind, OpInfo, I);
5395
5396 // Legalize the type.
5397 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Src);
5398
5399 auto *VTy = dyn_cast<FixedVectorType>(Src);
5400
5402
5403 // Add a cost for constant load to vector.
5404 if (Opcode == Instruction::Store && OpInfo.isConstant())
5405 Cost += getMemoryOpCost(Instruction::Load, Src, DL.getABITypeAlign(Src),
5406 /*AddressSpace=*/0, CostKind, OpInfo);
5407
5408 // Handle the simple case of non-vectors.
5409 // NOTE: this assumes that legalization never creates vector from scalars!
5410 if (!VTy || !LT.second.isVector()) {
5411 // Each load/store unit costs 1.
5412 return (LT.second.isFloatingPoint() ? Cost : 0) + LT.first * 1;
5413 }
5414
5415 bool IsLoad = Opcode == Instruction::Load;
5416
5417 Type *EltTy = VTy->getElementType();
5418
5419 const int EltTyBits = DL.getTypeSizeInBits(EltTy);
5420
5421 // Source of truth: how many elements were there in the original IR vector?
5422 const unsigned SrcNumElt = VTy->getNumElements();
5423
5424 // How far have we gotten?
5425 int NumEltRemaining = SrcNumElt;
5426 // Note that we intentionally capture by-reference, NumEltRemaining changes.
5427 auto NumEltDone = [&]() { return SrcNumElt - NumEltRemaining; };
5428
5429 const int MaxLegalOpSizeBytes = divideCeil(LT.second.getSizeInBits(), 8);
5430
5431 // Note that even if we can store 64 bits of an XMM, we still operate on XMM.
5432 const unsigned XMMBits = 128;
5433 if (XMMBits % EltTyBits != 0)
5434 // Vector size must be a multiple of the element size. I.e. no padding.
5435 return BaseT::getMemoryOpCost(Opcode, Src, Alignment, AddressSpace,
5436 CostKind, OpInfo, I);
5437 const int NumEltPerXMM = XMMBits / EltTyBits;
5438
5439 auto *XMMVecTy = FixedVectorType::get(EltTy, NumEltPerXMM);
5440
5441 for (int CurrOpSizeBytes = MaxLegalOpSizeBytes, SubVecEltsLeft = 0;
5442 NumEltRemaining > 0; CurrOpSizeBytes /= 2) {
5443 // How many elements would a single op deal with at once?
5444 if ((8 * CurrOpSizeBytes) % EltTyBits != 0)
5445 // Vector size must be a multiple of the element size. I.e. no padding.
5446 return BaseT::getMemoryOpCost(Opcode, Src, Alignment, AddressSpace,
5447 CostKind, OpInfo, I);
5448 int CurrNumEltPerOp = (8 * CurrOpSizeBytes) / EltTyBits;
5449
5450 assert(CurrOpSizeBytes > 0 && CurrNumEltPerOp > 0 && "How'd we get here?");
5451 assert((((NumEltRemaining * EltTyBits) < (2 * 8 * CurrOpSizeBytes)) ||
5452 (CurrOpSizeBytes == MaxLegalOpSizeBytes)) &&
5453 "Unless we haven't halved the op size yet, "
5454 "we have less than two op's sized units of work left.");
5455
5456 auto *CurrVecTy = CurrNumEltPerOp > NumEltPerXMM
5457 ? FixedVectorType::get(EltTy, CurrNumEltPerOp)
5458 : XMMVecTy;
5459
5460 assert(CurrVecTy->getNumElements() % CurrNumEltPerOp == 0 &&
5461 "After halving sizes, the vector elt count is no longer a multiple "
5462 "of number of elements per operation?");
5463 auto *CoalescedVecTy =
5464 CurrNumEltPerOp == 1
5465 ? CurrVecTy
5467 IntegerType::get(Src->getContext(),
5468 EltTyBits * CurrNumEltPerOp),
5469 CurrVecTy->getNumElements() / CurrNumEltPerOp);
5470 assert(DL.getTypeSizeInBits(CoalescedVecTy) ==
5471 DL.getTypeSizeInBits(CurrVecTy) &&
5472 "coalesciing elements doesn't change vector width.");
5473
5474 while (NumEltRemaining > 0) {
5475 assert(SubVecEltsLeft >= 0 && "Subreg element count overconsumtion?");
5476
5477 // Can we use this vector size, as per the remaining element count?
5478 // Iff the vector is naturally aligned, we can do a wide load regardless.
5479 if (NumEltRemaining < CurrNumEltPerOp &&
5480 (!IsLoad || Alignment < CurrOpSizeBytes) && CurrOpSizeBytes != 1)
5481 break; // Try smalled vector size.
5482
5483 // This isn't exactly right. We're using slow unaligned 32-byte accesses
5484 // as a proxy for a double-pumped AVX memory interface such as on
5485 // Sandybridge.
5486 // Sub-32-bit loads/stores will be slower either with PINSR*/PEXTR* or
5487 // will be scalarized.
5488 if (CurrOpSizeBytes == 32 && ST->isUnalignedMem32Slow())
5489 Cost += 2;
5490 else if (CurrOpSizeBytes < 4)
5491 Cost += 2;
5492 else
5493 Cost += 1;
5494
5495 // If we're loading a uniform value, then we don't need to split the load,
5496 // loading just a single (widest) vector can be reused by all splits.
5497 if (IsLoad && OpInfo.isUniform())
5498 return Cost;
5499
5500 bool Is0thSubVec = (NumEltDone() % LT.second.getVectorNumElements()) == 0;
5501
5502 // If we have fully processed the previous reg, we need to replenish it.
5503 if (SubVecEltsLeft == 0) {
5504 SubVecEltsLeft += CurrVecTy->getNumElements();
5505 // And that's free only for the 0'th subvector of a legalized vector.
5506 if (!Is0thSubVec)
5507 Cost +=
5510 VTy, VTy, {}, CostKind, NumEltDone(), CurrVecTy);
5511 }
5512
5513 // While we can directly load/store ZMM, YMM, and 64-bit halves of XMM,
5514 // for smaller widths (32/16/8) we have to insert/extract them separately.
5515 // Again, it's free for the 0'th subreg (if op is 32/64 bit wide,
5516 // but let's pretend that it is also true for 16/8 bit wide ops...)
5517 if (CurrOpSizeBytes <= 32 / 8 && !Is0thSubVec) {
5518 int NumEltDoneInCurrXMM = NumEltDone() % NumEltPerXMM;
5519 assert(NumEltDoneInCurrXMM % CurrNumEltPerOp == 0 && "");
5520 int CoalescedVecEltIdx = NumEltDoneInCurrXMM / CurrNumEltPerOp;
5521 APInt DemandedElts =
5522 APInt::getBitsSet(CoalescedVecTy->getNumElements(),
5523 CoalescedVecEltIdx, CoalescedVecEltIdx + 1);
5524 assert(DemandedElts.popcount() == 1 && "Inserting single value");
5525 Cost += getScalarizationOverhead(CoalescedVecTy, DemandedElts, IsLoad,
5526 !IsLoad, CostKind);
5527 }
5528
5529 SubVecEltsLeft -= CurrNumEltPerOp;
5530 NumEltRemaining -= CurrNumEltPerOp;
5531 Alignment = commonAlignment(Alignment, CurrOpSizeBytes);
5532 }
5533 }
5534
5535 assert(NumEltRemaining <= 0 && "Should have processed all the elements.");
5536
5537 return Cost;
5538}
5539
5543 switch (MICA.getID()) {
5544 case Intrinsic::masked_scatter:
5545 case Intrinsic::masked_gather:
5546 return getGatherScatterOpCost(MICA, CostKind);
5547 case Intrinsic::masked_load:
5548 case Intrinsic::masked_store:
5549 return getMaskedMemoryOpCost(MICA, CostKind);
5550 }
5552}
5553
5557 unsigned Opcode = MICA.getID() == Intrinsic::masked_load ? Instruction::Load
5558 : Instruction::Store;
5559 Type *SrcTy = MICA.getDataType();
5560 Align Alignment = MICA.getAlignment();
5561 unsigned AddressSpace = MICA.getAddressSpace();
5562
5563 bool IsLoad = (Instruction::Load == Opcode);
5564 bool IsStore = (Instruction::Store == Opcode);
5565
5566 auto *SrcVTy = dyn_cast<FixedVectorType>(SrcTy);
5567 if (!SrcVTy)
5568 // To calculate scalar take the regular cost, without mask
5569 return getMemoryOpCost(Opcode, SrcTy, Alignment, AddressSpace, CostKind);
5570
5571 unsigned NumElem = SrcVTy->getNumElements();
5572 auto *MaskTy =
5573 FixedVectorType::get(Type::getInt8Ty(SrcVTy->getContext()), NumElem);
5574 if ((IsLoad && !isLegalMaskedLoad(SrcVTy, Alignment, AddressSpace)) ||
5575 (IsStore && !isLegalMaskedStore(SrcVTy, Alignment, AddressSpace))) {
5576 // Scalarization
5577 APInt DemandedElts = APInt::getAllOnes(NumElem);
5579 MaskTy, DemandedElts, /*Insert*/ false, /*Extract*/ true, CostKind);
5580 InstructionCost ScalarCompareCost = getCmpSelInstrCost(
5581 Instruction::ICmp, Type::getInt8Ty(SrcVTy->getContext()), nullptr,
5583 InstructionCost BranchCost = getCFInstrCost(Instruction::CondBr, CostKind);
5584 InstructionCost MaskCmpCost = NumElem * (BranchCost + ScalarCompareCost);
5586 SrcVTy, DemandedElts, IsLoad, IsStore, CostKind);
5587 InstructionCost MemopCost =
5588 NumElem * BaseT::getMemoryOpCost(Opcode, SrcVTy->getScalarType(),
5589 Alignment, AddressSpace, CostKind);
5590 return MemopCost + ValueSplitCost + MaskSplitCost + MaskCmpCost;
5591 }
5592
5593 // Legalize the type.
5594 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(SrcVTy);
5595 auto VT = TLI->getValueType(DL, SrcVTy);
5597 MVT Ty = LT.second;
5598 if (Ty == MVT::i16 || Ty == MVT::i32 || Ty == MVT::i64)
5599 // APX masked load/store for scalar is cheap.
5600 return Cost + LT.first;
5601
5602 if (VT.isSimple() && Ty != VT.getSimpleVT() &&
5603 LT.second.getVectorNumElements() == NumElem)
5604 // Promotion requires extend/truncate for data and a shuffle for mask.
5605 Cost += getShuffleCost(TTI::SK_PermuteTwoSrc, SrcVTy, SrcVTy, {}, CostKind,
5606 0, nullptr) +
5607 getShuffleCost(TTI::SK_PermuteTwoSrc, MaskTy, MaskTy, {}, CostKind,
5608 0, nullptr);
5609
5610 else if (LT.first * Ty.getVectorNumElements() > NumElem) {
5611 auto *NewMaskTy = FixedVectorType::get(MaskTy->getElementType(),
5612 (unsigned)LT.first.getValue() *
5613 Ty.getVectorNumElements());
5614 // Expanding requires fill mask with zeroes
5615 Cost += getShuffleCost(TTI::SK_InsertSubvector, NewMaskTy, NewMaskTy, {},
5616 CostKind, 0, MaskTy);
5617 }
5618
5619 // Pre-AVX512 - each maskmov load costs 2 + store costs ~8.
5620 if (!ST->hasAVX512())
5621 return Cost + LT.first * (IsLoad ? 2 : 8);
5622
5623 // AVX-512 masked load/store is cheaper
5624 return Cost + LT.first;
5625}
5626
5628 ArrayRef<const Value *> Ptrs, const Value *Base,
5629 const TTI::PointersChainInfo &Info, Type *AccessTy,
5631 if (Info.isSameBase() && Info.isKnownStride()) {
5632 // If all the pointers have known stride all the differences are translated
5633 // into constants. X86 memory addressing allows encoding it into
5634 // displacement. So we just need to take the base GEP cost.
5635 if (const auto *BaseGEP = dyn_cast<GetElementPtrInst>(Base)) {
5636 SmallVector<const Value *> Indices(BaseGEP->indices());
5637 return getGEPCost(BaseGEP->getSourceElementType(),
5638 BaseGEP->getPointerOperand(), Indices, nullptr,
5639 CostKind);
5640 }
5641 return TTI::TCC_Free;
5642 }
5643 return BaseT::getPointersChainCost(Ptrs, Base, Info, AccessTy, CostKind);
5644}
5645
5648 const SCEV *Ptr,
5650 // Address computations in vectorized code with non-consecutive addresses will
5651 // likely result in more instructions compared to scalar code where the
5652 // computation can more often be merged into the index mode. The resulting
5653 // extra micro-ops can significantly decrease throughput.
5654 const unsigned NumVectorInstToHideOverhead = 10;
5655
5656 // Cost modeling of Strided Access Computation is hidden by the indexing
5657 // modes of X86 regardless of the stride value. We dont believe that there
5658 // is a difference between constant strided access in gerenal and constant
5659 // strided value which is less than or equal to 64.
5660 // Even in the case of (loop invariant) stride whose value is not known at
5661 // compile time, the address computation will not incur more than one extra
5662 // ADD instruction.
5663 if (PtrTy->isVectorTy() && SE && !ST->hasAVX2()) {
5664 // TODO: AVX2 is the current cut-off because we don't have correct
5665 // interleaving costs for prior ISA's.
5666 if (!BaseT::isStridedAccess(Ptr))
5667 return NumVectorInstToHideOverhead;
5668 if (!BaseT::getConstantStrideStep(SE, Ptr))
5669 return 1;
5670 }
5671
5672 return BaseT::getAddressComputationCost(PtrTy, SE, Ptr, CostKind);
5673}
5674
5677 std::optional<FastMathFlags> FMF,
5680 return BaseT::getArithmeticReductionCost(Opcode, ValTy, FMF, CostKind);
5681
5682 // We use the Intel Architecture Code Analyzer(IACA) to measure the throughput
5683 // and make it as the cost.
5684
5685 static const CostTblEntry SLMCostTbl[] = {
5686 { ISD::FADD, MVT::v2f64, 3 },
5687 { ISD::ADD, MVT::v2i64, 5 },
5688 };
5689
5690 static const CostTblEntry SSE2CostTbl[] = {
5691 { ISD::FADD, MVT::v2f64, 2 },
5692 { ISD::FADD, MVT::v2f32, 2 },
5693 { ISD::FADD, MVT::v4f32, 4 },
5694 { ISD::ADD, MVT::v2i64, 2 }, // The data reported by the IACA tool is "1.6".
5695 { ISD::ADD, MVT::v2i32, 2 }, // FIXME: chosen to be less than v4i32
5696 { ISD::ADD, MVT::v4i32, 3 }, // The data reported by the IACA tool is "3.3".
5697 { ISD::ADD, MVT::v2i16, 2 }, // The data reported by the IACA tool is "4.3".
5698 { ISD::ADD, MVT::v4i16, 3 }, // The data reported by the IACA tool is "4.3".
5699 { ISD::ADD, MVT::v8i16, 4 }, // The data reported by the IACA tool is "4.3".
5700 { ISD::ADD, MVT::v2i8, 2 },
5701 { ISD::ADD, MVT::v4i8, 2 },
5702 { ISD::ADD, MVT::v8i8, 2 },
5703 { ISD::ADD, MVT::v16i8, 3 },
5704 };
5705
5706 static const CostTblEntry AVX1CostTbl[] = {
5707 { ISD::FADD, MVT::v4f64, 3 },
5708 { ISD::FADD, MVT::v4f32, 3 },
5709 { ISD::FADD, MVT::v8f32, 4 },
5710 { ISD::ADD, MVT::v2i64, 1 }, // The data reported by the IACA tool is "1.5".
5711 { ISD::ADD, MVT::v4i64, 3 },
5712 { ISD::ADD, MVT::v8i32, 5 },
5713 { ISD::ADD, MVT::v16i16, 5 },
5714 { ISD::ADD, MVT::v32i8, 4 },
5715 };
5716
5717 static const CostTblEntry AVX512FCostTbl[] = {
5718 { ISD::FADD, MVT::v8f64, 4 },
5719 { ISD::FADD, MVT::v16f32, 5 },
5720 { ISD::ADD, MVT::v8i64, 4 },
5721 { ISD::ADD, MVT::v16i32, 6 },
5722 };
5723
5724 static const CostTblEntry AVX512BWCostTbl[] = {
5725 { ISD::ADD, MVT::v32i16, 7 },
5726 { ISD::ADD, MVT::v64i8, 4 },
5727 };
5728
5729 int ISD = TLI->InstructionOpcodeToISD(Opcode);
5730 assert(ISD && "Invalid opcode");
5731
5732 // Before legalizing the type, give a chance to look up illegal narrow types
5733 // in the table.
5734 // FIXME: Is there a better way to do this?
5735 EVT VT = TLI->getValueType(DL, ValTy);
5736 if (VT.isSimple()) {
5737 MVT MTy = VT.getSimpleVT();
5738 if (ST->useSLMArithCosts())
5739 if (const auto *Entry = CostTableLookup(SLMCostTbl, ISD, MTy))
5740 return Entry->Cost;
5741
5742 if (ST->hasBWI())
5743 if (const auto *Entry = CostTableLookup(AVX512BWCostTbl, ISD, MTy))
5744 return Entry->Cost;
5745
5746 if (ST->hasAVX512())
5747 if (const auto *Entry = CostTableLookup(AVX512FCostTbl, ISD, MTy))
5748 return Entry->Cost;
5749
5750 if (ST->hasAVX())
5751 if (const auto *Entry = CostTableLookup(AVX1CostTbl, ISD, MTy))
5752 return Entry->Cost;
5753
5754 if (ST->hasSSE2())
5755 if (const auto *Entry = CostTableLookup(SSE2CostTbl, ISD, MTy))
5756 return Entry->Cost;
5757 }
5758
5759 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(ValTy);
5760
5761 MVT MTy = LT.second;
5762
5763 auto *ValVTy = cast<FixedVectorType>(ValTy);
5764
5765 // Special case: vXi8 mul reductions are performed as vXi16.
5766 if (ISD == ISD::MUL && MTy.getScalarType() == MVT::i8) {
5767 auto *WideSclTy = IntegerType::get(ValVTy->getContext(), 16);
5768 auto *WideVecTy = FixedVectorType::get(WideSclTy, ValVTy->getNumElements());
5769 return getCastInstrCost(Instruction::ZExt, WideVecTy, ValTy,
5771 CostKind) +
5772 getArithmeticReductionCost(Opcode, WideVecTy, FMF, CostKind);
5773 }
5774
5775 InstructionCost ArithmeticCost = 0;
5776 if (LT.first != 1 && MTy.isVector() &&
5777 MTy.getVectorNumElements() < ValVTy->getNumElements()) {
5778 // Type needs to be split. We need LT.first - 1 arithmetic ops.
5779 auto *SingleOpTy = FixedVectorType::get(ValVTy->getElementType(),
5780 MTy.getVectorNumElements());
5781 ArithmeticCost = getArithmeticInstrCost(Opcode, SingleOpTy, CostKind);
5782 ArithmeticCost *= LT.first - 1;
5783 }
5784
5785 if (ST->useSLMArithCosts())
5786 if (const auto *Entry = CostTableLookup(SLMCostTbl, ISD, MTy))
5787 return ArithmeticCost + Entry->Cost;
5788
5789 if (ST->hasAVX())
5790 if (const auto *Entry = CostTableLookup(AVX1CostTbl, ISD, MTy))
5791 return ArithmeticCost + Entry->Cost;
5792
5793 if (ST->hasSSE2())
5794 if (const auto *Entry = CostTableLookup(SSE2CostTbl, ISD, MTy))
5795 return ArithmeticCost + Entry->Cost;
5796
5797 // FIXME: These assume a naive kshift+binop lowering, which is probably
5798 // conservative in most cases.
5799 static const CostTblEntry AVX512BoolReduction[] = {
5800 { ISD::AND, MVT::v2i1, 3 },
5801 { ISD::AND, MVT::v4i1, 5 },
5802 { ISD::AND, MVT::v8i1, 7 },
5803 { ISD::AND, MVT::v16i1, 9 },
5804 { ISD::AND, MVT::v32i1, 11 },
5805 { ISD::AND, MVT::v64i1, 13 },
5806 { ISD::OR, MVT::v2i1, 3 },
5807 { ISD::OR, MVT::v4i1, 5 },
5808 { ISD::OR, MVT::v8i1, 7 },
5809 { ISD::OR, MVT::v16i1, 9 },
5810 { ISD::OR, MVT::v32i1, 11 },
5811 { ISD::OR, MVT::v64i1, 13 },
5812 };
5813
5814 static const CostTblEntry AVX2BoolReduction[] = {
5815 { ISD::AND, MVT::v16i16, 2 }, // vpmovmskb + cmp
5816 { ISD::AND, MVT::v32i8, 2 }, // vpmovmskb + cmp
5817 { ISD::OR, MVT::v16i16, 2 }, // vpmovmskb + cmp
5818 { ISD::OR, MVT::v32i8, 2 }, // vpmovmskb + cmp
5819 };
5820
5821 static const CostTblEntry AVX1BoolReduction[] = {
5822 { ISD::AND, MVT::v4i64, 2 }, // vmovmskpd + cmp
5823 { ISD::AND, MVT::v8i32, 2 }, // vmovmskps + cmp
5824 { ISD::AND, MVT::v16i16, 4 }, // vextractf128 + vpand + vpmovmskb + cmp
5825 { ISD::AND, MVT::v32i8, 4 }, // vextractf128 + vpand + vpmovmskb + cmp
5826 { ISD::OR, MVT::v4i64, 2 }, // vmovmskpd + cmp
5827 { ISD::OR, MVT::v8i32, 2 }, // vmovmskps + cmp
5828 { ISD::OR, MVT::v16i16, 4 }, // vextractf128 + vpor + vpmovmskb + cmp
5829 { ISD::OR, MVT::v32i8, 4 }, // vextractf128 + vpor + vpmovmskb + cmp
5830 };
5831
5832 static const CostTblEntry SSE2BoolReduction[] = {
5833 { ISD::AND, MVT::v2i64, 2 }, // movmskpd + cmp
5834 { ISD::AND, MVT::v4i32, 2 }, // movmskps + cmp
5835 { ISD::AND, MVT::v8i16, 2 }, // pmovmskb + cmp
5836 { ISD::AND, MVT::v16i8, 2 }, // pmovmskb + cmp
5837 { ISD::OR, MVT::v2i64, 2 }, // movmskpd + cmp
5838 { ISD::OR, MVT::v4i32, 2 }, // movmskps + cmp
5839 { ISD::OR, MVT::v8i16, 2 }, // pmovmskb + cmp
5840 { ISD::OR, MVT::v16i8, 2 }, // pmovmskb + cmp
5841 };
5842
5843 // Handle bool allof/anyof patterns.
5844 if (ValVTy->getElementType()->isIntegerTy(1)) {
5845 if (ISD == ISD::ADD) {
5846 // vXi1 addition reduction will bitcast to scalar and perform a popcount.
5847 auto *IntTy = IntegerType::getIntNTy(ValVTy->getContext(),
5848 ValVTy->getNumElements());
5849 IntrinsicCostAttributes ICA(Intrinsic::ctpop, IntTy, {IntTy});
5850 return getCastInstrCost(Instruction::BitCast, IntTy, ValVTy,
5852 CostKind) +
5854 }
5855
5856 InstructionCost ArithmeticCost = 0;
5857 if (LT.first != 1 && MTy.isVector() &&
5858 MTy.getVectorNumElements() < ValVTy->getNumElements()) {
5859 // Type needs to be split. We need LT.first - 1 arithmetic ops.
5860 auto *SingleOpTy = FixedVectorType::get(ValVTy->getElementType(),
5861 MTy.getVectorNumElements());
5862 ArithmeticCost = getArithmeticInstrCost(Opcode, SingleOpTy, CostKind);
5863 ArithmeticCost *= LT.first - 1;
5864 }
5865
5866 if (ST->hasAVX512())
5867 if (const auto *Entry = CostTableLookup(AVX512BoolReduction, ISD, MTy))
5868 return ArithmeticCost + Entry->Cost;
5869 if (ST->hasAVX2())
5870 if (const auto *Entry = CostTableLookup(AVX2BoolReduction, ISD, MTy))
5871 return ArithmeticCost + Entry->Cost;
5872 if (ST->hasAVX())
5873 if (const auto *Entry = CostTableLookup(AVX1BoolReduction, ISD, MTy))
5874 return ArithmeticCost + Entry->Cost;
5875 if (ST->hasSSE2())
5876 if (const auto *Entry = CostTableLookup(SSE2BoolReduction, ISD, MTy))
5877 return ArithmeticCost + Entry->Cost;
5878
5879 return BaseT::getArithmeticReductionCost(Opcode, ValVTy, FMF, CostKind);
5880 }
5881
5882 unsigned NumVecElts = ValVTy->getNumElements();
5883 unsigned ScalarSize = ValVTy->getScalarSizeInBits();
5884
5885 // Special case power of 2 reductions where the scalar type isn't changed
5886 // by type legalization.
5887 if (!isPowerOf2_32(NumVecElts) || ScalarSize != MTy.getScalarSizeInBits())
5888 return BaseT::getArithmeticReductionCost(Opcode, ValVTy, FMF, CostKind);
5889
5890 InstructionCost ReductionCost = 0;
5891
5892 auto *Ty = ValVTy;
5893 if (LT.first != 1 && MTy.isVector() &&
5894 MTy.getVectorNumElements() < ValVTy->getNumElements()) {
5895 // Type needs to be split. We need LT.first - 1 arithmetic ops.
5896 Ty = FixedVectorType::get(ValVTy->getElementType(),
5897 MTy.getVectorNumElements());
5898 ReductionCost = getArithmeticInstrCost(Opcode, Ty, CostKind);
5899 ReductionCost *= LT.first - 1;
5900 NumVecElts = MTy.getVectorNumElements();
5901 }
5902
5903 // Now handle reduction with the legal type, taking into account size changes
5904 // at each level.
5905 while (NumVecElts > 1) {
5906 // Determine the size of the remaining vector we need to reduce.
5907 unsigned Size = NumVecElts * ScalarSize;
5908 NumVecElts /= 2;
5909 // If we're reducing from 256/512 bits, use an extract_subvector.
5910 if (Size > 128) {
5911 auto *SubTy = FixedVectorType::get(ValVTy->getElementType(), NumVecElts);
5912 ReductionCost += getShuffleCost(TTI::SK_ExtractSubvector, Ty, Ty, {},
5913 CostKind, NumVecElts, SubTy);
5914 Ty = SubTy;
5915 } else if (Size == 128) {
5916 // Reducing from 128 bits is a permute of v2f64/v2i64.
5917 FixedVectorType *ShufTy;
5918 if (ValVTy->isFloatingPointTy())
5919 ShufTy =
5920 FixedVectorType::get(Type::getDoubleTy(ValVTy->getContext()), 2);
5921 else
5922 ShufTy =
5923 FixedVectorType::get(Type::getInt64Ty(ValVTy->getContext()), 2);
5924 ReductionCost += getShuffleCost(TTI::SK_PermuteSingleSrc, ShufTy, ShufTy,
5925 {}, CostKind, 0, nullptr);
5926 } else if (Size == 64) {
5927 // Reducing from 64 bits is a shuffle of v4f32/v4i32.
5928 FixedVectorType *ShufTy;
5929 if (ValVTy->isFloatingPointTy())
5930 ShufTy =
5931 FixedVectorType::get(Type::getFloatTy(ValVTy->getContext()), 4);
5932 else
5933 ShufTy =
5934 FixedVectorType::get(Type::getInt32Ty(ValVTy->getContext()), 4);
5935 ReductionCost += getShuffleCost(TTI::SK_PermuteSingleSrc, ShufTy, ShufTy,
5936 {}, CostKind, 0, nullptr);
5937 } else {
5938 // Reducing from smaller size is a shift by immediate.
5939 auto *ShiftTy = FixedVectorType::get(
5940 Type::getIntNTy(ValVTy->getContext(), Size), 128 / Size);
5941 ReductionCost += getArithmeticInstrCost(
5942 Instruction::LShr, ShiftTy, CostKind,
5945 }
5946
5947 // Add the arithmetic op for this level.
5948 ReductionCost += getArithmeticInstrCost(Opcode, Ty, CostKind);
5949 }
5950
5951 // Add the final extract element to the cost.
5952 return ReductionCost + getVectorInstrCost(Instruction::ExtractElement, Ty,
5953 CostKind, 0, nullptr, nullptr,
5955}
5956
5959 FastMathFlags FMF) const {
5960 IntrinsicCostAttributes ICA(IID, Ty, {Ty, Ty}, FMF);
5961 return getIntrinsicInstrCost(ICA, CostKind);
5962}
5963
5966 FastMathFlags FMF,
5968 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(ValTy);
5969
5970 MVT MTy = LT.second;
5971
5973 if (ValTy->isIntOrIntVectorTy()) {
5974 ISD = (IID == Intrinsic::umin || IID == Intrinsic::umax) ? ISD::UMIN
5975 : ISD::SMIN;
5976 } else {
5977 assert(ValTy->isFPOrFPVectorTy() &&
5978 "Expected float point or integer vector type.");
5979 ISD = (IID == Intrinsic::minnum || IID == Intrinsic::maxnum)
5980 ? ISD::FMINNUM
5981 : ISD::FMINIMUM;
5982 }
5983
5984 // We use llvm-mca across all supported CPUs to measure the cost stats.
5985 static const CostKindTblEntry SSE2CostTbl[] = {
5986 {ISD::SMIN, MVT::v2i64, {3, 4, 5, 6}},
5987 {ISD::UMIN, MVT::v2i64, {3, 4, 5, 6}},
5988 {ISD::SMIN, MVT::v2i32, {2, 2, 5, 6}},
5989 {ISD::UMIN, MVT::v2i32, {2, 2, 5, 6}},
5990 {ISD::SMIN, MVT::v4i32, {3, 7,11,12}},
5991 {ISD::UMIN, MVT::v4i32, {4, 7,14,15}},
5992 {ISD::SMIN, MVT::v2i16, {2, 3, 4, 4}},
5993 {ISD::UMIN, MVT::v2i16, {2, 3, 4, 6}},
5994 {ISD::SMIN, MVT::v4i16, {3, 5, 6, 6}},
5995 {ISD::UMIN, MVT::v4i16, {3, 5, 8, 10}},
5996 {ISD::SMIN, MVT::v8i16, {3, 8, 8, 8}},
5997 {ISD::UMIN, MVT::v8i16, {4, 8,12,14}},
5998 {ISD::SMIN, MVT::v2i8, {2, 3, 5, 6}},
5999 {ISD::UMIN, MVT::v2i8, {2, 3, 4, 4}},
6000 {ISD::SMIN, MVT::v4i8, {4, 6,12,13}},
6001 {ISD::UMIN, MVT::v4i8, {3, 6, 7, 7}},
6002 {ISD::SMIN, MVT::v8i8, {5, 9,18,19}},
6003 {ISD::UMIN, MVT::v8i8, {4, 8, 9, 9}},
6004 {ISD::SMIN, MVT::v16i8, {7,13,24,25}},
6005 {ISD::UMIN, MVT::v16i8, {3,10,11,11}},
6006 };
6007
6008 static const CostKindTblEntry SSE41CostTbl[] = {
6009 {ISD::SMIN, MVT::v2i64, {3, 4, 4, 6}},
6010 {ISD::UMIN, MVT::v2i64, {3, 4, 4, 6}},
6011 {ISD::SMIN, MVT::v2i32, {2, 2, 3, 3}},
6012 {ISD::UMIN, MVT::v2i32, {2, 2, 3, 3}},
6013 {ISD::SMIN, MVT::v4i32, {3, 4, 5, 5}},
6014 {ISD::UMIN, MVT::v4i32, {3, 4, 5, 5}},
6015 {ISD::UMIN, MVT::v2i16, {2, 3, 4, 4}},
6016 {ISD::SMIN, MVT::v4i16, {3, 5, 6, 6}},
6017 {ISD::UMIN, MVT::v4i16, {3, 5, 6, 6}},
6018 {ISD::SMIN, MVT::v8i16, {2, 8, 4, 5}},
6019 {ISD::UMIN, MVT::v8i16, {2, 5, 2, 2}},
6020 {ISD::SMIN, MVT::v2i8, {2, 3, 4, 4}},
6021 {ISD::SMIN, MVT::v4i8, {3, 6, 7, 7}},
6022 {ISD::SMIN, MVT::v8i8, {4, 8, 9, 9}},
6023 {ISD::SMIN, MVT::v16i8, {3,10, 7, 8}},
6024 {ISD::UMIN, MVT::v16i8, {3, 8, 5, 5}},
6025 };
6026
6027 static const CostKindTblEntry AVX1CostTbl[] = {
6028 {ISD::SMIN, MVT::v4i64, {5,11, 7,10}},
6029 {ISD::UMIN, MVT::v4i64, {6,12,10,13}},
6030 {ISD::SMIN, MVT::v8i32, {4, 9, 7, 7}},
6031 {ISD::UMIN, MVT::v8i32, {4, 9, 7, 7}},
6032 {ISD::SMIN, MVT::v16i16, {3,15, 6, 7}},
6033 {ISD::UMIN, MVT::v16i16, {2, 9, 4, 4}},
6034 {ISD::SMIN, MVT::v32i8, {4,17, 8, 9}},
6035 {ISD::UMIN, MVT::v32i8, {3,11, 6, 6}},
6036 };
6037
6038 static const CostKindTblEntry AVX2CostTbl[] = {
6039 {ISD::SMIN, MVT::v4i64, {4,11, 7,10}},
6040 {ISD::UMIN, MVT::v4i64, {4,12,10,13}},
6041 {ISD::SMIN, MVT::v2i32, {1, 2, 3, 3}},
6042 {ISD::UMIN, MVT::v2i32, {1, 2, 3, 3}},
6043 {ISD::UMIN, MVT::v4i32, {2, 4, 5, 5}},
6044 {ISD::SMIN, MVT::v4i32, {2, 4, 5, 5}},
6045 {ISD::SMIN, MVT::v8i32, {3, 9, 7, 7}},
6046 {ISD::UMIN, MVT::v8i32, {3, 9, 7, 7}},
6047 {ISD::SMIN, MVT::v4i16, {2, 4, 5, 5}},
6048 {ISD::UMIN, MVT::v4i16, {2, 4, 5, 5}},
6049 {ISD::SMIN, MVT::v16i16, {2,15, 6, 7}},
6050 {ISD::SMIN, MVT::v8i8, {3, 6, 7, 7}},
6051 {ISD::UMIN, MVT::v8i8, {3, 6, 7, 7}},
6052 {ISD::SMIN, MVT::v32i8, {3,17, 8, 9}},
6053 };
6054
6055 static const CostKindTblEntry AVX512FCostTbl[] = {
6056 {ISD::SMIN, MVT::v2i64, {2, 4, 3, 3}},
6057 {ISD::UMIN, MVT::v2i64, {2, 4, 3, 3}},
6058 {ISD::SMIN, MVT::v4i64, {3,10, 5, 5}},
6059 {ISD::UMIN, MVT::v4i64, {3,10, 5, 5}},
6060 {ISD::SMIN, MVT::v8i64, {5,16, 7, 7}},
6061 {ISD::UMIN, MVT::v8i64, {5,16, 7, 7}},
6062 {ISD::SMIN, MVT::v16i32, {4,12, 9, 9}},
6063 {ISD::UMIN, MVT::v16i32, {4,12, 9, 9}},
6064 };
6065
6066 static const CostKindTblEntry AVX512BWCostTbl[] = {
6067 {ISD::SMIN, MVT::v2i16, {1, 2, 3, 3}},
6068 {ISD::UMIN, MVT::v2i16, {1, 2, 3, 3}},
6069 {ISD::SMIN, MVT::v32i16, {2,19, 8, 9}},
6070 {ISD::UMIN, MVT::v32i16, {2,12, 6, 6}},
6071 {ISD::SMIN, MVT::v2i8, {1, 2, 3, 3}},
6072 {ISD::UMIN, MVT::v2i8, {1, 2, 3, 3}},
6073 {ISD::SMIN, MVT::v4i8, {2, 4, 5, 5}},
6074 {ISD::UMIN, MVT::v4i8, {2, 4, 5, 5}},
6075 {ISD::SMIN, MVT::v16i8, {2,10, 6, 7}},
6076 {ISD::UMIN, MVT::v16i8, {2, 6, 4, 4}},
6077 {ISD::SMIN, MVT::v32i8, {2,17, 8, 9}},
6078 {ISD::UMIN, MVT::v32i8, {2,10, 6, 6}},
6079 {ISD::SMIN, MVT::v64i8, {2,21,10,11}},
6080 {ISD::UMIN, MVT::v64i8, {2,14, 8, 8}},
6081 };
6082
6083 // Before legalizing the type, give a chance to look up illegal narrow types
6084 // in the table.
6085 // FIXME: Is there a better way to do this?
6086 EVT VT = TLI->getValueType(DL, ValTy);
6087 if (VT.isSimple()) {
6088 MVT MTy = VT.getSimpleVT();
6089 if (ST->hasBWI())
6090 if (const auto *Entry = CostTableLookup(AVX512BWCostTbl, ISD, MTy))
6091 if (auto KindCost = Entry->Cost[CostKind])
6092 return *KindCost;
6093
6094 if (ST->hasAVX512())
6095 if (const auto *Entry = CostTableLookup(AVX512FCostTbl, ISD, MTy))
6096 if (auto KindCost = Entry->Cost[CostKind])
6097 return *KindCost;
6098
6099 if (ST->hasAVX2())
6100 if (const auto *Entry = CostTableLookup(AVX2CostTbl, ISD, MTy))
6101 if (auto KindCost = Entry->Cost[CostKind])
6102 return *KindCost;
6103
6104 if (ST->hasAVX())
6105 if (const auto *Entry = CostTableLookup(AVX1CostTbl, ISD, MTy))
6106 if (auto KindCost = Entry->Cost[CostKind])
6107 return *KindCost;
6108
6109 if (ST->hasSSE41())
6110 if (const auto *Entry = CostTableLookup(SSE41CostTbl, ISD, MTy))
6111 if (auto KindCost = Entry->Cost[CostKind])
6112 return *KindCost;
6113
6114 if (ST->hasSSE2())
6115 if (const auto *Entry = CostTableLookup(SSE2CostTbl, ISD, MTy))
6116 if (auto KindCost = Entry->Cost[CostKind])
6117 return *KindCost;
6118 }
6119
6120 auto *ValVTy = cast<FixedVectorType>(ValTy);
6121 unsigned NumVecElts = ValVTy->getNumElements();
6122
6123 auto *Ty = ValVTy;
6124 InstructionCost MinMaxCost = 0;
6125 if (LT.first != 1 && MTy.isVector() &&
6126 MTy.getVectorNumElements() < ValVTy->getNumElements()) {
6127 // Type needs to be split. We need LT.first - 1 operations ops.
6128 Ty = FixedVectorType::get(ValVTy->getElementType(),
6129 MTy.getVectorNumElements());
6130 MinMaxCost = getMinMaxCost(IID, Ty, CostKind, FMF);
6131 MinMaxCost *= LT.first - 1;
6132 NumVecElts = MTy.getVectorNumElements();
6133 }
6134
6135 if (ST->hasBWI())
6136 if (const auto *Entry = CostTableLookup(AVX512BWCostTbl, ISD, MTy))
6137 if (auto KindCost = Entry->Cost[CostKind])
6138 return MinMaxCost + *KindCost;
6139
6140 if (ST->hasAVX512())
6141 if (const auto *Entry = CostTableLookup(AVX512FCostTbl, ISD, MTy))
6142 if (auto KindCost = Entry->Cost[CostKind])
6143 return MinMaxCost + *KindCost;
6144
6145 if (ST->hasAVX2())
6146 if (const auto *Entry = CostTableLookup(AVX2CostTbl, ISD, MTy))
6147 if (auto KindCost = Entry->Cost[CostKind])
6148 return MinMaxCost + *KindCost;
6149
6150 if (ST->hasAVX())
6151 if (const auto *Entry = CostTableLookup(AVX1CostTbl, ISD, MTy))
6152 if (auto KindCost = Entry->Cost[CostKind])
6153 return MinMaxCost + *KindCost;
6154
6155 if (ST->hasSSE41())
6156 if (const auto *Entry = CostTableLookup(SSE41CostTbl, ISD, MTy))
6157 if (auto KindCost = Entry->Cost[CostKind])
6158 return MinMaxCost + *KindCost;
6159
6160 if (ST->hasSSE2())
6161 if (const auto *Entry = CostTableLookup(SSE2CostTbl, ISD, MTy))
6162 if (auto KindCost = Entry->Cost[CostKind])
6163 return MinMaxCost + *KindCost;
6164
6165 unsigned ScalarSize = ValTy->getScalarSizeInBits();
6166
6167 // Special case power of 2 reductions where the scalar type isn't changed
6168 // by type legalization.
6169 if (!isPowerOf2_32(ValVTy->getNumElements()) ||
6170 ScalarSize != MTy.getScalarSizeInBits())
6171 return BaseT::getMinMaxReductionCost(IID, ValTy, FMF, CostKind);
6172
6173 // Now handle reduction with the legal type, taking into account size changes
6174 // at each level.
6175 while (NumVecElts > 1) {
6176 // Determine the size of the remaining vector we need to reduce.
6177 unsigned Size = NumVecElts * ScalarSize;
6178 NumVecElts /= 2;
6179 // If we're reducing from 256/512 bits, use an extract_subvector.
6180 if (Size > 128) {
6181 auto *SubTy = FixedVectorType::get(ValVTy->getElementType(), NumVecElts);
6182 MinMaxCost += getShuffleCost(TTI::SK_ExtractSubvector, Ty, Ty, {},
6183 CostKind, NumVecElts, SubTy);
6184 Ty = SubTy;
6185 } else if (Size == 128) {
6186 // Reducing from 128 bits is a permute of v2f64/v2i64.
6187 VectorType *ShufTy;
6188 if (ValTy->isFloatingPointTy())
6189 ShufTy =
6191 else
6192 ShufTy = FixedVectorType::get(Type::getInt64Ty(ValTy->getContext()), 2);
6193 MinMaxCost += getShuffleCost(TTI::SK_PermuteSingleSrc, ShufTy, ShufTy, {},
6194 CostKind, 0, nullptr);
6195 } else if (Size == 64) {
6196 // Reducing from 64 bits is a shuffle of v4f32/v4i32.
6197 FixedVectorType *ShufTy;
6198 if (ValTy->isFloatingPointTy())
6199 ShufTy = FixedVectorType::get(Type::getFloatTy(ValTy->getContext()), 4);
6200 else
6201 ShufTy = FixedVectorType::get(Type::getInt32Ty(ValTy->getContext()), 4);
6202 MinMaxCost += getShuffleCost(TTI::SK_PermuteSingleSrc, ShufTy, ShufTy, {},
6203 CostKind, 0, nullptr);
6204 } else {
6205 // Reducing from smaller size is a shift by immediate.
6206 auto *ShiftTy = FixedVectorType::get(
6207 Type::getIntNTy(ValTy->getContext(), Size), 128 / Size);
6208 MinMaxCost += getArithmeticInstrCost(
6209 Instruction::LShr, ShiftTy, TTI::TCK_RecipThroughput,
6212 }
6213
6214 // Add the arithmetic op for this level.
6215 MinMaxCost += getMinMaxCost(IID, Ty, CostKind, FMF);
6216 }
6217
6218 // Add the final extract element to the cost.
6219 return MinMaxCost + getVectorInstrCost(Instruction::ExtractElement, Ty,
6220 CostKind, 0, nullptr, nullptr,
6222}
6223
6224/// Calculate the cost of materializing a 64-bit value. This helper
6225/// method might only calculate a fraction of a larger immediate. Therefore it
6226/// is valid to return a cost of ZERO.
6228 if (Val == 0)
6229 return TTI::TCC_Free;
6230
6231 if (isInt<32>(Val))
6232 return TTI::TCC_Basic;
6233
6234 return 2 * TTI::TCC_Basic;
6235}
6236
6239 assert(Ty->isIntegerTy());
6240
6241 unsigned BitSize = Ty->getPrimitiveSizeInBits();
6242 if (BitSize == 0)
6243 return ~0U;
6244
6245 // Never hoist constants larger than 128bit, because this might lead to
6246 // incorrect code generation or assertions in codegen.
6247 // Fixme: Create a cost model for types larger than i128 once the codegen
6248 // issues have been fixed.
6249 if (BitSize > 128)
6250 return TTI::TCC_Free;
6251
6252 if (Imm == 0)
6253 return TTI::TCC_Free;
6254
6255 // Sign-extend all constants to a multiple of 64-bit.
6256 APInt ImmVal = Imm;
6257 if (BitSize % 64 != 0)
6258 ImmVal = Imm.sext(alignTo(BitSize, 64));
6259
6260 // Split the constant into 64-bit chunks and calculate the cost for each
6261 // chunk.
6263 for (unsigned ShiftVal = 0; ShiftVal < BitSize; ShiftVal += 64) {
6264 APInt Tmp = ImmVal.ashr(ShiftVal).sextOrTrunc(64);
6265 int64_t Val = Tmp.getSExtValue();
6266 Cost += getIntImmCost(Val);
6267 }
6268 // We need at least one instruction to materialize the constant.
6269 return std::max<InstructionCost>(1, Cost);
6270}
6271
6273 const APInt &Imm, Type *Ty,
6275 Instruction *Inst) const {
6276 assert(Ty->isIntegerTy());
6277
6278 unsigned BitSize = Ty->getPrimitiveSizeInBits();
6279 unsigned ImmBitWidth = Imm.getBitWidth();
6280
6281 // There is no cost model for constants with a bit size of 0. Return TCC_Free
6282 // here, so that constant hoisting will ignore this constant.
6283 if (BitSize == 0)
6284 return TTI::TCC_Free;
6285
6286 unsigned ImmIdx = ~0U;
6287 switch (Opcode) {
6288 default:
6289 return TTI::TCC_Free;
6290 case Instruction::GetElementPtr:
6291 // Always hoist the base address of a GetElementPtr. This prevents the
6292 // creation of new constants for every base constant that gets constant
6293 // folded with the offset.
6294 if (Idx == 0)
6295 return 2 * TTI::TCC_Basic;
6296 return TTI::TCC_Free;
6297 case Instruction::Store:
6298 ImmIdx = 0;
6299 break;
6300 case Instruction::ICmp:
6301 // This is an imperfect hack to prevent constant hoisting of
6302 // compares that might be trying to check if a 64-bit value fits in
6303 // 32-bits. The backend can optimize these cases using a right shift by 32.
6304 // There are other predicates and immediates the backend can use shifts for.
6305 if (Idx == 1 && ImmBitWidth == 64) {
6306 uint64_t ImmVal = Imm.getZExtValue();
6307 if (ImmVal == 0x100000000ULL || ImmVal == 0xffffffff)
6308 return TTI::TCC_Free;
6309
6310 if (auto *Cmp = dyn_cast_or_null<CmpInst>(Inst)) {
6311 if (Cmp->isEquality()) {
6312 KnownBits Known = computeKnownBits(Cmp->getOperand(0), DL);
6313 if (Known.countMinTrailingZeros() >= 32)
6314 return TTI::TCC_Free;
6315 }
6316 }
6317 }
6318 ImmIdx = 1;
6319 break;
6320 case Instruction::And:
6321 // We support 64-bit ANDs with immediates with 32-bits of leading zeroes
6322 // by using a 32-bit operation with implicit zero extension. Detect such
6323 // immediates here as the normal path expects bit 31 to be sign extended.
6324 if (Idx == 1 && ImmBitWidth == 64 && Imm.isIntN(32))
6325 return TTI::TCC_Free;
6326 // If we have BMI then we can use BEXTR/BZHI to mask out upper i64 bits.
6327 if (Idx == 1 && ImmBitWidth == 64 && ST->is64Bit() && ST->hasBMI() &&
6328 Imm.isMask())
6329 return X86TTIImpl::getIntImmCost(ST->hasBMI2() ? 255 : 65535);
6330 ImmIdx = 1;
6331 break;
6332 case Instruction::Add:
6333 case Instruction::Sub:
6334 // For add/sub, we can use the opposite instruction for INT32_MIN.
6335 if (Idx == 1 && ImmBitWidth == 64 && Imm.getZExtValue() == 0x80000000)
6336 return TTI::TCC_Free;
6337 ImmIdx = 1;
6338 break;
6339 case Instruction::UDiv:
6340 case Instruction::SDiv:
6341 case Instruction::URem:
6342 case Instruction::SRem:
6343 // Division by constant is typically expanded later into a different
6344 // instruction sequence. This completely changes the constants.
6345 // Report them as "free" to stop ConstantHoist from marking them as opaque.
6346 return TTI::TCC_Free;
6347 case Instruction::Mul:
6348 case Instruction::Or:
6349 case Instruction::Xor:
6350 ImmIdx = 1;
6351 break;
6352 // Always return TCC_Free for the shift value of a shift instruction.
6353 case Instruction::Shl:
6354 case Instruction::LShr:
6355 case Instruction::AShr:
6356 if (Idx == 1)
6357 return TTI::TCC_Free;
6358 break;
6359 case Instruction::Trunc:
6360 case Instruction::ZExt:
6361 case Instruction::SExt:
6362 case Instruction::IntToPtr:
6363 case Instruction::PtrToInt:
6364 case Instruction::BitCast:
6365 case Instruction::PHI:
6366 case Instruction::Call:
6367 case Instruction::Select:
6368 case Instruction::Ret:
6369 case Instruction::Load:
6370 break;
6371 }
6372
6373 if (Idx == ImmIdx) {
6374 uint64_t NumConstants = divideCeil(BitSize, 64);
6376 return (Cost <= NumConstants * TTI::TCC_Basic)
6377 ? static_cast<int>(TTI::TCC_Free)
6378 : Cost;
6379 }
6380
6381 return X86TTIImpl::getIntImmCost(Imm, Ty, CostKind);
6382}
6383
6386 const APInt &Imm, Type *Ty,
6388 assert(Ty->isIntegerTy());
6389
6390 unsigned BitSize = Ty->getPrimitiveSizeInBits();
6391 // There is no cost model for constants with a bit size of 0. Return TCC_Free
6392 // here, so that constant hoisting will ignore this constant.
6393 if (BitSize == 0)
6394 return TTI::TCC_Free;
6395
6396 switch (IID) {
6397 default:
6398 return TTI::TCC_Free;
6399 case Intrinsic::sadd_with_overflow:
6400 case Intrinsic::uadd_with_overflow:
6401 case Intrinsic::ssub_with_overflow:
6402 case Intrinsic::usub_with_overflow:
6403 case Intrinsic::smul_with_overflow:
6404 case Intrinsic::umul_with_overflow:
6405 if ((Idx == 1) && Imm.getBitWidth() <= 64 && Imm.isSignedIntN(32))
6406 return TTI::TCC_Free;
6407 break;
6408 case Intrinsic::experimental_stackmap:
6409 if ((Idx < 2) || (Imm.getBitWidth() <= 64 && Imm.isSignedIntN(64)))
6410 return TTI::TCC_Free;
6411 break;
6412 case Intrinsic::experimental_patchpoint_void:
6413 case Intrinsic::experimental_patchpoint:
6414 if ((Idx < 4) || (Imm.getBitWidth() <= 64 && Imm.isSignedIntN(64)))
6415 return TTI::TCC_Free;
6416 break;
6417 }
6418 return X86TTIImpl::getIntImmCost(Imm, Ty, CostKind);
6419}
6420
6423 const Instruction *I) const {
6425 return Opcode == Instruction::PHI ? TTI::TCC_Free : TTI::TCC_Basic;
6426 // Branches are assumed to be predicted.
6427 return TTI::TCC_Free;
6428}
6429
6430int X86TTIImpl::getGatherOverhead() const {
6431 // Some CPUs have more overhead for gather. The specified overhead is relative
6432 // to the Load operation. "2" is the number provided by Intel architects. This
6433 // parameter is used for cost estimation of Gather Op and comparison with
6434 // other alternatives.
6435 // TODO: Remove the explicit hasAVX512()?, That would mean we would only
6436 // enable gather with a -march.
6437 if (ST->hasAVX512() || (ST->hasAVX2() && ST->hasFastGather()))
6438 return 2;
6439
6440 return 1024;
6441}
6442
6443int X86TTIImpl::getScatterOverhead() const {
6444 if (ST->hasAVX512())
6445 return 2;
6446
6447 return 1024;
6448}
6449
6450// Return an average cost of Gather / Scatter instruction, maybe improved later.
6451InstructionCost X86TTIImpl::getGSVectorCost(unsigned Opcode,
6453 Type *SrcVTy, const Value *Ptr,
6454 Align Alignment,
6455 unsigned AddressSpace) const {
6456
6457 assert(isa<VectorType>(SrcVTy) && "Unexpected type in getGSVectorCost");
6458 unsigned VF = cast<FixedVectorType>(SrcVTy)->getNumElements();
6459
6460 // Try to reduce index size from 64 bit (default for GEP)
6461 // to 32. It is essential for VF 16. If the index can't be reduced to 32, the
6462 // operation will use 16 x 64 indices which do not fit in a zmm and needs
6463 // to split. Also check that the base pointer is the same for all lanes,
6464 // and that there's at most one variable index.
6465 auto getIndexSizeInBits = [](const Value *Ptr, const DataLayout &DL) {
6466 unsigned IndexSize = DL.getPointerSizeInBits();
6467 const GetElementPtrInst *GEP = dyn_cast_or_null<GetElementPtrInst>(Ptr);
6468 if (IndexSize < 64 || !GEP)
6469 return IndexSize;
6470
6471 unsigned NumOfVarIndices = 0;
6472 const Value *Ptrs = GEP->getPointerOperand();
6473 if (Ptrs->getType()->isVectorTy() && !getSplatValue(Ptrs))
6474 return IndexSize;
6475 for (unsigned I = 1, E = GEP->getNumOperands(); I != E; ++I) {
6476 if (isa<Constant>(GEP->getOperand(I)))
6477 continue;
6478 Type *IndxTy = GEP->getOperand(I)->getType();
6479 if (auto *IndexVTy = dyn_cast<VectorType>(IndxTy))
6480 IndxTy = IndexVTy->getElementType();
6481 if ((IndxTy->getPrimitiveSizeInBits() == 64 &&
6482 !isa<SExtInst>(GEP->getOperand(I))) ||
6483 ++NumOfVarIndices > 1)
6484 return IndexSize; // 64
6485 }
6486 return (unsigned)32;
6487 };
6488
6489 // Trying to reduce IndexSize to 32 bits for vector 16.
6490 // By default the IndexSize is equal to pointer size.
6491 unsigned IndexSize = (ST->hasAVX512() && VF >= 16)
6492 ? getIndexSizeInBits(Ptr, DL)
6493 : DL.getPointerSizeInBits();
6494
6495 auto *IndexVTy = FixedVectorType::get(
6496 IntegerType::get(SrcVTy->getContext(), IndexSize), VF);
6497 std::pair<InstructionCost, MVT> IdxsLT = getTypeLegalizationCost(IndexVTy);
6498 std::pair<InstructionCost, MVT> SrcLT = getTypeLegalizationCost(SrcVTy);
6499 InstructionCost::CostType SplitFactor =
6500 std::max(IdxsLT.first, SrcLT.first).getValue();
6501 if (SplitFactor > 1) {
6502 // Handle splitting of vector of pointers
6503 auto *SplitSrcTy =
6504 FixedVectorType::get(SrcVTy->getScalarType(), VF / SplitFactor);
6505 return SplitFactor * getGSVectorCost(Opcode, CostKind, SplitSrcTy, Ptr,
6506 Alignment, AddressSpace);
6507 }
6508
6509 // If we didn't split, this will be a single gather/scatter instruction.
6511 return 1;
6512
6513 // The gather / scatter cost is given by Intel architects. It is a rough
6514 // number since we are looking at one instruction in a time.
6515 const int GSOverhead = (Opcode == Instruction::Load) ? getGatherOverhead()
6516 : getScatterOverhead();
6517 return GSOverhead + VF * getMemoryOpCost(Opcode, SrcVTy->getScalarType(),
6518 Alignment, AddressSpace, CostKind);
6519}
6520
6521/// Calculate the cost of Gather / Scatter operation
6525 bool IsLoad = MICA.getID() == Intrinsic::masked_gather ||
6526 MICA.getID() == Intrinsic::vp_gather;
6527 unsigned Opcode = IsLoad ? Instruction::Load : Instruction::Store;
6528 Type *SrcVTy = MICA.getDataType();
6529 const Value *Ptr = MICA.getPointer();
6530 Align Alignment = MICA.getAlignment();
6531 if ((Opcode == Instruction::Load &&
6532 (!isLegalMaskedGather(SrcVTy, Align(Alignment)) ||
6534 Align(Alignment)))) ||
6535 (Opcode == Instruction::Store &&
6536 (!isLegalMaskedScatter(SrcVTy, Align(Alignment)) ||
6538 Align(Alignment)))))
6540
6541 assert(SrcVTy->isVectorTy() && "Unexpected data type for Gather/Scatter");
6542 unsigned AddressSpace = MICA.getAddressSpace();
6543 return getGSVectorCost(Opcode, CostKind, SrcVTy, Ptr, Alignment,
6544 AddressSpace);
6545}
6546
6548 const TargetTransformInfo::LSRCost &C2) const {
6549 // X86 specific here are "instruction number 1st priority".
6550 return std::tie(C1.Insns, C1.NumRegs, C1.AddRecCost, C1.NumIVMuls,
6551 C1.NumBaseAdds, C1.ScaleCost, C1.ImmCost, C1.SetupCost) <
6552 std::tie(C2.Insns, C2.NumRegs, C2.AddRecCost, C2.NumIVMuls,
6553 C2.NumBaseAdds, C2.ScaleCost, C2.ImmCost, C2.SetupCost);
6554}
6555
6557 return ST->hasMacroFusion() || ST->hasBranchFusion();
6558}
6559
6560static bool isLegalMaskedLoadStore(Type *ScalarTy, const X86Subtarget *ST) {
6561 if (!ST->hasAVX())
6562 return false;
6563
6564 if (ScalarTy->isPointerTy())
6565 return true;
6566
6567 if (ScalarTy->isFloatTy() || ScalarTy->isDoubleTy())
6568 return true;
6569
6570 if (ScalarTy->isHalfTy() && ST->hasBWI())
6571 return true;
6572
6573 if (ScalarTy->isBFloatTy() && ST->hasBF16())
6574 return true;
6575
6576 if (!ScalarTy->isIntegerTy())
6577 return false;
6578
6579 unsigned IntWidth = ScalarTy->getIntegerBitWidth();
6580 return IntWidth == 32 || IntWidth == 64 ||
6581 ((IntWidth == 8 || IntWidth == 16) && ST->hasBWI());
6582}
6583
6585 unsigned AddressSpace,
6586 TTI::MaskKind MaskKind) const {
6587 Type *ScalarTy = DataTy->getScalarType();
6588
6589 // The backend can't handle a single element vector w/o CFCMOV.
6590 if (isa<VectorType>(DataTy) &&
6591 cast<FixedVectorType>(DataTy)->getNumElements() == 1)
6592 return ST->hasCF() &&
6593 hasConditionalLoadStoreForType(ScalarTy, /*IsStore=*/false);
6594
6595 return isLegalMaskedLoadStore(ScalarTy, ST);
6596}
6597
6599 unsigned AddressSpace,
6600 TTI::MaskKind MaskKind) const {
6601 Type *ScalarTy = DataTy->getScalarType();
6602
6603 // The backend can't handle a single element vector w/o CFCMOV.
6604 if (isa<VectorType>(DataTy) &&
6605 cast<FixedVectorType>(DataTy)->getNumElements() == 1)
6606 return ST->hasCF() &&
6607 hasConditionalLoadStoreForType(ScalarTy, /*IsStore=*/true);
6608
6609 return isLegalMaskedLoadStore(ScalarTy, ST);
6610}
6611
6612bool X86TTIImpl::isLegalNTLoad(Type *DataType, Align Alignment) const {
6613 unsigned DataSize = DL.getTypeStoreSize(DataType);
6614 // The only supported nontemporal loads are for aligned vectors of 16 or 32
6615 // bytes. Note that 32-byte nontemporal vector loads are supported by AVX2
6616 // (the equivalent stores only require AVX).
6617 if (Alignment >= DataSize && (DataSize == 16 || DataSize == 32))
6618 return DataSize == 16 ? ST->hasSSE1() : ST->hasAVX2();
6619
6620 return false;
6621}
6622
6623bool X86TTIImpl::isLegalNTStore(Type *DataType, Align Alignment) const {
6624 unsigned DataSize = DL.getTypeStoreSize(DataType);
6625
6626 // SSE4A supports nontemporal stores of float and double at arbitrary
6627 // alignment.
6628 if (ST->hasSSE4A() && (DataType->isFloatTy() || DataType->isDoubleTy()))
6629 return true;
6630
6631 // Besides the SSE4A subtarget exception above, only aligned stores are
6632 // available nontemporaly on any other subtarget. And only stores with a size
6633 // of 4..32 bytes (powers of 2, only) are permitted.
6634 if (Alignment < DataSize || DataSize < 4 || DataSize > 32 ||
6635 !isPowerOf2_32(DataSize))
6636 return false;
6637
6638 // 32-byte vector nontemporal stores are supported by AVX (the equivalent
6639 // loads require AVX2).
6640 if (DataSize == 32)
6641 return ST->hasAVX();
6642 if (DataSize == 16)
6643 return ST->hasSSE1();
6644 return true;
6645}
6646
6648 ElementCount NumElements) const {
6649 // movddup
6650 return ST->hasSSE3() && !NumElements.isScalable() &&
6651 NumElements.getFixedValue() == 2 &&
6652 ElementTy == Type::getDoubleTy(ElementTy->getContext());
6653}
6654
6655bool X86TTIImpl::isLegalMaskedExpandLoad(Type *DataTy, Align Alignment) const {
6656 if (!isa<VectorType>(DataTy))
6657 return false;
6658
6659 if (!ST->hasAVX512())
6660 return false;
6661
6662 // The backend can't handle a single element vector.
6663 if (cast<FixedVectorType>(DataTy)->getNumElements() == 1)
6664 return false;
6665
6666 Type *ScalarTy = cast<VectorType>(DataTy)->getElementType();
6667
6668 if (ScalarTy->isFloatTy() || ScalarTy->isDoubleTy())
6669 return true;
6670
6671 if (!ScalarTy->isIntegerTy())
6672 return false;
6673
6674 unsigned IntWidth = ScalarTy->getIntegerBitWidth();
6675 return IntWidth == 32 || IntWidth == 64 ||
6676 ((IntWidth == 8 || IntWidth == 16) && ST->hasVBMI2());
6677}
6678
6680 Align Alignment) const {
6681 return isLegalMaskedExpandLoad(DataTy, Alignment);
6682}
6683
6684bool X86TTIImpl::supportsGather() const {
6685 // Some CPUs have better gather performance than others.
6686 // TODO: Remove the explicit ST->hasAVX512()?, That would mean we would only
6687 // enable gather with a -march.
6688 return ST->hasAVX512() || (ST->hasFastGather() && ST->hasAVX2());
6689}
6690
6692 Align Alignment) const {
6693 // Gather / Scatter for vector 2 is not profitable on KNL / SKX
6694 // Vector-4 of gather/scatter instruction does not exist on KNL. We can extend
6695 // it to 8 elements, but zeroing upper bits of the mask vector will add more
6696 // instructions. Right now we give the scalar cost of vector-4 for KNL. TODO:
6697 // Check, maybe the gather/scatter instruction is better in the VariableMask
6698 // case.
6699 unsigned NumElts = cast<FixedVectorType>(VTy)->getNumElements();
6700 return NumElts == 1 ||
6701 (ST->hasAVX512() && (NumElts == 2 || (NumElts == 4 && !ST->hasVLX())));
6702}
6703
6705 Align Alignment) const {
6706 Type *ScalarTy = DataTy->getScalarType();
6707 if (ScalarTy->isPointerTy())
6708 return true;
6709
6710 if (ScalarTy->isFloatTy() || ScalarTy->isDoubleTy())
6711 return true;
6712
6713 if (!ScalarTy->isIntegerTy())
6714 return false;
6715
6716 unsigned IntWidth = ScalarTy->getIntegerBitWidth();
6717 return IntWidth == 32 || IntWidth == 64;
6718}
6719
6720bool X86TTIImpl::isLegalMaskedGather(Type *DataTy, Align Alignment) const {
6721 if (!supportsGather() || !ST->preferGather())
6722 return false;
6723 return isLegalMaskedGatherScatter(DataTy, Alignment);
6724}
6725
6726bool X86TTIImpl::isLegalAltInstr(VectorType *VecTy, unsigned Opcode0,
6727 unsigned Opcode1,
6728 const SmallBitVector &OpcodeMask) const {
6729 // ADDSUBPS 4xf32 SSE3
6730 // VADDSUBPS 4xf32 AVX
6731 // VADDSUBPS 8xf32 AVX2
6732 // ADDSUBPD 2xf64 SSE3
6733 // VADDSUBPD 2xf64 AVX
6734 // VADDSUBPD 4xf64 AVX2
6735
6736 unsigned NumElements = cast<FixedVectorType>(VecTy)->getNumElements();
6737 assert(OpcodeMask.size() == NumElements && "Mask and VecTy are incompatible");
6738 if (!isPowerOf2_32(NumElements))
6739 return false;
6740 // Check the opcode pattern. We apply the mask on the opcode arguments and
6741 // then check if it is what we expect.
6742 for (int Lane : seq<int>(0, NumElements)) {
6743 unsigned Opc = OpcodeMask.test(Lane) ? Opcode1 : Opcode0;
6744 // We expect FSub for even lanes and FAdd for odd lanes.
6745 if (Lane % 2 == 0 && Opc != Instruction::FSub)
6746 return false;
6747 if (Lane % 2 == 1 && Opc != Instruction::FAdd)
6748 return false;
6749 }
6750 // Now check that the pattern is supported by the target ISA.
6751 Type *ElemTy = cast<VectorType>(VecTy)->getElementType();
6752 if (ElemTy->isFloatTy())
6753 return ST->hasSSE3() && NumElements % 4 == 0;
6754 if (ElemTy->isDoubleTy())
6755 return ST->hasSSE3() && NumElements % 2 == 0;
6756 return false;
6757}
6758
6759bool X86TTIImpl::isLegalMaskedScatter(Type *DataType, Align Alignment) const {
6760 // AVX2 doesn't support scatter
6761 if (!ST->hasAVX512() || !ST->preferScatter())
6762 return false;
6763 return isLegalMaskedGatherScatter(DataType, Alignment);
6764}
6765
6766bool X86TTIImpl::hasDivRemOp(Type *DataType, bool IsSigned) const {
6767 EVT VT = TLI->getValueType(DL, DataType);
6768 return TLI->isOperationLegal(IsSigned ? ISD::SDIVREM : ISD::UDIVREM, VT);
6769}
6770
6772 // FDIV is always expensive, even if it has a very low uop count.
6773 // TODO: Still necessary for recent CPUs with low latency/throughput fdiv?
6774 if (I->getOpcode() == Instruction::FDiv)
6775 return true;
6776
6778}
6779
6780bool X86TTIImpl::isFCmpOrdCheaperThanFCmpZero(Type *Ty) const { return false; }
6781
6783 const Function *Callee) const {
6784 const TargetMachine &TM = getTLI()->getTargetMachine();
6785
6786 // Work this as a subsetting of subtarget features.
6787 const X86Subtarget &CallerSubtarget = TM.getSubtarget<X86Subtarget>(*Caller);
6788 const X86Subtarget &CalleeSubtarget = TM.getSubtarget<X86Subtarget>(*Callee);
6789 const FeatureBitset &CallerBits = CallerSubtarget.getFeatureBits();
6790 const FeatureBitset &CalleeBits = CalleeSubtarget.getFeatureBits();
6791
6792 // Check whether callee features are a subset of caller features
6793 // (apart from the ignore list).
6794 const FeatureBitset &InlineIgnoreFeatures =
6795 CallerSubtarget.getInlineIgnoreFeatures();
6796 FeatureBitset RealCallerBits = CallerBits & ~InlineIgnoreFeatures;
6797 FeatureBitset RealCalleeBits = CalleeBits & ~InlineIgnoreFeatures;
6798 if ((RealCallerBits & RealCalleeBits) != RealCalleeBits)
6799 return false;
6800
6801 // If the features are not exactly the same (or there is a difference in
6802 // AVX512 register usage), we need to additionally check for calls
6803 // that may become ABI-incompatible as a result of inlining.
6804 if (RealCallerBits == RealCalleeBits &&
6805 CallerSubtarget.useAVX512Regs() == CalleeSubtarget.useAVX512Regs())
6806 return true;
6807
6808 for (const Instruction &I : instructions(Callee)) {
6809 if (const auto *CB = dyn_cast<CallBase>(&I)) {
6810 // Having more target features is fine for inline ASM and intrinsics.
6811 if (CB->isInlineAsm() || CB->getIntrinsicID() != Intrinsic::not_intrinsic)
6812 continue;
6813
6815 for (Value *Arg : CB->args())
6816 Types.push_back(Arg->getType());
6817 if (!CB->getType()->isVoidTy())
6818 Types.push_back(CB->getType());
6819
6820 // Simple types are always ABI compatible.
6821 auto IsSimpleTy = [](Type *Ty) {
6822 return !Ty->isVectorTy() && !Ty->isAggregateType();
6823 };
6824 if (all_of(Types, IsSimpleTy))
6825 continue;
6826
6827 // Do a precise compatibility check.
6828 if (!areTypesABICompatible(Caller, Callee, Types))
6829 return false;
6830 }
6831 }
6832 return true;
6833}
6834
6836 const Function *Callee,
6837 ArrayRef<Type *> Types) const {
6838 const TargetMachine &TM = getTLI()->getTargetMachine();
6839 const TargetLowering *CallerTLI =
6840 TM.getSubtargetImpl(*Caller)->getTargetLowering();
6841 const TargetLowering *CalleeTLI =
6842 TM.getSubtargetImpl(*Callee)->getTargetLowering();
6843
6844 LLVMContext &Ctx = Caller->getContext();
6845 const DataLayout &DL = Caller->getDataLayout();
6846 CallingConv::ID CC = Callee->getCallingConv();
6847 return all_of(Types, [&](Type *Ty) {
6848 SmallVector<EVT> VTs;
6849 ComputeValueVTs(*CallerTLI, DL, Ty, VTs);
6850 return all_of(VTs, [&](EVT VT) {
6851 return CallerTLI->getRegisterTypeForCallingConv(Ctx, CC, VT) ==
6852 CalleeTLI->getRegisterTypeForCallingConv(Ctx, CC, VT);
6853 });
6854 });
6855}
6856
6858X86TTIImpl::enableMemCmpExpansion(bool OptSize, bool IsZeroCmp) const {
6860 Options.MaxNumLoads = TLI->getMaxExpandSizeMemcmp(OptSize);
6861 Options.NumLoadsPerBlock = 2;
6862 // All GPR and vector loads can be unaligned.
6863 Options.AllowOverlappingLoads = true;
6864 if (IsZeroCmp) {
6865 // Only enable vector loads for equality comparison. Right now the vector
6866 // version is not as fast for three way compare (see #33329).
6867 const unsigned PreferredWidth = ST->getPreferVectorWidth();
6868 if (PreferredWidth >= 512 && ST->hasAVX512())
6869 Options.LoadSizes.push_back(64);
6870 if (PreferredWidth >= 256 && ST->hasAVX()) Options.LoadSizes.push_back(32);
6871 if (PreferredWidth >= 128 && ST->hasSSE2()) Options.LoadSizes.push_back(16);
6872 }
6873 if (ST->is64Bit()) {
6874 Options.LoadSizes.push_back(8);
6875 }
6876 Options.LoadSizes.push_back(4);
6877 Options.LoadSizes.push_back(2);
6878 Options.LoadSizes.push_back(1);
6879 return Options;
6880}
6881
6883 return supportsGather();
6884}
6885
6887 return false;
6888}
6889
6891 // TODO: We expect this to be beneficial regardless of arch,
6892 // but there are currently some unexplained performance artifacts on Atom.
6893 // As a temporary solution, disable on Atom.
6894 return !(ST->isAtom());
6895}
6896
6898 switch (II->getIntrinsicID()) {
6899 default:
6900 return true;
6901 case Intrinsic::vector_reduce_mul:
6902 case Intrinsic::vector_reduce_smax:
6903 case Intrinsic::vector_reduce_smin:
6904 case Intrinsic::vector_reduce_umax:
6905 case Intrinsic::vector_reduce_umin:
6906 return false;
6907 }
6908}
6909
6910// Get estimation for interleaved load/store operations and strided load.
6911// \p Indices contains indices for strided load.
6912// \p Factor - the factor of interleaving.
6913// AVX-512 provides 3-src shuffles that significantly reduces the cost.
6915 unsigned Opcode, FixedVectorType *VecTy, unsigned Factor,
6916 ArrayRef<unsigned> Indices, Align Alignment, unsigned AddressSpace,
6917 TTI::TargetCostKind CostKind, bool UseMaskForCond,
6918 bool UseMaskForGaps) const {
6919 // VecTy for interleave memop is <VF*Factor x Elt>.
6920 // So, for VF=4, Interleave Factor = 3, Element type = i32 we have
6921 // VecTy = <12 x i32>.
6922
6923 // Calculate the number of memory operations (NumOfMemOps), required
6924 // for load/store the VecTy.
6925 MVT LegalVT = getTypeLegalizationCost(VecTy).second;
6926 unsigned VecTySize = DL.getTypeStoreSize(VecTy);
6927 unsigned LegalVTSize = LegalVT.getStoreSize();
6928 unsigned NumOfMemOps = (VecTySize + LegalVTSize - 1) / LegalVTSize;
6929
6930 // Get the cost of one memory operation.
6931 auto *SingleMemOpTy = FixedVectorType::get(VecTy->getElementType(),
6932 LegalVT.getVectorNumElements());
6933 InstructionCost MemOpCost;
6934 bool UseMaskedMemOp = UseMaskForCond || UseMaskForGaps;
6935 if (UseMaskedMemOp) {
6936 unsigned IID = Opcode == Instruction::Load ? Intrinsic::masked_load
6937 : Intrinsic::masked_store;
6938 MemOpCost = getMaskedMemoryOpCost(
6939 {IID, SingleMemOpTy, Alignment, AddressSpace}, CostKind);
6940 } else
6941 MemOpCost = getMemoryOpCost(Opcode, SingleMemOpTy, Alignment, AddressSpace,
6942 CostKind);
6943
6944 unsigned VF = VecTy->getNumElements() / Factor;
6945 MVT VT =
6946 MVT::getVectorVT(TLI->getSimpleValueType(DL, VecTy->getScalarType()), VF);
6947
6948 InstructionCost MaskCost;
6949 if (UseMaskedMemOp) {
6950 APInt DemandedLoadStoreElts = APInt::getZero(VecTy->getNumElements());
6951 for (unsigned Index : Indices) {
6952 assert(Index < Factor && "Invalid index for interleaved memory op");
6953 for (unsigned Elm = 0; Elm < VF; Elm++)
6954 DemandedLoadStoreElts.setBit(Index + Elm * Factor);
6955 }
6956
6957 Type *I1Type = Type::getInt1Ty(VecTy->getContext());
6958
6959 MaskCost = getReplicationShuffleCost(
6960 I1Type, Factor, VF,
6961 UseMaskForGaps ? DemandedLoadStoreElts
6963 CostKind);
6964
6965 // The Gaps mask is invariant and created outside the loop, therefore the
6966 // cost of creating it is not accounted for here. However if we have both
6967 // a MaskForGaps and some other mask that guards the execution of the
6968 // memory access, we need to account for the cost of And-ing the two masks
6969 // inside the loop.
6970 if (UseMaskForGaps) {
6971 auto *MaskVT = FixedVectorType::get(I1Type, VecTy->getNumElements());
6972 MaskCost += getArithmeticInstrCost(BinaryOperator::And, MaskVT, CostKind);
6973 }
6974 }
6975
6976 if (Opcode == Instruction::Load) {
6977 // The tables (AVX512InterleavedLoadTbl and AVX512InterleavedStoreTbl)
6978 // contain the cost of the optimized shuffle sequence that the
6979 // X86InterleavedAccess pass will generate.
6980 // The cost of loads and stores are computed separately from the table.
6981
6982 // X86InterleavedAccess support only the following interleaved-access group.
6983 static const CostTblEntry AVX512InterleavedLoadTbl[] = {
6984 {3, MVT::v16i8, 12}, //(load 48i8 and) deinterleave into 3 x 16i8
6985 {3, MVT::v32i8, 14}, //(load 96i8 and) deinterleave into 3 x 32i8
6986 {3, MVT::v64i8, 22}, //(load 96i8 and) deinterleave into 3 x 32i8
6987 };
6988
6989 if (const auto *Entry =
6990 CostTableLookup(AVX512InterleavedLoadTbl, Factor, VT))
6991 return MaskCost + NumOfMemOps * MemOpCost + Entry->Cost;
6992 //If an entry does not exist, fallback to the default implementation.
6993
6994 // Kind of shuffle depends on number of loaded values.
6995 // If we load the entire data in one register, we can use a 1-src shuffle.
6996 // Otherwise, we'll merge 2 sources in each operation.
6997 TTI::ShuffleKind ShuffleKind =
6998 (NumOfMemOps > 1) ? TTI::SK_PermuteTwoSrc : TTI::SK_PermuteSingleSrc;
6999
7000 InstructionCost ShuffleCost = getShuffleCost(
7001 ShuffleKind, SingleMemOpTy, SingleMemOpTy, {}, CostKind, 0, nullptr);
7002
7003 unsigned NumOfLoadsInInterleaveGrp =
7004 Indices.size() ? Indices.size() : Factor;
7005 auto *ResultTy = FixedVectorType::get(VecTy->getElementType(),
7006 VecTy->getNumElements() / Factor);
7007 InstructionCost NumOfResults =
7008 getTypeLegalizationCost(ResultTy).first * NumOfLoadsInInterleaveGrp;
7009
7010 // About a half of the loads may be folded in shuffles when we have only
7011 // one result. If we have more than one result, or the loads are masked,
7012 // we do not fold loads at all.
7013 unsigned NumOfUnfoldedLoads =
7014 UseMaskedMemOp || NumOfResults > 1 ? NumOfMemOps : NumOfMemOps / 2;
7015
7016 // Get a number of shuffle operations per result.
7017 unsigned NumOfShufflesPerResult =
7018 std::max((unsigned)1, (unsigned)(NumOfMemOps - 1));
7019
7020 // The SK_MergeTwoSrc shuffle clobbers one of src operands.
7021 // When we have more than one destination, we need additional instructions
7022 // to keep sources.
7023 InstructionCost NumOfMoves = 0;
7024 if (NumOfResults > 1 && ShuffleKind == TTI::SK_PermuteTwoSrc)
7025 NumOfMoves = NumOfResults * NumOfShufflesPerResult / 2;
7026
7027 InstructionCost Cost = NumOfResults * NumOfShufflesPerResult * ShuffleCost +
7028 MaskCost + NumOfUnfoldedLoads * MemOpCost +
7029 NumOfMoves;
7030
7031 return Cost;
7032 }
7033
7034 // Store.
7035 assert(Opcode == Instruction::Store &&
7036 "Expected Store Instruction at this point");
7037 // X86InterleavedAccess support only the following interleaved-access group.
7038 static const CostTblEntry AVX512InterleavedStoreTbl[] = {
7039 {3, MVT::v16i8, 12}, // interleave 3 x 16i8 into 48i8 (and store)
7040 {3, MVT::v32i8, 14}, // interleave 3 x 32i8 into 96i8 (and store)
7041 {3, MVT::v64i8, 26}, // interleave 3 x 64i8 into 96i8 (and store)
7042
7043 {4, MVT::v8i8, 10}, // interleave 4 x 8i8 into 32i8 (and store)
7044 {4, MVT::v16i8, 11}, // interleave 4 x 16i8 into 64i8 (and store)
7045 {4, MVT::v32i8, 14}, // interleave 4 x 32i8 into 128i8 (and store)
7046 {4, MVT::v64i8, 24} // interleave 4 x 32i8 into 256i8 (and store)
7047 };
7048
7049 if (const auto *Entry =
7050 CostTableLookup(AVX512InterleavedStoreTbl, Factor, VT))
7051 return MaskCost + NumOfMemOps * MemOpCost + Entry->Cost;
7052 //If an entry does not exist, fallback to the default implementation.
7053
7054 // There is no strided stores meanwhile. And store can't be folded in
7055 // shuffle.
7056 unsigned NumOfSources = Factor; // The number of values to be merged.
7057 InstructionCost ShuffleCost =
7058 getShuffleCost(TTI::SK_PermuteTwoSrc, SingleMemOpTy, SingleMemOpTy, {},
7059 CostKind, 0, nullptr);
7060 unsigned NumOfShufflesPerStore = NumOfSources - 1;
7061
7062 // The SK_MergeTwoSrc shuffle clobbers one of src operands.
7063 // We need additional instructions to keep sources.
7064 unsigned NumOfMoves = NumOfMemOps * NumOfShufflesPerStore / 2;
7066 MaskCost +
7067 NumOfMemOps * (MemOpCost + NumOfShufflesPerStore * ShuffleCost) +
7068 NumOfMoves;
7069 return Cost;
7070}
7071
7073 unsigned Opcode, Type *BaseTy, unsigned Factor, ArrayRef<unsigned> Indices,
7074 Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind,
7075 bool UseMaskForCond, bool UseMaskForGaps) const {
7076 auto *VecTy = cast<FixedVectorType>(BaseTy);
7077
7078 auto isSupportedOnAVX512 = [&](Type *VecTy) {
7079 Type *EltTy = cast<VectorType>(VecTy)->getElementType();
7080 if (EltTy->isFloatTy() || EltTy->isDoubleTy() || EltTy->isIntegerTy(64) ||
7081 EltTy->isIntegerTy(32) || EltTy->isPointerTy())
7082 return true;
7083 if (EltTy->isIntegerTy(16) || EltTy->isIntegerTy(8) || EltTy->isHalfTy())
7084 return ST->hasBWI();
7085 if (EltTy->isBFloatTy())
7086 return ST->hasBF16();
7087 return false;
7088 };
7089 if (ST->hasAVX512() && isSupportedOnAVX512(VecTy))
7091 Opcode, VecTy, Factor, Indices, Alignment,
7092 AddressSpace, CostKind, UseMaskForCond, UseMaskForGaps);
7093
7094 if (UseMaskForCond || UseMaskForGaps)
7095 return BaseT::getInterleavedMemoryOpCost(Opcode, VecTy, Factor, Indices,
7096 Alignment, AddressSpace, CostKind,
7097 UseMaskForCond, UseMaskForGaps);
7098
7099 // Get estimation for interleaved load/store operations for SSE-AVX2.
7100 // As opposed to AVX-512, SSE-AVX2 do not have generic shuffles that allow
7101 // computing the cost using a generic formula as a function of generic
7102 // shuffles. We therefore use a lookup table instead, filled according to
7103 // the instruction sequences that codegen currently generates.
7104
7105 // VecTy for interleave memop is <VF*Factor x Elt>.
7106 // So, for VF=4, Interleave Factor = 3, Element type = i32 we have
7107 // VecTy = <12 x i32>.
7108 MVT LegalVT = getTypeLegalizationCost(VecTy).second;
7109
7110 // This function can be called with VecTy=<6xi128>, Factor=3, in which case
7111 // the VF=2, while v2i128 is an unsupported MVT vector type
7112 // (see MachineValueType.h::getVectorVT()).
7113 if (!LegalVT.isVector())
7114 return BaseT::getInterleavedMemoryOpCost(Opcode, VecTy, Factor, Indices,
7115 Alignment, AddressSpace, CostKind);
7116
7117 unsigned VF = VecTy->getNumElements() / Factor;
7118 Type *ScalarTy = VecTy->getElementType();
7119 // Deduplicate entries, model floats/pointers as appropriately-sized integers.
7120 if (!ScalarTy->isIntegerTy())
7121 ScalarTy =
7122 Type::getIntNTy(ScalarTy->getContext(), DL.getTypeSizeInBits(ScalarTy));
7123
7124 // Get the cost of all the memory operations.
7125 // FIXME: discount dead loads.
7126 InstructionCost MemOpCosts =
7127 getMemoryOpCost(Opcode, VecTy, Alignment, AddressSpace, CostKind);
7128
7129 auto *VT = FixedVectorType::get(ScalarTy, VF);
7130 EVT ETy = TLI->getValueType(DL, VT);
7131 if (!ETy.isSimple())
7132 return BaseT::getInterleavedMemoryOpCost(Opcode, VecTy, Factor, Indices,
7133 Alignment, AddressSpace, CostKind);
7134
7135 // TODO: Complete for other data-types and strides.
7136 // Each combination of Stride, element bit width and VF results in a different
7137 // sequence; The cost tables are therefore accessed with:
7138 // Factor (stride) and VectorType=VFxiN.
7139 // The Cost accounts only for the shuffle sequence;
7140 // The cost of the loads/stores is accounted for separately.
7141 //
7142 static const CostTblEntry AVX2InterleavedLoadTbl[] = {
7143 {2, MVT::v2i8, 2}, // (load 4i8 and) deinterleave into 2 x 2i8
7144 {2, MVT::v4i8, 2}, // (load 8i8 and) deinterleave into 2 x 4i8
7145 {2, MVT::v8i8, 2}, // (load 16i8 and) deinterleave into 2 x 8i8
7146 {2, MVT::v16i8, 4}, // (load 32i8 and) deinterleave into 2 x 16i8
7147 {2, MVT::v32i8, 6}, // (load 64i8 and) deinterleave into 2 x 32i8
7148
7149 {2, MVT::v8i16, 6}, // (load 16i16 and) deinterleave into 2 x 8i16
7150 {2, MVT::v16i16, 9}, // (load 32i16 and) deinterleave into 2 x 16i16
7151 {2, MVT::v32i16, 18}, // (load 64i16 and) deinterleave into 2 x 32i16
7152
7153 {2, MVT::v8i32, 4}, // (load 16i32 and) deinterleave into 2 x 8i32
7154 {2, MVT::v16i32, 8}, // (load 32i32 and) deinterleave into 2 x 16i32
7155 {2, MVT::v32i32, 16}, // (load 64i32 and) deinterleave into 2 x 32i32
7156
7157 {2, MVT::v4i64, 4}, // (load 8i64 and) deinterleave into 2 x 4i64
7158 {2, MVT::v8i64, 8}, // (load 16i64 and) deinterleave into 2 x 8i64
7159 {2, MVT::v16i64, 16}, // (load 32i64 and) deinterleave into 2 x 16i64
7160 {2, MVT::v32i64, 32}, // (load 64i64 and) deinterleave into 2 x 32i64
7161
7162 {3, MVT::v2i8, 3}, // (load 6i8 and) deinterleave into 3 x 2i8
7163 {3, MVT::v4i8, 3}, // (load 12i8 and) deinterleave into 3 x 4i8
7164 {3, MVT::v8i8, 6}, // (load 24i8 and) deinterleave into 3 x 8i8
7165 {3, MVT::v16i8, 11}, // (load 48i8 and) deinterleave into 3 x 16i8
7166 {3, MVT::v32i8, 14}, // (load 96i8 and) deinterleave into 3 x 32i8
7167
7168 {3, MVT::v2i16, 5}, // (load 6i16 and) deinterleave into 3 x 2i16
7169 {3, MVT::v4i16, 7}, // (load 12i16 and) deinterleave into 3 x 4i16
7170 {3, MVT::v8i16, 9}, // (load 24i16 and) deinterleave into 3 x 8i16
7171 {3, MVT::v16i16, 28}, // (load 48i16 and) deinterleave into 3 x 16i16
7172 {3, MVT::v32i16, 56}, // (load 96i16 and) deinterleave into 3 x 32i16
7173
7174 {3, MVT::v2i32, 3}, // (load 6i32 and) deinterleave into 3 x 2i32
7175 {3, MVT::v4i32, 3}, // (load 12i32 and) deinterleave into 3 x 4i32
7176 {3, MVT::v8i32, 7}, // (load 24i32 and) deinterleave into 3 x 8i32
7177 {3, MVT::v16i32, 14}, // (load 48i32 and) deinterleave into 3 x 16i32
7178 {3, MVT::v32i32, 32}, // (load 96i32 and) deinterleave into 3 x 32i32
7179
7180 {3, MVT::v2i64, 1}, // (load 6i64 and) deinterleave into 3 x 2i64
7181 {3, MVT::v4i64, 5}, // (load 12i64 and) deinterleave into 3 x 4i64
7182 {3, MVT::v8i64, 10}, // (load 24i64 and) deinterleave into 3 x 8i64
7183 {3, MVT::v16i64, 20}, // (load 48i64 and) deinterleave into 3 x 16i64
7184
7185 {4, MVT::v2i8, 4}, // (load 8i8 and) deinterleave into 4 x 2i8
7186 {4, MVT::v4i8, 4}, // (load 16i8 and) deinterleave into 4 x 4i8
7187 {4, MVT::v8i8, 12}, // (load 32i8 and) deinterleave into 4 x 8i8
7188 {4, MVT::v16i8, 24}, // (load 64i8 and) deinterleave into 4 x 16i8
7189 {4, MVT::v32i8, 56}, // (load 128i8 and) deinterleave into 4 x 32i8
7190
7191 {4, MVT::v2i16, 6}, // (load 8i16 and) deinterleave into 4 x 2i16
7192 {4, MVT::v4i16, 17}, // (load 16i16 and) deinterleave into 4 x 4i16
7193 {4, MVT::v8i16, 33}, // (load 32i16 and) deinterleave into 4 x 8i16
7194 {4, MVT::v16i16, 75}, // (load 64i16 and) deinterleave into 4 x 16i16
7195 {4, MVT::v32i16, 150}, // (load 128i16 and) deinterleave into 4 x 32i16
7196
7197 {4, MVT::v2i32, 4}, // (load 8i32 and) deinterleave into 4 x 2i32
7198 {4, MVT::v4i32, 8}, // (load 16i32 and) deinterleave into 4 x 4i32
7199 {4, MVT::v8i32, 16}, // (load 32i32 and) deinterleave into 4 x 8i32
7200 {4, MVT::v16i32, 32}, // (load 64i32 and) deinterleave into 4 x 16i32
7201 {4, MVT::v32i32, 68}, // (load 128i32 and) deinterleave into 4 x 32i32
7202
7203 {4, MVT::v2i64, 6}, // (load 8i64 and) deinterleave into 4 x 2i64
7204 {4, MVT::v4i64, 8}, // (load 16i64 and) deinterleave into 4 x 4i64
7205 {4, MVT::v8i64, 20}, // (load 32i64 and) deinterleave into 4 x 8i64
7206 {4, MVT::v16i64, 40}, // (load 64i64 and) deinterleave into 4 x 16i64
7207
7208 {6, MVT::v2i8, 6}, // (load 12i8 and) deinterleave into 6 x 2i8
7209 {6, MVT::v4i8, 14}, // (load 24i8 and) deinterleave into 6 x 4i8
7210 {6, MVT::v8i8, 18}, // (load 48i8 and) deinterleave into 6 x 8i8
7211 {6, MVT::v16i8, 43}, // (load 96i8 and) deinterleave into 6 x 16i8
7212 {6, MVT::v32i8, 82}, // (load 192i8 and) deinterleave into 6 x 32i8
7213
7214 {6, MVT::v2i16, 13}, // (load 12i16 and) deinterleave into 6 x 2i16
7215 {6, MVT::v4i16, 9}, // (load 24i16 and) deinterleave into 6 x 4i16
7216 {6, MVT::v8i16, 39}, // (load 48i16 and) deinterleave into 6 x 8i16
7217 {6, MVT::v16i16, 106}, // (load 96i16 and) deinterleave into 6 x 16i16
7218 {6, MVT::v32i16, 212}, // (load 192i16 and) deinterleave into 6 x 32i16
7219
7220 {6, MVT::v2i32, 6}, // (load 12i32 and) deinterleave into 6 x 2i32
7221 {6, MVT::v4i32, 15}, // (load 24i32 and) deinterleave into 6 x 4i32
7222 {6, MVT::v8i32, 31}, // (load 48i32 and) deinterleave into 6 x 8i32
7223 {6, MVT::v16i32, 64}, // (load 96i32 and) deinterleave into 6 x 16i32
7224
7225 {6, MVT::v2i64, 6}, // (load 12i64 and) deinterleave into 6 x 2i64
7226 {6, MVT::v4i64, 18}, // (load 24i64 and) deinterleave into 6 x 4i64
7227 {6, MVT::v8i64, 36}, // (load 48i64 and) deinterleave into 6 x 8i64
7228
7229 {8, MVT::v8i32, 40} // (load 64i32 and) deinterleave into 8 x 8i32
7230 };
7231
7232 static const CostTblEntry SSSE3InterleavedLoadTbl[] = {
7233 {2, MVT::v4i16, 2}, // (load 8i16 and) deinterleave into 2 x 4i16
7234 };
7235
7236 static const CostTblEntry SSE2InterleavedLoadTbl[] = {
7237 {2, MVT::v2i16, 2}, // (load 4i16 and) deinterleave into 2 x 2i16
7238 {2, MVT::v4i16, 7}, // (load 8i16 and) deinterleave into 2 x 4i16
7239
7240 {2, MVT::v2i32, 2}, // (load 4i32 and) deinterleave into 2 x 2i32
7241 {2, MVT::v4i32, 2}, // (load 8i32 and) deinterleave into 2 x 4i32
7242
7243 {2, MVT::v2i64, 2}, // (load 4i64 and) deinterleave into 2 x 2i64
7244 };
7245
7246 static const CostTblEntry AVX2InterleavedStoreTbl[] = {
7247 {2, MVT::v16i8, 3}, // interleave 2 x 16i8 into 32i8 (and store)
7248 {2, MVT::v32i8, 4}, // interleave 2 x 32i8 into 64i8 (and store)
7249
7250 {2, MVT::v8i16, 3}, // interleave 2 x 8i16 into 16i16 (and store)
7251 {2, MVT::v16i16, 4}, // interleave 2 x 16i16 into 32i16 (and store)
7252 {2, MVT::v32i16, 8}, // interleave 2 x 32i16 into 64i16 (and store)
7253
7254 {2, MVT::v4i32, 2}, // interleave 2 x 4i32 into 8i32 (and store)
7255 {2, MVT::v8i32, 4}, // interleave 2 x 8i32 into 16i32 (and store)
7256 {2, MVT::v16i32, 8}, // interleave 2 x 16i32 into 32i32 (and store)
7257 {2, MVT::v32i32, 16}, // interleave 2 x 32i32 into 64i32 (and store)
7258
7259 {2, MVT::v2i64, 2}, // interleave 2 x 2i64 into 4i64 (and store)
7260 {2, MVT::v4i64, 4}, // interleave 2 x 4i64 into 8i64 (and store)
7261 {2, MVT::v8i64, 8}, // interleave 2 x 8i64 into 16i64 (and store)
7262 {2, MVT::v16i64, 16}, // interleave 2 x 16i64 into 32i64 (and store)
7263 {2, MVT::v32i64, 32}, // interleave 2 x 32i64 into 64i64 (and store)
7264
7265 {3, MVT::v2i8, 4}, // interleave 3 x 2i8 into 6i8 (and store)
7266 {3, MVT::v4i8, 4}, // interleave 3 x 4i8 into 12i8 (and store)
7267 {3, MVT::v8i8, 6}, // interleave 3 x 8i8 into 24i8 (and store)
7268 {3, MVT::v16i8, 11}, // interleave 3 x 16i8 into 48i8 (and store)
7269 {3, MVT::v32i8, 13}, // interleave 3 x 32i8 into 96i8 (and store)
7270
7271 {3, MVT::v2i16, 4}, // interleave 3 x 2i16 into 6i16 (and store)
7272 {3, MVT::v4i16, 6}, // interleave 3 x 4i16 into 12i16 (and store)
7273 {3, MVT::v8i16, 12}, // interleave 3 x 8i16 into 24i16 (and store)
7274 {3, MVT::v16i16, 27}, // interleave 3 x 16i16 into 48i16 (and store)
7275 {3, MVT::v32i16, 54}, // interleave 3 x 32i16 into 96i16 (and store)
7276
7277 {3, MVT::v2i32, 4}, // interleave 3 x 2i32 into 6i32 (and store)
7278 {3, MVT::v4i32, 5}, // interleave 3 x 4i32 into 12i32 (and store)
7279 {3, MVT::v8i32, 11}, // interleave 3 x 8i32 into 24i32 (and store)
7280 {3, MVT::v16i32, 22}, // interleave 3 x 16i32 into 48i32 (and store)
7281 {3, MVT::v32i32, 48}, // interleave 3 x 32i32 into 96i32 (and store)
7282
7283 {3, MVT::v2i64, 4}, // interleave 3 x 2i64 into 6i64 (and store)
7284 {3, MVT::v4i64, 6}, // interleave 3 x 4i64 into 12i64 (and store)
7285 {3, MVT::v8i64, 12}, // interleave 3 x 8i64 into 24i64 (and store)
7286 {3, MVT::v16i64, 24}, // interleave 3 x 16i64 into 48i64 (and store)
7287
7288 {4, MVT::v2i8, 4}, // interleave 4 x 2i8 into 8i8 (and store)
7289 {4, MVT::v4i8, 4}, // interleave 4 x 4i8 into 16i8 (and store)
7290 {4, MVT::v8i8, 4}, // interleave 4 x 8i8 into 32i8 (and store)
7291 {4, MVT::v16i8, 8}, // interleave 4 x 16i8 into 64i8 (and store)
7292 {4, MVT::v32i8, 12}, // interleave 4 x 32i8 into 128i8 (and store)
7293
7294 {4, MVT::v2i16, 2}, // interleave 4 x 2i16 into 8i16 (and store)
7295 {4, MVT::v4i16, 6}, // interleave 4 x 4i16 into 16i16 (and store)
7296 {4, MVT::v8i16, 10}, // interleave 4 x 8i16 into 32i16 (and store)
7297 {4, MVT::v16i16, 32}, // interleave 4 x 16i16 into 64i16 (and store)
7298 {4, MVT::v32i16, 64}, // interleave 4 x 32i16 into 128i16 (and store)
7299
7300 {4, MVT::v2i32, 5}, // interleave 4 x 2i32 into 8i32 (and store)
7301 {4, MVT::v4i32, 6}, // interleave 4 x 4i32 into 16i32 (and store)
7302 {4, MVT::v8i32, 16}, // interleave 4 x 8i32 into 32i32 (and store)
7303 {4, MVT::v16i32, 32}, // interleave 4 x 16i32 into 64i32 (and store)
7304 {4, MVT::v32i32, 64}, // interleave 4 x 32i32 into 128i32 (and store)
7305
7306 {4, MVT::v2i64, 6}, // interleave 4 x 2i64 into 8i64 (and store)
7307 {4, MVT::v4i64, 8}, // interleave 4 x 4i64 into 16i64 (and store)
7308 {4, MVT::v8i64, 20}, // interleave 4 x 8i64 into 32i64 (and store)
7309 {4, MVT::v16i64, 40}, // interleave 4 x 16i64 into 64i64 (and store)
7310
7311 {6, MVT::v2i8, 7}, // interleave 6 x 2i8 into 12i8 (and store)
7312 {6, MVT::v4i8, 9}, // interleave 6 x 4i8 into 24i8 (and store)
7313 {6, MVT::v8i8, 16}, // interleave 6 x 8i8 into 48i8 (and store)
7314 {6, MVT::v16i8, 27}, // interleave 6 x 16i8 into 96i8 (and store)
7315 {6, MVT::v32i8, 90}, // interleave 6 x 32i8 into 192i8 (and store)
7316
7317 {6, MVT::v2i16, 10}, // interleave 6 x 2i16 into 12i16 (and store)
7318 {6, MVT::v4i16, 15}, // interleave 6 x 4i16 into 24i16 (and store)
7319 {6, MVT::v8i16, 21}, // interleave 6 x 8i16 into 48i16 (and store)
7320 {6, MVT::v16i16, 58}, // interleave 6 x 16i16 into 96i16 (and store)
7321 {6, MVT::v32i16, 90}, // interleave 6 x 32i16 into 192i16 (and store)
7322
7323 {6, MVT::v2i32, 9}, // interleave 6 x 2i32 into 12i32 (and store)
7324 {6, MVT::v4i32, 12}, // interleave 6 x 4i32 into 24i32 (and store)
7325 {6, MVT::v8i32, 33}, // interleave 6 x 8i32 into 48i32 (and store)
7326 {6, MVT::v16i32, 66}, // interleave 6 x 16i32 into 96i32 (and store)
7327
7328 {6, MVT::v2i64, 8}, // interleave 6 x 2i64 into 12i64 (and store)
7329 {6, MVT::v4i64, 15}, // interleave 6 x 4i64 into 24i64 (and store)
7330 {6, MVT::v8i64, 30}, // interleave 6 x 8i64 into 48i64 (and store)
7331 };
7332
7333 static const CostTblEntry SSE2InterleavedStoreTbl[] = {
7334 {2, MVT::v2i8, 1}, // interleave 2 x 2i8 into 4i8 (and store)
7335 {2, MVT::v4i8, 1}, // interleave 2 x 4i8 into 8i8 (and store)
7336 {2, MVT::v8i8, 1}, // interleave 2 x 8i8 into 16i8 (and store)
7337
7338 {2, MVT::v2i16, 1}, // interleave 2 x 2i16 into 4i16 (and store)
7339 {2, MVT::v4i16, 1}, // interleave 2 x 4i16 into 8i16 (and store)
7340
7341 {2, MVT::v2i32, 1}, // interleave 2 x 2i32 into 4i32 (and store)
7342 };
7343
7344 if (Opcode == Instruction::Load) {
7345 auto GetDiscountedCost = [Factor, NumMembers = Indices.size(),
7346 MemOpCosts](const CostTblEntry *Entry) {
7347 // NOTE: this is just an approximation!
7348 // It can over/under -estimate the cost!
7349 return MemOpCosts + divideCeil(NumMembers * Entry->Cost, Factor);
7350 };
7351
7352 if (ST->hasAVX2())
7353 if (const auto *Entry = CostTableLookup(AVX2InterleavedLoadTbl, Factor,
7354 ETy.getSimpleVT()))
7355 return GetDiscountedCost(Entry);
7356
7357 if (ST->hasSSSE3())
7358 if (const auto *Entry = CostTableLookup(SSSE3InterleavedLoadTbl, Factor,
7359 ETy.getSimpleVT()))
7360 return GetDiscountedCost(Entry);
7361
7362 if (ST->hasSSE2())
7363 if (const auto *Entry = CostTableLookup(SSE2InterleavedLoadTbl, Factor,
7364 ETy.getSimpleVT()))
7365 return GetDiscountedCost(Entry);
7366 } else {
7367 assert(Opcode == Instruction::Store &&
7368 "Expected Store Instruction at this point");
7369 assert((!Indices.size() || Indices.size() == Factor) &&
7370 "Interleaved store only supports fully-interleaved groups.");
7371 if (ST->hasAVX2())
7372 if (const auto *Entry = CostTableLookup(AVX2InterleavedStoreTbl, Factor,
7373 ETy.getSimpleVT()))
7374 return MemOpCosts + Entry->Cost;
7375
7376 if (ST->hasSSE2())
7377 if (const auto *Entry = CostTableLookup(SSE2InterleavedStoreTbl, Factor,
7378 ETy.getSimpleVT()))
7379 return MemOpCosts + Entry->Cost;
7380 }
7381
7382 return BaseT::getInterleavedMemoryOpCost(Opcode, VecTy, Factor, Indices,
7383 Alignment, AddressSpace, CostKind,
7384 UseMaskForCond, UseMaskForGaps);
7385}
7386
7388 StackOffset BaseOffset,
7389 bool HasBaseReg, int64_t Scale,
7390 unsigned AddrSpace) const {
7391 // Scaling factors are not free at all.
7392 // An indexed folded instruction, i.e., inst (reg1, reg2, scale),
7393 // will take 2 allocations in the out of order engine instead of 1
7394 // for plain addressing mode, i.e. inst (reg1).
7395 // E.g.,
7396 // vaddps (%rsi,%rdx), %ymm0, %ymm1
7397 // Requires two allocations (one for the load, one for the computation)
7398 // whereas:
7399 // vaddps (%rsi), %ymm0, %ymm1
7400 // Requires just 1 allocation, i.e., freeing allocations for other operations
7401 // and having less micro operations to execute.
7402 //
7403 // For some X86 architectures, this is even worse because for instance for
7404 // stores, the complex addressing mode forces the instruction to use the
7405 // "load" ports instead of the dedicated "store" port.
7406 // E.g., on Haswell:
7407 // vmovaps %ymm1, (%r8, %rdi) can use port 2 or 3.
7408 // vmovaps %ymm1, (%r8) can use port 2, 3, or 7.
7410 AM.BaseGV = BaseGV;
7411 AM.BaseOffs = BaseOffset.getFixed();
7412 AM.HasBaseReg = HasBaseReg;
7413 AM.Scale = Scale;
7414 AM.ScalableOffset = BaseOffset.getScalable();
7415 if (getTLI()->isLegalAddressingMode(DL, AM, Ty, AddrSpace))
7416 // Scale represents reg2 * scale, thus account for 1
7417 // as soon as we use a second register.
7418 return AM.Scale != 0;
7420}
7421
7423 // TODO: Hook MispredictPenalty of SchedMachineModel into this.
7424 return 14;
7425}
7426
7428 unsigned Bits = Ty->getScalarSizeInBits();
7429
7430 // XOP has v16i8/v8i16/v4i32/v2i64 variable vector shifts.
7431 // Splitting for v32i8/v16i16 on XOP+AVX2 targets is still preferred.
7432 if (ST->hasXOP() && (Bits == 8 || Bits == 16 || Bits == 32 || Bits == 64))
7433 return false;
7434
7435 // AVX2 has vpsllv[dq] instructions (and other shifts) that make variable
7436 // shifts just as cheap as scalar ones.
7437 if (ST->hasAVX2() && (Bits == 32 || Bits == 64))
7438 return false;
7439
7440 // AVX512BW has shifts such as vpsllvw.
7441 if (ST->hasBWI() && Bits == 16)
7442 return false;
7443
7444 // Otherwise, it's significantly cheaper to shift by a scalar amount than by a
7445 // fully general vector.
7446 return true;
7447}
7448
7449unsigned X86TTIImpl::getStoreMinimumVF(unsigned VF, Type *ScalarMemTy,
7450 Type *ScalarValTy, Align Alignment,
7451 unsigned AddrSpace) const {
7452 if (ST->hasF16C() && ScalarMemTy->isHalfTy()) {
7453 return 4;
7454 }
7455 return BaseT::getStoreMinimumVF(VF, ScalarMemTy, ScalarValTy, Alignment,
7456 AddrSpace);
7457}
7458
7460 SmallVectorImpl<Use *> &Ops) const {
7461 using namespace llvm::PatternMatch;
7462
7463 if (I->getOpcode() == Instruction::And &&
7464 (ST->hasBMI() || (I->getType()->isVectorTy() && ST->hasSSE2()))) {
7465 for (auto &Op : I->operands()) {
7466 // (and X, (not Y)) -> (andn X, Y)
7467 if (match(Op.get(), m_Not(m_Value())) && !I->getType()->isIntegerTy(8)) {
7468 Ops.push_back(&Op);
7469 return true;
7470 }
7471 // (and X, (splat (not Y))) -> (andn X, (splat Y))
7472 if (match(Op.get(),
7474 m_Value(), m_ZeroMask()))) {
7475 Use &InsertElt = cast<Instruction>(Op)->getOperandUse(0);
7476 Use &Not = cast<Instruction>(InsertElt)->getOperandUse(1);
7477 Ops.push_back(&Not);
7478 Ops.push_back(&InsertElt);
7479 Ops.push_back(&Op);
7480 return true;
7481 }
7482 }
7483 }
7484
7485 FixedVectorType *VTy = dyn_cast<FixedVectorType>(I->getType());
7486 if (!VTy)
7487 return false;
7488
7489 if (I->getOpcode() == Instruction::Mul &&
7490 VTy->getElementType()->isIntegerTy(64)) {
7491 for (auto &Op : I->operands()) {
7492 // Make sure we are not already sinking this operand
7493 if (any_of(Ops, [&](Use *U) { return U->get() == Op; }))
7494 continue;
7495
7496 // Look for PMULDQ pattern where the input is a sext_inreg from vXi32 or
7497 // the PMULUDQ pattern where the input is a zext_inreg from vXi32.
7498 if (ST->hasSSE41() &&
7499 match(Op.get(), m_AShr(m_Shl(m_Value(), m_SpecificInt(32)),
7500 m_SpecificInt(32)))) {
7501 Ops.push_back(&cast<Instruction>(Op)->getOperandUse(0));
7502 Ops.push_back(&Op);
7503 } else if (ST->hasSSE2() &&
7504 match(Op.get(),
7505 m_And(m_Value(), m_SpecificInt(UINT64_C(0xffffffff))))) {
7506 Ops.push_back(&Op);
7507 }
7508 }
7509
7510 return !Ops.empty();
7511 }
7512
7513 // A uniform shift amount in a vector shift or funnel shift may be much
7514 // cheaper than a generic variable vector shift, so make that pattern visible
7515 // to SDAG by sinking the shuffle instruction next to the shift.
7516 int ShiftAmountOpNum = -1;
7517 if (I->isShift())
7518 ShiftAmountOpNum = 1;
7519 else if (auto *II = dyn_cast<IntrinsicInst>(I)) {
7520 if (II->getIntrinsicID() == Intrinsic::fshl ||
7521 II->getIntrinsicID() == Intrinsic::fshr)
7522 ShiftAmountOpNum = 2;
7523 }
7524
7525 if (ShiftAmountOpNum == -1)
7526 return false;
7527
7528 auto *Shuf = dyn_cast<ShuffleVectorInst>(I->getOperand(ShiftAmountOpNum));
7529 if (Shuf && getSplatIndex(Shuf->getShuffleMask()) >= 0 &&
7530 isVectorShiftByScalarCheap(I->getType())) {
7531 Ops.push_back(&I->getOperandUse(ShiftAmountOpNum));
7532 return true;
7533 }
7534
7535 return false;
7536}
7537
7539 bool HasEGPR = ST->hasEGPR();
7540 const TargetMachine &TM = getTLI()->getTargetMachine();
7541
7542 for (User *U : F.users()) {
7544 if (!CB || CB->getCalledOperand() != &F)
7545 continue;
7546 Function *CallerFunc = CB->getFunction();
7547 if (TM.getSubtarget<X86Subtarget>(*CallerFunc).hasEGPR() != HasEGPR)
7548 return false;
7549 }
7550
7551 return true;
7552}
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
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
VectorInstrContext
Represents a hint about the context in which an insert/extract is used.
@ None
The insert/extract is not used with a load/store.
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.
@ 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
@ 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:165
@ 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:546
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:385
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:279
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:394
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
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.
auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
Definition Sequence.h:305
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