LLVM 24.0.0git
X86TargetTransformInfo.cpp
Go to the documentation of this file.
1//===-- X86TargetTransformInfo.cpp - X86 specific TTI pass ----------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8/// \file
9/// This file implements a TargetTransformInfo analysis pass specific to the
10/// X86 target machine. It uses the target's detailed information to provide
11/// more precise answers to certain TTI queries, while letting the target
12/// independent and default TTI implementations handle the rest.
13///
14//===----------------------------------------------------------------------===//
15/// About Cost Model numbers used below it's necessary to say the following:
16/// the numbers correspond to some "generic" X86 CPU instead of usage of a
17/// specific CPU model. Usually the numbers correspond to the CPU where the
18/// feature first appeared. For example, if we do Subtarget.hasSSE42() in
19/// the lookups below the cost is based on Nehalem as that was the first CPU
20/// to support that feature level and thus has most likely the worst case cost,
21/// although we may discard an outlying worst cost from one CPU (e.g. Atom).
22///
23/// Some examples of other technologies/CPUs:
24/// SSE 3 - Pentium4 / Athlon64
25/// SSE 4.1 - Penryn
26/// SSE 4.2 - Nehalem / Silvermont
27/// AVX - Sandy Bridge / Jaguar / Bulldozer
28/// AVX2 - Haswell / Ryzen
29/// AVX-512 - Xeon Phi / Skylake
30///
31/// And some examples of instruction target dependent costs (latency)
32/// divss sqrtss rsqrtss
33/// AMD K7 11-16 19 3
34/// Piledriver 9-24 13-15 5
35/// Jaguar 14 16 2
36/// Pentium II,III 18 30 2
37/// Nehalem 7-14 7-18 3
38/// Haswell 10-13 11 5
39///
40/// Interpreting the 4 TargetCostKind types:
41/// TCK_RecipThroughput and TCK_Latency should try to match the worst case
42/// values reported by the CPU scheduler models (and llvm-mca).
43/// TCK_CodeSize should match the instruction count (e.g. divss = 1), NOT the
44/// actual encoding size of the instruction.
45/// TCK_SizeAndLatency should match the worst case micro-op counts reported by
46/// by the CPU scheduler models (and llvm-mca), to ensure that they are
47/// compatible with the MicroOpBufferSize and LoopMicroOpBufferSize values which are
48/// often used as the cost thresholds where TCK_SizeAndLatency is requested.
49//===----------------------------------------------------------------------===//
50
60#include <optional>
61
62using namespace llvm;
63
64#define DEBUG_TYPE "x86tti"
65
66//===----------------------------------------------------------------------===//
67//
68// X86 cost model.
69//
70//===----------------------------------------------------------------------===//
71
72// Helper struct to store/access costs for each cost kind.
73// TODO: Move this to allow other targets to use it?
75 unsigned RecipThroughputCost = ~0U;
76 unsigned LatencyCost = ~0U;
77 unsigned CodeSizeCost = ~0U;
78 unsigned SizeAndLatencyCost = ~0U;
79
80 std::optional<unsigned>
82 unsigned Cost = ~0U;
83 switch (Kind) {
86 break;
89 break;
92 break;
95 break;
96 }
97 if (Cost == ~0U)
98 return std::nullopt;
99 return Cost;
100 }
101};
104
106X86TTIImpl::getPopcntSupport(unsigned TyWidth) const {
107 assert(isPowerOf2_32(TyWidth) && "Ty width must be power of 2");
108 // TODO: Currently the __builtin_popcount() implementation using SSE3
109 // instructions is inefficient. Once the problem is fixed, we should
110 // call ST->hasSSE3() instead of ST->hasPOPCNT().
111 return ST->hasPOPCNT() ? TTI::PSK_FastHardware : TTI::PSK_Software;
112}
113
114std::optional<unsigned> X86TTIImpl::getCacheSize(
116 switch (Level) {
118 // - Penryn
119 // - Nehalem
120 // - Westmere
121 // - Sandy Bridge
122 // - Ivy Bridge
123 // - Haswell
124 // - Broadwell
125 // - Skylake
126 // - Kabylake
127 return 32 * 1024; // 32 KiB
129 // - Penryn
130 // - Nehalem
131 // - Westmere
132 // - Sandy Bridge
133 // - Ivy Bridge
134 // - Haswell
135 // - Broadwell
136 // - Skylake
137 // - Kabylake
138 return 256 * 1024; // 256 KiB
139 }
140
141 llvm_unreachable("Unknown TargetTransformInfo::CacheLevel");
142}
143
144std::optional<unsigned> X86TTIImpl::getCacheAssociativity(
146 // - Penryn
147 // - Nehalem
148 // - Westmere
149 // - Sandy Bridge
150 // - Ivy Bridge
151 // - Haswell
152 // - Broadwell
153 // - Skylake
154 // - Kabylake
155 switch (Level) {
157 [[fallthrough]];
159 return 8;
160 }
161
162 llvm_unreachable("Unknown TargetTransformInfo::CacheLevel");
163}
164
166
168 return Vector ? VectorClass
169 : Ty && Ty->isFloatingPointTy() ? ScalarFPClass
170 : GPRClass;
171}
172
173unsigned X86TTIImpl::getNumberOfRegisters(unsigned ClassID) const {
174 if (ClassID == VectorClass && !ST->hasSSE1())
175 return 0;
176
177 if (!ST->is64Bit())
178 return 8;
179
180 if ((ClassID == GPRClass && ST->hasEGPR()) ||
181 (ClassID != GPRClass && ST->hasAVX512()))
182 return 32;
183
184 return 16;
185}
186
188 if (!ST->hasCF())
189 return false;
190 if (!Ty)
191 return true;
192 // Conditional faulting is supported by CFCMOV, which only accepts
193 // 16/32/64-bit operands.
194 // TODO: Support f32/f64 with VMOVSS/VMOVSD with zero mask when it's
195 // profitable.
196 auto *VTy = dyn_cast<FixedVectorType>(Ty);
197 if (!Ty->isIntegerTy() && (!VTy || VTy->getNumElements() != 1))
198 return false;
199 auto *ScalarTy = Ty->getScalarType();
200 switch (cast<IntegerType>(ScalarTy)->getBitWidth()) {
201 default:
202 return false;
203 case 16:
204 case 32:
205 case 64:
206 return true;
207 }
208}
209
212 unsigned PreferVectorWidth = ST->getPreferVectorWidth();
213 switch (K) {
215 return TypeSize::getFixed(ST->is64Bit() ? 64 : 32);
217 if (ST->hasAVX512() && PreferVectorWidth >= 512)
218 return TypeSize::getFixed(512);
219 if (ST->hasAVX() && PreferVectorWidth >= 256)
220 return TypeSize::getFixed(256);
221 if (ST->hasSSE1() && PreferVectorWidth >= 128)
222 return TypeSize::getFixed(128);
223 return TypeSize::getFixed(0);
225 return TypeSize::getScalable(0);
226 }
227
228 llvm_unreachable("Unsupported register kind");
229}
230
235
237 bool HasUnorderedReductions) const {
238 // If the loop will not be vectorized, don't interleave the loop.
239 // Let regular unroll to unroll the loop, which saves the overflow
240 // check and memory check cost.
241 if (VF.isScalar())
242 return 1;
243
244 if (ST->isAtom())
245 return 1;
246
247 // Sandybridge and Haswell have multiple execution ports and pipelined
248 // vector units.
249 if (ST->hasAVX())
250 return 4;
251
252 return 2;
253}
254
256 unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind,
258 ArrayRef<const Value *> Args, const Instruction *CxtI) const {
259
260 // vXi8 multiplications are always promoted to vXi16.
261 // Sub-128-bit types can be extended/packed more efficiently.
262 if (Opcode == Instruction::Mul && Ty->isVectorTy() &&
263 Ty->getPrimitiveSizeInBits() <= 64 && Ty->getScalarSizeInBits() == 8) {
264 Type *WideVecTy =
266 return getCastInstrCost(Instruction::ZExt, WideVecTy, Ty,
268 CostKind) +
269 getCastInstrCost(Instruction::Trunc, Ty, WideVecTy,
271 CostKind) +
272 getArithmeticInstrCost(Opcode, WideVecTy, CostKind, Op1Info, Op2Info);
273 }
274
275 // Legalize the type.
276 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Ty);
277
278 int ISD = TLI->InstructionOpcodeToISD(Opcode);
279 assert(ISD && "Invalid opcode");
280
281 if (ISD == ISD::MUL && Args.size() == 2 && LT.second.isVector() &&
282 (LT.second.getScalarType() == MVT::i32 ||
283 LT.second.getScalarType() == MVT::i64)) {
284 // Check if the operands can be represented as a smaller datatype.
285 bool Op1Signed = false, Op2Signed = false;
286 unsigned Op1MinSize = BaseT::minRequiredElementSize(Args[0], Op1Signed);
287 unsigned Op2MinSize = BaseT::minRequiredElementSize(Args[1], Op2Signed);
288 unsigned OpMinSize = std::max(Op1MinSize, Op2MinSize);
289 bool SignedMode = Op1Signed || Op2Signed;
290
291 // If both vXi32 are representable as i15 and at least one is constant,
292 // zero-extended, or sign-extended from vXi16 (or less pre-SSE41) then we
293 // can treat this as PMADDWD which has the same costs as a vXi16 multiply.
294 if (OpMinSize <= 15 && !ST->isPMADDWDSlow() &&
295 LT.second.getScalarType() == MVT::i32) {
296 bool Op1Constant =
297 isa<ConstantDataVector>(Args[0]) || isa<ConstantVector>(Args[0]);
298 bool Op2Constant =
299 isa<ConstantDataVector>(Args[1]) || isa<ConstantVector>(Args[1]);
300 bool Op1Sext = isa<SExtInst>(Args[0]) &&
301 (Op1MinSize == 15 || (Op1MinSize < 15 && !ST->hasSSE41()));
302 bool Op2Sext = isa<SExtInst>(Args[1]) &&
303 (Op2MinSize == 15 || (Op2MinSize < 15 && !ST->hasSSE41()));
304
305 bool IsZeroExtended = !Op1Signed || !Op2Signed;
306 bool IsConstant = Op1Constant || Op2Constant;
307 bool IsSext = Op1Sext || Op2Sext;
308 if (IsConstant || IsZeroExtended || IsSext)
309 LT.second =
310 MVT::getVectorVT(MVT::i16, 2 * LT.second.getVectorNumElements());
311 }
312
313 // Check if the vXi32 operands can be shrunk into a smaller datatype.
314 // This should match the codegen from reduceVMULWidth.
315 // TODO: Make this generic (!ST->SSE41 || ST->isPMULLDSlow()).
316 if (ST->useSLMArithCosts() && LT.second == MVT::v4i32) {
317 if (OpMinSize <= 7)
318 return LT.first * 3; // pmullw/sext
319 if (!SignedMode && OpMinSize <= 8)
320 return LT.first * 3; // pmullw/zext
321 if (OpMinSize <= 15)
322 return LT.first * 5; // pmullw/pmulhw/pshuf
323 if (!SignedMode && OpMinSize <= 16)
324 return LT.first * 5; // pmullw/pmulhw/pshuf
325 }
326
327 // If both vXi64 are representable as (unsigned) i32, then we can perform
328 // the multiple with a single PMULUDQ instruction.
329 // TODO: Add (SSE41+) PMULDQ handling for signed extensions.
330 if (!SignedMode && OpMinSize <= 32 && LT.second.getScalarType() == MVT::i64)
331 ISD = X86ISD::PMULUDQ;
332 }
333
334 // Vector multiply by pow2 will be simplified to shifts.
335 // Vector multiply by -pow2 will be simplified to shifts/negates.
336 if (ISD == ISD::MUL && Op2Info.isConstant() &&
337 (Op2Info.isPowerOf2() || Op2Info.isNegatedPowerOf2())) {
339 getArithmeticInstrCost(Instruction::Shl, Ty, CostKind,
340 Op1Info.getNoProps(), Op2Info.getNoProps());
341 if (Op2Info.isNegatedPowerOf2())
342 Cost += getArithmeticInstrCost(Instruction::Sub, Ty, CostKind);
343 return Cost;
344 }
345
346 // On X86, vector signed division by constants power-of-two are
347 // normally expanded to the sequence SRA + SRL + ADD + SRA.
348 // The OperandValue properties may not be the same as that of the previous
349 // operation; conservatively assume OP_None.
350 if ((ISD == ISD::SDIV || ISD == ISD::SREM) &&
351 Op2Info.isConstant() && Op2Info.isPowerOf2()) {
353 2 * getArithmeticInstrCost(Instruction::AShr, Ty, CostKind,
354 Op1Info.getNoProps(), Op2Info.getNoProps());
355 Cost += getArithmeticInstrCost(Instruction::LShr, Ty, CostKind,
356 Op1Info.getNoProps(), Op2Info.getNoProps());
357 Cost += getArithmeticInstrCost(Instruction::Add, Ty, CostKind,
358 Op1Info.getNoProps(), Op2Info.getNoProps());
359
360 if (ISD == ISD::SREM) {
361 // For SREM: (X % C) is the equivalent of (X - (X/C)*C)
362 Cost += getArithmeticInstrCost(Instruction::Mul, Ty, CostKind, Op1Info.getNoProps(),
363 Op2Info.getNoProps());
364 Cost += getArithmeticInstrCost(Instruction::Sub, Ty, CostKind, Op1Info.getNoProps(),
365 Op2Info.getNoProps());
366 }
367
368 return Cost;
369 }
370
371 // Vector unsigned division/remainder will be simplified to shifts/masks.
372 if ((ISD == ISD::UDIV || ISD == ISD::UREM) &&
373 Op2Info.isConstant() && Op2Info.isPowerOf2()) {
374 if (ISD == ISD::UDIV)
375 return getArithmeticInstrCost(Instruction::LShr, Ty, CostKind,
376 Op1Info.getNoProps(), Op2Info.getNoProps());
377 // UREM
378 return getArithmeticInstrCost(Instruction::And, Ty, CostKind,
379 Op1Info.getNoProps(), Op2Info.getNoProps());
380 }
381
382 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 PCLMULCostTbl[] = {
4500 { ISD::CLMUL, MVT::v2i64, { 3, 12, 4, 8 } }, // MOV+2xPCLMUL+unpack
4501 { ISD::CLMUL, MVT::v4i32, { 8, 18, 12, 16 } }, // MOV+4xPCLMUL+unpack
4502 { ISD::CLMUL, MVT::i64, { 3, 12, 4, 8 } }, // MOV+PCLMUL+MOV
4503 { ISD::CLMUL, MVT::i32, { 3, 12, 4, 8 } }, // MOV+PCLMUL+MOV
4504 { ISD::CLMUL, MVT::i16, { 3, 12, 4, 8 } }, // MOV+PCLMUL+MOV
4505 { ISD::CLMUL, MVT::i8, { 3, 12, 4, 8 } }, // MOV+PCLMUL+MOV
4506 };
4507 static const CostKindTblEntry X64CostTbl[] = { // 64-bit targets
4508 { ISD::ABS, MVT::i64, { 1, 2, 3, 3 } }, // SUB+CMOV
4509 { ISD::BITREVERSE, MVT::i64, { 10, 12, 20, 22 } },
4510 { ISD::BSWAP, MVT::i64, { 1, 2, 1, 2 } },
4511 { ISD::CTLZ, MVT::i64, { 1, 2, 3, 3 } }, // MOV+BSR+XOR
4512 { ISD::CTLZ, MVT::i32, { 1, 2, 3, 3 } }, // MOV+BSR+XOR
4513 { ISD::CTLZ, MVT::i16, { 2, 2, 3, 3 } }, // MOV+BSR+XOR
4514 { ISD::CTLZ, MVT::i8, { 2, 2, 4, 3 } }, // MOV+BSR+XOR
4515 { ISD::CTLZ_ZERO_POISON,MVT::i64,{ 1, 2, 2, 2 } }, // BSR+XOR
4516 { ISD::CTTZ, MVT::i64, { 1, 2, 2, 2 } }, // MOV+BSF
4517 { ISD::CTTZ, MVT::i32, { 1, 2, 2, 2 } }, // MOV+BSF
4518 { ISD::CTTZ, MVT::i16, { 2, 2, 2, 2 } }, // MOV+BSF
4519 { ISD::CTTZ, MVT::i8, { 2, 2, 2, 2 } }, // MOV+BSF
4520 { ISD::CTTZ_ZERO_POISON,MVT::i64,{ 1, 2, 1, 2 } }, // BSF
4521 { ISD::CTPOP, MVT::i64, { 10, 6, 19, 19 } },
4522 { ISD::ROTL, MVT::i64, { 2, 3, 1, 3 } },
4523 { ISD::ROTR, MVT::i64, { 2, 3, 1, 3 } },
4524 { X86ISD::VROTLI, MVT::i64, { 1, 1, 1, 1 } },
4525 { ISD::FSHL, MVT::i64, { 4, 4, 1, 4 } },
4526 { ISD::SADDSAT, MVT::i64, { 4, 4, 7, 10 } },
4527 { ISD::SSUBSAT, MVT::i64, { 4, 5, 8, 11 } },
4528 { ISD::UADDSAT, MVT::i64, { 2, 3, 4, 7 } },
4529 { ISD::USUBSAT, MVT::i64, { 2, 3, 4, 7 } },
4530 { ISD::SMAX, MVT::i64, { 1, 3, 2, 3 } },
4531 { ISD::SMIN, MVT::i64, { 1, 3, 2, 3 } },
4532 { ISD::UMAX, MVT::i64, { 1, 3, 2, 3 } },
4533 { ISD::UMIN, MVT::i64, { 1, 3, 2, 3 } },
4534 { ISD::SADDO, MVT::i64, { 2, 2, 4, 6 } },
4535 { ISD::UADDO, MVT::i64, { 2, 2, 4, 6 } },
4536 { ISD::SMULO, MVT::i64, { 4, 4, 4, 6 } },
4537 { ISD::UMULO, MVT::i64, { 8, 8, 4, 7 } },
4538 };
4539 static const CostKindTblEntry X86CostTbl[] = { // 32 or 64-bit targets
4540 { ISD::ABS, MVT::i32, { 1, 2, 3, 3 } }, // SUB+XOR+SRA or SUB+CMOV
4541 { ISD::ABS, MVT::i16, { 2, 2, 3, 3 } }, // SUB+XOR+SRA or SUB+CMOV
4542 { ISD::ABS, MVT::i8, { 2, 4, 4, 3 } }, // SUB+XOR+SRA
4543 { ISD::BITREVERSE, MVT::i32, { 9, 12, 17, 19 } },
4544 { ISD::BITREVERSE, MVT::i16, { 9, 12, 17, 19 } },
4545 { ISD::BITREVERSE, MVT::i8, { 7, 9, 13, 14 } },
4546 { ISD::BSWAP, MVT::i32, { 1, 1, 1, 1 } },
4547 { ISD::BSWAP, MVT::i16, { 1, 2, 1, 2 } }, // ROL
4548 { ISD::CTLZ, MVT::i32, { 2, 2, 4, 5 } }, // BSR+XOR or BSR+XOR+CMOV
4549 { ISD::CTLZ, MVT::i16, { 2, 2, 4, 5 } }, // BSR+XOR or BSR+XOR+CMOV
4550 { ISD::CTLZ, MVT::i8, { 2, 2, 5, 6 } }, // BSR+XOR or BSR+XOR+CMOV
4551 { ISD::CTLZ_ZERO_POISON,MVT::i32,{ 1, 2, 2, 2 } }, // BSR+XOR
4552 { ISD::CTLZ_ZERO_POISON,MVT::i16,{ 2, 2, 2, 2 } }, // BSR+XOR
4553 { ISD::CTLZ_ZERO_POISON,MVT::i8, { 2, 2, 3, 3 } }, // BSR+XOR
4554 { ISD::CTTZ, MVT::i32, { 2, 2, 3, 3 } }, // TEST+BSF+CMOV/BRANCH
4555 { ISD::CTTZ, MVT::i16, { 2, 2, 2, 3 } }, // TEST+BSF+CMOV/BRANCH
4556 { ISD::CTTZ, MVT::i8, { 2, 2, 2, 3 } }, // TEST+BSF+CMOV/BRANCH
4557 { ISD::CTTZ_ZERO_POISON,MVT::i32,{ 1, 2, 1, 2 } }, // BSF
4558 { ISD::CTTZ_ZERO_POISON,MVT::i16,{ 2, 2, 1, 2 } }, // BSF
4559 { ISD::CTTZ_ZERO_POISON,MVT::i8, { 2, 2, 1, 2 } }, // BSF
4560 { ISD::CTPOP, MVT::i32, { 8, 7, 15, 15 } },
4561 { ISD::CTPOP, MVT::i16, { 9, 8, 17, 17 } },
4562 { ISD::CTPOP, MVT::i8, { 7, 6, 6, 6 } },
4563 { ISD::ROTL, MVT::i32, { 2, 3, 1, 3 } },
4564 { ISD::ROTL, MVT::i16, { 2, 3, 1, 3 } },
4565 { ISD::ROTL, MVT::i8, { 2, 3, 1, 3 } },
4566 { ISD::ROTR, MVT::i32, { 2, 3, 1, 3 } },
4567 { ISD::ROTR, MVT::i16, { 2, 3, 1, 3 } },
4568 { ISD::ROTR, MVT::i8, { 2, 3, 1, 3 } },
4569 { X86ISD::VROTLI, MVT::i32, { 1, 1, 1, 1 } },
4570 { X86ISD::VROTLI, MVT::i16, { 1, 1, 1, 1 } },
4571 { X86ISD::VROTLI, MVT::i8, { 1, 1, 1, 1 } },
4572 { ISD::FSHL, MVT::i32, { 4, 4, 1, 4 } },
4573 { ISD::FSHL, MVT::i16, { 4, 4, 2, 5 } },
4574 { ISD::FSHL, MVT::i8, { 4, 4, 2, 5 } },
4575 { ISD::SADDSAT, MVT::i32, { 3, 4, 6, 9 } },
4576 { ISD::SADDSAT, MVT::i16, { 4, 4, 7, 10 } },
4577 { ISD::SADDSAT, MVT::i8, { 4, 5, 8, 11 } },
4578 { ISD::SSUBSAT, MVT::i32, { 4, 4, 7, 10 } },
4579 { ISD::SSUBSAT, MVT::i16, { 4, 4, 7, 10 } },
4580 { ISD::SSUBSAT, MVT::i8, { 4, 5, 8, 11 } },
4581 { ISD::UADDSAT, MVT::i32, { 2, 3, 4, 7 } },
4582 { ISD::UADDSAT, MVT::i16, { 2, 3, 4, 7 } },
4583 { ISD::UADDSAT, MVT::i8, { 3, 3, 5, 8 } },
4584 { ISD::USUBSAT, MVT::i32, { 2, 3, 4, 7 } },
4585 { ISD::USUBSAT, MVT::i16, { 2, 3, 4, 7 } },
4586 { ISD::USUBSAT, MVT::i8, { 3, 3, 5, 8 } },
4587 { ISD::SMAX, MVT::i32, { 1, 2, 2, 3 } },
4588 { ISD::SMAX, MVT::i16, { 1, 4, 2, 4 } },
4589 { ISD::SMAX, MVT::i8, { 1, 4, 2, 4 } },
4590 { ISD::SMIN, MVT::i32, { 1, 2, 2, 3 } },
4591 { ISD::SMIN, MVT::i16, { 1, 4, 2, 4 } },
4592 { ISD::SMIN, MVT::i8, { 1, 4, 2, 4 } },
4593 { ISD::UMAX, MVT::i32, { 1, 2, 2, 3 } },
4594 { ISD::UMAX, MVT::i16, { 1, 4, 2, 4 } },
4595 { ISD::UMAX, MVT::i8, { 1, 4, 2, 4 } },
4596 { ISD::UMIN, MVT::i32, { 1, 2, 2, 3 } },
4597 { ISD::UMIN, MVT::i16, { 1, 4, 2, 4 } },
4598 { ISD::UMIN, MVT::i8, { 1, 4, 2, 4 } },
4599 { ISD::SADDO, MVT::i32, { 2, 2, 4, 6 } },
4600 { ISD::SADDO, MVT::i16, { 2, 2, 4, 6 } },
4601 { ISD::SADDO, MVT::i8, { 2, 2, 4, 6 } },
4602 { ISD::UADDO, MVT::i32, { 2, 2, 4, 6 } },
4603 { ISD::UADDO, MVT::i16, { 2, 2, 4, 6 } },
4604 { ISD::UADDO, MVT::i8, { 2, 2, 4, 6 } },
4605 { ISD::SMULO, MVT::i32, { 2, 2, 4, 6 } },
4606 { ISD::SMULO, MVT::i16, { 5, 5, 4, 6 } },
4607 { ISD::SMULO, MVT::i8, { 6, 6, 4, 6 } },
4608 { ISD::UMULO, MVT::i32, { 6, 6, 4, 8 } },
4609 { ISD::UMULO, MVT::i16, { 6, 6, 4, 9 } },
4610 { ISD::UMULO, MVT::i8, { 6, 6, 4, 6 } },
4611 };
4612
4613 Type *RetTy = ICA.getReturnType();
4614 Type *OpTy = RetTy;
4615 Intrinsic::ID IID = ICA.getID();
4616 unsigned ISD = ISD::DELETED_NODE;
4617 switch (IID) {
4618 default:
4619 break;
4620 case Intrinsic::abs:
4621 ISD = ISD::ABS;
4622 break;
4623 case Intrinsic::bitreverse:
4625 break;
4626 case Intrinsic::bswap:
4627 ISD = ISD::BSWAP;
4628 break;
4629 case Intrinsic::ctlz:
4630 ISD = ISD::CTLZ;
4631 break;
4632 case Intrinsic::ctpop:
4633 ISD = ISD::CTPOP;
4634 break;
4635 case Intrinsic::cttz:
4636 ISD = ISD::CTTZ;
4637 break;
4638 case Intrinsic::fshl:
4639 ISD = ISD::FSHL;
4640 if (!ICA.isTypeBasedOnly()) {
4641 const SmallVectorImpl<const Value *> &Args = ICA.getArgs();
4642 if (Args[0] == Args[1]) {
4643 ISD = ISD::ROTL;
4644 // Handle uniform constant rotation amounts.
4645 // TODO: Handle funnel-shift cases.
4646 const APInt *Amt;
4647 if (Args[2] &&
4649 ISD = X86ISD::VROTLI;
4650 }
4651 }
4652 break;
4653 case Intrinsic::fshr:
4654 // FSHR has same costs so don't duplicate.
4655 ISD = ISD::FSHL;
4656 if (!ICA.isTypeBasedOnly()) {
4657 const SmallVectorImpl<const Value *> &Args = ICA.getArgs();
4658 if (Args[0] == Args[1]) {
4659 ISD = ISD::ROTR;
4660 // Handle uniform constant rotation amount.
4661 // TODO: Handle funnel-shift cases.
4662 const APInt *Amt;
4663 if (Args[2] &&
4665 ISD = X86ISD::VROTLI;
4666 }
4667 }
4668 break;
4669 case Intrinsic::lrint:
4670 case Intrinsic::llrint: {
4671 // X86 can use the CVTP2SI instructions to lower lrint/llrint calls, which
4672 // have the same costs as the CVTTP2SI (fptosi) instructions
4673 const SmallVectorImpl<Type *> &ArgTys = ICA.getArgTypes();
4674 return getCastInstrCost(Instruction::FPToSI, RetTy, ArgTys[0],
4676 }
4677 case Intrinsic::maxnum:
4678 case Intrinsic::minnum:
4679 // FMINNUM has same costs so don't duplicate.
4680 ISD = ISD::FMAXNUM;
4681 break;
4682 case Intrinsic::sadd_sat:
4683 ISD = ISD::SADDSAT;
4684 break;
4685 case Intrinsic::smax:
4686 ISD = ISD::SMAX;
4687 break;
4688 case Intrinsic::smin:
4689 ISD = ISD::SMIN;
4690 break;
4691 case Intrinsic::ssub_sat:
4692 ISD = ISD::SSUBSAT;
4693 break;
4694 case Intrinsic::uadd_sat:
4695 ISD = ISD::UADDSAT;
4696 break;
4697 case Intrinsic::umax:
4698 ISD = ISD::UMAX;
4699 break;
4700 case Intrinsic::umin:
4701 ISD = ISD::UMIN;
4702 break;
4703 case Intrinsic::usub_sat:
4704 ISD = ISD::USUBSAT;
4705 break;
4706 case Intrinsic::sqrt:
4707 ISD = ISD::FSQRT;
4708 break;
4709 case Intrinsic::sadd_with_overflow:
4710 case Intrinsic::ssub_with_overflow:
4711 // SSUBO has same costs so don't duplicate.
4712 ISD = ISD::SADDO;
4713 OpTy = RetTy->getContainedType(0);
4714 break;
4715 case Intrinsic::uadd_with_overflow:
4716 case Intrinsic::usub_with_overflow:
4717 // USUBO has same costs so don't duplicate.
4718 ISD = ISD::UADDO;
4719 OpTy = RetTy->getContainedType(0);
4720 break;
4721 case Intrinsic::smul_with_overflow:
4722 ISD = ISD::SMULO;
4723 OpTy = RetTy->getContainedType(0);
4724 break;
4725 case Intrinsic::umul_with_overflow:
4726 ISD = ISD::UMULO;
4727 OpTy = RetTy->getContainedType(0);
4728 break;
4729 case Intrinsic::clmul:
4730 ISD = ISD::CLMUL;
4731 break;
4732 }
4733
4734 if (ISD != ISD::DELETED_NODE) {
4735 auto adjustTableCost = [&](int ISD, unsigned Cost,
4736 std::pair<InstructionCost, MVT> LT,
4738 InstructionCost LegalizationCost = LT.first;
4739 MVT MTy = LT.second;
4740
4741 // If there are no NANs to deal with, then these are reduced to a
4742 // single MIN** or MAX** instruction instead of the MIN/CMP/SELECT that we
4743 // assume is used in the non-fast case.
4744 if (ISD == ISD::FMAXNUM || ISD == ISD::FMINNUM) {
4745 if (FMF.noNaNs())
4746 return LegalizationCost * 1;
4747 }
4748
4749 // For cases where some ops can be folded into a load/store, assume free.
4750 if (MTy.isScalarInteger()) {
4751 if (ISD == ISD::BSWAP && ST->hasMOVBE() && ST->hasFastMOVBE()) {
4752 if (const Instruction *II = ICA.getInst()) {
4753 if (II->hasOneUse() && isa<StoreInst>(II->user_back()))
4754 return TTI::TCC_Free;
4755 if (auto *LI = dyn_cast<LoadInst>(II->getOperand(0))) {
4756 if (LI->hasOneUse())
4757 return TTI::TCC_Free;
4758 }
4759 }
4760 }
4761 }
4762
4763 return LegalizationCost * (int)Cost;
4764 };
4765
4766 // Legalize the type.
4767 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(OpTy);
4768 MVT MTy = LT.second;
4769
4770 // Without BMI/LZCNT see if we're only looking for a *_ZERO_POISON cost.
4771 if (((ISD == ISD::CTTZ && !ST->hasBMI()) ||
4772 (ISD == ISD::CTLZ && !ST->hasLZCNT())) &&
4773 !MTy.isVector() && !ICA.isTypeBasedOnly()) {
4774 const SmallVectorImpl<const Value *> &Args = ICA.getArgs();
4775 if (auto *Cst = dyn_cast<ConstantInt>(Args[1]))
4776 if (Cst->isAllOnesValue())
4777 ISD =
4779 }
4780
4781 // FSQRT is a single instruction.
4783 return LT.first;
4784
4785 if (ST->useGLMDivSqrtCosts())
4786 if (const auto *Entry = CostTableLookup(GLMCostTbl, ISD, MTy))
4787 if (auto KindCost = Entry->Cost[CostKind])
4788 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4789
4790 if (ST->useSLMArithCosts())
4791 if (const auto *Entry = CostTableLookup(SLMCostTbl, ISD, MTy))
4792 if (auto KindCost = Entry->Cost[CostKind])
4793 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4794
4795 if (ST->hasVBMI2())
4796 if (const auto *Entry = CostTableLookup(AVX512VBMI2CostTbl, ISD, MTy))
4797 if (auto KindCost = Entry->Cost[CostKind])
4798 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4799
4800 if (ST->hasBITALG())
4801 if (const auto *Entry = CostTableLookup(AVX512BITALGCostTbl, ISD, MTy))
4802 if (auto KindCost = Entry->Cost[CostKind])
4803 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4804
4805 if (ST->hasVPOPCNTDQ())
4806 if (const auto *Entry = CostTableLookup(AVX512VPOPCNTDQCostTbl, ISD, MTy))
4807 if (auto KindCost = Entry->Cost[CostKind])
4808 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4809
4810 if (ST->hasGFNI())
4811 if (const auto *Entry = CostTableLookup(GFNICostTbl, ISD, MTy))
4812 if (auto KindCost = Entry->Cost[CostKind])
4813 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4814
4815 if (ST->hasCDI())
4816 if (const auto *Entry = CostTableLookup(AVX512CDCostTbl, ISD, MTy))
4817 if (auto KindCost = Entry->Cost[CostKind])
4818 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4819
4820 if (ST->hasBWI())
4821 if (const auto *Entry = CostTableLookup(AVX512BWCostTbl, ISD, MTy))
4822 if (auto KindCost = Entry->Cost[CostKind])
4823 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4824
4825 if (ST->hasAVX512())
4826 if (const auto *Entry = CostTableLookup(AVX512CostTbl, ISD, MTy))
4827 if (auto KindCost = Entry->Cost[CostKind])
4828 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4829
4830 if (ST->hasXOP())
4831 if (const auto *Entry = CostTableLookup(XOPCostTbl, ISD, MTy))
4832 if (auto KindCost = Entry->Cost[CostKind])
4833 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4834
4835 if (ST->hasAVX2())
4836 if (const auto *Entry = CostTableLookup(AVX2CostTbl, ISD, MTy))
4837 if (auto KindCost = Entry->Cost[CostKind])
4838 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4839
4840 if (ST->hasAVX())
4841 if (const auto *Entry = CostTableLookup(AVX1CostTbl, ISD, MTy))
4842 if (auto KindCost = Entry->Cost[CostKind])
4843 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4844
4845 if (ST->hasSSE42())
4846 if (const auto *Entry = CostTableLookup(SSE42CostTbl, ISD, MTy))
4847 if (auto KindCost = Entry->Cost[CostKind])
4848 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4849
4850 if (ST->hasSSE41())
4851 if (const auto *Entry = CostTableLookup(SSE41CostTbl, ISD, MTy))
4852 if (auto KindCost = Entry->Cost[CostKind])
4853 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4854
4855 if (ST->hasSSSE3())
4856 if (const auto *Entry = CostTableLookup(SSSE3CostTbl, ISD, MTy))
4857 if (auto KindCost = Entry->Cost[CostKind])
4858 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4859
4860 if (ST->hasSSE2())
4861 if (const auto *Entry = CostTableLookup(SSE2CostTbl, ISD, MTy))
4862 if (auto KindCost = Entry->Cost[CostKind])
4863 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4864
4865 if (ST->hasSSE1())
4866 if (const auto *Entry = CostTableLookup(SSE1CostTbl, ISD, MTy))
4867 if (auto KindCost = Entry->Cost[CostKind])
4868 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4869
4870 if (ST->hasBMI()) {
4871 if (ST->is64Bit())
4872 if (const auto *Entry = CostTableLookup(BMI64CostTbl, 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(BMI32CostTbl, ISD, MTy))
4877 if (auto KindCost = Entry->Cost[CostKind])
4878 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4879 }
4880
4881 if (ST->hasLZCNT()) {
4882 if (ST->is64Bit())
4883 if (const auto *Entry = CostTableLookup(LZCNT64CostTbl, 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(LZCNT32CostTbl, ISD, MTy))
4888 if (auto KindCost = Entry->Cost[CostKind])
4889 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4890 }
4891
4892 if (ST->hasPOPCNT()) {
4893 if (ST->is64Bit())
4894 if (const auto *Entry = CostTableLookup(POPCNT64CostTbl, ISD, MTy))
4895 if (auto KindCost = Entry->Cost[CostKind])
4896 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4897
4898 if (const auto *Entry = CostTableLookup(POPCNT32CostTbl, ISD, MTy))
4899 if (auto KindCost = Entry->Cost[CostKind])
4900 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4901 }
4902
4903 // FIXME: PCLMUL w/ AVX/AVX512 and VPCLMULQDQ are not handled properly.
4904 if (ST->hasPCLMUL())
4905 if (const auto *Entry = CostTableLookup(PCLMULCostTbl, ISD, MTy))
4906 if (auto KindCost = Entry->Cost[CostKind])
4907 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4908
4909 if (ST->is64Bit())
4910 if (const auto *Entry = CostTableLookup(X64CostTbl, ISD, MTy))
4911 if (auto KindCost = Entry->Cost[CostKind])
4912 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4913
4914 if (const auto *Entry = CostTableLookup(X86CostTbl, ISD, MTy))
4915 if (auto KindCost = Entry->Cost[CostKind])
4916 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4917
4918 // Without arg data, we need to compute the expanded costs of custom lowered
4919 // intrinsics to prevent use of the (very low) default costs.
4920 if (ICA.isTypeBasedOnly() &&
4921 (IID == Intrinsic::fshl || IID == Intrinsic::fshr)) {
4922 Type *CondTy = RetTy->getWithNewBitWidth(1);
4924 Cost += getArithmeticInstrCost(BinaryOperator::Or, RetTy, CostKind);
4925 Cost += getArithmeticInstrCost(BinaryOperator::Sub, RetTy, CostKind);
4926 Cost += getArithmeticInstrCost(BinaryOperator::Shl, RetTy, CostKind);
4927 Cost += getArithmeticInstrCost(BinaryOperator::LShr, RetTy, CostKind);
4928 Cost += getArithmeticInstrCost(BinaryOperator::And, RetTy, CostKind);
4929 Cost += getCmpSelInstrCost(BinaryOperator::ICmp, RetTy, CondTy,
4931 Cost += getCmpSelInstrCost(BinaryOperator::Select, RetTy, CondTy,
4933 return Cost;
4934 }
4935 }
4936
4938}
4939
4941 unsigned Opcode, Type *Val, TTI::TargetCostKind CostKind, unsigned Index,
4942 const Value *Op0, const Value *Op1, TTI::VectorInstrContext VIC) const {
4943 static const CostTblEntry SLMCostTbl[] = {
4944 { ISD::EXTRACT_VECTOR_ELT, MVT::i8, 4 },
4945 { ISD::EXTRACT_VECTOR_ELT, MVT::i16, 4 },
4946 { ISD::EXTRACT_VECTOR_ELT, MVT::i32, 4 },
4947 { ISD::EXTRACT_VECTOR_ELT, MVT::i64, 7 }
4948 };
4949
4950 assert(Val->isVectorTy() && "This must be a vector type");
4951 auto *VT = cast<VectorType>(Val);
4952 if (VT->isScalableTy())
4954
4955 Type *ScalarType = Val->getScalarType();
4956 InstructionCost RegisterFileMoveCost = 0;
4957
4958 // Non-immediate extraction/insertion can be handled as a sequence of
4959 // aliased loads+stores via the stack.
4960 if (Index == -1U && (Opcode == Instruction::ExtractElement ||
4961 Opcode == Instruction::InsertElement)) {
4962 // TODO: On some SSE41+ targets, we expand to cmp+splat+select patterns:
4963 // inselt N0, N1, N2 --> select (SplatN2 == {0,1,2...}) ? SplatN1 : N0.
4964
4965 // TODO: Move this to BasicTTIImpl.h? We'd need better gep + index handling.
4966 assert(isa<FixedVectorType>(Val) && "Fixed vector type expected");
4967 Align VecAlign = DL.getPrefTypeAlign(Val);
4968 Align SclAlign = DL.getPrefTypeAlign(ScalarType);
4969
4970 // Extract - store vector to stack, load scalar.
4971 if (Opcode == Instruction::ExtractElement) {
4972 return getMemoryOpCost(Instruction::Store, Val, VecAlign, 0, CostKind) +
4973 getMemoryOpCost(Instruction::Load, ScalarType, SclAlign, 0,
4974 CostKind);
4975 }
4976 // Insert - store vector to stack, store scalar, load vector.
4977 if (Opcode == Instruction::InsertElement) {
4978 return getMemoryOpCost(Instruction::Store, Val, VecAlign, 0, CostKind) +
4979 getMemoryOpCost(Instruction::Store, ScalarType, SclAlign, 0,
4980 CostKind) +
4981 getMemoryOpCost(Instruction::Load, Val, VecAlign, 0, CostKind);
4982 }
4983 }
4984
4985 if (Index != -1U && (Opcode == Instruction::ExtractElement ||
4986 Opcode == Instruction::InsertElement)) {
4987 // Extraction of vXi1 elements are now efficiently handled by MOVMSK.
4988 if (Opcode == Instruction::ExtractElement &&
4989 ScalarType->getScalarSizeInBits() == 1 &&
4990 cast<FixedVectorType>(Val)->getNumElements() > 1)
4991 return 1;
4992
4993 // Legalize the type.
4994 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Val);
4995
4996 // This type is legalized to a scalar type.
4997 if (!LT.second.isVector())
4998 return TTI::TCC_Free;
4999
5000 // The type may be split. Normalize the index to the new type.
5001 unsigned SizeInBits = LT.second.getSizeInBits();
5002 unsigned NumElts = LT.second.getVectorNumElements();
5003 unsigned SubNumElts = NumElts;
5004 Index = Index % NumElts;
5005
5006 // For >128-bit vectors, we need to extract higher 128-bit subvectors.
5007 // For inserts, we also need to insert the subvector back.
5008 if (SizeInBits > 128) {
5009 assert((SizeInBits % 128) == 0 && "Illegal vector");
5010 unsigned NumSubVecs = SizeInBits / 128;
5011 SubNumElts = NumElts / NumSubVecs;
5012 if (SubNumElts <= Index) {
5013 RegisterFileMoveCost += (Opcode == Instruction::InsertElement ? 2 : 1);
5014 Index %= SubNumElts;
5015 }
5016 }
5017
5018 MVT MScalarTy = LT.second.getScalarType();
5019 auto IsCheapPInsrPExtrInsertPS = [&]() {
5020 // Assume pinsr/pextr XMM <-> GPR is relatively cheap on all targets.
5021 // Inserting f32 into index0 is just movss.
5022 // Also, assume insertps is relatively cheap on all >= SSE41 targets.
5023 return (MScalarTy == MVT::i16 && ST->hasSSE2()) ||
5024 (MScalarTy.isInteger() && ST->hasSSE41()) ||
5025 (MScalarTy == MVT::f32 && ST->hasSSE1() && Index == 0 &&
5026 Opcode == Instruction::InsertElement) ||
5027 (MScalarTy == MVT::f32 && ST->hasSSE41() &&
5028 Opcode == Instruction::InsertElement);
5029 };
5030
5031 if (Index == 0) {
5032 // Floating point scalars are already located in index #0.
5033 // Many insertions to #0 can fold away for scalar fp-ops, so let's assume
5034 // true for all.
5035 if (ScalarType->isFloatingPointTy() &&
5036 (Opcode != Instruction::InsertElement || !Op0 ||
5037 isa<UndefValue>(Op0)))
5038 return RegisterFileMoveCost;
5039
5040 if (Opcode == Instruction::InsertElement &&
5042 // Consider the gather cost to be cheap.
5044 return RegisterFileMoveCost;
5045 if (!IsCheapPInsrPExtrInsertPS()) {
5046 // mov constant-to-GPR + movd/movq GPR -> XMM.
5047 if (isa_and_nonnull<Constant>(Op1) && Op1->getType()->isIntegerTy())
5048 return 2 + RegisterFileMoveCost;
5049 // Assume movd/movq GPR -> XMM is relatively cheap on all targets.
5050 return 1 + RegisterFileMoveCost;
5051 }
5052 }
5053
5054 // Assume movd/movq XMM -> GPR is relatively cheap on all targets.
5055 if (ScalarType->isIntegerTy() && Opcode == Instruction::ExtractElement)
5056 return 1 + RegisterFileMoveCost;
5057 }
5058
5059 int ISD = TLI->InstructionOpcodeToISD(Opcode);
5060 assert(ISD && "Unexpected vector opcode");
5061 if (ST->useSLMArithCosts())
5062 if (auto *Entry = CostTableLookup(SLMCostTbl, ISD, MScalarTy))
5063 return Entry->Cost + RegisterFileMoveCost;
5064
5065 // Consider cheap cases.
5066 if (IsCheapPInsrPExtrInsertPS())
5067 return 1 + RegisterFileMoveCost;
5068
5069 // For extractions we just need to shuffle the element to index 0, which
5070 // should be very cheap (assume cost = 1). For insertions we need to shuffle
5071 // the elements to its destination. In both cases we must handle the
5072 // subvector move(s).
5073 // If the vector type is already less than 128-bits then don't reduce it.
5074 // TODO: Under what circumstances should we shuffle using the full width?
5075 InstructionCost ShuffleCost = 1;
5076 if (Opcode == Instruction::InsertElement) {
5077 auto *SubTy = cast<VectorType>(Val);
5078 EVT VT = TLI->getValueType(DL, Val);
5079 if (VT.getScalarType() != MScalarTy || VT.getSizeInBits() >= 128)
5080 SubTy = FixedVectorType::get(ScalarType, SubNumElts);
5081 ShuffleCost = getShuffleCost(TTI::SK_PermuteTwoSrc, SubTy, SubTy, {},
5082 CostKind, 0, SubTy);
5083 }
5084 int IntOrFpCost = ScalarType->isFloatingPointTy() ? 0 : 1;
5085 return ShuffleCost + IntOrFpCost + RegisterFileMoveCost;
5086 }
5087
5088 return BaseT::getVectorInstrCost(Opcode, Val, CostKind, Index, Op0, Op1,
5089 VIC) +
5090 RegisterFileMoveCost;
5091}
5092
5094 VectorType *Ty, const APInt &DemandedElts, bool Insert, bool Extract,
5095 TTI::TargetCostKind CostKind, bool ForPoisonSrc, ArrayRef<Value *> VL,
5096 TTI::VectorInstrContext VIC) const {
5097 assert(DemandedElts.getBitWidth() ==
5098 cast<FixedVectorType>(Ty)->getNumElements() &&
5099 "Vector size mismatch");
5100
5101 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Ty);
5102 MVT MScalarTy = LT.second.getScalarType();
5103 unsigned LegalVectorBitWidth = LT.second.getSizeInBits();
5105
5106 constexpr unsigned LaneBitWidth = 128;
5107 assert((LegalVectorBitWidth < LaneBitWidth ||
5108 (LegalVectorBitWidth % LaneBitWidth) == 0) &&
5109 "Illegal vector");
5110
5111 const int NumLegalVectors = LT.first.getValue();
5112 assert(NumLegalVectors >= 0 && "Negative cost!");
5113
5114 // For insertions, a ISD::BUILD_VECTOR style vector initialization can be much
5115 // cheaper than an accumulation of ISD::INSERT_VECTOR_ELT. SLPVectorizer has
5116 // a special heuristic regarding poison input which is passed here in
5117 // ForPoisonSrc.
5118 if (Insert && !ForPoisonSrc) {
5119 // This is nearly identical to BaseT::getScalarizationOverhead(), except
5120 // it is passing nullptr to getVectorInstrCost() for Op0 (instead of
5121 // Constant::getNullValue()), which makes the X86TTIImpl
5122 // getVectorInstrCost() return 0 instead of 1.
5123 for (unsigned I : seq(DemandedElts.getBitWidth())) {
5124 if (!DemandedElts[I])
5125 continue;
5126 Cost += getVectorInstrCost(Instruction::InsertElement, Ty, CostKind, I,
5128 VL.empty() ? nullptr : VL[I],
5130 }
5131 return Cost;
5132 }
5133
5134 if (Insert) {
5135 if ((MScalarTy == MVT::i16 && ST->hasSSE2()) ||
5136 (MScalarTy.isInteger() && ST->hasSSE41()) ||
5137 (MScalarTy == MVT::f32 && ST->hasSSE41())) {
5138 // For types we can insert directly, insertion into 128-bit sub vectors is
5139 // cheap, followed by a cheap chain of concatenations.
5140 if (LegalVectorBitWidth <= LaneBitWidth) {
5141 Cost += BaseT::getScalarizationOverhead(Ty, DemandedElts, Insert,
5142 /*Extract*/ false, CostKind);
5143 } else {
5144 // In each 128-lane, if at least one index is demanded but not all
5145 // indices are demanded and this 128-lane is not the first 128-lane of
5146 // the legalized-vector, then this 128-lane needs a extracti128; If in
5147 // each 128-lane, there is at least one demanded index, this 128-lane
5148 // needs a inserti128.
5149
5150 // The following cases will help you build a better understanding:
5151 // Assume we insert several elements into a v8i32 vector in avx2,
5152 // Case#1: inserting into 1th index needs vpinsrd + inserti128.
5153 // Case#2: inserting into 5th index needs extracti128 + vpinsrd +
5154 // inserti128.
5155 // Case#3: inserting into 4,5,6,7 index needs 4*vpinsrd + inserti128.
5156 assert((LegalVectorBitWidth % LaneBitWidth) == 0 && "Illegal vector");
5157 unsigned NumLegalLanes = LegalVectorBitWidth / LaneBitWidth;
5158 unsigned NumLanesTotal = NumLegalLanes * NumLegalVectors;
5159 unsigned NumLegalElts =
5160 LT.second.getVectorNumElements() * NumLegalVectors;
5161 assert(NumLegalElts >= DemandedElts.getBitWidth() &&
5162 "Vector has been legalized to smaller element count");
5163 assert((NumLegalElts % NumLanesTotal) == 0 &&
5164 "Unexpected elts per lane");
5165 unsigned NumEltsPerLane = NumLegalElts / NumLanesTotal;
5166
5167 APInt WidenedDemandedElts = DemandedElts.zext(NumLegalElts);
5168 auto *LaneTy =
5169 FixedVectorType::get(Ty->getElementType(), NumEltsPerLane);
5170
5171 for (unsigned I = 0; I != NumLanesTotal; ++I) {
5172 APInt LaneEltMask = WidenedDemandedElts.extractBits(
5173 NumEltsPerLane, NumEltsPerLane * I);
5174 if (LaneEltMask.isZero())
5175 continue;
5176 // FIXME: we don't need to extract if all non-demanded elements
5177 // are legalization-inserted padding.
5178 if (!LaneEltMask.isAllOnes())
5180 CostKind, I * NumEltsPerLane, LaneTy);
5181 Cost += BaseT::getScalarizationOverhead(LaneTy, LaneEltMask, Insert,
5182 /*Extract*/ false, CostKind);
5183 }
5184
5185 APInt AffectedLanes =
5186 APIntOps::ScaleBitMask(WidenedDemandedElts, NumLanesTotal);
5187 APInt FullyAffectedLegalVectors = APIntOps::ScaleBitMask(
5188 AffectedLanes, NumLegalVectors, /*MatchAllBits=*/true);
5189 for (int LegalVec = 0; LegalVec != NumLegalVectors; ++LegalVec) {
5190 for (unsigned Lane = 0; Lane != NumLegalLanes; ++Lane) {
5191 unsigned I = NumLegalLanes * LegalVec + Lane;
5192 // No need to insert unaffected lane; or lane 0 of each legal vector
5193 // iff ALL lanes of that vector were affected and will be inserted.
5194 if (!AffectedLanes[I] ||
5195 (Lane == 0 && FullyAffectedLegalVectors[LegalVec]))
5196 continue;
5198 CostKind, I * NumEltsPerLane, LaneTy);
5199 }
5200 }
5201 }
5202 } else if (LT.second.isVector()) {
5203 // Without fast insertion, we need to use MOVD/MOVQ to pass each demanded
5204 // integer element as a SCALAR_TO_VECTOR, then we build the vector as a
5205 // series of UNPCK followed by CONCAT_VECTORS - all of these can be
5206 // considered cheap.
5207 if (Ty->isIntOrIntVectorTy())
5208 Cost += DemandedElts.popcount();
5209
5210 // Get the smaller of the legalized or original pow2-extended number of
5211 // vector elements, which represents the number of unpacks we'll end up
5212 // performing.
5213 unsigned NumElts = LT.second.getVectorNumElements();
5214 unsigned Pow2Elts =
5215 PowerOf2Ceil(cast<FixedVectorType>(Ty)->getNumElements());
5216 Cost += (std::min<unsigned>(NumElts, Pow2Elts) - 1) * LT.first;
5217 }
5218 }
5219
5220 if (Extract) {
5221 // vXi1 can be efficiently extracted with MOVMSK.
5222 // TODO: AVX512 predicate mask handling.
5223 // NOTE: This doesn't work well for roundtrip scalarization.
5224 if (!Insert && Ty->getScalarSizeInBits() == 1 && !ST->hasAVX512()) {
5225 unsigned NumElts = cast<FixedVectorType>(Ty)->getNumElements();
5226 unsigned MaxElts = ST->hasAVX2() ? 32 : 16;
5227 unsigned MOVMSKCost = (NumElts + MaxElts - 1) / MaxElts;
5228 return MOVMSKCost;
5229 }
5230
5231 if (LT.second.isVector()) {
5232 unsigned NumLegalElts =
5233 LT.second.getVectorNumElements() * NumLegalVectors;
5234 assert(NumLegalElts >= DemandedElts.getBitWidth() &&
5235 "Vector has been legalized to smaller element count");
5236
5237 // If we're extracting elements from a 128-bit subvector lane,
5238 // we only need to extract each lane once, not for every element.
5239 if (LegalVectorBitWidth > LaneBitWidth) {
5240 unsigned NumLegalLanes = LegalVectorBitWidth / LaneBitWidth;
5241 unsigned NumLanesTotal = NumLegalLanes * NumLegalVectors;
5242 assert((NumLegalElts % NumLanesTotal) == 0 &&
5243 "Unexpected elts per lane");
5244 unsigned NumEltsPerLane = NumLegalElts / NumLanesTotal;
5245
5246 // Add cost for each demanded 128-bit subvector extraction.
5247 // Luckily this is a lot easier than for insertion.
5248 APInt WidenedDemandedElts = DemandedElts.zext(NumLegalElts);
5249 auto *LaneTy =
5250 FixedVectorType::get(Ty->getElementType(), NumEltsPerLane);
5251
5252 for (unsigned I = 0; I != NumLanesTotal; ++I) {
5253 APInt LaneEltMask = WidenedDemandedElts.extractBits(
5254 NumEltsPerLane, I * NumEltsPerLane);
5255 if (LaneEltMask.isZero())
5256 continue;
5258 I * NumEltsPerLane, LaneTy);
5260 LaneTy, LaneEltMask, /*Insert*/ false, Extract, CostKind);
5261 }
5262
5263 return Cost;
5264 }
5265 }
5266
5267 // Fallback to default extraction.
5268 Cost += BaseT::getScalarizationOverhead(Ty, DemandedElts, /*Insert*/ false,
5269 Extract, CostKind);
5270 }
5271
5272 return Cost;
5273}
5274
5276X86TTIImpl::getReplicationShuffleCost(Type *EltTy, int ReplicationFactor,
5277 int VF, const APInt &DemandedDstElts,
5279 const unsigned EltTyBits = DL.getTypeSizeInBits(EltTy);
5280 // We don't differentiate element types here, only element bit width.
5281 EltTy = IntegerType::getIntNTy(EltTy->getContext(), EltTyBits);
5282
5283 auto bailout = [&]() {
5284 return BaseT::getReplicationShuffleCost(EltTy, ReplicationFactor, VF,
5285 DemandedDstElts, CostKind);
5286 };
5287
5288 // For now, only deal with AVX512 cases.
5289 if (!ST->hasAVX512())
5290 return bailout();
5291
5292 // Do we have a native shuffle for this element type, or should we promote?
5293 unsigned PromEltTyBits = EltTyBits;
5294 switch (EltTyBits) {
5295 case 32:
5296 case 64:
5297 break; // AVX512F.
5298 case 16:
5299 if (!ST->hasBWI())
5300 PromEltTyBits = 32; // promote to i32, AVX512F.
5301 break; // AVX512BW
5302 case 8:
5303 if (!ST->hasVBMI())
5304 PromEltTyBits = 32; // promote to i32, AVX512F.
5305 break; // AVX512VBMI
5306 case 1:
5307 // There is no support for shuffling i1 elements. We *must* promote.
5308 if (ST->hasBWI()) {
5309 if (ST->hasVBMI())
5310 PromEltTyBits = 8; // promote to i8, AVX512VBMI.
5311 else
5312 PromEltTyBits = 16; // promote to i16, AVX512BW.
5313 break;
5314 }
5315 PromEltTyBits = 32; // promote to i32, AVX512F.
5316 break;
5317 default:
5318 return bailout();
5319 }
5320 auto *PromEltTy = IntegerType::getIntNTy(EltTy->getContext(), PromEltTyBits);
5321
5322 auto *SrcVecTy = FixedVectorType::get(EltTy, VF);
5323 auto *PromSrcVecTy = FixedVectorType::get(PromEltTy, VF);
5324
5325 int NumDstElements = VF * ReplicationFactor;
5326 auto *PromDstVecTy = FixedVectorType::get(PromEltTy, NumDstElements);
5327 auto *DstVecTy = FixedVectorType::get(EltTy, NumDstElements);
5328
5329 // Legalize the types.
5330 MVT LegalSrcVecTy = getTypeLegalizationCost(SrcVecTy).second;
5331 MVT LegalPromSrcVecTy = getTypeLegalizationCost(PromSrcVecTy).second;
5332 MVT LegalPromDstVecTy = getTypeLegalizationCost(PromDstVecTy).second;
5333 MVT LegalDstVecTy = getTypeLegalizationCost(DstVecTy).second;
5334 // They should have legalized into vector types.
5335 if (!LegalSrcVecTy.isVector() || !LegalPromSrcVecTy.isVector() ||
5336 !LegalPromDstVecTy.isVector() || !LegalDstVecTy.isVector())
5337 return bailout();
5338
5339 if (PromEltTyBits != EltTyBits) {
5340 // If we have to perform the shuffle with wider elt type than our data type,
5341 // then we will first need to anyext (we don't care about the new bits)
5342 // the source elements, and then truncate Dst elements.
5343 InstructionCost PromotionCost;
5344 PromotionCost += getCastInstrCost(
5345 Instruction::SExt, /*Dst=*/PromSrcVecTy, /*Src=*/SrcVecTy,
5347 PromotionCost +=
5348 getCastInstrCost(Instruction::Trunc, /*Dst=*/DstVecTy,
5349 /*Src=*/PromDstVecTy,
5351 return PromotionCost + getReplicationShuffleCost(PromEltTy,
5352 ReplicationFactor, VF,
5353 DemandedDstElts, CostKind);
5354 }
5355
5356 assert(LegalSrcVecTy.getScalarSizeInBits() == EltTyBits &&
5357 LegalSrcVecTy.getScalarType() == LegalDstVecTy.getScalarType() &&
5358 "We expect that the legalization doesn't affect the element width, "
5359 "doesn't coalesce/split elements.");
5360
5361 unsigned NumEltsPerDstVec = LegalDstVecTy.getVectorNumElements();
5362 unsigned NumDstVectors =
5363 divideCeil(DstVecTy->getNumElements(), NumEltsPerDstVec);
5364
5365 auto *SingleDstVecTy = FixedVectorType::get(EltTy, NumEltsPerDstVec);
5366
5367 // Not all the produced Dst elements may be demanded. In our case,
5368 // given that a single Dst vector is formed by a single shuffle,
5369 // if all elements that will form a single Dst vector aren't demanded,
5370 // then we won't need to do that shuffle, so adjust the cost accordingly.
5371 APInt DemandedDstVectors = APIntOps::ScaleBitMask(
5372 DemandedDstElts.zext(NumDstVectors * NumEltsPerDstVec), NumDstVectors);
5373 unsigned NumDstVectorsDemanded = DemandedDstVectors.popcount();
5374
5375 InstructionCost SingleShuffleCost =
5376 getShuffleCost(TTI::SK_PermuteSingleSrc, SingleDstVecTy, SingleDstVecTy,
5377 /*Mask=*/{}, CostKind,
5378 /*Index=*/0, /*SubTp=*/nullptr);
5379 return NumDstVectorsDemanded * SingleShuffleCost;
5380}
5381
5383 Align Alignment,
5384 unsigned AddressSpace,
5386 TTI::OperandValueInfo OpInfo,
5387 const Instruction *I) const {
5388 // FIXME: Load latency isn't handled here
5389 if (Opcode == Instruction::Load && CostKind == TTI::TCK_Latency)
5390 return BaseT::getMemoryOpCost(Opcode, Src, Alignment, AddressSpace,
5391 CostKind, OpInfo, I);
5392
5393 // TODO: Handle other cost kinds.
5395 if (auto *SI = dyn_cast_or_null<StoreInst>(I)) {
5396 // Store instruction with index and scale costs 2 Uops.
5397 // Check the preceding GEP to identify non-const indices.
5398 if (auto *GEP = dyn_cast<GetElementPtrInst>(SI->getPointerOperand())) {
5399 if (!all_of(GEP->indices(), [](Value *V) { return isa<Constant>(V); }))
5400 return TTI::TCC_Basic * 2;
5401 }
5402 }
5403 return TTI::TCC_Basic;
5404 }
5405
5406 assert((Opcode == Instruction::Load || Opcode == Instruction::Store) &&
5407 "Invalid Opcode");
5408 // Type legalization can't handle structs
5409 if (TLI->getValueType(DL, Src, true) == MVT::Other)
5410 return BaseT::getMemoryOpCost(Opcode, Src, Alignment, AddressSpace,
5411 CostKind, OpInfo, I);
5412
5413 // Legalize the type.
5414 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Src);
5415
5416 auto *VTy = dyn_cast<FixedVectorType>(Src);
5417
5419
5420 // Add a cost for constant load to vector.
5421 if (Opcode == Instruction::Store && OpInfo.isConstant())
5422 Cost += getMemoryOpCost(Instruction::Load, Src, DL.getABITypeAlign(Src),
5423 /*AddressSpace=*/0, CostKind, OpInfo);
5424
5425 // Handle the simple case of non-vectors.
5426 // NOTE: this assumes that legalization never creates vector from scalars!
5427 if (!VTy || !LT.second.isVector()) {
5428 // Each load/store unit costs 1.
5429 return (LT.second.isFloatingPoint() ? Cost : 0) + LT.first * 1;
5430 }
5431
5432 bool IsLoad = Opcode == Instruction::Load;
5433
5434 Type *EltTy = VTy->getElementType();
5435
5436 const int EltTyBits = DL.getTypeSizeInBits(EltTy);
5437
5438 // Source of truth: how many elements were there in the original IR vector?
5439 const unsigned SrcNumElt = VTy->getNumElements();
5440
5441 // How far have we gotten?
5442 int NumEltRemaining = SrcNumElt;
5443 // Note that we intentionally capture by-reference, NumEltRemaining changes.
5444 auto NumEltDone = [&]() { return SrcNumElt - NumEltRemaining; };
5445
5446 const int MaxLegalOpSizeBytes = divideCeil(LT.second.getSizeInBits(), 8);
5447
5448 // Note that even if we can store 64 bits of an XMM, we still operate on XMM.
5449 const unsigned XMMBits = 128;
5450 if (XMMBits % EltTyBits != 0)
5451 // Vector size must be a multiple of the element size. I.e. no padding.
5452 return BaseT::getMemoryOpCost(Opcode, Src, Alignment, AddressSpace,
5453 CostKind, OpInfo, I);
5454 const int NumEltPerXMM = XMMBits / EltTyBits;
5455
5456 auto *XMMVecTy = FixedVectorType::get(EltTy, NumEltPerXMM);
5457
5458 for (int CurrOpSizeBytes = MaxLegalOpSizeBytes, SubVecEltsLeft = 0;
5459 NumEltRemaining > 0; CurrOpSizeBytes /= 2) {
5460 // How many elements would a single op deal with at once?
5461 if ((8 * CurrOpSizeBytes) % EltTyBits != 0)
5462 // Vector size must be a multiple of the element size. I.e. no padding.
5463 return BaseT::getMemoryOpCost(Opcode, Src, Alignment, AddressSpace,
5464 CostKind, OpInfo, I);
5465 int CurrNumEltPerOp = (8 * CurrOpSizeBytes) / EltTyBits;
5466
5467 assert(CurrOpSizeBytes > 0 && CurrNumEltPerOp > 0 && "How'd we get here?");
5468 assert((((NumEltRemaining * EltTyBits) < (2 * 8 * CurrOpSizeBytes)) ||
5469 (CurrOpSizeBytes == MaxLegalOpSizeBytes)) &&
5470 "Unless we haven't halved the op size yet, "
5471 "we have less than two op's sized units of work left.");
5472
5473 auto *CurrVecTy = CurrNumEltPerOp > NumEltPerXMM
5474 ? FixedVectorType::get(EltTy, CurrNumEltPerOp)
5475 : XMMVecTy;
5476
5477 assert(CurrVecTy->getNumElements() % CurrNumEltPerOp == 0 &&
5478 "After halving sizes, the vector elt count is no longer a multiple "
5479 "of number of elements per operation?");
5480 auto *CoalescedVecTy =
5481 CurrNumEltPerOp == 1
5482 ? CurrVecTy
5484 IntegerType::get(Src->getContext(),
5485 EltTyBits * CurrNumEltPerOp),
5486 CurrVecTy->getNumElements() / CurrNumEltPerOp);
5487 assert(DL.getTypeSizeInBits(CoalescedVecTy) ==
5488 DL.getTypeSizeInBits(CurrVecTy) &&
5489 "coalesciing elements doesn't change vector width.");
5490
5491 while (NumEltRemaining > 0) {
5492 assert(SubVecEltsLeft >= 0 && "Subreg element count overconsumtion?");
5493
5494 // Can we use this vector size, as per the remaining element count?
5495 // Iff the vector is naturally aligned, we can do a wide load regardless.
5496 if (NumEltRemaining < CurrNumEltPerOp &&
5497 (!IsLoad || Alignment < CurrOpSizeBytes) && CurrOpSizeBytes != 1)
5498 break; // Try smalled vector size.
5499
5500 // This isn't exactly right. We're using slow unaligned 32-byte accesses
5501 // as a proxy for a double-pumped AVX memory interface such as on
5502 // Sandybridge.
5503 // Sub-32-bit loads/stores will be slower either with PINSR*/PEXTR* or
5504 // will be scalarized.
5505 if (CurrOpSizeBytes == 32 && ST->isUnalignedMem32Slow())
5506 Cost += 2;
5507 else if (CurrOpSizeBytes < 4)
5508 Cost += 2;
5509 else
5510 Cost += 1;
5511
5512 // If we're loading a uniform value, then we don't need to split the load,
5513 // loading just a single (widest) vector can be reused by all splits.
5514 if (IsLoad && OpInfo.isUniform())
5515 return Cost;
5516
5517 bool Is0thSubVec = (NumEltDone() % LT.second.getVectorNumElements()) == 0;
5518
5519 // If we have fully processed the previous reg, we need to replenish it.
5520 if (SubVecEltsLeft == 0) {
5521 SubVecEltsLeft += CurrVecTy->getNumElements();
5522 // And that's free only for the 0'th subvector of a legalized vector.
5523 if (!Is0thSubVec)
5524 Cost +=
5527 VTy, VTy, {}, CostKind, NumEltDone(), CurrVecTy);
5528 }
5529
5530 // While we can directly load/store ZMM, YMM, and 64-bit halves of XMM,
5531 // for smaller widths (32/16/8) we have to insert/extract them separately.
5532 // Again, it's free for the 0'th subreg (if op is 32/64 bit wide,
5533 // but let's pretend that it is also true for 16/8 bit wide ops...)
5534 if (CurrOpSizeBytes <= 32 / 8 && !Is0thSubVec) {
5535 int NumEltDoneInCurrXMM = NumEltDone() % NumEltPerXMM;
5536 assert(NumEltDoneInCurrXMM % CurrNumEltPerOp == 0 && "");
5537 int CoalescedVecEltIdx = NumEltDoneInCurrXMM / CurrNumEltPerOp;
5538 APInt DemandedElts =
5539 APInt::getBitsSet(CoalescedVecTy->getNumElements(),
5540 CoalescedVecEltIdx, CoalescedVecEltIdx + 1);
5541 assert(DemandedElts.popcount() == 1 && "Inserting single value");
5542 Cost += getScalarizationOverhead(CoalescedVecTy, DemandedElts, IsLoad,
5543 !IsLoad, CostKind);
5544 }
5545
5546 SubVecEltsLeft -= CurrNumEltPerOp;
5547 NumEltRemaining -= CurrNumEltPerOp;
5548 Alignment = commonAlignment(Alignment, CurrOpSizeBytes);
5549 }
5550 }
5551
5552 assert(NumEltRemaining <= 0 && "Should have processed all the elements.");
5553
5554 return Cost;
5555}
5556
5560 switch (MICA.getID()) {
5561 case Intrinsic::masked_scatter:
5562 case Intrinsic::masked_gather:
5563 return getGatherScatterOpCost(MICA, CostKind);
5564 case Intrinsic::masked_load:
5565 case Intrinsic::masked_store:
5566 return getMaskedMemoryOpCost(MICA, CostKind);
5567 }
5569}
5570
5574 unsigned Opcode = MICA.getID() == Intrinsic::masked_load ? Instruction::Load
5575 : Instruction::Store;
5576 Type *SrcTy = MICA.getDataType();
5577 Align Alignment = MICA.getAlignment();
5578 unsigned AddressSpace = MICA.getAddressSpace();
5579
5580 bool IsLoad = (Instruction::Load == Opcode);
5581 bool IsStore = (Instruction::Store == Opcode);
5582
5583 auto *SrcVTy = dyn_cast<FixedVectorType>(SrcTy);
5584 if (!SrcVTy)
5585 // To calculate scalar take the regular cost, without mask
5586 return getMemoryOpCost(Opcode, SrcTy, Alignment, AddressSpace, CostKind);
5587
5588 unsigned NumElem = SrcVTy->getNumElements();
5589 auto *MaskTy =
5590 FixedVectorType::get(Type::getInt8Ty(SrcVTy->getContext()), NumElem);
5591 if ((IsLoad && !isLegalMaskedLoad(SrcVTy, Alignment, AddressSpace)) ||
5592 (IsStore && !isLegalMaskedStore(SrcVTy, Alignment, AddressSpace))) {
5593 // Scalarization
5594 APInt DemandedElts = APInt::getAllOnes(NumElem);
5596 MaskTy, DemandedElts, /*Insert*/ false, /*Extract*/ true, CostKind);
5597 InstructionCost ScalarCompareCost = getCmpSelInstrCost(
5598 Instruction::ICmp, Type::getInt8Ty(SrcVTy->getContext()), nullptr,
5600 InstructionCost BranchCost = getCFInstrCost(Instruction::CondBr, CostKind);
5601 InstructionCost MaskCmpCost = NumElem * (BranchCost + ScalarCompareCost);
5603 SrcVTy, DemandedElts, IsLoad, IsStore, CostKind);
5604 InstructionCost MemopCost =
5605 NumElem * BaseT::getMemoryOpCost(Opcode, SrcVTy->getScalarType(),
5606 Alignment, AddressSpace, CostKind);
5607 return MemopCost + ValueSplitCost + MaskSplitCost + MaskCmpCost;
5608 }
5609
5610 // Legalize the type.
5611 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(SrcVTy);
5612 auto VT = TLI->getValueType(DL, SrcVTy);
5614 MVT Ty = LT.second;
5615 if (Ty == MVT::i16 || Ty == MVT::i32 || Ty == MVT::i64)
5616 // APX masked load/store for scalar is cheap.
5617 return Cost + LT.first;
5618
5619 if (VT.isSimple() && Ty != VT.getSimpleVT() &&
5620 LT.second.getVectorNumElements() == NumElem)
5621 // Promotion requires extend/truncate for data and a shuffle for mask.
5622 Cost += getShuffleCost(TTI::SK_PermuteTwoSrc, SrcVTy, SrcVTy, {}, CostKind,
5623 0, nullptr) +
5624 getShuffleCost(TTI::SK_PermuteTwoSrc, MaskTy, MaskTy, {}, CostKind,
5625 0, nullptr);
5626
5627 else if (LT.first * Ty.getVectorNumElements() > NumElem) {
5628 auto *NewMaskTy = FixedVectorType::get(MaskTy->getElementType(),
5629 (unsigned)LT.first.getValue() *
5630 Ty.getVectorNumElements());
5631 // Expanding requires fill mask with zeroes
5632 Cost += getShuffleCost(TTI::SK_InsertSubvector, NewMaskTy, NewMaskTy, {},
5633 CostKind, 0, MaskTy);
5634 }
5635
5636 // Pre-AVX512 - each maskmov load costs 2 + store costs ~8.
5637 if (!ST->hasAVX512())
5638 return Cost + LT.first * (IsLoad ? 2 : 8);
5639
5640 // AVX-512 masked load/store is cheaper
5641 return Cost + LT.first;
5642}
5643
5645 ArrayRef<const Value *> Ptrs, const Value *Base,
5646 const TTI::PointersChainInfo &Info, Type *AccessTy,
5648 if (Info.isSameBase() && Info.isKnownStride()) {
5649 // If all the pointers have known stride all the differences are translated
5650 // into constants. X86 memory addressing allows encoding it into
5651 // displacement. So we just need to take the base GEP cost.
5652 if (const auto *BaseGEP = dyn_cast<GetElementPtrInst>(Base)) {
5653 SmallVector<const Value *> Indices(BaseGEP->indices());
5654 return getGEPCost(BaseGEP->getSourceElementType(),
5655 BaseGEP->getPointerOperand(), Indices, nullptr,
5656 CostKind);
5657 }
5658 return TTI::TCC_Free;
5659 }
5660 return BaseT::getPointersChainCost(Ptrs, Base, Info, AccessTy, CostKind);
5661}
5662
5665 const SCEV *Ptr,
5667 // Address computations in vectorized code with non-consecutive addresses will
5668 // likely result in more instructions compared to scalar code where the
5669 // computation can more often be merged into the index mode. The resulting
5670 // extra micro-ops can significantly decrease throughput.
5671 const unsigned NumVectorInstToHideOverhead = 10;
5672
5673 // Cost modeling of Strided Access Computation is hidden by the indexing
5674 // modes of X86 regardless of the stride value. We dont believe that there
5675 // is a difference between constant strided access in gerenal and constant
5676 // strided value which is less than or equal to 64.
5677 // Even in the case of (loop invariant) stride whose value is not known at
5678 // compile time, the address computation will not incur more than one extra
5679 // ADD instruction.
5680 if (PtrTy->isVectorTy() && SE && !ST->hasAVX2()) {
5681 // TODO: AVX2 is the current cut-off because we don't have correct
5682 // interleaving costs for prior ISA's.
5683 if (!BaseT::isStridedAccess(Ptr))
5684 return NumVectorInstToHideOverhead;
5685 if (!BaseT::getConstantStrideStep(SE, Ptr))
5686 return 1;
5687 }
5688
5689 return BaseT::getAddressComputationCost(PtrTy, SE, Ptr, CostKind);
5690}
5691
5694 std::optional<FastMathFlags> FMF,
5697 return BaseT::getArithmeticReductionCost(Opcode, ValTy, FMF, CostKind);
5698
5699 // We use the Intel Architecture Code Analyzer(IACA) to measure the throughput
5700 // and make it as the cost.
5701
5702 static const CostKindTblEntry SLMCostTbl[] = {
5703 { ISD::FADD, MVT::v2f64, {3, 3, 3, 3} },
5704 { ISD::ADD, MVT::v2i64, {5, 5, 5, 5} },
5705 };
5706
5707 static const CostKindTblEntry SSE2CostTbl[] = {
5708 { ISD::FADD, MVT::v2f64, {2, 2, 2, 2} },
5709 { ISD::FADD, MVT::v2f32, {2, 2, 2, 2} },
5710 { ISD::FADD, MVT::v4f32, {4, 4, 4, 4} },
5711 { ISD::ADD, MVT::v2i64, {2, 2, 2, 2} }, // The data reported by the IACA tool is "1.6".
5712 { ISD::ADD, MVT::v2i32, {2, 2, 2, 2} }, // FIXME: chosen to be less than v4i32
5713 { ISD::ADD, MVT::v4i32, {3, 3, 3, 3} }, // The data reported by the IACA tool is "3.3".
5714 { ISD::ADD, MVT::v2i16, {2, 2, 2, 2} }, // The data reported by the IACA tool is "4.3".
5715 { ISD::ADD, MVT::v4i16, {3, 3, 3, 3} }, // The data reported by the IACA tool is "4.3".
5716 { ISD::ADD, MVT::v8i16, {4, 4, 4, 4} }, // The data reported by the IACA tool is "4.3".
5717 { ISD::ADD, MVT::v2i8, {2, 2, 2, 2} },
5718 { ISD::ADD, MVT::v4i8, {2, 2, 2, 2} },
5719 { ISD::ADD, MVT::v8i8, {2, 2, 2, 2} },
5720 { ISD::ADD, MVT::v16i8, {3, 3, 3, 3} },
5721 };
5722
5723 static const CostKindTblEntry AVX1CostTbl[] = {
5724 { ISD::FADD, MVT::v4f64, {3, 3, 3, 3} },
5725 { ISD::FADD, MVT::v4f32, {3, 3, 3, 3} },
5726 { ISD::FADD, MVT::v8f32, {4, 4, 4, 4} },
5727 { ISD::ADD, MVT::v2i64, {1, 1, 1, 1} }, // The data reported by the IACA tool is "1.5".
5728 { ISD::ADD, MVT::v4i64, {3, 3, 3, 3} },
5729 { ISD::ADD, MVT::v8i32, {5, 5, 5, 5} },
5730 { ISD::ADD, MVT::v16i16, {5, 5, 5, 5} },
5731 { ISD::ADD, MVT::v32i8, {4, 4, 4, 4} },
5732 };
5733
5734 static const CostKindTblEntry AVX512FCostTbl[] = {
5735 { ISD::FADD, MVT::v8f64, {4, 4, 4, 4} },
5736 { ISD::FADD, MVT::v16f32, {5, 5, 5, 5} },
5737 { ISD::ADD, MVT::v8i64, {4, 4, 4, 4} },
5738 { ISD::ADD, MVT::v16i32, {6, 6, 6, 6} },
5739 };
5740
5741 static const CostKindTblEntry AVX512BWCostTbl[] = {
5742 { ISD::ADD, MVT::v32i16, {7, 7, 7, 7} },
5743 { ISD::ADD, MVT::v64i8, {4, 4, 4, 4} },
5744 };
5745
5746 int ISD = TLI->InstructionOpcodeToISD(Opcode);
5747 assert(ISD && "Invalid opcode");
5748
5749 // Before legalizing the type, give a chance to look up illegal narrow types
5750 // in the table.
5751 // FIXME: Is there a better way to do this?
5752 EVT VT = TLI->getValueType(DL, ValTy);
5753 if (VT.isSimple()) {
5754 MVT MTy = VT.getSimpleVT();
5755 if (ST->useSLMArithCosts())
5756 if (const auto *Entry = CostTableLookup(SLMCostTbl, ISD, MTy))
5757 if (auto KindCost = Entry->Cost[CostKind])
5758 return *KindCost;
5759
5760 if (ST->hasBWI())
5761 if (const auto *Entry = CostTableLookup(AVX512BWCostTbl, ISD, MTy))
5762 if (auto KindCost = Entry->Cost[CostKind])
5763 return *KindCost;
5764
5765 if (ST->hasAVX512())
5766 if (const auto *Entry = CostTableLookup(AVX512FCostTbl, ISD, MTy))
5767 if (auto KindCost = Entry->Cost[CostKind])
5768 return *KindCost;
5769
5770 if (ST->hasAVX())
5771 if (const auto *Entry = CostTableLookup(AVX1CostTbl, ISD, MTy))
5772 if (auto KindCost = Entry->Cost[CostKind])
5773 return *KindCost;
5774
5775 if (ST->hasSSE2())
5776 if (const auto *Entry = CostTableLookup(SSE2CostTbl, ISD, MTy))
5777 if (auto KindCost = Entry->Cost[CostKind])
5778 return *KindCost;
5779 }
5780
5781 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(ValTy);
5782
5783 MVT MTy = LT.second;
5784
5785 auto *ValVTy = cast<FixedVectorType>(ValTy);
5786
5787 // Special case: vXi8 mul reductions are performed as vXi16.
5788 if (ISD == ISD::MUL && MTy.getScalarType() == MVT::i8) {
5789 auto *WideSclTy = IntegerType::get(ValVTy->getContext(), 16);
5790 auto *WideVecTy = FixedVectorType::get(WideSclTy, ValVTy->getNumElements());
5791 return getCastInstrCost(Instruction::ZExt, WideVecTy, ValTy,
5793 CostKind) +
5794 getArithmeticReductionCost(Opcode, WideVecTy, FMF, CostKind);
5795 }
5796
5797 InstructionCost ArithmeticCost = 0;
5798 if (LT.first != 1 && MTy.isVector() &&
5799 MTy.getVectorNumElements() < ValVTy->getNumElements()) {
5800 // Type needs to be split. We need LT.first - 1 arithmetic ops.
5801 auto *SingleOpTy = FixedVectorType::get(ValVTy->getElementType(),
5802 MTy.getVectorNumElements());
5803 ArithmeticCost = getArithmeticInstrCost(Opcode, SingleOpTy, CostKind);
5804 ArithmeticCost *= LT.first - 1;
5805 }
5806
5807 if (ST->useSLMArithCosts())
5808 if (const auto *Entry = CostTableLookup(SLMCostTbl, ISD, MTy))
5809 if (auto KindCost = Entry->Cost[CostKind])
5810 return ArithmeticCost + *KindCost;
5811
5812 if (ST->hasBWI())
5813 if (const auto *Entry = CostTableLookup(AVX512BWCostTbl, ISD, MTy))
5814 if (auto KindCost = Entry->Cost[CostKind])
5815 return ArithmeticCost + *KindCost;
5816
5817 if (ST->hasAVX512())
5818 if (const auto *Entry = CostTableLookup(AVX512FCostTbl, ISD, MTy))
5819 if (auto KindCost = Entry->Cost[CostKind])
5820 return ArithmeticCost + *KindCost;
5821
5822 if (ST->hasAVX())
5823 if (const auto *Entry = CostTableLookup(AVX1CostTbl, ISD, MTy))
5824 if (auto KindCost = Entry->Cost[CostKind])
5825 return ArithmeticCost + *KindCost;
5826
5827 if (ST->hasSSE2())
5828 if (const auto *Entry = CostTableLookup(SSE2CostTbl, ISD, MTy))
5829 if (auto KindCost = Entry->Cost[CostKind])
5830 return ArithmeticCost + *KindCost;
5831
5832 // FIXME: These assume a naive kshift+binop lowering, which is probably
5833 // conservative in most cases.
5834 static const CostKindTblEntry AVX512BoolReduction[] = {
5835 { ISD::AND, MVT::v2i1, { 3, 3, 3, 3} },
5836 { ISD::AND, MVT::v4i1, { 5, 5, 5, 5} },
5837 { ISD::AND, MVT::v8i1, { 7, 7, 7, 7} },
5838 { ISD::AND, MVT::v16i1, { 9, 9, 9, 9} },
5839 { ISD::AND, MVT::v32i1, {11,11,11,11} },
5840 { ISD::AND, MVT::v64i1, {13,13,13,13} },
5841 { ISD::OR, MVT::v2i1, { 3, 3, 3, 3} },
5842 { ISD::OR, MVT::v4i1, { 5, 5, 5, 5} },
5843 { ISD::OR, MVT::v8i1, { 7, 7, 7, 7} },
5844 { ISD::OR, MVT::v16i1, { 9, 9, 9, 9} },
5845 { ISD::OR, MVT::v32i1, {11,11,11,11} },
5846 { ISD::OR, MVT::v64i1, {13,13,13,13} },
5847 };
5848
5849 static const CostKindTblEntry AVX2BoolReduction[] = {
5850 { ISD::AND, MVT::v16i16, { 2, 2, 2, 2} }, // vpmovmskb + cmp
5851 { ISD::AND, MVT::v32i8, { 2, 2, 2, 2} }, // vpmovmskb + cmp
5852 { ISD::OR, MVT::v16i16, { 2, 2, 2, 2} }, // vpmovmskb + cmp
5853 { ISD::OR, MVT::v32i8, { 2, 2, 2, 2} }, // vpmovmskb + cmp
5854 };
5855
5856 static const CostKindTblEntry AVX1BoolReduction[] = {
5857 { ISD::AND, MVT::v4i64, {2, 2, 2, 2} }, // vmovmskpd + cmp
5858 { ISD::AND, MVT::v8i32, {2, 2, 2, 2} }, // vmovmskps + cmp
5859 { ISD::AND, MVT::v16i16, {4, 4, 4, 4} }, // vextractf128 + vpand + vpmovmskb + cmp
5860 { ISD::AND, MVT::v32i8, {4, 4, 4, 4} }, // vextractf128 + vpand + vpmovmskb + cmp
5861 { ISD::OR, MVT::v4i64, {2, 2, 2, 2} }, // vmovmskpd + cmp
5862 { ISD::OR, MVT::v8i32, {2, 2, 2, 2} }, // vmovmskps + cmp
5863 { ISD::OR, MVT::v16i16, {4, 4, 4, 4} }, // vextractf128 + vpor + vpmovmskb + cmp
5864 { ISD::OR, MVT::v32i8, {4, 4, 4, 4} }, // vextractf128 + vpor + vpmovmskb + cmp
5865 };
5866
5867 static const CostKindTblEntry SSE2BoolReduction[] = {
5868 { ISD::AND, MVT::v2i64, {2, 2, 2, 2} }, // movmskpd + cmp
5869 { ISD::AND, MVT::v4i32, {2, 2, 2, 2} }, // movmskps + cmp
5870 { ISD::AND, MVT::v8i16, {2, 2, 2, 2} }, // pmovmskb + cmp
5871 { ISD::AND, MVT::v16i8, {2, 2, 2, 2} }, // pmovmskb + cmp
5872 { ISD::OR, MVT::v2i64, {2, 2, 2, 2} }, // movmskpd + cmp
5873 { ISD::OR, MVT::v4i32, {2, 2, 2, 2} }, // movmskps + cmp
5874 { ISD::OR, MVT::v8i16, {2, 2, 2, 2} }, // pmovmskb + cmp
5875 { ISD::OR, MVT::v16i8, {2, 2, 2, 2} }, // pmovmskb + cmp
5876 };
5877
5878 // Handle bool allof/anyof patterns.
5879 if (ValVTy->getElementType()->isIntegerTy(1)) {
5880 if (ISD == ISD::ADD) {
5881 // vXi1 addition reduction will bitcast to scalar and perform a popcount.
5882 auto *IntTy = IntegerType::getIntNTy(ValVTy->getContext(),
5883 ValVTy->getNumElements());
5884 IntrinsicCostAttributes ICA(Intrinsic::ctpop, IntTy, {IntTy});
5885 return getCastInstrCost(Instruction::BitCast, IntTy, ValVTy,
5887 CostKind) +
5889 }
5890
5891 InstructionCost ArithmeticCost = 0;
5892 if (LT.first != 1 && MTy.isVector() &&
5893 MTy.getVectorNumElements() < ValVTy->getNumElements()) {
5894 // Type needs to be split. We need LT.first - 1 arithmetic ops.
5895 auto *SingleOpTy = FixedVectorType::get(ValVTy->getElementType(),
5896 MTy.getVectorNumElements());
5897 ArithmeticCost = getArithmeticInstrCost(Opcode, SingleOpTy, CostKind);
5898 ArithmeticCost *= LT.first - 1;
5899 }
5900
5901 if (ST->hasAVX512())
5902 if (const auto *Entry = CostTableLookup(AVX512BoolReduction, ISD, MTy))
5903 if (auto KindCost = Entry->Cost[CostKind])
5904 return ArithmeticCost + *KindCost;
5905 if (ST->hasAVX2())
5906 if (const auto *Entry = CostTableLookup(AVX2BoolReduction, ISD, MTy))
5907 if (auto KindCost = Entry->Cost[CostKind])
5908 return ArithmeticCost + *KindCost;
5909 if (ST->hasAVX())
5910 if (const auto *Entry = CostTableLookup(AVX1BoolReduction, ISD, MTy))
5911 if (auto KindCost = Entry->Cost[CostKind])
5912 return ArithmeticCost + *KindCost;
5913 if (ST->hasSSE2())
5914 if (const auto *Entry = CostTableLookup(SSE2BoolReduction, ISD, MTy))
5915 if (auto KindCost = Entry->Cost[CostKind])
5916 return ArithmeticCost + *KindCost;
5917
5918 return BaseT::getArithmeticReductionCost(Opcode, ValVTy, FMF, CostKind);
5919 }
5920
5921 unsigned NumVecElts = ValVTy->getNumElements();
5922 unsigned ScalarSize = ValVTy->getScalarSizeInBits();
5923
5924 // Special case power of 2 reductions where the scalar type isn't changed
5925 // by type legalization.
5926 if (!isPowerOf2_32(NumVecElts) || ScalarSize != MTy.getScalarSizeInBits())
5927 return BaseT::getArithmeticReductionCost(Opcode, ValVTy, FMF, CostKind);
5928
5929 InstructionCost ReductionCost = 0;
5930
5931 auto *Ty = ValVTy;
5932 if (LT.first != 1 && MTy.isVector() &&
5933 MTy.getVectorNumElements() < ValVTy->getNumElements()) {
5934 // Type needs to be split. We need LT.first - 1 arithmetic ops.
5935 Ty = FixedVectorType::get(ValVTy->getElementType(),
5936 MTy.getVectorNumElements());
5937 ReductionCost = getArithmeticInstrCost(Opcode, Ty, CostKind);
5938 ReductionCost *= LT.first - 1;
5939 NumVecElts = MTy.getVectorNumElements();
5940 }
5941
5942 // Now handle reduction with the legal type, taking into account size changes
5943 // at each level.
5944 while (NumVecElts > 1) {
5945 // Determine the size of the remaining vector we need to reduce.
5946 unsigned Size = NumVecElts * ScalarSize;
5947 NumVecElts /= 2;
5948 // If we're reducing from 256/512 bits, use an extract_subvector.
5949 if (Size > 128) {
5950 auto *SubTy = FixedVectorType::get(ValVTy->getElementType(), NumVecElts);
5951 ReductionCost += getShuffleCost(TTI::SK_ExtractSubvector, Ty, Ty, {},
5952 CostKind, NumVecElts, SubTy);
5953 Ty = SubTy;
5954 } else if (Size == 128) {
5955 // Reducing from 128 bits is a permute of v2f64/v2i64.
5956 FixedVectorType *ShufTy;
5957 if (ValVTy->isFloatingPointTy())
5958 ShufTy =
5959 FixedVectorType::get(Type::getDoubleTy(ValVTy->getContext()), 2);
5960 else
5961 ShufTy =
5962 FixedVectorType::get(Type::getInt64Ty(ValVTy->getContext()), 2);
5963 ReductionCost += getShuffleCost(TTI::SK_PermuteSingleSrc, ShufTy, ShufTy,
5964 {}, CostKind, 0, nullptr);
5965 } else if (Size == 64) {
5966 // Reducing from 64 bits is a shuffle of v4f32/v4i32.
5967 FixedVectorType *ShufTy;
5968 if (ValVTy->isFloatingPointTy())
5969 ShufTy =
5970 FixedVectorType::get(Type::getFloatTy(ValVTy->getContext()), 4);
5971 else
5972 ShufTy =
5973 FixedVectorType::get(Type::getInt32Ty(ValVTy->getContext()), 4);
5974 ReductionCost += getShuffleCost(TTI::SK_PermuteSingleSrc, ShufTy, ShufTy,
5975 {}, CostKind, 0, nullptr);
5976 } else {
5977 // Reducing from smaller size is a shift by immediate.
5978 auto *ShiftTy = FixedVectorType::get(
5979 Type::getIntNTy(ValVTy->getContext(), Size), 128 / Size);
5980 ReductionCost += getArithmeticInstrCost(
5981 Instruction::LShr, ShiftTy, CostKind,
5984 }
5985
5986 // Add the arithmetic op for this level.
5987 ReductionCost += getArithmeticInstrCost(Opcode, Ty, CostKind);
5988 }
5989
5990 // Add the final extract element to the cost.
5991 return ReductionCost + getVectorInstrCost(Instruction::ExtractElement, Ty,
5992 CostKind, 0, nullptr, nullptr,
5994}
5995
5998 FastMathFlags FMF) const {
5999 IntrinsicCostAttributes ICA(IID, Ty, {Ty, Ty}, FMF);
6000 return getIntrinsicInstrCost(ICA, CostKind);
6001}
6002
6005 FastMathFlags FMF,
6007 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(ValTy);
6008
6009 MVT MTy = LT.second;
6010
6012 if (ValTy->isIntOrIntVectorTy()) {
6013 ISD = (IID == Intrinsic::umin || IID == Intrinsic::umax) ? ISD::UMIN
6014 : ISD::SMIN;
6015 } else {
6016 assert(ValTy->isFPOrFPVectorTy() &&
6017 "Expected float point or integer vector type.");
6018 ISD = (IID == Intrinsic::minnum || IID == Intrinsic::maxnum)
6019 ? ISD::FMINNUM
6020 : ISD::FMINIMUM;
6021 }
6022
6023 // We use llvm-mca across all supported CPUs to measure the cost stats.
6024 static const CostKindTblEntry SSE2CostTbl[] = {
6025 {ISD::SMIN, MVT::v2i64, {3, 4, 5, 6}},
6026 {ISD::UMIN, MVT::v2i64, {3, 4, 5, 6}},
6027 {ISD::SMIN, MVT::v2i32, {2, 2, 5, 6}},
6028 {ISD::UMIN, MVT::v2i32, {2, 2, 5, 6}},
6029 {ISD::SMIN, MVT::v4i32, {3, 7,11,12}},
6030 {ISD::UMIN, MVT::v4i32, {4, 7,14,15}},
6031 {ISD::SMIN, MVT::v2i16, {2, 3, 4, 4}},
6032 {ISD::UMIN, MVT::v2i16, {2, 3, 4, 6}},
6033 {ISD::SMIN, MVT::v4i16, {3, 5, 6, 6}},
6034 {ISD::UMIN, MVT::v4i16, {3, 5, 8, 10}},
6035 {ISD::SMIN, MVT::v8i16, {3, 8, 8, 8}},
6036 {ISD::UMIN, MVT::v8i16, {4, 8,12,14}},
6037 {ISD::SMIN, MVT::v2i8, {2, 3, 5, 6}},
6038 {ISD::UMIN, MVT::v2i8, {2, 3, 4, 4}},
6039 {ISD::SMIN, MVT::v4i8, {4, 6,12,13}},
6040 {ISD::UMIN, MVT::v4i8, {3, 6, 7, 7}},
6041 {ISD::SMIN, MVT::v8i8, {5, 9,18,19}},
6042 {ISD::UMIN, MVT::v8i8, {4, 8, 9, 9}},
6043 {ISD::SMIN, MVT::v16i8, {7,13,24,25}},
6044 {ISD::UMIN, MVT::v16i8, {3,10,11,11}},
6045 };
6046
6047 static const CostKindTblEntry SSE41CostTbl[] = {
6048 {ISD::SMIN, MVT::v2i64, {3, 4, 4, 6}},
6049 {ISD::UMIN, MVT::v2i64, {3, 4, 4, 6}},
6050 {ISD::SMIN, MVT::v2i32, {2, 2, 3, 3}},
6051 {ISD::UMIN, MVT::v2i32, {2, 2, 3, 3}},
6052 {ISD::SMIN, MVT::v4i32, {3, 4, 5, 5}},
6053 {ISD::UMIN, MVT::v4i32, {3, 4, 5, 5}},
6054 {ISD::UMIN, MVT::v2i16, {2, 3, 4, 4}},
6055 {ISD::SMIN, MVT::v4i16, {3, 5, 6, 6}},
6056 {ISD::UMIN, MVT::v4i16, {3, 5, 6, 6}},
6057 {ISD::SMIN, MVT::v8i16, {2, 8, 4, 5}},
6058 {ISD::UMIN, MVT::v8i16, {2, 5, 2, 2}},
6059 {ISD::SMIN, MVT::v2i8, {2, 3, 4, 4}},
6060 {ISD::SMIN, MVT::v4i8, {3, 6, 7, 7}},
6061 {ISD::SMIN, MVT::v8i8, {4, 8, 9, 9}},
6062 {ISD::SMIN, MVT::v16i8, {3,10, 7, 8}},
6063 {ISD::UMIN, MVT::v16i8, {3, 8, 5, 5}},
6064 };
6065
6066 static const CostKindTblEntry AVX1CostTbl[] = {
6067 {ISD::SMIN, MVT::v4i64, {5,11, 7,10}},
6068 {ISD::UMIN, MVT::v4i64, {6,12,10,13}},
6069 {ISD::SMIN, MVT::v8i32, {4, 9, 7, 7}},
6070 {ISD::UMIN, MVT::v8i32, {4, 9, 7, 7}},
6071 {ISD::SMIN, MVT::v16i16, {3,15, 6, 7}},
6072 {ISD::UMIN, MVT::v16i16, {2, 9, 4, 4}},
6073 {ISD::SMIN, MVT::v32i8, {4,17, 8, 9}},
6074 {ISD::UMIN, MVT::v32i8, {3,11, 6, 6}},
6075 };
6076
6077 static const CostKindTblEntry AVX2CostTbl[] = {
6078 {ISD::SMIN, MVT::v4i64, {4,11, 7,10}},
6079 {ISD::UMIN, MVT::v4i64, {4,12,10,13}},
6080 {ISD::SMIN, MVT::v2i32, {1, 2, 3, 3}},
6081 {ISD::UMIN, MVT::v2i32, {1, 2, 3, 3}},
6082 {ISD::UMIN, MVT::v4i32, {2, 4, 5, 5}},
6083 {ISD::SMIN, MVT::v4i32, {2, 4, 5, 5}},
6084 {ISD::SMIN, MVT::v8i32, {3, 9, 7, 7}},
6085 {ISD::UMIN, MVT::v8i32, {3, 9, 7, 7}},
6086 {ISD::SMIN, MVT::v4i16, {2, 4, 5, 5}},
6087 {ISD::UMIN, MVT::v4i16, {2, 4, 5, 5}},
6088 {ISD::SMIN, MVT::v16i16, {2,15, 6, 7}},
6089 {ISD::SMIN, MVT::v8i8, {3, 6, 7, 7}},
6090 {ISD::UMIN, MVT::v8i8, {3, 6, 7, 7}},
6091 {ISD::SMIN, MVT::v32i8, {3,17, 8, 9}},
6092 };
6093
6094 static const CostKindTblEntry AVX512FCostTbl[] = {
6095 {ISD::SMIN, MVT::v2i64, {2, 4, 3, 3}},
6096 {ISD::UMIN, MVT::v2i64, {2, 4, 3, 3}},
6097 {ISD::SMIN, MVT::v4i64, {3,10, 5, 5}},
6098 {ISD::UMIN, MVT::v4i64, {3,10, 5, 5}},
6099 {ISD::SMIN, MVT::v8i64, {5,16, 7, 7}},
6100 {ISD::UMIN, MVT::v8i64, {5,16, 7, 7}},
6101 {ISD::SMIN, MVT::v16i32, {4,12, 9, 9}},
6102 {ISD::UMIN, MVT::v16i32, {4,12, 9, 9}},
6103 };
6104
6105 static const CostKindTblEntry AVX512BWCostTbl[] = {
6106 {ISD::SMIN, MVT::v2i16, {1, 2, 3, 3}},
6107 {ISD::UMIN, MVT::v2i16, {1, 2, 3, 3}},
6108 {ISD::SMIN, MVT::v32i16, {2,19, 8, 9}},
6109 {ISD::UMIN, MVT::v32i16, {2,12, 6, 6}},
6110 {ISD::SMIN, MVT::v2i8, {1, 2, 3, 3}},
6111 {ISD::UMIN, MVT::v2i8, {1, 2, 3, 3}},
6112 {ISD::SMIN, MVT::v4i8, {2, 4, 5, 5}},
6113 {ISD::UMIN, MVT::v4i8, {2, 4, 5, 5}},
6114 {ISD::SMIN, MVT::v16i8, {2,10, 6, 7}},
6115 {ISD::UMIN, MVT::v16i8, {2, 6, 4, 4}},
6116 {ISD::SMIN, MVT::v32i8, {2,17, 8, 9}},
6117 {ISD::UMIN, MVT::v32i8, {2,10, 6, 6}},
6118 {ISD::SMIN, MVT::v64i8, {2,21,10,11}},
6119 {ISD::UMIN, MVT::v64i8, {2,14, 8, 8}},
6120 };
6121
6122 // Before legalizing the type, give a chance to look up illegal narrow types
6123 // in the table.
6124 // FIXME: Is there a better way to do this?
6125 EVT VT = TLI->getValueType(DL, ValTy);
6126 if (VT.isSimple()) {
6127 MVT MTy = VT.getSimpleVT();
6128 if (ST->hasBWI())
6129 if (const auto *Entry = CostTableLookup(AVX512BWCostTbl, ISD, MTy))
6130 if (auto KindCost = Entry->Cost[CostKind])
6131 return *KindCost;
6132
6133 if (ST->hasAVX512())
6134 if (const auto *Entry = CostTableLookup(AVX512FCostTbl, ISD, MTy))
6135 if (auto KindCost = Entry->Cost[CostKind])
6136 return *KindCost;
6137
6138 if (ST->hasAVX2())
6139 if (const auto *Entry = CostTableLookup(AVX2CostTbl, ISD, MTy))
6140 if (auto KindCost = Entry->Cost[CostKind])
6141 return *KindCost;
6142
6143 if (ST->hasAVX())
6144 if (const auto *Entry = CostTableLookup(AVX1CostTbl, ISD, MTy))
6145 if (auto KindCost = Entry->Cost[CostKind])
6146 return *KindCost;
6147
6148 if (ST->hasSSE41())
6149 if (const auto *Entry = CostTableLookup(SSE41CostTbl, ISD, MTy))
6150 if (auto KindCost = Entry->Cost[CostKind])
6151 return *KindCost;
6152
6153 if (ST->hasSSE2())
6154 if (const auto *Entry = CostTableLookup(SSE2CostTbl, ISD, MTy))
6155 if (auto KindCost = Entry->Cost[CostKind])
6156 return *KindCost;
6157 }
6158
6159 auto *ValVTy = cast<FixedVectorType>(ValTy);
6160 unsigned NumVecElts = ValVTy->getNumElements();
6161
6162 auto *Ty = ValVTy;
6163 InstructionCost MinMaxCost = 0;
6164 if (LT.first != 1 && MTy.isVector() &&
6165 MTy.getVectorNumElements() < ValVTy->getNumElements()) {
6166 // Type needs to be split. We need LT.first - 1 operations ops.
6167 Ty = FixedVectorType::get(ValVTy->getElementType(),
6168 MTy.getVectorNumElements());
6169 MinMaxCost = getMinMaxCost(IID, Ty, CostKind, FMF);
6170 MinMaxCost *= LT.first - 1;
6171 NumVecElts = MTy.getVectorNumElements();
6172 }
6173
6174 if (ST->hasBWI())
6175 if (const auto *Entry = CostTableLookup(AVX512BWCostTbl, ISD, MTy))
6176 if (auto KindCost = Entry->Cost[CostKind])
6177 return MinMaxCost + *KindCost;
6178
6179 if (ST->hasAVX512())
6180 if (const auto *Entry = CostTableLookup(AVX512FCostTbl, ISD, MTy))
6181 if (auto KindCost = Entry->Cost[CostKind])
6182 return MinMaxCost + *KindCost;
6183
6184 if (ST->hasAVX2())
6185 if (const auto *Entry = CostTableLookup(AVX2CostTbl, ISD, MTy))
6186 if (auto KindCost = Entry->Cost[CostKind])
6187 return MinMaxCost + *KindCost;
6188
6189 if (ST->hasAVX())
6190 if (const auto *Entry = CostTableLookup(AVX1CostTbl, ISD, MTy))
6191 if (auto KindCost = Entry->Cost[CostKind])
6192 return MinMaxCost + *KindCost;
6193
6194 if (ST->hasSSE41())
6195 if (const auto *Entry = CostTableLookup(SSE41CostTbl, ISD, MTy))
6196 if (auto KindCost = Entry->Cost[CostKind])
6197 return MinMaxCost + *KindCost;
6198
6199 if (ST->hasSSE2())
6200 if (const auto *Entry = CostTableLookup(SSE2CostTbl, ISD, MTy))
6201 if (auto KindCost = Entry->Cost[CostKind])
6202 return MinMaxCost + *KindCost;
6203
6204 unsigned ScalarSize = ValTy->getScalarSizeInBits();
6205
6206 // Special case power of 2 reductions where the scalar type isn't changed
6207 // by type legalization.
6208 if (!isPowerOf2_32(ValVTy->getNumElements()) ||
6209 ScalarSize != MTy.getScalarSizeInBits())
6210 return BaseT::getMinMaxReductionCost(IID, ValTy, FMF, CostKind);
6211
6212 // Now handle reduction with the legal type, taking into account size changes
6213 // at each level.
6214 while (NumVecElts > 1) {
6215 // Determine the size of the remaining vector we need to reduce.
6216 unsigned Size = NumVecElts * ScalarSize;
6217 NumVecElts /= 2;
6218 // If we're reducing from 256/512 bits, use an extract_subvector.
6219 if (Size > 128) {
6220 auto *SubTy = FixedVectorType::get(ValVTy->getElementType(), NumVecElts);
6221 MinMaxCost += getShuffleCost(TTI::SK_ExtractSubvector, Ty, Ty, {},
6222 CostKind, NumVecElts, SubTy);
6223 Ty = SubTy;
6224 } else if (Size == 128) {
6225 // Reducing from 128 bits is a permute of v2f64/v2i64.
6226 VectorType *ShufTy;
6227 if (ValTy->isFloatingPointTy())
6228 ShufTy =
6230 else
6231 ShufTy = FixedVectorType::get(Type::getInt64Ty(ValTy->getContext()), 2);
6232 MinMaxCost += getShuffleCost(TTI::SK_PermuteSingleSrc, ShufTy, ShufTy, {},
6233 CostKind, 0, nullptr);
6234 } else if (Size == 64) {
6235 // Reducing from 64 bits is a shuffle of v4f32/v4i32.
6236 FixedVectorType *ShufTy;
6237 if (ValTy->isFloatingPointTy())
6238 ShufTy = FixedVectorType::get(Type::getFloatTy(ValTy->getContext()), 4);
6239 else
6240 ShufTy = FixedVectorType::get(Type::getInt32Ty(ValTy->getContext()), 4);
6241 MinMaxCost += getShuffleCost(TTI::SK_PermuteSingleSrc, ShufTy, ShufTy, {},
6242 CostKind, 0, nullptr);
6243 } else {
6244 // Reducing from smaller size is a shift by immediate.
6245 auto *ShiftTy = FixedVectorType::get(
6246 Type::getIntNTy(ValTy->getContext(), Size), 128 / Size);
6247 MinMaxCost += getArithmeticInstrCost(
6248 Instruction::LShr, ShiftTy, TTI::TCK_RecipThroughput,
6251 }
6252
6253 // Add the arithmetic op for this level.
6254 MinMaxCost += getMinMaxCost(IID, Ty, CostKind, FMF);
6255 }
6256
6257 // Add the final extract element to the cost.
6258 return MinMaxCost + getVectorInstrCost(Instruction::ExtractElement, Ty,
6259 CostKind, 0, nullptr, nullptr,
6261}
6262
6263/// Calculate the cost of materializing a 64-bit value. This helper
6264/// method might only calculate a fraction of a larger immediate. Therefore it
6265/// is valid to return a cost of ZERO.
6267 if (Val == 0)
6268 return TTI::TCC_Free;
6269
6270 if (isInt<32>(Val))
6271 return TTI::TCC_Basic;
6272
6273 return 2 * TTI::TCC_Basic;
6274}
6275
6278 assert(Ty->isIntegerTy());
6279
6280 unsigned BitSize = Ty->getPrimitiveSizeInBits();
6281 if (BitSize == 0)
6282 return ~0U;
6283
6284 // Never hoist constants larger than 128bit, because this might lead to
6285 // incorrect code generation or assertions in codegen.
6286 // Fixme: Create a cost model for types larger than i128 once the codegen
6287 // issues have been fixed.
6288 if (BitSize > 128)
6289 return TTI::TCC_Free;
6290
6291 if (Imm == 0)
6292 return TTI::TCC_Free;
6293
6294 // Sign-extend all constants to a multiple of 64-bit.
6295 APInt ImmVal = Imm;
6296 if (BitSize % 64 != 0)
6297 ImmVal = Imm.sext(alignTo(BitSize, 64));
6298
6299 // Split the constant into 64-bit chunks and calculate the cost for each
6300 // chunk.
6302 for (unsigned ShiftVal = 0; ShiftVal < BitSize; ShiftVal += 64) {
6303 APInt Tmp = ImmVal.ashr(ShiftVal).sextOrTrunc(64);
6304 int64_t Val = Tmp.getSExtValue();
6305 Cost += getIntImmCost(Val);
6306 }
6307 // We need at least one instruction to materialize the constant.
6308 return std::max<InstructionCost>(1, Cost);
6309}
6310
6312 const APInt &Imm, Type *Ty,
6314 Instruction *Inst) const {
6315 assert(Ty->isIntegerTy());
6316
6317 unsigned BitSize = Ty->getPrimitiveSizeInBits();
6318 unsigned ImmBitWidth = Imm.getBitWidth();
6319
6320 // There is no cost model for constants with a bit size of 0. Return TCC_Free
6321 // here, so that constant hoisting will ignore this constant.
6322 if (BitSize == 0)
6323 return TTI::TCC_Free;
6324
6325 unsigned ImmIdx = ~0U;
6326 switch (Opcode) {
6327 default:
6328 return TTI::TCC_Free;
6329 case Instruction::GetElementPtr:
6330 // Always hoist the base address of a GetElementPtr. This prevents the
6331 // creation of new constants for every base constant that gets constant
6332 // folded with the offset.
6333 if (Idx == 0)
6334 return 2 * TTI::TCC_Basic;
6335 return TTI::TCC_Free;
6336 case Instruction::Store:
6337 ImmIdx = 0;
6338 break;
6339 case Instruction::ICmp:
6340 // This is an imperfect hack to prevent constant hoisting of
6341 // compares that might be trying to check if a 64-bit value fits in
6342 // 32-bits. The backend can optimize these cases using a right shift by 32.
6343 // There are other predicates and immediates the backend can use shifts for.
6344 if (Idx == 1 && ImmBitWidth == 64) {
6345 uint64_t ImmVal = Imm.getZExtValue();
6346 if (ImmVal == 0x100000000ULL || ImmVal == 0xffffffff)
6347 return TTI::TCC_Free;
6348
6349 if (auto *Cmp = dyn_cast_or_null<CmpInst>(Inst)) {
6350 if (Cmp->isEquality()) {
6351 KnownBits Known = computeKnownBits(Cmp->getOperand(0), DL);
6352 if (Known.countMinTrailingZeros() >= 32)
6353 return TTI::TCC_Free;
6354 }
6355 }
6356 }
6357 ImmIdx = 1;
6358 break;
6359 case Instruction::And:
6360 // We support 64-bit ANDs with immediates with 32-bits of leading zeroes
6361 // by using a 32-bit operation with implicit zero extension. Detect such
6362 // immediates here as the normal path expects bit 31 to be sign extended.
6363 if (Idx == 1 && ImmBitWidth == 64 && Imm.isIntN(32))
6364 return TTI::TCC_Free;
6365 // If we have BMI then we can use BEXTR/BZHI to mask out upper i64 bits.
6366 if (Idx == 1 && ImmBitWidth == 64 && ST->is64Bit() && ST->hasBMI() &&
6367 Imm.isMask())
6368 return X86TTIImpl::getIntImmCost(ST->hasBMI2() ? 255 : 65535);
6369 ImmIdx = 1;
6370 break;
6371 case Instruction::Add:
6372 case Instruction::Sub:
6373 // For add/sub, we can use the opposite instruction for INT32_MIN.
6374 if (Idx == 1 && ImmBitWidth == 64 && Imm.getZExtValue() == 0x80000000)
6375 return TTI::TCC_Free;
6376 ImmIdx = 1;
6377 break;
6378 case Instruction::UDiv:
6379 case Instruction::SDiv:
6380 case Instruction::URem:
6381 case Instruction::SRem:
6382 // Division by constant is typically expanded later into a different
6383 // instruction sequence. This completely changes the constants.
6384 // Report them as "free" to stop ConstantHoist from marking them as opaque.
6385 return TTI::TCC_Free;
6386 case Instruction::Mul:
6387 case Instruction::Or:
6388 case Instruction::Xor:
6389 ImmIdx = 1;
6390 break;
6391 // Always return TCC_Free for the shift value of a shift instruction.
6392 case Instruction::Shl:
6393 case Instruction::LShr:
6394 case Instruction::AShr:
6395 if (Idx == 1)
6396 return TTI::TCC_Free;
6397 break;
6398 case Instruction::Trunc:
6399 case Instruction::ZExt:
6400 case Instruction::SExt:
6401 case Instruction::IntToPtr:
6402 case Instruction::PtrToInt:
6403 case Instruction::BitCast:
6404 case Instruction::PHI:
6405 case Instruction::Call:
6406 case Instruction::Select:
6407 case Instruction::Ret:
6408 case Instruction::Load:
6409 break;
6410 }
6411
6412 if (Idx == ImmIdx) {
6413 uint64_t NumConstants = divideCeil(BitSize, 64);
6415 return (Cost <= NumConstants * TTI::TCC_Basic)
6416 ? static_cast<int>(TTI::TCC_Free)
6417 : Cost;
6418 }
6419
6420 return X86TTIImpl::getIntImmCost(Imm, Ty, CostKind);
6421}
6422
6425 const APInt &Imm, Type *Ty,
6427 assert(Ty->isIntegerTy());
6428
6429 unsigned BitSize = Ty->getPrimitiveSizeInBits();
6430 // There is no cost model for constants with a bit size of 0. Return TCC_Free
6431 // here, so that constant hoisting will ignore this constant.
6432 if (BitSize == 0)
6433 return TTI::TCC_Free;
6434
6435 switch (IID) {
6436 default:
6437 return TTI::TCC_Free;
6438 case Intrinsic::sadd_with_overflow:
6439 case Intrinsic::uadd_with_overflow:
6440 case Intrinsic::ssub_with_overflow:
6441 case Intrinsic::usub_with_overflow:
6442 case Intrinsic::smul_with_overflow:
6443 case Intrinsic::umul_with_overflow:
6444 if ((Idx == 1) && Imm.getBitWidth() <= 64 && Imm.isSignedIntN(32))
6445 return TTI::TCC_Free;
6446 break;
6447 case Intrinsic::experimental_stackmap:
6448 if ((Idx < 2) || (Imm.getBitWidth() <= 64 && Imm.isSignedIntN(64)))
6449 return TTI::TCC_Free;
6450 break;
6451 case Intrinsic::experimental_patchpoint_void:
6452 case Intrinsic::experimental_patchpoint:
6453 if ((Idx < 4) || (Imm.getBitWidth() <= 64 && Imm.isSignedIntN(64)))
6454 return TTI::TCC_Free;
6455 break;
6456 }
6457 return X86TTIImpl::getIntImmCost(Imm, Ty, CostKind);
6458}
6459
6462 const Instruction *I) const {
6464 return Opcode == Instruction::PHI ? TTI::TCC_Free : TTI::TCC_Basic;
6465 // Branches are assumed to be predicted.
6466 return TTI::TCC_Free;
6467}
6468
6469int X86TTIImpl::getGatherOverhead() const {
6470 // Some CPUs have more overhead for gather. The specified overhead is relative
6471 // to the Load operation. "2" is the number provided by Intel architects. This
6472 // parameter is used for cost estimation of Gather Op and comparison with
6473 // other alternatives.
6474 // TODO: Remove the explicit hasAVX512()?, That would mean we would only
6475 // enable gather with a -march.
6476 if (ST->hasAVX512() || (ST->hasAVX2() && ST->hasFastGather()))
6477 return 2;
6478
6479 return 1024;
6480}
6481
6482int X86TTIImpl::getScatterOverhead() const {
6483 if (ST->hasAVX512())
6484 return 2;
6485
6486 return 1024;
6487}
6488
6489// Return an average cost of Gather / Scatter instruction, maybe improved later.
6490InstructionCost X86TTIImpl::getGSVectorCost(unsigned Opcode,
6492 Type *SrcVTy, const Value *Ptr,
6493 Align Alignment,
6494 unsigned AddressSpace) const {
6495
6496 assert(isa<VectorType>(SrcVTy) && "Unexpected type in getGSVectorCost");
6497 unsigned VF = cast<FixedVectorType>(SrcVTy)->getNumElements();
6498
6499 // Try to reduce index size from 64 bit (default for GEP)
6500 // to 32. It is essential for VF 16. If the index can't be reduced to 32, the
6501 // operation will use 16 x 64 indices which do not fit in a zmm and needs
6502 // to split. Also check that the base pointer is the same for all lanes,
6503 // and that there's at most one variable index.
6504 auto getIndexSizeInBits = [](const Value *Ptr, const DataLayout &DL) {
6505 unsigned IndexSize = DL.getPointerSizeInBits();
6506 const GetElementPtrInst *GEP = dyn_cast_or_null<GetElementPtrInst>(Ptr);
6507 if (IndexSize < 64 || !GEP)
6508 return IndexSize;
6509
6510 unsigned NumOfVarIndices = 0;
6511 const Value *Ptrs = GEP->getPointerOperand();
6512 if (Ptrs->getType()->isVectorTy() && !getSplatValue(Ptrs))
6513 return IndexSize;
6514 for (unsigned I = 1, E = GEP->getNumOperands(); I != E; ++I) {
6515 if (isa<Constant>(GEP->getOperand(I)))
6516 continue;
6517 Type *IndxTy = GEP->getOperand(I)->getType();
6518 if (auto *IndexVTy = dyn_cast<VectorType>(IndxTy))
6519 IndxTy = IndexVTy->getElementType();
6520 if ((IndxTy->getPrimitiveSizeInBits() == 64 &&
6521 !isa<SExtInst>(GEP->getOperand(I))) ||
6522 ++NumOfVarIndices > 1)
6523 return IndexSize; // 64
6524 }
6525 return (unsigned)32;
6526 };
6527
6528 // Trying to reduce IndexSize to 32 bits for vector 16.
6529 // By default the IndexSize is equal to pointer size.
6530 unsigned IndexSize = (ST->hasAVX512() && VF >= 16)
6531 ? getIndexSizeInBits(Ptr, DL)
6532 : DL.getPointerSizeInBits();
6533
6534 auto *IndexVTy = FixedVectorType::get(
6535 IntegerType::get(SrcVTy->getContext(), IndexSize), VF);
6536 std::pair<InstructionCost, MVT> IdxsLT = getTypeLegalizationCost(IndexVTy);
6537 std::pair<InstructionCost, MVT> SrcLT = getTypeLegalizationCost(SrcVTy);
6538 InstructionCost::CostType SplitFactor =
6539 std::max(IdxsLT.first, SrcLT.first).getValue();
6540 if (SplitFactor > 1) {
6541 // Handle splitting of vector of pointers
6542 auto *SplitSrcTy =
6543 FixedVectorType::get(SrcVTy->getScalarType(), VF / SplitFactor);
6544 return SplitFactor * getGSVectorCost(Opcode, CostKind, SplitSrcTy, Ptr,
6545 Alignment, AddressSpace);
6546 }
6547
6548 // If we didn't split, this will be a single gather/scatter instruction.
6550 return 1;
6551
6552 // The gather / scatter cost is given by Intel architects. It is a rough
6553 // number since we are looking at one instruction in a time.
6554 const int GSOverhead = (Opcode == Instruction::Load) ? getGatherOverhead()
6555 : getScatterOverhead();
6556 return GSOverhead + VF * getMemoryOpCost(Opcode, SrcVTy->getScalarType(),
6557 Alignment, AddressSpace, CostKind);
6558}
6559
6560/// Calculate the cost of Gather / Scatter operation
6564 bool IsLoad = MICA.getID() == Intrinsic::masked_gather ||
6565 MICA.getID() == Intrinsic::vp_gather;
6566 unsigned Opcode = IsLoad ? Instruction::Load : Instruction::Store;
6567 Type *SrcVTy = MICA.getDataType();
6568 const Value *Ptr = MICA.getPointer();
6569 Align Alignment = MICA.getAlignment();
6570 if ((Opcode == Instruction::Load &&
6571 (!isLegalMaskedGather(SrcVTy, Align(Alignment)) ||
6573 Align(Alignment)))) ||
6574 (Opcode == Instruction::Store &&
6575 (!isLegalMaskedScatter(SrcVTy, Align(Alignment)) ||
6577 Align(Alignment)))))
6579
6580 assert(SrcVTy->isVectorTy() && "Unexpected data type for Gather/Scatter");
6581 unsigned AddressSpace = MICA.getAddressSpace();
6582 return getGSVectorCost(Opcode, CostKind, SrcVTy, Ptr, Alignment,
6583 AddressSpace);
6584}
6585
6587 const TargetTransformInfo::LSRCost &C2) const {
6588 // X86 specific here are "instruction number 1st priority".
6589 return std::tie(C1.Insns, C1.NumRegs, C1.AddRecCost, C1.NumIVMuls,
6590 C1.NumBaseAdds, C1.ScaleCost, C1.ImmCost, C1.SetupCost) <
6591 std::tie(C2.Insns, C2.NumRegs, C2.AddRecCost, C2.NumIVMuls,
6592 C2.NumBaseAdds, C2.ScaleCost, C2.ImmCost, C2.SetupCost);
6593}
6594
6596 return ST->hasMacroFusion() || ST->hasBranchFusion();
6597}
6598
6599static bool isLegalMaskedLoadStore(Type *ScalarTy, const X86Subtarget *ST) {
6600 if (!ST->hasAVX())
6601 return false;
6602
6603 if (ScalarTy->isPointerTy())
6604 return true;
6605
6606 if (ScalarTy->isFloatTy() || ScalarTy->isDoubleTy())
6607 return true;
6608
6609 if (ScalarTy->isHalfTy() && ST->hasBWI())
6610 return true;
6611
6612 if (ScalarTy->isBFloatTy() && ST->hasBF16())
6613 return true;
6614
6615 if (!ScalarTy->isIntegerTy())
6616 return false;
6617
6618 unsigned IntWidth = ScalarTy->getIntegerBitWidth();
6619 return IntWidth == 32 || IntWidth == 64 ||
6620 ((IntWidth == 8 || IntWidth == 16) && ST->hasBWI());
6621}
6622
6624 unsigned AddressSpace,
6625 TTI::MaskKind MaskKind) const {
6626 Type *ScalarTy = DataTy->getScalarType();
6627
6628 // The backend can't handle a single element vector w/o CFCMOV.
6629 if (isa<VectorType>(DataTy) &&
6630 cast<FixedVectorType>(DataTy)->getNumElements() == 1)
6631 return ST->hasCF() &&
6632 hasConditionalLoadStoreForType(ScalarTy, /*IsStore=*/false);
6633
6634 return isLegalMaskedLoadStore(ScalarTy, ST);
6635}
6636
6638 unsigned AddressSpace,
6639 TTI::MaskKind MaskKind) const {
6640 Type *ScalarTy = DataTy->getScalarType();
6641
6642 // The backend can't handle a single element vector w/o CFCMOV.
6643 if (isa<VectorType>(DataTy) &&
6644 cast<FixedVectorType>(DataTy)->getNumElements() == 1)
6645 return ST->hasCF() &&
6646 hasConditionalLoadStoreForType(ScalarTy, /*IsStore=*/true);
6647
6648 return isLegalMaskedLoadStore(ScalarTy, ST);
6649}
6650
6651bool X86TTIImpl::isLegalNTLoad(Type *DataType, Align Alignment) const {
6652 unsigned DataSize = DL.getTypeStoreSize(DataType);
6653 // The only supported nontemporal loads are for aligned vectors of 16 or 32
6654 // bytes. Note that 32-byte nontemporal vector loads are supported by AVX2
6655 // (the equivalent stores only require AVX).
6656 if (Alignment >= DataSize && (DataSize == 16 || DataSize == 32))
6657 return DataSize == 16 ? ST->hasSSE1() : ST->hasAVX2();
6658
6659 return false;
6660}
6661
6662bool X86TTIImpl::isLegalNTStore(Type *DataType, Align Alignment) const {
6663 unsigned DataSize = DL.getTypeStoreSize(DataType);
6664
6665 // SSE4A supports nontemporal stores of float and double at arbitrary
6666 // alignment.
6667 if (ST->hasSSE4A() && (DataType->isFloatTy() || DataType->isDoubleTy()))
6668 return true;
6669
6670 // Besides the SSE4A subtarget exception above, only aligned stores are
6671 // available nontemporaly on any other subtarget. And only stores with a size
6672 // of 4..32 bytes (powers of 2, only) are permitted.
6673 if (Alignment < DataSize || DataSize < 4 || DataSize > 32 ||
6674 !isPowerOf2_32(DataSize))
6675 return false;
6676
6677 // 32-byte vector nontemporal stores are supported by AVX (the equivalent
6678 // loads require AVX2).
6679 if (DataSize == 32)
6680 return ST->hasAVX();
6681 if (DataSize == 16)
6682 return ST->hasSSE1();
6683 return true;
6684}
6685
6687 ElementCount NumElements) const {
6688 // movddup
6689 return ST->hasSSE3() && !NumElements.isScalable() &&
6690 NumElements.getFixedValue() == 2 &&
6691 ElementTy == Type::getDoubleTy(ElementTy->getContext());
6692}
6693
6694bool X86TTIImpl::isLegalMaskedExpandLoad(Type *DataTy, Align Alignment) const {
6695 if (!isa<VectorType>(DataTy))
6696 return false;
6697
6698 if (!ST->hasAVX512())
6699 return false;
6700
6701 // The backend can't handle a single element vector.
6702 if (cast<FixedVectorType>(DataTy)->getNumElements() == 1)
6703 return false;
6704
6705 Type *ScalarTy = cast<VectorType>(DataTy)->getElementType();
6706
6707 if (ScalarTy->isFloatTy() || ScalarTy->isDoubleTy())
6708 return true;
6709
6710 if (!ScalarTy->isIntegerTy())
6711 return false;
6712
6713 unsigned IntWidth = ScalarTy->getIntegerBitWidth();
6714 return IntWidth == 32 || IntWidth == 64 ||
6715 ((IntWidth == 8 || IntWidth == 16) && ST->hasVBMI2());
6716}
6717
6719 Align Alignment) const {
6720 return isLegalMaskedExpandLoad(DataTy, Alignment);
6721}
6722
6723bool X86TTIImpl::supportsGather() const {
6724 // Some CPUs have better gather performance than others.
6725 // TODO: Remove the explicit ST->hasAVX512()?, That would mean we would only
6726 // enable gather with a -march.
6727 return ST->hasAVX512() || (ST->hasFastGather() && ST->hasAVX2());
6728}
6729
6731 Align Alignment) const {
6732 // Gather / Scatter for vector 2 is not profitable on KNL / SKX
6733 // Vector-4 of gather/scatter instruction does not exist on KNL. We can extend
6734 // it to 8 elements, but zeroing upper bits of the mask vector will add more
6735 // instructions. Right now we give the scalar cost of vector-4 for KNL. TODO:
6736 // Check, maybe the gather/scatter instruction is better in the VariableMask
6737 // case.
6738 unsigned NumElts = cast<FixedVectorType>(VTy)->getNumElements();
6739 return NumElts == 1 ||
6740 (ST->hasAVX512() && (NumElts == 2 || (NumElts == 4 && !ST->hasVLX())));
6741}
6742
6744 Align Alignment) const {
6745 Type *ScalarTy = DataTy->getScalarType();
6746 if (ScalarTy->isPointerTy())
6747 return true;
6748
6749 if (ScalarTy->isFloatTy() || ScalarTy->isDoubleTy())
6750 return true;
6751
6752 if (!ScalarTy->isIntegerTy())
6753 return false;
6754
6755 unsigned IntWidth = ScalarTy->getIntegerBitWidth();
6756 return IntWidth == 32 || IntWidth == 64;
6757}
6758
6759bool X86TTIImpl::isLegalMaskedGather(Type *DataTy, Align Alignment) const {
6760 if (!supportsGather() || !ST->preferGather())
6761 return false;
6762 return isLegalMaskedGatherScatter(DataTy, Alignment);
6763}
6764
6765bool X86TTIImpl::isLegalAltInstr(VectorType *VecTy, unsigned Opcode0,
6766 unsigned Opcode1,
6767 const SmallBitVector &OpcodeMask) const {
6768 // ADDSUBPS 4xf32 SSE3
6769 // VADDSUBPS 4xf32 AVX
6770 // VADDSUBPS 8xf32 AVX2
6771 // ADDSUBPD 2xf64 SSE3
6772 // VADDSUBPD 2xf64 AVX
6773 // VADDSUBPD 4xf64 AVX2
6774
6775 unsigned NumElements = cast<FixedVectorType>(VecTy)->getNumElements();
6776 assert(OpcodeMask.size() == NumElements && "Mask and VecTy are incompatible");
6777 if (!isPowerOf2_32(NumElements))
6778 return false;
6779 // Check the opcode pattern. We apply the mask on the opcode arguments and
6780 // then check if it is what we expect.
6781 for (int Lane : seq<int>(0, NumElements)) {
6782 unsigned Opc = OpcodeMask.test(Lane) ? Opcode1 : Opcode0;
6783 // We expect FSub for even lanes and FAdd for odd lanes.
6784 if (Lane % 2 == 0 && Opc != Instruction::FSub)
6785 return false;
6786 if (Lane % 2 == 1 && Opc != Instruction::FAdd)
6787 return false;
6788 }
6789 // Now check that the pattern is supported by the target ISA.
6790 Type *ElemTy = cast<VectorType>(VecTy)->getElementType();
6791 if (ElemTy->isFloatTy())
6792 return ST->hasSSE3() && NumElements % 4 == 0;
6793 if (ElemTy->isDoubleTy())
6794 return ST->hasSSE3() && NumElements % 2 == 0;
6795 return false;
6796}
6797
6798bool X86TTIImpl::isLegalMaskedScatter(Type *DataType, Align Alignment) const {
6799 // AVX2 doesn't support scatter
6800 if (!ST->hasAVX512() || !ST->preferScatter())
6801 return false;
6802 return isLegalMaskedGatherScatter(DataType, Alignment);
6803}
6804
6805bool X86TTIImpl::hasDivRemOp(Type *DataType, bool IsSigned) const {
6806 EVT VT = TLI->getValueType(DL, DataType);
6807 return TLI->isOperationLegal(IsSigned ? ISD::SDIVREM : ISD::UDIVREM, VT);
6808}
6809
6811 // FDIV is always expensive, even if it has a very low uop count.
6812 // TODO: Still necessary for recent CPUs with low latency/throughput fdiv?
6813 if (I->getOpcode() == Instruction::FDiv)
6814 return true;
6815
6817}
6818
6819bool X86TTIImpl::isFCmpOrdCheaperThanFCmpZero(Type *Ty) const { return false; }
6820
6822 const Function *Callee) const {
6823 const TargetMachine &TM = getTLI()->getTargetMachine();
6824
6825 // Work this as a subsetting of subtarget features.
6826 const X86Subtarget &CallerSubtarget = TM.getSubtarget<X86Subtarget>(*Caller);
6827 const X86Subtarget &CalleeSubtarget = TM.getSubtarget<X86Subtarget>(*Callee);
6828 const FeatureBitset &CallerBits = CallerSubtarget.getFeatureBits();
6829 const FeatureBitset &CalleeBits = CalleeSubtarget.getFeatureBits();
6830
6831 // Check whether callee features are a subset of caller features
6832 // (apart from the ignore list).
6833 const FeatureBitset &InlineIgnoreFeatures =
6834 CallerSubtarget.getInlineIgnoreFeatures();
6835 FeatureBitset RealCallerBits = CallerBits & ~InlineIgnoreFeatures;
6836 FeatureBitset RealCalleeBits = CalleeBits & ~InlineIgnoreFeatures;
6837 if ((RealCallerBits & RealCalleeBits) != RealCalleeBits)
6838 return false;
6839
6840 // If the features are not exactly the same (or there is a difference in
6841 // AVX512 register usage), we need to additionally check for calls
6842 // that may become ABI-incompatible as a result of inlining.
6843 if (RealCallerBits == RealCalleeBits &&
6844 CallerSubtarget.useAVX512Regs() == CalleeSubtarget.useAVX512Regs())
6845 return true;
6846
6847 for (const Instruction &I : instructions(Callee)) {
6848 if (const auto *CB = dyn_cast<CallBase>(&I)) {
6849 // Having more target features is fine for inline ASM and intrinsics.
6850 if (CB->isInlineAsm() || CB->getIntrinsicID() != Intrinsic::not_intrinsic)
6851 continue;
6852
6854 for (Value *Arg : CB->args())
6855 Types.push_back(Arg->getType());
6856 if (!CB->getType()->isVoidTy())
6857 Types.push_back(CB->getType());
6858
6859 // Simple types are always ABI compatible.
6860 auto IsSimpleTy = [](Type *Ty) {
6861 return !Ty->isVectorTy() && !Ty->isAggregateType();
6862 };
6863 if (all_of(Types, IsSimpleTy))
6864 continue;
6865
6866 // Do a precise compatibility check.
6867 if (!areTypesABICompatible(Caller, Callee, Types))
6868 return false;
6869 }
6870 }
6871 return true;
6872}
6873
6875 const Function *Callee,
6876 ArrayRef<Type *> Types) const {
6877 const TargetMachine &TM = getTLI()->getTargetMachine();
6878 const TargetLowering *CallerTLI =
6879 TM.getSubtargetImpl(*Caller)->getTargetLowering();
6880 const TargetLowering *CalleeTLI =
6881 TM.getSubtargetImpl(*Callee)->getTargetLowering();
6882
6883 LLVMContext &Ctx = Caller->getContext();
6884 const DataLayout &DL = Caller->getDataLayout();
6885 CallingConv::ID CC = Callee->getCallingConv();
6886 return all_of(Types, [&](Type *Ty) {
6887 SmallVector<EVT> VTs;
6888 ComputeValueVTs(*CallerTLI, DL, Ty, VTs);
6889 return all_of(VTs, [&](EVT VT) {
6890 return CallerTLI->getRegisterTypeForCallingConv(Ctx, CC, VT) ==
6891 CalleeTLI->getRegisterTypeForCallingConv(Ctx, CC, VT);
6892 });
6893 });
6894}
6895
6897X86TTIImpl::enableMemCmpExpansion(bool OptSize, bool IsZeroCmp) const {
6899 Options.MaxNumLoads = TLI->getMaxExpandSizeMemcmp(OptSize);
6900 Options.NumLoadsPerBlock = 2;
6901 // All GPR and vector loads can be unaligned.
6902 Options.AllowOverlappingLoads = true;
6903 if (IsZeroCmp) {
6904 // Only enable vector loads for equality comparison. Right now the vector
6905 // version is not as fast for three way compare (see #33329).
6906 const unsigned PreferredWidth = ST->getPreferVectorWidth();
6907 if (PreferredWidth >= 512 && ST->hasAVX512())
6908 Options.LoadSizes.push_back(64);
6909 if (PreferredWidth >= 256 && ST->hasAVX()) Options.LoadSizes.push_back(32);
6910 if (PreferredWidth >= 128 && ST->hasSSE2()) Options.LoadSizes.push_back(16);
6911 }
6912 if (ST->is64Bit()) {
6913 Options.LoadSizes.push_back(8);
6914 }
6915 Options.LoadSizes.push_back(4);
6916 Options.LoadSizes.push_back(2);
6917 Options.LoadSizes.push_back(1);
6918 return Options;
6919}
6920
6922 return supportsGather();
6923}
6924
6926 return false;
6927}
6928
6930 // TODO: We expect this to be beneficial regardless of arch,
6931 // but there are currently some unexplained performance artifacts on Atom.
6932 // As a temporary solution, disable on Atom.
6933 return !(ST->isAtom());
6934}
6935
6937 switch (II->getIntrinsicID()) {
6938 default:
6939 return true;
6940 case Intrinsic::vector_reduce_mul:
6941 case Intrinsic::vector_reduce_smax:
6942 case Intrinsic::vector_reduce_smin:
6943 case Intrinsic::vector_reduce_umax:
6944 case Intrinsic::vector_reduce_umin:
6945 return false;
6946 }
6947}
6948
6949// Get estimation for interleaved load/store operations and strided load.
6950// \p Indices contains indices for strided load.
6951// \p Factor - the factor of interleaving.
6952// AVX-512 provides 3-src shuffles that significantly reduces the cost.
6954 unsigned Opcode, FixedVectorType *VecTy, unsigned Factor,
6955 ArrayRef<unsigned> Indices, Align Alignment, unsigned AddressSpace,
6956 TTI::TargetCostKind CostKind, bool UseMaskForCond,
6957 bool UseMaskForGaps) const {
6958 // VecTy for interleave memop is <VF*Factor x Elt>.
6959 // So, for VF=4, Interleave Factor = 3, Element type = i32 we have
6960 // VecTy = <12 x i32>.
6961
6962 // Calculate the number of memory operations (NumOfMemOps), required
6963 // for load/store the VecTy.
6964 MVT LegalVT = getTypeLegalizationCost(VecTy).second;
6965 unsigned VecTySize = DL.getTypeStoreSize(VecTy);
6966 unsigned LegalVTSize = LegalVT.getStoreSize();
6967 unsigned NumOfMemOps = (VecTySize + LegalVTSize - 1) / LegalVTSize;
6968
6969 // Get the cost of one memory operation.
6970 auto *SingleMemOpTy = FixedVectorType::get(VecTy->getElementType(),
6971 LegalVT.getVectorNumElements());
6972 InstructionCost MemOpCost;
6973 bool UseMaskedMemOp = UseMaskForCond || UseMaskForGaps;
6974 if (UseMaskedMemOp) {
6975 unsigned IID = Opcode == Instruction::Load ? Intrinsic::masked_load
6976 : Intrinsic::masked_store;
6977 MemOpCost = getMaskedMemoryOpCost(
6978 {IID, SingleMemOpTy, Alignment, AddressSpace}, CostKind);
6979 } else
6980 MemOpCost = getMemoryOpCost(Opcode, SingleMemOpTy, Alignment, AddressSpace,
6981 CostKind);
6982
6983 unsigned VF = VecTy->getNumElements() / Factor;
6984 MVT VT =
6985 MVT::getVectorVT(TLI->getSimpleValueType(DL, VecTy->getScalarType()), VF);
6986
6987 InstructionCost MaskCost;
6988 if (UseMaskedMemOp) {
6989 APInt DemandedLoadStoreElts = APInt::getZero(VecTy->getNumElements());
6990 for (unsigned Index : Indices) {
6991 assert(Index < Factor && "Invalid index for interleaved memory op");
6992 for (unsigned Elm = 0; Elm < VF; Elm++)
6993 DemandedLoadStoreElts.setBit(Index + Elm * Factor);
6994 }
6995
6996 Type *I1Type = Type::getInt1Ty(VecTy->getContext());
6997
6998 MaskCost = getReplicationShuffleCost(
6999 I1Type, Factor, VF,
7000 UseMaskForGaps ? DemandedLoadStoreElts
7002 CostKind);
7003
7004 // The Gaps mask is invariant and created outside the loop, therefore the
7005 // cost of creating it is not accounted for here. However if we have both
7006 // a MaskForGaps and some other mask that guards the execution of the
7007 // memory access, we need to account for the cost of And-ing the two masks
7008 // inside the loop.
7009 if (UseMaskForGaps) {
7010 auto *MaskVT = FixedVectorType::get(I1Type, VecTy->getNumElements());
7011 MaskCost += getArithmeticInstrCost(BinaryOperator::And, MaskVT, CostKind);
7012 }
7013 }
7014
7015 if (Opcode == Instruction::Load) {
7016 // The tables (AVX512InterleavedLoadTbl and AVX512InterleavedStoreTbl)
7017 // contain the cost of the optimized shuffle sequence that the
7018 // X86InterleavedAccess pass will generate.
7019 // The cost of loads and stores are computed separately from the table.
7020
7021 // X86InterleavedAccess support only the following interleaved-access group.
7022 static const CostTblEntry AVX512InterleavedLoadTbl[] = {
7023 {3, MVT::v16i8, 12}, //(load 48i8 and) deinterleave into 3 x 16i8
7024 {3, MVT::v32i8, 14}, //(load 96i8 and) deinterleave into 3 x 32i8
7025 {3, MVT::v64i8, 22}, //(load 96i8 and) deinterleave into 3 x 32i8
7026 };
7027
7028 if (const auto *Entry =
7029 CostTableLookup(AVX512InterleavedLoadTbl, Factor, VT))
7030 return MaskCost + NumOfMemOps * MemOpCost + Entry->Cost;
7031 //If an entry does not exist, fallback to the default implementation.
7032
7033 // Kind of shuffle depends on number of loaded values.
7034 // If we load the entire data in one register, we can use a 1-src shuffle.
7035 // Otherwise, we'll merge 2 sources in each operation.
7036 TTI::ShuffleKind ShuffleKind =
7037 (NumOfMemOps > 1) ? TTI::SK_PermuteTwoSrc : TTI::SK_PermuteSingleSrc;
7038
7039 InstructionCost ShuffleCost = getShuffleCost(
7040 ShuffleKind, SingleMemOpTy, SingleMemOpTy, {}, CostKind, 0, nullptr);
7041
7042 unsigned NumOfLoadsInInterleaveGrp =
7043 Indices.size() ? Indices.size() : Factor;
7044 auto *ResultTy = FixedVectorType::get(VecTy->getElementType(),
7045 VecTy->getNumElements() / Factor);
7046 InstructionCost NumOfResults =
7047 getTypeLegalizationCost(ResultTy).first * NumOfLoadsInInterleaveGrp;
7048
7049 // About a half of the loads may be folded in shuffles when we have only
7050 // one result. If we have more than one result, or the loads are masked,
7051 // we do not fold loads at all.
7052 unsigned NumOfUnfoldedLoads =
7053 UseMaskedMemOp || NumOfResults > 1 ? NumOfMemOps : NumOfMemOps / 2;
7054
7055 // Get a number of shuffle operations per result.
7056 unsigned NumOfShufflesPerResult =
7057 std::max((unsigned)1, (unsigned)(NumOfMemOps - 1));
7058
7059 // The SK_MergeTwoSrc shuffle clobbers one of src operands.
7060 // When we have more than one destination, we need additional instructions
7061 // to keep sources.
7062 InstructionCost NumOfMoves = 0;
7063 if (NumOfResults > 1 && ShuffleKind == TTI::SK_PermuteTwoSrc)
7064 NumOfMoves = NumOfResults * NumOfShufflesPerResult / 2;
7065
7066 InstructionCost Cost = NumOfResults * NumOfShufflesPerResult * ShuffleCost +
7067 MaskCost + NumOfUnfoldedLoads * MemOpCost +
7068 NumOfMoves;
7069
7070 return Cost;
7071 }
7072
7073 // Store.
7074 assert(Opcode == Instruction::Store &&
7075 "Expected Store Instruction at this point");
7076 // X86InterleavedAccess support only the following interleaved-access group.
7077 static const CostTblEntry AVX512InterleavedStoreTbl[] = {
7078 {3, MVT::v16i8, 12}, // interleave 3 x 16i8 into 48i8 (and store)
7079 {3, MVT::v32i8, 14}, // interleave 3 x 32i8 into 96i8 (and store)
7080 {3, MVT::v64i8, 26}, // interleave 3 x 64i8 into 96i8 (and store)
7081
7082 {4, MVT::v8i8, 10}, // interleave 4 x 8i8 into 32i8 (and store)
7083 {4, MVT::v16i8, 11}, // interleave 4 x 16i8 into 64i8 (and store)
7084 {4, MVT::v32i8, 14}, // interleave 4 x 32i8 into 128i8 (and store)
7085 {4, MVT::v64i8, 24} // interleave 4 x 32i8 into 256i8 (and store)
7086 };
7087
7088 if (const auto *Entry =
7089 CostTableLookup(AVX512InterleavedStoreTbl, Factor, VT))
7090 return MaskCost + NumOfMemOps * MemOpCost + Entry->Cost;
7091 //If an entry does not exist, fallback to the default implementation.
7092
7093 // There is no strided stores meanwhile. And store can't be folded in
7094 // shuffle.
7095 unsigned NumOfSources = Factor; // The number of values to be merged.
7096 InstructionCost ShuffleCost =
7097 getShuffleCost(TTI::SK_PermuteTwoSrc, SingleMemOpTy, SingleMemOpTy, {},
7098 CostKind, 0, nullptr);
7099 unsigned NumOfShufflesPerStore = NumOfSources - 1;
7100
7101 // The SK_MergeTwoSrc shuffle clobbers one of src operands.
7102 // We need additional instructions to keep sources.
7103 unsigned NumOfMoves = NumOfMemOps * NumOfShufflesPerStore / 2;
7105 MaskCost +
7106 NumOfMemOps * (MemOpCost + NumOfShufflesPerStore * ShuffleCost) +
7107 NumOfMoves;
7108 return Cost;
7109}
7110
7112 unsigned Opcode, Type *BaseTy, unsigned Factor, ArrayRef<unsigned> Indices,
7113 Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind,
7114 bool UseMaskForCond, bool UseMaskForGaps) const {
7115 auto *VecTy = cast<FixedVectorType>(BaseTy);
7116
7117 auto isSupportedOnAVX512 = [&](Type *VecTy) {
7118 Type *EltTy = cast<VectorType>(VecTy)->getElementType();
7119 if (EltTy->isFloatTy() || EltTy->isDoubleTy() || EltTy->isIntegerTy(64) ||
7120 EltTy->isIntegerTy(32) || EltTy->isPointerTy())
7121 return true;
7122 if (EltTy->isIntegerTy(16) || EltTy->isIntegerTy(8) || EltTy->isHalfTy())
7123 return ST->hasBWI();
7124 if (EltTy->isBFloatTy())
7125 return ST->hasBF16();
7126 return false;
7127 };
7128 if (ST->hasAVX512() && isSupportedOnAVX512(VecTy))
7130 Opcode, VecTy, Factor, Indices, Alignment,
7131 AddressSpace, CostKind, UseMaskForCond, UseMaskForGaps);
7132
7133 if (UseMaskForCond || UseMaskForGaps)
7134 return BaseT::getInterleavedMemoryOpCost(Opcode, VecTy, Factor, Indices,
7135 Alignment, AddressSpace, CostKind,
7136 UseMaskForCond, UseMaskForGaps);
7137
7138 // Get estimation for interleaved load/store operations for SSE-AVX2.
7139 // As opposed to AVX-512, SSE-AVX2 do not have generic shuffles that allow
7140 // computing the cost using a generic formula as a function of generic
7141 // shuffles. We therefore use a lookup table instead, filled according to
7142 // the instruction sequences that codegen currently generates.
7143
7144 // VecTy for interleave memop is <VF*Factor x Elt>.
7145 // So, for VF=4, Interleave Factor = 3, Element type = i32 we have
7146 // VecTy = <12 x i32>.
7147 MVT LegalVT = getTypeLegalizationCost(VecTy).second;
7148
7149 // This function can be called with VecTy=<6xi128>, Factor=3, in which case
7150 // the VF=2, while v2i128 is an unsupported MVT vector type
7151 // (see MachineValueType.h::getVectorVT()).
7152 if (!LegalVT.isVector())
7153 return BaseT::getInterleavedMemoryOpCost(Opcode, VecTy, Factor, Indices,
7154 Alignment, AddressSpace, CostKind);
7155
7156 unsigned VF = VecTy->getNumElements() / Factor;
7157 Type *ScalarTy = VecTy->getElementType();
7158 // Deduplicate entries, model floats/pointers as appropriately-sized integers.
7159 if (!ScalarTy->isIntegerTy())
7160 ScalarTy =
7161 Type::getIntNTy(ScalarTy->getContext(), DL.getTypeSizeInBits(ScalarTy));
7162
7163 // Get the cost of all the memory operations.
7164 // FIXME: discount dead loads.
7165 InstructionCost MemOpCosts =
7166 getMemoryOpCost(Opcode, VecTy, Alignment, AddressSpace, CostKind);
7167
7168 auto *VT = FixedVectorType::get(ScalarTy, VF);
7169 EVT ETy = TLI->getValueType(DL, VT);
7170 if (!ETy.isSimple())
7171 return BaseT::getInterleavedMemoryOpCost(Opcode, VecTy, Factor, Indices,
7172 Alignment, AddressSpace, CostKind);
7173
7174 // TODO: Complete for other data-types and strides.
7175 // Each combination of Stride, element bit width and VF results in a different
7176 // sequence; The cost tables are therefore accessed with:
7177 // Factor (stride) and VectorType=VFxiN.
7178 // The Cost accounts only for the shuffle sequence;
7179 // The cost of the loads/stores is accounted for separately.
7180 //
7181 static const CostTblEntry AVX2InterleavedLoadTbl[] = {
7182 {2, MVT::v2i8, 2}, // (load 4i8 and) deinterleave into 2 x 2i8
7183 {2, MVT::v4i8, 2}, // (load 8i8 and) deinterleave into 2 x 4i8
7184 {2, MVT::v8i8, 2}, // (load 16i8 and) deinterleave into 2 x 8i8
7185 {2, MVT::v16i8, 4}, // (load 32i8 and) deinterleave into 2 x 16i8
7186 {2, MVT::v32i8, 6}, // (load 64i8 and) deinterleave into 2 x 32i8
7187
7188 {2, MVT::v8i16, 6}, // (load 16i16 and) deinterleave into 2 x 8i16
7189 {2, MVT::v16i16, 9}, // (load 32i16 and) deinterleave into 2 x 16i16
7190 {2, MVT::v32i16, 18}, // (load 64i16 and) deinterleave into 2 x 32i16
7191
7192 {2, MVT::v8i32, 4}, // (load 16i32 and) deinterleave into 2 x 8i32
7193 {2, MVT::v16i32, 8}, // (load 32i32 and) deinterleave into 2 x 16i32
7194 {2, MVT::v32i32, 16}, // (load 64i32 and) deinterleave into 2 x 32i32
7195
7196 {2, MVT::v4i64, 4}, // (load 8i64 and) deinterleave into 2 x 4i64
7197 {2, MVT::v8i64, 8}, // (load 16i64 and) deinterleave into 2 x 8i64
7198 {2, MVT::v16i64, 16}, // (load 32i64 and) deinterleave into 2 x 16i64
7199 {2, MVT::v32i64, 32}, // (load 64i64 and) deinterleave into 2 x 32i64
7200
7201 {3, MVT::v2i8, 3}, // (load 6i8 and) deinterleave into 3 x 2i8
7202 {3, MVT::v4i8, 3}, // (load 12i8 and) deinterleave into 3 x 4i8
7203 {3, MVT::v8i8, 6}, // (load 24i8 and) deinterleave into 3 x 8i8
7204 {3, MVT::v16i8, 11}, // (load 48i8 and) deinterleave into 3 x 16i8
7205 {3, MVT::v32i8, 14}, // (load 96i8 and) deinterleave into 3 x 32i8
7206
7207 {3, MVT::v2i16, 5}, // (load 6i16 and) deinterleave into 3 x 2i16
7208 {3, MVT::v4i16, 7}, // (load 12i16 and) deinterleave into 3 x 4i16
7209 {3, MVT::v8i16, 9}, // (load 24i16 and) deinterleave into 3 x 8i16
7210 {3, MVT::v16i16, 28}, // (load 48i16 and) deinterleave into 3 x 16i16
7211 {3, MVT::v32i16, 56}, // (load 96i16 and) deinterleave into 3 x 32i16
7212
7213 {3, MVT::v2i32, 3}, // (load 6i32 and) deinterleave into 3 x 2i32
7214 {3, MVT::v4i32, 3}, // (load 12i32 and) deinterleave into 3 x 4i32
7215 {3, MVT::v8i32, 7}, // (load 24i32 and) deinterleave into 3 x 8i32
7216 {3, MVT::v16i32, 14}, // (load 48i32 and) deinterleave into 3 x 16i32
7217 {3, MVT::v32i32, 32}, // (load 96i32 and) deinterleave into 3 x 32i32
7218
7219 {3, MVT::v2i64, 1}, // (load 6i64 and) deinterleave into 3 x 2i64
7220 {3, MVT::v4i64, 5}, // (load 12i64 and) deinterleave into 3 x 4i64
7221 {3, MVT::v8i64, 10}, // (load 24i64 and) deinterleave into 3 x 8i64
7222 {3, MVT::v16i64, 20}, // (load 48i64 and) deinterleave into 3 x 16i64
7223
7224 {4, MVT::v2i8, 4}, // (load 8i8 and) deinterleave into 4 x 2i8
7225 {4, MVT::v4i8, 4}, // (load 16i8 and) deinterleave into 4 x 4i8
7226 {4, MVT::v8i8, 12}, // (load 32i8 and) deinterleave into 4 x 8i8
7227 {4, MVT::v16i8, 24}, // (load 64i8 and) deinterleave into 4 x 16i8
7228 {4, MVT::v32i8, 56}, // (load 128i8 and) deinterleave into 4 x 32i8
7229
7230 {4, MVT::v2i16, 6}, // (load 8i16 and) deinterleave into 4 x 2i16
7231 {4, MVT::v4i16, 17}, // (load 16i16 and) deinterleave into 4 x 4i16
7232 {4, MVT::v8i16, 33}, // (load 32i16 and) deinterleave into 4 x 8i16
7233 {4, MVT::v16i16, 75}, // (load 64i16 and) deinterleave into 4 x 16i16
7234 {4, MVT::v32i16, 150}, // (load 128i16 and) deinterleave into 4 x 32i16
7235
7236 {4, MVT::v2i32, 4}, // (load 8i32 and) deinterleave into 4 x 2i32
7237 {4, MVT::v4i32, 8}, // (load 16i32 and) deinterleave into 4 x 4i32
7238 {4, MVT::v8i32, 16}, // (load 32i32 and) deinterleave into 4 x 8i32
7239 {4, MVT::v16i32, 32}, // (load 64i32 and) deinterleave into 4 x 16i32
7240 {4, MVT::v32i32, 68}, // (load 128i32 and) deinterleave into 4 x 32i32
7241
7242 {4, MVT::v2i64, 6}, // (load 8i64 and) deinterleave into 4 x 2i64
7243 {4, MVT::v4i64, 8}, // (load 16i64 and) deinterleave into 4 x 4i64
7244 {4, MVT::v8i64, 20}, // (load 32i64 and) deinterleave into 4 x 8i64
7245 {4, MVT::v16i64, 40}, // (load 64i64 and) deinterleave into 4 x 16i64
7246
7247 {6, MVT::v2i8, 6}, // (load 12i8 and) deinterleave into 6 x 2i8
7248 {6, MVT::v4i8, 14}, // (load 24i8 and) deinterleave into 6 x 4i8
7249 {6, MVT::v8i8, 18}, // (load 48i8 and) deinterleave into 6 x 8i8
7250 {6, MVT::v16i8, 43}, // (load 96i8 and) deinterleave into 6 x 16i8
7251 {6, MVT::v32i8, 82}, // (load 192i8 and) deinterleave into 6 x 32i8
7252
7253 {6, MVT::v2i16, 13}, // (load 12i16 and) deinterleave into 6 x 2i16
7254 {6, MVT::v4i16, 9}, // (load 24i16 and) deinterleave into 6 x 4i16
7255 {6, MVT::v8i16, 39}, // (load 48i16 and) deinterleave into 6 x 8i16
7256 {6, MVT::v16i16, 106}, // (load 96i16 and) deinterleave into 6 x 16i16
7257 {6, MVT::v32i16, 212}, // (load 192i16 and) deinterleave into 6 x 32i16
7258
7259 {6, MVT::v2i32, 6}, // (load 12i32 and) deinterleave into 6 x 2i32
7260 {6, MVT::v4i32, 15}, // (load 24i32 and) deinterleave into 6 x 4i32
7261 {6, MVT::v8i32, 31}, // (load 48i32 and) deinterleave into 6 x 8i32
7262 {6, MVT::v16i32, 64}, // (load 96i32 and) deinterleave into 6 x 16i32
7263
7264 {6, MVT::v2i64, 6}, // (load 12i64 and) deinterleave into 6 x 2i64
7265 {6, MVT::v4i64, 18}, // (load 24i64 and) deinterleave into 6 x 4i64
7266 {6, MVT::v8i64, 36}, // (load 48i64 and) deinterleave into 6 x 8i64
7267
7268 {8, MVT::v8i32, 40} // (load 64i32 and) deinterleave into 8 x 8i32
7269 };
7270
7271 static const CostTblEntry SSSE3InterleavedLoadTbl[] = {
7272 {2, MVT::v4i16, 2}, // (load 8i16 and) deinterleave into 2 x 4i16
7273 };
7274
7275 static const CostTblEntry SSE2InterleavedLoadTbl[] = {
7276 {2, MVT::v2i16, 2}, // (load 4i16 and) deinterleave into 2 x 2i16
7277 {2, MVT::v4i16, 7}, // (load 8i16 and) deinterleave into 2 x 4i16
7278
7279 {2, MVT::v2i32, 2}, // (load 4i32 and) deinterleave into 2 x 2i32
7280 {2, MVT::v4i32, 2}, // (load 8i32 and) deinterleave into 2 x 4i32
7281
7282 {2, MVT::v2i64, 2}, // (load 4i64 and) deinterleave into 2 x 2i64
7283 };
7284
7285 static const CostTblEntry AVX2InterleavedStoreTbl[] = {
7286 {2, MVT::v16i8, 3}, // interleave 2 x 16i8 into 32i8 (and store)
7287 {2, MVT::v32i8, 4}, // interleave 2 x 32i8 into 64i8 (and store)
7288
7289 {2, MVT::v8i16, 3}, // interleave 2 x 8i16 into 16i16 (and store)
7290 {2, MVT::v16i16, 4}, // interleave 2 x 16i16 into 32i16 (and store)
7291 {2, MVT::v32i16, 8}, // interleave 2 x 32i16 into 64i16 (and store)
7292
7293 {2, MVT::v4i32, 2}, // interleave 2 x 4i32 into 8i32 (and store)
7294 {2, MVT::v8i32, 4}, // interleave 2 x 8i32 into 16i32 (and store)
7295 {2, MVT::v16i32, 8}, // interleave 2 x 16i32 into 32i32 (and store)
7296 {2, MVT::v32i32, 16}, // interleave 2 x 32i32 into 64i32 (and store)
7297
7298 {2, MVT::v2i64, 2}, // interleave 2 x 2i64 into 4i64 (and store)
7299 {2, MVT::v4i64, 4}, // interleave 2 x 4i64 into 8i64 (and store)
7300 {2, MVT::v8i64, 8}, // interleave 2 x 8i64 into 16i64 (and store)
7301 {2, MVT::v16i64, 16}, // interleave 2 x 16i64 into 32i64 (and store)
7302 {2, MVT::v32i64, 32}, // interleave 2 x 32i64 into 64i64 (and store)
7303
7304 {3, MVT::v2i8, 4}, // interleave 3 x 2i8 into 6i8 (and store)
7305 {3, MVT::v4i8, 4}, // interleave 3 x 4i8 into 12i8 (and store)
7306 {3, MVT::v8i8, 6}, // interleave 3 x 8i8 into 24i8 (and store)
7307 {3, MVT::v16i8, 11}, // interleave 3 x 16i8 into 48i8 (and store)
7308 {3, MVT::v32i8, 13}, // interleave 3 x 32i8 into 96i8 (and store)
7309
7310 {3, MVT::v2i16, 4}, // interleave 3 x 2i16 into 6i16 (and store)
7311 {3, MVT::v4i16, 6}, // interleave 3 x 4i16 into 12i16 (and store)
7312 {3, MVT::v8i16, 12}, // interleave 3 x 8i16 into 24i16 (and store)
7313 {3, MVT::v16i16, 27}, // interleave 3 x 16i16 into 48i16 (and store)
7314 {3, MVT::v32i16, 54}, // interleave 3 x 32i16 into 96i16 (and store)
7315
7316 {3, MVT::v2i32, 4}, // interleave 3 x 2i32 into 6i32 (and store)
7317 {3, MVT::v4i32, 5}, // interleave 3 x 4i32 into 12i32 (and store)
7318 {3, MVT::v8i32, 11}, // interleave 3 x 8i32 into 24i32 (and store)
7319 {3, MVT::v16i32, 22}, // interleave 3 x 16i32 into 48i32 (and store)
7320 {3, MVT::v32i32, 48}, // interleave 3 x 32i32 into 96i32 (and store)
7321
7322 {3, MVT::v2i64, 4}, // interleave 3 x 2i64 into 6i64 (and store)
7323 {3, MVT::v4i64, 6}, // interleave 3 x 4i64 into 12i64 (and store)
7324 {3, MVT::v8i64, 12}, // interleave 3 x 8i64 into 24i64 (and store)
7325 {3, MVT::v16i64, 24}, // interleave 3 x 16i64 into 48i64 (and store)
7326
7327 {4, MVT::v2i8, 4}, // interleave 4 x 2i8 into 8i8 (and store)
7328 {4, MVT::v4i8, 4}, // interleave 4 x 4i8 into 16i8 (and store)
7329 {4, MVT::v8i8, 4}, // interleave 4 x 8i8 into 32i8 (and store)
7330 {4, MVT::v16i8, 8}, // interleave 4 x 16i8 into 64i8 (and store)
7331 {4, MVT::v32i8, 12}, // interleave 4 x 32i8 into 128i8 (and store)
7332
7333 {4, MVT::v2i16, 2}, // interleave 4 x 2i16 into 8i16 (and store)
7334 {4, MVT::v4i16, 6}, // interleave 4 x 4i16 into 16i16 (and store)
7335 {4, MVT::v8i16, 10}, // interleave 4 x 8i16 into 32i16 (and store)
7336 {4, MVT::v16i16, 32}, // interleave 4 x 16i16 into 64i16 (and store)
7337 {4, MVT::v32i16, 64}, // interleave 4 x 32i16 into 128i16 (and store)
7338
7339 {4, MVT::v2i32, 5}, // interleave 4 x 2i32 into 8i32 (and store)
7340 {4, MVT::v4i32, 6}, // interleave 4 x 4i32 into 16i32 (and store)
7341 {4, MVT::v8i32, 16}, // interleave 4 x 8i32 into 32i32 (and store)
7342 {4, MVT::v16i32, 32}, // interleave 4 x 16i32 into 64i32 (and store)
7343 {4, MVT::v32i32, 64}, // interleave 4 x 32i32 into 128i32 (and store)
7344
7345 {4, MVT::v2i64, 6}, // interleave 4 x 2i64 into 8i64 (and store)
7346 {4, MVT::v4i64, 8}, // interleave 4 x 4i64 into 16i64 (and store)
7347 {4, MVT::v8i64, 20}, // interleave 4 x 8i64 into 32i64 (and store)
7348 {4, MVT::v16i64, 40}, // interleave 4 x 16i64 into 64i64 (and store)
7349
7350 {6, MVT::v2i8, 7}, // interleave 6 x 2i8 into 12i8 (and store)
7351 {6, MVT::v4i8, 9}, // interleave 6 x 4i8 into 24i8 (and store)
7352 {6, MVT::v8i8, 16}, // interleave 6 x 8i8 into 48i8 (and store)
7353 {6, MVT::v16i8, 27}, // interleave 6 x 16i8 into 96i8 (and store)
7354 {6, MVT::v32i8, 90}, // interleave 6 x 32i8 into 192i8 (and store)
7355
7356 {6, MVT::v2i16, 10}, // interleave 6 x 2i16 into 12i16 (and store)
7357 {6, MVT::v4i16, 15}, // interleave 6 x 4i16 into 24i16 (and store)
7358 {6, MVT::v8i16, 21}, // interleave 6 x 8i16 into 48i16 (and store)
7359 {6, MVT::v16i16, 58}, // interleave 6 x 16i16 into 96i16 (and store)
7360 {6, MVT::v32i16, 90}, // interleave 6 x 32i16 into 192i16 (and store)
7361
7362 {6, MVT::v2i32, 9}, // interleave 6 x 2i32 into 12i32 (and store)
7363 {6, MVT::v4i32, 12}, // interleave 6 x 4i32 into 24i32 (and store)
7364 {6, MVT::v8i32, 33}, // interleave 6 x 8i32 into 48i32 (and store)
7365 {6, MVT::v16i32, 66}, // interleave 6 x 16i32 into 96i32 (and store)
7366
7367 {6, MVT::v2i64, 8}, // interleave 6 x 2i64 into 12i64 (and store)
7368 {6, MVT::v4i64, 15}, // interleave 6 x 4i64 into 24i64 (and store)
7369 {6, MVT::v8i64, 30}, // interleave 6 x 8i64 into 48i64 (and store)
7370 };
7371
7372 static const CostTblEntry SSE2InterleavedStoreTbl[] = {
7373 {2, MVT::v2i8, 1}, // interleave 2 x 2i8 into 4i8 (and store)
7374 {2, MVT::v4i8, 1}, // interleave 2 x 4i8 into 8i8 (and store)
7375 {2, MVT::v8i8, 1}, // interleave 2 x 8i8 into 16i8 (and store)
7376
7377 {2, MVT::v2i16, 1}, // interleave 2 x 2i16 into 4i16 (and store)
7378 {2, MVT::v4i16, 1}, // interleave 2 x 4i16 into 8i16 (and store)
7379
7380 {2, MVT::v2i32, 1}, // interleave 2 x 2i32 into 4i32 (and store)
7381 };
7382
7383 if (Opcode == Instruction::Load) {
7384 auto GetDiscountedCost = [Factor, NumMembers = Indices.size(),
7385 MemOpCosts](const CostTblEntry *Entry) {
7386 // NOTE: this is just an approximation!
7387 // It can over/under -estimate the cost!
7388 return MemOpCosts + divideCeil(NumMembers * Entry->Cost, Factor);
7389 };
7390
7391 if (ST->hasAVX2())
7392 if (const auto *Entry = CostTableLookup(AVX2InterleavedLoadTbl, Factor,
7393 ETy.getSimpleVT()))
7394 return GetDiscountedCost(Entry);
7395
7396 if (ST->hasSSSE3())
7397 if (const auto *Entry = CostTableLookup(SSSE3InterleavedLoadTbl, Factor,
7398 ETy.getSimpleVT()))
7399 return GetDiscountedCost(Entry);
7400
7401 if (ST->hasSSE2())
7402 if (const auto *Entry = CostTableLookup(SSE2InterleavedLoadTbl, Factor,
7403 ETy.getSimpleVT()))
7404 return GetDiscountedCost(Entry);
7405 } else {
7406 assert(Opcode == Instruction::Store &&
7407 "Expected Store Instruction at this point");
7408 assert((!Indices.size() || Indices.size() == Factor) &&
7409 "Interleaved store only supports fully-interleaved groups.");
7410 if (ST->hasAVX2())
7411 if (const auto *Entry = CostTableLookup(AVX2InterleavedStoreTbl, Factor,
7412 ETy.getSimpleVT()))
7413 return MemOpCosts + Entry->Cost;
7414
7415 if (ST->hasSSE2())
7416 if (const auto *Entry = CostTableLookup(SSE2InterleavedStoreTbl, Factor,
7417 ETy.getSimpleVT()))
7418 return MemOpCosts + Entry->Cost;
7419 }
7420
7421 return BaseT::getInterleavedMemoryOpCost(Opcode, VecTy, Factor, Indices,
7422 Alignment, AddressSpace, CostKind,
7423 UseMaskForCond, UseMaskForGaps);
7424}
7425
7427 StackOffset BaseOffset,
7428 bool HasBaseReg, int64_t Scale,
7429 unsigned AddrSpace) const {
7430 // Scaling factors are not free at all.
7431 // An indexed folded instruction, i.e., inst (reg1, reg2, scale),
7432 // will take 2 allocations in the out of order engine instead of 1
7433 // for plain addressing mode, i.e. inst (reg1).
7434 // E.g.,
7435 // vaddps (%rsi,%rdx), %ymm0, %ymm1
7436 // Requires two allocations (one for the load, one for the computation)
7437 // whereas:
7438 // vaddps (%rsi), %ymm0, %ymm1
7439 // Requires just 1 allocation, i.e., freeing allocations for other operations
7440 // and having less micro operations to execute.
7441 //
7442 // For some X86 architectures, this is even worse because for instance for
7443 // stores, the complex addressing mode forces the instruction to use the
7444 // "load" ports instead of the dedicated "store" port.
7445 // E.g., on Haswell:
7446 // vmovaps %ymm1, (%r8, %rdi) can use port 2 or 3.
7447 // vmovaps %ymm1, (%r8) can use port 2, 3, or 7.
7449 AM.BaseGV = BaseGV;
7450 AM.BaseOffs = BaseOffset.getFixed();
7451 AM.HasBaseReg = HasBaseReg;
7452 AM.Scale = Scale;
7453 AM.ScalableOffset = BaseOffset.getScalable();
7454 if (getTLI()->isLegalAddressingMode(DL, AM, Ty, AddrSpace))
7455 // Scale represents reg2 * scale, thus account for 1
7456 // as soon as we use a second register.
7457 return AM.Scale != 0;
7459}
7460
7462 // TODO: Hook MispredictPenalty of SchedMachineModel into this.
7463 return 14;
7464}
7465
7467 unsigned Bits = Ty->getScalarSizeInBits();
7468
7469 // XOP has v16i8/v8i16/v4i32/v2i64 variable vector shifts.
7470 // Splitting for v32i8/v16i16 on XOP+AVX2 targets is still preferred.
7471 if (ST->hasXOP() && (Bits == 8 || Bits == 16 || Bits == 32 || Bits == 64))
7472 return false;
7473
7474 // AVX2 has vpsllv[dq] instructions (and other shifts) that make variable
7475 // shifts just as cheap as scalar ones.
7476 if (ST->hasAVX2() && (Bits == 32 || Bits == 64))
7477 return false;
7478
7479 // AVX512BW has shifts such as vpsllvw.
7480 if (ST->hasBWI() && Bits == 16)
7481 return false;
7482
7483 // Otherwise, it's significantly cheaper to shift by a scalar amount than by a
7484 // fully general vector.
7485 return true;
7486}
7487
7488unsigned X86TTIImpl::getStoreMinimumVF(unsigned VF, Type *ScalarMemTy,
7489 Type *ScalarValTy, Align Alignment,
7490 unsigned AddrSpace) const {
7491 if (ST->hasF16C() && ScalarMemTy->isHalfTy()) {
7492 return 4;
7493 }
7494 return BaseT::getStoreMinimumVF(VF, ScalarMemTy, ScalarValTy, Alignment,
7495 AddrSpace);
7496}
7497
7499 SmallVectorImpl<Use *> &Ops) const {
7500 using namespace llvm::PatternMatch;
7501
7502 if (I->getOpcode() == Instruction::And &&
7503 (ST->hasBMI() || (I->getType()->isVectorTy() && ST->hasSSE2()))) {
7504 for (auto &Op : I->operands()) {
7505 // (and X, (not Y)) -> (andn X, Y)
7506 if (match(Op.get(), m_Not(m_Value())) && !I->getType()->isIntegerTy(8)) {
7507 Ops.push_back(&Op);
7508 return true;
7509 }
7510 // (and X, (splat (not Y))) -> (andn X, (splat Y))
7511 if (match(Op.get(),
7513 m_Value(), m_ZeroMask()))) {
7514 Use &InsertElt = cast<Instruction>(Op)->getOperandUse(0);
7515 Use &Not = cast<Instruction>(InsertElt)->getOperandUse(1);
7516 Ops.push_back(&Not);
7517 Ops.push_back(&InsertElt);
7518 Ops.push_back(&Op);
7519 return true;
7520 }
7521 }
7522 }
7523
7524 FixedVectorType *VTy = dyn_cast<FixedVectorType>(I->getType());
7525 if (!VTy)
7526 return false;
7527
7528 if (I->getOpcode() == Instruction::Mul &&
7529 VTy->getElementType()->isIntegerTy(64)) {
7530 for (auto &Op : I->operands()) {
7531 // Make sure we are not already sinking this operand
7532 if (any_of(Ops, [&](Use *U) { return U->get() == Op; }))
7533 continue;
7534
7535 // Look for PMULDQ pattern where the input is a sext_inreg from vXi32 or
7536 // the PMULUDQ pattern where the input is a zext_inreg from vXi32.
7537 if (ST->hasSSE41() &&
7538 match(Op.get(), m_AShr(m_Shl(m_Value(), m_SpecificInt(32)),
7539 m_SpecificInt(32)))) {
7540 Ops.push_back(&cast<Instruction>(Op)->getOperandUse(0));
7541 Ops.push_back(&Op);
7542 } else if (ST->hasSSE2() &&
7543 match(Op.get(),
7544 m_And(m_Value(), m_SpecificInt(UINT64_C(0xffffffff))))) {
7545 Ops.push_back(&Op);
7546 }
7547 }
7548
7549 return !Ops.empty();
7550 }
7551
7552 // A uniform shift amount in a vector shift or funnel shift may be much
7553 // cheaper than a generic variable vector shift, so make that pattern visible
7554 // to SDAG by sinking the shuffle instruction next to the shift.
7555 int ShiftAmountOpNum = -1;
7556 if (I->isShift())
7557 ShiftAmountOpNum = 1;
7558 else if (auto *II = dyn_cast<IntrinsicInst>(I)) {
7559 if (II->getIntrinsicID() == Intrinsic::fshl ||
7560 II->getIntrinsicID() == Intrinsic::fshr)
7561 ShiftAmountOpNum = 2;
7562 }
7563
7564 if (ShiftAmountOpNum == -1)
7565 return false;
7566
7567 auto *Shuf = dyn_cast<ShuffleVectorInst>(I->getOperand(ShiftAmountOpNum));
7568 if (Shuf && getSplatIndex(Shuf->getShuffleMask()) >= 0 &&
7569 isVectorShiftByScalarCheap(I->getType())) {
7570 Ops.push_back(&I->getOperandUse(ShiftAmountOpNum));
7571 return true;
7572 }
7573
7574 return false;
7575}
7576
7578 bool HasEGPR = ST->hasEGPR();
7579 const TargetMachine &TM = getTLI()->getTargetMachine();
7580
7581 for (User *U : F.users()) {
7583 if (!CB || CB->getCalledOperand() != &F)
7584 continue;
7585 Function *CallerFunc = CB->getFunction();
7586 if (TM.getSubtarget<X86Subtarget>(*CallerFunc).hasEGPR() != HasEGPR)
7587 return false;
7588 }
7589
7590 return true;
7591}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Expand Atomic instructions
This file provides a helper that implements much of the TTI interface in terms of the target-independ...
#define X(NUM, ENUM, NAME)
Definition ELF.h:856
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static cl::opt< OutputCostKind > CostKind("cost-kind", cl::desc("Target cost kind"), cl::init(OutputCostKind::RecipThroughput), cl::values(clEnumValN(OutputCostKind::RecipThroughput, "throughput", "Reciprocal throughput"), clEnumValN(OutputCostKind::Latency, "latency", "Instruction latency"), clEnumValN(OutputCostKind::CodeSize, "code-size", "Code size"), clEnumValN(OutputCostKind::SizeAndLatency, "size-latency", "Code size and latency"), clEnumValN(OutputCostKind::All, "all", "Print all cost kinds")))
Cost tables and simple lookup functions.
Hexagon Common GEP
iv users
Definition IVUsers.cpp:48
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static LVOptions Options
Definition LVOptions.cpp:25
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
uint64_t IntrinsicInst * II
#define P(N)
This file implements the SmallBitVector class.
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
This file describes how to lower LLVM code to machine code.
This pass exposes codegen information to IR-level passes.
static unsigned getBitWidth(Type *Ty, const DataLayout &DL)
Returns the bitwidth of the given scalar or pointer type.
CostTblEntryT< CostKindCosts > CostKindTblEntry
static bool isLegalMaskedLoadStore(Type *ScalarTy, const X86Subtarget *ST)
TypeConversionCostTblEntryT< CostKindCosts > TypeConversionCostKindTblEntry
This file a TargetTransformInfoImplBase conforming object specific to the X86 target machine.
Class for arbitrary precision integers.
Definition APInt.h:78
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
Definition APInt.h:235
LLVM_ABI APInt zext(unsigned width) const
Zero extend to a new width.
Definition APInt.cpp:1055
unsigned popcount() const
Count the number of bits set.
Definition APInt.h:1695
void setBit(unsigned BitPosition)
Set the given bit to 1 whose position is given as "bitPosition".
Definition APInt.h:1355
bool isAllOnes() const
Determine if all bits are set. This is true for zero-width values.
Definition APInt.h:372
static APInt getBitsSet(unsigned numBits, unsigned loBit, unsigned hiBit)
Get a value with a block of bits set.
Definition APInt.h:259
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
Definition APInt.h:381
unsigned getBitWidth() const
Return the number of bits in the APInt.
Definition APInt.h:1513
LLVM_ABI APInt sextOrTrunc(unsigned width) const
Sign extend or truncate to width.
Definition APInt.cpp:1084
APInt ashr(unsigned ShiftAmt) const
Arithmetic right-shift function.
Definition APInt.h:834
static APInt getZero(unsigned numBits)
Get the '0' value for the specified bit-width.
Definition APInt.h:201
LLVM_ABI APInt extractBits(unsigned numBits, unsigned bitPosition) const
Return an APInt with the extracted bits [bitPosition,bitPosition+numBits).
Definition APInt.cpp:483
int64_t getSExtValue() const
Get sign extended value.
Definition APInt.h:1587
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
size_t size() const
Get the array size.
Definition ArrayRef.h:141
bool empty() const
Check if the array is empty.
Definition ArrayRef.h:136
InstructionCost getInterleavedMemoryOpCost(unsigned Opcode, Type *VecTy, unsigned Factor, ArrayRef< unsigned > Indices, Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind, bool UseMaskForCond=false, bool UseMaskForGaps=false) const override
InstructionCost getArithmeticInstrCost(unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind, TTI::OperandValueInfo Opd1Info={TTI::OK_AnyValue, TTI::OP_None}, TTI::OperandValueInfo Opd2Info={TTI::OK_AnyValue, TTI::OP_None}, ArrayRef< const Value * > Args={}, const Instruction *CxtI=nullptr) const override
InstructionCost getMinMaxReductionCost(Intrinsic::ID IID, VectorType *Ty, FastMathFlags FMF, TTI::TargetCostKind CostKind) const override
InstructionCost getGEPCost(Type *PointeeType, const Value *Ptr, ArrayRef< const Value * > Operands, Type *AccessType, TTI::TargetCostKind CostKind) const override
TTI::ShuffleKind improveShuffleKindFromMask(TTI::ShuffleKind Kind, ArrayRef< int > Mask, VectorType *SrcTy, int &Index, VectorType *&SubTy) const
bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset, bool HasBaseReg, int64_t Scale, unsigned AddrSpace, Instruction *I=nullptr, int64_t ScalableOffset=0) const override
InstructionCost getShuffleCost(TTI::ShuffleKind Kind, VectorType *DstTy, VectorType *SrcTy, ArrayRef< int > Mask, TTI::TargetCostKind CostKind, int Index, VectorType *SubTp, ArrayRef< const Value * > Args={}, const Instruction *CxtI=nullptr) const override
unsigned getStoreMinimumVF(unsigned VF, Type *ScalarMemTy, Type *ScalarValTy, Align Alignment, unsigned AddrSpace) const override
InstructionCost getScalarizationOverhead(VectorType *InTy, const APInt &DemandedElts, bool Insert, bool Extract, TTI::TargetCostKind CostKind, bool ForPoisonSrc=true, ArrayRef< Value * > VL={}, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const override
InstructionCost getArithmeticReductionCost(unsigned Opcode, VectorType *Ty, std::optional< FastMathFlags > FMF, TTI::TargetCostKind CostKind) const override
InstructionCost getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy, CmpInst::Predicate VecPred, TTI::TargetCostKind CostKind, TTI::OperandValueInfo Op1Info={TTI::OK_AnyValue, TTI::OP_None}, TTI::OperandValueInfo Op2Info={TTI::OK_AnyValue, TTI::OP_None}, const Instruction *I=nullptr) const override
InstructionCost getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src, TTI::CastContextHint CCH, TTI::TargetCostKind CostKind, const Instruction *I=nullptr) const override
std::pair< InstructionCost, MVT > getTypeLegalizationCost(Type *Ty) const
InstructionCost getReplicationShuffleCost(Type *EltTy, int ReplicationFactor, int VF, const APInt &DemandedDstElts, TTI::TargetCostKind CostKind) const override
InstructionCost getVectorInstrCost(unsigned Opcode, Type *Val, TTI::TargetCostKind CostKind, unsigned Index, const Value *Op0, const Value *Op1, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const override
InstructionCost getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA, TTI::TargetCostKind CostKind) const override
InstructionCost getAddressComputationCost(Type *PtrTy, ScalarEvolution *, const SCEV *, TTI::TargetCostKind) const override
InstructionCost getMemIntrinsicInstrCost(const MemIntrinsicCostAttributes &MICA, TTI::TargetCostKind CostKind) const override
InstructionCost getMemoryOpCost(unsigned Opcode, Type *Src, Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind, TTI::OperandValueInfo OpInfo={TTI::OK_AnyValue, TTI::OP_None}, const Instruction *I=nullptr) const override
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Value * getCalledOperand() const
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition InstrTypes.h:740
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
Definition InstrTypes.h:743
@ ICMP_SLE
signed less or equal
Definition InstrTypes.h:770
@ ICMP_UGE
unsigned greater or equal
Definition InstrTypes.h:764
@ ICMP_UGT
unsigned greater than
Definition InstrTypes.h:763
@ FCMP_ONE
0 1 1 0 True if ordered and operands are unequal
Definition InstrTypes.h:748
@ FCMP_UEQ
1 0 0 1 True if unordered or equal
Definition InstrTypes.h:751
@ ICMP_ULT
unsigned less than
Definition InstrTypes.h:765
@ ICMP_NE
not equal
Definition InstrTypes.h:762
@ ICMP_SGE
signed greater or equal
Definition InstrTypes.h:768
@ ICMP_ULE
unsigned less or equal
Definition InstrTypes.h:766
@ FCMP_UNO
1 0 0 0 True if unordered: isnan(X) | isnan(Y)
Definition InstrTypes.h:750
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
constexpr bool isScalar() const
Exactly one element.
Definition TypeSize.h:320
Convenience struct for specifying and reasoning about fast-math flags.
Definition FMF.h:23
Container class for subtarget features.
Class to represent fixed width SIMD vectors.
unsigned getNumElements() const
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
Definition Type.cpp:867
static InstructionCost getInvalid(CostType Val=0)
CostType getValue() const
This function is intended to be used as sparingly as possible, since the class provides the full rang...
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
Definition Type.cpp:348
const SmallVectorImpl< Type * > & getArgTypes() const
const SmallVectorImpl< const Value * > & getArgs() const
const IntrinsicInst * getInst() const
A wrapper class for inspecting calls to intrinsic functions.
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
Machine Value Type.
bool is128BitVector() const
Return true if this is a 128-bit vector type.
uint64_t getScalarSizeInBits() const
unsigned getVectorNumElements() const
bool isVector() const
Return true if this is a vector value type.
bool isInteger() const
Return true if this is an integer or a vector integer type.
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
bool isScalarInteger() const
Return true if this is an integer, not including vectors.
static MVT getVectorVT(MVT VT, unsigned NumElements)
MVT getVectorElementType() const
MVT getScalarType() const
If this is a vector, return the element type, otherwise return this.
Information for memory intrinsic cost model.
This class represents an analyzed expression in the program.
The main scalar evolution driver.
static LLVM_ABI bool isIdentityMask(ArrayRef< int > Mask, int NumSrcElts)
Return true if this shuffle mask chooses elements from exactly one source vector without lane crossin...
This is a 'bitvector' (really, a variable-sized bit array), optimized for the case when the array is ...
bool test(unsigned Idx) const
Returns true if bit Idx is set.
size_type size() const
Returns the number of bits in this bitvector.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StackOffset holds a fixed and a scalable offset in bytes.
Definition TypeSize.h:30
static StackOffset getScalable(int64_t Scalable)
Definition TypeSize.h:40
static StackOffset getFixed(int64_t Fixed)
Definition TypeSize.h:39
virtual MVT getRegisterTypeForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const
Certain combinations of ABIs, Targets and features require that types are legal for some operations a...
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
Primary interface to the complete machine description for the target machine.
const STC & getSubtarget(const Function &F) const
This method returns a pointer to the specified type of TargetSubtargetInfo.
virtual const TargetSubtargetInfo * getSubtargetImpl(const Function &) const
Virtual method implemented by subclasses that returns a reference to that target's TargetSubtargetInf...
virtual const TargetLowering * getTargetLowering() const
virtual InstructionCost getPointersChainCost(ArrayRef< const Value * > Ptrs, const Value *Base, const TTI::PointersChainInfo &Info, Type *AccessTy, TTI::TargetCostKind CostKind) const
bool isStridedAccess(const SCEV *Ptr) const
unsigned minRequiredElementSize(const Value *Val, bool &isSigned) const
const SCEVConstant * getConstantStrideStep(ScalarEvolution *SE, const SCEV *Ptr) const
virtual bool isExpensiveToSpeculativelyExecute(const Instruction *I) const
MaskKind
Some targets only support masked load/store with a constant mask.
TargetCostKind
The kind of cost model.
@ TCK_RecipThroughput
Reciprocal throughput.
@ TCK_CodeSize
Instruction code size.
@ TCK_SizeAndLatency
The weighted sum of size and latency.
@ TCK_Latency
The latency of instruction.
static bool requiresOrderedReduction(std::optional< FastMathFlags > FMF)
A helper function to determine the type of reduction algorithm used for a given Opcode and set of Fas...
PopcntSupportKind
Flags indicating the kind of support for population count.
llvm::VectorInstrContext VectorInstrContext
@ TCC_Free
Expected to fold away in lowering.
@ TCC_Basic
The cost of a typical 'add' instruction.
ShuffleKind
The various kinds of shuffle patterns for vector queries.
@ SK_InsertSubvector
InsertSubvector. Index indicates start offset.
@ SK_Select
Selects elements from the corresponding lane of either source operand.
@ SK_PermuteSingleSrc
Shuffle elements of single source vector with any shuffle mask.
@ SK_Transpose
Transpose two vectors.
@ SK_Splice
Concatenates elements from the first input vector with elements of the second input vector.
@ SK_Broadcast
Broadcast element 0 to all other elements.
@ SK_PermuteTwoSrc
Merge elements from two source vectors into one with any shuffle mask.
@ SK_Reverse
Reverse the order of the vector.
@ SK_ExtractSubvector
ExtractSubvector Index indicates start offset.
CastContextHint
Represents a hint about the context in which a cast is used.
@ None
The cast is not used with a load/store of any kind.
CacheLevel
The possible cache levels.
static constexpr TypeSize getFixed(ScalarTy ExactSize)
Definition TypeSize.h:343
static constexpr TypeSize getScalable(ScalarTy MinimumSize)
Definition TypeSize.h:346
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
Definition Type.cpp:310
LLVM_ABI unsigned getIntegerBitWidth() const
bool isVectorTy() const
True if this is an instance of VectorType.
Definition Type.h:288
LLVM_ABI bool isScalableTy(SmallPtrSetImpl< const Type * > &Visited) const
Return true if this is a type whose size is a known multiple of vscale.
Definition Type.cpp:61
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
Definition Type.cpp:309
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
Definition Type.h:263
bool isPointerTy() const
True if this is an instance of PointerType.
Definition Type.h:282
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
Definition Type.h:155
bool isBFloatTy() const
Return true if this is 'bfloat', a 16-bit bfloat type.
Definition Type.h:147
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
Definition Type.cpp:307
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Definition Type.h:368
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
Definition Type.cpp:197
LLVM_ABI Type * getWithNewBitWidth(unsigned NewBitWidth) const
Given an integer or vector type, change the lane bitwidth to NewBitwidth, whilst keeping the old numb...
bool isHalfTy() const
Return true if this is 'half', a 16-bit IEEE fp type.
Definition Type.h:144
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
Definition Type.h:130
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
Definition Type.cpp:232
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
Definition Type.h:158
static LLVM_ABI IntegerType * getInt1Ty(LLVMContext &C)
Definition Type.cpp:306
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
Definition Type.h:186
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:257
static LLVM_ABI IntegerType * getIntNTy(LLVMContext &C, unsigned N)
Definition Type.cpp:313
static LLVM_ABI Type * getDoubleTy(LLVMContext &C)
Definition Type.cpp:287
bool isFPOrFPVectorTy() const
Return true if this is a FP type or a vector of FP.
Definition Type.h:227
Type * getContainedType(unsigned i) const
This method is used to implement the type iterator (defined at the end of the file).
Definition Type.h:397
static LLVM_ABI Type * getFloatTy(LLVMContext &C)
Definition Type.cpp:286
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:255
Base class of all SIMD vector types.
static VectorType * getExtendedElementVectorType(VectorType *VTy)
This static method is like getInteger except that the element types are twice as wide as the elements...
ElementCount getElementCount() const
Return an ElementCount instance to represent the (possibly scalable) number of elements in the vector...
static VectorType * getDoubleElementsVectorType(VectorType *VTy)
This static method returns a VectorType with twice as many elements as the input type and the same el...
Type * getElementType() const
bool useAVX512Regs() const
bool hasAVX512() const
bool hasAVX2() const
bool useFastCCForInternalCall(Function &F) const override
InstructionCost getReplicationShuffleCost(Type *EltTy, int ReplicationFactor, int VF, const APInt &DemandedDstElts, TTI::TargetCostKind CostKind) const override
bool isLegalNTLoad(Type *DataType, Align Alignment) const override
std::optional< unsigned > getCacheAssociativity(TargetTransformInfo::CacheLevel Level) const override
InstructionCost getMinMaxReductionCost(Intrinsic::ID IID, VectorType *Ty, FastMathFlags FMF, TTI::TargetCostKind CostKind) const override
Try to calculate op costs for min/max reduction operations.
bool isLegalBroadcastLoad(Type *ElementTy, ElementCount NumElements) const override
unsigned getRegisterClassForType(bool Vector, Type *Ty) const override
InstructionCost getMemIntrinsicInstrCost(const MemIntrinsicCostAttributes &MICA, TTI::TargetCostKind CostKind) const override
Get memory intrinsic cost based on arguments.
unsigned getMaxInterleaveFactor(ElementCount VF, bool HasUnorderedReductions) const override
InstructionCost getShuffleCost(TTI::ShuffleKind Kind, VectorType *DstTy, VectorType *SrcTy, ArrayRef< int > Mask, TTI::TargetCostKind CostKind, int Index, VectorType *SubTp, ArrayRef< const Value * > Args={}, const Instruction *CxtI=nullptr) const override
bool isLegalNTStore(Type *DataType, Align Alignment) const override
InstructionCost getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src, TTI::CastContextHint CCH, TTI::TargetCostKind CostKind, const Instruction *I=nullptr) const override
InstructionCost getInterleavedMemoryOpCostAVX512(unsigned Opcode, FixedVectorType *VecTy, unsigned Factor, ArrayRef< unsigned > Indices, Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind, bool UseMaskForCond=false, bool UseMaskForGaps=false) const
bool isLegalAltInstr(VectorType *VecTy, unsigned Opcode0, unsigned Opcode1, const SmallBitVector &OpcodeMask) const override
TypeSize getRegisterBitWidth(TargetTransformInfo::RegisterKind K) const override
bool isVectorShiftByScalarCheap(Type *Ty) const override
bool isLegalMaskedGather(Type *DataType, Align Alignment) const override
bool shouldExpandReduction(const IntrinsicInst *II) const override
InstructionCost getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, StackOffset BaseOffset, bool HasBaseReg, int64_t Scale, unsigned AddrSpace) const override
Return the cost of the scaling factor used in the addressing mode represented by AM for this target,...
unsigned getAtomicMemIntrinsicMaxElementSize() const override
InstructionCost getPointersChainCost(ArrayRef< const Value * > Ptrs, const Value *Base, const TTI::PointersChainInfo &Info, Type *AccessTy, TTI::TargetCostKind CostKind) const override
bool forceScalarizeMaskedGather(VectorType *VTy, Align Alignment) const override
InstructionCost getBranchMispredictPenalty() const override
bool isExpensiveToSpeculativelyExecute(const Instruction *I) const override
bool hasConditionalLoadStoreForType(Type *Ty, bool IsStore) const override
bool isLegalMaskedStore(Type *DataType, Align Alignment, unsigned AddressSpace, TTI::MaskKind MaskKind=TTI::MaskKind::VariableOrConstantMask) const override
std::optional< unsigned > getCacheSize(TargetTransformInfo::CacheLevel Level) const override
InstructionCost getArithmeticInstrCost(unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind, TTI::OperandValueInfo Op1Info={TTI::OK_AnyValue, TTI::OP_None}, TTI::OperandValueInfo Op2Info={TTI::OK_AnyValue, TTI::OP_None}, ArrayRef< const Value * > Args={}, const Instruction *CxtI=nullptr) const override
bool isLegalMaskedGatherScatter(Type *DataType, Align Alignment) const
bool isLegalMaskedLoad(Type *DataType, Align Alignment, unsigned AddressSpace, TTI::MaskKind MaskKind=TTI::MaskKind::VariableOrConstantMask) const override
bool enableInterleavedAccessVectorization() const override
unsigned getLoadStoreVecRegBitWidth(unsigned AS) const override
unsigned getNumberOfRegisters(unsigned ClassID) const override
InstructionCost getVectorInstrCost(unsigned Opcode, Type *Val, TTI::TargetCostKind CostKind, unsigned Index, const Value *Op0, const Value *Op1, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const override
bool isLegalMaskedScatter(Type *DataType, Align Alignment) const override
unsigned getStoreMinimumVF(unsigned VF, Type *ScalarMemTy, Type *ScalarValTy, Align Alignment, unsigned AddrSpace) const override
bool hasDivRemOp(Type *DataType, bool IsSigned) const override
bool isLegalMaskedCompressStore(Type *DataType, Align Alignment) const override
InstructionCost getIntImmCostIntrin(Intrinsic::ID IID, unsigned Idx, const APInt &Imm, Type *Ty, TTI::TargetCostKind CostKind) const override
bool supportsEfficientVectorElementLoadStore() const override
InstructionCost getIntImmCostInst(unsigned Opcode, unsigned Idx, const APInt &Imm, Type *Ty, TTI::TargetCostKind CostKind, Instruction *Inst=nullptr) const override
bool isLegalMaskedExpandLoad(Type *DataType, Align Alignment) const override
TTI::PopcntSupportKind getPopcntSupport(unsigned TyWidth) const override
bool isFCmpOrdCheaperThanFCmpZero(Type *Ty) const override
TTI::MemCmpExpansionOptions enableMemCmpExpansion(bool OptSize, bool IsZeroCmp) const override
InstructionCost getIntImmCost(int64_t) const
Calculate the cost of materializing a 64-bit value.
InstructionCost getMinMaxCost(Intrinsic::ID IID, Type *Ty, TTI::TargetCostKind CostKind, FastMathFlags FMF) const
InstructionCost getCFInstrCost(unsigned Opcode, TTI::TargetCostKind CostKind, const Instruction *I=nullptr) const override
InstructionCost getInterleavedMemoryOpCost(unsigned Opcode, Type *VecTy, unsigned Factor, ArrayRef< unsigned > Indices, Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind, bool UseMaskForCond=false, bool UseMaskForGaps=false) const override
bool canMacroFuseCmp() const override
bool areInlineCompatible(const Function *Caller, const Function *Callee) const override
InstructionCost getMaskedMemoryOpCost(const MemIntrinsicCostAttributes &MICA, TTI::TargetCostKind CostKind) const
bool prefersVectorizedAddressing() const override
bool areTypesABICompatible(const Function *Caller, const Function *Callee, ArrayRef< Type * > Type) const override
InstructionCost getAltInstrCost(VectorType *VecTy, unsigned Opcode0, unsigned Opcode1, const SmallBitVector &OpcodeMask, TTI::TargetCostKind CostKind) const override
bool forceScalarizeMaskedScatter(VectorType *VTy, Align Alignment) const override
InstructionCost getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA, TTI::TargetCostKind CostKind) const override
Get intrinsic cost based on arguments.
bool isProfitableToSinkOperands(Instruction *I, SmallVectorImpl< Use * > &Ops) const override
InstructionCost getScalarizationOverhead(VectorType *Ty, const APInt &DemandedElts, bool Insert, bool Extract, TTI::TargetCostKind CostKind, bool ForPoisonSrc=true, ArrayRef< Value * > VL={}, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const override
Estimate the overhead of scalarizing an instruction.
InstructionCost getArithmeticReductionCost(unsigned Opcode, VectorType *Ty, std::optional< FastMathFlags > FMF, TTI::TargetCostKind CostKind) const override
InstructionCost getGatherScatterOpCost(const MemIntrinsicCostAttributes &MICA, TTI::TargetCostKind CostKind) const
Calculate the cost of Gather / Scatter operation.
InstructionCost getMemoryOpCost(unsigned Opcode, Type *Src, Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind, TTI::OperandValueInfo OpInfo={TTI::OK_AnyValue, TTI::OP_None}, const Instruction *I=nullptr) const override
InstructionCost getAddressComputationCost(Type *PtrTy, ScalarEvolution *SE, const SCEV *Ptr, TTI::TargetCostKind CostKind) const override
InstructionCost getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy, CmpInst::Predicate VecPred, TTI::TargetCostKind CostKind, TTI::OperandValueInfo Op1Info={TTI::OK_AnyValue, TTI::OP_None}, TTI::OperandValueInfo Op2Info={TTI::OK_AnyValue, TTI::OP_None}, const Instruction *I=nullptr) const override
bool isLSRCostLess(const TargetTransformInfo::LSRCost &C1, const TargetTransformInfo::LSRCost &C2) const override
constexpr ScalarTy getFixedValue() const
Definition TypeSize.h:200
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
Definition TypeSize.h:168
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
Definition TypeSize.h:165
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
LLVM_ABI APInt ScaleBitMask(const APInt &A, unsigned NewBitWidth, bool MatchAllBits=false)
Splat/Merge neighboring bits to widen/narrow the bitmask represented by.
Definition APInt.cpp:3040
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
ISD namespace - This namespace contains an enum which represents all of the SelectionDAG node types a...
Definition ISDOpcodes.h:24
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
Definition ISDOpcodes.h:41
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
Definition ISDOpcodes.h:829
@ DELETED_NODE
DELETED_NODE - This is an illegal value that is used to catch errors.
Definition ISDOpcodes.h:45
@ BSWAP
Byte Swap and Counting operators.
Definition ISDOpcodes.h:789
@ ADD
Simple integer binary arithmetic operators.
Definition ISDOpcodes.h:264
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
Definition ISDOpcodes.h:890
@ FADD
Simple binary floating point operators.
Definition ISDOpcodes.h:417
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
Definition ISDOpcodes.h:749
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
Definition ISDOpcodes.h:280
@ CLMUL
Carry-less multiplication operations.
Definition ISDOpcodes.h:780
@ CTLZ_ZERO_POISON
Definition ISDOpcodes.h:798
@ SIGN_EXTEND
Conversion operators.
Definition ISDOpcodes.h:854
@ FNEG
Perform various unary floating-point operations inspired by libm.
@ SSUBSAT
RESULT = [US]SUBSAT(LHS, RHS) - Perform saturation subtraction on 2 integers with the same bit width ...
Definition ISDOpcodes.h:374
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
Definition ISDOpcodes.h:806
@ SADDO
RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
Definition ISDOpcodes.h:348
@ SHL
Shift and rotation operations.
Definition ISDOpcodes.h:771
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
Definition ISDOpcodes.h:578
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
Definition ISDOpcodes.h:860
@ FMINNUM
FMINNUM/FMAXNUM - Perform floating-point minimum maximum on two values, following IEEE-754 definition...
@ SMULO
Same for multiplication.
Definition ISDOpcodes.h:356
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
Definition ISDOpcodes.h:729
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
Definition ISDOpcodes.h:988
@ FMINIMUM
FMINIMUM/FMAXIMUM - NaN-propagating minimum/maximum that also treat -0.0 as less than 0....
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
Definition ISDOpcodes.h:936
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition ISDOpcodes.h:741
@ CTTZ_ZERO_POISON
Bit counting operators with a poisoned result for zero inputs.
Definition ISDOpcodes.h:797
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
Definition ISDOpcodes.h:969
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
Definition ISDOpcodes.h:866
@ SADDSAT
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
Definition ISDOpcodes.h:365
SpecificConstantMatch m_ZeroInt()
Convenience matchers for specific integer values.
BinaryOp_match< SrcTy, SpecificConstantMatch, TargetOpcode::G_XOR, true > m_Not(const SrcTy &&Src)
Matches a register not-ed by a G_XOR.
OneUse_match< SubPat > m_OneUse(const SubPat &SP)
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::AShr > m_AShr(const LHS &L, const RHS &R)
ap_match< APInt > m_APIntAllowPoison(const APInt *&Res)
Match APInt while allowing poison in splat vector constants.
specific_intval< false > m_SpecificInt(const APInt &V)
Match a specific integer value or vector with all elements equal to the value.
bool match(Val *V, const Pattern &P)
auto m_Value()
Match an arbitrary value and ignore it.
TwoOps_match< V1_t, V2_t, Instruction::ShuffleVector > m_Shuffle(const V1_t &v1, const V2_t &v2)
Matches ShuffleVectorInst independently of mask value.
OneOps_match< OpTy, Instruction::Load > m_Load(const OpTy &Op)
Matches LoadInst.
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
ThreeOps_match< Val_t, Elt_t, Idx_t, Instruction::InsertElement > m_InsertElt(const Val_t &Val, const Elt_t &Elt, const Idx_t &Idx)
Matches InsertElementInst.
This is an optimization pass for GlobalISel generic memory operations.
constexpr auto not_equal_to(T &&Arg)
Functor variant of std::not_equal_to that can be used as a UnaryPredicate in functional algorithms li...
Definition STLExtras.h:2180
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1739
const CostTblEntryT< CostType > * CostTableLookup(ArrayRef< CostTblEntryT< CostType > > Tbl, int ISD, MVT Ty)
Find in cost table.
Definition CostTable.h:36
InstructionCost Cost
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Definition MathExtras.h:166
@ Known
Known to have no common set bits.
LLVM_ABI void ComputeValueVTs(const TargetLowering &TLI, const DataLayout &DL, Type *Ty, SmallVectorImpl< EVT > &ValueVTs, SmallVectorImpl< EVT > *MemVTs=nullptr, SmallVectorImpl< TypeSize > *Offsets=nullptr, TypeSize StartingOffset=TypeSize::getZero())
ComputeValueVTs - Given an LLVM IR type, compute a sequence of EVTs that represent all the individual...
Definition Analysis.cpp:119
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
Definition STLExtras.h:2554
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
constexpr T alignDown(U Value, V Align, W Skew=0)
Returns the largest unsigned integer less than or equal to Value and is Skew mod Align.
Definition MathExtras.h:547
LLVM_ABI Value * getSplatValue(const Value *V)
Get splat value if the input is a splat vector or return nullptr.
bool isa_and_nonnull(const Y &Val)
Definition Casting.h:676
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
uint64_t PowerOf2Ceil(uint64_t A)
Returns the power of two which is greater than or equal to the given value.
Definition MathExtras.h:386
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1746
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition MathExtras.h:280
LLVM_ABI void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true, unsigned Depth=0)
Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition Alignment.h:144
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
constexpr int PoisonMaskElem
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
Definition MathExtras.h:395
DWARFExpression::Operation Op
OutputIt copy(R &&Range, OutputIt Out)
Definition STLExtras.h:1885
CostTblEntryT< uint16_t > CostTblEntry
Definition CostTable.h:31
auto count_if(R &&Range, UnaryPredicate P)
Wrapper function around std::count_if to count the number of times an element satisfying a given pred...
Definition STLExtras.h:2019
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
constexpr auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
Definition Sequence.h:341
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
Definition Alignment.h:201
LLVM_ABI void processShuffleMasks(ArrayRef< int > Mask, unsigned NumOfSrcRegs, unsigned NumOfDestRegs, unsigned NumOfUsedRegs, function_ref< void()> NoInputAction, function_ref< void(ArrayRef< int >, unsigned, unsigned)> SingleInputAction, function_ref< void(ArrayRef< int >, unsigned, unsigned, bool)> ManyInputsAction)
Splits and processes shuffle mask depending on the number of input and output registers.
const TypeConversionCostTblEntryT< CostType > * ConvertCostTableLookup(ArrayRef< TypeConversionCostTblEntryT< CostType > > Tbl, int ISD, MVT Dst, MVT Src)
Find in type conversion cost table.
Definition CostTable.h:67
LLVM_ABI int getSplatIndex(ArrayRef< int > Mask)
If all non-negative Mask elements are the same value, return that value.
#define N
std::optional< unsigned > operator[](TargetTransformInfo::TargetCostKind Kind) const
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
Cost Table Entry.
Definition CostTable.h:26
Extended Value Type.
Definition ValueTypes.h:35
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
Definition ValueTypes.h:145
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition ValueTypes.h:396
uint64_t getScalarSizeInBits() const
Definition ValueTypes.h:408
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition ValueTypes.h:339
bool isVector() const
Return true if this is a vector value type.
Definition ValueTypes.h:176
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
Definition ValueTypes.h:346
This represents an addressing mode of: BaseGV + BaseOffs + BaseReg + Scale*ScaleReg + ScalableOffset*...
unsigned Insns
TODO: Some of these could be merged.
Returns options for expansion of memcmp. IsZeroCmp is.
Describe known properties for a set of pointers.
Type Conversion Cost Table.
Definition CostTable.h:56