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?
74struct CostKindCosts {
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 *CtxI) const {
259
260 // vXi8 multiplications are always promoted to vXi16.
261 // Sub-128-bit types can be extended/packed more efficiently.
262 if (Opcode == Instruction::Mul && Ty->isVectorTy() &&
263 Ty->getPrimitiveSizeInBits() <= 64 && Ty->getScalarSizeInBits() == 8) {
264 Type *WideVecTy =
266 return getCastInstrCost(Instruction::ZExt, WideVecTy, Ty,
268 CostKind) +
269 getCastInstrCost(Instruction::Trunc, Ty, WideVecTy,
271 CostKind) +
272 getArithmeticInstrCost(Opcode, WideVecTy, CostKind, Op1Info, Op2Info);
273 }
274
275 // Legalize the type.
276 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Ty);
277
278 int ISD = TLI->InstructionOpcodeToISD(Opcode);
279 assert(ISD && "Invalid opcode");
280
281 if (ISD == ISD::MUL && Args.size() == 2 && LT.second.isVector() &&
282 (LT.second.getScalarType() == MVT::i32 ||
283 LT.second.getScalarType() == MVT::i64)) {
284 // Check if the operands can be represented as a smaller datatype.
285 bool Op1Signed = false, Op2Signed = false;
286 unsigned Op1MinSize = BaseT::minRequiredElementSize(Args[0], Op1Signed);
287 unsigned Op2MinSize = BaseT::minRequiredElementSize(Args[1], Op2Signed);
288 unsigned OpMinSize = std::max(Op1MinSize, Op2MinSize);
289 bool SignedMode = Op1Signed || Op2Signed;
290
291 // If both vXi32 are representable as i15 and at least one is constant,
292 // zero-extended, or sign-extended from vXi16 (or less pre-SSE41) then we
293 // can treat this as PMADDWD which has the same costs as a vXi16 multiply.
294 if (OpMinSize <= 15 && !ST->isPMADDWDSlow() &&
295 LT.second.getScalarType() == MVT::i32) {
296 bool Op1Constant =
297 isa<ConstantDataVector>(Args[0]) || isa<ConstantVector>(Args[0]);
298 bool Op2Constant =
299 isa<ConstantDataVector>(Args[1]) || isa<ConstantVector>(Args[1]);
300 bool Op1Sext = isa<SExtInst>(Args[0]) &&
301 (Op1MinSize == 15 || (Op1MinSize < 15 && !ST->hasSSE41()));
302 bool Op2Sext = isa<SExtInst>(Args[1]) &&
303 (Op2MinSize == 15 || (Op2MinSize < 15 && !ST->hasSSE41()));
304
305 bool IsZeroExtended = !Op1Signed || !Op2Signed;
306 bool IsConstant = Op1Constant || Op2Constant;
307 bool IsSext = Op1Sext || Op2Sext;
308 if (IsConstant || IsZeroExtended || IsSext)
309 LT.second =
310 MVT::getVectorVT(MVT::i16, 2 * LT.second.getVectorNumElements());
311 }
312
313 // Check if the vXi32 operands can be shrunk into a smaller datatype.
314 // This should match the codegen from reduceVMULWidth.
315 // TODO: Make this generic (!ST->SSE41 || ST->isPMULLDSlow()).
316 if (ST->useSLMArithCosts() && LT.second == MVT::v4i32) {
317 if (OpMinSize <= 7)
318 return LT.first * 3; // pmullw/sext
319 if (!SignedMode && OpMinSize <= 8)
320 return LT.first * 3; // pmullw/zext
321 if (OpMinSize <= 15)
322 return LT.first * 5; // pmullw/pmulhw/pshuf
323 if (!SignedMode && OpMinSize <= 16)
324 return LT.first * 5; // pmullw/pmulhw/pshuf
325 }
326
327 // If both vXi64 are representable as (unsigned) i32, then we can perform
328 // the multiple with a single PMULUDQ instruction.
329 // TODO: Add (SSE41+) PMULDQ handling for signed extensions.
330 if (!SignedMode && OpMinSize <= 32 && LT.second.getScalarType() == MVT::i64)
331 ISD = X86ISD::PMULUDQ;
332 }
333
334 // Vector multiply by pow2 will be simplified to shifts.
335 // Vector multiply by -pow2 will be simplified to shifts/negates.
336 if (ISD == ISD::MUL && Op2Info.isConstant() &&
337 (Op2Info.isPowerOf2() || Op2Info.isNegatedPowerOf2())) {
339 getArithmeticInstrCost(Instruction::Shl, Ty, CostKind,
340 Op1Info.getNoProps(), Op2Info.getNoProps());
341 if (Op2Info.isNegatedPowerOf2())
342 Cost += getArithmeticInstrCost(Instruction::Sub, Ty, CostKind);
343 return Cost;
344 }
345
346 // On X86, vector signed division by constants power-of-two are
347 // normally expanded to the sequence SRA + SRL + ADD + SRA.
348 // The OperandValue properties may not be the same as that of the previous
349 // operation; conservatively assume OP_None.
350 if ((ISD == ISD::SDIV || ISD == ISD::SREM) &&
351 Op2Info.isConstant() && Op2Info.isPowerOf2()) {
353 2 * getArithmeticInstrCost(Instruction::AShr, Ty, CostKind,
354 Op1Info.getNoProps(), Op2Info.getNoProps());
355 Cost += getArithmeticInstrCost(Instruction::LShr, Ty, CostKind,
356 Op1Info.getNoProps(), Op2Info.getNoProps());
357 Cost += getArithmeticInstrCost(Instruction::Add, Ty, CostKind,
358 Op1Info.getNoProps(), Op2Info.getNoProps());
359
360 if (ISD == ISD::SREM) {
361 // For SREM: (X % C) is the equivalent of (X - (X/C)*C)
362 Cost += getArithmeticInstrCost(Instruction::Mul, Ty, CostKind, Op1Info.getNoProps(),
363 Op2Info.getNoProps());
364 Cost += getArithmeticInstrCost(Instruction::Sub, Ty, CostKind, Op1Info.getNoProps(),
365 Op2Info.getNoProps());
366 }
367
368 return Cost;
369 }
370
371 // Vector unsigned division/remainder will be simplified to shifts/masks.
372 if ((ISD == ISD::UDIV || ISD == ISD::UREM) &&
373 Op2Info.isConstant() && Op2Info.isPowerOf2()) {
374 if (ISD == ISD::UDIV)
375 return getArithmeticInstrCost(Instruction::LShr, Ty, CostKind,
376 Op1Info.getNoProps(), Op2Info.getNoProps());
377 // UREM
378 return getArithmeticInstrCost(Instruction::And, Ty, CostKind,
379 Op1Info.getNoProps(), Op2Info.getNoProps());
380 }
381
382 // A rem paired with a div on the same operands in the same block is free:
383 // the pair costs the div alone. Power-of-two divisors are handled above.
384 if ((ISD == ISD::UREM || ISD == ISD::SREM) && CostKind != TTI::TCK_Latency &&
385 CtxI && CtxI->getOpcode() == Opcode) {
386 using namespace PatternMatch;
387 // Same use limit as SLP, bounds the walk over the operand users.
388 constexpr unsigned MaxUses = 64;
389 unsigned DivOpcode =
390 ISD == ISD::SREM ? Instruction::SDiv : Instruction::UDiv;
391 const Value *X = CtxI->getOperand(0);
392 const Value *Y = CtxI->getOperand(1);
393 // Constants have context-wide use lists, walk the variable operand.
394 const Value *V = isa<Constant>(Y) ? X : Y;
395 if (!isa<Constant>(V) && !V->hasNUsesOrMore(MaxUses) &&
396 any_of(V->users(), [&](const User *U) {
397 return match(U, m_BinOp(DivOpcode, m_Specific(X), m_Specific(Y))) &&
398 cast<Instruction>(U)->getParent() == CtxI->getParent();
399 }))
400 return TTI::TCC_Free;
401 }
402
403 // A scalar integer divide/remainder by a constant is not a hardware divide;
404 // it lowers to a magic-number multiply-high plus a few fixup ops. Cost it as
405 // that sequence rather than the generic single-instruction divide, so the
406 // vectorizers do not compare against an artificially cheap scalar lane. The
407 // power-of-two cases are handled above; negated powers of two are left to the
408 // generic handling.
409 if (!Ty->isVectorTy() && Op2Info.isConstant() && !Op2Info.isNegatedPowerOf2() &&
410 (ISD == ISD::UDIV || ISD == ISD::SDIV || ISD == ISD::UREM ||
411 ISD == ISD::SREM)) {
412 unsigned Cost = ISD == ISD::UREM || ISD == ISD::SREM ? 6 : 5;
414 Cost += 2;
415 return LT.first * Cost;
416 }
417
418 static const CostKindTblEntry GFNIUniformConstCostTable[] = {
419 { ISD::SHL, MVT::v16i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
420 { ISD::SRL, MVT::v16i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
421 { ISD::SRA, MVT::v16i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
422 { ISD::SHL, MVT::v32i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
423 { ISD::SRL, MVT::v32i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
424 { ISD::SRA, MVT::v32i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
425 { ISD::SHL, MVT::v64i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
426 { ISD::SRL, MVT::v64i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
427 { ISD::SRA, MVT::v64i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
428 };
429
430 if (Op2Info.isUniform() && Op2Info.isConstant() && ST->hasGFNI())
431 if (const auto *Entry =
432 CostTableLookup(GFNIUniformConstCostTable, ISD, LT.second))
433 if (auto KindCost = Entry->Cost[CostKind])
434 return LT.first * *KindCost;
435
436 static const CostKindTblEntry AVX512BWUniformConstCostTable[] = {
437 { ISD::SHL, MVT::v16i8, { 1, 7, 2, 3 } }, // psllw + pand.
438 { ISD::SRL, MVT::v16i8, { 1, 7, 2, 3 } }, // psrlw + pand.
439 { ISD::SRA, MVT::v16i8, { 1, 8, 4, 5 } }, // psrlw, pand, pxor, psubb.
440 { ISD::SHL, MVT::v32i8, { 1, 8, 2, 3 } }, // psllw + pand.
441 { ISD::SRL, MVT::v32i8, { 1, 8, 2, 3 } }, // psrlw + pand.
442 { ISD::SRA, MVT::v32i8, { 1, 9, 4, 5 } }, // psrlw, pand, pxor, psubb.
443 { ISD::SHL, MVT::v64i8, { 1, 8, 2, 3 } }, // psllw + pand.
444 { ISD::SRL, MVT::v64i8, { 1, 8, 2, 3 } }, // psrlw + pand.
445 { ISD::SRA, MVT::v64i8, { 1, 9, 4, 6 } }, // psrlw, pand, pxor, psubb.
446
447 { ISD::SHL, MVT::v16i16, { 1, 1, 1, 1 } }, // psllw
448 { ISD::SRL, MVT::v16i16, { 1, 1, 1, 1 } }, // psrlw
449 { ISD::SRA, MVT::v16i16, { 1, 1, 1, 1 } }, // psrlw
450 { ISD::SHL, MVT::v32i16, { 1, 1, 1, 1 } }, // psllw
451 { ISD::SRL, MVT::v32i16, { 1, 1, 1, 1 } }, // psrlw
452 { ISD::SRA, MVT::v32i16, { 1, 1, 1, 1 } }, // psrlw
453 };
454
455 if (Op2Info.isUniform() && Op2Info.isConstant() && ST->hasBWI())
456 if (const auto *Entry =
457 CostTableLookup(AVX512BWUniformConstCostTable, ISD, LT.second))
458 if (auto KindCost = Entry->Cost[CostKind])
459 return LT.first * *KindCost;
460
461 static const CostKindTblEntry AVX512DQUniformConstCostTable[] = {
462 { ISD::SDIV, MVT::v4i64, { 15 } }, // vpmullq-based MULHS sequence
463 { ISD::SREM, MVT::v4i64, { 17 } }, // vpmullq-based MULHS+mul+sub sequence
464 { ISD::SDIV, MVT::v8i64, { 15 } }, // vpmullq-based MULHS sequence
465 { ISD::SREM, MVT::v8i64, { 17 } }, // vpmullq-based MULHS+mul+sub sequence
466 // The remainder's multiply-back is a single vpmullq with DQ, just like the
467 // pmulld the vXi32 entries above rely on. Without DQ it is another
468 // vpmuludq schoolbook, so the AVX512/AVX2 tables charge more.
469 { ISD::UREM, MVT::v4i64, { 17 } }, // MULHU + vpmullq + sub sequence
470 { ISD::UREM, MVT::v8i64, { 17 } }, // MULHU + vpmullq + sub sequence
471 };
472
473 if (Op2Info.isUniform() && Op2Info.isConstant() && ST->hasDQI())
474 if (const auto *Entry =
475 CostTableLookup(AVX512DQUniformConstCostTable, ISD, LT.second))
476 if (auto KindCost = Entry->Cost[CostKind])
477 return LT.first * *KindCost;
478
479 static const CostKindTblEntry AVX512UniformConstCostTable[] = {
480 { ISD::SHL, MVT::v64i8, { 2, 12, 5, 6 } }, // psllw + pand.
481 { ISD::SRL, MVT::v64i8, { 2, 12, 5, 6 } }, // psrlw + pand.
482 { ISD::SRA, MVT::v64i8, { 3, 10, 12, 12 } }, // psrlw, pand, pxor, psubb.
483
484 { ISD::SHL, MVT::v16i16, { 2, 7, 4, 4 } }, // psllw + split.
485 { ISD::SRL, MVT::v16i16, { 2, 7, 4, 4 } }, // psrlw + split.
486 { ISD::SRA, MVT::v16i16, { 2, 7, 4, 4 } }, // psraw + split.
487
488 { ISD::SHL, MVT::v8i32, { 1, 1, 1, 1 } }, // pslld
489 { ISD::SRL, MVT::v8i32, { 1, 1, 1, 1 } }, // psrld
490 { ISD::SRA, MVT::v8i32, { 1, 1, 1, 1 } }, // psrad
491 { ISD::SHL, MVT::v16i32, { 1, 1, 1, 1 } }, // pslld
492 { ISD::SRL, MVT::v16i32, { 1, 1, 1, 1 } }, // psrld
493 { ISD::SRA, MVT::v16i32, { 1, 1, 1, 1 } }, // psrad
494
495 { ISD::SRA, MVT::v2i64, { 1, 1, 1, 1 } }, // psraq
496 { ISD::SHL, MVT::v4i64, { 1, 1, 1, 1 } }, // psllq
497 { ISD::SRL, MVT::v4i64, { 1, 1, 1, 1 } }, // psrlq
498 { ISD::SRA, MVT::v4i64, { 1, 1, 1, 1 } }, // psraq
499 { ISD::SHL, MVT::v8i64, { 1, 1, 1, 1 } }, // psllq
500 { ISD::SRL, MVT::v8i64, { 1, 1, 1, 1 } }, // psrlq
501 { ISD::SRA, MVT::v8i64, { 1, 1, 1, 1 } }, // psraq
502
503 { ISD::SDIV, MVT::v16i32, { 6 } }, // pmuludq sequence
504 { ISD::SREM, MVT::v16i32, { 8 } }, // pmuludq+mul+sub sequence
505 { ISD::UDIV, MVT::v16i32, { 5 } }, // pmuludq sequence
506 { ISD::UREM, MVT::v16i32, { 7 } }, // pmuludq+mul+sub sequence
507
508 { ISD::UDIV, MVT::v8i64, { 15 } }, // pmuludq-based MULHU sequence
509 { ISD::UREM, MVT::v8i64, { 21 } }, // pmuludq-based MULHU+mul+sub sequence
510 };
511
512 if (Op2Info.isUniform() && Op2Info.isConstant() && ST->hasAVX512())
513 if (const auto *Entry =
514 CostTableLookup(AVX512UniformConstCostTable, ISD, LT.second))
515 if (auto KindCost = Entry->Cost[CostKind])
516 return LT.first * *KindCost;
517
518 static const CostKindTblEntry AVX2UniformConstCostTable[] = {
519 { ISD::SHL, MVT::v16i8, { 1, 8, 2, 3 } }, // psllw + pand.
520 { ISD::SRL, MVT::v16i8, { 1, 8, 2, 3 } }, // psrlw + pand.
521 { ISD::SRA, MVT::v16i8, { 2, 10, 5, 6 } }, // psrlw, pand, pxor, psubb.
522 { ISD::SHL, MVT::v32i8, { 2, 8, 2, 4 } }, // psllw + pand.
523 { ISD::SRL, MVT::v32i8, { 2, 8, 2, 4 } }, // psrlw + pand.
524 { ISD::SRA, MVT::v32i8, { 3, 10, 5, 9 } }, // psrlw, pand, pxor, psubb.
525
526 { ISD::SHL, MVT::v8i16, { 1, 1, 1, 1 } }, // psllw
527 { ISD::SRL, MVT::v8i16, { 1, 1, 1, 1 } }, // psrlw
528 { ISD::SRA, MVT::v8i16, { 1, 1, 1, 1 } }, // psraw
529 { ISD::SHL, MVT::v16i16,{ 2, 2, 1, 2 } }, // psllw
530 { ISD::SRL, MVT::v16i16,{ 2, 2, 1, 2 } }, // psrlw
531 { ISD::SRA, MVT::v16i16,{ 2, 2, 1, 2 } }, // psraw
532
533 { ISD::SHL, MVT::v4i32, { 1, 1, 1, 1 } }, // pslld
534 { ISD::SRL, MVT::v4i32, { 1, 1, 1, 1 } }, // psrld
535 { ISD::SRA, MVT::v4i32, { 1, 1, 1, 1 } }, // psrad
536 { ISD::SHL, MVT::v8i32, { 2, 2, 1, 2 } }, // pslld
537 { ISD::SRL, MVT::v8i32, { 2, 2, 1, 2 } }, // psrld
538 { ISD::SRA, MVT::v8i32, { 2, 2, 1, 2 } }, // psrad
539
540 { ISD::SHL, MVT::v2i64, { 1, 1, 1, 1 } }, // psllq
541 { ISD::SRL, MVT::v2i64, { 1, 1, 1, 1 } }, // psrlq
542 { ISD::SRA, MVT::v2i64, { 2, 3, 3, 3 } }, // psrad + shuffle.
543 { ISD::SHL, MVT::v4i64, { 2, 2, 1, 2 } }, // psllq
544 { ISD::SRL, MVT::v4i64, { 2, 2, 1, 2 } }, // psrlq
545 { ISD::SRA, MVT::v4i64, { 4, 4, 3, 6 } }, // psrad + shuffle + split.
546
547 { ISD::SDIV, MVT::v8i32, { 6 } }, // pmuludq sequence
548 { ISD::SREM, MVT::v8i32, { 8 } }, // pmuludq+mul+sub sequence
549 { ISD::UDIV, MVT::v8i32, { 5 } }, // pmuludq sequence
550 { ISD::UREM, MVT::v8i32, { 7 } }, // pmuludq+mul+sub sequence
551
552 { ISD::UDIV, MVT::v4i64, { 15 } }, // pmuludq-based MULHU sequence
553 { ISD::UREM, MVT::v4i64, { 21 } }, // pmuludq-based MULHU+mul+sub sequence
554 };
555
556 if (Op2Info.isUniform() && Op2Info.isConstant() && ST->hasAVX2())
557 if (const auto *Entry =
558 CostTableLookup(AVX2UniformConstCostTable, ISD, LT.second))
559 if (auto KindCost = Entry->Cost[CostKind])
560 return LT.first * *KindCost;
561
562 static const CostKindTblEntry AVXUniformConstCostTable[] = {
563 { ISD::SHL, MVT::v16i8, { 2, 7, 2, 3 } }, // psllw + pand.
564 { ISD::SRL, MVT::v16i8, { 2, 7, 2, 3 } }, // psrlw + pand.
565 { ISD::SRA, MVT::v16i8, { 3, 9, 5, 6 } }, // psrlw, pand, pxor, psubb.
566 { ISD::SHL, MVT::v32i8, { 4, 7, 7, 8 } }, // 2*(psllw + pand) + split.
567 { ISD::SRL, MVT::v32i8, { 4, 7, 7, 8 } }, // 2*(psrlw + pand) + split.
568 { ISD::SRA, MVT::v32i8, { 7, 7, 12, 13 } }, // 2*(psrlw, pand, pxor, psubb) + split.
569
570 { ISD::SHL, MVT::v8i16, { 1, 2, 1, 1 } }, // psllw.
571 { ISD::SRL, MVT::v8i16, { 1, 2, 1, 1 } }, // psrlw.
572 { ISD::SRA, MVT::v8i16, { 1, 2, 1, 1 } }, // psraw.
573 { ISD::SHL, MVT::v16i16,{ 3, 6, 4, 5 } }, // psllw + split.
574 { ISD::SRL, MVT::v16i16,{ 3, 6, 4, 5 } }, // psrlw + split.
575 { ISD::SRA, MVT::v16i16,{ 3, 6, 4, 5 } }, // psraw + split.
576
577 { ISD::SHL, MVT::v4i32, { 1, 2, 1, 1 } }, // pslld.
578 { ISD::SRL, MVT::v4i32, { 1, 2, 1, 1 } }, // psrld.
579 { ISD::SRA, MVT::v4i32, { 1, 2, 1, 1 } }, // psrad.
580 { ISD::SHL, MVT::v8i32, { 3, 6, 4, 5 } }, // pslld + split.
581 { ISD::SRL, MVT::v8i32, { 3, 6, 4, 5 } }, // psrld + split.
582 { ISD::SRA, MVT::v8i32, { 3, 6, 4, 5 } }, // psrad + split.
583
584 { ISD::SHL, MVT::v2i64, { 1, 2, 1, 1 } }, // psllq.
585 { ISD::SRL, MVT::v2i64, { 1, 2, 1, 1 } }, // psrlq.
586 { ISD::SRA, MVT::v2i64, { 2, 3, 3, 3 } }, // psrad + shuffle.
587 { ISD::SHL, MVT::v4i64, { 3, 6, 4, 5 } }, // 2 x psllq + split.
588 { ISD::SRL, MVT::v4i64, { 3, 6, 4, 5 } }, // 2 x psllq + split.
589 { ISD::SRA, MVT::v4i64, { 5, 7, 8, 9 } }, // 2 x psrad + shuffle + split.
590
591 { ISD::SDIV, MVT::v8i32, { 14 } }, // 2*pmuludq sequence + split.
592 { ISD::SREM, MVT::v8i32, { 18 } }, // 2*pmuludq+mul+sub sequence + split.
593 { ISD::UDIV, MVT::v8i32, { 12 } }, // 2*pmuludq sequence + split.
594 { ISD::UREM, MVT::v8i32, { 16 } }, // 2*pmuludq+mul+sub sequence + split.
595 };
596
597 // XOP has faster vXi8 shifts.
598 if (Op2Info.isUniform() && Op2Info.isConstant() && ST->hasAVX() &&
599 (!ST->hasXOP() || LT.second.getScalarSizeInBits() != 8))
600 if (const auto *Entry =
601 CostTableLookup(AVXUniformConstCostTable, ISD, LT.second))
602 if (auto KindCost = Entry->Cost[CostKind])
603 return LT.first * *KindCost;
604
605 static const CostKindTblEntry SSE2UniformConstCostTable[] = {
606 { ISD::SHL, MVT::v16i8, { 1, 7, 2, 3 } }, // psllw + pand.
607 { ISD::SRL, MVT::v16i8, { 1, 7, 2, 3 } }, // psrlw + pand.
608 { ISD::SRA, MVT::v16i8, { 3, 9, 5, 6 } }, // psrlw, pand, pxor, psubb.
609
610 { ISD::SHL, MVT::v8i16, { 1, 1, 1, 1 } }, // psllw.
611 { ISD::SRL, MVT::v8i16, { 1, 1, 1, 1 } }, // psrlw.
612 { ISD::SRA, MVT::v8i16, { 1, 1, 1, 1 } }, // psraw.
613
614 { ISD::SHL, MVT::v4i32, { 1, 1, 1, 1 } }, // pslld
615 { ISD::SRL, MVT::v4i32, { 1, 1, 1, 1 } }, // psrld.
616 { ISD::SRA, MVT::v4i32, { 1, 1, 1, 1 } }, // psrad.
617
618 { ISD::SHL, MVT::v2i64, { 1, 1, 1, 1 } }, // psllq.
619 { ISD::SRL, MVT::v2i64, { 1, 1, 1, 1 } }, // psrlq.
620 { ISD::SRA, MVT::v2i64, { 3, 5, 6, 6 } }, // 2 x psrad + shuffle.
621
622 { ISD::SDIV, MVT::v4i32, { 6 } }, // pmuludq sequence
623 { ISD::SREM, MVT::v4i32, { 8 } }, // pmuludq+mul+sub sequence
624 { ISD::UDIV, MVT::v4i32, { 5 } }, // pmuludq sequence
625 { ISD::UREM, MVT::v4i32, { 7 } }, // pmuludq+mul+sub sequence
626 };
627
628 // XOP has faster vXi8 shifts.
629 if (Op2Info.isUniform() && Op2Info.isConstant() && ST->hasSSE2() &&
630 (!ST->hasXOP() || LT.second.getScalarSizeInBits() != 8))
631 if (const auto *Entry =
632 CostTableLookup(SSE2UniformConstCostTable, ISD, LT.second))
633 if (auto KindCost = Entry->Cost[CostKind])
634 return LT.first * *KindCost;
635
636 static const CostKindTblEntry AVX512BWConstCostTable[] = {
637 { ISD::SDIV, MVT::v64i8, { 14 } }, // 2*ext+2*pmulhw sequence
638 { ISD::SREM, MVT::v64i8, { 16 } }, // 2*ext+2*pmulhw+mul+sub sequence
639 { ISD::UDIV, MVT::v64i8, { 14 } }, // 2*ext+2*pmulhw sequence
640 { ISD::UREM, MVT::v64i8, { 16 } }, // 2*ext+2*pmulhw+mul+sub sequence
641
642 { ISD::SDIV, MVT::v32i16, { 6 } }, // vpmulhw sequence
643 { ISD::SREM, MVT::v32i16, { 8 } }, // vpmulhw+mul+sub sequence
644 { ISD::UDIV, MVT::v32i16, { 6 } }, // vpmulhuw sequence
645 { ISD::UREM, MVT::v32i16, { 8 } }, // vpmulhuw+mul+sub sequence
646 };
647
648 if (Op2Info.isConstant() && ST->hasBWI())
649 if (const auto *Entry =
650 CostTableLookup(AVX512BWConstCostTable, ISD, LT.second))
651 if (auto KindCost = Entry->Cost[CostKind])
652 return LT.first * *KindCost;
653
654 static const CostKindTblEntry AVX512DQConstCostTable[] = {
655 { ISD::SDIV, MVT::v4i64, { 19 } }, // vpmullq-based MULHS sequence
656 { ISD::SREM, MVT::v4i64, { 21 } }, // vpmullq-based MULHS+mul+sub sequence
657 { ISD::SDIV, MVT::v8i64, { 19 } }, // vpmullq-based MULHS sequence
658 { ISD::SREM, MVT::v8i64, { 21 } }, // vpmullq-based MULHS+mul+sub sequence
659 // The remainder's multiply-back is a single vpmullq with DQ, whereas the
660 // AVX512/AVX2 tables have to charge for another vpmuludq schoolbook.
661 { ISD::UREM, MVT::v4i64, { 24 } }, // MULHU + vpmullq + sub sequence
662 { ISD::UREM, MVT::v8i64, { 24 } }, // MULHU + vpmullq + sub sequence
663 };
664
665 if (Op2Info.isConstant() && ST->hasDQI())
666 if (const auto *Entry =
667 CostTableLookup(AVX512DQConstCostTable, ISD, LT.second))
668 if (auto KindCost = Entry->Cost[CostKind])
669 return LT.first * *KindCost;
670
671 static const CostKindTblEntry AVX512ConstCostTable[] = {
672 { ISD::SDIV, MVT::v64i8, { 28 } }, // 4*ext+4*pmulhw sequence
673 { ISD::SREM, MVT::v64i8, { 32 } }, // 4*ext+4*pmulhw+mul+sub sequence
674 { ISD::UDIV, MVT::v64i8, { 28 } }, // 4*ext+4*pmulhw sequence
675 { ISD::UREM, MVT::v64i8, { 32 } }, // 4*ext+4*pmulhw+mul+sub sequence
676
677 { ISD::SDIV, MVT::v32i16, { 12 } }, // 2*vpmulhw sequence
678 { ISD::SREM, MVT::v32i16, { 16 } }, // 2*vpmulhw+mul+sub sequence
679 { ISD::UDIV, MVT::v32i16, { 12 } }, // 2*vpmulhuw sequence
680 { ISD::UREM, MVT::v32i16, { 16 } }, // 2*vpmulhuw+mul+sub sequence
681
682 { ISD::SDIV, MVT::v16i32, { 15 } }, // vpmuldq sequence
683 { ISD::SREM, MVT::v16i32, { 17 } }, // vpmuldq+mul+sub sequence
684 { ISD::UDIV, MVT::v16i32, { 15 } }, // vpmuludq sequence
685 { ISD::UREM, MVT::v16i32, { 17 } }, // vpmuludq+mul+sub sequence
686
687 { ISD::UDIV, MVT::v8i64, { 22 } }, // vpmuludq-based MULHU sequence
688 { ISD::UREM, MVT::v8i64, { 28 } }, // vpmuludq-based MULHU+mul+sub sequence
689 };
690
691 if (Op2Info.isConstant() && ST->hasAVX512())
692 if (const auto *Entry =
693 CostTableLookup(AVX512ConstCostTable, ISD, LT.second))
694 if (auto KindCost = Entry->Cost[CostKind])
695 return LT.first * *KindCost;
696
697 static const CostKindTblEntry AVX2ConstCostTable[] = {
698 { ISD::SDIV, MVT::v32i8, { 14 } }, // 2*ext+2*pmulhw sequence
699 { ISD::SREM, MVT::v32i8, { 16 } }, // 2*ext+2*pmulhw+mul+sub sequence
700 { ISD::UDIV, MVT::v32i8, { 14 } }, // 2*ext+2*pmulhw sequence
701 { ISD::UREM, MVT::v32i8, { 16 } }, // 2*ext+2*pmulhw+mul+sub sequence
702
703 { ISD::SDIV, MVT::v16i16, { 6 } }, // vpmulhw sequence
704 { ISD::SREM, MVT::v16i16, { 8 } }, // vpmulhw+mul+sub sequence
705 { ISD::UDIV, MVT::v16i16, { 6 } }, // vpmulhuw sequence
706 { ISD::UREM, MVT::v16i16, { 8 } }, // vpmulhuw+mul+sub sequence
707
708 { ISD::SDIV, MVT::v8i32, { 15 } }, // vpmuldq sequence
709 { ISD::SREM, MVT::v8i32, { 19 } }, // vpmuldq+mul+sub sequence
710 { ISD::UDIV, MVT::v8i32, { 15 } }, // vpmuludq sequence
711 { ISD::UREM, MVT::v8i32, { 19 } }, // vpmuludq+mul+sub sequence
712
713 { ISD::UDIV, MVT::v4i64, { 22 } }, // vpmuludq-based MULHU sequence
714 { ISD::UREM, MVT::v4i64, { 28 } }, // vpmuludq-based MULHU+mul+sub sequence
715 };
716
717 if (Op2Info.isConstant() && ST->hasAVX2())
718 if (const auto *Entry = CostTableLookup(AVX2ConstCostTable, ISD, LT.second))
719 if (auto KindCost = Entry->Cost[CostKind])
720 return LT.first * *KindCost;
721
722 static const CostKindTblEntry AVXConstCostTable[] = {
723 { ISD::SDIV, MVT::v32i8, { 30 } }, // 4*ext+4*pmulhw sequence + split.
724 { ISD::SREM, MVT::v32i8, { 34 } }, // 4*ext+4*pmulhw+mul+sub sequence + split.
725 { ISD::UDIV, MVT::v32i8, { 30 } }, // 4*ext+4*pmulhw sequence + split.
726 { ISD::UREM, MVT::v32i8, { 34 } }, // 4*ext+4*pmulhw+mul+sub sequence + split.
727
728 { ISD::SDIV, MVT::v16i16, { 14 } }, // 2*pmulhw sequence + split.
729 { ISD::SREM, MVT::v16i16, { 18 } }, // 2*pmulhw+mul+sub sequence + split.
730 { ISD::UDIV, MVT::v16i16, { 14 } }, // 2*pmulhuw sequence + split.
731 { ISD::UREM, MVT::v16i16, { 18 } }, // 2*pmulhuw+mul+sub sequence + split.
732
733 { ISD::SDIV, MVT::v8i32, { 32 } }, // vpmuludq sequence
734 { ISD::SREM, MVT::v8i32, { 38 } }, // vpmuludq+mul+sub sequence
735 { ISD::UDIV, MVT::v8i32, { 32 } }, // 2*pmuludq sequence + split.
736 { ISD::UREM, MVT::v8i32, { 42 } }, // 2*pmuludq+mul+sub sequence + split.
737 };
738
739 if (Op2Info.isConstant() && ST->hasAVX())
740 if (const auto *Entry = CostTableLookup(AVXConstCostTable, ISD, LT.second))
741 if (auto KindCost = Entry->Cost[CostKind])
742 return LT.first * *KindCost;
743
744 static const CostKindTblEntry SSE41ConstCostTable[] = {
745 { ISD::SDIV, MVT::v4i32, { 15 } }, // vpmuludq sequence
746 { ISD::SREM, MVT::v4i32, { 20 } }, // vpmuludq+mul+sub sequence
747 };
748
749 if (Op2Info.isConstant() && ST->hasSSE41())
750 if (const auto *Entry =
751 CostTableLookup(SSE41ConstCostTable, ISD, LT.second))
752 if (auto KindCost = Entry->Cost[CostKind])
753 return LT.first * *KindCost;
754
755 static const CostKindTblEntry SSE2ConstCostTable[] = {
756 { ISD::SDIV, MVT::v16i8, { 14 } }, // 2*ext+2*pmulhw sequence
757 { ISD::SREM, MVT::v16i8, { 16 } }, // 2*ext+2*pmulhw+mul+sub sequence
758 { ISD::UDIV, MVT::v16i8, { 14 } }, // 2*ext+2*pmulhw sequence
759 { ISD::UREM, MVT::v16i8, { 16 } }, // 2*ext+2*pmulhw+mul+sub sequence
760
761 { ISD::SDIV, MVT::v8i16, { 6 } }, // pmulhw sequence
762 { ISD::SREM, MVT::v8i16, { 8 } }, // pmulhw+mul+sub sequence
763 { ISD::UDIV, MVT::v8i16, { 6 } }, // pmulhuw sequence
764 { ISD::UREM, MVT::v8i16, { 8 } }, // pmulhuw+mul+sub sequence
765
766 { ISD::SDIV, MVT::v4i32, { 19 } }, // pmuludq sequence
767 { ISD::SREM, MVT::v4i32, { 24 } }, // pmuludq+mul+sub sequence
768 { ISD::UDIV, MVT::v4i32, { 15 } }, // pmuludq sequence
769 { ISD::UREM, MVT::v4i32, { 20 } }, // pmuludq+mul+sub sequence
770 };
771
772 if (Op2Info.isConstant() && ST->hasSSE2())
773 if (const auto *Entry = CostTableLookup(SSE2ConstCostTable, ISD, LT.second))
774 if (auto KindCost = Entry->Cost[CostKind])
775 return LT.first * *KindCost;
776
777 // rem matches div because the divider returns the remainder for free.
778 static const CostKindTblEntry ScalarVarDivCostTable[] = {
779 { ISD::SDIV, MVT::i8, { 15, 20, 2, 4 } },
780 { ISD::UDIV, MVT::i8, { 15, 20, 2, 4 } },
781 { ISD::SREM, MVT::i8, { 15, 20, 2, 4 } },
782 { ISD::UREM, MVT::i8, { 15, 20, 2, 4 } },
783 { ISD::SDIV, MVT::i16, { 17, 20, 2, 4 } },
784 { ISD::UDIV, MVT::i16, { 17, 20, 2, 4 } },
785 { ISD::SREM, MVT::i16, { 17, 20, 2, 4 } },
786 { ISD::UREM, MVT::i16, { 17, 20, 2, 4 } },
787 { ISD::SDIV, MVT::i32, { 25, 22, 2, 4 } },
788 { ISD::UDIV, MVT::i32, { 25, 22, 2, 4 } },
789 { ISD::SREM, MVT::i32, { 25, 22, 2, 4 } },
790 { ISD::UREM, MVT::i32, { 25, 22, 2, 4 } },
791 { ISD::SDIV, MVT::i64, { 41, 24, 2, 4 } },
792 { ISD::UDIV, MVT::i64, { 41, 24, 2, 4 } },
793 { ISD::SREM, MVT::i64, { 41, 24, 2, 4 } },
794 { ISD::UREM, MVT::i64, { 41, 24, 2, 4 } },
795 };
796
797 if (!LT.second.isVector() && !Op2Info.isConstant())
798 if (const auto *Entry =
799 CostTableLookup(ScalarVarDivCostTable, ISD, LT.second))
800 if (auto KindCost = Entry->Cost[CostKind])
801 return LT.first * *KindCost;
802
803 // Variable divisors lower through a float divide. strictfp needs SAE
804 // rounding which is 512-bit only.
805 bool IsStrictFP =
806 CtxI && CtxI->getFunction()->hasFnAttribute(Attribute::StrictFP);
807 bool IsDivRem = ISD == ISD::UDIV || ISD == ISD::SDIV || ISD == ISD::UREM ||
808 ISD == ISD::SREM;
809 bool VarDivToFP = IsDivRem && !Op2Info.isConstant() &&
810 (!IsStrictFP || ST->useAVX512Regs());
811
812 // i64 needs the qq converts, which are AVX512DQ only. Two tables because the
813 // lowering picks by operand value and not by type.
814 static const CostKindTblEntry AVX512DQExactVarDivCostTable[] = {
815 { ISD::UDIV, MVT::v2i64, { 5 } }, // cvt+divpd sequence
816 { ISD::SDIV, MVT::v2i64, { 5 } },
817 { ISD::UREM, MVT::v2i64, { 5 } },
818 { ISD::SREM, MVT::v2i64, { 5 } },
819 { ISD::UDIV, MVT::v4i64, { 8 } },
820 { ISD::SDIV, MVT::v4i64, { 8 } },
821 { ISD::UREM, MVT::v4i64, { 8 } },
822 { ISD::SREM, MVT::v4i64, { 8 } },
823 { ISD::UDIV, MVT::v8i64, { 16 } },
824 { ISD::SDIV, MVT::v8i64, { 16 } },
825 { ISD::UREM, MVT::v8i64, { 16 } },
826 { ISD::SREM, MVT::v8i64, { 16 } },
827 };
828
829 static const CostKindTblEntry AVX512DQVarDivCostTable[] = {
830 { ISD::UDIV, MVT::v2i64, { 16 } },
831 { ISD::SDIV, MVT::v2i64, { 16 } },
832 { ISD::UREM, MVT::v2i64, { 16 } },
833 { ISD::SREM, MVT::v2i64, { 16 } },
834 { ISD::UDIV, MVT::v4i64, { 16 } },
835 { ISD::SDIV, MVT::v4i64, { 16 } },
836 { ISD::UREM, MVT::v4i64, { 16 } },
837 { ISD::SREM, MVT::v4i64, { 16 } },
838 { ISD::UDIV, MVT::v8i64, { 16 } },
839 { ISD::SDIV, MVT::v8i64, { 18 } },
840 { ISD::UREM, MVT::v8i64, { 16 } },
841 { ISD::SREM, MVT::v8i64, { 18 } },
842 };
843
844 // The DAG combine picks between the two sequences with these same two
845 // queries, so the cost cannot disagree with what codegen emits.
846 bool IsSignedDiv = ISD == ISD::SDIV || ISD == ISD::SREM;
847 auto OperandsFit = [&](unsigned Mantissa) {
848 if (Args.size() != 2 || !CtxI)
849 return false;
850 unsigned EltBits = LT.second.getScalarSizeInBits();
851 const DataLayout &DL = CtxI->getDataLayout();
852 auto Fits = [&](const Value *V) {
853 if (IsSignedDiv)
854 return ComputeNumSignBits(V, DL, /*AC=*/nullptr, CtxI) + Mantissa >
855 EltBits;
856 return computeKnownBits(V, DL, /*AC=*/nullptr, CtxI)
857 .countMaxActiveBits() <= Mantissa;
858 };
859 return Fits(Args[0]) && Fits(Args[1]);
860 };
861
862 // An i32 divide goes through f32 when both operands fit in 24 bits, and
863 // through f64 at twice the vector width when they do not.
864 bool ExactI32 =
865 VarDivToFP && LT.second.getScalarType() == MVT::i32 &&
867
868 if (VarDivToFP && ST->hasDQI() && ST->useAVX512Regs() &&
869 LT.second.getScalarType() == MVT::i64) {
870 bool ExactFPDiv =
872
873 // Only the reciprocal chain multiplies, so only it is vpmullq gated.
874 bool SlowMultiply =
875 !ExactFPDiv && LT.second == MVT::v2i64 && ST->isPMULLQSlow();
876
877 if (!SlowMultiply) {
879 ExactFPDiv ? AVX512DQExactVarDivCostTable : AVX512DQVarDivCostTable;
880 if (const auto *Entry = CostTableLookup(Tbl, ISD, LT.second))
881 if (auto KindCost = Entry->Cost[CostKind])
882 return LT.first * *KindCost;
883 }
884 }
885
886 static const CostKindTblEntry AVX512BWVarDivCostTable[] = {
887 { ISD::UDIV, MVT::v16i8, { 10 } }, // unpack+cvt+divps sequence
888 { ISD::SDIV, MVT::v16i8, { 10 } },
889 { ISD::UREM, MVT::v16i8, { 10 } },
890 { ISD::SREM, MVT::v16i8, { 10 } },
891 { ISD::UDIV, MVT::v32i8, { 20 } },
892 { ISD::SDIV, MVT::v32i8, { 20 } },
893 { ISD::UREM, MVT::v32i8, { 20 } },
894 { ISD::SREM, MVT::v32i8, { 20 } },
895 { ISD::UDIV, MVT::v64i8, { 40 } },
896 { ISD::SDIV, MVT::v64i8, { 40 } },
897 { ISD::UREM, MVT::v64i8, { 40 } },
898 { ISD::SREM, MVT::v64i8, { 40 } },
899 { ISD::UDIV, MVT::v8i16, { 5 } },
900 { ISD::SDIV, MVT::v8i16, { 5 } },
901 { ISD::UREM, MVT::v8i16, { 5 } },
902 { ISD::SREM, MVT::v8i16, { 5 } },
903 { ISD::UDIV, MVT::v16i16, { 10 } },
904 { ISD::SDIV, MVT::v16i16, { 10 } },
905 { ISD::UREM, MVT::v16i16, { 10 } },
906 { ISD::SREM, MVT::v16i16, { 10 } },
907 { ISD::UDIV, MVT::v32i16, { 20 } },
908 { ISD::SDIV, MVT::v32i16, { 20 } },
909 { ISD::UREM, MVT::v32i16, { 20 } },
910 { ISD::SREM, MVT::v32i16, { 20 } },
911 { ISD::UDIV, MVT::v4i32, { 8 } }, // cvt+divpd sequence
912 { ISD::SDIV, MVT::v4i32, { 8 } },
913 { ISD::UREM, MVT::v4i32, { 8 } },
914 { ISD::SREM, MVT::v4i32, { 8 } },
915 { ISD::UDIV, MVT::v8i32, { 16 } },
916 { ISD::SDIV, MVT::v8i32, { 16 } },
917 { ISD::UREM, MVT::v8i32, { 16 } },
918 { ISD::SREM, MVT::v8i32, { 16 } },
919 { ISD::UDIV, MVT::v16i32, { 32 } },
920 { ISD::SDIV, MVT::v16i32, { 32 } },
921 { ISD::UREM, MVT::v16i32, { 32 } },
922 { ISD::SREM, MVT::v16i32, { 32 } },
923 };
924
925 static const CostKindTblEntry AVX512BWExactVarDivCostTable[] = {
926 { ISD::UDIV, MVT::v4i32, { 3 } }, // cvt+divps sequence
927 { ISD::SDIV, MVT::v4i32, { 3 } },
928 { ISD::UREM, MVT::v4i32, { 3 } },
929 { ISD::SREM, MVT::v4i32, { 3 } },
930 { ISD::UDIV, MVT::v8i32, { 5 } },
931 { ISD::SDIV, MVT::v8i32, { 5 } },
932 { ISD::UREM, MVT::v8i32, { 5 } },
933 { ISD::SREM, MVT::v8i32, { 5 } },
934 { ISD::UDIV, MVT::v16i32, { 10 } },
935 { ISD::SDIV, MVT::v16i32, { 10 } },
936 { ISD::UREM, MVT::v16i32, { 10 } },
937 { ISD::SREM, MVT::v16i32, { 10 } },
938 };
939
940 if (VarDivToFP && ST->hasBWI()) {
941 ArrayRef<CostKindTblEntry> Tbl = AVX512BWVarDivCostTable;
942 if (ExactI32)
943 Tbl = AVX512BWExactVarDivCostTable;
944 if (const auto *Entry = CostTableLookup(Tbl, ISD, LT.second))
945 if (auto KindCost = Entry->Cost[CostKind])
946 return LT.first * *KindCost;
947 }
948
949 static const CostKindTblEntry AVX512VarDivCostTable[] = {
950 { ISD::UDIV, MVT::v16i8, { 14 } }, // unpack+cvt+divps sequence
951 { ISD::SDIV, MVT::v16i8, { 14 } },
952 { ISD::UREM, MVT::v16i8, { 14 } },
953 { ISD::SREM, MVT::v16i8, { 14 } },
954 { ISD::UDIV, MVT::v32i8, { 28 } },
955 { ISD::SDIV, MVT::v32i8, { 28 } },
956 { ISD::UREM, MVT::v32i8, { 28 } },
957 { ISD::SREM, MVT::v32i8, { 28 } },
958 { ISD::UDIV, MVT::v64i8, { 56 } },
959 { ISD::SDIV, MVT::v64i8, { 56 } },
960 { ISD::UREM, MVT::v64i8, { 56 } },
961 { ISD::SREM, MVT::v64i8, { 56 } },
962 { ISD::UDIV, MVT::v8i16, { 14 } },
963 { ISD::SDIV, MVT::v8i16, { 14 } },
964 { ISD::UREM, MVT::v8i16, { 14 } },
965 { ISD::SREM, MVT::v8i16, { 14 } },
966 { ISD::UDIV, MVT::v16i16, { 14 } },
967 { ISD::SDIV, MVT::v16i16, { 14 } },
968 { ISD::UREM, MVT::v16i16, { 14 } },
969 { ISD::SREM, MVT::v16i16, { 14 } },
970 { ISD::UDIV, MVT::v32i16, { 28 } },
971 { ISD::SDIV, MVT::v32i16, { 28 } },
972 { ISD::UREM, MVT::v32i16, { 28 } },
973 { ISD::SREM, MVT::v32i16, { 28 } },
974 { ISD::UDIV, MVT::v4i32, { 28 } }, // cvt+divpd sequence
975 { ISD::SDIV, MVT::v4i32, { 28 } },
976 { ISD::UREM, MVT::v4i32, { 28 } },
977 { ISD::SREM, MVT::v4i32, { 28 } },
978 { ISD::UDIV, MVT::v8i32, { 28 } },
979 { ISD::SDIV, MVT::v8i32, { 28 } },
980 { ISD::UREM, MVT::v8i32, { 28 } },
981 { ISD::SREM, MVT::v8i32, { 28 } },
982 { ISD::UDIV, MVT::v16i32, { 56 } },
983 { ISD::SDIV, MVT::v16i32, { 56 } },
984 { ISD::UREM, MVT::v16i32, { 56 } },
985 { ISD::SREM, MVT::v16i32, { 56 } },
986 };
987
988 static const CostKindTblEntry AVX512ExactVarDivCostTable[] = {
989 { ISD::UDIV, MVT::v4i32, { 7 } }, // cvt+divps sequence
990 { ISD::SDIV, MVT::v4i32, { 7 } },
991 { ISD::UREM, MVT::v4i32, { 7 } },
992 { ISD::SREM, MVT::v4i32, { 7 } },
993 { ISD::UDIV, MVT::v8i32, { 14 } },
994 { ISD::SDIV, MVT::v8i32, { 14 } },
995 { ISD::UREM, MVT::v8i32, { 14 } },
996 { ISD::SREM, MVT::v8i32, { 14 } },
997 { ISD::UDIV, MVT::v16i32, { 14 } },
998 { ISD::SDIV, MVT::v16i32, { 14 } },
999 { ISD::UREM, MVT::v16i32, { 14 } },
1000 { ISD::SREM, MVT::v16i32, { 14 } },
1001 };
1002
1003 if (VarDivToFP && ST->hasAVX512()) {
1004 ArrayRef<CostKindTblEntry> Tbl = AVX512VarDivCostTable;
1005 if (ExactI32)
1006 Tbl = AVX512ExactVarDivCostTable;
1007 if (const auto *Entry = CostTableLookup(Tbl, ISD, LT.second))
1008 if (auto KindCost = Entry->Cost[CostKind])
1009 return LT.first * *KindCost;
1010 }
1011
1012 static const CostKindTblEntry AVX2VarDivCostTable[] = {
1013 { ISD::UDIV, MVT::v16i8, { 28 } }, // unpack+cvt+divps sequence
1014 { ISD::SDIV, MVT::v16i8, { 28 } },
1015 { ISD::UREM, MVT::v16i8, { 28 } },
1016 { ISD::SREM, MVT::v16i8, { 28 } },
1017 { ISD::UDIV, MVT::v32i8, { 56 } },
1018 { ISD::SDIV, MVT::v32i8, { 56 } },
1019 { ISD::UREM, MVT::v32i8, { 56 } },
1020 { ISD::SREM, MVT::v32i8, { 56 } },
1021 { ISD::UDIV, MVT::v8i16, { 14 } },
1022 { ISD::SDIV, MVT::v8i16, { 14 } },
1023 { ISD::UREM, MVT::v8i16, { 14 } },
1024 { ISD::SREM, MVT::v8i16, { 14 } },
1025 { ISD::UDIV, MVT::v16i16, { 28 } },
1026 { ISD::SDIV, MVT::v16i16, { 28 } },
1027 { ISD::UREM, MVT::v16i16, { 28 } },
1028 { ISD::SREM, MVT::v16i16, { 28 } },
1029 { ISD::UDIV, MVT::v4i32, { 28 } }, // cvt+divpd sequence
1030 { ISD::SDIV, MVT::v4i32, { 28 } },
1031 { ISD::UREM, MVT::v4i32, { 28 } },
1032 { ISD::SREM, MVT::v4i32, { 28 } },
1033 { ISD::UDIV, MVT::v8i32, { 56 } },
1034 { ISD::SDIV, MVT::v8i32, { 56 } },
1035 { ISD::UREM, MVT::v8i32, { 56 } },
1036 { ISD::SREM, MVT::v8i32, { 56 } },
1037 };
1038
1039 static const CostKindTblEntry AVX2ExactVarDivCostTable[] = {
1040 { ISD::UDIV, MVT::v4i32, { 9 } }, // cvt+divps sequence
1041 { ISD::SDIV, MVT::v4i32, { 8 } },
1042 { ISD::UREM, MVT::v4i32, { 9 } },
1043 { ISD::SREM, MVT::v4i32, { 8 } },
1044 { ISD::UDIV, MVT::v8i32, { 14 } },
1045 { ISD::SDIV, MVT::v8i32, { 14 } },
1046 { ISD::UREM, MVT::v8i32, { 14 } },
1047 { ISD::SREM, MVT::v8i32, { 14 } },
1048 };
1049
1050 if (VarDivToFP && ST->hasAVX2()) {
1051 ArrayRef<CostKindTblEntry> Tbl = AVX2VarDivCostTable;
1052 if (ExactI32)
1053 Tbl = AVX2ExactVarDivCostTable;
1054 if (const auto *Entry = CostTableLookup(Tbl, ISD, LT.second))
1055 if (auto KindCost = Entry->Cost[CostKind])
1056 return LT.first * *KindCost;
1057 }
1058
1059 // No unsigned i32 entries below AVX2, where the u32 to f64 converts are
1060 // emulated and the fold stays off.
1061 static const CostKindTblEntry AVX1VarDivCostTable[] = {
1062 { ISD::UDIV, MVT::v16i8, { 56 } }, // unpack+cvt+divps sequence
1063 { ISD::SDIV, MVT::v16i8, { 56 } },
1064 { ISD::UREM, MVT::v16i8, { 56 } },
1065 { ISD::SREM, MVT::v16i8, { 56 } },
1066 { ISD::UDIV, MVT::v32i8, { 112 } },
1067 { ISD::SDIV, MVT::v32i8, { 112 } },
1068 { ISD::UREM, MVT::v32i8, { 112 } },
1069 { ISD::SREM, MVT::v32i8, { 112 } },
1070 { ISD::UDIV, MVT::v8i16, { 28 } },
1071 { ISD::SDIV, MVT::v8i16, { 28 } },
1072 { ISD::UREM, MVT::v8i16, { 28 } },
1073 { ISD::SREM, MVT::v8i16, { 28 } },
1074 { ISD::UDIV, MVT::v16i16, { 56 } },
1075 { ISD::SDIV, MVT::v16i16, { 56 } },
1076 { ISD::UREM, MVT::v16i16, { 56 } },
1077 { ISD::SREM, MVT::v16i16, { 56 } },
1078 { ISD::SDIV, MVT::v4i32, { 44 } }, // cvt+divpd sequence
1079 { ISD::SREM, MVT::v4i32, { 44 } },
1080 { ISD::SDIV, MVT::v8i32, { 88 } },
1081 { ISD::SREM, MVT::v8i32, { 88 } },
1082 };
1083
1084 static const CostKindTblEntry AVX1ExactVarDivCostTable[] = {
1085 { ISD::SDIV, MVT::v4i32, { 14 } }, // cvt+divps sequence
1086 { ISD::SREM, MVT::v4i32, { 14 } },
1087 { ISD::SDIV, MVT::v8i32, { 28 } },
1088 { ISD::SREM, MVT::v8i32, { 28 } },
1089 };
1090
1091 if (VarDivToFP && ST->hasAVX()) {
1092 ArrayRef<CostKindTblEntry> Tbl = AVX1VarDivCostTable;
1093 if (ExactI32)
1094 Tbl = AVX1ExactVarDivCostTable;
1095 if (const auto *Entry = CostTableLookup(Tbl, ISD, LT.second))
1096 if (auto KindCost = Entry->Cost[CostKind])
1097 return LT.first * *KindCost;
1098 }
1099
1100 static const CostKindTblEntry SSE2VarDivCostTable[] = {
1101 { ISD::UDIV, MVT::v16i8, { 56 } }, // unpack+cvt+divps sequence
1102 { ISD::SDIV, MVT::v16i8, { 56 } },
1103 { ISD::UREM, MVT::v16i8, { 56 } },
1104 { ISD::SREM, MVT::v16i8, { 56 } },
1105 { ISD::UDIV, MVT::v8i16, { 28 } },
1106 { ISD::SDIV, MVT::v8i16, { 28 } },
1107 { ISD::UREM, MVT::v8i16, { 28 } },
1108 { ISD::SREM, MVT::v8i16, { 28 } },
1109 { ISD::SDIV, MVT::v4i32, { 44 } }, // cvt+divpd sequence
1110 { ISD::SREM, MVT::v4i32, { 44 } },
1111 };
1112
1113 static const CostKindTblEntry SSE2ExactVarDivCostTable[] = {
1114 { ISD::SDIV, MVT::v4i32, { 14 } }, // cvt+divps sequence
1115 { ISD::SREM, MVT::v4i32, { 14 } },
1116 };
1117
1118 if (VarDivToFP && ST->hasSSE2()) {
1119 ArrayRef<CostKindTblEntry> Tbl = SSE2VarDivCostTable;
1120 if (ExactI32)
1121 Tbl = SSE2ExactVarDivCostTable;
1122 if (const auto *Entry = CostTableLookup(Tbl, ISD, LT.second))
1123 if (auto KindCost = Entry->Cost[CostKind])
1124 return LT.first * *KindCost;
1125 }
1126
1127 static const CostKindTblEntry AVX512BWUniformCostTable[] = {
1128 { ISD::SHL, MVT::v16i8, { 3, 5, 5, 7 } }, // psllw + pand.
1129 { ISD::SRL, MVT::v16i8, { 3,10, 5, 8 } }, // psrlw + pand.
1130 { ISD::SRA, MVT::v16i8, { 4,12, 8,12 } }, // psrlw, pand, pxor, psubb.
1131 { ISD::SHL, MVT::v32i8, { 4, 7, 6, 8 } }, // psllw + pand.
1132 { ISD::SRL, MVT::v32i8, { 4, 8, 7, 9 } }, // psrlw + pand.
1133 { ISD::SRA, MVT::v32i8, { 5,10,10,13 } }, // psrlw, pand, pxor, psubb.
1134 { ISD::SHL, MVT::v64i8, { 4, 7, 6, 8 } }, // psllw + pand.
1135 { ISD::SRL, MVT::v64i8, { 4, 8, 7,10 } }, // psrlw + pand.
1136 { ISD::SRA, MVT::v64i8, { 5,10,10,15 } }, // psrlw, pand, pxor, psubb.
1137
1138 { ISD::SHL, MVT::v32i16, { 2, 4, 2, 3 } }, // psllw
1139 { ISD::SRL, MVT::v32i16, { 2, 4, 2, 3 } }, // psrlw
1140 { ISD::SRA, MVT::v32i16, { 2, 4, 2, 3 } }, // psrqw
1141 };
1142
1143 if (ST->hasBWI() && Op2Info.isUniform())
1144 if (const auto *Entry =
1145 CostTableLookup(AVX512BWUniformCostTable, ISD, LT.second))
1146 if (auto KindCost = Entry->Cost[CostKind])
1147 return LT.first * *KindCost;
1148
1149 static const CostKindTblEntry AVX512UniformCostTable[] = {
1150 { ISD::SHL, MVT::v32i16, { 5,10, 5, 7 } }, // psllw + split.
1151 { ISD::SRL, MVT::v32i16, { 5,10, 5, 7 } }, // psrlw + split.
1152 { ISD::SRA, MVT::v32i16, { 5,10, 5, 7 } }, // psraw + split.
1153
1154 { ISD::SHL, MVT::v16i32, { 2, 4, 2, 3 } }, // pslld
1155 { ISD::SRL, MVT::v16i32, { 2, 4, 2, 3 } }, // psrld
1156 { ISD::SRA, MVT::v16i32, { 2, 4, 2, 3 } }, // psrad
1157
1158 { ISD::SRA, MVT::v2i64, { 1, 2, 1, 2 } }, // psraq
1159 { ISD::SHL, MVT::v4i64, { 1, 4, 1, 2 } }, // psllq
1160 { ISD::SRL, MVT::v4i64, { 1, 4, 1, 2 } }, // psrlq
1161 { ISD::SRA, MVT::v4i64, { 1, 4, 1, 2 } }, // psraq
1162 { ISD::SHL, MVT::v8i64, { 1, 4, 1, 2 } }, // psllq
1163 { ISD::SRL, MVT::v8i64, { 1, 4, 1, 2 } }, // psrlq
1164 { ISD::SRA, MVT::v8i64, { 1, 4, 1, 2 } }, // psraq
1165 };
1166
1167 if (ST->hasAVX512() && Op2Info.isUniform())
1168 if (const auto *Entry =
1169 CostTableLookup(AVX512UniformCostTable, ISD, LT.second))
1170 if (auto KindCost = Entry->Cost[CostKind])
1171 return LT.first * *KindCost;
1172
1173 static const CostKindTblEntry AVX2UniformCostTable[] = {
1174 // Uniform splats are cheaper for the following instructions.
1175 { ISD::SHL, MVT::v16i8, { 3, 5, 5, 7 } }, // psllw + pand.
1176 { ISD::SRL, MVT::v16i8, { 3, 9, 5, 8 } }, // psrlw + pand.
1177 { ISD::SRA, MVT::v16i8, { 4, 5, 9,13 } }, // psrlw, pand, pxor, psubb.
1178 { ISD::SHL, MVT::v32i8, { 4, 7, 6, 8 } }, // psllw + pand.
1179 { ISD::SRL, MVT::v32i8, { 4, 8, 7, 9 } }, // psrlw + pand.
1180 { ISD::SRA, MVT::v32i8, { 6, 9,11,16 } }, // psrlw, pand, pxor, psubb.
1181
1182 { ISD::SHL, MVT::v8i16, { 1, 2, 1, 2 } }, // psllw.
1183 { ISD::SRL, MVT::v8i16, { 1, 2, 1, 2 } }, // psrlw.
1184 { ISD::SRA, MVT::v8i16, { 1, 2, 1, 2 } }, // psraw.
1185 { ISD::SHL, MVT::v16i16, { 2, 4, 2, 3 } }, // psllw.
1186 { ISD::SRL, MVT::v16i16, { 2, 4, 2, 3 } }, // psrlw.
1187 { ISD::SRA, MVT::v16i16, { 2, 4, 2, 3 } }, // psraw.
1188
1189 { ISD::SHL, MVT::v4i32, { 1, 2, 1, 2 } }, // pslld
1190 { ISD::SRL, MVT::v4i32, { 1, 2, 1, 2 } }, // psrld
1191 { ISD::SRA, MVT::v4i32, { 1, 2, 1, 2 } }, // psrad
1192 { ISD::SHL, MVT::v8i32, { 2, 4, 2, 3 } }, // pslld
1193 { ISD::SRL, MVT::v8i32, { 2, 4, 2, 3 } }, // psrld
1194 { ISD::SRA, MVT::v8i32, { 2, 4, 2, 3 } }, // psrad
1195
1196 { ISD::SHL, MVT::v2i64, { 1, 2, 1, 2 } }, // psllq
1197 { ISD::SRL, MVT::v2i64, { 1, 2, 1, 2 } }, // psrlq
1198 { ISD::SRA, MVT::v2i64, { 2, 4, 5, 7 } }, // 2 x psrad + shuffle.
1199 { ISD::SHL, MVT::v4i64, { 2, 4, 1, 2 } }, // psllq
1200 { ISD::SRL, MVT::v4i64, { 2, 4, 1, 2 } }, // psrlq
1201 { ISD::SRA, MVT::v4i64, { 4, 6, 5, 9 } }, // 2 x psrad + shuffle.
1202 };
1203
1204 if (ST->hasAVX2() && Op2Info.isUniform())
1205 if (const auto *Entry =
1206 CostTableLookup(AVX2UniformCostTable, ISD, LT.second))
1207 if (auto KindCost = Entry->Cost[CostKind])
1208 return LT.first * *KindCost;
1209
1210 static const CostKindTblEntry AVXUniformCostTable[] = {
1211 { ISD::SHL, MVT::v16i8, { 4, 4, 6, 8 } }, // psllw + pand.
1212 { ISD::SRL, MVT::v16i8, { 4, 8, 5, 8 } }, // psrlw + pand.
1213 { ISD::SRA, MVT::v16i8, { 6, 6, 9,13 } }, // psrlw, pand, pxor, psubb.
1214 { ISD::SHL, MVT::v32i8, { 7, 8,11,14 } }, // psllw + pand + split.
1215 { ISD::SRL, MVT::v32i8, { 7, 9,10,14 } }, // psrlw + pand + split.
1216 { ISD::SRA, MVT::v32i8, { 10,11,16,21 } }, // psrlw, pand, pxor, psubb + split.
1217
1218 { ISD::SHL, MVT::v8i16, { 1, 3, 1, 2 } }, // psllw.
1219 { ISD::SRL, MVT::v8i16, { 1, 3, 1, 2 } }, // psrlw.
1220 { ISD::SRA, MVT::v8i16, { 1, 3, 1, 2 } }, // psraw.
1221 { ISD::SHL, MVT::v16i16, { 3, 7, 5, 7 } }, // psllw + split.
1222 { ISD::SRL, MVT::v16i16, { 3, 7, 5, 7 } }, // psrlw + split.
1223 { ISD::SRA, MVT::v16i16, { 3, 7, 5, 7 } }, // psraw + split.
1224
1225 { ISD::SHL, MVT::v4i32, { 1, 3, 1, 2 } }, // pslld.
1226 { ISD::SRL, MVT::v4i32, { 1, 3, 1, 2 } }, // psrld.
1227 { ISD::SRA, MVT::v4i32, { 1, 3, 1, 2 } }, // psrad.
1228 { ISD::SHL, MVT::v8i32, { 3, 7, 5, 7 } }, // pslld + split.
1229 { ISD::SRL, MVT::v8i32, { 3, 7, 5, 7 } }, // psrld + split.
1230 { ISD::SRA, MVT::v8i32, { 3, 7, 5, 7 } }, // psrad + split.
1231
1232 { ISD::SHL, MVT::v2i64, { 1, 3, 1, 2 } }, // psllq.
1233 { ISD::SRL, MVT::v2i64, { 1, 3, 1, 2 } }, // psrlq.
1234 { ISD::SRA, MVT::v2i64, { 3, 4, 5, 7 } }, // 2 x psrad + shuffle.
1235 { ISD::SHL, MVT::v4i64, { 3, 7, 4, 6 } }, // psllq + split.
1236 { ISD::SRL, MVT::v4i64, { 3, 7, 4, 6 } }, // psrlq + split.
1237 { ISD::SRA, MVT::v4i64, { 6, 7,10,13 } }, // 2 x (2 x psrad + shuffle) + split.
1238 };
1239
1240 // XOP has faster vXi8 shifts.
1241 if (ST->hasAVX() && Op2Info.isUniform() &&
1242 (!ST->hasXOP() || LT.second.getScalarSizeInBits() != 8))
1243 if (const auto *Entry =
1244 CostTableLookup(AVXUniformCostTable, ISD, LT.second))
1245 if (auto KindCost = Entry->Cost[CostKind])
1246 return LT.first * *KindCost;
1247
1248 static const CostKindTblEntry SSE2UniformCostTable[] = {
1249 // Uniform splats are cheaper for the following instructions.
1250 { ISD::SHL, MVT::v16i8, { 9, 10, 6, 9 } }, // psllw + pand.
1251 { ISD::SRL, MVT::v16i8, { 9, 13, 5, 9 } }, // psrlw + pand.
1252 { ISD::SRA, MVT::v16i8, { 11, 15, 9,13 } }, // pcmpgtb sequence.
1253
1254 { ISD::SHL, MVT::v8i16, { 2, 2, 1, 2 } }, // psllw.
1255 { ISD::SRL, MVT::v8i16, { 2, 2, 1, 2 } }, // psrlw.
1256 { ISD::SRA, MVT::v8i16, { 2, 2, 1, 2 } }, // psraw.
1257
1258 { ISD::SHL, MVT::v4i32, { 2, 2, 1, 2 } }, // pslld
1259 { ISD::SRL, MVT::v4i32, { 2, 2, 1, 2 } }, // psrld.
1260 { ISD::SRA, MVT::v4i32, { 2, 2, 1, 2 } }, // psrad.
1261
1262 { ISD::SHL, MVT::v2i64, { 2, 2, 1, 2 } }, // psllq.
1263 { ISD::SRL, MVT::v2i64, { 2, 2, 1, 2 } }, // psrlq.
1264 { ISD::SRA, MVT::v2i64, { 5, 9, 5, 7 } }, // 2*psrlq + xor + sub.
1265 };
1266
1267 if (ST->hasSSE2() && Op2Info.isUniform() &&
1268 (!ST->hasXOP() || LT.second.getScalarSizeInBits() != 8))
1269 if (const auto *Entry =
1270 CostTableLookup(SSE2UniformCostTable, ISD, LT.second))
1271 if (auto KindCost = Entry->Cost[CostKind])
1272 return LT.first * *KindCost;
1273
1274 static const CostKindTblEntry AVX512DQCostTable[] = {
1275 { ISD::MUL, MVT::v2i64, { 2, 15, 1, 3 } }, // pmullq
1276 { ISD::MUL, MVT::v4i64, { 2, 15, 1, 3 } }, // pmullq
1277 { ISD::MUL, MVT::v8i64, { 3, 15, 1, 3 } } // pmullq
1278 };
1279
1280 // Look for AVX512DQ lowering tricks for custom cases.
1281 if (ST->hasDQI())
1282 if (const auto *Entry = CostTableLookup(AVX512DQCostTable, ISD, LT.second))
1283 if (auto KindCost = Entry->Cost[CostKind])
1284 return LT.first * *KindCost;
1285
1286 static const CostKindTblEntry AVX512BWCostTable[] = {
1287 { ISD::SHL, MVT::v16i8, { 4, 8, 4, 5 } }, // extend/vpsllvw/pack sequence.
1288 { ISD::SRL, MVT::v16i8, { 4, 8, 4, 5 } }, // extend/vpsrlvw/pack sequence.
1289 { ISD::SRA, MVT::v16i8, { 4, 8, 4, 5 } }, // extend/vpsravw/pack sequence.
1290 { ISD::SHL, MVT::v32i8, { 4, 23,11,16 } }, // extend/vpsllvw/pack sequence.
1291 { ISD::SRL, MVT::v32i8, { 4, 30,12,18 } }, // extend/vpsrlvw/pack sequence.
1292 { ISD::SRA, MVT::v32i8, { 6, 13,24,30 } }, // extend/vpsravw/pack sequence.
1293 { ISD::SHL, MVT::v64i8, { 6, 19,13,15 } }, // extend/vpsllvw/pack sequence.
1294 { ISD::SRL, MVT::v64i8, { 7, 27,15,18 } }, // extend/vpsrlvw/pack sequence.
1295 { ISD::SRA, MVT::v64i8, { 15, 15,30,30 } }, // extend/vpsravw/pack sequence.
1296
1297 { ISD::SHL, MVT::v8i16, { 1, 1, 1, 1 } }, // vpsllvw
1298 { ISD::SRL, MVT::v8i16, { 1, 1, 1, 1 } }, // vpsrlvw
1299 { ISD::SRA, MVT::v8i16, { 1, 1, 1, 1 } }, // vpsravw
1300 { ISD::SHL, MVT::v16i16, { 1, 1, 1, 1 } }, // vpsllvw
1301 { ISD::SRL, MVT::v16i16, { 1, 1, 1, 1 } }, // vpsrlvw
1302 { ISD::SRA, MVT::v16i16, { 1, 1, 1, 1 } }, // vpsravw
1303 { ISD::SHL, MVT::v32i16, { 1, 1, 1, 1 } }, // vpsllvw
1304 { ISD::SRL, MVT::v32i16, { 1, 1, 1, 1 } }, // vpsrlvw
1305 { ISD::SRA, MVT::v32i16, { 1, 1, 1, 1 } }, // vpsravw
1306
1307 { ISD::ADD, MVT::v64i8, { 1, 1, 1, 1 } }, // paddb
1308 { ISD::ADD, MVT::v32i16, { 1, 1, 1, 1 } }, // paddw
1309
1310 { ISD::ADD, MVT::v32i8, { 1, 1, 1, 1 } }, // paddb
1311 { ISD::ADD, MVT::v16i16, { 1, 1, 1, 1 } }, // paddw
1312 { ISD::ADD, MVT::v8i32, { 1, 1, 1, 1 } }, // paddd
1313 { ISD::ADD, MVT::v4i64, { 1, 1, 1, 1 } }, // paddq
1314
1315 { ISD::SUB, MVT::v64i8, { 1, 1, 1, 1 } }, // psubb
1316 { ISD::SUB, MVT::v32i16, { 1, 1, 1, 1 } }, // psubw
1317
1318 { ISD::MUL, MVT::v16i8, { 4, 12, 4, 5 } }, // extend/pmullw/trunc
1319 { ISD::MUL, MVT::v32i8, { 3, 10, 7,10 } }, // pmaddubsw
1320 { ISD::MUL, MVT::v64i8, { 3, 11, 7,10 } }, // pmaddubsw
1321 { ISD::MUL, MVT::v32i16, { 1, 5, 1, 1 } }, // pmullw
1322
1323 { ISD::SUB, MVT::v32i8, { 1, 1, 1, 1 } }, // psubb
1324 { ISD::SUB, MVT::v16i16, { 1, 1, 1, 1 } }, // psubw
1325 { ISD::SUB, MVT::v8i32, { 1, 1, 1, 1 } }, // psubd
1326 { ISD::SUB, MVT::v4i64, { 1, 1, 1, 1 } }, // psubq
1327 };
1328
1329 // Look for AVX512BW lowering tricks for custom cases.
1330 if (ST->hasBWI())
1331 if (const auto *Entry = CostTableLookup(AVX512BWCostTable, ISD, LT.second))
1332 if (auto KindCost = Entry->Cost[CostKind])
1333 return LT.first * *KindCost;
1334
1335 static const CostKindTblEntry AVX512CostTable[] = {
1336 { ISD::SHL, MVT::v64i8, { 15, 19,27,33 } }, // vpblendv+split sequence.
1337 { ISD::SRL, MVT::v64i8, { 15, 19,30,36 } }, // vpblendv+split sequence.
1338 { ISD::SRA, MVT::v64i8, { 37, 37,51,63 } }, // vpblendv+split sequence.
1339
1340 { ISD::SHL, MVT::v32i16, { 11, 16,11,15 } }, // 2*extend/vpsrlvd/pack sequence.
1341 { ISD::SRL, MVT::v32i16, { 11, 16,11,15 } }, // 2*extend/vpsrlvd/pack sequence.
1342 { ISD::SRA, MVT::v32i16, { 11, 16,11,15 } }, // 2*extend/vpsravd/pack sequence.
1343
1344 { ISD::SHL, MVT::v4i32, { 1, 1, 1, 1 } },
1345 { ISD::SRL, MVT::v4i32, { 1, 1, 1, 1 } },
1346 { ISD::SRA, MVT::v4i32, { 1, 1, 1, 1 } },
1347 { ISD::SHL, MVT::v8i32, { 1, 1, 1, 1 } },
1348 { ISD::SRL, MVT::v8i32, { 1, 1, 1, 1 } },
1349 { ISD::SRA, MVT::v8i32, { 1, 1, 1, 1 } },
1350 { ISD::SHL, MVT::v16i32, { 1, 1, 1, 1 } },
1351 { ISD::SRL, MVT::v16i32, { 1, 1, 1, 1 } },
1352 { ISD::SRA, MVT::v16i32, { 1, 1, 1, 1 } },
1353
1354 { ISD::SHL, MVT::v2i64, { 1, 1, 1, 1 } },
1355 { ISD::SRL, MVT::v2i64, { 1, 1, 1, 1 } },
1356 { ISD::SRA, MVT::v2i64, { 1, 1, 1, 1 } },
1357 { ISD::SHL, MVT::v4i64, { 1, 1, 1, 1 } },
1358 { ISD::SRL, MVT::v4i64, { 1, 1, 1, 1 } },
1359 { ISD::SRA, MVT::v4i64, { 1, 1, 1, 1 } },
1360 { ISD::SHL, MVT::v8i64, { 1, 1, 1, 1 } },
1361 { ISD::SRL, MVT::v8i64, { 1, 1, 1, 1 } },
1362 { ISD::SRA, MVT::v8i64, { 1, 1, 1, 1 } },
1363
1364 { ISD::ADD, MVT::v64i8, { 3, 7, 5, 5 } }, // 2*paddb + split
1365 { ISD::ADD, MVT::v32i16, { 3, 7, 5, 5 } }, // 2*paddw + split
1366
1367 { ISD::SUB, MVT::v64i8, { 3, 7, 5, 5 } }, // 2*psubb + split
1368 { ISD::SUB, MVT::v32i16, { 3, 7, 5, 5 } }, // 2*psubw + split
1369
1370 { ISD::AND, MVT::v32i8, { 1, 1, 1, 1 } },
1371 { ISD::AND, MVT::v16i16, { 1, 1, 1, 1 } },
1372 { ISD::AND, MVT::v8i32, { 1, 1, 1, 1 } },
1373 { ISD::AND, MVT::v4i64, { 1, 1, 1, 1 } },
1374
1375 { ISD::OR, MVT::v32i8, { 1, 1, 1, 1 } },
1376 { ISD::OR, MVT::v16i16, { 1, 1, 1, 1 } },
1377 { ISD::OR, MVT::v8i32, { 1, 1, 1, 1 } },
1378 { ISD::OR, MVT::v4i64, { 1, 1, 1, 1 } },
1379
1380 { ISD::XOR, MVT::v32i8, { 1, 1, 1, 1 } },
1381 { ISD::XOR, MVT::v16i16, { 1, 1, 1, 1 } },
1382 { ISD::XOR, MVT::v8i32, { 1, 1, 1, 1 } },
1383 { ISD::XOR, MVT::v4i64, { 1, 1, 1, 1 } },
1384
1385 { ISD::MUL, MVT::v16i32, { 1, 10, 1, 2 } }, // pmulld (Skylake from agner.org)
1386 { ISD::MUL, MVT::v8i32, { 1, 10, 1, 2 } }, // pmulld (Skylake from agner.org)
1387 { ISD::MUL, MVT::v4i32, { 1, 10, 1, 2 } }, // pmulld (Skylake from agner.org)
1388 { ISD::MUL, MVT::v8i64, { 6, 9, 8, 8 } }, // 3*pmuludq/3*shift/2*add
1389 { ISD::MUL, MVT::i64, { 1 } }, // Skylake from http://www.agner.org/
1390
1391 { X86ISD::PMULUDQ, MVT::v8i64, { 1, 5, 1, 1 } },
1392
1393 { ISD::FNEG, MVT::v8f64, { 1, 1, 1, 2 } }, // Skylake from http://www.agner.org/
1394 { ISD::FADD, MVT::v8f64, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1395 { ISD::FADD, MVT::v4f64, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1396 { ISD::FSUB, MVT::v8f64, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1397 { ISD::FSUB, MVT::v4f64, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1398 { ISD::FMUL, MVT::v8f64, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1399 { ISD::FMUL, MVT::v4f64, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1400 { ISD::FMUL, MVT::v2f64, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1401 { ISD::FMUL, MVT::f64, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1402
1403 { ISD::FDIV, MVT::f64, { 4, 14, 1, 1 } }, // Skylake from http://www.agner.org/
1404 { ISD::FDIV, MVT::v2f64, { 4, 14, 1, 1 } }, // Skylake from http://www.agner.org/
1405 { ISD::FDIV, MVT::v4f64, { 8, 14, 1, 1 } }, // Skylake from http://www.agner.org/
1406 { ISD::FDIV, MVT::v8f64, { 16, 23, 1, 3 } }, // Skylake from http://www.agner.org/
1407
1408 { ISD::FNEG, MVT::v16f32, { 1, 1, 1, 2 } }, // Skylake from http://www.agner.org/
1409 { ISD::FADD, MVT::v16f32, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1410 { ISD::FADD, MVT::v8f32, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1411 { ISD::FSUB, MVT::v16f32, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1412 { ISD::FSUB, MVT::v8f32, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1413 { ISD::FMUL, MVT::v16f32, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1414 { ISD::FMUL, MVT::v8f32, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1415 { ISD::FMUL, MVT::v4f32, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1416 { ISD::FMUL, MVT::f32, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1417
1418 { ISD::FDIV, MVT::f32, { 3, 11, 1, 1 } }, // Skylake from http://www.agner.org/
1419 { ISD::FDIV, MVT::v4f32, { 3, 11, 1, 1 } }, // Skylake from http://www.agner.org/
1420 { ISD::FDIV, MVT::v8f32, { 5, 11, 1, 1 } }, // Skylake from http://www.agner.org/
1421 { ISD::FDIV, MVT::v16f32, { 10, 18, 1, 3 } }, // Skylake from http://www.agner.org/
1422 };
1423
1424 if (ST->hasAVX512())
1425 if (const auto *Entry = CostTableLookup(AVX512CostTable, ISD, LT.second))
1426 if (auto KindCost = Entry->Cost[CostKind])
1427 return LT.first * *KindCost;
1428
1429 static const CostKindTblEntry AVX2ShiftCostTable[] = {
1430 // Shifts on vXi64/vXi32 on AVX2 is legal even though we declare to
1431 // customize them to detect the cases where shift amount is a scalar one.
1432 { ISD::SHL, MVT::v4i32, { 2, 3, 1, 3 } }, // vpsllvd (Haswell from agner.org)
1433 { ISD::SRL, MVT::v4i32, { 2, 3, 1, 3 } }, // vpsrlvd (Haswell from agner.org)
1434 { ISD::SRA, MVT::v4i32, { 2, 3, 1, 3 } }, // vpsravd (Haswell from agner.org)
1435 { ISD::SHL, MVT::v8i32, { 4, 4, 1, 3 } }, // vpsllvd (Haswell from agner.org)
1436 { ISD::SRL, MVT::v8i32, { 4, 4, 1, 3 } }, // vpsrlvd (Haswell from agner.org)
1437 { ISD::SRA, MVT::v8i32, { 4, 4, 1, 3 } }, // vpsravd (Haswell from agner.org)
1438 { ISD::SHL, MVT::v2i64, { 2, 3, 1, 1 } }, // vpsllvq (Haswell from agner.org)
1439 { ISD::SRL, MVT::v2i64, { 2, 3, 1, 1 } }, // vpsrlvq (Haswell from agner.org)
1440 { ISD::SHL, MVT::v4i64, { 4, 4, 1, 2 } }, // vpsllvq (Haswell from agner.org)
1441 { ISD::SRL, MVT::v4i64, { 4, 4, 1, 2 } }, // vpsrlvq (Haswell from agner.org)
1442 };
1443
1444 if (ST->hasAVX512()) {
1445 if (ISD == ISD::SHL && LT.second == MVT::v32i16 && Op2Info.isConstant())
1446 // On AVX512, a packed v32i16 shift left by a constant build_vector
1447 // is lowered into a vector multiply (vpmullw).
1448 return getArithmeticInstrCost(Instruction::Mul, Ty, CostKind,
1449 Op1Info.getNoProps(), Op2Info.getNoProps());
1450 }
1451
1452 // Look for AVX2 lowering tricks (XOP is always better at v4i32 shifts).
1453 if (ST->hasAVX2() && !(ST->hasXOP() && LT.second == MVT::v4i32)) {
1454 if (ISD == ISD::SHL && LT.second == MVT::v16i16 &&
1455 Op2Info.isConstant())
1456 // On AVX2, a packed v16i16 shift left by a constant build_vector
1457 // is lowered into a vector multiply (vpmullw).
1458 return getArithmeticInstrCost(Instruction::Mul, Ty, CostKind,
1459 Op1Info.getNoProps(), Op2Info.getNoProps());
1460
1461 if (const auto *Entry = CostTableLookup(AVX2ShiftCostTable, ISD, LT.second))
1462 if (auto KindCost = Entry->Cost[CostKind])
1463 return LT.first * *KindCost;
1464 }
1465
1466 static const CostKindTblEntry XOPShiftCostTable[] = {
1467 // 128bit shifts take 1cy, but right shifts require negation beforehand.
1468 { ISD::SHL, MVT::v16i8, { 1, 3, 1, 1 } },
1469 { ISD::SRL, MVT::v16i8, { 2, 3, 1, 1 } },
1470 { ISD::SRA, MVT::v16i8, { 2, 3, 1, 1 } },
1471 { ISD::SHL, MVT::v8i16, { 1, 3, 1, 1 } },
1472 { ISD::SRL, MVT::v8i16, { 2, 3, 1, 1 } },
1473 { ISD::SRA, MVT::v8i16, { 2, 3, 1, 1 } },
1474 { ISD::SHL, MVT::v4i32, { 1, 3, 1, 1 } },
1475 { ISD::SRL, MVT::v4i32, { 2, 3, 1, 1 } },
1476 { ISD::SRA, MVT::v4i32, { 2, 3, 1, 1 } },
1477 { ISD::SHL, MVT::v2i64, { 1, 3, 1, 1 } },
1478 { ISD::SRL, MVT::v2i64, { 2, 3, 1, 1 } },
1479 { ISD::SRA, MVT::v2i64, { 2, 3, 1, 1 } },
1480 // 256bit shifts require splitting if AVX2 didn't catch them above.
1481 { ISD::SHL, MVT::v32i8, { 4, 7, 5, 6 } },
1482 { ISD::SRL, MVT::v32i8, { 6, 7, 5, 6 } },
1483 { ISD::SRA, MVT::v32i8, { 6, 7, 5, 6 } },
1484 { ISD::SHL, MVT::v16i16, { 4, 7, 5, 6 } },
1485 { ISD::SRL, MVT::v16i16, { 6, 7, 5, 6 } },
1486 { ISD::SRA, MVT::v16i16, { 6, 7, 5, 6 } },
1487 { ISD::SHL, MVT::v8i32, { 4, 7, 5, 6 } },
1488 { ISD::SRL, MVT::v8i32, { 6, 7, 5, 6 } },
1489 { ISD::SRA, MVT::v8i32, { 6, 7, 5, 6 } },
1490 { ISD::SHL, MVT::v4i64, { 4, 7, 5, 6 } },
1491 { ISD::SRL, MVT::v4i64, { 6, 7, 5, 6 } },
1492 { ISD::SRA, MVT::v4i64, { 6, 7, 5, 6 } },
1493 };
1494
1495 // Look for XOP lowering tricks.
1496 if (ST->hasXOP()) {
1497 // If the right shift is constant then we'll fold the negation so
1498 // it's as cheap as a left shift.
1499 int ShiftISD = ISD;
1500 if ((ShiftISD == ISD::SRL || ShiftISD == ISD::SRA) && Op2Info.isConstant())
1501 ShiftISD = ISD::SHL;
1502 if (const auto *Entry =
1503 CostTableLookup(XOPShiftCostTable, ShiftISD, LT.second))
1504 if (auto KindCost = Entry->Cost[CostKind])
1505 return LT.first * *KindCost;
1506 }
1507
1508 if (ISD == ISD::SHL && !Op2Info.isUniform() && Op2Info.isConstant()) {
1509 MVT VT = LT.second;
1510 // Vector shift left by non uniform constant can be lowered
1511 // into vector multiply.
1512 if (((VT == MVT::v8i16 || VT == MVT::v4i32) && ST->hasSSE2()) ||
1513 ((VT == MVT::v16i16 || VT == MVT::v8i32) && ST->hasAVX()))
1514 ISD = ISD::MUL;
1515 }
1516
1517 static const CostKindTblEntry GLMCostTable[] = {
1518 { ISD::FDIV, MVT::f32, { 18, 19, 1, 1 } }, // divss
1519 { ISD::FDIV, MVT::v4f32, { 35, 36, 1, 1 } }, // divps
1520 { ISD::FDIV, MVT::f64, { 33, 34, 1, 1 } }, // divsd
1521 { ISD::FDIV, MVT::v2f64, { 65, 66, 1, 1 } }, // divpd
1522 };
1523
1524 if (ST->useGLMDivSqrtCosts())
1525 if (const auto *Entry = CostTableLookup(GLMCostTable, ISD, LT.second))
1526 if (auto KindCost = Entry->Cost[CostKind])
1527 return LT.first * *KindCost;
1528
1529 static const CostKindTblEntry SLMCostTable[] = {
1530 { ISD::MUL, MVT::v4i32, { 11, 11, 1, 7 } }, // pmulld
1531 { ISD::MUL, MVT::v8i16, { 2, 5, 1, 1 } }, // pmullw
1532 { ISD::FMUL, MVT::f64, { 2, 5, 1, 1 } }, // mulsd
1533 { ISD::FMUL, MVT::f32, { 1, 4, 1, 1 } }, // mulss
1534 { ISD::FMUL, MVT::v2f64, { 4, 7, 1, 1 } }, // mulpd
1535 { ISD::FMUL, MVT::v4f32, { 2, 5, 1, 1 } }, // mulps
1536 { ISD::FDIV, MVT::f32, { 17, 19, 1, 1 } }, // divss
1537 { ISD::FDIV, MVT::v4f32, { 39, 39, 1, 6 } }, // divps
1538 { ISD::FDIV, MVT::f64, { 32, 34, 1, 1 } }, // divsd
1539 { ISD::FDIV, MVT::v2f64, { 69, 69, 1, 6 } }, // divpd
1540 { ISD::FADD, MVT::v2f64, { 2, 4, 1, 1 } }, // addpd
1541 { ISD::FSUB, MVT::v2f64, { 2, 4, 1, 1 } }, // subpd
1542 // v2i64/v4i64 mul is custom lowered as a series of long:
1543 // multiplies(3), shifts(3) and adds(2)
1544 // slm muldq version throughput is 2 and addq throughput 4
1545 // thus: 3X2 (muldq throughput) + 3X1 (shift throughput) +
1546 // 3X4 (addq throughput) = 17
1547 { ISD::MUL, MVT::v2i64, { 17, 22, 9, 9 } },
1548 // slm addq\subq throughput is 4
1549 { ISD::ADD, MVT::v2i64, { 4, 2, 1, 2 } },
1550 { ISD::SUB, MVT::v2i64, { 4, 2, 1, 2 } },
1551 };
1552
1553 if (ST->useSLMArithCosts())
1554 if (const auto *Entry = CostTableLookup(SLMCostTable, ISD, LT.second))
1555 if (auto KindCost = Entry->Cost[CostKind])
1556 return LT.first * *KindCost;
1557
1558 static const CostKindTblEntry AVX2CostTable[] = {
1559 { ISD::SHL, MVT::v16i8, { 6, 21,11,16 } }, // vpblendvb sequence.
1560 { ISD::SHL, MVT::v32i8, { 6, 23,11,22 } }, // vpblendvb sequence.
1561 { ISD::SHL, MVT::v8i16, { 5, 18, 5,10 } }, // extend/vpsrlvd/pack sequence.
1562 { ISD::SHL, MVT::v16i16, { 8, 10,10,14 } }, // extend/vpsrlvd/pack sequence.
1563
1564 { ISD::SRL, MVT::v16i8, { 6, 27,12,18 } }, // vpblendvb sequence.
1565 { ISD::SRL, MVT::v32i8, { 8, 30,12,24 } }, // vpblendvb sequence.
1566 { ISD::SRL, MVT::v8i16, { 5, 11, 5,10 } }, // extend/vpsrlvd/pack sequence.
1567 { ISD::SRL, MVT::v16i16, { 8, 10,10,14 } }, // extend/vpsrlvd/pack sequence.
1568
1569 { ISD::SRA, MVT::v16i8, { 17, 17,24,30 } }, // vpblendvb sequence.
1570 { ISD::SRA, MVT::v32i8, { 18, 20,24,43 } }, // vpblendvb sequence.
1571 { ISD::SRA, MVT::v8i16, { 5, 11, 5,10 } }, // extend/vpsravd/pack sequence.
1572 { ISD::SRA, MVT::v16i16, { 8, 10,10,14 } }, // extend/vpsravd/pack sequence.
1573 { ISD::SRA, MVT::v2i64, { 4, 5, 5, 5 } }, // srl/xor/sub sequence.
1574 { ISD::SRA, MVT::v4i64, { 8, 8, 5, 9 } }, // srl/xor/sub sequence.
1575
1576 { ISD::SUB, MVT::v32i8, { 1, 1, 1, 2 } }, // psubb
1577 { ISD::ADD, MVT::v32i8, { 1, 1, 1, 2 } }, // paddb
1578 { ISD::SUB, MVT::v16i16, { 1, 1, 1, 2 } }, // psubw
1579 { ISD::ADD, MVT::v16i16, { 1, 1, 1, 2 } }, // paddw
1580 { ISD::SUB, MVT::v8i32, { 1, 1, 1, 2 } }, // psubd
1581 { ISD::ADD, MVT::v8i32, { 1, 1, 1, 2 } }, // paddd
1582 { ISD::SUB, MVT::v4i64, { 1, 1, 1, 2 } }, // psubq
1583 { ISD::ADD, MVT::v4i64, { 1, 1, 1, 2 } }, // paddq
1584
1585 { ISD::MUL, MVT::v16i8, { 5, 18, 6,12 } }, // extend/pmullw/pack
1586 { ISD::MUL, MVT::v32i8, { 4, 8, 8,16 } }, // pmaddubsw
1587 { ISD::MUL, MVT::v16i16, { 2, 5, 1, 2 } }, // pmullw
1588 { ISD::MUL, MVT::v8i32, { 4, 10, 1, 2 } }, // pmulld
1589 { ISD::MUL, MVT::v4i32, { 2, 10, 1, 2 } }, // pmulld
1590 { ISD::MUL, MVT::v4i64, { 6, 10, 8,13 } }, // 3*pmuludq/3*shift/2*add
1591 { ISD::MUL, MVT::v2i64, { 6, 10, 8, 8 } }, // 3*pmuludq/3*shift/2*add
1592
1593 { X86ISD::PMULUDQ, MVT::v4i64, { 1, 5, 1, 1 } },
1594
1595 { ISD::FNEG, MVT::v4f64, { 1, 1, 1, 2 } }, // vxorpd
1596 { ISD::FNEG, MVT::v8f32, { 1, 1, 1, 2 } }, // vxorps
1597
1598 { ISD::FADD, MVT::f64, { 1, 4, 1, 1 } }, // vaddsd
1599 { ISD::FADD, MVT::f32, { 1, 4, 1, 1 } }, // vaddss
1600 { ISD::FADD, MVT::v2f64, { 1, 4, 1, 1 } }, // vaddpd
1601 { ISD::FADD, MVT::v4f32, { 1, 4, 1, 1 } }, // vaddps
1602 { ISD::FADD, MVT::v4f64, { 1, 4, 1, 2 } }, // vaddpd
1603 { ISD::FADD, MVT::v8f32, { 1, 4, 1, 2 } }, // vaddps
1604
1605 { ISD::FSUB, MVT::f64, { 1, 4, 1, 1 } }, // vsubsd
1606 { ISD::FSUB, MVT::f32, { 1, 4, 1, 1 } }, // vsubss
1607 { ISD::FSUB, MVT::v2f64, { 1, 4, 1, 1 } }, // vsubpd
1608 { ISD::FSUB, MVT::v4f32, { 1, 4, 1, 1 } }, // vsubps
1609 { ISD::FSUB, MVT::v4f64, { 1, 4, 1, 2 } }, // vsubpd
1610 { ISD::FSUB, MVT::v8f32, { 1, 4, 1, 2 } }, // vsubps
1611
1612 { ISD::FMUL, MVT::f64, { 1, 5, 1, 1 } }, // vmulsd
1613 { ISD::FMUL, MVT::f32, { 1, 5, 1, 1 } }, // vmulss
1614 { ISD::FMUL, MVT::v2f64, { 1, 5, 1, 1 } }, // vmulpd
1615 { ISD::FMUL, MVT::v4f32, { 1, 5, 1, 1 } }, // vmulps
1616 { ISD::FMUL, MVT::v4f64, { 1, 5, 1, 2 } }, // vmulpd
1617 { ISD::FMUL, MVT::v8f32, { 1, 5, 1, 2 } }, // vmulps
1618
1619 { ISD::FDIV, MVT::f32, { 7, 13, 1, 1 } }, // vdivss
1620 { ISD::FDIV, MVT::v4f32, { 7, 13, 1, 1 } }, // vdivps
1621 { ISD::FDIV, MVT::v8f32, { 14, 21, 1, 3 } }, // vdivps
1622 { ISD::FDIV, MVT::f64, { 14, 20, 1, 1 } }, // vdivsd
1623 { ISD::FDIV, MVT::v2f64, { 14, 20, 1, 1 } }, // vdivpd
1624 { ISD::FDIV, MVT::v4f64, { 28, 35, 1, 3 } }, // vdivpd
1625 };
1626
1627 // Look for AVX2 lowering tricks for custom cases.
1628 if (ST->hasAVX2())
1629 if (const auto *Entry = CostTableLookup(AVX2CostTable, ISD, LT.second))
1630 if (auto KindCost = Entry->Cost[CostKind])
1631 return LT.first * *KindCost;
1632
1633 static const CostKindTblEntry AVX1CostTable[] = {
1634 // We don't have to scalarize unsupported ops. We can issue two half-sized
1635 // operations and we only need to extract the upper YMM half.
1636 // Two ops + 1 extract + 1 insert = 4.
1637 { ISD::MUL, MVT::v32i8, { 10, 11, 18, 19 } }, // pmaddubsw + split
1638 { ISD::MUL, MVT::v16i8, { 5, 6, 8, 12 } }, // 2*pmaddubsw/3*and/psllw/or
1639 { ISD::MUL, MVT::v16i16, { 4, 8, 5, 6 } }, // pmullw + split
1640 { ISD::MUL, MVT::v8i32, { 5, 8, 5, 10 } }, // pmulld + split
1641 { ISD::MUL, MVT::v4i32, { 2, 5, 1, 3 } }, // pmulld
1642 { ISD::MUL, MVT::v4i64, { 12, 15, 19, 20 } },
1643
1644 { X86ISD::PMULUDQ, MVT::v4i64, { 3, 5, 5, 6 } }, // pmuludq + split
1645
1646 { ISD::AND, MVT::v32i8, { 1, 1, 1, 2 } }, // vandps
1647 { ISD::AND, MVT::v16i16, { 1, 1, 1, 2 } }, // vandps
1648 { ISD::AND, MVT::v8i32, { 1, 1, 1, 2 } }, // vandps
1649 { ISD::AND, MVT::v4i64, { 1, 1, 1, 2 } }, // vandps
1650
1651 { ISD::OR, MVT::v32i8, { 1, 1, 1, 2 } }, // vorps
1652 { ISD::OR, MVT::v16i16, { 1, 1, 1, 2 } }, // vorps
1653 { ISD::OR, MVT::v8i32, { 1, 1, 1, 2 } }, // vorps
1654 { ISD::OR, MVT::v4i64, { 1, 1, 1, 2 } }, // vorps
1655
1656 { ISD::XOR, MVT::v32i8, { 1, 1, 1, 2 } }, // vxorps
1657 { ISD::XOR, MVT::v16i16, { 1, 1, 1, 2 } }, // vxorps
1658 { ISD::XOR, MVT::v8i32, { 1, 1, 1, 2 } }, // vxorps
1659 { ISD::XOR, MVT::v4i64, { 1, 1, 1, 2 } }, // vxorps
1660
1661 { ISD::SUB, MVT::v32i8, { 4, 2, 5, 6 } }, // psubb + split
1662 { ISD::ADD, MVT::v32i8, { 4, 2, 5, 6 } }, // paddb + split
1663 { ISD::SUB, MVT::v16i16, { 4, 2, 5, 6 } }, // psubw + split
1664 { ISD::ADD, MVT::v16i16, { 4, 2, 5, 6 } }, // paddw + split
1665 { ISD::SUB, MVT::v8i32, { 4, 2, 5, 6 } }, // psubd + split
1666 { ISD::ADD, MVT::v8i32, { 4, 2, 5, 6 } }, // paddd + split
1667 { ISD::SUB, MVT::v4i64, { 4, 2, 5, 6 } }, // psubq + split
1668 { ISD::ADD, MVT::v4i64, { 4, 2, 5, 6 } }, // paddq + split
1669 { ISD::SUB, MVT::v2i64, { 1, 1, 1, 1 } }, // psubq
1670 { ISD::ADD, MVT::v2i64, { 1, 1, 1, 1 } }, // paddq
1671
1672 { ISD::SHL, MVT::v16i8, { 10, 21,11,17 } }, // pblendvb sequence.
1673 { ISD::SHL, MVT::v32i8, { 22, 22,27,40 } }, // pblendvb sequence + split.
1674 { ISD::SHL, MVT::v8i16, { 6, 9,11,11 } }, // pblendvb sequence.
1675 { ISD::SHL, MVT::v16i16, { 13, 16,24,25 } }, // pblendvb sequence + split.
1676 { ISD::SHL, MVT::v4i32, { 3, 11, 4, 6 } }, // pslld/paddd/cvttps2dq/pmulld
1677 { ISD::SHL, MVT::v8i32, { 9, 11,12,17 } }, // pslld/paddd/cvttps2dq/pmulld + split
1678 { ISD::SHL, MVT::v2i64, { 2, 4, 4, 6 } }, // Shift each lane + blend.
1679 { ISD::SHL, MVT::v4i64, { 6, 7,11,15 } }, // Shift each lane + blend + split.
1680
1681 { ISD::SRL, MVT::v16i8, { 11, 27,12,18 } }, // pblendvb sequence.
1682 { ISD::SRL, MVT::v32i8, { 23, 23,30,43 } }, // pblendvb sequence + split.
1683 { ISD::SRL, MVT::v8i16, { 13, 16,14,22 } }, // pblendvb sequence.
1684 { ISD::SRL, MVT::v16i16, { 28, 30,31,48 } }, // pblendvb sequence + split.
1685 { ISD::SRL, MVT::v4i32, { 6, 7,12,16 } }, // Shift each lane + blend.
1686 { ISD::SRL, MVT::v8i32, { 14, 14,26,34 } }, // Shift each lane + blend + split.
1687 { ISD::SRL, MVT::v2i64, { 2, 4, 4, 6 } }, // Shift each lane + blend.
1688 { ISD::SRL, MVT::v4i64, { 6, 7,11,15 } }, // Shift each lane + blend + split.
1689
1690 { ISD::SRA, MVT::v16i8, { 21, 22,24,36 } }, // pblendvb sequence.
1691 { ISD::SRA, MVT::v32i8, { 44, 45,51,76 } }, // pblendvb sequence + split.
1692 { ISD::SRA, MVT::v8i16, { 13, 16,14,22 } }, // pblendvb sequence.
1693 { ISD::SRA, MVT::v16i16, { 28, 30,31,48 } }, // pblendvb sequence + split.
1694 { ISD::SRA, MVT::v4i32, { 6, 7,12,16 } }, // Shift each lane + blend.
1695 { ISD::SRA, MVT::v8i32, { 14, 14,26,34 } }, // Shift each lane + blend + split.
1696 { ISD::SRA, MVT::v2i64, { 5, 6,10,14 } }, // Shift each lane + blend.
1697 { ISD::SRA, MVT::v4i64, { 12, 12,22,30 } }, // Shift each lane + blend + split.
1698
1699 { ISD::FNEG, MVT::v4f64, { 2, 2, 1, 2 } }, // BTVER2 from http://www.agner.org/
1700 { ISD::FNEG, MVT::v8f32, { 2, 2, 1, 2 } }, // BTVER2 from http://www.agner.org/
1701
1702 { ISD::FADD, MVT::f64, { 1, 5, 1, 1 } }, // BDVER2 from http://www.agner.org/
1703 { ISD::FADD, MVT::f32, { 1, 5, 1, 1 } }, // BDVER2 from http://www.agner.org/
1704 { ISD::FADD, MVT::v2f64, { 1, 5, 1, 1 } }, // BDVER2 from http://www.agner.org/
1705 { ISD::FADD, MVT::v4f32, { 1, 5, 1, 1 } }, // BDVER2 from http://www.agner.org/
1706 { ISD::FADD, MVT::v4f64, { 2, 5, 1, 2 } }, // BDVER2 from http://www.agner.org/
1707 { ISD::FADD, MVT::v8f32, { 2, 5, 1, 2 } }, // BDVER2 from http://www.agner.org/
1708
1709 { ISD::FSUB, MVT::f64, { 1, 5, 1, 1 } }, // BDVER2 from http://www.agner.org/
1710 { ISD::FSUB, MVT::f32, { 1, 5, 1, 1 } }, // BDVER2 from http://www.agner.org/
1711 { ISD::FSUB, MVT::v2f64, { 1, 5, 1, 1 } }, // BDVER2 from http://www.agner.org/
1712 { ISD::FSUB, MVT::v4f32, { 1, 5, 1, 1 } }, // BDVER2 from http://www.agner.org/
1713 { ISD::FSUB, MVT::v4f64, { 2, 5, 1, 2 } }, // BDVER2 from http://www.agner.org/
1714 { ISD::FSUB, MVT::v8f32, { 2, 5, 1, 2 } }, // BDVER2 from http://www.agner.org/
1715
1716 { ISD::FMUL, MVT::f64, { 2, 5, 1, 1 } }, // BTVER2 from http://www.agner.org/
1717 { ISD::FMUL, MVT::f32, { 1, 5, 1, 1 } }, // BTVER2 from http://www.agner.org/
1718 { ISD::FMUL, MVT::v2f64, { 2, 5, 1, 1 } }, // BTVER2 from http://www.agner.org/
1719 { ISD::FMUL, MVT::v4f32, { 1, 5, 1, 1 } }, // BTVER2 from http://www.agner.org/
1720 { ISD::FMUL, MVT::v4f64, { 4, 5, 1, 2 } }, // BTVER2 from http://www.agner.org/
1721 { ISD::FMUL, MVT::v8f32, { 2, 5, 1, 2 } }, // BTVER2 from http://www.agner.org/
1722
1723 { ISD::FDIV, MVT::f32, { 14, 14, 1, 1 } }, // SNB from http://www.agner.org/
1724 { ISD::FDIV, MVT::v4f32, { 14, 14, 1, 1 } }, // SNB from http://www.agner.org/
1725 { ISD::FDIV, MVT::v8f32, { 28, 29, 1, 3 } }, // SNB from http://www.agner.org/
1726 { ISD::FDIV, MVT::f64, { 22, 22, 1, 1 } }, // SNB from http://www.agner.org/
1727 { ISD::FDIV, MVT::v2f64, { 22, 22, 1, 1 } }, // SNB from http://www.agner.org/
1728 { ISD::FDIV, MVT::v4f64, { 44, 45, 1, 3 } }, // SNB from http://www.agner.org/
1729 };
1730
1731 if (ST->hasAVX())
1732 if (const auto *Entry = CostTableLookup(AVX1CostTable, ISD, LT.second))
1733 if (auto KindCost = Entry->Cost[CostKind])
1734 return LT.first * *KindCost;
1735
1736 static const CostKindTblEntry SSE42CostTable[] = {
1737 { ISD::FADD, MVT::f64, { 1, 3, 1, 1 } }, // Nehalem from http://www.agner.org/
1738 { ISD::FADD, MVT::f32, { 1, 3, 1, 1 } }, // Nehalem from http://www.agner.org/
1739 { ISD::FADD, MVT::v2f64, { 1, 3, 1, 1 } }, // Nehalem from http://www.agner.org/
1740 { ISD::FADD, MVT::v4f32, { 1, 3, 1, 1 } }, // Nehalem from http://www.agner.org/
1741
1742 { ISD::FSUB, MVT::f64, { 1, 3, 1, 1 } }, // Nehalem from http://www.agner.org/
1743 { ISD::FSUB, MVT::f32 , { 1, 3, 1, 1 } }, // Nehalem from http://www.agner.org/
1744 { ISD::FSUB, MVT::v2f64, { 1, 3, 1, 1 } }, // Nehalem from http://www.agner.org/
1745 { ISD::FSUB, MVT::v4f32, { 1, 3, 1, 1 } }, // Nehalem from http://www.agner.org/
1746
1747 { ISD::FMUL, MVT::f64, { 1, 5, 1, 1 } }, // Nehalem from http://www.agner.org/
1748 { ISD::FMUL, MVT::f32, { 1, 5, 1, 1 } }, // Nehalem from http://www.agner.org/
1749 { ISD::FMUL, MVT::v2f64, { 1, 5, 1, 1 } }, // Nehalem from http://www.agner.org/
1750 { ISD::FMUL, MVT::v4f32, { 1, 5, 1, 1 } }, // Nehalem from http://www.agner.org/
1751
1752 { ISD::FDIV, MVT::f32, { 14, 14, 1, 1 } }, // Nehalem from http://www.agner.org/
1753 { ISD::FDIV, MVT::v4f32, { 14, 14, 1, 1 } }, // Nehalem from http://www.agner.org/
1754 { ISD::FDIV, MVT::f64, { 22, 22, 1, 1 } }, // Nehalem from http://www.agner.org/
1755 { ISD::FDIV, MVT::v2f64, { 22, 22, 1, 1 } }, // Nehalem from http://www.agner.org/
1756
1757 { ISD::MUL, MVT::v2i64, { 6, 10,10,10 } } // 3*pmuludq/3*shift/2*add
1758 };
1759
1760 if (ST->hasSSE42())
1761 if (const auto *Entry = CostTableLookup(SSE42CostTable, ISD, LT.second))
1762 if (auto KindCost = Entry->Cost[CostKind])
1763 return LT.first * *KindCost;
1764
1765 static const CostKindTblEntry SSE41CostTable[] = {
1766 { ISD::SHL, MVT::v16i8, { 15, 24,17,22 } }, // pblendvb sequence.
1767 { ISD::SHL, MVT::v8i16, { 11, 14,11,11 } }, // pblendvb sequence.
1768 { ISD::SHL, MVT::v4i32, { 14, 20, 4,10 } }, // pslld/paddd/cvttps2dq/pmulld
1769
1770 { ISD::SRL, MVT::v16i8, { 16, 27,18,24 } }, // pblendvb sequence.
1771 { ISD::SRL, MVT::v8i16, { 22, 26,23,27 } }, // pblendvb sequence.
1772 { ISD::SRL, MVT::v4i32, { 16, 17,15,19 } }, // Shift each lane + blend.
1773 { ISD::SRL, MVT::v2i64, { 4, 6, 5, 7 } }, // splat+shuffle sequence.
1774
1775 { ISD::SRA, MVT::v16i8, { 38, 41,30,36 } }, // pblendvb sequence.
1776 { ISD::SRA, MVT::v8i16, { 22, 26,23,27 } }, // pblendvb sequence.
1777 { ISD::SRA, MVT::v4i32, { 16, 17,15,19 } }, // Shift each lane + blend.
1778 { ISD::SRA, MVT::v2i64, { 8, 17, 5, 7 } }, // splat+shuffle sequence.
1779
1780 { ISD::MUL, MVT::v4i32, { 2, 11, 1, 1 } } // pmulld (Nehalem from agner.org)
1781 };
1782
1783 if (ST->hasSSE41())
1784 if (const auto *Entry = CostTableLookup(SSE41CostTable, ISD, LT.second))
1785 if (auto KindCost = Entry->Cost[CostKind])
1786 return LT.first * *KindCost;
1787
1788 static const CostKindTblEntry SSSE3CostTable[] = {
1789 { ISD::MUL, MVT::v16i8, { 5, 18,10,12 } }, // 2*pmaddubsw/3*and/psllw/or
1790 };
1791
1792 if (ST->hasSSSE3())
1793 if (const auto *Entry = CostTableLookup(SSSE3CostTable, ISD, LT.second))
1794 if (auto KindCost = Entry->Cost[CostKind])
1795 return LT.first * *KindCost;
1796
1797 static const CostKindTblEntry SSE2CostTable[] = {
1798 // We don't correctly identify costs of casts because they are marked as
1799 // custom.
1800 { ISD::SHL, MVT::v16i8, { 13, 21,26,28 } }, // cmpgtb sequence.
1801 { ISD::SHL, MVT::v8i16, { 24, 27,16,20 } }, // cmpgtw sequence.
1802 { ISD::SHL, MVT::v4i32, { 17, 19,10,12 } }, // pslld/paddd/cvttps2dq/pmuludq.
1803 { ISD::SHL, MVT::v2i64, { 4, 6, 5, 7 } }, // splat+shuffle sequence.
1804
1805 { ISD::SRL, MVT::v16i8, { 14, 28,27,30 } }, // cmpgtb sequence.
1806 { ISD::SRL, MVT::v8i16, { 16, 19,31,31 } }, // cmpgtw sequence.
1807 { ISD::SRL, MVT::v4i32, { 12, 12,15,19 } }, // Shift each lane + blend.
1808 { ISD::SRL, MVT::v2i64, { 4, 6, 5, 7 } }, // splat+shuffle sequence.
1809
1810 { ISD::SRA, MVT::v16i8, { 27, 30,54,54 } }, // unpacked cmpgtb sequence.
1811 { ISD::SRA, MVT::v8i16, { 16, 19,31,31 } }, // cmpgtw sequence.
1812 { ISD::SRA, MVT::v4i32, { 12, 12,15,19 } }, // Shift each lane + blend.
1813 { ISD::SRA, MVT::v2i64, { 8, 11,12,16 } }, // srl/xor/sub splat+shuffle sequence.
1814
1815 { ISD::AND, MVT::v16i8, { 1, 1, 1, 1 } }, // pand
1816 { ISD::AND, MVT::v8i16, { 1, 1, 1, 1 } }, // pand
1817 { ISD::AND, MVT::v4i32, { 1, 1, 1, 1 } }, // pand
1818 { ISD::AND, MVT::v2i64, { 1, 1, 1, 1 } }, // pand
1819
1820 { ISD::OR, MVT::v16i8, { 1, 1, 1, 1 } }, // por
1821 { ISD::OR, MVT::v8i16, { 1, 1, 1, 1 } }, // por
1822 { ISD::OR, MVT::v4i32, { 1, 1, 1, 1 } }, // por
1823 { ISD::OR, MVT::v2i64, { 1, 1, 1, 1 } }, // por
1824
1825 { ISD::XOR, MVT::v16i8, { 1, 1, 1, 1 } }, // pxor
1826 { ISD::XOR, MVT::v8i16, { 1, 1, 1, 1 } }, // pxor
1827 { ISD::XOR, MVT::v4i32, { 1, 1, 1, 1 } }, // pxor
1828 { ISD::XOR, MVT::v2i64, { 1, 1, 1, 1 } }, // pxor
1829
1830 { ISD::ADD, MVT::v2i64, { 1, 2, 1, 2 } }, // paddq
1831 { ISD::SUB, MVT::v2i64, { 1, 2, 1, 2 } }, // psubq
1832
1833 { ISD::MUL, MVT::v16i8, { 6, 18,12,12 } }, // 2*unpack/2*pmullw/2*and/pack
1834 { ISD::MUL, MVT::v8i16, { 1, 5, 1, 1 } }, // pmullw
1835 { ISD::MUL, MVT::v4i32, { 6, 8, 7, 7 } }, // 3*pmuludq/4*shuffle
1836 { ISD::MUL, MVT::v2i64, { 7, 10,10,10 } }, // 3*pmuludq/3*shift/2*add
1837
1838 { X86ISD::PMULUDQ, MVT::v2i64, { 1, 5, 1, 1 } },
1839
1840 { ISD::FDIV, MVT::f32, { 23, 23, 1, 1 } }, // Pentium IV from http://www.agner.org/
1841 { ISD::FDIV, MVT::v4f32, { 39, 39, 1, 1 } }, // Pentium IV from http://www.agner.org/
1842 { ISD::FDIV, MVT::f64, { 38, 38, 1, 1 } }, // Pentium IV from http://www.agner.org/
1843 { ISD::FDIV, MVT::v2f64, { 69, 69, 1, 1 } }, // Pentium IV from http://www.agner.org/
1844
1845 { ISD::FNEG, MVT::f32, { 1, 1, 1, 1 } }, // Pentium IV from http://www.agner.org/
1846 { ISD::FNEG, MVT::f64, { 1, 1, 1, 1 } }, // Pentium IV from http://www.agner.org/
1847 { ISD::FNEG, MVT::v4f32, { 1, 1, 1, 1 } }, // Pentium IV from http://www.agner.org/
1848 { ISD::FNEG, MVT::v2f64, { 1, 1, 1, 1 } }, // Pentium IV from http://www.agner.org/
1849
1850 { ISD::FADD, MVT::f32, { 2, 3, 1, 1 } }, // Pentium IV from http://www.agner.org/
1851 { ISD::FADD, MVT::f64, { 2, 3, 1, 1 } }, // Pentium IV from http://www.agner.org/
1852 { ISD::FADD, MVT::v2f64, { 2, 3, 1, 1 } }, // Pentium IV from http://www.agner.org/
1853
1854 { ISD::FSUB, MVT::f32, { 2, 3, 1, 1 } }, // Pentium IV from http://www.agner.org/
1855 { ISD::FSUB, MVT::f64, { 2, 3, 1, 1 } }, // Pentium IV from http://www.agner.org/
1856 { ISD::FSUB, MVT::v2f64, { 2, 3, 1, 1 } }, // Pentium IV from http://www.agner.org/
1857
1858 { ISD::FMUL, MVT::f64, { 2, 5, 1, 1 } }, // Pentium IV from http://www.agner.org/
1859 { ISD::FMUL, MVT::v2f64, { 2, 5, 1, 1 } }, // Pentium IV from http://www.agner.org/
1860 };
1861
1862 if (ST->hasSSE2())
1863 if (const auto *Entry = CostTableLookup(SSE2CostTable, ISD, LT.second))
1864 if (auto KindCost = Entry->Cost[CostKind])
1865 return LT.first * *KindCost;
1866
1867 static const CostKindTblEntry SSE1CostTable[] = {
1868 { ISD::FDIV, MVT::f32, { 17, 18, 1, 1 } }, // Pentium III from http://www.agner.org/
1869 { ISD::FDIV, MVT::v4f32, { 34, 48, 1, 1 } }, // Pentium III from http://www.agner.org/
1870
1871 { ISD::FNEG, MVT::f32, { 2, 2, 1, 2 } }, // Pentium III from http://www.agner.org/
1872 { ISD::FNEG, MVT::v4f32, { 2, 2, 1, 2 } }, // Pentium III from http://www.agner.org/
1873
1874 { ISD::FADD, MVT::f32, { 1, 3, 1, 1 } }, // Pentium III from http://www.agner.org/
1875 { ISD::FADD, MVT::v4f32, { 2, 3, 1, 1 } }, // Pentium III from http://www.agner.org/
1876
1877 { ISD::FSUB, MVT::f32, { 1, 3, 1, 1 } }, // Pentium III from http://www.agner.org/
1878 { ISD::FSUB, MVT::v4f32, { 2, 3, 1, 1 } }, // Pentium III from http://www.agner.org/
1879
1880 { ISD::FMUL, MVT::f32, { 2, 5, 1, 1 } }, // Pentium III from http://www.agner.org/
1881 { ISD::FMUL, MVT::v4f32, { 2, 5, 1, 1 } }, // Pentium III from http://www.agner.org/
1882 };
1883
1884 if (ST->hasSSE1())
1885 if (const auto *Entry = CostTableLookup(SSE1CostTable, ISD, LT.second))
1886 if (auto KindCost = Entry->Cost[CostKind])
1887 return LT.first * *KindCost;
1888
1889 static const CostKindTblEntry X64CostTbl[] = { // 64-bit targets
1890 { ISD::ADD, MVT::i64, { 1 } }, // Core (Merom) from http://www.agner.org/
1891 { ISD::SUB, MVT::i64, { 1 } }, // Core (Merom) from http://www.agner.org/
1892 { ISD::MUL, MVT::i64, { 2, 6, 1, 2 } },
1893 };
1894
1895 if (ST->is64Bit())
1896 if (const auto *Entry = CostTableLookup(X64CostTbl, ISD, LT.second))
1897 if (auto KindCost = Entry->Cost[CostKind])
1898 return LT.first * *KindCost;
1899
1900 static const CostKindTblEntry X86CostTbl[] = { // 32 or 64-bit targets
1901 { ISD::ADD, MVT::i8, { 1 } }, // Pentium III from http://www.agner.org/
1902 { ISD::ADD, MVT::i16, { 1 } }, // Pentium III from http://www.agner.org/
1903 { ISD::ADD, MVT::i32, { 1 } }, // Pentium III from http://www.agner.org/
1904
1905 { ISD::SUB, MVT::i8, { 1 } }, // Pentium III from http://www.agner.org/
1906 { ISD::SUB, MVT::i16, { 1 } }, // Pentium III from http://www.agner.org/
1907 { ISD::SUB, MVT::i32, { 1 } }, // Pentium III from http://www.agner.org/
1908
1909 { ISD::MUL, MVT::i8, { 3, 4, 1, 1 } },
1910 { ISD::MUL, MVT::i16, { 2, 4, 1, 1 } },
1911 { ISD::MUL, MVT::i32, { 1, 4, 1, 1 } },
1912
1913 { ISD::FNEG, MVT::f64, { 2, 2, 1, 3 } }, // (x87)
1914 { ISD::FADD, MVT::f64, { 2, 3, 1, 1 } }, // (x87)
1915 { ISD::FSUB, MVT::f64, { 2, 3, 1, 1 } }, // (x87)
1916 { ISD::FMUL, MVT::f64, { 2, 5, 1, 1 } }, // (x87)
1917 { ISD::FDIV, MVT::f64, { 38, 38, 1, 1 } }, // (x87)
1918 };
1919
1920 if (const auto *Entry = CostTableLookup(X86CostTbl, ISD, LT.second))
1921 if (auto KindCost = Entry->Cost[CostKind])
1922 return LT.first * *KindCost;
1923
1924 // It is not a good idea to vectorize division. We have to scalarize it and
1925 // in the process we will often end up having to spilling regular
1926 // registers. The overhead of division is going to dominate most kernels
1927 // anyways so try hard to prevent vectorization of division - it is
1928 // generally a bad idea. Assume somewhat arbitrarily that we have to be able
1929 // to hide "20 cycles" for each lane.
1930 if (CostKind == TTI::TCK_RecipThroughput && LT.second.isVector() &&
1931 (ISD == ISD::SDIV || ISD == ISD::SREM || ISD == ISD::UDIV ||
1932 ISD == ISD::UREM)) {
1933 InstructionCost ScalarCost =
1934 getArithmeticInstrCost(Opcode, Ty->getScalarType(), CostKind,
1935 Op1Info.getNoProps(), Op2Info.getNoProps());
1936 return 20 * LT.first * LT.second.getVectorNumElements() * ScalarCost;
1937 }
1938
1939 // Handle some basic single instruction code size cases.
1940 if (CostKind == TTI::TCK_CodeSize) {
1941 switch (ISD) {
1942 case ISD::FADD:
1943 case ISD::FSUB:
1944 case ISD::FMUL:
1945 case ISD::FDIV:
1946 case ISD::FNEG:
1947 case ISD::AND:
1948 case ISD::OR:
1949 case ISD::XOR:
1950 return LT.first;
1951 break;
1952 }
1953 }
1954
1955 // Fallback to the default implementation.
1956 return BaseT::getArithmeticInstrCost(Opcode, Ty, CostKind, Op1Info, Op2Info,
1957 Args, CtxI);
1958}
1959
1962 unsigned Opcode1, const SmallBitVector &OpcodeMask,
1964 ArrayRef<const Value *> Scalars) const {
1965 if (isLegalAltInstr(VecTy, Opcode0, Opcode1, OpcodeMask, Scalars))
1966 return TTI::TCC_Basic;
1968}
1969
1971 TTI::ShuffleKind Kind, VectorType *DstTy, VectorType *SrcTy,
1973 VectorType *SubTp, ArrayRef<const Value *> Args, const Instruction *CtxI,
1974 TTI::VectorInstrContext VIC) const {
1975 assert((Mask.empty() || DstTy->isScalableTy() ||
1976 Mask.size() == DstTy->getElementCount().getKnownMinValue()) &&
1977 "Expected the Mask to match the return size if given");
1978 assert(SrcTy->getScalarType() == DstTy->getScalarType() &&
1979 "Expected the same scalar types");
1980
1981 // 64-bit packed float vectors (v2f32) are widened to type v4f32.
1982 // 64-bit packed integer vectors (v2i32) are widened to type v4i32.
1983 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(SrcTy);
1984
1985 Kind = improveShuffleKindFromMask(Kind, Mask, SrcTy, Index, SubTp);
1986
1987 // If all args are constant than this will be constant folded away.
1988 if (!Args.empty() &&
1989 all_of(Args, [](const Value *Arg) { return isa<Constant>(Arg); }))
1990 return TTI::TCC_Free;
1991
1992 // Recognize a basic concat_vector shuffle.
1993 if (Kind == TTI::SK_PermuteTwoSrc &&
1994 Mask.size() == (2 * SrcTy->getElementCount().getKnownMinValue()) &&
1995 ShuffleVectorInst::isIdentityMask(Mask, Mask.size()))
1999 CostKind, Mask, Mask.size() / 2, SrcTy);
2000
2001 // Treat Transpose as 2-op shuffles - there's no difference in lowering.
2002 if (Kind == TTI::SK_Transpose)
2003 if (LT.second != MVT::v4f64 && LT.second != MVT::v4i64)
2004 Kind = TTI::SK_PermuteTwoSrc;
2005
2006 if (Kind == TTI::SK_Broadcast) {
2007 // For Broadcasts we are splatting the first element from the first input
2008 // register, so only need to reference that input and all the output
2009 // registers are the same.
2010 LT.first = 1;
2011
2012 // If we're broadcasting a load then AVX/AVX2 can do this for free.
2013 // If many-used-load whose every use is one of a small set of operations
2014 // that SLP can rewrite into a single vector lane, codegen can fold it into
2015 // the free broadcast.
2016 using namespace PatternMatch;
2017 auto IsBroadcastLoadFoldUser = [&](const User *U) {
2018 if (isa<InsertElementInst>(U) && U->getOperand(1) == Args[0])
2019 return true;
2020 if (U->getType()->isVectorTy())
2021 return false;
2022 // Terminators (return/branch/switch/indirectbr/resume/invoke EH)
2023 // and phis carry the value across control flow.
2024 if (const auto *I = dyn_cast<Instruction>(U))
2025 if (I->isTerminator() ||
2027 return false;
2028 // Only pure calls can be folded.
2029 if (const auto *CB = dyn_cast<CallBase>(U))
2030 return CB->doesNotAccessMemory() && !CB->mayHaveSideEffects();
2031 return true;
2032 };
2033 auto IsFoldableSLPBroadcastLoad = [&]() {
2034 if (!match(Args[0], m_Load(m_Value())))
2035 return false;
2036 auto *FVT = dyn_cast<FixedVectorType>(DstTy);
2037 if (!FVT)
2038 return false;
2039 // getNumUses() counts each Use, matching the per-lane broadcast
2040 // accounting (a use like `op %x, %x` consumes two broadcast lanes).
2041 if (Args[0]->getNumUses() != FVT->getNumElements())
2042 return false;
2043 return all_of(Args[0]->users(), IsBroadcastLoadFoldUser);
2044 };
2045 if (!Args.empty() &&
2046 (match(Args[0], m_OneUse(m_Load(m_Value()))) ||
2047 IsFoldableSLPBroadcastLoad()) &&
2048 (ST->hasAVX2() ||
2049 (ST->hasAVX() && LT.second.getScalarSizeInBits() >= 32)))
2050 return TTI::TCC_Free;
2051 }
2052
2053 // Attempt to detect a cheaper inlane shuffle, avoiding 128-bit subvector
2054 // permutation.
2055 // Attempt to detect a shuffle mask with a single defined element.
2056 bool IsInLaneShuffle = false;
2057 bool IsSingleElementMask = false;
2058 if (SrcTy->getPrimitiveSizeInBits() > 0 &&
2059 (SrcTy->getPrimitiveSizeInBits() % 128) == 0 &&
2060 SrcTy->getScalarSizeInBits() == LT.second.getScalarSizeInBits() &&
2061 Mask.size() == SrcTy->getElementCount().getKnownMinValue()) {
2062 unsigned NumLanes = SrcTy->getPrimitiveSizeInBits() / 128;
2063 unsigned NumEltsPerLane = Mask.size() / NumLanes;
2064 if ((Mask.size() % NumLanes) == 0) {
2065 IsInLaneShuffle = all_of(enumerate(Mask), [&](const auto &P) {
2066 return P.value() == PoisonMaskElem ||
2067 ((P.value() % Mask.size()) / NumEltsPerLane) ==
2068 (P.index() / NumEltsPerLane);
2069 });
2070 IsSingleElementMask =
2071 (Mask.size() - 1) == static_cast<unsigned>(count_if(Mask, [](int M) {
2072 return M == PoisonMaskElem;
2073 }));
2074 }
2075 }
2076
2077 // Treat <X x bfloat> shuffles as <X x half>.
2078 if (LT.second.isVectorOf(MVT::bf16))
2079 LT.second = LT.second.changeVectorElementType(MVT::f16);
2080
2081 // Subvector extractions are free if they start at the beginning of a
2082 // vector and cheap if the subvectors are aligned.
2083 if (Kind == TTI::SK_ExtractSubvector && LT.second.isVector()) {
2084 int NumElts = LT.second.getVectorNumElements();
2085 if ((Index % NumElts) == 0)
2086 return TTI::TCC_Free;
2087 std::pair<InstructionCost, MVT> SubLT = getTypeLegalizationCost(SubTp);
2088 if (SubLT.second.isVector()) {
2089 int NumSubElts = SubLT.second.getVectorNumElements();
2090 if ((Index % NumSubElts) == 0 && (NumElts % NumSubElts) == 0)
2091 return SubLT.first;
2092 // Handle some cases for widening legalization. For now we only handle
2093 // cases where the original subvector was naturally aligned and evenly
2094 // fit in its legalized subvector type.
2095 // FIXME: Remove some of the alignment restrictions.
2096 // FIXME: We can use permq for 64-bit or larger extracts from 256-bit
2097 // vectors.
2098 int OrigSubElts = cast<FixedVectorType>(SubTp)->getNumElements();
2099 if (NumSubElts > OrigSubElts && (Index % OrigSubElts) == 0 &&
2100 (NumSubElts % OrigSubElts) == 0 &&
2101 LT.second.getVectorElementType() ==
2102 SubLT.second.getVectorElementType() &&
2103 LT.second.getVectorElementType().getSizeInBits() ==
2104 SrcTy->getElementType()->getPrimitiveSizeInBits()) {
2105 assert(NumElts >= NumSubElts && NumElts > OrigSubElts &&
2106 "Unexpected number of elements!");
2107 auto *VecTy = FixedVectorType::get(SrcTy->getElementType(),
2108 LT.second.getVectorNumElements());
2109 auto *SubTy = FixedVectorType::get(SrcTy->getElementType(),
2110 SubLT.second.getVectorNumElements());
2111 int ExtractIndex = alignDown((Index % NumElts), NumSubElts);
2112 InstructionCost ExtractCost =
2114 ExtractIndex, SubTy);
2115
2116 // If the original size is 32-bits or more, we can use pshufd. Otherwise
2117 // if we have SSSE3 we can use pshufb.
2118 if (SubTp->getPrimitiveSizeInBits() >= 32 || ST->hasSSSE3())
2119 return ExtractCost + 1; // pshufd or pshufb
2120
2121 assert(SubTp->getPrimitiveSizeInBits() == 16 &&
2122 "Unexpected vector size");
2123
2124 return ExtractCost + 2; // worst case pshufhw + pshufd
2125 }
2126 }
2127 // If the extract subvector is not optimal, treat it as single op shuffle.
2129 }
2130
2131 // Subvector insertions are cheap if the subvectors are aligned.
2132 // Note that in general, the insertion starting at the beginning of a vector
2133 // isn't free, because we need to preserve the rest of the wide vector,
2134 // but if the destination vector legalizes to the same width as the subvector
2135 // then the insertion will simplify to a (free) register copy.
2136 if (Kind == TTI::SK_InsertSubvector && LT.second.isVector()) {
2137 std::pair<InstructionCost, MVT> DstLT = getTypeLegalizationCost(DstTy);
2138 int NumElts = DstLT.second.getVectorNumElements();
2139 std::pair<InstructionCost, MVT> SubLT = getTypeLegalizationCost(SubTp);
2140 if (SubLT.second.isVector()) {
2141 int NumSubElts = SubLT.second.getVectorNumElements();
2142 bool MatchingTypes =
2143 NumElts == NumSubElts &&
2144 (SubTp->getElementCount().getKnownMinValue() % NumSubElts) == 0;
2145 if ((Index % NumSubElts) == 0 && (NumElts % NumSubElts) == 0)
2146 return MatchingTypes ? TTI::TCC_Free : SubLT.first;
2147 }
2148
2149 // Attempt to match MOVSS (Idx == 0) or INSERTPS pattern. This will have
2150 // been matched by improveShuffleKindFromMask as a SK_InsertSubvector of
2151 // v1f32 (legalised to f32) into a v4f32.
2152 if (LT.first == 1 && LT.second == MVT::v4f32 && SubLT.first == 1 &&
2153 SubLT.second == MVT::f32 && (Index == 0 || ST->hasSSE41()))
2154 return 1;
2155
2156 // If the insertion is the lowest subvector then it will be blended
2157 // otherwise treat it like a 2-op shuffle.
2158 Kind =
2159 (Index == 0 && LT.first == 1) ? TTI::SK_Select : TTI::SK_PermuteTwoSrc;
2160 }
2161
2162 // Handle some common (illegal) sub-vector types as they are often very cheap
2163 // to shuffle even on targets without PSHUFB.
2164 EVT VT = TLI->getValueType(DL, SrcTy);
2165 if (VT.isSimple() && VT.isVector() && VT.getSizeInBits() < 128 &&
2166 !ST->hasSSSE3()) {
2167 static const CostKindTblEntry SSE2SubVectorShuffleTbl[] = {
2168 {TTI::SK_Broadcast, MVT::v4i16, {1,1,1,1}}, // pshuflw
2169 {TTI::SK_Broadcast, MVT::v2i16, {1,1,1,1}}, // pshuflw
2170 {TTI::SK_Broadcast, MVT::v8i8, {2,2,2,2}}, // punpck/pshuflw
2171 {TTI::SK_Broadcast, MVT::v4i8, {2,2,2,2}}, // punpck/pshuflw
2172 {TTI::SK_Broadcast, MVT::v2i8, {1,1,1,1}}, // punpck
2173
2174 {TTI::SK_Reverse, MVT::v4i16, {1,1,1,1}}, // pshuflw
2175 {TTI::SK_Reverse, MVT::v2i16, {1,1,1,1}}, // pshuflw
2176 {TTI::SK_Reverse, MVT::v4i8, {3,3,3,3}}, // punpck/pshuflw/packus
2177 {TTI::SK_Reverse, MVT::v2i8, {1,1,1,1}}, // punpck
2178
2179 {TTI::SK_Splice, MVT::v4i16, {2,2,2,2}}, // punpck+psrldq
2180 {TTI::SK_Splice, MVT::v2i16, {2,2,2,2}}, // punpck+psrldq
2181 {TTI::SK_Splice, MVT::v4i8, {2,2,2,2}}, // punpck+psrldq
2182 {TTI::SK_Splice, MVT::v2i8, {2,2,2,2}}, // punpck+psrldq
2183
2184 {TTI::SK_PermuteTwoSrc, MVT::v4i16, {2,2,2,2}}, // punpck/pshuflw
2185 {TTI::SK_PermuteTwoSrc, MVT::v2i16, {2,2,2,2}}, // punpck/pshuflw
2186 {TTI::SK_PermuteTwoSrc, MVT::v8i8, {7,7,7,7}}, // punpck/pshuflw
2187 {TTI::SK_PermuteTwoSrc, MVT::v4i8, {4,4,4,4}}, // punpck/pshuflw
2188 {TTI::SK_PermuteTwoSrc, MVT::v2i8, {2,2,2,2}}, // punpck
2189
2190 {TTI::SK_PermuteSingleSrc, MVT::v4i16, {1,1,1,1}}, // pshuflw
2191 {TTI::SK_PermuteSingleSrc, MVT::v2i16, {1,1,1,1}}, // pshuflw
2192 {TTI::SK_PermuteSingleSrc, MVT::v8i8, {5,5,5,5}}, // punpck/pshuflw
2193 {TTI::SK_PermuteSingleSrc, MVT::v4i8, {3,3,3,3}}, // punpck/pshuflw
2194 {TTI::SK_PermuteSingleSrc, MVT::v2i8, {1,1,1,1}}, // punpck
2195 };
2196
2197 if (ST->hasSSE2())
2198 if (const auto *Entry =
2199 CostTableLookup(SSE2SubVectorShuffleTbl, Kind, VT.getSimpleVT()))
2200 if (auto KindCost = Entry->Cost[CostKind])
2201 return LT.first * *KindCost;
2202 }
2203
2204 // We are going to permute multiple sources and the result will be in multiple
2205 // destinations. Providing an accurate cost only for splits where the element
2206 // type remains the same.
2207 if (LT.first != 1) {
2208 MVT LegalVT = LT.second;
2209 if (LegalVT.isVector() &&
2210 LegalVT.getVectorElementType().getSizeInBits() ==
2211 SrcTy->getElementType()->getPrimitiveSizeInBits() &&
2212 LegalVT.getVectorNumElements() <
2213 cast<FixedVectorType>(SrcTy)->getNumElements()) {
2214 unsigned VecTySize = DL.getTypeStoreSize(SrcTy);
2215 unsigned LegalVTSize = LegalVT.getStoreSize();
2216 // Number of source vectors after legalization:
2217 unsigned NumOfSrcs = (VecTySize + LegalVTSize - 1) / LegalVTSize;
2218 // Number of destination vectors after legalization:
2219 InstructionCost NumOfDests = LT.first;
2220
2221 auto *SingleOpTy = FixedVectorType::get(SrcTy->getElementType(),
2222 LegalVT.getVectorNumElements());
2223
2224 if (!Mask.empty() && NumOfDests.isValid()) {
2225 // Try to perform better estimation of the permutation.
2226 // 1. Split the source/destination vectors into real registers.
2227 // 2. Do the mask analysis to identify which real registers are
2228 // permuted. If more than 1 source registers are used for the
2229 // destination register building, the cost for this destination register
2230 // is (Number_of_source_register - 1) * Cost_PermuteTwoSrc. If only one
2231 // source register is used, build mask and calculate the cost as a cost
2232 // of PermuteSingleSrc.
2233 // Also, for the single register permute we try to identify if the
2234 // destination register is just a copy of the source register or the
2235 // copy of the previous destination register (the cost is
2236 // TTI::TCC_Basic). If the source register is just reused, the cost for
2237 // this operation is TTI::TCC_Free.
2238 NumOfDests =
2240 FixedVectorType::get(SrcTy->getElementType(), Mask.size()))
2241 .first;
2242 unsigned E = NumOfDests.getValue();
2243 unsigned NormalizedVF =
2244 LegalVT.getVectorNumElements() * std::max(NumOfSrcs, E);
2245 unsigned NumOfSrcRegs = NormalizedVF / LegalVT.getVectorNumElements();
2246 unsigned NumOfDestRegs = NormalizedVF / LegalVT.getVectorNumElements();
2247 SmallVector<int> NormalizedMask(NormalizedVF, PoisonMaskElem);
2248 copy(Mask, NormalizedMask.begin());
2249 unsigned PrevSrcReg = 0;
2250 ArrayRef<int> PrevRegMask;
2253 NormalizedMask, NumOfSrcRegs, NumOfDestRegs, NumOfDestRegs, []() {},
2254 [this, SingleOpTy, CostKind, &PrevSrcReg, &PrevRegMask,
2255 &Cost](ArrayRef<int> RegMask, unsigned SrcReg, unsigned DestReg) {
2256 if (!ShuffleVectorInst::isIdentityMask(RegMask, RegMask.size())) {
2257 // Check if the previous register can be just copied to the next
2258 // one.
2259 if (PrevRegMask.empty() || PrevSrcReg != SrcReg ||
2260 PrevRegMask != RegMask)
2261 Cost +=
2263 SingleOpTy, CostKind, RegMask, 0, nullptr);
2264 else
2265 // Just a copy of previous destination register.
2267 return;
2268 }
2269 if (SrcReg != DestReg &&
2270 any_of(RegMask, not_equal_to(PoisonMaskElem))) {
2271 // Just a copy of the source register.
2273 }
2274 PrevSrcReg = SrcReg;
2275 PrevRegMask = RegMask;
2276 },
2277 [this, SingleOpTy, CostKind,
2278 &Cost](ArrayRef<int> RegMask, unsigned /*Unused*/,
2279 unsigned /*Unused*/, bool /*Unused*/) {
2281 SingleOpTy, CostKind, RegMask, 0, nullptr);
2282 });
2283 return Cost;
2284 }
2285
2286 InstructionCost NumOfShuffles = (NumOfSrcs - 1) * NumOfDests;
2287 return NumOfShuffles * getShuffleCost(TTI::SK_PermuteTwoSrc, SingleOpTy,
2288 SingleOpTy, CostKind, {}, 0,
2289 nullptr);
2290 }
2291
2292 return BaseT::getShuffleCost(Kind, DstTy, SrcTy, CostKind, Mask, Index,
2293 SubTp);
2294 }
2295
2296 // If we're just moving a single element around (probably as an alternative to
2297 // extracting it), we can assume this is cheap.
2298 if (LT.first == 1 && IsInLaneShuffle && IsSingleElementMask)
2299 return TTI::TCC_Basic;
2300
2301 static const CostKindTblEntry AVX512VBMIShuffleTbl[] = {
2302 { TTI::SK_Reverse, MVT::v64i8, { 1, 1, 1, 1 } }, // vpermb
2303 { TTI::SK_Reverse, MVT::v32i8, { 1, 1, 1, 1 } }, // vpermb
2304 { TTI::SK_PermuteSingleSrc, MVT::v64i8, { 1, 1, 1, 1 } }, // vpermb
2305 { TTI::SK_PermuteSingleSrc, MVT::v32i8, { 1, 1, 1, 1 } }, // vpermb
2306 { TTI::SK_PermuteTwoSrc, MVT::v64i8, { 2, 2, 2, 2 } }, // vpermt2b
2307 { TTI::SK_PermuteTwoSrc, MVT::v32i8, { 2, 2, 2, 2 } }, // vpermt2b
2308 { TTI::SK_PermuteTwoSrc, MVT::v16i8, { 2, 2, 2, 2 } } // vpermt2b
2309 };
2310
2311 if (ST->hasVBMI())
2312 if (const auto *Entry =
2313 CostTableLookup(AVX512VBMIShuffleTbl, Kind, LT.second))
2314 if (auto KindCost = Entry->Cost[CostKind])
2315 return LT.first * *KindCost;
2316
2317 static const CostKindTblEntry AVX512BWShuffleTbl[] = {
2318 { TTI::SK_Broadcast, MVT::v32i16, { 1, 3, 1, 1 } }, // vpbroadcastw
2319 { TTI::SK_Broadcast, MVT::v32f16, { 1, 3, 1, 1 } }, // vpbroadcastw
2320 { TTI::SK_Broadcast, MVT::v64i8, { 1, 3, 1, 1 } }, // vpbroadcastb
2321
2322 { TTI::SK_Reverse, MVT::v32i16, { 2, 6, 2, 4 } }, // vpermw
2323 { TTI::SK_Reverse, MVT::v32f16, { 2, 6, 2, 4 } }, // vpermw
2324 { TTI::SK_Reverse, MVT::v16i16, { 2, 2, 2, 2 } }, // vpermw
2325 { TTI::SK_Reverse, MVT::v16f16, { 2, 2, 2, 2 } }, // vpermw
2326 { TTI::SK_Reverse, MVT::v64i8, { 2, 9, 2, 3 } }, // pshufb + vshufi64x2
2327
2328 { TTI::SK_PermuteSingleSrc, MVT::v32i16, { 2, 2, 2, 2 } }, // vpermw
2329 { TTI::SK_PermuteSingleSrc, MVT::v32f16, { 2, 2, 2, 2 } }, // vpermw
2330 { TTI::SK_PermuteSingleSrc, MVT::v16i16, { 2, 2, 2, 2 } }, // vpermw
2331 { TTI::SK_PermuteSingleSrc, MVT::v16f16, { 2, 2, 2, 2 } }, // vpermw
2332 { TTI::SK_PermuteSingleSrc, MVT::v64i8, { 8, 8, 8, 8 } }, // extend to v32i16
2333
2334 { TTI::SK_PermuteTwoSrc, MVT::v32i16,{ 2, 2, 2, 2 } }, // vpermt2w
2335 { TTI::SK_PermuteTwoSrc, MVT::v32f16,{ 2, 2, 2, 2 } }, // vpermt2w
2336 { TTI::SK_PermuteTwoSrc, MVT::v16i16,{ 2, 2, 2, 2 } }, // vpermt2w
2337 { TTI::SK_PermuteTwoSrc, MVT::v8i16, { 2, 2, 2, 2 } }, // vpermt2w
2338 { TTI::SK_PermuteTwoSrc, MVT::v64i8, { 19, 19, 19, 19 } }, // 6 * v32i8 + 1
2339
2340 { TTI::SK_Select, MVT::v32i16, { 1, 1, 1, 1 } }, // vblendmw
2341 { TTI::SK_Select, MVT::v64i8, { 1, 1, 1, 1 } }, // vblendmb
2342
2343 { TTI::SK_Splice, MVT::v32i16, { 2, 2, 2, 2 } }, // vshufi64x2 + palignr
2344 { TTI::SK_Splice, MVT::v32f16, { 2, 2, 2, 2 } }, // vshufi64x2 + palignr
2345 { TTI::SK_Splice, MVT::v64i8, { 2, 2, 2, 2 } }, // vshufi64x2 + palignr
2346 };
2347
2348 if (ST->hasBWI())
2349 if (const auto *Entry =
2350 CostTableLookup(AVX512BWShuffleTbl, Kind, LT.second))
2351 if (auto KindCost = Entry->Cost[CostKind])
2352 return LT.first * *KindCost;
2353
2354 static const CostKindTblEntry AVX512InLaneShuffleTbl[] = {
2355 {TTI::SK_PermuteTwoSrc, MVT::v8f64, { 1, 3, 1, 1 } },
2356 {TTI::SK_PermuteTwoSrc, MVT::v16f32, { 1, 3, 1, 1 } },
2357 {TTI::SK_PermuteTwoSrc, MVT::v8i64, { 1, 3, 1, 1 } },
2358 {TTI::SK_PermuteTwoSrc, MVT::v16i32, { 1, 3, 1, 1 } },
2359 {TTI::SK_PermuteTwoSrc, MVT::v4f64, { 1, 3, 1, 1 } },
2360 {TTI::SK_PermuteTwoSrc, MVT::v8f32, { 1, 3, 1, 1 } },
2361 {TTI::SK_PermuteTwoSrc, MVT::v4i64, { 1, 3, 1, 1 } },
2362 {TTI::SK_PermuteTwoSrc, MVT::v8i32, { 1, 3, 1, 1 } },
2363 };
2364
2365 if (IsInLaneShuffle && ST->hasAVX512())
2366 if (const auto *Entry =
2367 CostTableLookup(AVX512InLaneShuffleTbl, Kind, LT.second))
2368 if (auto KindCost = Entry->Cost[CostKind])
2369 return LT.first * *KindCost;
2370
2371 static const CostKindTblEntry AVX512ShuffleTbl[] = {
2372 {TTI::SK_Broadcast, MVT::v8f64, { 1, 3, 1, 1 } }, // vbroadcastsd
2373 {TTI::SK_Broadcast, MVT::v4f64, { 1, 3, 1, 1 } }, // vbroadcastsd
2374 {TTI::SK_Broadcast, MVT::v16f32, { 1, 3, 1, 1 } }, // vbroadcastss
2375 {TTI::SK_Broadcast, MVT::v8f32, { 1, 3, 1, 1 } }, // vbroadcastss
2376 {TTI::SK_Broadcast, MVT::v8i64, { 1, 3, 1, 1 } }, // vpbroadcastq
2377 {TTI::SK_Broadcast, MVT::v4i64, { 1, 3, 1, 1 } }, // vpbroadcastq
2378 {TTI::SK_Broadcast, MVT::v16i32, { 1, 3, 1, 1 } }, // vpbroadcastd
2379 {TTI::SK_Broadcast, MVT::v8i32, { 1, 3, 1, 1 } }, // vpbroadcastd
2380 {TTI::SK_Broadcast, MVT::v32i16, { 1, 3, 1, 1 } }, // vpbroadcastw
2381 {TTI::SK_Broadcast, MVT::v16i16, { 1, 3, 1, 1 } }, // vpbroadcastw
2382 {TTI::SK_Broadcast, MVT::v32f16, { 1, 3, 1, 1 } }, // vpbroadcastw
2383 {TTI::SK_Broadcast, MVT::v16f16, { 1, 3, 1, 1 } }, // vpbroadcastw
2384 {TTI::SK_Broadcast, MVT::v64i8, { 1, 3, 1, 1 } }, // vpbroadcastb
2385 {TTI::SK_Broadcast, MVT::v32i8, { 1, 3, 1, 1 }}, // vpbroadcastb
2386
2387 {TTI::SK_Reverse, MVT::v8f64, { 1, 5, 2, 3 } }, // vpermpd
2388 {TTI::SK_Reverse, MVT::v16f32, { 1, 3, 2, 3 } }, // vpermps
2389 {TTI::SK_Reverse, MVT::v8i64, { 1, 5, 2, 3 } }, // vpermq
2390 {TTI::SK_Reverse, MVT::v16i32, { 1, 3, 2, 3 } }, // vpermd
2391 {TTI::SK_Reverse, MVT::v32i16, { 7, 7, 7, 7 } }, // per mca
2392 {TTI::SK_Reverse, MVT::v32f16, { 7, 7, 7, 7 } }, // per mca
2393 {TTI::SK_Reverse, MVT::v64i8, { 7, 7, 7, 7 } }, // per mca
2394
2395 {TTI::SK_Splice, MVT::v8f64, { 1, 1, 1, 1 } }, // vpalignd
2396 {TTI::SK_Splice, MVT::v4f64, { 1, 1, 1, 1 } }, // vpalignd
2397 {TTI::SK_Splice, MVT::v16f32, { 1, 1, 1, 1 } }, // vpalignd
2398 {TTI::SK_Splice, MVT::v8f32, { 1, 1, 1, 1 } }, // vpalignd
2399 {TTI::SK_Splice, MVT::v8i64, { 1, 1, 1, 1 } }, // vpalignd
2400 {TTI::SK_Splice, MVT::v4i64, { 1, 1, 1, 1 } }, // vpalignd
2401 {TTI::SK_Splice, MVT::v16i32, { 1, 1, 1, 1 } }, // vpalignd
2402 {TTI::SK_Splice, MVT::v8i32, { 1, 1, 1, 1 } }, // vpalignd
2403 {TTI::SK_Splice, MVT::v32i16, { 4, 4, 4, 4 } }, // split + palignr
2404 {TTI::SK_Splice, MVT::v32f16, { 4, 4, 4, 4 } }, // split + palignr
2405 {TTI::SK_Splice, MVT::v64i8, { 4, 4, 4, 4 } }, // split + palignr
2406
2407 {TTI::SK_PermuteSingleSrc, MVT::v8f64, { 1, 3, 1, 1 } }, // vpermpd
2408 {TTI::SK_PermuteSingleSrc, MVT::v4f64, { 1, 3, 1, 1 } }, // vpermpd
2409 {TTI::SK_PermuteSingleSrc, MVT::v2f64, { 1, 3, 1, 1 } }, // vpermpd
2410 {TTI::SK_PermuteSingleSrc, MVT::v16f32, { 1, 3, 1, 1 } }, // vpermps
2411 {TTI::SK_PermuteSingleSrc, MVT::v8f32, { 1, 3, 1, 1 } }, // vpermps
2412 {TTI::SK_PermuteSingleSrc, MVT::v4f32, { 1, 3, 1, 1 } }, // vpermps
2413 {TTI::SK_PermuteSingleSrc, MVT::v8i64, { 1, 3, 1, 1 } }, // vpermq
2414 {TTI::SK_PermuteSingleSrc, MVT::v4i64, { 1, 3, 1, 1 } }, // vpermq
2415 {TTI::SK_PermuteSingleSrc, MVT::v2i64, { 1, 3, 1, 1 } }, // vpermq
2416 {TTI::SK_PermuteSingleSrc, MVT::v16i32, { 1, 3, 1, 1 } }, // vpermd
2417 {TTI::SK_PermuteSingleSrc, MVT::v8i32, { 1, 3, 1, 1 } }, // vpermd
2418 {TTI::SK_PermuteSingleSrc, MVT::v4i32, { 1, 3, 1, 1 } }, // vpermd
2419 {TTI::SK_PermuteSingleSrc, MVT::v16i8, { 1, 3, 1, 1 } }, // pshufb
2420
2421 {TTI::SK_PermuteTwoSrc, MVT::v8f64, { 2, 3, 1, 1 } }, // vpermt2pd
2422 {TTI::SK_PermuteTwoSrc, MVT::v16f32, { 2, 3, 1, 1 } }, // vpermt2ps
2423 {TTI::SK_PermuteTwoSrc, MVT::v8i64, { 2, 3, 1, 1 } }, // vpermt2q
2424 {TTI::SK_PermuteTwoSrc, MVT::v16i32, { 2, 3, 1, 1 } }, // vpermt2d
2425 {TTI::SK_PermuteTwoSrc, MVT::v4f64, { 2, 3, 1, 1 } }, // vpermt2pd
2426 {TTI::SK_PermuteTwoSrc, MVT::v8f32, { 2, 3, 1, 1 } }, // vpermt2ps
2427 {TTI::SK_PermuteTwoSrc, MVT::v4i64, { 2, 3, 1, 1 } }, // vpermt2q
2428 {TTI::SK_PermuteTwoSrc, MVT::v8i32, { 2, 3, 1, 1 } }, // vpermt2d
2429 {TTI::SK_PermuteTwoSrc, MVT::v2f64, { 1, 3, 1, 1 } },
2430 {TTI::SK_PermuteTwoSrc, MVT::v4f32, { 1, 3, 1, 1 } },
2431 {TTI::SK_PermuteTwoSrc, MVT::v2i64, { 1, 3, 1, 1 } },
2432 {TTI::SK_PermuteTwoSrc, MVT::v4i32, { 1, 3, 1, 1 } },
2433
2434 // FIXME: This just applies the type legalization cost rules above
2435 // assuming these completely split.
2436 {TTI::SK_PermuteSingleSrc, MVT::v32i16, { 14, 14, 14, 14 } },
2437 {TTI::SK_PermuteSingleSrc, MVT::v32f16, { 14, 14, 14, 14 } },
2438 {TTI::SK_PermuteSingleSrc, MVT::v64i8, { 14, 14, 14, 14 } },
2439 {TTI::SK_PermuteTwoSrc, MVT::v32i16, { 42, 42, 42, 42 } },
2440 {TTI::SK_PermuteTwoSrc, MVT::v32f16, { 42, 42, 42, 42 } },
2441 {TTI::SK_PermuteTwoSrc, MVT::v64i8, { 42, 42, 42, 42 } },
2442
2443 {TTI::SK_Select, MVT::v32i16, { 1, 1, 1, 1 } }, // vpternlogq
2444 {TTI::SK_Select, MVT::v32f16, { 1, 1, 1, 1 } }, // vpternlogq
2445 {TTI::SK_Select, MVT::v64i8, { 1, 1, 1, 1 } }, // vpternlogq
2446 {TTI::SK_Select, MVT::v8f64, { 1, 1, 1, 1 } }, // vblendmpd
2447 {TTI::SK_Select, MVT::v16f32, { 1, 1, 1, 1 } }, // vblendmps
2448 {TTI::SK_Select, MVT::v8i64, { 1, 1, 1, 1 } }, // vblendmq
2449 {TTI::SK_Select, MVT::v16i32, { 1, 1, 1, 1 } }, // vblendmd
2450 };
2451
2452 if (ST->hasAVX512())
2453 if (const auto *Entry = CostTableLookup(AVX512ShuffleTbl, Kind, LT.second))
2454 if (auto KindCost = Entry->Cost[CostKind])
2455 return LT.first * *KindCost;
2456
2457 static const CostKindTblEntry AVX2InLaneShuffleTbl[] = {
2458 { TTI::SK_PermuteSingleSrc, MVT::v16i16, { 1, 1, 1, 1 } }, // vpshufb
2459 { TTI::SK_PermuteSingleSrc, MVT::v16f16, { 1, 1, 1, 1 } }, // vpshufb
2460 { TTI::SK_PermuteSingleSrc, MVT::v32i8, { 1, 1, 1, 1 } }, // vpshufb
2461
2462 { TTI::SK_Transpose, MVT::v4f64, { 1, 1, 1, 1 } }, // vshufpd/vunpck
2463 { TTI::SK_Transpose, MVT::v4i64, { 1, 1, 1, 1 } }, // vshufpd/vunpck
2464
2465 { TTI::SK_PermuteTwoSrc, MVT::v4f64, { 2, 2, 2, 2 } }, // 2*vshufpd + vblendpd
2466 { TTI::SK_PermuteTwoSrc, MVT::v8f32, { 2, 2, 2, 2 } }, // 2*vshufps + vblendps
2467 { TTI::SK_PermuteTwoSrc, MVT::v4i64, { 2, 2, 2, 2 } }, // 2*vpshufd + vpblendd
2468 { TTI::SK_PermuteTwoSrc, MVT::v8i32, { 2, 2, 2, 2 } }, // 2*vpshufd + vpblendd
2469 { TTI::SK_PermuteTwoSrc, MVT::v16i16, { 2, 2, 2, 2 } }, // 2*vpshufb + vpor
2470 { TTI::SK_PermuteTwoSrc, MVT::v16f16, { 2, 2, 2, 2 } }, // 2*vpshufb + vpor
2471 { TTI::SK_PermuteTwoSrc, MVT::v32i8, { 2, 2, 2, 2 } }, // 2*vpshufb + vpor
2472 };
2473
2474 if (IsInLaneShuffle && ST->hasAVX2())
2475 if (const auto *Entry =
2476 CostTableLookup(AVX2InLaneShuffleTbl, Kind, LT.second))
2477 if (auto KindCost = Entry->Cost[CostKind])
2478 return LT.first * *KindCost;
2479
2480 static const CostKindTblEntry AVX2ShuffleTbl[] = {
2481 { TTI::SK_Broadcast, MVT::v4f64, { 1, 3, 1, 2 } }, // vbroadcastpd
2482 { TTI::SK_Broadcast, MVT::v8f32, { 1, 3, 1, 2 } }, // vbroadcastps
2483 { TTI::SK_Broadcast, MVT::v4i64, { 1, 3, 1, 2 } }, // vpbroadcastq
2484 { TTI::SK_Broadcast, MVT::v8i32, { 1, 3, 1, 2 } }, // vpbroadcastd
2485 { TTI::SK_Broadcast, MVT::v16i16, { 1, 3, 1, 2 } }, // vpbroadcastw
2486 { TTI::SK_Broadcast, MVT::v8i16, { 1, 3, 1, 1 } }, // vpbroadcastw
2487 { TTI::SK_Broadcast, MVT::v16f16, { 1, 3, 1, 2 } }, // vpbroadcastw
2488 { TTI::SK_Broadcast, MVT::v8f16, { 1, 3, 1, 1 } }, // vpbroadcastw
2489 { TTI::SK_Broadcast, MVT::v32i8, { 1, 3, 1, 2 } }, // vpbroadcastb
2490 { TTI::SK_Broadcast, MVT::v16i8, { 1, 3, 1, 1 } }, // vpbroadcastb
2491
2492 { TTI::SK_Reverse, MVT::v4f64, { 1, 6, 1, 2 } }, // vpermpd
2493 { TTI::SK_Reverse, MVT::v8f32, { 2, 7, 2, 4 } }, // vpermps
2494 { TTI::SK_Reverse, MVT::v4i64, { 1, 6, 1, 2 } }, // vpermq
2495 { TTI::SK_Reverse, MVT::v8i32, { 2, 7, 2, 4 } }, // vpermd
2496 { TTI::SK_Reverse, MVT::v16i16, { 2, 9, 2, 4 } }, // vperm2i128 + pshufb
2497 { TTI::SK_Reverse, MVT::v16f16, { 2, 9, 2, 4 } }, // vperm2i128 + pshufb
2498 { TTI::SK_Reverse, MVT::v32i8, { 2, 9, 2, 4 } }, // vperm2i128 + pshufb
2499
2500 { TTI::SK_Select, MVT::v16i16, { 1, 1, 1, 1 } }, // vpblendvb
2501 { TTI::SK_Select, MVT::v16f16, { 1, 1, 1, 1 } }, // vpblendvb
2502 { TTI::SK_Select, MVT::v32i8, { 1, 1, 1, 1 } }, // vpblendvb
2503
2504 { TTI::SK_Splice, MVT::v8i32, { 2, 2, 2, 2 } }, // vperm2i128 + vpalignr
2505 { TTI::SK_Splice, MVT::v8f32, { 2, 2, 2, 2 } }, // vperm2i128 + vpalignr
2506 { TTI::SK_Splice, MVT::v16i16, { 2, 2, 2, 2 } }, // vperm2i128 + vpalignr
2507 { TTI::SK_Splice, MVT::v16f16, { 2, 2, 2, 2 } }, // vperm2i128 + vpalignr
2508 { TTI::SK_Splice, MVT::v32i8, { 2, 2, 2, 2 } }, // vperm2i128 + vpalignr
2509
2510 { TTI::SK_PermuteSingleSrc, MVT::v4f64, { 1, 1, 1, 1 } }, // vpermpd
2511 { TTI::SK_PermuteSingleSrc, MVT::v8f32, { 1, 1, 1, 1 } }, // vpermps
2512 { TTI::SK_PermuteSingleSrc, MVT::v4i64, { 1, 1, 1, 1 } }, // vpermq
2513 { TTI::SK_PermuteSingleSrc, MVT::v8i32, { 1, 1, 1, 1 } }, // vpermd
2514 { TTI::SK_PermuteSingleSrc, MVT::v16i16, { 4, 4, 4, 4 } },
2515 { TTI::SK_PermuteSingleSrc, MVT::v16f16, { 4, 4, 4, 4 } },
2516 { TTI::SK_PermuteSingleSrc, MVT::v32i8, { 4, 4, 4, 4 } },
2517
2518 { TTI::SK_PermuteTwoSrc, MVT::v4f64, { 3, 3, 3, 3 } }, // 2*vpermpd + vblendpd
2519 { TTI::SK_PermuteTwoSrc, MVT::v8f32, { 3, 3, 3, 3 } }, // 2*vpermps + vblendps
2520 { TTI::SK_PermuteTwoSrc, MVT::v4i64, { 3, 3, 3, 3 } }, // 2*vpermq + vpblendd
2521 { TTI::SK_PermuteTwoSrc, MVT::v8i32, { 3, 3, 3, 3 } }, // 2*vpermd + vpblendd
2522 { TTI::SK_PermuteTwoSrc, MVT::v16i16, { 7, 7, 7, 7 } },
2523 { TTI::SK_PermuteTwoSrc, MVT::v16f16, { 7, 7, 7, 7 } },
2524 { TTI::SK_PermuteTwoSrc, MVT::v32i8, { 7, 7, 7, 7 } },
2525 };
2526
2527 if (ST->hasAVX2())
2528 if (const auto *Entry = CostTableLookup(AVX2ShuffleTbl, Kind, LT.second))
2529 if (auto KindCost = Entry->Cost[CostKind])
2530 return LT.first * *KindCost;
2531
2532 static const CostKindTblEntry XOPShuffleTbl[] = {
2533 { TTI::SK_PermuteSingleSrc, MVT::v4f64, { 2, 2, 2, 2 } }, // vperm2f128 + vpermil2pd
2534 { TTI::SK_PermuteSingleSrc, MVT::v8f32, { 2, 2, 2, 2 } }, // vperm2f128 + vpermil2ps
2535 { TTI::SK_PermuteSingleSrc, MVT::v4i64, { 2, 2, 2, 2 } }, // vperm2f128 + vpermil2pd
2536 { TTI::SK_PermuteSingleSrc, MVT::v8i32, { 2, 2, 2, 2 } }, // vperm2f128 + vpermil2ps
2537 { TTI::SK_PermuteSingleSrc, MVT::v16i16,{ 4, 4, 4, 4 } }, // vextractf128 + 2*vpperm
2538 // + vinsertf128
2539 { TTI::SK_PermuteSingleSrc, MVT::v32i8, { 4, 4, 4, 4 } }, // vextractf128 + 2*vpperm
2540 // + vinsertf128
2541
2542 { TTI::SK_PermuteTwoSrc, MVT::v16i16, { 9, 9, 9, 9 } }, // 2*vextractf128 + 6*vpperm
2543 // + vinsertf128
2544
2545 { TTI::SK_PermuteTwoSrc, MVT::v8i16, { 1, 1, 1, 1 } }, // vpperm
2546 { TTI::SK_PermuteTwoSrc, MVT::v32i8, { 9, 9, 9, 9 } }, // 2*vextractf128 + 6*vpperm
2547 // + vinsertf128
2548 { TTI::SK_PermuteTwoSrc, MVT::v16i8, { 1, 1, 1, 1 } }, // vpperm
2549 };
2550
2551 if (ST->hasXOP())
2552 if (const auto *Entry = CostTableLookup(XOPShuffleTbl, Kind, LT.second))
2553 if (auto KindCost = Entry->Cost[CostKind])
2554 return LT.first * *KindCost;
2555
2556 static const CostKindTblEntry AVX1InLaneShuffleTbl[] = {
2557 { TTI::SK_PermuteSingleSrc, MVT::v4f64, { 1, 1, 1, 1 } }, // vpermilpd
2558 { TTI::SK_PermuteSingleSrc, MVT::v4i64, { 1, 1, 1, 1 } }, // vpermilpd
2559 { TTI::SK_PermuteSingleSrc, MVT::v8f32, { 1, 1, 1, 1 } }, // vpermilps
2560 { TTI::SK_PermuteSingleSrc, MVT::v8i32, { 1, 1, 1, 1 } }, // vpermilps
2561
2562 { TTI::SK_PermuteSingleSrc, MVT::v16i16, { 4, 4, 4, 4 } }, // vextractf128 + 2*pshufb
2563 // + vpor + vinsertf128
2564 { TTI::SK_PermuteSingleSrc, MVT::v16f16, { 4, 4, 4, 4 } }, // vextractf128 + 2*pshufb
2565 // + vpor + vinsertf128
2566 { TTI::SK_PermuteSingleSrc, MVT::v32i8, { 4, 4, 4, 4 } }, // vextractf128 + 2*pshufb
2567 // + vpor + vinsertf128
2568
2569 { TTI::SK_Transpose, MVT::v4f64, { 1, 1, 1, 1 } }, // vshufpd/vunpck
2570 { TTI::SK_Transpose, MVT::v4i64, { 1, 1, 1, 1 } }, // vshufpd/vunpck
2571
2572 { TTI::SK_PermuteTwoSrc, MVT::v4f64, { 2, 2, 2, 2 } }, // 2*vshufpd + vblendpd
2573 { TTI::SK_PermuteTwoSrc, MVT::v8f32, { 2, 2, 2, 2 } }, // 2*vshufps + vblendps
2574 { TTI::SK_PermuteTwoSrc, MVT::v4i64, { 2, 2, 2, 2 } }, // 2*vpermilpd + vblendpd
2575 { TTI::SK_PermuteTwoSrc, MVT::v8i32, { 2, 2, 2, 2 } }, // 2*vpermilps + vblendps
2576 { TTI::SK_PermuteTwoSrc, MVT::v16i16, { 9, 9, 9, 9 } }, // 2*vextractf128 + 4*pshufb
2577 // + 2*vpor + vinsertf128
2578 { TTI::SK_PermuteTwoSrc, MVT::v16f16, { 9, 9, 9, 9 } }, // 2*vextractf128 + 4*pshufb
2579 // + 2*vpor + vinsertf128
2580 { TTI::SK_PermuteTwoSrc, MVT::v32i8, { 9, 9, 9, 9 } }, // 2*vextractf128 + 4*pshufb
2581 // + 2*vpor + vinsertf128
2582 };
2583
2584 if (IsInLaneShuffle && ST->hasAVX())
2585 if (const auto *Entry =
2586 CostTableLookup(AVX1InLaneShuffleTbl, Kind, LT.second))
2587 if (auto KindCost = Entry->Cost[CostKind])
2588 return LT.first * *KindCost;
2589
2590 static const CostKindTblEntry AVX1ShuffleTbl[] = {
2591 {TTI::SK_Broadcast, MVT::v4f64, {2,3,2,3}}, // vperm2f128 + vpermilpd
2592 {TTI::SK_Broadcast, MVT::v8f32, {2,3,2,3}}, // vperm2f128 + vpermilps
2593 {TTI::SK_Broadcast, MVT::v4i64, {2,3,2,3}}, // vperm2f128 + vpermilpd
2594 {TTI::SK_Broadcast, MVT::v8i32, {2,3,2,3}}, // vperm2f128 + vpermilps
2595 {TTI::SK_Broadcast, MVT::v16i16, {2,3,3,4}}, // vpshuflw + vpshufd + vinsertf128
2596 {TTI::SK_Broadcast, MVT::v16f16, {2,3,3,4}}, // vpshuflw + vpshufd + vinsertf128
2597 {TTI::SK_Broadcast, MVT::v32i8, {3,4,3,6}}, // vpshufb + vinsertf128
2598
2599 {TTI::SK_Reverse, MVT::v4f64, {2,6,2,2}}, // vperm2f128 + vpermilpd
2600 {TTI::SK_Reverse, MVT::v8f32, {2,7,2,4}}, // vperm2f128 + vpermilps
2601 {TTI::SK_Reverse, MVT::v4i64, {2,6,2,2}}, // vperm2f128 + vpermilpd
2602 {TTI::SK_Reverse, MVT::v8i32, {2,7,2,4}}, // vperm2f128 + vpermilps
2603 {TTI::SK_Reverse, MVT::v16i16, {2,9,5,5}}, // vextractf128 + 2*pshufb
2604 // + vinsertf128
2605 {TTI::SK_Reverse, MVT::v16f16, {2,9,5,5}}, // vextractf128 + 2*pshufb
2606 // + vinsertf128
2607 {TTI::SK_Reverse, MVT::v32i8, {2,9,5,5}}, // vextractf128 + 2*pshufb
2608 // + vinsertf128
2609
2610 {TTI::SK_Select, MVT::v4i64, {1,1,1,1}}, // vblendpd
2611 {TTI::SK_Select, MVT::v4f64, {1,1,1,1}}, // vblendpd
2612 {TTI::SK_Select, MVT::v8i32, {1,1,1,1}}, // vblendps
2613 {TTI::SK_Select, MVT::v8f32, {1,1,1,1}}, // vblendps
2614 {TTI::SK_Select, MVT::v16i16, {3,3,3,3}}, // vpand + vpandn + vpor
2615 {TTI::SK_Select, MVT::v16f16, {3,3,3,3}}, // vpand + vpandn + vpor
2616 {TTI::SK_Select, MVT::v32i8, {3,3,3,3}}, // vpand + vpandn + vpor
2617
2618 {TTI::SK_Splice, MVT::v4i64, {2,2,2,2}}, // vperm2f128 + shufpd
2619 {TTI::SK_Splice, MVT::v4f64, {2,2,2,2}}, // vperm2f128 + shufpd
2620 {TTI::SK_Splice, MVT::v8i32, {4,4,4,4}}, // 2*vperm2f128 + 2*vshufps
2621 {TTI::SK_Splice, MVT::v8f32, {4,4,4,4}}, // 2*vperm2f128 + 2*vshufps
2622 {TTI::SK_Splice, MVT::v16i16, {5,5,5,5}}, // 2*vperm2f128 + 2*vpalignr + vinsertf128
2623 {TTI::SK_Splice, MVT::v16f16, {5,5,5,5}}, // 2*vperm2f128 + 2*vpalignr + vinsertf128
2624 {TTI::SK_Splice, MVT::v32i8, {5,5,5,5}}, // 2*vperm2f128 + 2*vpalignr + vinsertf128
2625
2626 {TTI::SK_PermuteSingleSrc, MVT::v4f64, {2,2,2,2}}, // vperm2f128 + vshufpd
2627 {TTI::SK_PermuteSingleSrc, MVT::v4i64, {2,2,2,2}}, // vperm2f128 + vshufpd
2628 {TTI::SK_PermuteSingleSrc, MVT::v8f32, {4,4,4,4}}, // 2*vperm2f128 + 2*vshufps
2629 {TTI::SK_PermuteSingleSrc, MVT::v8i32, {4,4,4,4}}, // 2*vperm2f128 + 2*vshufps
2630 {TTI::SK_PermuteSingleSrc, MVT::v16i16,{8,8,8,8}}, // vextractf128 + 4*pshufb
2631 // + 2*por + vinsertf128
2632 {TTI::SK_PermuteSingleSrc, MVT::v16f16,{8,8,8,8}}, // vextractf128 + 4*pshufb
2633 // + 2*por + vinsertf128
2634 {TTI::SK_PermuteSingleSrc, MVT::v32i8, {8,8,8,8}}, // vextractf128 + 4*pshufb
2635 // + 2*por + vinsertf128
2636
2637 {TTI::SK_PermuteTwoSrc, MVT::v4f64, {3,3,3,3}}, // 2*vperm2f128 + vshufpd
2638 {TTI::SK_PermuteTwoSrc, MVT::v4i64, {3,3,3,3}}, // 2*vperm2f128 + vshufpd
2639 {TTI::SK_PermuteTwoSrc, MVT::v8f32, {4,4,4,4}}, // 2*vperm2f128 + 2*vshufps
2640 {TTI::SK_PermuteTwoSrc, MVT::v8i32, {4,4,4,4}}, // 2*vperm2f128 + 2*vshufps
2641 {TTI::SK_PermuteTwoSrc, MVT::v16i16,{15,15,15,15}}, // 2*vextractf128 + 8*pshufb
2642 // + 4*por + vinsertf128
2643 {TTI::SK_PermuteTwoSrc, MVT::v16f16,{15,15,15,15}}, // 2*vextractf128 + 8*pshufb
2644 // + 4*por + vinsertf128
2645 {TTI::SK_PermuteTwoSrc, MVT::v32i8, {15,15,15,15}}, // 2*vextractf128 + 8*pshufb
2646 // + 4*por + vinsertf128
2647 };
2648
2649 if (ST->hasAVX())
2650 if (const auto *Entry = CostTableLookup(AVX1ShuffleTbl, Kind, LT.second))
2651 if (auto KindCost = Entry->Cost[CostKind])
2652 return LT.first * *KindCost;
2653
2654 static const CostKindTblEntry SSE41ShuffleTbl[] = {
2655 {TTI::SK_Select, MVT::v2i64, {1,1,1,1}}, // pblendw
2656 {TTI::SK_Select, MVT::v2f64, {1,1,1,1}}, // movsd
2657 {TTI::SK_Select, MVT::v4i32, {1,1,1,1}}, // pblendw
2658 {TTI::SK_Select, MVT::v4f32, {1,1,1,1}}, // blendps
2659 {TTI::SK_Select, MVT::v8i16, {1,1,1,1}}, // pblendw
2660 {TTI::SK_Select, MVT::v8f16, {1,1,1,1}}, // pblendw
2661 {TTI::SK_Select, MVT::v16i8, {1,1,1,1}} // pblendvb
2662 };
2663
2664 if (ST->hasSSE41())
2665 if (const auto *Entry = CostTableLookup(SSE41ShuffleTbl, Kind, LT.second))
2666 if (auto KindCost = Entry->Cost[CostKind])
2667 return LT.first * *KindCost;
2668
2669 static const CostKindTblEntry SSSE3ShuffleTbl[] = {
2670 {TTI::SK_Broadcast, MVT::v8i16, {1, 3, 2, 2}}, // pshufb
2671 {TTI::SK_Broadcast, MVT::v8f16, {1, 3, 2, 2}}, // pshufb
2672 {TTI::SK_Broadcast, MVT::v16i8, {1, 3, 2, 2}}, // pshufb
2673
2674 {TTI::SK_Reverse, MVT::v8i16, {1, 2, 1, 2}}, // pshufb
2675 {TTI::SK_Reverse, MVT::v8f16, {1, 2, 1, 2}}, // pshufb
2676 {TTI::SK_Reverse, MVT::v16i8, {1, 2, 1, 2}}, // pshufb
2677
2678 {TTI::SK_Splice, MVT::v4i32, {1, 1, 1, 1}}, // palignr
2679 {TTI::SK_Splice, MVT::v4f32, {1, 1, 1, 1}}, // palignr
2680 {TTI::SK_Splice, MVT::v8i16, {1, 1, 1, 1}}, // palignr
2681 {TTI::SK_Splice, MVT::v8f16, {1, 1, 1, 1}}, // palignr
2682 {TTI::SK_Splice, MVT::v16i8, {1, 1, 1, 1}}, // palignr
2683
2684 {TTI::SK_PermuteSingleSrc, MVT::v8i16, {1, 1, 1, 1}}, // pshufb
2685 {TTI::SK_PermuteSingleSrc, MVT::v8f16, {1, 1, 1, 1}}, // pshufb
2686 {TTI::SK_PermuteSingleSrc, MVT::v16i8, {1, 1, 1, 1}}, // pshufb
2687
2688 {TTI::SK_PermuteTwoSrc, MVT::v8i16, {3, 3, 3, 3}}, // 2*pshufb + por
2689 {TTI::SK_PermuteTwoSrc, MVT::v8f16, {3, 3, 3, 3}}, // 2*pshufb + por
2690 {TTI::SK_PermuteTwoSrc, MVT::v16i8, {3, 3, 3, 3}}, // 2*pshufb + por
2691 };
2692
2693 if (ST->hasSSSE3())
2694 if (const auto *Entry = CostTableLookup(SSSE3ShuffleTbl, Kind, LT.second))
2695 if (auto KindCost = Entry->Cost[CostKind])
2696 return LT.first * *KindCost;
2697
2698 static const CostKindTblEntry SSE2ShuffleTbl[] = {
2699 {TTI::SK_Broadcast, MVT::v2f64, {1, 1, 1, 1}}, // shufpd
2700 {TTI::SK_Broadcast, MVT::v2i64, {1, 1, 1, 1}}, // pshufd
2701 {TTI::SK_Broadcast, MVT::v4i32, {1, 1, 1, 1}}, // pshufd
2702 {TTI::SK_Broadcast, MVT::v8i16, {1, 2, 2, 2}}, // pshuflw + pshufd
2703 {TTI::SK_Broadcast, MVT::v8f16, {1, 2, 2, 2}}, // pshuflw + pshufd
2704 {TTI::SK_Broadcast, MVT::v16i8, {2, 3, 3, 4}}, // unpck + pshuflw + pshufd
2705
2706 {TTI::SK_Reverse, MVT::v2f64, {1, 1, 1, 1}}, // shufpd
2707 {TTI::SK_Reverse, MVT::v2i64, {1, 1, 1, 1}}, // pshufd
2708 {TTI::SK_Reverse, MVT::v4i32, {1, 1, 1, 1}}, // pshufd
2709 {TTI::SK_Reverse, MVT::v8i16, {2, 3, 3, 3}}, // pshuflw + pshufhw + pshufd
2710 {TTI::SK_Reverse, MVT::v8f16, {2, 3, 3, 3}}, // pshuflw + pshufhw + pshufd
2711 {TTI::SK_Reverse, MVT::v16i8, {5, 6,11,11}}, // 2*pshuflw + 2*pshufhw
2712 // + 2*pshufd + 2*unpck + packus
2713
2714 {TTI::SK_Select, MVT::v2i64, {1, 1, 1, 1}}, // movsd
2715 {TTI::SK_Select, MVT::v2f64, {1, 1, 1, 1}}, // movsd
2716 {TTI::SK_Select, MVT::v4i32, {2, 2, 2, 2}}, // 2*shufps
2717 {TTI::SK_Select, MVT::v8i16, {2, 2, 3, 3}}, // pand + pandn + por
2718 {TTI::SK_Select, MVT::v8f16, {2, 2, 3, 3}}, // pand + pandn + por
2719 {TTI::SK_Select, MVT::v16i8, {2, 2, 3, 3}}, // pand + pandn + por
2720
2721 {TTI::SK_Splice, MVT::v2i64, {1, 1, 1, 1}}, // shufpd
2722 {TTI::SK_Splice, MVT::v2f64, {1, 1, 1, 1}}, // shufpd
2723 {TTI::SK_Splice, MVT::v4i32, {2, 2, 2, 2}}, // 2*{unpck,movsd,pshufd}
2724 {TTI::SK_Splice, MVT::v8i16, {3, 3, 3, 3}}, // psrldq + psrlldq + por
2725 {TTI::SK_Splice, MVT::v8f16, {3, 3, 3, 3}}, // psrldq + psrlldq + por
2726 {TTI::SK_Splice, MVT::v16i8, {3, 3, 3, 3}}, // psrldq + psrlldq + por
2727
2728 {TTI::SK_PermuteSingleSrc, MVT::v2f64, {1, 1, 1, 1}}, // shufpd
2729 {TTI::SK_PermuteSingleSrc, MVT::v2i64, {1, 1, 1, 1}}, // pshufd
2730 {TTI::SK_PermuteSingleSrc, MVT::v4i32, {1, 1, 1, 1}}, // pshufd
2731 {TTI::SK_PermuteSingleSrc, MVT::v8i16, {3, 5, 5, 5}}, // 2*pshuflw + 2*pshufhw
2732 // + pshufd/unpck
2733 {TTI::SK_PermuteSingleSrc, MVT::v8f16, {3, 5, 5, 5}}, // 2*pshuflw + 2*pshufhw
2734 // + pshufd/unpck
2735 {TTI::SK_PermuteSingleSrc, MVT::v16i8, {8, 10, 10, 10}}, // 2*pshuflw + 2*pshufhw
2736 // + 2*pshufd + 2*unpck + 2*packus
2737
2738 {TTI::SK_PermuteTwoSrc, MVT::v2f64, {1, 1, 1, 1}}, // shufpd
2739 {TTI::SK_PermuteTwoSrc, MVT::v2i64, {1, 1, 1, 1}}, // shufpd
2740 {TTI::SK_PermuteTwoSrc, MVT::v4i32, {2, 2, 2, 2}}, // 2*{unpck,movsd,pshufd}
2741 {TTI::SK_PermuteTwoSrc, MVT::v8i16, {6, 8, 8, 8}}, // blend+permute
2742 {TTI::SK_PermuteTwoSrc, MVT::v8f16, {6, 8, 8, 8}}, // blend+permute
2743 {TTI::SK_PermuteTwoSrc, MVT::v16i8, {11, 13, 13, 13}}, // blend+permute
2744 };
2745
2746 static const CostTblEntry SSE3BroadcastLoadTbl[] = {
2747 {TTI::SK_Broadcast, MVT::v2f64, 0}, // broadcast handled by movddup
2748 };
2749
2750 if (ST->hasSSE2()) {
2751 bool IsLoad =
2752 llvm::any_of(Args, [](const auto &V) { return isa<LoadInst>(V); });
2753 if (ST->hasSSE3() && IsLoad)
2754 if (const auto *Entry =
2755 CostTableLookup(SSE3BroadcastLoadTbl, Kind, LT.second)) {
2756 assert(isLegalBroadcastLoad(SrcTy->getElementType(),
2757 LT.second.getVectorElementCount()) &&
2758 "Table entry missing from isLegalBroadcastLoad()");
2759 return LT.first * Entry->Cost;
2760 }
2761
2762 if (const auto *Entry = CostTableLookup(SSE2ShuffleTbl, Kind, LT.second))
2763 if (auto KindCost = Entry->Cost[CostKind])
2764 return LT.first * *KindCost;
2765 }
2766
2767 static const CostKindTblEntry SSE1ShuffleTbl[] = {
2768 { TTI::SK_Broadcast, MVT::v4f32, {1,1,1,1} }, // shufps
2769 { TTI::SK_Reverse, MVT::v4f32, {1,1,1,1} }, // shufps
2770 { TTI::SK_Select, MVT::v4f32, {2,2,2,2} }, // 2*shufps
2771 { TTI::SK_Splice, MVT::v4f32, {2,2,2,2} }, // 2*shufps
2772 { TTI::SK_PermuteSingleSrc, MVT::v4f32, {1,1,1,1} }, // shufps
2773 { TTI::SK_PermuteTwoSrc, MVT::v4f32, {2,2,2,2} }, // 2*shufps
2774 };
2775
2776 if (ST->hasSSE1()) {
2777 if (LT.first == 1 && LT.second == MVT::v4f32 && Mask.size() == 4) {
2778 // SHUFPS: both pairs must come from the same source register.
2779 auto MatchSHUFPS = [](int X, int Y) {
2780 return X < 0 || Y < 0 || ((X & 4) == (Y & 4));
2781 };
2782 if (MatchSHUFPS(Mask[0], Mask[1]) && MatchSHUFPS(Mask[2], Mask[3]))
2783 return 1;
2784 }
2785 if (const auto *Entry = CostTableLookup(SSE1ShuffleTbl, Kind, LT.second))
2786 if (auto KindCost = Entry->Cost[CostKind])
2787 return LT.first * *KindCost;
2788 }
2789
2790 return BaseT::getShuffleCost(Kind, DstTy, SrcTy, CostKind, Mask, Index,
2791 SubTp);
2792}
2793
2795 Type *Src,
2798 const Instruction *I) const {
2799 int ISD = TLI->InstructionOpcodeToISD(Opcode);
2800 assert(ISD && "Invalid opcode");
2801
2802 // A narrow (i8/i16) zero-extension used as a GEP *index* can be folded into
2803 // the addressing mode of the consuming memory op, but only if the source is
2804 // already materialised zero-extended in a full register. X86's SIB form
2805 // [base + index*scale + disp] reads the index at full width and does NOT
2806 // zero-extend a narrow index (unlike AArch64's uxtw-extended addressing), so
2807 // a "dirty" narrow source (e.g. an i16 add result used only as an index)
2808 // still needs a dedicated movzx and is not free. Price it as free only with
2809 // positive evidence that no movzx is required.
2810 if (ISD == ISD::ZERO_EXTEND && I && I->hasOneUse() && Src->isIntegerTy() &&
2811 Src->getScalarSizeInBits() < 32) {
2812 const Use &U = *I->use_begin();
2813 if (isa<GetElementPtrInst>(U.getUser()) &&
2814 U.getOperandNo() != GetElementPtrInst::getPointerOperandIndex()) {
2815 const Value *Op = I->getOperand(0);
2816 // Clean sources: an extending load, a zeroext argument, or a value whose
2817 // high bits are provably zero (e.g. from a shift/mask). These mirror the
2818 // proof-based reasoning the middle end uses elsewhere (ValueTracking and
2819 // InstCombine's canEvaluateZExtd); we intentionally do NOT treat a merely
2820 // multiply-used operand as clean, since that is a guess rather than
2821 // proof.
2822 if (isa<LoadInst>(Op))
2823 return TTI::TCC_Free;
2824 if (const auto *A = dyn_cast<Argument>(Op))
2825 if (A->hasAttribute(Attribute::ZExt))
2826 return TTI::TCC_Free;
2827 if (computeKnownBits(Op, I->getDataLayout(), /*AC=*/nullptr, I)
2828 .countMinLeadingZeros() > 0)
2829 return TTI::TCC_Free;
2830 }
2831 }
2832
2833 // The cost tables include both specific, custom (non-legal) src/dst type
2834 // conversions and generic, legalized types. We test for customs first, before
2835 // falling back to legalization.
2836 // FIXME: Need a better design of the cost table to handle non-simple types of
2837 // potential massive combinations (elem_num x src_type x dst_type).
2838 static const TypeConversionCostKindTblEntry AVX512BWConversionTbl[]{
2839 { ISD::SIGN_EXTEND, MVT::v32i16, MVT::v32i8, { 1, 1, 1, 1 } },
2840 { ISD::ZERO_EXTEND, MVT::v32i16, MVT::v32i8, { 1, 1, 1, 1 } },
2841
2842 // Mask sign extend has an instruction.
2843 { ISD::SIGN_EXTEND, MVT::v2i8, MVT::v2i1, { 1, 1, 1, 1 } },
2844 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v2i1, { 1, 1, 1, 1 } },
2845 { ISD::SIGN_EXTEND, MVT::v2i16, MVT::v2i1, { 1, 1, 1, 1 } },
2846 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v2i1, { 1, 1, 1, 1 } },
2847 { ISD::SIGN_EXTEND, MVT::v4i8, MVT::v4i1, { 1, 1, 1, 1 } },
2848 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v4i1, { 1, 1, 1, 1 } },
2849 { ISD::SIGN_EXTEND, MVT::v4i16, MVT::v4i1, { 1, 1, 1, 1 } },
2850 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v4i1, { 1, 1, 1, 1 } },
2851 { ISD::SIGN_EXTEND, MVT::v8i8, MVT::v8i1, { 1, 1, 1, 1 } },
2852 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v8i1, { 1, 1, 1, 1 } },
2853 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v8i1, { 1, 1, 1, 1 } },
2854 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v16i1, { 1, 1, 1, 1 } },
2855 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i1, { 1, 1, 1, 1 } },
2856 { ISD::SIGN_EXTEND, MVT::v32i8, MVT::v32i1, { 1, 1, 1, 1 } },
2857 { ISD::SIGN_EXTEND, MVT::v32i16, MVT::v32i1, { 1, 1, 1, 1 } },
2858 { ISD::SIGN_EXTEND, MVT::v64i8, MVT::v64i1, { 1, 1, 1, 1 } },
2859 { ISD::SIGN_EXTEND, MVT::v32i16, MVT::v64i1, { 1, 1, 1, 1 } },
2860
2861 // Mask zero extend is a sext + shift.
2862 { ISD::ZERO_EXTEND, MVT::v2i8, MVT::v2i1, { 2, 1, 1, 1 } },
2863 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v2i1, { 2, 1, 1, 1 } },
2864 { ISD::ZERO_EXTEND, MVT::v2i16, MVT::v2i1, { 2, 1, 1, 1 } },
2865 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v2i1, { 2, 1, 1, 1 } },
2866 { ISD::ZERO_EXTEND, MVT::v4i8, MVT::v4i1, { 2, 1, 1, 1 } },
2867 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v4i1, { 2, 1, 1, 1 } },
2868 { ISD::ZERO_EXTEND, MVT::v4i16, MVT::v4i1, { 2, 1, 1, 1 } },
2869 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v4i1, { 2, 1, 1, 1 } },
2870 { ISD::ZERO_EXTEND, MVT::v8i8, MVT::v8i1, { 2, 1, 1, 1 } },
2871 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v8i1, { 2, 1, 1, 1 } },
2872 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v8i1, { 2, 1, 1, 1 } },
2873 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v16i1, { 2, 1, 1, 1 } },
2874 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i1, { 2, 1, 1, 1 } },
2875 { ISD::ZERO_EXTEND, MVT::v32i8, MVT::v32i1, { 2, 1, 1, 1 } },
2876 { ISD::ZERO_EXTEND, MVT::v32i16, MVT::v32i1, { 2, 1, 1, 1 } },
2877 { ISD::ZERO_EXTEND, MVT::v64i8, MVT::v64i1, { 2, 1, 1, 1 } },
2878 { ISD::ZERO_EXTEND, MVT::v32i16, MVT::v64i1, { 2, 1, 1, 1 } },
2879
2880 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i8, { 2, 1, 1, 1 } },
2881 { ISD::TRUNCATE, MVT::v2i1, MVT::v16i8, { 2, 1, 1, 1 } },
2882 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i16, { 2, 1, 1, 1 } },
2883 { ISD::TRUNCATE, MVT::v2i1, MVT::v8i16, { 2, 1, 1, 1 } },
2884 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i8, { 2, 1, 1, 1 } },
2885 { ISD::TRUNCATE, MVT::v4i1, MVT::v16i8, { 2, 1, 1, 1 } },
2886 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i16, { 2, 1, 1, 1 } },
2887 { ISD::TRUNCATE, MVT::v4i1, MVT::v8i16, { 2, 1, 1, 1 } },
2888 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i8, { 2, 1, 1, 1 } },
2889 { ISD::TRUNCATE, MVT::v8i1, MVT::v16i8, { 2, 1, 1, 1 } },
2890 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i16, { 2, 1, 1, 1 } },
2891 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i8, { 2, 1, 1, 1 } },
2892 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i16, { 2, 1, 1, 1 } },
2893 { ISD::TRUNCATE, MVT::v32i1, MVT::v32i8, { 2, 1, 1, 1 } },
2894 { ISD::TRUNCATE, MVT::v32i1, MVT::v32i16, { 2, 1, 1, 1 } },
2895 { ISD::TRUNCATE, MVT::v64i1, MVT::v64i8, { 2, 1, 1, 1 } },
2896 { ISD::TRUNCATE, MVT::v64i1, MVT::v32i16, { 2, 1, 1, 1 } },
2897
2898 { ISD::TRUNCATE, MVT::v32i8, MVT::v32i16, { 2, 1, 1, 1 } },
2899 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i16, { 2, 1, 1, 1 } }, // widen to zmm
2900 { ISD::TRUNCATE, MVT::v2i8, MVT::v2i16, { 2, 1, 1, 1 } }, // vpmovwb
2901 { ISD::TRUNCATE, MVT::v4i8, MVT::v4i16, { 2, 1, 1, 1 } }, // vpmovwb
2902 { ISD::TRUNCATE, MVT::v8i8, MVT::v8i16, { 2, 1, 1, 1 } }, // vpmovwb
2903 };
2904
2905 static const TypeConversionCostKindTblEntry AVX512DQConversionTbl[] = {
2906 // Mask sign extend has an instruction.
2907 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v2i1, { 1, 1, 1, 1 } },
2908 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v2i1, { 1, 1, 1, 1 } },
2909 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v4i1, { 1, 1, 1, 1 } },
2910 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i1, { 1, 1, 1, 1 } },
2911 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i1, { 1, 1, 1, 1 } },
2912 { ISD::SIGN_EXTEND, MVT::v8i64, MVT::v16i1, { 1, 1, 1, 1 } },
2913 { ISD::SIGN_EXTEND, MVT::v8i64, MVT::v8i1, { 1, 1, 1, 1 } },
2914 { ISD::SIGN_EXTEND, MVT::v16i32, MVT::v16i1, { 1, 1, 1, 1 } },
2915
2916 // Mask zero extend is a sext + shift.
2917 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v2i1, { 2, 1, 1, 1, } },
2918 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v2i1, { 2, 1, 1, 1, } },
2919 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v4i1, { 2, 1, 1, 1, } },
2920 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i1, { 2, 1, 1, 1, } },
2921 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i1, { 2, 1, 1, 1, } },
2922 { ISD::ZERO_EXTEND, MVT::v8i64, MVT::v16i1, { 2, 1, 1, 1, } },
2923 { ISD::ZERO_EXTEND, MVT::v8i64, MVT::v8i1, { 2, 1, 1, 1, } },
2924 { ISD::ZERO_EXTEND, MVT::v16i32, MVT::v16i1, { 2, 1, 1, 1, } },
2925
2926 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i64, { 2, 1, 1, 1 } },
2927 { ISD::TRUNCATE, MVT::v2i1, MVT::v4i32, { 2, 1, 1, 1 } },
2928 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i32, { 2, 1, 1, 1 } },
2929 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i64, { 2, 1, 1, 1 } },
2930 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i32, { 2, 1, 1, 1 } },
2931 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i64, { 2, 1, 1, 1 } },
2932 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i32, { 2, 1, 1, 1 } },
2933 { ISD::TRUNCATE, MVT::v16i1, MVT::v8i64, { 2, 1, 1, 1 } },
2934
2935 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v8i64, { 1, 1, 1, 1 } },
2936 { ISD::SINT_TO_FP, MVT::v8f64, MVT::v8i64, { 1, 1, 1, 1 } },
2937
2938 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i64, { 1, 1, 1, 1 } },
2939 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i64, { 1, 1, 1, 1 } },
2940
2941 { ISD::FP_TO_SINT, MVT::v8i64, MVT::v8f32, { 1, 1, 1, 1 } },
2942 { ISD::FP_TO_SINT, MVT::v8i64, MVT::v8f64, { 1, 1, 1, 1 } },
2943
2944 { ISD::FP_TO_UINT, MVT::v8i64, MVT::v8f32, { 1, 1, 1, 1 } },
2945 { ISD::FP_TO_UINT, MVT::v8i64, MVT::v8f64, { 1, 1, 1, 1 } },
2946 };
2947
2948 // TODO: For AVX512DQ + AVX512VL, we also have cheap casts for 128-bit and
2949 // 256-bit wide vectors.
2950
2951 static const TypeConversionCostKindTblEntry AVX512FConversionTbl[] = {
2952 { ISD::FP_EXTEND, MVT::v8f64, MVT::v8f32, { 1, 1, 1, 1 } },
2953 { ISD::FP_EXTEND, MVT::v8f64, MVT::v16f32, { 3, 1, 1, 1 } },
2954 { ISD::FP_EXTEND, MVT::v16f64, MVT::v16f32, { 4, 1, 1, 1 } }, // 2*vcvtps2pd+vextractf64x4
2955 { ISD::FP_EXTEND, MVT::v16f32, MVT::v16f16, { 1, 1, 1, 1 } }, // vcvtph2ps
2956 { ISD::FP_EXTEND, MVT::v8f64, MVT::v8f16, { 2, 1, 1, 1 } }, // vcvtph2ps+vcvtps2pd
2957 { ISD::FP_ROUND, MVT::v8f32, MVT::v8f64, { 1, 1, 1, 1 } },
2958 { ISD::FP_ROUND, MVT::v16f16, MVT::v16f32, { 1, 1, 1, 1 } }, // vcvtps2ph
2959
2960 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i8, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
2961 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i8, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
2962 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i8, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
2963 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i8, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
2964 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i16, { 3, 1, 1, 1 } }, // sext+vpsllq+vptestmq
2965 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i16, { 3, 1, 1, 1 } }, // sext+vpsllq+vptestmq
2966 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i16, { 3, 1, 1, 1 } }, // sext+vpsllq+vptestmq
2967 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i16, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
2968 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i32, { 2, 1, 1, 1 } }, // zmm vpslld+vptestmd
2969 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i32, { 2, 1, 1, 1 } }, // zmm vpslld+vptestmd
2970 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i32, { 2, 1, 1, 1 } }, // zmm vpslld+vptestmd
2971 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i32, { 2, 1, 1, 1 } }, // vpslld+vptestmd
2972 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i64, { 2, 1, 1, 1 } }, // zmm vpsllq+vptestmq
2973 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i64, { 2, 1, 1, 1 } }, // zmm vpsllq+vptestmq
2974 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i64, { 2, 1, 1, 1 } }, // vpsllq+vptestmq
2975 { ISD::TRUNCATE, MVT::v2i8, MVT::v2i32, { 2, 1, 1, 1 } }, // vpmovdb
2976 { ISD::TRUNCATE, MVT::v4i8, MVT::v4i32, { 2, 1, 1, 1 } }, // vpmovdb
2977 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i32, { 2, 1, 1, 1 } }, // vpmovdb
2978 { ISD::TRUNCATE, MVT::v32i8, MVT::v16i32, { 2, 1, 1, 1 } }, // vpmovdb
2979 { ISD::TRUNCATE, MVT::v64i8, MVT::v16i32, { 2, 1, 1, 1 } }, // vpmovdb
2980 { ISD::TRUNCATE, MVT::v16i16, MVT::v16i32, { 2, 1, 1, 1 } }, // vpmovdw
2981 { ISD::TRUNCATE, MVT::v32i16, MVT::v16i32, { 2, 1, 1, 1 } }, // vpmovdw
2982 { ISD::TRUNCATE, MVT::v2i8, MVT::v2i64, { 2, 1, 1, 1 } }, // vpmovqb
2983 { ISD::TRUNCATE, MVT::v2i16, MVT::v2i64, { 1, 1, 1, 1 } }, // vpshufb
2984 { ISD::TRUNCATE, MVT::v8i8, MVT::v8i64, { 2, 1, 1, 1 } }, // vpmovqb
2985 { ISD::TRUNCATE, MVT::v16i8, MVT::v8i64, { 2, 1, 1, 1 } }, // vpmovqb
2986 { ISD::TRUNCATE, MVT::v32i8, MVT::v8i64, { 2, 1, 1, 1 } }, // vpmovqb
2987 { ISD::TRUNCATE, MVT::v64i8, MVT::v8i64, { 2, 1, 1, 1 } }, // vpmovqb
2988 { ISD::TRUNCATE, MVT::v8i16, MVT::v8i64, { 2, 1, 1, 1 } }, // vpmovqw
2989 { ISD::TRUNCATE, MVT::v16i16, MVT::v8i64, { 2, 1, 1, 1 } }, // vpmovqw
2990 { ISD::TRUNCATE, MVT::v32i16, MVT::v8i64, { 2, 1, 1, 1 } }, // vpmovqw
2991 { ISD::TRUNCATE, MVT::v8i32, MVT::v8i64, { 1, 1, 1, 1 } }, // vpmovqd
2992 { ISD::TRUNCATE, MVT::v4i32, MVT::v4i64, { 1, 1, 1, 1 } }, // zmm vpmovqd
2993 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i64, { 5, 1, 1, 1 } },// 2*vpmovqd+concat+vpmovdb
2994
2995 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i16, { 3, 1, 1, 1 } }, // extend to v16i32
2996 { ISD::TRUNCATE, MVT::v32i8, MVT::v32i16, { 8, 1, 1, 1 } },
2997 { ISD::TRUNCATE, MVT::v64i8, MVT::v32i16, { 8, 1, 1, 1 } },
2998
2999 // Sign extend is zmm vpternlogd+vptruncdb.
3000 // Zero extend is zmm broadcast load+vptruncdw.
3001 { ISD::SIGN_EXTEND, MVT::v2i8, MVT::v2i1, { 3, 1, 1, 1 } },
3002 { ISD::ZERO_EXTEND, MVT::v2i8, MVT::v2i1, { 4, 1, 1, 1 } },
3003 { ISD::SIGN_EXTEND, MVT::v4i8, MVT::v4i1, { 3, 1, 1, 1 } },
3004 { ISD::ZERO_EXTEND, MVT::v4i8, MVT::v4i1, { 4, 1, 1, 1 } },
3005 { ISD::SIGN_EXTEND, MVT::v8i8, MVT::v8i1, { 3, 1, 1, 1 } },
3006 { ISD::ZERO_EXTEND, MVT::v8i8, MVT::v8i1, { 4, 1, 1, 1 } },
3007 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v16i1, { 3, 1, 1, 1 } },
3008 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v16i1, { 4, 1, 1, 1 } },
3009
3010 // Sign extend is zmm vpternlogd+vptruncdw.
3011 // Zero extend is zmm vpternlogd+vptruncdw+vpsrlw.
3012 { ISD::SIGN_EXTEND, MVT::v2i16, MVT::v2i1, { 3, 1, 1, 1 } },
3013 { ISD::ZERO_EXTEND, MVT::v2i16, MVT::v2i1, { 4, 1, 1, 1 } },
3014 { ISD::SIGN_EXTEND, MVT::v4i16, MVT::v4i1, { 3, 1, 1, 1 } },
3015 { ISD::ZERO_EXTEND, MVT::v4i16, MVT::v4i1, { 4, 1, 1, 1 } },
3016 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v8i1, { 3, 1, 1, 1 } },
3017 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v8i1, { 4, 1, 1, 1 } },
3018 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i1, { 3, 1, 1, 1 } },
3019 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i1, { 4, 1, 1, 1 } },
3020
3021 { ISD::SIGN_EXTEND, MVT::v2i32, MVT::v2i1, { 1, 1, 1, 1 } }, // zmm vpternlogd
3022 { ISD::ZERO_EXTEND, MVT::v2i32, MVT::v2i1, { 2, 1, 1, 1 } }, // zmm vpternlogd+psrld
3023 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v4i1, { 1, 1, 1, 1 } }, // zmm vpternlogd
3024 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v4i1, { 2, 1, 1, 1 } }, // zmm vpternlogd+psrld
3025 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i1, { 1, 1, 1, 1 } }, // zmm vpternlogd
3026 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i1, { 2, 1, 1, 1 } }, // zmm vpternlogd+psrld
3027 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v2i1, { 1, 1, 1, 1 } }, // zmm vpternlogq
3028 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v2i1, { 2, 1, 1, 1 } }, // zmm vpternlogq+psrlq
3029 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i1, { 1, 1, 1, 1 } }, // zmm vpternlogq
3030 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i1, { 2, 1, 1, 1 } }, // zmm vpternlogq+psrlq
3031
3032 { ISD::SIGN_EXTEND, MVT::v16i32, MVT::v16i1, { 1, 1, 1, 1 } }, // vpternlogd
3033 { ISD::ZERO_EXTEND, MVT::v16i32, MVT::v16i1, { 2, 1, 1, 1 } }, // vpternlogd+psrld
3034 { ISD::SIGN_EXTEND, MVT::v8i64, MVT::v8i1, { 1, 1, 1, 1 } }, // vpternlogq
3035 { ISD::ZERO_EXTEND, MVT::v8i64, MVT::v8i1, { 2, 1, 1, 1 } }, // vpternlogq+psrlq
3036
3037 { ISD::SIGN_EXTEND, MVT::v16i32, MVT::v16i8, { 1, 1, 1, 1 } },
3038 { ISD::ZERO_EXTEND, MVT::v16i32, MVT::v16i8, { 1, 1, 1, 1 } },
3039 { ISD::SIGN_EXTEND, MVT::v16i32, MVT::v16i16, { 1, 1, 1, 1 } },
3040 { ISD::ZERO_EXTEND, MVT::v16i32, MVT::v16i16, { 1, 1, 1, 1 } },
3041 { ISD::SIGN_EXTEND, MVT::v8i64, MVT::v8i8, { 1, 1, 1, 1 } },
3042 { ISD::ZERO_EXTEND, MVT::v8i64, MVT::v8i8, { 1, 1, 1, 1 } },
3043 { ISD::SIGN_EXTEND, MVT::v8i64, MVT::v8i16, { 1, 1, 1, 1 } },
3044 { ISD::ZERO_EXTEND, MVT::v8i64, MVT::v8i16, { 1, 1, 1, 1 } },
3045 { ISD::SIGN_EXTEND, MVT::v8i64, MVT::v8i32, { 1, 1, 1, 1 } },
3046 { ISD::ZERO_EXTEND, MVT::v8i64, MVT::v8i32, { 1, 1, 1, 1 } },
3047
3048 { ISD::SIGN_EXTEND, MVT::v32i16, MVT::v32i8, { 3, 1, 1, 1 } }, // FIXME: May not be right
3049 { ISD::ZERO_EXTEND, MVT::v32i16, MVT::v32i8, { 3, 1, 1, 1 } }, // FIXME: May not be right
3050
3051 { ISD::SINT_TO_FP, MVT::v8f64, MVT::v8i1, { 4, 1, 1, 1 } },
3052 { ISD::SINT_TO_FP, MVT::v16f32, MVT::v16i1, { 3, 1, 1, 1 } },
3053 { ISD::SINT_TO_FP, MVT::v8f64, MVT::v16i8, { 2, 1, 1, 1 } },
3054 { ISD::SINT_TO_FP, MVT::v16f32, MVT::v16i8, { 1, 1, 1, 1 } },
3055 { ISD::SINT_TO_FP, MVT::v8f64, MVT::v8i16, { 2, 1, 1, 1 } },
3056 { ISD::SINT_TO_FP, MVT::v16f32, MVT::v16i16, { 1, 1, 1, 1 } },
3057 { ISD::SINT_TO_FP, MVT::v8f64, MVT::v8i32, { 1, 1, 1, 1 } },
3058 { ISD::SINT_TO_FP, MVT::v16f32, MVT::v16i32, { 1, 1, 1, 1 } },
3059
3060 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i1, { 4, 1, 1, 1 } },
3061 { ISD::UINT_TO_FP, MVT::v16f32, MVT::v16i1, { 3, 1, 1, 1 } },
3062 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v16i8, { 2, 1, 1, 1 } },
3063 { ISD::UINT_TO_FP, MVT::v16f32, MVT::v16i8, { 1, 1, 1, 1 } },
3064 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i16, { 2, 1, 1, 1 } },
3065 { ISD::UINT_TO_FP, MVT::v16f32, MVT::v16i16, { 1, 1, 1, 1 } },
3066 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i32, { 1, 1, 1, 1 } },
3067 { ISD::UINT_TO_FP, MVT::v16f32, MVT::v16i32, { 1, 1, 1, 1 } },
3068 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i64, {26, 1, 1, 1 } },
3069 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i64, { 5, 1, 1, 1 } },
3070
3071 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v16f32, { 2, 1, 1, 1 } },
3072 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v16f64, { 7, 1, 1, 1 } },
3073 { ISD::FP_TO_SINT, MVT::v32i8, MVT::v32f64, {15, 1, 1, 1 } },
3074 { ISD::FP_TO_SINT, MVT::v64i8, MVT::v64f32, {11, 1, 1, 1 } },
3075 { ISD::FP_TO_SINT, MVT::v64i8, MVT::v64f64, {31, 1, 1, 1 } },
3076 { ISD::FP_TO_SINT, MVT::v8i16, MVT::v8f64, { 3, 1, 1, 1 } },
3077 { ISD::FP_TO_SINT, MVT::v16i16, MVT::v16f64, { 7, 1, 1, 1 } },
3078 { ISD::FP_TO_SINT, MVT::v32i16, MVT::v32f32, { 5, 1, 1, 1 } },
3079 { ISD::FP_TO_SINT, MVT::v32i16, MVT::v32f64, {15, 1, 1, 1 } },
3080 { ISD::FP_TO_SINT, MVT::v8i32, MVT::v8f64, { 1, 1, 1, 1 } },
3081 { ISD::FP_TO_SINT, MVT::v16i32, MVT::v16f64, { 3, 1, 1, 1 } },
3082
3083 { ISD::FP_TO_UINT, MVT::v8i32, MVT::v8f64, { 1, 1, 1, 1 } },
3084 { ISD::FP_TO_UINT, MVT::v8i16, MVT::v8f64, { 3, 1, 1, 1 } },
3085 { ISD::FP_TO_UINT, MVT::v8i8, MVT::v8f64, { 3, 1, 1, 1 } },
3086 { ISD::FP_TO_UINT, MVT::v16i32, MVT::v16f32, { 1, 1, 1, 1 } },
3087 { ISD::FP_TO_UINT, MVT::v16i16, MVT::v16f32, { 3, 1, 1, 1 } },
3088 { ISD::FP_TO_UINT, MVT::v16i8, MVT::v16f32, { 3, 1, 1, 1 } },
3089 };
3090
3091 static const TypeConversionCostKindTblEntry AVX512BWVLConversionTbl[] {
3092 // Mask sign extend has an instruction.
3093 { ISD::SIGN_EXTEND, MVT::v2i8, MVT::v2i1, { 1, 1, 1, 1 } },
3094 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v2i1, { 1, 1, 1, 1 } },
3095 { ISD::SIGN_EXTEND, MVT::v2i16, MVT::v2i1, { 1, 1, 1, 1 } },
3096 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v2i1, { 1, 1, 1, 1 } },
3097 { ISD::SIGN_EXTEND, MVT::v4i16, MVT::v4i1, { 1, 1, 1, 1 } },
3098 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v4i1, { 1, 1, 1, 1 } },
3099 { ISD::SIGN_EXTEND, MVT::v4i8, MVT::v4i1, { 1, 1, 1, 1 } },
3100 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v4i1, { 1, 1, 1, 1 } },
3101 { ISD::SIGN_EXTEND, MVT::v8i8, MVT::v8i1, { 1, 1, 1, 1 } },
3102 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v8i1, { 1, 1, 1, 1 } },
3103 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v8i1, { 1, 1, 1, 1 } },
3104 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v16i1, { 1, 1, 1, 1 } },
3105 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i1, { 1, 1, 1, 1 } },
3106 { ISD::SIGN_EXTEND, MVT::v32i8, MVT::v32i1, { 1, 1, 1, 1 } },
3107 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v32i1, { 1, 1, 1, 1 } },
3108 { ISD::SIGN_EXTEND, MVT::v32i8, MVT::v64i1, { 1, 1, 1, 1 } },
3109 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v64i1, { 1, 1, 1, 1 } },
3110
3111 // Mask zero extend is a sext + shift.
3112 { ISD::ZERO_EXTEND, MVT::v2i8, MVT::v2i1, { 2, 1, 1, 1 } },
3113 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v2i1, { 2, 1, 1, 1 } },
3114 { ISD::ZERO_EXTEND, MVT::v2i16, MVT::v2i1, { 2, 1, 1, 1 } },
3115 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v2i1, { 2, 1, 1, 1 } },
3116 { ISD::ZERO_EXTEND, MVT::v4i8, MVT::v4i1, { 2, 1, 1, 1 } },
3117 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v4i1, { 2, 1, 1, 1 } },
3118 { ISD::ZERO_EXTEND, MVT::v4i16, MVT::v4i1, { 2, 1, 1, 1 } },
3119 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v4i1, { 2, 1, 1, 1 } },
3120 { ISD::ZERO_EXTEND, MVT::v8i8, MVT::v8i1, { 2, 1, 1, 1 } },
3121 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v8i1, { 2, 1, 1, 1 } },
3122 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v8i1, { 2, 1, 1, 1 } },
3123 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v16i1, { 2, 1, 1, 1 } },
3124 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i1, { 2, 1, 1, 1 } },
3125 { ISD::ZERO_EXTEND, MVT::v32i8, MVT::v32i1, { 2, 1, 1, 1 } },
3126 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v32i1, { 2, 1, 1, 1 } },
3127 { ISD::ZERO_EXTEND, MVT::v32i8, MVT::v64i1, { 2, 1, 1, 1 } },
3128 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v64i1, { 2, 1, 1, 1 } },
3129
3130 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i8, { 2, 1, 1, 1 } },
3131 { ISD::TRUNCATE, MVT::v2i1, MVT::v16i8, { 2, 1, 1, 1 } },
3132 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i16, { 2, 1, 1, 1 } },
3133 { ISD::TRUNCATE, MVT::v2i1, MVT::v8i16, { 2, 1, 1, 1 } },
3134 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i8, { 2, 1, 1, 1 } },
3135 { ISD::TRUNCATE, MVT::v4i1, MVT::v16i8, { 2, 1, 1, 1 } },
3136 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i16, { 2, 1, 1, 1 } },
3137 { ISD::TRUNCATE, MVT::v4i1, MVT::v8i16, { 2, 1, 1, 1 } },
3138 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i8, { 2, 1, 1, 1 } },
3139 { ISD::TRUNCATE, MVT::v8i1, MVT::v16i8, { 2, 1, 1, 1 } },
3140 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i16, { 2, 1, 1, 1 } },
3141 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i8, { 2, 1, 1, 1 } },
3142 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i16, { 2, 1, 1, 1 } },
3143 { ISD::TRUNCATE, MVT::v32i1, MVT::v32i8, { 2, 1, 1, 1 } },
3144 { ISD::TRUNCATE, MVT::v32i1, MVT::v16i16, { 2, 1, 1, 1 } },
3145 { ISD::TRUNCATE, MVT::v64i1, MVT::v32i8, { 2, 1, 1, 1 } },
3146 { ISD::TRUNCATE, MVT::v64i1, MVT::v16i16, { 2, 1, 1, 1 } },
3147
3148 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i16, { 2, 1, 1, 1 } },
3149 };
3150
3151 static const TypeConversionCostKindTblEntry AVX512DQVLConversionTbl[] = {
3152 // Mask sign extend has an instruction.
3153 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v2i1, { 1, 1, 1, 1 } },
3154 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v2i1, { 1, 1, 1, 1 } },
3155 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v4i1, { 1, 1, 1, 1 } },
3156 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v16i1, { 1, 1, 1, 1 } },
3157 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i1, { 1, 1, 1, 1 } },
3158 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v8i1, { 1, 1, 1, 1 } },
3159 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v16i1, { 1, 1, 1, 1 } },
3160 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i1, { 1, 1, 1, 1 } },
3161
3162 // Mask zero extend is a sext + shift.
3163 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v2i1, { 2, 1, 1, 1 } },
3164 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v2i1, { 2, 1, 1, 1 } },
3165 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v4i1, { 2, 1, 1, 1 } },
3166 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v16i1, { 2, 1, 1, 1 } },
3167 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i1, { 2, 1, 1, 1 } },
3168 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v8i1, { 2, 1, 1, 1 } },
3169 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v16i1, { 2, 1, 1, 1 } },
3170 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i1, { 2, 1, 1, 1 } },
3171
3172 { ISD::TRUNCATE, MVT::v16i1, MVT::v4i64, { 2, 1, 1, 1 } },
3173 { ISD::TRUNCATE, MVT::v16i1, MVT::v8i32, { 2, 1, 1, 1 } },
3174 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i64, { 2, 1, 1, 1 } },
3175 { ISD::TRUNCATE, MVT::v2i1, MVT::v4i32, { 2, 1, 1, 1 } },
3176 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i32, { 2, 1, 1, 1 } },
3177 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i64, { 2, 1, 1, 1 } },
3178 { ISD::TRUNCATE, MVT::v8i1, MVT::v4i64, { 2, 1, 1, 1 } },
3179 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i32, { 2, 1, 1, 1 } },
3180
3181 { ISD::SINT_TO_FP, MVT::v2f32, MVT::v2i64, { 1, 1, 1, 1 } },
3182 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v2i64, { 1, 1, 1, 1 } },
3183 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v4i64, { 1, 1, 1, 1 } },
3184 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v4i64, { 1, 1, 1, 1 } },
3185
3186 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i64, { 1, 1, 1, 1 } },
3187 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i64, { 1, 1, 1, 1 } },
3188 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i64, { 1, 1, 1, 1 } },
3189 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i64, { 1, 1, 1, 1 } },
3190
3191 { ISD::FP_TO_SINT, MVT::v2i64, MVT::v4f32, { 1, 1, 1, 1 } },
3192 { ISD::FP_TO_SINT, MVT::v4i64, MVT::v4f32, { 1, 1, 1, 1 } },
3193 { ISD::FP_TO_SINT, MVT::v2i64, MVT::v2f64, { 1, 1, 1, 1 } },
3194 { ISD::FP_TO_SINT, MVT::v4i64, MVT::v4f64, { 1, 1, 1, 1 } },
3195
3196 { ISD::FP_TO_UINT, MVT::v2i64, MVT::v4f32, { 1, 1, 1, 1 } },
3197 { ISD::FP_TO_UINT, MVT::v4i64, MVT::v4f32, { 1, 1, 1, 1 } },
3198 { ISD::FP_TO_UINT, MVT::v2i64, MVT::v2f64, { 1, 1, 1, 1 } },
3199 { ISD::FP_TO_UINT, MVT::v4i64, MVT::v4f64, { 1, 1, 1, 1 } },
3200 };
3201
3202 static const TypeConversionCostKindTblEntry AVX512VLConversionTbl[] = {
3203 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i8, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
3204 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i8, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
3205 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i8, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
3206 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i8, { 8, 1, 1, 1 } }, // split+2*v8i8
3207 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i16, { 3, 1, 1, 1 } }, // sext+vpsllq+vptestmq
3208 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i16, { 3, 1, 1, 1 } }, // sext+vpsllq+vptestmq
3209 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i16, { 3, 1, 1, 1 } }, // sext+vpsllq+vptestmq
3210 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i16, { 8, 1, 1, 1 } }, // split+2*v8i16
3211 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i32, { 2, 1, 1, 1 } }, // vpslld+vptestmd
3212 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i32, { 2, 1, 1, 1 } }, // vpslld+vptestmd
3213 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i32, { 2, 1, 1, 1 } }, // vpslld+vptestmd
3214 { ISD::TRUNCATE, MVT::v16i1, MVT::v8i32, { 2, 1, 1, 1 } }, // vpslld+vptestmd
3215 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i64, { 2, 1, 1, 1 } }, // vpsllq+vptestmq
3216 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i64, { 2, 1, 1, 1 } }, // vpsllq+vptestmq
3217 { ISD::TRUNCATE, MVT::v4i32, MVT::v4i64, { 1, 1, 1, 1 } }, // vpmovqd
3218 { ISD::TRUNCATE, MVT::v4i8, MVT::v4i64, { 2, 1, 1, 1 } }, // vpmovqb
3219 { ISD::TRUNCATE, MVT::v4i16, MVT::v4i64, { 2, 1, 1, 1 } }, // vpmovqw
3220 { ISD::TRUNCATE, MVT::v8i8, MVT::v8i32, { 2, 1, 1, 1 } }, // vpmovwb
3221
3222 // sign extend is vpcmpeq+maskedmove+vpmovdw+vpacksswb
3223 // zero extend is vpcmpeq+maskedmove+vpmovdw+vpsrlw+vpackuswb
3224 { ISD::SIGN_EXTEND, MVT::v2i8, MVT::v2i1, { 5, 1, 1, 1 } },
3225 { ISD::ZERO_EXTEND, MVT::v2i8, MVT::v2i1, { 6, 1, 1, 1 } },
3226 { ISD::SIGN_EXTEND, MVT::v4i8, MVT::v4i1, { 5, 1, 1, 1 } },
3227 { ISD::ZERO_EXTEND, MVT::v4i8, MVT::v4i1, { 6, 1, 1, 1 } },
3228 { ISD::SIGN_EXTEND, MVT::v8i8, MVT::v8i1, { 5, 1, 1, 1 } },
3229 { ISD::ZERO_EXTEND, MVT::v8i8, MVT::v8i1, { 6, 1, 1, 1 } },
3230 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v16i1, {10, 1, 1, 1 } },
3231 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v16i1, {12, 1, 1, 1 } },
3232
3233 // sign extend is vpcmpeq+maskedmove+vpmovdw
3234 // zero extend is vpcmpeq+maskedmove+vpmovdw+vpsrlw
3235 { ISD::SIGN_EXTEND, MVT::v2i16, MVT::v2i1, { 4, 1, 1, 1 } },
3236 { ISD::ZERO_EXTEND, MVT::v2i16, MVT::v2i1, { 5, 1, 1, 1 } },
3237 { ISD::SIGN_EXTEND, MVT::v4i16, MVT::v4i1, { 4, 1, 1, 1 } },
3238 { ISD::ZERO_EXTEND, MVT::v4i16, MVT::v4i1, { 5, 1, 1, 1 } },
3239 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v8i1, { 4, 1, 1, 1 } },
3240 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v8i1, { 5, 1, 1, 1 } },
3241 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i1, {10, 1, 1, 1 } },
3242 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i1, {12, 1, 1, 1 } },
3243
3244 { ISD::SIGN_EXTEND, MVT::v2i32, MVT::v2i1, { 1, 1, 1, 1 } }, // vpternlogd
3245 { ISD::ZERO_EXTEND, MVT::v2i32, MVT::v2i1, { 2, 1, 1, 1 } }, // vpternlogd+psrld
3246 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v4i1, { 1, 1, 1, 1 } }, // vpternlogd
3247 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v4i1, { 2, 1, 1, 1 } }, // vpternlogd+psrld
3248 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i1, { 1, 1, 1, 1 } }, // vpternlogd
3249 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i1, { 2, 1, 1, 1 } }, // vpternlogd+psrld
3250 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v16i1, { 1, 1, 1, 1 } }, // vpternlogd
3251 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v16i1, { 2, 1, 1, 1 } }, // vpternlogd+psrld
3252
3253 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v2i1, { 1, 1, 1, 1 } }, // vpternlogq
3254 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v2i1, { 2, 1, 1, 1 } }, // vpternlogq+psrlq
3255 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i1, { 1, 1, 1, 1 } }, // vpternlogq
3256 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i1, { 2, 1, 1, 1 } }, // vpternlogq+psrlq
3257
3258 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v16i8, { 1, 1, 1, 1 } },
3259 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v16i8, { 1, 1, 1, 1 } },
3260 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v16i8, { 1, 1, 1, 1 } },
3261 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v16i8, { 1, 1, 1, 1 } },
3262 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i8, { 1, 1, 1, 1 } },
3263 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i8, { 1, 1, 1, 1 } },
3264 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v8i16, { 1, 1, 1, 1 } },
3265 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v8i16, { 1, 1, 1, 1 } },
3266 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i16, { 1, 1, 1, 1 } },
3267 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i16, { 1, 1, 1, 1 } },
3268 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i32, { 1, 1, 1, 1 } },
3269 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i32, { 1, 1, 1, 1 } },
3270
3271 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v16i8, { 1, 1, 1, 1 } },
3272 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v16i8, { 1, 1, 1, 1 } },
3273 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v8i16, { 1, 1, 1, 1 } },
3274 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v8i16, { 1, 1, 1, 1 } },
3275
3276 { ISD::UINT_TO_FP, MVT::f32, MVT::i64, { 1, 1, 1, 1 } },
3277 { ISD::UINT_TO_FP, MVT::f64, MVT::i64, { 1, 1, 1, 1 } },
3278 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v16i8, { 1, 1, 1, 1 } },
3279 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v16i8, { 1, 1, 1, 1 } },
3280 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v8i16, { 1, 1, 1, 1 } },
3281 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i16, { 1, 1, 1, 1 } },
3282 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i32, { 1, 1, 1, 1 } },
3283 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i32, { 1, 1, 1, 1 } },
3284 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i32, { 1, 1, 1, 1 } },
3285 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i32, { 1, 1, 1, 1 } },
3286 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i64, { 5, 1, 1, 1 } },
3287 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i64, { 5, 1, 1, 1 } },
3288 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i64, { 5, 1, 1, 1 } },
3289
3290 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v8f32, { 2, 1, 1, 1 } },
3291 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v16f32, { 2, 1, 1, 1 } },
3292 { ISD::FP_TO_SINT, MVT::v32i8, MVT::v32f32, { 5, 1, 1, 1 } },
3293
3294 { ISD::FP_TO_UINT, MVT::i64, MVT::f32, { 1, 1, 1, 1 } },
3295 { ISD::FP_TO_UINT, MVT::i64, MVT::f64, { 1, 1, 1, 1 } },
3296 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f32, { 1, 1, 1, 1 } },
3297 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v2f64, { 1, 1, 1, 1 } },
3298 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f64, { 1, 1, 1, 1 } },
3299 { ISD::FP_TO_UINT, MVT::v8i32, MVT::v8f32, { 1, 1, 1, 1 } },
3300 { ISD::FP_TO_UINT, MVT::v8i32, MVT::v8f64, { 1, 1, 1, 1 } },
3301 };
3302
3303 static const TypeConversionCostKindTblEntry AVX2ConversionTbl[] = {
3304 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i1, { 3, 1, 1, 1 } },
3305 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i1, { 3, 1, 1, 1 } },
3306 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i1, { 3, 1, 1, 1 } },
3307 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i1, { 3, 1, 1, 1 } },
3308 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i1, { 1, 1, 1, 1 } },
3309 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i1, { 1, 1, 1, 1 } },
3310
3311 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v16i8, { 2, 1, 1, 1 } },
3312 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v16i8, { 2, 1, 1, 1 } },
3313 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v16i8, { 2, 1, 1, 1 } },
3314 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v16i8, { 2, 1, 1, 1 } },
3315 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i8, { 2, 1, 1, 1 } },
3316 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i8, { 2, 1, 1, 1 } },
3317 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v8i16, { 2, 1, 1, 1 } },
3318 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v8i16, { 2, 1, 1, 1 } },
3319 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i16, { 2, 1, 1, 1 } },
3320 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i16, { 2, 1, 1, 1 } },
3321 { ISD::ZERO_EXTEND, MVT::v16i32, MVT::v16i16, { 3, 1, 1, 1 } },
3322 { ISD::SIGN_EXTEND, MVT::v16i32, MVT::v16i16, { 3, 1, 1, 1 } },
3323 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i32, { 2, 1, 1, 1 } },
3324 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i32, { 2, 1, 1, 1 } },
3325
3326 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i32, { 2, 1, 1, 1 } },
3327
3328 { ISD::TRUNCATE, MVT::v16i16, MVT::v16i32, { 4, 1, 1, 1 } },
3329 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i32, { 4, 1, 1, 1 } },
3330 { ISD::TRUNCATE, MVT::v16i8, MVT::v8i16, { 1, 1, 1, 1 } },
3331 { ISD::TRUNCATE, MVT::v16i8, MVT::v4i32, { 1, 1, 1, 1 } },
3332 { ISD::TRUNCATE, MVT::v16i8, MVT::v2i64, { 1, 1, 1, 1 } },
3333 { ISD::TRUNCATE, MVT::v16i8, MVT::v8i32, { 4, 1, 1, 1 } },
3334 { ISD::TRUNCATE, MVT::v16i8, MVT::v4i64, { 4, 1, 1, 1 } },
3335 { ISD::TRUNCATE, MVT::v8i16, MVT::v4i32, { 1, 1, 1, 1 } },
3336 { ISD::TRUNCATE, MVT::v8i16, MVT::v2i64, { 1, 1, 1, 1 } },
3337 { ISD::TRUNCATE, MVT::v8i16, MVT::v4i64, { 5, 1, 1, 1 } },
3338 { ISD::TRUNCATE, MVT::v4i32, MVT::v4i64, { 1, 1, 1, 1 } },
3339 { ISD::TRUNCATE, MVT::v8i16, MVT::v8i32, { 2, 1, 1, 1 } },
3340
3341 { ISD::FP_EXTEND, MVT::v8f64, MVT::v8f32, { 3, 1, 1, 1 } },
3342 { ISD::FP_ROUND, MVT::v8f32, MVT::v8f64, { 3, 1, 1, 1 } },
3343
3344 { ISD::FP_TO_SINT, MVT::v16i16, MVT::v8f32, { 1, 1, 1, 1 } },
3345 { ISD::FP_TO_SINT, MVT::v4i32, MVT::v4f64, { 1, 1, 1, 1 } },
3346 { ISD::FP_TO_SINT, MVT::v8i32, MVT::v8f32, { 1, 1, 1, 1 } },
3347 { ISD::FP_TO_SINT, MVT::v8i32, MVT::v8f64, { 3, 1, 1, 1 } },
3348
3349 { ISD::FP_TO_UINT, MVT::i64, MVT::f32, { 3, 1, 1, 1 } },
3350 { ISD::FP_TO_UINT, MVT::i64, MVT::f64, { 3, 1, 1, 1 } },
3351 { ISD::FP_TO_UINT, MVT::v16i16, MVT::v8f32, { 1, 1, 1, 1 } },
3352 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f32, { 3, 1, 1, 1 } },
3353 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v2f64, { 4, 1, 1, 1 } },
3354 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f64, { 4, 1, 1, 1 } },
3355 { ISD::FP_TO_UINT, MVT::v8i32, MVT::v8f32, { 3, 1, 1, 1 } },
3356 { ISD::FP_TO_UINT, MVT::v8i32, MVT::v4f64, { 4, 1, 1, 1 } },
3357
3358 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v16i8, { 2, 1, 1, 1 } },
3359 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v16i8, { 2, 1, 1, 1 } },
3360 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v8i16, { 2, 1, 1, 1 } },
3361 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v8i16, { 2, 1, 1, 1 } },
3362 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v4i32, { 1, 1, 1, 1 } },
3363 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v8i32, { 1, 1, 1, 1 } },
3364 { ISD::SINT_TO_FP, MVT::v8f64, MVT::v8i32, { 3, 1, 1, 1 } },
3365
3366 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v16i8, { 2, 1, 1, 1 } },
3367 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v16i8, { 2, 1, 1, 1 } },
3368 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v8i16, { 2, 1, 1, 1 } },
3369 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i16, { 2, 1, 1, 1 } },
3370 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i32, { 2, 1, 1, 1 } },
3371 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i32, { 1, 1, 1, 1 } },
3372 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i32, { 2, 1, 1, 1 } },
3373 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i32, { 2, 1, 1, 1 } },
3374 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i32, { 2, 1, 1, 1 } },
3375 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i32, { 4, 1, 1, 1 } },
3376 };
3377
3378 static const TypeConversionCostKindTblEntry AVXConversionTbl[] = {
3379 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i1, { 4, 1, 1, 1 } },
3380 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i1, { 4, 1, 1, 1 } },
3381 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i1, { 4, 1, 1, 1 } },
3382 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i1, { 4, 1, 1, 1 } },
3383 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i1, { 4, 1, 1, 1 } },
3384 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i1, { 4, 1, 1, 1 } },
3385
3386 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v16i8, { 3, 1, 1, 1 } },
3387 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v16i8, { 3, 1, 1, 1 } },
3388 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v16i8, { 3, 1, 1, 1 } },
3389 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v16i8, { 3, 1, 1, 1 } },
3390 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i8, { 3, 1, 1, 1 } },
3391 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i8, { 3, 1, 1, 1 } },
3392 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v8i16, { 3, 1, 1, 1 } },
3393 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v8i16, { 3, 1, 1, 1 } },
3394 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i16, { 3, 1, 1, 1 } },
3395 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i16, { 3, 1, 1, 1 } },
3396 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i32, { 3, 1, 1, 1 } },
3397 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i32, { 3, 1, 1, 1 } },
3398
3399 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i64, { 4, 1, 1, 1 } },
3400 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i32, { 5, 1, 1, 1 } },
3401 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i16, { 4, 1, 1, 1 } },
3402 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i64, { 9, 1, 1, 1 } },
3403 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i64, {11, 1, 1, 1 } },
3404
3405 { ISD::TRUNCATE, MVT::v16i16, MVT::v16i32, { 6, 1, 1, 1 } },
3406 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i32, { 6, 1, 1, 1 } },
3407 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i16, { 2, 1, 1, 1 } }, // and+extract+packuswb
3408 { ISD::TRUNCATE, MVT::v16i8, MVT::v8i32, { 5, 1, 1, 1 } },
3409 { ISD::TRUNCATE, MVT::v8i16, MVT::v8i32, { 5, 1, 1, 1 } },
3410 { ISD::TRUNCATE, MVT::v16i8, MVT::v4i64, { 5, 1, 1, 1 } },
3411 { ISD::TRUNCATE, MVT::v8i16, MVT::v4i64, { 3, 1, 1, 1 } }, // and+extract+2*packusdw
3412 { ISD::TRUNCATE, MVT::v4i32, MVT::v4i64, { 2, 1, 1, 1 } },
3413
3414 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v4i1, { 3, 1, 1, 1 } },
3415 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v4i1, { 3, 1, 1, 1 } },
3416 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v8i1, { 8, 1, 1, 1 } },
3417 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v16i8, { 4, 1, 1, 1 } },
3418 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v16i8, { 2, 1, 1, 1 } },
3419 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v8i16, { 4, 1, 1, 1 } },
3420 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v8i16, { 2, 1, 1, 1 } },
3421 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v4i32, { 2, 1, 1, 1 } },
3422 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v8i32, { 2, 1, 1, 1 } },
3423 { ISD::SINT_TO_FP, MVT::v8f64, MVT::v8i32, { 4, 1, 1, 1 } },
3424 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v2i64, { 5, 1, 1, 1 } },
3425 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v4i64, { 8, 1, 1, 1 } },
3426
3427 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i1, { 7, 1, 1, 1 } },
3428 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i1, { 7, 1, 1, 1 } },
3429 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i1, { 6, 1, 1, 1 } },
3430 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v16i8, { 4, 1, 1, 1 } },
3431 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v16i8, { 2, 1, 1, 1 } },
3432 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i16, { 4, 1, 1, 1 } },
3433 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v8i16, { 2, 1, 1, 1 } },
3434 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i32, { 4, 1, 1, 1 } },
3435 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i32, { 4, 1, 1, 1 } },
3436 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i32, { 5, 1, 1, 1 } },
3437 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i32, { 6, 1, 1, 1 } },
3438 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i32, { 8, 1, 1, 1 } },
3439 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i32, {10, 1, 1, 1 } },
3440 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i64, {11, 1, 1, 1 } },
3441 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i64, {18, 1, 1, 1 } },
3442 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i64, { 5, 1, 1, 1 } },
3443 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i64, {10, 1, 1, 1 } },
3444
3445 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v8f32, { 2, 1, 1, 1 } },
3446 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v4f64, { 2, 1, 1, 1 } },
3447 { ISD::FP_TO_SINT, MVT::v32i8, MVT::v8f32, { 2, 1, 1, 1 } },
3448 { ISD::FP_TO_SINT, MVT::v32i8, MVT::v4f64, { 2, 1, 1, 1 } },
3449 { ISD::FP_TO_SINT, MVT::v8i16, MVT::v8f32, { 2, 1, 1, 1 } },
3450 { ISD::FP_TO_SINT, MVT::v8i16, MVT::v4f64, { 2, 1, 1, 1 } },
3451 { ISD::FP_TO_SINT, MVT::v16i16, MVT::v8f32, { 2, 1, 1, 1 } },
3452 { ISD::FP_TO_SINT, MVT::v16i16, MVT::v4f64, { 2, 1, 1, 1 } },
3453 { ISD::FP_TO_SINT, MVT::v4i32, MVT::v4f64, { 2, 1, 1, 1 } },
3454 { ISD::FP_TO_SINT, MVT::v8i32, MVT::v8f32, { 2, 1, 1, 1 } },
3455 { ISD::FP_TO_SINT, MVT::v8i32, MVT::v8f64, { 5, 1, 1, 1 } },
3456
3457 { ISD::FP_TO_UINT, MVT::v16i8, MVT::v8f32, { 2, 1, 1, 1 } },
3458 { ISD::FP_TO_UINT, MVT::v16i8, MVT::v4f64, { 2, 1, 1, 1 } },
3459 { ISD::FP_TO_UINT, MVT::v32i8, MVT::v8f32, { 2, 1, 1, 1 } },
3460 { ISD::FP_TO_UINT, MVT::v32i8, MVT::v4f64, { 2, 1, 1, 1 } },
3461 { ISD::FP_TO_UINT, MVT::v8i16, MVT::v8f32, { 2, 1, 1, 1 } },
3462 { ISD::FP_TO_UINT, MVT::v8i16, MVT::v4f64, { 2, 1, 1, 1 } },
3463 { ISD::FP_TO_UINT, MVT::v16i16, MVT::v8f32, { 2, 1, 1, 1 } },
3464 { ISD::FP_TO_UINT, MVT::v16i16, MVT::v4f64, { 2, 1, 1, 1 } },
3465 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f32, { 3, 1, 1, 1 } },
3466 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v2f64, { 4, 1, 1, 1 } },
3467 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f64, { 6, 1, 1, 1 } },
3468 { ISD::FP_TO_UINT, MVT::v8i32, MVT::v8f32, { 7, 1, 1, 1 } },
3469 { ISD::FP_TO_UINT, MVT::v8i32, MVT::v4f64, { 7, 1, 1, 1 } },
3470
3471 { ISD::FP_EXTEND, MVT::v4f64, MVT::v4f32, { 1, 1, 1, 1 } },
3472 { ISD::FP_ROUND, MVT::v4f32, MVT::v4f64, { 1, 1, 1, 1 } },
3473 };
3474
3475 static const TypeConversionCostKindTblEntry SSE41ConversionTbl[] = {
3476 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v16i8, { 1, 1, 1, 1 } },
3477 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v16i8, { 1, 1, 1, 1 } },
3478 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v16i8, { 1, 1, 1, 1 } },
3479 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v16i8, { 1, 1, 1, 1 } },
3480 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v16i8, { 1, 1, 1, 1 } },
3481 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v16i8, { 1, 1, 1, 1 } },
3482 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v8i16, { 1, 1, 1, 1 } },
3483 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v8i16, { 1, 1, 1, 1 } },
3484 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v8i16, { 1, 1, 1, 1 } },
3485 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v8i16, { 1, 1, 1, 1 } },
3486 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v4i32, { 1, 1, 1, 1 } },
3487 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v4i32, { 1, 1, 1, 1 } },
3488
3489 // These truncates end up widening elements.
3490 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i8, { 1, 1, 1, 1 } }, // PMOVXZBQ
3491 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i16, { 1, 1, 1, 1 } }, // PMOVXZWQ
3492 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i8, { 1, 1, 1, 1 } }, // PMOVXZBD
3493
3494 { ISD::TRUNCATE, MVT::v16i8, MVT::v4i32, { 2, 1, 1, 1 } },
3495 { ISD::TRUNCATE, MVT::v8i16, MVT::v4i32, { 2, 1, 1, 1 } },
3496 { ISD::TRUNCATE, MVT::v16i8, MVT::v2i64, { 2, 1, 1, 1 } },
3497
3498 { ISD::SINT_TO_FP, MVT::f32, MVT::i32, { 1, 1, 1, 1 } },
3499 { ISD::SINT_TO_FP, MVT::f64, MVT::i32, { 1, 1, 1, 1 } },
3500 { ISD::SINT_TO_FP, MVT::f32, MVT::i64, { 1, 1, 1, 1 } },
3501 { ISD::SINT_TO_FP, MVT::f64, MVT::i64, { 1, 1, 1, 1 } },
3502 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v16i8, { 1, 1, 1, 1 } },
3503 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v16i8, { 1, 1, 1, 1 } },
3504 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v8i16, { 1, 1, 1, 1 } },
3505 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v8i16, { 1, 1, 1, 1 } },
3506 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v4i32, { 1, 1, 1, 1 } },
3507 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v4i32, { 1, 1, 1, 1 } },
3508 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v4i32, { 2, 1, 1, 1 } },
3509
3510 { ISD::UINT_TO_FP, MVT::f32, MVT::i32, { 1, 1, 1, 1 } },
3511 { ISD::UINT_TO_FP, MVT::f64, MVT::i32, { 1, 1, 1, 1 } },
3512 { ISD::UINT_TO_FP, MVT::f32, MVT::i64, { 4, 1, 1, 1 } },
3513 { ISD::UINT_TO_FP, MVT::f64, MVT::i64, { 4, 1, 1, 1 } },
3514 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v16i8, { 1, 1, 1, 1 } },
3515 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v16i8, { 1, 1, 1, 1 } },
3516 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v8i16, { 1, 1, 1, 1 } },
3517 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v8i16, { 1, 1, 1, 1 } },
3518 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i32, { 3, 1, 1, 1 } },
3519 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i32, { 3, 1, 1, 1 } },
3520 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v4i32, { 2, 1, 1, 1 } },
3521 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v2i64, {12, 1, 1, 1 } },
3522 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i64, {22, 1, 1, 1 } },
3523 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i64, { 4, 1, 1, 1 } },
3524
3525 { ISD::FP_TO_SINT, MVT::i32, MVT::f32, { 1, 1, 1, 1 } },
3526 { ISD::FP_TO_SINT, MVT::i64, MVT::f32, { 1, 1, 1, 1 } },
3527 { ISD::FP_TO_SINT, MVT::i32, MVT::f64, { 1, 1, 1, 1 } },
3528 { ISD::FP_TO_SINT, MVT::i64, MVT::f64, { 1, 1, 1, 1 } },
3529 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v4f32, { 2, 1, 1, 1 } },
3530 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v2f64, { 2, 1, 1, 1 } },
3531 { ISD::FP_TO_SINT, MVT::v8i16, MVT::v4f32, { 1, 1, 1, 1 } },
3532 { ISD::FP_TO_SINT, MVT::v8i16, MVT::v2f64, { 1, 1, 1, 1 } },
3533 { ISD::FP_TO_SINT, MVT::v4i32, MVT::v4f32, { 1, 1, 1, 1 } },
3534 { ISD::FP_TO_SINT, MVT::v4i32, MVT::v2f64, { 1, 1, 1, 1 } },
3535
3536 { ISD::FP_TO_UINT, MVT::i32, MVT::f32, { 1, 1, 1, 1 } },
3537 { ISD::FP_TO_UINT, MVT::i64, MVT::f32, { 4, 1, 1, 1 } },
3538 { ISD::FP_TO_UINT, MVT::i32, MVT::f64, { 1, 1, 1, 1 } },
3539 { ISD::FP_TO_UINT, MVT::i64, MVT::f64, { 4, 1, 1, 1 } },
3540 { ISD::FP_TO_UINT, MVT::v16i8, MVT::v4f32, { 2, 1, 1, 1 } },
3541 { ISD::FP_TO_UINT, MVT::v16i8, MVT::v2f64, { 2, 1, 1, 1 } },
3542 { ISD::FP_TO_UINT, MVT::v8i16, MVT::v4f32, { 1, 1, 1, 1 } },
3543 { ISD::FP_TO_UINT, MVT::v8i16, MVT::v2f64, { 1, 1, 1, 1 } },
3544 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f32, { 4, 1, 1, 1 } },
3545 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v2f64, { 4, 1, 1, 1 } },
3546 };
3547
3548 static const TypeConversionCostKindTblEntry SSE2ConversionTbl[] = {
3549 // These are somewhat magic numbers justified by comparing the
3550 // output of llvm-mca for our various supported scheduler models
3551 // and basing it off the worst case scenario.
3552 { ISD::SINT_TO_FP, MVT::f32, MVT::i32, { 3, 1, 1, 1 } },
3553 { ISD::SINT_TO_FP, MVT::f64, MVT::i32, { 3, 1, 1, 1 } },
3554 { ISD::SINT_TO_FP, MVT::f32, MVT::i64, { 3, 1, 1, 1 } },
3555 { ISD::SINT_TO_FP, MVT::f64, MVT::i64, { 3, 1, 1, 1 } },
3556 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v16i8, { 3, 1, 1, 1 } },
3557 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v16i8, { 4, 1, 1, 1 } },
3558 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v8i16, { 3, 1, 1, 1 } },
3559 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v8i16, { 4, 1, 1, 1 } },
3560 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v4i32, { 3, 1, 1, 1 } },
3561 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v4i32, { 4, 1, 1, 1 } },
3562 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v2i64, { 8, 1, 1, 1 } },
3563 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v2i64, { 8, 1, 1, 1 } },
3564
3565 { ISD::UINT_TO_FP, MVT::f32, MVT::i32, { 3, 1, 1, 1 } },
3566 { ISD::UINT_TO_FP, MVT::f64, MVT::i32, { 3, 1, 1, 1 } },
3567 { ISD::UINT_TO_FP, MVT::f32, MVT::i64, { 8, 1, 1, 1 } },
3568 { ISD::UINT_TO_FP, MVT::f64, MVT::i64, { 9, 1, 1, 1 } },
3569 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v16i8, { 4, 1, 1, 1 } },
3570 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v16i8, { 4, 1, 1, 1 } },
3571 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v8i16, { 4, 1, 1, 1 } },
3572 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v8i16, { 4, 1, 1, 1 } },
3573 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i32, { 7, 1, 1, 1 } },
3574 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v4i32, { 7, 1, 1, 1 } },
3575 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i32, { 5, 1, 1, 1 } },
3576 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i64, {15, 1, 1, 1 } },
3577 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v2i64, {18, 1, 1, 1 } },
3578
3579 { ISD::FP_TO_SINT, MVT::i32, MVT::f32, { 4, 1, 1, 1 } },
3580 { ISD::FP_TO_SINT, MVT::i64, MVT::f32, { 4, 1, 1, 1 } },
3581 { ISD::FP_TO_SINT, MVT::i32, MVT::f64, { 4, 1, 1, 1 } },
3582 { ISD::FP_TO_SINT, MVT::i64, MVT::f64, { 4, 1, 1, 1 } },
3583 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v4f32, { 6, 1, 1, 1 } },
3584 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v2f64, { 6, 1, 1, 1 } },
3585 { ISD::FP_TO_SINT, MVT::v8i16, MVT::v4f32, { 5, 1, 1, 1 } },
3586 { ISD::FP_TO_SINT, MVT::v8i16, MVT::v2f64, { 5, 1, 1, 1 } },
3587 { ISD::FP_TO_SINT, MVT::v4i32, MVT::v4f32, { 4, 1, 1, 1 } },
3588 { ISD::FP_TO_SINT, MVT::v4i32, MVT::v2f64, { 4, 1, 1, 1 } },
3589
3590 { ISD::FP_TO_UINT, MVT::i32, MVT::f32, { 4, 1, 1, 1 } },
3591 { ISD::FP_TO_UINT, MVT::i64, MVT::f32, { 4, 1, 1, 1 } },
3592 { ISD::FP_TO_UINT, MVT::i32, MVT::f64, { 4, 1, 1, 1 } },
3593 { ISD::FP_TO_UINT, MVT::i64, MVT::f64, {15, 1, 1, 1 } },
3594 { ISD::FP_TO_UINT, MVT::v16i8, MVT::v4f32, { 6, 1, 1, 1 } },
3595 { ISD::FP_TO_UINT, MVT::v16i8, MVT::v2f64, { 6, 1, 1, 1 } },
3596 { ISD::FP_TO_UINT, MVT::v8i16, MVT::v4f32, { 5, 1, 1, 1 } },
3597 { ISD::FP_TO_UINT, MVT::v8i16, MVT::v2f64, { 5, 1, 1, 1 } },
3598 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f32, { 8, 1, 1, 1 } },
3599 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v2f64, { 8, 1, 1, 1 } },
3600
3601 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v16i8, { 4, 1, 1, 1 } },
3602 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v16i8, { 4, 1, 1, 1 } },
3603 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v16i8, { 2, 1, 1, 1 } },
3604 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v16i8, { 3, 1, 1, 1 } },
3605 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v16i8, { 1, 1, 1, 1 } },
3606 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v16i8, { 2, 1, 1, 1 } },
3607 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v8i16, { 2, 1, 1, 1 } },
3608 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v8i16, { 3, 1, 1, 1 } },
3609 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v8i16, { 1, 1, 1, 1 } },
3610 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v8i16, { 2, 1, 1, 1 } },
3611 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v4i32, { 1, 1, 1, 1 } },
3612 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v4i32, { 2, 1, 1, 1 } },
3613
3614 // These truncates are really widening elements.
3615 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i32, { 1, 1, 1, 1 } }, // PSHUFD
3616 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i16, { 2, 1, 1, 1 } }, // PUNPCKLWD+DQ
3617 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i8, { 3, 1, 1, 1 } }, // PUNPCKLBW+WD+PSHUFD
3618 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i16, { 1, 1, 1, 1 } }, // PUNPCKLWD
3619 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i8, { 2, 1, 1, 1 } }, // PUNPCKLBW+WD
3620 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i8, { 1, 1, 1, 1 } }, // PUNPCKLBW
3621
3622 { ISD::TRUNCATE, MVT::v16i8, MVT::v8i16, { 2, 1, 1, 1 } }, // PAND+PACKUSWB
3623 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i16, { 3, 1, 1, 1 } },
3624 { ISD::TRUNCATE, MVT::v16i8, MVT::v4i32, { 3, 1, 1, 1 } }, // PAND+2*PACKUSWB
3625 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i32, { 7, 1, 1, 1 } },
3626 { ISD::TRUNCATE, MVT::v2i16, MVT::v2i32, { 1, 1, 1, 1 } },
3627 { ISD::TRUNCATE, MVT::v8i16, MVT::v4i32, { 3, 1, 1, 1 } },
3628 { ISD::TRUNCATE, MVT::v8i16, MVT::v8i32, { 5, 1, 1, 1 } },
3629 { ISD::TRUNCATE, MVT::v16i16, MVT::v16i32, {10, 1, 1, 1 } },
3630 { ISD::TRUNCATE, MVT::v16i8, MVT::v2i64, { 4, 1, 1, 1 } }, // PAND+3*PACKUSWB
3631 { ISD::TRUNCATE, MVT::v8i16, MVT::v2i64, { 2, 1, 1, 1 } }, // PSHUFD+PSHUFLW
3632 { ISD::TRUNCATE, MVT::v4i32, MVT::v2i64, { 1, 1, 1, 1 } }, // PSHUFD
3633 };
3634
3635 static const TypeConversionCostKindTblEntry F16ConversionTbl[] = {
3636 { ISD::FP_ROUND, MVT::f16, MVT::f32, { 1, 1, 1, 1 } },
3637 { ISD::FP_ROUND, MVT::v8f16, MVT::v8f32, { 1, 1, 1, 1 } },
3638 { ISD::FP_ROUND, MVT::v4f16, MVT::v4f32, { 1, 1, 1, 1 } },
3639 { ISD::FP_EXTEND, MVT::f32, MVT::f16, { 1, 1, 1, 1 } },
3640 { ISD::FP_EXTEND, MVT::f64, MVT::f16, { 2, 1, 1, 1 } }, // vcvtph2ps+vcvtps2pd
3641 { ISD::FP_EXTEND, MVT::v8f32, MVT::v8f16, { 1, 1, 1, 1 } },
3642 { ISD::FP_EXTEND, MVT::v4f32, MVT::v4f16, { 1, 1, 1, 1 } },
3643 { ISD::FP_EXTEND, MVT::v4f64, MVT::v4f16, { 2, 1, 1, 1 } }, // vcvtph2ps+vcvtps2pd
3644 };
3645
3646 // Attempt to map directly to (simple) MVT types to let us match custom entries.
3647 EVT SrcTy = TLI->getValueType(DL, Src);
3648 EVT DstTy = TLI->getValueType(DL, Dst);
3649
3650 // If we're sign-extending a vector comparison result back to the comparison
3651 // width, this will be free without AVX512 (or for 8/16-bit types without
3652 // BWI).
3653 if (!ST->hasAVX512() || (!ST->hasBWI() && DstTy.getScalarSizeInBits() < 32)) {
3654 if (I && Opcode == Instruction::CastOps::SExt &&
3655 SrcTy.isFixedLengthVectorOf(MVT::i1)) {
3656 if (auto *CmpI = dyn_cast<CmpInst>(I->getOperand(0))) {
3657 Type *CmpTy = CmpI->getOperand(0)->getType();
3658 if (CmpTy->getScalarSizeInBits() == DstTy.getScalarSizeInBits())
3659 return TTI::TCC_Free;
3660 }
3661 }
3662 }
3663
3664 // The function getSimpleVT only handles simple value types.
3665 if (SrcTy.isSimple() && DstTy.isSimple()) {
3666 MVT SimpleSrcTy = SrcTy.getSimpleVT();
3667 MVT SimpleDstTy = DstTy.getSimpleVT();
3668
3669 if (ST->useAVX512Regs()) {
3670 if (ST->hasBWI())
3671 if (const auto *Entry = ConvertCostTableLookup(
3672 AVX512BWConversionTbl, ISD, SimpleDstTy, SimpleSrcTy))
3673 if (auto KindCost = Entry->Cost[CostKind])
3674 return *KindCost;
3675
3676 if (ST->hasDQI())
3677 if (const auto *Entry = ConvertCostTableLookup(
3678 AVX512DQConversionTbl, ISD, SimpleDstTy, SimpleSrcTy))
3679 if (auto KindCost = Entry->Cost[CostKind])
3680 return *KindCost;
3681
3682 if (ST->hasAVX512())
3683 if (const auto *Entry = ConvertCostTableLookup(
3684 AVX512FConversionTbl, ISD, SimpleDstTy, SimpleSrcTy))
3685 if (auto KindCost = Entry->Cost[CostKind])
3686 return *KindCost;
3687 }
3688
3689 if (ST->hasBWI())
3690 if (const auto *Entry = ConvertCostTableLookup(
3691 AVX512BWVLConversionTbl, ISD, SimpleDstTy, SimpleSrcTy))
3692 if (auto KindCost = Entry->Cost[CostKind])
3693 return *KindCost;
3694
3695 if (ST->hasDQI())
3696 if (const auto *Entry = ConvertCostTableLookup(
3697 AVX512DQVLConversionTbl, ISD, SimpleDstTy, SimpleSrcTy))
3698 if (auto KindCost = Entry->Cost[CostKind])
3699 return *KindCost;
3700
3701 if (ST->hasAVX512())
3702 if (const auto *Entry = ConvertCostTableLookup(AVX512VLConversionTbl, ISD,
3703 SimpleDstTy, SimpleSrcTy))
3704 if (auto KindCost = Entry->Cost[CostKind])
3705 return *KindCost;
3706
3707 if (ST->hasAVX2()) {
3708 if (const auto *Entry = ConvertCostTableLookup(AVX2ConversionTbl, ISD,
3709 SimpleDstTy, SimpleSrcTy))
3710 if (auto KindCost = Entry->Cost[CostKind])
3711 return *KindCost;
3712 }
3713
3714 if (ST->hasAVX()) {
3715 if (const auto *Entry = ConvertCostTableLookup(AVXConversionTbl, ISD,
3716 SimpleDstTy, SimpleSrcTy))
3717 if (auto KindCost = Entry->Cost[CostKind])
3718 return *KindCost;
3719 }
3720
3721 if (ST->hasF16C()) {
3722 if (const auto *Entry = ConvertCostTableLookup(F16ConversionTbl, ISD,
3723 SimpleDstTy, SimpleSrcTy))
3724 if (auto KindCost = Entry->Cost[CostKind])
3725 return *KindCost;
3726 }
3727
3728 if (ST->hasSSE41()) {
3729 if (const auto *Entry = ConvertCostTableLookup(SSE41ConversionTbl, ISD,
3730 SimpleDstTy, SimpleSrcTy))
3731 if (auto KindCost = Entry->Cost[CostKind])
3732 return *KindCost;
3733 }
3734
3735 if (ST->hasSSE2()) {
3736 if (const auto *Entry = ConvertCostTableLookup(SSE2ConversionTbl, ISD,
3737 SimpleDstTy, SimpleSrcTy))
3738 if (auto KindCost = Entry->Cost[CostKind])
3739 return *KindCost;
3740 }
3741
3742 if ((ISD == ISD::FP_ROUND && SimpleDstTy == MVT::f16) ||
3743 (ISD == ISD::FP_EXTEND && SimpleSrcTy == MVT::f16)) {
3744 // fp16 conversions not covered by any table entries require a libcall.
3745 // Return a large (arbitrary) number to model this.
3746 return InstructionCost(64);
3747 }
3748 }
3749
3750 // Fall back to legalized types.
3751 std::pair<InstructionCost, MVT> LTSrc = getTypeLegalizationCost(Src);
3752 std::pair<InstructionCost, MVT> LTDest = getTypeLegalizationCost(Dst);
3753
3754 // If we're truncating to the same legalized type - just assume its free.
3755 if (ISD == ISD::TRUNCATE && LTSrc.second == LTDest.second)
3756 return TTI::TCC_Free;
3757
3758 if (ST->useAVX512Regs()) {
3759 if (ST->hasBWI())
3760 if (const auto *Entry = ConvertCostTableLookup(
3761 AVX512BWConversionTbl, ISD, LTDest.second, LTSrc.second))
3762 if (auto KindCost = Entry->Cost[CostKind])
3763 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3764
3765 if (ST->hasDQI())
3766 if (const auto *Entry = ConvertCostTableLookup(
3767 AVX512DQConversionTbl, ISD, LTDest.second, LTSrc.second))
3768 if (auto KindCost = Entry->Cost[CostKind])
3769 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3770
3771 if (ST->hasAVX512())
3772 if (const auto *Entry = ConvertCostTableLookup(
3773 AVX512FConversionTbl, ISD, LTDest.second, LTSrc.second))
3774 if (auto KindCost = Entry->Cost[CostKind])
3775 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3776 }
3777
3778 if (ST->hasBWI())
3779 if (const auto *Entry = ConvertCostTableLookup(AVX512BWVLConversionTbl, ISD,
3780 LTDest.second, LTSrc.second))
3781 if (auto KindCost = Entry->Cost[CostKind])
3782 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3783
3784 if (ST->hasDQI())
3785 if (const auto *Entry = ConvertCostTableLookup(AVX512DQVLConversionTbl, ISD,
3786 LTDest.second, LTSrc.second))
3787 if (auto KindCost = Entry->Cost[CostKind])
3788 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3789
3790 if (ST->hasAVX512())
3791 if (const auto *Entry = ConvertCostTableLookup(AVX512VLConversionTbl, ISD,
3792 LTDest.second, LTSrc.second))
3793 if (auto KindCost = Entry->Cost[CostKind])
3794 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3795
3796 if (ST->hasAVX2())
3797 if (const auto *Entry = ConvertCostTableLookup(AVX2ConversionTbl, ISD,
3798 LTDest.second, LTSrc.second))
3799 if (auto KindCost = Entry->Cost[CostKind])
3800 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3801
3802 if (ST->hasAVX())
3803 if (const auto *Entry = ConvertCostTableLookup(AVXConversionTbl, ISD,
3804 LTDest.second, LTSrc.second))
3805 if (auto KindCost = Entry->Cost[CostKind])
3806 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3807
3808 if (ST->hasF16C()) {
3809 if (const auto *Entry = ConvertCostTableLookup(F16ConversionTbl, ISD,
3810 LTDest.second, LTSrc.second))
3811 if (auto KindCost = Entry->Cost[CostKind])
3812 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3813 }
3814
3815 if (ST->hasSSE41())
3816 if (const auto *Entry = ConvertCostTableLookup(SSE41ConversionTbl, ISD,
3817 LTDest.second, LTSrc.second))
3818 if (auto KindCost = Entry->Cost[CostKind])
3819 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3820
3821 if (ST->hasSSE2())
3822 if (const auto *Entry = ConvertCostTableLookup(SSE2ConversionTbl, ISD,
3823 LTDest.second, LTSrc.second))
3824 if (auto KindCost = Entry->Cost[CostKind])
3825 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3826
3827 // Fallback, for i8/i16 sitofp/uitofp cases we need to extend to i32 for
3828 // sitofp.
3829 if ((ISD == ISD::SINT_TO_FP || ISD == ISD::UINT_TO_FP) &&
3830 1 < Src->getScalarSizeInBits() && Src->getScalarSizeInBits() < 32) {
3831 Type *ExtSrc = Src->getWithNewBitWidth(32);
3832 unsigned ExtOpc =
3833 (ISD == ISD::SINT_TO_FP) ? Instruction::SExt : Instruction::ZExt;
3834
3835 // For scalar loads the extend would be free.
3836 InstructionCost ExtCost = 0;
3837 if (!(Src->isIntegerTy() && I && isa<LoadInst>(I->getOperand(0))))
3838 ExtCost = getCastInstrCost(ExtOpc, ExtSrc, Src, CCH, CostKind);
3839
3840 return ExtCost + getCastInstrCost(Instruction::SIToFP, Dst, ExtSrc,
3842 }
3843
3844 // Fallback for fptosi/fptoui i8/i16 cases we need to truncate from fptosi
3845 // i32.
3846 if ((ISD == ISD::FP_TO_SINT || ISD == ISD::FP_TO_UINT) &&
3847 1 < Dst->getScalarSizeInBits() && Dst->getScalarSizeInBits() < 32) {
3848 Type *TruncDst = Dst->getWithNewBitWidth(32);
3849 return getCastInstrCost(Instruction::FPToSI, TruncDst, Src, CCH, CostKind) +
3850 getCastInstrCost(Instruction::Trunc, Dst, TruncDst,
3852 }
3853
3854 // TODO: Allow non-throughput costs that aren't binary.
3855 auto AdjustCost = [&CostKind](InstructionCost Cost,
3858 return Cost == 0 ? 0 : N;
3859 return Cost * N;
3860 };
3861 return AdjustCost(
3862 BaseT::getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I));
3863}
3864
3865// Additive cost for a predicated op's "predicate fanout": a select, masked
3866// load/store or gather/scatter keeps a compact <N x i1> mask, but if its data
3867// legalizes into more parts than the mask, codegen builds a sub-mask per extra
3868// part (kshiftr on AVX-512, unpack/extend on SSE/AVX) the per-part tables miss.
3869// FanoutCostPerPart is a tie-break: it beats the vectorizer's widest-VF bias.
3871 Type *DataVTy, Type *MaskVTy) {
3872 constexpr unsigned FanoutCostPerPart = 4;
3873 unsigned DataParts = TTI.getNumberOfParts(DataVTy);
3874 unsigned MaskParts = TTI.getNumberOfParts(MaskVTy);
3875 if (DataParts > MaskParts && MaskParts > 0)
3876 return InstructionCost((DataParts - MaskParts) * FanoutCostPerPart);
3877 return InstructionCost(0);
3878}
3879
3881 unsigned Opcode, Type *ValTy, Type *CondTy, CmpInst::Predicate VecPred,
3883 TTI::OperandValueInfo Op2Info, const Instruction *I) const {
3884 // Early out if this type isn't scalar/vector integer/float.
3885 if (!(ValTy->isIntOrIntVectorTy() || ValTy->isFPOrFPVectorTy()))
3886 return BaseT::getCmpSelInstrCost(Opcode, ValTy, CondTy, VecPred, CostKind,
3887 Op1Info, Op2Info, I);
3888
3889 // Legalize the type.
3890 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(ValTy);
3891
3892 MVT MTy = LT.second;
3893
3894 int ISD = TLI->InstructionOpcodeToISD(Opcode);
3895 assert(ISD && "Invalid opcode");
3896
3897 // Predicate fanout (see getPredicateFanoutCost), AVX-512 only: on SSE/AVX a
3898 // select blend is already priced per part, so charging it there shrinks VF.
3899 InstructionCost MaskExpCost = 0;
3900 if (Opcode == Instruction::Select && ST->hasAVX512() &&
3902 MaskExpCost = getPredicateFanoutCost(*this, ValTy, CondTy);
3903
3904 InstructionCost ExtraCost = 0;
3905 if (Opcode == Instruction::ICmp || Opcode == Instruction::FCmp) {
3906 // Some vector comparison predicates cost extra instructions.
3907 // TODO: Adjust ExtraCost based on CostKind?
3908 // TODO: Should we invert this and assume worst case cmp costs
3909 // and reduce for particular predicates?
3910 if (MTy.isVector() &&
3911 !((ST->hasXOP() && (!ST->hasAVX2() || MTy.is128BitVector())) ||
3912 (ST->hasAVX512() && 32 <= MTy.getScalarSizeInBits()) ||
3913 ST->hasBWI())) {
3914 // Fallback to I if a specific predicate wasn't specified.
3915 CmpInst::Predicate Pred = VecPred;
3916 if (I && (Pred == CmpInst::BAD_ICMP_PREDICATE ||
3918 Pred = cast<CmpInst>(I)->getPredicate();
3919
3920 bool CmpWithConstant = false;
3921 if (auto *CmpInstr = dyn_cast_or_null<CmpInst>(I))
3922 CmpWithConstant = isa<Constant>(CmpInstr->getOperand(1));
3923
3924 switch (Pred) {
3926 // xor(cmpeq(x,y),-1)
3927 ExtraCost = CmpWithConstant ? 0 : 1;
3928 break;
3931 // xor(cmpgt(x,y),-1)
3932 ExtraCost = CmpWithConstant ? 0 : 1;
3933 break;
3936 // cmpgt(xor(x,signbit),xor(y,signbit))
3937 // xor(cmpeq(pmaxu(x,y),x),-1)
3938 ExtraCost = CmpWithConstant ? 1 : 2;
3939 break;
3942 if ((ST->hasSSE41() && MTy.getScalarSizeInBits() == 32) ||
3943 (ST->hasSSE2() && MTy.getScalarSizeInBits() < 32)) {
3944 // cmpeq(psubus(x,y),0)
3945 // cmpeq(pminu(x,y),x)
3946 ExtraCost = 1;
3947 } else {
3948 // xor(cmpgt(xor(x,signbit),xor(y,signbit)),-1)
3949 ExtraCost = CmpWithConstant ? 2 : 3;
3950 }
3951 break;
3954 // Without AVX we need to expand FCMP_ONE/FCMP_UEQ cases.
3955 // Use FCMP_UEQ expansion - FCMP_ONE should be the same.
3956 if (CondTy && !ST->hasAVX())
3957 return getCmpSelInstrCost(Opcode, ValTy, CondTy,
3959 Op1Info, Op2Info) +
3960 getCmpSelInstrCost(Opcode, ValTy, CondTy,
3962 Op1Info, Op2Info) +
3963 getArithmeticInstrCost(Instruction::Or, CondTy, CostKind);
3964
3965 break;
3968 // Assume worst case scenario and add the maximum extra cost.
3969 ExtraCost = 3;
3970 break;
3971 default:
3972 break;
3973 }
3974 }
3975 }
3976
3977 static const CostKindTblEntry SLMCostTbl[] = {
3978 // slm pcmpeq/pcmpgt throughput is 2
3979 { ISD::SETCC, MVT::v2i64, { 2, 5, 1, 2 } },
3980 // slm pblendvb/blendvpd/blendvps throughput is 4
3981 { ISD::SELECT, MVT::v2f64, { 4, 4, 1, 3 } }, // vblendvpd
3982 { ISD::SELECT, MVT::v4f32, { 4, 4, 1, 3 } }, // vblendvps
3983 { ISD::SELECT, MVT::v2i64, { 4, 4, 1, 3 } }, // pblendvb
3984 { ISD::SELECT, MVT::v8i32, { 4, 4, 1, 3 } }, // pblendvb
3985 { ISD::SELECT, MVT::v8i16, { 4, 4, 1, 3 } }, // pblendvb
3986 { ISD::SELECT, MVT::v16i8, { 4, 4, 1, 3 } }, // pblendvb
3987 };
3988
3989 static const CostKindTblEntry AVX512BWCostTbl[] = {
3990 { ISD::SETCC, MVT::v32i16, { 1, 1, 1, 1 } },
3991 { ISD::SETCC, MVT::v16i16, { 1, 1, 1, 1 } },
3992 { ISD::SETCC, MVT::v64i8, { 1, 1, 1, 1 } },
3993 { ISD::SETCC, MVT::v32i8, { 1, 1, 1, 1 } },
3994
3995 { ISD::SELECT, MVT::v32i16, { 1, 1, 1, 1 } },
3996 { ISD::SELECT, MVT::v64i8, { 1, 1, 1, 1 } },
3997 };
3998
3999 static const CostKindTblEntry AVX512CostTbl[] = {
4000 { ISD::SETCC, MVT::v8f64, { 1, 4, 1, 1 } },
4001 { ISD::SETCC, MVT::v4f64, { 1, 4, 1, 1 } },
4002 { ISD::SETCC, MVT::v16f32, { 1, 4, 1, 1 } },
4003 { ISD::SETCC, MVT::v8f32, { 1, 4, 1, 1 } },
4004
4005 { ISD::SETCC, MVT::v8i64, { 1, 1, 1, 1 } },
4006 { ISD::SETCC, MVT::v4i64, { 1, 1, 1, 1 } },
4007 { ISD::SETCC, MVT::v2i64, { 1, 1, 1, 1 } },
4008 { ISD::SETCC, MVT::v16i32, { 1, 1, 1, 1 } },
4009 { ISD::SETCC, MVT::v8i32, { 1, 1, 1, 1 } },
4010 { ISD::SETCC, MVT::v32i16, { 3, 7, 5, 5 } },
4011 { ISD::SETCC, MVT::v64i8, { 3, 7, 5, 5 } },
4012
4013 { ISD::SELECT, MVT::v8i64, { 1, 1, 1, 1 } },
4014 { ISD::SELECT, MVT::v4i64, { 1, 1, 1, 1 } },
4015 { ISD::SELECT, MVT::v2i64, { 1, 1, 1, 1 } },
4016 { ISD::SELECT, MVT::v16i32, { 1, 1, 1, 1 } },
4017 { ISD::SELECT, MVT::v8i32, { 1, 1, 1, 1 } },
4018 { ISD::SELECT, MVT::v4i32, { 1, 1, 1, 1 } },
4019 { ISD::SELECT, MVT::v8f64, { 1, 1, 1, 1 } },
4020 { ISD::SELECT, MVT::v4f64, { 1, 1, 1, 1 } },
4021 { ISD::SELECT, MVT::v2f64, { 1, 1, 1, 1 } },
4022 { ISD::SELECT, MVT::f64, { 1, 1, 1, 1 } },
4023 { ISD::SELECT, MVT::v16f32, { 1, 1, 1, 1 } },
4024 { ISD::SELECT, MVT::v8f32 , { 1, 1, 1, 1 } },
4025 { ISD::SELECT, MVT::v4f32, { 1, 1, 1, 1 } },
4026 { ISD::SELECT, MVT::f32 , { 1, 1, 1, 1 } },
4027
4028 { ISD::SELECT, MVT::v32i16, { 2, 2, 4, 4 } },
4029 { ISD::SELECT, MVT::v16i16, { 1, 1, 1, 1 } },
4030 { ISD::SELECT, MVT::v8i16, { 1, 1, 1, 1 } },
4031 { ISD::SELECT, MVT::v64i8, { 2, 2, 4, 4 } },
4032 { ISD::SELECT, MVT::v32i8, { 1, 1, 1, 1 } },
4033 { ISD::SELECT, MVT::v16i8, { 1, 1, 1, 1 } },
4034 };
4035
4036 static const CostKindTblEntry AVX2CostTbl[] = {
4037 { ISD::SETCC, MVT::v4f64, { 1, 4, 1, 2 } },
4038 { ISD::SETCC, MVT::v2f64, { 1, 4, 1, 1 } },
4039 { ISD::SETCC, MVT::f64, { 1, 4, 1, 1 } },
4040 { ISD::SETCC, MVT::v8f32, { 1, 4, 1, 2 } },
4041 { ISD::SETCC, MVT::v4f32, { 1, 4, 1, 1 } },
4042 { ISD::SETCC, MVT::f32, { 1, 4, 1, 1 } },
4043
4044 { ISD::SETCC, MVT::v4i64, { 1, 1, 1, 2 } },
4045 { ISD::SETCC, MVT::v8i32, { 1, 1, 1, 2 } },
4046 { ISD::SETCC, MVT::v16i16, { 1, 1, 1, 2 } },
4047 { ISD::SETCC, MVT::v32i8, { 1, 1, 1, 2 } },
4048
4049 { ISD::SELECT, MVT::v4f64, { 2, 2, 1, 2 } }, // vblendvpd
4050 { ISD::SELECT, MVT::v8f32, { 2, 2, 1, 2 } }, // vblendvps
4051 { ISD::SELECT, MVT::v4i64, { 2, 2, 1, 2 } }, // pblendvb
4052 { ISD::SELECT, MVT::v8i32, { 2, 2, 1, 2 } }, // pblendvb
4053 { ISD::SELECT, MVT::v16i16, { 2, 2, 1, 2 } }, // pblendvb
4054 { ISD::SELECT, MVT::v32i8, { 2, 2, 1, 2 } }, // pblendvb
4055 };
4056
4057 static const CostKindTblEntry XOPCostTbl[] = {
4058 { ISD::SETCC, MVT::v4i64, { 4, 2, 5, 6 } },
4059 { ISD::SETCC, MVT::v2i64, { 1, 1, 1, 1 } },
4060 };
4061
4062 static const CostKindTblEntry AVX1CostTbl[] = {
4063 { ISD::SETCC, MVT::v4f64, { 2, 3, 1, 2 } },
4064 { ISD::SETCC, MVT::v2f64, { 1, 3, 1, 1 } },
4065 { ISD::SETCC, MVT::f64, { 1, 3, 1, 1 } },
4066 { ISD::SETCC, MVT::v8f32, { 2, 3, 1, 2 } },
4067 { ISD::SETCC, MVT::v4f32, { 1, 3, 1, 1 } },
4068 { ISD::SETCC, MVT::f32, { 1, 3, 1, 1 } },
4069
4070 // AVX1 does not support 8-wide integer compare.
4071 { ISD::SETCC, MVT::v4i64, { 4, 2, 5, 6 } },
4072 { ISD::SETCC, MVT::v8i32, { 4, 2, 5, 6 } },
4073 { ISD::SETCC, MVT::v16i16, { 4, 2, 5, 6 } },
4074 { ISD::SETCC, MVT::v32i8, { 4, 2, 5, 6 } },
4075
4076 { ISD::SELECT, MVT::v4f64, { 3, 3, 1, 2 } }, // vblendvpd
4077 { ISD::SELECT, MVT::v8f32, { 3, 3, 1, 2 } }, // vblendvps
4078 { ISD::SELECT, MVT::v4i64, { 3, 3, 1, 2 } }, // vblendvpd
4079 { ISD::SELECT, MVT::v8i32, { 3, 3, 1, 2 } }, // vblendvps
4080 { ISD::SELECT, MVT::v16i16, { 3, 3, 3, 3 } }, // vandps + vandnps + vorps
4081 { ISD::SELECT, MVT::v32i8, { 3, 3, 3, 3 } }, // vandps + vandnps + vorps
4082 };
4083
4084 static const CostKindTblEntry SSE42CostTbl[] = {
4085 { ISD::SETCC, MVT::v2i64, { 1, 2, 1, 2 } },
4086 };
4087
4088 static const CostKindTblEntry SSE41CostTbl[] = {
4089 { ISD::SETCC, MVT::v2f64, { 1, 5, 1, 1 } },
4090 { ISD::SETCC, MVT::v4f32, { 1, 5, 1, 1 } },
4091
4092 { ISD::SELECT, MVT::v2f64, { 2, 2, 1, 2 } }, // blendvpd
4093 { ISD::SELECT, MVT::f64, { 2, 2, 1, 2 } }, // blendvpd
4094 { ISD::SELECT, MVT::v4f32, { 2, 2, 1, 2 } }, // blendvps
4095 { ISD::SELECT, MVT::f32 , { 2, 2, 1, 2 } }, // blendvps
4096 { ISD::SELECT, MVT::v2i64, { 2, 2, 1, 2 } }, // pblendvb
4097 { ISD::SELECT, MVT::v4i32, { 2, 2, 1, 2 } }, // pblendvb
4098 { ISD::SELECT, MVT::v8i16, { 2, 2, 1, 2 } }, // pblendvb
4099 { ISD::SELECT, MVT::v16i8, { 2, 2, 1, 2 } }, // pblendvb
4100 };
4101
4102 static const CostKindTblEntry SSE2CostTbl[] = {
4103 { ISD::SETCC, MVT::v2f64, { 2, 5, 1, 1 } },
4104 { ISD::SETCC, MVT::f64, { 1, 5, 1, 1 } },
4105
4106 { ISD::SETCC, MVT::v2i64, { 5, 4, 5, 5 } }, // pcmpeqd/pcmpgtd expansion
4107 { ISD::SETCC, MVT::v4i32, { 1, 1, 1, 1 } },
4108 { ISD::SETCC, MVT::v8i16, { 1, 1, 1, 1 } },
4109 { ISD::SETCC, MVT::v16i8, { 1, 1, 1, 1 } },
4110
4111 { ISD::SELECT, MVT::v2f64, { 2, 2, 3, 3 } }, // andpd + andnpd + orpd
4112 { ISD::SELECT, MVT::f64, { 2, 2, 3, 3 } }, // andpd + andnpd + orpd
4113 { ISD::SELECT, MVT::v2i64, { 2, 2, 3, 3 } }, // pand + pandn + por
4114 { ISD::SELECT, MVT::v4i32, { 2, 2, 3, 3 } }, // pand + pandn + por
4115 { ISD::SELECT, MVT::v8i16, { 2, 2, 3, 3 } }, // pand + pandn + por
4116 { ISD::SELECT, MVT::v16i8, { 2, 2, 3, 3 } }, // pand + pandn + por
4117 };
4118
4119 static const CostKindTblEntry SSE1CostTbl[] = {
4120 { ISD::SETCC, MVT::v4f32, { 2, 5, 1, 1 } },
4121 { ISD::SETCC, MVT::f32, { 1, 5, 1, 1 } },
4122
4123 { ISD::SELECT, MVT::v4f32, { 2, 2, 3, 3 } }, // andps + andnps + orps
4124 { ISD::SELECT, MVT::f32, { 2, 2, 3, 3 } }, // andps + andnps + orps
4125 };
4126
4127 if (ST->useSLMArithCosts())
4128 if (const auto *Entry = CostTableLookup(SLMCostTbl, ISD, MTy))
4129 if (auto KindCost = Entry->Cost[CostKind])
4130 return LT.first * (ExtraCost + *KindCost) + MaskExpCost;
4131
4132 if (ST->hasBWI())
4133 if (const auto *Entry = CostTableLookup(AVX512BWCostTbl, ISD, MTy))
4134 if (auto KindCost = Entry->Cost[CostKind])
4135 return LT.first * (ExtraCost + *KindCost) + MaskExpCost;
4136
4137 if (ST->hasAVX512())
4138 if (const auto *Entry = CostTableLookup(AVX512CostTbl, ISD, MTy))
4139 if (auto KindCost = Entry->Cost[CostKind])
4140 return LT.first * (ExtraCost + *KindCost) + MaskExpCost;
4141
4142 if (ST->hasAVX2())
4143 if (const auto *Entry = CostTableLookup(AVX2CostTbl, ISD, MTy))
4144 if (auto KindCost = Entry->Cost[CostKind])
4145 return LT.first * (ExtraCost + *KindCost) + MaskExpCost;
4146
4147 if (ST->hasXOP())
4148 if (const auto *Entry = CostTableLookup(XOPCostTbl, ISD, MTy))
4149 if (auto KindCost = Entry->Cost[CostKind])
4150 return LT.first * (ExtraCost + *KindCost) + MaskExpCost;
4151
4152 if (ST->hasAVX())
4153 if (const auto *Entry = CostTableLookup(AVX1CostTbl, ISD, MTy))
4154 if (auto KindCost = Entry->Cost[CostKind])
4155 return LT.first * (ExtraCost + *KindCost) + MaskExpCost;
4156
4157 if (ST->hasSSE42())
4158 if (const auto *Entry = CostTableLookup(SSE42CostTbl, ISD, MTy))
4159 if (auto KindCost = Entry->Cost[CostKind])
4160 return LT.first * (ExtraCost + *KindCost) + MaskExpCost;
4161
4162 if (ST->hasSSE41())
4163 if (const auto *Entry = CostTableLookup(SSE41CostTbl, ISD, MTy))
4164 if (auto KindCost = Entry->Cost[CostKind])
4165 return LT.first * (ExtraCost + *KindCost) + MaskExpCost;
4166
4167 if (ST->hasSSE2())
4168 if (const auto *Entry = CostTableLookup(SSE2CostTbl, ISD, MTy))
4169 if (auto KindCost = Entry->Cost[CostKind])
4170 return LT.first * (ExtraCost + *KindCost) + MaskExpCost;
4171
4172 if (ST->hasSSE1())
4173 if (const auto *Entry = CostTableLookup(SSE1CostTbl, ISD, MTy))
4174 if (auto KindCost = Entry->Cost[CostKind])
4175 return LT.first * (ExtraCost + *KindCost) + MaskExpCost;
4176
4177 // Assume a 3cy latency for fp select ops.
4178 if (CostKind == TTI::TCK_Latency && Opcode == Instruction::Select)
4179 if (ValTy->getScalarType()->isFloatingPointTy())
4180 return 3;
4181
4182 return BaseT::getCmpSelInstrCost(Opcode, ValTy, CondTy, VecPred, CostKind,
4183 Op1Info, Op2Info, I) +
4184 MaskExpCost;
4185}
4186
4188
4189/// Returns true if the square root is divided into with the reciprocal
4190/// allowed and the target replaces the pair with the rsqrt* based estimate.
4192 const X86TargetLowering &TLI,
4193 const DataLayout &DL) {
4194 using namespace PatternMatch;
4195 const IntrinsicInst *II = ICA.getInst();
4196 if (!II || !II->hasOneUse() ||
4197 !match(II->user_back(), m_FDiv(m_Value(), m_Specific(II))) ||
4198 !cast<FPMathOperator>(II->user_back())->hasAllowReciprocal())
4199 return false;
4200 EVT VT = TLI.getValueType(DL, ICA.getReturnType());
4201 return TLI.hasSqrtEstimate(VT, /*Reciprocal=*/true) &&
4202 TLI.getRecipEstimateSqrtEnabled(VT, *II->getFunction()) !=
4204}
4205
4209 // Costs should match the codegen from:
4210 // BITREVERSE: llvm\test\CodeGen\X86\vector-bitreverse.ll
4211 // BSWAP: llvm\test\CodeGen\X86\bswap-vector.ll
4212 // CTLZ: llvm\test\CodeGen\X86\vector-lzcnt-*.ll
4213 // CTPOP: llvm\test\CodeGen\X86\vector-popcnt-*.ll
4214 // CTTZ: llvm\test\CodeGen\X86\vector-tzcnt-*.ll
4215
4216 // TODO: Overflow intrinsics (*ADDO, *SUBO, *MULO) with vector types are not
4217 // specialized in these tables yet.
4218 static const CostKindTblEntry AVX512VBMI2CostTbl[] = {
4219 { ISD::FSHL, MVT::v8i64, { 1, 1, 1, 1 } },
4220 { ISD::FSHL, MVT::v4i64, { 1, 1, 1, 1 } },
4221 { ISD::FSHL, MVT::v2i64, { 1, 1, 1, 1 } },
4222 { ISD::FSHL, MVT::v16i32, { 1, 1, 1, 1 } },
4223 { ISD::FSHL, MVT::v8i32, { 1, 1, 1, 1 } },
4224 { ISD::FSHL, MVT::v4i32, { 1, 1, 1, 1 } },
4225 { ISD::FSHL, MVT::v32i16, { 1, 1, 1, 1 } },
4226 { ISD::FSHL, MVT::v16i16, { 1, 1, 1, 1 } },
4227 { ISD::FSHL, MVT::v8i16, { 1, 1, 1, 1 } },
4228 { ISD::ROTL, MVT::v32i16, { 1, 1, 1, 1 } },
4229 { ISD::ROTL, MVT::v16i16, { 1, 1, 1, 1 } },
4230 { ISD::ROTL, MVT::v8i16, { 1, 1, 1, 1 } },
4231 { ISD::ROTR, MVT::v32i16, { 1, 1, 1, 1 } },
4232 { ISD::ROTR, MVT::v16i16, { 1, 1, 1, 1 } },
4233 { ISD::ROTR, MVT::v8i16, { 1, 1, 1, 1 } },
4234 { X86ISD::VROTLI, MVT::v32i16, { 1, 1, 1, 1 } },
4235 { X86ISD::VROTLI, MVT::v16i16, { 1, 1, 1, 1 } },
4236 { X86ISD::VROTLI, MVT::v8i16, { 1, 1, 1, 1 } },
4237 };
4238 static const CostKindTblEntry AVX512BITALGCostTbl[] = {
4239 { ISD::CTPOP, MVT::v32i16, { 1, 1, 1, 1 } },
4240 { ISD::CTPOP, MVT::v64i8, { 1, 1, 1, 1 } },
4241 { ISD::CTPOP, MVT::v16i16, { 1, 1, 1, 1 } },
4242 { ISD::CTPOP, MVT::v32i8, { 1, 1, 1, 1 } },
4243 { ISD::CTPOP, MVT::v8i16, { 1, 1, 1, 1 } },
4244 { ISD::CTPOP, MVT::v16i8, { 1, 1, 1, 1 } },
4245 };
4246 static const CostKindTblEntry AVX512VPOPCNTDQCostTbl[] = {
4247 { ISD::CTPOP, MVT::v8i64, { 1, 1, 1, 1 } },
4248 { ISD::CTPOP, MVT::v16i32, { 1, 1, 1, 1 } },
4249 { ISD::CTPOP, MVT::v4i64, { 1, 1, 1, 1 } },
4250 { ISD::CTPOP, MVT::v8i32, { 1, 1, 1, 1 } },
4251 { ISD::CTPOP, MVT::v2i64, { 1, 1, 1, 1 } },
4252 { ISD::CTPOP, MVT::v4i32, { 1, 1, 1, 1 } },
4253 };
4254 static const CostKindTblEntry AVX512CDCostTbl[] = {
4255 { ISD::CTLZ, MVT::v8i64, { 1, 5, 1, 1 } },
4256 { ISD::CTLZ, MVT::v16i32, { 1, 5, 1, 1 } },
4257 { ISD::CTLZ, MVT::v32i16, { 18, 27, 23, 27 } },
4258 { ISD::CTLZ, MVT::v64i8, { 3, 16, 9, 11 } },
4259 { ISD::CTLZ, MVT::v4i64, { 1, 5, 1, 1 } },
4260 { ISD::CTLZ, MVT::v8i32, { 1, 5, 1, 1 } },
4261 { ISD::CTLZ, MVT::v16i16, { 8, 19, 11, 13 } },
4262 { ISD::CTLZ, MVT::v32i8, { 2, 11, 9, 10 } },
4263 { ISD::CTLZ, MVT::v2i64, { 1, 5, 1, 1 } },
4264 { ISD::CTLZ, MVT::v4i32, { 1, 5, 1, 1 } },
4265 { ISD::CTLZ, MVT::v8i16, { 3, 15, 4, 6 } },
4266 { ISD::CTLZ, MVT::v16i8, { 2, 10, 9, 10 } },
4267
4268 { ISD::CTTZ, MVT::v8i64, { 2, 8, 6, 7 } },
4269 { ISD::CTTZ, MVT::v16i32, { 2, 8, 6, 7 } },
4270 { ISD::CTTZ, MVT::v4i64, { 1, 8, 6, 6 } },
4271 { ISD::CTTZ, MVT::v8i32, { 1, 8, 6, 6 } },
4272 { ISD::CTTZ, MVT::v2i64, { 1, 8, 6, 6 } },
4273 { ISD::CTTZ, MVT::v4i32, { 1, 8, 6, 6 } },
4274 };
4275 static const CostKindTblEntry AVX512BWCostTbl[] = {
4276 { ISD::ABS, MVT::v32i16, { 1, 1, 1, 1 } },
4277 { ISD::ABS, MVT::v64i8, { 1, 1, 1, 1 } },
4278 { ISD::BITREVERSE, MVT::v2i64, { 3, 10, 10, 11 } },
4279 { ISD::BITREVERSE, MVT::v4i64, { 3, 11, 10, 11 } },
4280 { ISD::BITREVERSE, MVT::v8i64, { 3, 12, 10, 14 } },
4281 { ISD::BITREVERSE, MVT::v4i32, { 3, 10, 10, 11 } },
4282 { ISD::BITREVERSE, MVT::v8i32, { 3, 11, 10, 11 } },
4283 { ISD::BITREVERSE, MVT::v16i32, { 3, 12, 10, 14 } },
4284 { ISD::BITREVERSE, MVT::v8i16, { 3, 10, 10, 11 } },
4285 { ISD::BITREVERSE, MVT::v16i16, { 3, 11, 10, 11 } },
4286 { ISD::BITREVERSE, MVT::v32i16, { 3, 12, 10, 14 } },
4287 { ISD::BITREVERSE, MVT::v16i8, { 2, 5, 9, 9 } },
4288 { ISD::BITREVERSE, MVT::v32i8, { 2, 5, 9, 9 } },
4289 { ISD::BITREVERSE, MVT::v64i8, { 2, 5, 9, 12 } },
4290 { ISD::BSWAP, MVT::v2i64, { 1, 1, 1, 2 } },
4291 { ISD::BSWAP, MVT::v4i64, { 1, 1, 1, 2 } },
4292 { ISD::BSWAP, MVT::v8i64, { 1, 1, 1, 2 } },
4293 { ISD::BSWAP, MVT::v4i32, { 1, 1, 1, 2 } },
4294 { ISD::BSWAP, MVT::v8i32, { 1, 1, 1, 2 } },
4295 { ISD::BSWAP, MVT::v16i32, { 1, 1, 1, 2 } },
4296 { ISD::BSWAP, MVT::v8i16, { 1, 1, 1, 2 } },
4297 { ISD::BSWAP, MVT::v16i16, { 1, 1, 1, 2 } },
4298 { ISD::BSWAP, MVT::v32i16, { 1, 1, 1, 2 } },
4299 { ISD::CTLZ, MVT::v8i64, { 8, 22, 23, 23 } },
4300 { ISD::CTLZ, MVT::v16i32, { 8, 23, 25, 25 } },
4301 { ISD::CTLZ, MVT::v32i16, { 4, 15, 15, 16 } },
4302 { ISD::CTLZ, MVT::v64i8, { 3, 12, 10, 9 } },
4303 { ISD::CTPOP, MVT::v2i64, { 3, 7, 10, 10 } },
4304 { ISD::CTPOP, MVT::v4i64, { 3, 7, 10, 10 } },
4305 { ISD::CTPOP, MVT::v8i64, { 3, 8, 10, 12 } },
4306 { ISD::CTPOP, MVT::v4i32, { 7, 11, 14, 14 } },
4307 { ISD::CTPOP, MVT::v8i32, { 7, 11, 14, 14 } },
4308 { ISD::CTPOP, MVT::v16i32, { 7, 12, 14, 16 } },
4309 { ISD::CTPOP, MVT::v8i16, { 2, 7, 11, 11 } },
4310 { ISD::CTPOP, MVT::v16i16, { 2, 7, 11, 11 } },
4311 { ISD::CTPOP, MVT::v32i16, { 3, 7, 11, 13 } },
4312 { ISD::CTPOP, MVT::v16i8, { 2, 4, 8, 8 } },
4313 { ISD::CTPOP, MVT::v32i8, { 2, 4, 8, 8 } },
4314 { ISD::CTPOP, MVT::v64i8, { 2, 5, 8, 10 } },
4315 { ISD::CTTZ, MVT::v8i16, { 3, 9, 14, 14 } },
4316 { ISD::CTTZ, MVT::v16i16, { 3, 9, 14, 14 } },
4317 { ISD::CTTZ, MVT::v32i16, { 3, 10, 14, 16 } },
4318 { ISD::CTTZ, MVT::v16i8, { 2, 6, 11, 11 } },
4319 { ISD::CTTZ, MVT::v32i8, { 2, 6, 11, 11 } },
4320 { ISD::CTTZ, MVT::v64i8, { 3, 7, 11, 13 } },
4321 { ISD::MULHS, MVT::v32i16, { 1, 5, 1, 1 } },
4322 { ISD::MULHU, MVT::v32i16, { 1, 5, 1, 1 } },
4323 { ISD::ROTL, MVT::v32i16, { 2, 8, 6, 8 } },
4324 { ISD::ROTL, MVT::v16i16, { 2, 8, 6, 7 } },
4325 { ISD::ROTL, MVT::v8i16, { 2, 7, 6, 7 } },
4326 { ISD::ROTL, MVT::v64i8, { 5, 6, 11, 12 } },
4327 { ISD::ROTL, MVT::v32i8, { 5, 15, 7, 10 } },
4328 { ISD::ROTL, MVT::v16i8, { 5, 15, 7, 10 } },
4329 { ISD::ROTR, MVT::v32i16, { 2, 8, 6, 8 } },
4330 { ISD::ROTR, MVT::v16i16, { 2, 8, 6, 7 } },
4331 { ISD::ROTR, MVT::v8i16, { 2, 7, 6, 7 } },
4332 { ISD::ROTR, MVT::v64i8, { 5, 6, 12, 14 } },
4333 { ISD::ROTR, MVT::v32i8, { 5, 14, 6, 9 } },
4334 { ISD::ROTR, MVT::v16i8, { 5, 14, 6, 9 } },
4335 { X86ISD::VROTLI, MVT::v32i16, { 2, 5, 3, 3 } },
4336 { X86ISD::VROTLI, MVT::v16i16, { 1, 5, 3, 3 } },
4337 { X86ISD::VROTLI, MVT::v8i16, { 1, 5, 3, 3 } },
4338 { X86ISD::VROTLI, MVT::v64i8, { 2, 9, 3, 4 } },
4339 { X86ISD::VROTLI, MVT::v32i8, { 1, 9, 3, 4 } },
4340 { X86ISD::VROTLI, MVT::v16i8, { 1, 8, 3, 4 } },
4341 { ISD::SADDSAT, MVT::v32i16, { 1, 1, 1, 1 } },
4342 { ISD::SADDSAT, MVT::v64i8, { 1, 1, 1, 1 } },
4343 { ISD::SMAX, MVT::v32i16, { 1, 1, 1, 1 } },
4344 { ISD::SMAX, MVT::v64i8, { 1, 1, 1, 1 } },
4345 { ISD::SMIN, MVT::v32i16, { 1, 1, 1, 1 } },
4346 { ISD::SMIN, MVT::v64i8, { 1, 1, 1, 1 } },
4347 { ISD::SMULO, MVT::v32i16, { 3, 6, 4, 4 } },
4348 { ISD::SMULO, MVT::v64i8, { 8, 21, 17, 18 } },
4349 { ISD::UMULO, MVT::v32i16, { 2, 5, 3, 3 } },
4350 { ISD::UMULO, MVT::v64i8, { 8, 15, 15, 16 } },
4351 { ISD::SSUBSAT, MVT::v32i16, { 1, 1, 1, 1 } },
4352 { ISD::SSUBSAT, MVT::v64i8, { 1, 1, 1, 1 } },
4353 { ISD::UADDSAT, MVT::v32i16, { 1, 1, 1, 1 } },
4354 { ISD::UADDSAT, MVT::v64i8, { 1, 1, 1, 1 } },
4355 { ISD::UMAX, MVT::v32i16, { 1, 1, 1, 1 } },
4356 { ISD::UMAX, MVT::v64i8, { 1, 1, 1, 1 } },
4357 { ISD::UMIN, MVT::v32i16, { 1, 1, 1, 1 } },
4358 { ISD::UMIN, MVT::v64i8, { 1, 1, 1, 1 } },
4359 { ISD::USUBSAT, MVT::v32i16, { 1, 1, 1, 1 } },
4360 { ISD::USUBSAT, MVT::v64i8, { 1, 1, 1, 1 } },
4361 };
4362 static const CostKindTblEntry AVX512CostTbl[] = {
4363 { ISD::ABS, MVT::v8i64, { 1, 1, 1, 1 } },
4364 { ISD::ABS, MVT::v4i64, { 1, 1, 1, 1 } },
4365 { ISD::ABS, MVT::v2i64, { 1, 1, 1, 1 } },
4366 { ISD::ABS, MVT::v16i32, { 1, 1, 1, 1 } },
4367 { ISD::ABS, MVT::v8i32, { 1, 1, 1, 1 } },
4368 { ISD::ABS, MVT::v32i16, { 2, 7, 4, 4 } },
4369 { ISD::ABS, MVT::v16i16, { 1, 1, 1, 1 } },
4370 { ISD::ABS, MVT::v64i8, { 2, 7, 4, 4 } },
4371 { ISD::ABS, MVT::v32i8, { 1, 1, 1, 1 } },
4372 { ISD::BITREVERSE, MVT::v8i64, { 9, 13, 20, 20 } },
4373 { ISD::BITREVERSE, MVT::v16i32, { 9, 13, 20, 20 } },
4374 { ISD::BITREVERSE, MVT::v32i16, { 9, 13, 20, 20 } },
4375 { ISD::BITREVERSE, MVT::v64i8, { 6, 11, 17, 17 } },
4376 { ISD::BSWAP, MVT::v8i64, { 4, 7, 5, 5 } },
4377 { ISD::BSWAP, MVT::v16i32, { 4, 7, 5, 5 } },
4378 { ISD::BSWAP, MVT::v32i16, { 4, 7, 5, 5 } },
4379 { ISD::CTLZ, MVT::v8i64, { 10, 28, 32, 32 } },
4380 { ISD::CTLZ, MVT::v16i32, { 12, 30, 38, 38 } },
4381 { ISD::CTLZ, MVT::v32i16, { 8, 15, 29, 29 } },
4382 { ISD::CTLZ, MVT::v64i8, { 6, 11, 19, 19 } },
4383 { ISD::CTPOP, MVT::v8i64, { 16, 16, 19, 19 } },
4384 { ISD::CTPOP, MVT::v16i32, { 24, 19, 27, 27 } },
4385 { ISD::CTPOP, MVT::v32i16, { 18, 15, 22, 22 } },
4386 { ISD::CTPOP, MVT::v64i8, { 12, 11, 16, 16 } },
4387 { ISD::CTTZ, MVT::v8i64, { 2, 8, 6, 7 } },
4388 { ISD::CTTZ, MVT::v16i32, { 2, 8, 6, 7 } },
4389 { ISD::CTTZ, MVT::v32i16, { 7, 17, 27, 27 } },
4390 { ISD::CTTZ, MVT::v64i8, { 6, 13, 21, 21 } },
4391 { ISD::MULHS, MVT::v16i32, { 3, 10, 6, 7 } },
4392 { ISD::MULHS, MVT::v8i32, { 3, 9, 6, 6 } },
4393 { ISD::MULHS, MVT::v32i16, { 3, 7, 5, 5 } },
4394 { ISD::MULHS, MVT::v16i16, { 1, 5, 1, 1 } },
4395 { ISD::MULHU, MVT::v16i32, { 3, 10, 6, 7 } },
4396 { ISD::MULHU, MVT::v8i32, { 3, 9, 6, 6 } },
4397 { ISD::MULHU, MVT::v32i16, { 3, 7, 5, 5 } },
4398 { ISD::MULHU, MVT::v16i16, { 1, 5, 1, 1 } },
4399 { ISD::ROTL, MVT::v8i64, { 1, 1, 1, 1 } },
4400 { ISD::ROTL, MVT::v4i64, { 1, 1, 1, 1 } },
4401 { ISD::ROTL, MVT::v2i64, { 1, 1, 1, 1 } },
4402 { ISD::ROTL, MVT::v16i32, { 1, 1, 1, 1 } },
4403 { ISD::ROTL, MVT::v8i32, { 1, 1, 1, 1 } },
4404 { ISD::ROTL, MVT::v4i32, { 1, 1, 1, 1 } },
4405 { ISD::ROTR, MVT::v8i64, { 1, 1, 1, 1 } },
4406 { ISD::ROTR, MVT::v4i64, { 1, 1, 1, 1 } },
4407 { ISD::ROTR, MVT::v2i64, { 1, 1, 1, 1 } },
4408 { ISD::ROTR, MVT::v16i32, { 1, 1, 1, 1 } },
4409 { ISD::ROTR, MVT::v8i32, { 1, 1, 1, 1 } },
4410 { ISD::ROTR, MVT::v4i32, { 1, 1, 1, 1 } },
4411 { X86ISD::VROTLI, MVT::v8i64, { 1, 1, 1, 1 } },
4412 { X86ISD::VROTLI, MVT::v4i64, { 1, 1, 1, 1 } },
4413 { X86ISD::VROTLI, MVT::v2i64, { 1, 1, 1, 1 } },
4414 { X86ISD::VROTLI, MVT::v16i32, { 1, 1, 1, 1 } },
4415 { X86ISD::VROTLI, MVT::v8i32, { 1, 1, 1, 1 } },
4416 { X86ISD::VROTLI, MVT::v4i32, { 1, 1, 1, 1 } },
4417 { ISD::SADDSAT, MVT::v2i64, { 3, 3, 8, 9 } },
4418 { ISD::SADDSAT, MVT::v4i64, { 2, 2, 6, 7 } },
4419 { ISD::SADDSAT, MVT::v8i64, { 3, 3, 6, 7 } },
4420 { ISD::SADDSAT, MVT::v4i32, { 2, 2, 6, 7 } },
4421 { ISD::SADDSAT, MVT::v8i32, { 2, 2, 6, 7 } },
4422 { ISD::SADDSAT, MVT::v16i32, { 3, 3, 6, 7 } },
4423 { ISD::SADDSAT, MVT::v32i16, { 2, 2, 2, 2 } },
4424 { ISD::SADDSAT, MVT::v64i8, { 2, 2, 2, 2 } },
4425 { ISD::SMAX, MVT::v8i64, { 1, 3, 1, 1 } },
4426 { ISD::SMAX, MVT::v16i32, { 1, 1, 1, 1 } },
4427 { ISD::SMAX, MVT::v32i16, { 3, 7, 5, 5 } },
4428 { ISD::SMAX, MVT::v64i8, { 3, 7, 5, 5 } },
4429 { ISD::SMAX, MVT::v4i64, { 1, 3, 1, 1 } },
4430 { ISD::SMAX, MVT::v2i64, { 1, 3, 1, 1 } },
4431 { ISD::SMIN, MVT::v8i64, { 1, 3, 1, 1 } },
4432 { ISD::SMIN, MVT::v16i32, { 1, 1, 1, 1 } },
4433 { ISD::SMIN, MVT::v32i16, { 3, 7, 5, 5 } },
4434 { ISD::SMIN, MVT::v64i8, { 3, 7, 5, 5 } },
4435 { ISD::SMIN, MVT::v4i64, { 1, 3, 1, 1 } },
4436 { ISD::SMIN, MVT::v2i64, { 1, 3, 1, 1 } },
4437 { ISD::SMULO, MVT::v8i64, { 44, 44, 81, 93 } },
4438 { ISD::SMULO, MVT::v16i32, { 5, 12, 9, 11 } },
4439 { ISD::SMULO, MVT::v32i16, { 6, 12, 17, 17 } },
4440 { ISD::SMULO, MVT::v64i8, { 22, 28, 42, 42 } },
4441 { ISD::SSUBSAT, MVT::v2i64, { 2, 13, 9, 10 } },
4442 { ISD::SSUBSAT, MVT::v4i64, { 2, 15, 7, 8 } },
4443 { ISD::SSUBSAT, MVT::v8i64, { 2, 14, 7, 8 } },
4444 { ISD::SSUBSAT, MVT::v4i32, { 2, 14, 7, 8 } },
4445 { ISD::SSUBSAT, MVT::v8i32, { 2, 15, 7, 8 } },
4446 { ISD::SSUBSAT, MVT::v16i32, { 2, 14, 7, 8 } },
4447 { ISD::SSUBSAT, MVT::v32i16, { 2, 2, 2, 2 } },
4448 { ISD::SSUBSAT, MVT::v64i8, { 2, 2, 2, 2 } },
4449 { ISD::UMAX, MVT::v8i64, { 1, 3, 1, 1 } },
4450 { ISD::UMAX, MVT::v16i32, { 1, 1, 1, 1 } },
4451 { ISD::UMAX, MVT::v32i16, { 3, 7, 5, 5 } },
4452 { ISD::UMAX, MVT::v64i8, { 3, 7, 5, 5 } },
4453 { ISD::UMAX, MVT::v4i64, { 1, 3, 1, 1 } },
4454 { ISD::UMAX, MVT::v2i64, { 1, 3, 1, 1 } },
4455 { ISD::UMIN, MVT::v8i64, { 1, 3, 1, 1 } },
4456 { ISD::UMIN, MVT::v16i32, { 1, 1, 1, 1 } },
4457 { ISD::UMIN, MVT::v32i16, { 3, 7, 5, 5 } },
4458 { ISD::UMIN, MVT::v64i8, { 3, 7, 5, 5 } },
4459 { ISD::UMIN, MVT::v4i64, { 1, 3, 1, 1 } },
4460 { ISD::UMIN, MVT::v2i64, { 1, 3, 1, 1 } },
4461 { ISD::UMULO, MVT::v8i64, { 52, 52, 95, 104} },
4462 { ISD::UMULO, MVT::v16i32, { 5, 12, 8, 10 } },
4463 { ISD::UMULO, MVT::v32i16, { 5, 13, 16, 16 } },
4464 { ISD::UMULO, MVT::v64i8, { 18, 24, 30, 30 } },
4465 { ISD::UADDSAT, MVT::v2i64, { 1, 4, 4, 4 } },
4466 { ISD::UADDSAT, MVT::v4i64, { 1, 4, 4, 4 } },
4467 { ISD::UADDSAT, MVT::v8i64, { 1, 4, 4, 4 } },
4468 { ISD::UADDSAT, MVT::v4i32, { 1, 2, 4, 4 } },
4469 { ISD::UADDSAT, MVT::v8i32, { 1, 2, 4, 4 } },
4470 { ISD::UADDSAT, MVT::v16i32, { 2, 2, 4, 4 } },
4471 { ISD::UADDSAT, MVT::v32i16, { 2, 2, 2, 2 } },
4472 { ISD::UADDSAT, MVT::v64i8, { 2, 2, 2, 2 } },
4473 { ISD::USUBSAT, MVT::v2i64, { 1, 4, 2, 2 } },
4474 { ISD::USUBSAT, MVT::v4i64, { 1, 4, 2, 2 } },
4475 { ISD::USUBSAT, MVT::v8i64, { 1, 4, 2, 2 } },
4476 { ISD::USUBSAT, MVT::v8i32, { 1, 2, 2, 2 } },
4477 { ISD::USUBSAT, MVT::v16i32, { 1, 2, 2, 2 } },
4478 { ISD::USUBSAT, MVT::v32i16, { 2, 2, 2, 2 } },
4479 { ISD::USUBSAT, MVT::v64i8, { 2, 2, 2, 2 } },
4480 { ISD::FMAXNUM, MVT::f32, { 2, 2, 3, 3 } },
4481 { ISD::FMAXNUM, MVT::v4f32, { 1, 1, 3, 3 } },
4482 { ISD::FMAXNUM, MVT::v8f32, { 2, 2, 3, 3 } },
4483 { ISD::FMAXNUM, MVT::v16f32, { 4, 4, 3, 3 } },
4484 { ISD::FMAXNUM, MVT::f64, { 2, 2, 3, 3 } },
4485 { ISD::FMAXNUM, MVT::v2f64, { 1, 1, 3, 3 } },
4486 { ISD::FMAXNUM, MVT::v4f64, { 2, 2, 3, 3 } },
4487 { ISD::FMAXNUM, MVT::v8f64, { 3, 3, 3, 3 } },
4488 { ISD::FSQRT, MVT::f32, { 3, 12, 1, 1 } }, // Skylake from http://www.agner.org/
4489 { ISD::FSQRT, MVT::v4f32, { 3, 12, 1, 1 } }, // Skylake from http://www.agner.org/
4490 { ISD::FSQRT, MVT::v8f32, { 6, 12, 1, 1 } }, // Skylake from http://www.agner.org/
4491 { ISD::FSQRT, MVT::v16f32, { 12, 20, 1, 3 } }, // Skylake from http://www.agner.org/
4492 { ISD::FSQRT, MVT::f64, { 6, 18, 1, 1 } }, // Skylake from http://www.agner.org/
4493 { ISD::FSQRT, MVT::v2f64, { 6, 18, 1, 1 } }, // Skylake from http://www.agner.org/
4494 { ISD::FSQRT, MVT::v4f64, { 12, 18, 1, 1 } }, // Skylake from http://www.agner.org/
4495 { ISD::FSQRT, MVT::v8f64, { 24, 32, 1, 3 } }, // Skylake from http://www.agner.org/
4496 };
4497 static const CostKindTblEntry XOPCostTbl[] = {
4498 { ISD::BITREVERSE, MVT::v4i64, { 3, 6, 5, 6 } },
4499 { ISD::BITREVERSE, MVT::v8i32, { 3, 6, 5, 6 } },
4500 { ISD::BITREVERSE, MVT::v16i16, { 3, 6, 5, 6 } },
4501 { ISD::BITREVERSE, MVT::v32i8, { 3, 6, 5, 6 } },
4502 { ISD::BITREVERSE, MVT::v2i64, { 2, 7, 1, 1 } },
4503 { ISD::BITREVERSE, MVT::v4i32, { 2, 7, 1, 1 } },
4504 { ISD::BITREVERSE, MVT::v8i16, { 2, 7, 1, 1 } },
4505 { ISD::BITREVERSE, MVT::v16i8, { 2, 7, 1, 1 } },
4506 { ISD::BITREVERSE, MVT::i64, { 2, 2, 3, 4 } },
4507 { ISD::BITREVERSE, MVT::i32, { 2, 2, 3, 4 } },
4508 { ISD::BITREVERSE, MVT::i16, { 2, 2, 3, 4 } },
4509 { ISD::BITREVERSE, MVT::i8, { 2, 2, 3, 4 } },
4510 // XOP: ROTL = VPROT(X,Y), ROTR = VPROT(X,SUB(0,Y))
4511 { ISD::ROTL, MVT::v4i64, { 4, 7, 5, 6 } },
4512 { ISD::ROTL, MVT::v8i32, { 4, 7, 5, 6 } },
4513 { ISD::ROTL, MVT::v16i16, { 4, 7, 5, 6 } },
4514 { ISD::ROTL, MVT::v32i8, { 4, 7, 5, 6 } },
4515 { ISD::ROTL, MVT::v2i64, { 1, 3, 1, 1 } },
4516 { ISD::ROTL, MVT::v4i32, { 1, 3, 1, 1 } },
4517 { ISD::ROTL, MVT::v8i16, { 1, 3, 1, 1 } },
4518 { ISD::ROTL, MVT::v16i8, { 1, 3, 1, 1 } },
4519 { ISD::ROTR, MVT::v4i64, { 4, 7, 8, 9 } },
4520 { ISD::ROTR, MVT::v8i32, { 4, 7, 8, 9 } },
4521 { ISD::ROTR, MVT::v16i16, { 4, 7, 8, 9 } },
4522 { ISD::ROTR, MVT::v32i8, { 4, 7, 8, 9 } },
4523 { ISD::ROTR, MVT::v2i64, { 1, 3, 3, 3 } },
4524 { ISD::ROTR, MVT::v4i32, { 1, 3, 3, 3 } },
4525 { ISD::ROTR, MVT::v8i16, { 1, 3, 3, 3 } },
4526 { ISD::ROTR, MVT::v16i8, { 1, 3, 3, 3 } },
4527 { X86ISD::VROTLI, MVT::v4i64, { 4, 7, 5, 6 } },
4528 { X86ISD::VROTLI, MVT::v8i32, { 4, 7, 5, 6 } },
4529 { X86ISD::VROTLI, MVT::v16i16, { 4, 7, 5, 6 } },
4530 { X86ISD::VROTLI, MVT::v32i8, { 4, 7, 5, 6 } },
4531 { X86ISD::VROTLI, MVT::v2i64, { 1, 3, 1, 1 } },
4532 { X86ISD::VROTLI, MVT::v4i32, { 1, 3, 1, 1 } },
4533 { X86ISD::VROTLI, MVT::v8i16, { 1, 3, 1, 1 } },
4534 { X86ISD::VROTLI, MVT::v16i8, { 1, 3, 1, 1 } },
4535 };
4536 static const CostKindTblEntry AVX2CostTbl[] = {
4537 { ISD::ABS, MVT::v2i64, { 2, 4, 3, 5 } }, // VBLENDVPD(X,VPSUBQ(0,X),X)
4538 { ISD::ABS, MVT::v4i64, { 2, 4, 3, 5 } }, // VBLENDVPD(X,VPSUBQ(0,X),X)
4539 { ISD::ABS, MVT::v4i32, { 1, 1, 1, 1 } },
4540 { ISD::ABS, MVT::v8i32, { 1, 1, 1, 2 } },
4541 { ISD::ABS, MVT::v8i16, { 1, 1, 1, 1 } },
4542 { ISD::ABS, MVT::v16i16, { 1, 1, 1, 2 } },
4543 { ISD::ABS, MVT::v16i8, { 1, 1, 1, 1 } },
4544 { ISD::ABS, MVT::v32i8, { 1, 1, 1, 2 } },
4545 { ISD::BITREVERSE, MVT::v2i64, { 3, 11, 10, 11 } },
4546 { ISD::BITREVERSE, MVT::v4i64, { 5, 11, 10, 17 } },
4547 { ISD::BITREVERSE, MVT::v4i32, { 3, 11, 10, 11 } },
4548 { ISD::BITREVERSE, MVT::v8i32, { 5, 11, 10, 17 } },
4549 { ISD::BITREVERSE, MVT::v8i16, { 3, 11, 10, 11 } },
4550 { ISD::BITREVERSE, MVT::v16i16, { 5, 11, 10, 17 } },
4551 { ISD::BITREVERSE, MVT::v16i8, { 3, 6, 9, 9 } },
4552 { ISD::BITREVERSE, MVT::v32i8, { 4, 5, 9, 15 } },
4553 { ISD::BSWAP, MVT::v2i64, { 1, 2, 1, 2 } },
4554 { ISD::BSWAP, MVT::v4i64, { 1, 3, 1, 2 } },
4555 { ISD::BSWAP, MVT::v4i32, { 1, 2, 1, 2 } },
4556 { ISD::BSWAP, MVT::v8i32, { 1, 3, 1, 2 } },
4557 { ISD::BSWAP, MVT::v8i16, { 1, 2, 1, 2 } },
4558 { ISD::BSWAP, MVT::v16i16, { 1, 3, 1, 2 } },
4559 { ISD::CTLZ, MVT::v2i64, { 7, 18, 24, 25 } },
4560 { ISD::CTLZ, MVT::v4i64, { 14, 18, 24, 44 } },
4561 { ISD::CTLZ, MVT::v4i32, { 5, 16, 19, 20 } },
4562 { ISD::CTLZ, MVT::v8i32, { 10, 16, 19, 34 } },
4563 { ISD::CTLZ, MVT::v8i16, { 4, 13, 14, 15 } },
4564 { ISD::CTLZ, MVT::v16i16, { 6, 14, 14, 24 } },
4565 { ISD::CTLZ, MVT::v16i8, { 3, 12, 9, 10 } },
4566 { ISD::CTLZ, MVT::v32i8, { 4, 12, 9, 14 } },
4567 { ISD::CTPOP, MVT::v2i64, { 3, 9, 10, 10 } },
4568 { ISD::CTPOP, MVT::v4i64, { 4, 9, 10, 14 } },
4569 { ISD::CTPOP, MVT::v4i32, { 7, 12, 14, 14 } },
4570 { ISD::CTPOP, MVT::v8i32, { 7, 12, 14, 18 } },
4571 { ISD::CTPOP, MVT::v8i16, { 3, 7, 11, 11 } },
4572 { ISD::CTPOP, MVT::v16i16, { 6, 8, 11, 18 } },
4573 { ISD::CTPOP, MVT::v16i8, { 2, 5, 8, 8 } },
4574 { ISD::CTPOP, MVT::v32i8, { 3, 5, 8, 12 } },
4575 { ISD::CTTZ, MVT::v2i64, { 4, 11, 13, 13 } },
4576 { ISD::CTTZ, MVT::v4i64, { 5, 11, 13, 20 } },
4577 { ISD::CTTZ, MVT::v4i32, { 7, 14, 17, 17 } },
4578 { ISD::CTTZ, MVT::v8i32, { 7, 15, 17, 24 } },
4579 { ISD::CTTZ, MVT::v8i16, { 4, 9, 14, 14 } },
4580 { ISD::CTTZ, MVT::v16i16, { 6, 9, 14, 24 } },
4581 { ISD::CTTZ, MVT::v16i8, { 3, 7, 11, 11 } },
4582 { ISD::CTTZ, MVT::v32i8, { 5, 7, 11, 18 } },
4583 { ISD::MULHS, MVT::v8i32, { 4, 9, 6, 12 } },
4584 { ISD::MULHS, MVT::v16i16, { 2, 5, 1, 2 } },
4585 { ISD::MULHU, MVT::v8i32, { 4, 9, 6, 12 } },
4586 { ISD::MULHU, MVT::v16i16, { 2, 5, 1, 2 } },
4587 { ISD::SADDSAT, MVT::v2i64, { 4, 13, 8, 11 } },
4588 { ISD::SADDSAT, MVT::v4i64, { 3, 10, 8, 12 } },
4589 { ISD::SADDSAT, MVT::v4i32, { 2, 6, 7, 9 } },
4590 { ISD::SADDSAT, MVT::v8i32, { 4, 6, 7, 13 } },
4591 { ISD::SADDSAT, MVT::v16i16, { 1, 1, 1, 2 } },
4592 { ISD::SADDSAT, MVT::v32i8, { 1, 1, 1, 2 } },
4593 { ISD::SMAX, MVT::v2i64, { 2, 7, 2, 3 } },
4594 { ISD::SMAX, MVT::v4i64, { 2, 7, 2, 3 } },
4595 { ISD::SMAX, MVT::v8i32, { 1, 1, 1, 2 } },
4596 { ISD::SMAX, MVT::v16i16, { 1, 1, 1, 2 } },
4597 { ISD::SMAX, MVT::v32i8, { 1, 1, 1, 2 } },
4598 { ISD::SMIN, MVT::v2i64, { 2, 7, 2, 3 } },
4599 { ISD::SMIN, MVT::v4i64, { 2, 7, 2, 3 } },
4600 { ISD::SMIN, MVT::v8i32, { 1, 1, 1, 2 } },
4601 { ISD::SMIN, MVT::v16i16, { 1, 1, 1, 2 } },
4602 { ISD::SMIN, MVT::v32i8, { 1, 1, 1, 2 } },
4603 { ISD::SMULO, MVT::v4i64, { 20, 20, 33, 37 } },
4604 { ISD::SMULO, MVT::v2i64, { 8, 8, 13, 15 } },
4605 { ISD::SMULO, MVT::v8i32, { 8, 20, 13, 24 } },
4606 { ISD::SMULO, MVT::v4i32, { 5, 15, 11, 12 } },
4607 { ISD::SMULO, MVT::v16i16, { 4, 14, 8, 14 } },
4608 { ISD::SMULO, MVT::v8i16, { 3, 9, 6, 6 } },
4609 { ISD::SMULO, MVT::v32i8, { 9, 15, 18, 35 } },
4610 { ISD::SMULO, MVT::v16i8, { 6, 22, 14, 21 } },
4611 { ISD::SSUBSAT, MVT::v2i64, { 4, 13, 9, 13 } },
4612 { ISD::SSUBSAT, MVT::v4i64, { 4, 15, 9, 13 } },
4613 { ISD::SSUBSAT, MVT::v4i32, { 3, 14, 9, 11 } },
4614 { ISD::SSUBSAT, MVT::v8i32, { 4, 15, 9, 16 } },
4615 { ISD::SSUBSAT, MVT::v16i16, { 1, 1, 1, 2 } },
4616 { ISD::SSUBSAT, MVT::v32i8, { 1, 1, 1, 2 } },
4617 { ISD::UADDSAT, MVT::v2i64, { 2, 8, 6, 6 } },
4618 { ISD::UADDSAT, MVT::v4i64, { 3, 8, 6, 10 } },
4619 { ISD::UADDSAT, MVT::v8i32, { 2, 2, 4, 8 } },
4620 { ISD::UADDSAT, MVT::v16i16, { 1, 1, 1, 2 } },
4621 { ISD::UADDSAT, MVT::v32i8, { 1, 1, 1, 2 } },
4622 { ISD::UMAX, MVT::v2i64, { 2, 8, 5, 6 } },
4623 { ISD::UMAX, MVT::v4i64, { 2, 8, 5, 8 } },
4624 { ISD::UMAX, MVT::v8i32, { 1, 1, 1, 2 } },
4625 { ISD::UMAX, MVT::v16i16, { 1, 1, 1, 2 } },
4626 { ISD::UMAX, MVT::v32i8, { 1, 1, 1, 2 } },
4627 { ISD::UMIN, MVT::v2i64, { 2, 8, 5, 6 } },
4628 { ISD::UMIN, MVT::v4i64, { 2, 8, 5, 8 } },
4629 { ISD::UMIN, MVT::v8i32, { 1, 1, 1, 2 } },
4630 { ISD::UMIN, MVT::v16i16, { 1, 1, 1, 2 } },
4631 { ISD::UMIN, MVT::v32i8, { 1, 1, 1, 2 } },
4632 { ISD::UMULO, MVT::v4i64, { 24, 24, 39, 43 } },
4633 { ISD::UMULO, MVT::v2i64, { 10, 10, 15, 19 } },
4634 { ISD::UMULO, MVT::v8i32, { 8, 11, 13, 23 } },
4635 { ISD::UMULO, MVT::v4i32, { 5, 12, 11, 12 } },
4636 { ISD::UMULO, MVT::v16i16, { 4, 6, 8, 13 } },
4637 { ISD::UMULO, MVT::v8i16, { 2, 8, 6, 6 } },
4638 { ISD::UMULO, MVT::v32i8, { 9, 13, 17, 33 } },
4639 { ISD::UMULO, MVT::v16i8, { 6, 19, 13, 20 } },
4640 { ISD::USUBSAT, MVT::v2i64, { 2, 7, 6, 6 } },
4641 { ISD::USUBSAT, MVT::v4i64, { 3, 7, 6, 10 } },
4642 { ISD::USUBSAT, MVT::v8i32, { 2, 2, 2, 4 } },
4643 { ISD::USUBSAT, MVT::v16i16, { 1, 1, 1, 2 } },
4644 { ISD::USUBSAT, MVT::v32i8, { 1, 1, 1, 2 } },
4645 { ISD::FMAXNUM, MVT::f32, { 2, 7, 3, 5 } }, // MAXSS + CMPUNORDSS + BLENDVPS
4646 { ISD::FMAXNUM, MVT::v4f32, { 2, 7, 3, 5 } }, // MAXPS + CMPUNORDPS + BLENDVPS
4647 { ISD::FMAXNUM, MVT::v8f32, { 3, 7, 3, 6 } }, // MAXPS + CMPUNORDPS + BLENDVPS
4648 { ISD::FMAXNUM, MVT::f64, { 2, 7, 3, 5 } }, // MAXSD + CMPUNORDSD + BLENDVPD
4649 { ISD::FMAXNUM, MVT::v2f64, { 2, 7, 3, 5 } }, // MAXPD + CMPUNORDPD + BLENDVPD
4650 { ISD::FMAXNUM, MVT::v4f64, { 3, 7, 3, 6 } }, // MAXPD + CMPUNORDPD + BLENDVPD
4651 { ISD::FSQRT, MVT::f32, { 7, 15, 1, 1 } }, // vsqrtss
4652 { ISD::FSQRT, MVT::v4f32, { 7, 15, 1, 1 } }, // vsqrtps
4653 { ISD::FSQRT, MVT::v8f32, { 14, 21, 1, 3 } }, // vsqrtps
4654 { ISD::FSQRT, MVT::f64, { 14, 21, 1, 1 } }, // vsqrtsd
4655 { ISD::FSQRT, MVT::v2f64, { 14, 21, 1, 1 } }, // vsqrtpd
4656 { ISD::FSQRT, MVT::v4f64, { 28, 35, 1, 3 } }, // vsqrtpd
4657 };
4658 static const CostKindTblEntry AVX1CostTbl[] = {
4659 { ISD::ABS, MVT::v4i64, { 6, 8, 6, 12 } }, // VBLENDVPD(X,VPSUBQ(0,X),X)
4660 { ISD::ABS, MVT::v8i32, { 3, 6, 4, 5 } },
4661 { ISD::ABS, MVT::v16i16, { 3, 6, 4, 5 } },
4662 { ISD::ABS, MVT::v32i8, { 3, 6, 4, 5 } },
4663 { ISD::BITREVERSE, MVT::v4i64, { 17, 20, 20, 33 } }, // 2 x 128-bit Op + extract/insert
4664 { ISD::BITREVERSE, MVT::v2i64, { 8, 13, 10, 16 } },
4665 { ISD::BITREVERSE, MVT::v8i32, { 17, 20, 20, 33 } }, // 2 x 128-bit Op + extract/insert
4666 { ISD::BITREVERSE, MVT::v4i32, { 8, 13, 10, 16 } },
4667 { ISD::BITREVERSE, MVT::v16i16, { 17, 20, 20, 33 } }, // 2 x 128-bit Op + extract/insert
4668 { ISD::BITREVERSE, MVT::v8i16, { 8, 13, 10, 16 } },
4669 { ISD::BITREVERSE, MVT::v32i8, { 13, 15, 17, 26 } }, // 2 x 128-bit Op + extract/insert
4670 { ISD::BITREVERSE, MVT::v16i8, { 7, 7, 9, 13 } },
4671 { ISD::BSWAP, MVT::v4i64, { 5, 6, 5, 10 } },
4672 { ISD::BSWAP, MVT::v2i64, { 2, 2, 1, 3 } },
4673 { ISD::BSWAP, MVT::v8i32, { 5, 6, 5, 10 } },
4674 { ISD::BSWAP, MVT::v4i32, { 2, 2, 1, 3 } },
4675 { ISD::BSWAP, MVT::v16i16, { 5, 6, 5, 10 } },
4676 { ISD::BSWAP, MVT::v8i16, { 2, 2, 1, 3 } },
4677 { ISD::CTLZ, MVT::v4i64, { 29, 33, 49, 58 } }, // 2 x 128-bit Op + extract/insert
4678 { ISD::CTLZ, MVT::v2i64, { 14, 24, 24, 28 } },
4679 { ISD::CTLZ, MVT::v8i32, { 24, 28, 39, 48 } }, // 2 x 128-bit Op + extract/insert
4680 { ISD::CTLZ, MVT::v4i32, { 12, 20, 19, 23 } },
4681 { ISD::CTLZ, MVT::v16i16, { 19, 22, 29, 38 } }, // 2 x 128-bit Op + extract/insert
4682 { ISD::CTLZ, MVT::v8i16, { 9, 16, 14, 18 } },
4683 { ISD::CTLZ, MVT::v32i8, { 14, 15, 19, 28 } }, // 2 x 128-bit Op + extract/insert
4684 { ISD::CTLZ, MVT::v16i8, { 7, 12, 9, 13 } },
4685 { ISD::CTPOP, MVT::v4i64, { 14, 18, 19, 28 } }, // 2 x 128-bit Op + extract/insert
4686 { ISD::CTPOP, MVT::v2i64, { 7, 14, 10, 14 } },
4687 { ISD::CTPOP, MVT::v8i32, { 18, 24, 27, 36 } }, // 2 x 128-bit Op + extract/insert
4688 { ISD::CTPOP, MVT::v4i32, { 9, 20, 14, 18 } },
4689 { ISD::CTPOP, MVT::v16i16, { 16, 21, 22, 31 } }, // 2 x 128-bit Op + extract/insert
4690 { ISD::CTPOP, MVT::v8i16, { 8, 18, 11, 15 } },
4691 { ISD::CTPOP, MVT::v32i8, { 13, 15, 16, 25 } }, // 2 x 128-bit Op + extract/insert
4692 { ISD::CTPOP, MVT::v16i8, { 6, 12, 8, 12 } },
4693 { ISD::CTTZ, MVT::v4i64, { 17, 22, 24, 33 } }, // 2 x 128-bit Op + extract/insert
4694 { ISD::CTTZ, MVT::v2i64, { 9, 19, 13, 17 } },
4695 { ISD::CTTZ, MVT::v8i32, { 21, 27, 32, 41 } }, // 2 x 128-bit Op + extract/insert
4696 { ISD::CTTZ, MVT::v4i32, { 11, 24, 17, 21 } },
4697 { ISD::CTTZ, MVT::v16i16, { 18, 24, 27, 36 } }, // 2 x 128-bit Op + extract/insert
4698 { ISD::CTTZ, MVT::v8i16, { 9, 21, 14, 18 } },
4699 { ISD::CTTZ, MVT::v32i8, { 15, 18, 21, 30 } }, // 2 x 128-bit Op + extract/insert
4700 { ISD::CTTZ, MVT::v16i8, { 8, 16, 11, 15 } },
4701 { ISD::MULHS, MVT::v8i32, { 9, 11, 14, 18 } },
4702 { ISD::MULHS, MVT::v16i16, { 3, 7, 5, 6 } },
4703 { ISD::MULHU, MVT::v8i32, { 9, 11, 14, 18 } },
4704 { ISD::MULHU, MVT::v16i16, { 3, 7, 5, 6 } },
4705 { ISD::SADDSAT, MVT::v2i64, { 6, 13, 8, 11 } },
4706 { ISD::SADDSAT, MVT::v4i64, { 13, 20, 15, 25 } }, // 2 x 128-bit Op + extract/insert
4707 { ISD::SADDSAT, MVT::v8i32, { 12, 18, 14, 24 } }, // 2 x 128-bit Op + extract/insert
4708 { ISD::SADDSAT, MVT::v16i16, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4709 { ISD::SADDSAT, MVT::v32i8, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4710 { ISD::SMAX, MVT::v4i64, { 6, 9, 6, 12 } }, // 2 x 128-bit Op + extract/insert
4711 { ISD::SMAX, MVT::v2i64, { 3, 7, 2, 4 } },
4712 { ISD::SMAX, MVT::v8i32, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4713 { ISD::SMAX, MVT::v16i16, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4714 { ISD::SMAX, MVT::v32i8, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4715 { ISD::SMIN, MVT::v4i64, { 6, 9, 6, 12 } }, // 2 x 128-bit Op + extract/insert
4716 { ISD::SMIN, MVT::v2i64, { 3, 7, 2, 3 } },
4717 { ISD::SMIN, MVT::v8i32, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4718 { ISD::SMIN, MVT::v16i16, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4719 { ISD::SMIN, MVT::v32i8, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4720 { ISD::SMULO, MVT::v4i64, { 20, 20, 33, 37 } },
4721 { ISD::SMULO, MVT::v2i64, { 9, 9, 13, 17 } },
4722 { ISD::SMULO, MVT::v8i32, { 15, 20, 24, 29 } },
4723 { ISD::SMULO, MVT::v4i32, { 7, 15, 11, 13 } },
4724 { ISD::SMULO, MVT::v16i16, { 8, 14, 14, 15 } },
4725 { ISD::SMULO, MVT::v8i16, { 3, 9, 6, 6 } },
4726 { ISD::SMULO, MVT::v32i8, { 20, 20, 37, 39 } },
4727 { ISD::SMULO, MVT::v16i8, { 9, 22, 18, 21 } },
4728 { ISD::SSUBSAT, MVT::v2i64, { 7, 13, 9, 13 } },
4729 { ISD::SSUBSAT, MVT::v4i64, { 15, 21, 18, 29 } }, // 2 x 128-bit Op + extract/insert
4730 { ISD::SSUBSAT, MVT::v8i32, { 15, 19, 18, 29 } }, // 2 x 128-bit Op + extract/insert
4731 { ISD::SSUBSAT, MVT::v16i16, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4732 { ISD::SSUBSAT, MVT::v32i8, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4733 { ISD::UADDSAT, MVT::v2i64, { 3, 8, 6, 6 } },
4734 { ISD::UADDSAT, MVT::v4i64, { 8, 11, 14, 15 } }, // 2 x 128-bit Op + extract/insert
4735 { ISD::UADDSAT, MVT::v8i32, { 6, 6, 10, 11 } }, // 2 x 128-bit Op + extract/insert
4736 { ISD::UADDSAT, MVT::v16i16, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4737 { ISD::UADDSAT, MVT::v32i8, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4738 { ISD::UMAX, MVT::v4i64, { 9, 10, 11, 17 } }, // 2 x 128-bit Op + extract/insert
4739 { ISD::UMAX, MVT::v2i64, { 4, 8, 5, 7 } },
4740 { ISD::UMAX, MVT::v8i32, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4741 { ISD::UMAX, MVT::v16i16, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4742 { ISD::UMAX, MVT::v32i8, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4743 { ISD::UMIN, MVT::v4i64, { 9, 10, 11, 17 } }, // 2 x 128-bit Op + extract/insert
4744 { ISD::UMIN, MVT::v2i64, { 4, 8, 5, 7 } },
4745 { ISD::UMIN, MVT::v8i32, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4746 { ISD::UMIN, MVT::v16i16, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4747 { ISD::UMIN, MVT::v32i8, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4748 { ISD::UMULO, MVT::v4i64, { 24, 26, 39, 45 } },
4749 { ISD::UMULO, MVT::v2i64, { 10, 12, 15, 20 } },
4750 { ISD::UMULO, MVT::v8i32, { 14, 15, 23, 28 } },
4751 { ISD::UMULO, MVT::v4i32, { 7, 12, 11, 13 } },
4752 { ISD::UMULO, MVT::v16i16, { 7, 11, 13, 14 } },
4753 { ISD::UMULO, MVT::v8i16, { 3, 8, 6, 6 } },
4754 { ISD::UMULO, MVT::v32i8, { 19, 19, 35, 37 } },
4755 { ISD::UMULO, MVT::v16i8, { 9, 19, 17, 20 } },
4756 { ISD::USUBSAT, MVT::v2i64, { 3, 7, 6, 6 } },
4757 { ISD::USUBSAT, MVT::v4i64, { 8, 10, 14, 15 } }, // 2 x 128-bit Op + extract/insert
4758 { ISD::USUBSAT, MVT::v8i32, { 4, 4, 7, 8 } }, // 2 x 128-bit Op + extract/insert
4759 { ISD::USUBSAT, MVT::v8i32, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4760 { ISD::USUBSAT, MVT::v16i16, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4761 { ISD::USUBSAT, MVT::v32i8, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4762 { ISD::FMAXNUM, MVT::f32, { 3, 6, 3, 5 } }, // MAXSS + CMPUNORDSS + BLENDVPS
4763 { ISD::FMAXNUM, MVT::v4f32, { 3, 6, 3, 5 } }, // MAXPS + CMPUNORDPS + BLENDVPS
4764 { ISD::FMAXNUM, MVT::v8f32, { 5, 7, 3, 10 } }, // MAXPS + CMPUNORDPS + BLENDVPS
4765 { ISD::FMAXNUM, MVT::f64, { 3, 6, 3, 5 } }, // MAXSD + CMPUNORDSD + BLENDVPD
4766 { ISD::FMAXNUM, MVT::v2f64, { 3, 6, 3, 5 } }, // MAXPD + CMPUNORDPD + BLENDVPD
4767 { ISD::FMAXNUM, MVT::v4f64, { 5, 7, 3, 10 } }, // MAXPD + CMPUNORDPD + BLENDVPD
4768 { ISD::FSQRT, MVT::f32, { 21, 21, 1, 1 } }, // vsqrtss
4769 { ISD::FSQRT, MVT::v4f32, { 21, 21, 1, 1 } }, // vsqrtps
4770 { ISD::FSQRT, MVT::v8f32, { 42, 42, 1, 3 } }, // vsqrtps
4771 { ISD::FSQRT, MVT::f64, { 27, 27, 1, 1 } }, // vsqrtsd
4772 { ISD::FSQRT, MVT::v2f64, { 27, 27, 1, 1 } }, // vsqrtpd
4773 { ISD::FSQRT, MVT::v4f64, { 54, 54, 1, 3 } }, // vsqrtpd
4774 };
4775 static const CostKindTblEntry GFNICostTbl[] = {
4776 { ISD::BITREVERSE, MVT::i8, { 3, 3, 3, 4 } }, // gf2p8affineqb
4777 { ISD::BITREVERSE, MVT::i16, { 3, 3, 4, 6 } }, // gf2p8affineqb
4778 { ISD::BITREVERSE, MVT::i32, { 3, 3, 4, 5 } }, // gf2p8affineqb
4779 { ISD::BITREVERSE, MVT::i64, { 3, 3, 4, 6 } }, // gf2p8affineqb
4780 { ISD::BITREVERSE, MVT::v16i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
4781 { ISD::BITREVERSE, MVT::v32i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
4782 { ISD::BITREVERSE, MVT::v64i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
4783 { ISD::BITREVERSE, MVT::v8i16, { 1, 8, 2, 4 } }, // gf2p8affineqb
4784 { ISD::BITREVERSE, MVT::v16i16, { 1, 9, 2, 4 } }, // gf2p8affineqb
4785 { ISD::BITREVERSE, MVT::v32i16, { 1, 9, 2, 4 } }, // gf2p8affineqb
4786 { ISD::BITREVERSE, MVT::v4i32, { 1, 8, 2, 4 } }, // gf2p8affineqb
4787 { ISD::BITREVERSE, MVT::v8i32, { 1, 9, 2, 4 } }, // gf2p8affineqb
4788 { ISD::BITREVERSE, MVT::v16i32, { 1, 9, 2, 4 } }, // gf2p8affineqb
4789 { ISD::BITREVERSE, MVT::v2i64, { 1, 8, 2, 4 } }, // gf2p8affineqb
4790 { ISD::BITREVERSE, MVT::v4i64, { 1, 9, 2, 4 } }, // gf2p8affineqb
4791 { ISD::BITREVERSE, MVT::v8i64, { 1, 9, 2, 4 } }, // gf2p8affineqb
4792 { X86ISD::VROTLI, MVT::v16i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
4793 { X86ISD::VROTLI, MVT::v32i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
4794 { X86ISD::VROTLI, MVT::v64i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
4795 };
4796 static const CostKindTblEntry GLMCostTbl[] = {
4797 { ISD::FSQRT, MVT::f32, { 19, 20, 1, 1 } }, // sqrtss
4798 { ISD::FSQRT, MVT::v4f32, { 37, 41, 1, 5 } }, // sqrtps
4799 { ISD::FSQRT, MVT::f64, { 34, 35, 1, 1 } }, // sqrtsd
4800 { ISD::FSQRT, MVT::v2f64, { 67, 71, 1, 5 } }, // sqrtpd
4801 };
4802 static const CostKindTblEntry SLMCostTbl[] = {
4803 { ISD::BSWAP, MVT::v2i64, { 5, 5, 1, 5 } },
4804 { ISD::BSWAP, MVT::v4i32, { 5, 5, 1, 5 } },
4805 { ISD::BSWAP, MVT::v8i16, { 5, 5, 1, 5 } },
4806 { ISD::FSQRT, MVT::f32, { 20, 20, 1, 1 } }, // sqrtss
4807 { ISD::FSQRT, MVT::v4f32, { 40, 41, 1, 5 } }, // sqrtps
4808 { ISD::FSQRT, MVT::f64, { 35, 35, 1, 1 } }, // sqrtsd
4809 { ISD::FSQRT, MVT::v2f64, { 70, 71, 1, 5 } }, // sqrtpd
4810 };
4811 static const CostKindTblEntry SSE42CostTbl[] = {
4812 { ISD::FMAXNUM, MVT::f32, { 5, 5, 7, 7 } }, // MAXSS + CMPUNORDSS + BLENDVPS
4813 { ISD::FMAXNUM, MVT::v4f32, { 4, 4, 4, 5 } }, // MAXPS + CMPUNORDPS + BLENDVPS
4814 { ISD::FMAXNUM, MVT::f64, { 5, 5, 7, 7 } }, // MAXSD + CMPUNORDSD + BLENDVPD
4815 { ISD::FMAXNUM, MVT::v2f64, { 4, 4, 4, 5 } }, // MAXPD + CMPUNORDPD + BLENDVPD
4816 { ISD::FSQRT, MVT::f32, { 18, 18, 1, 1 } }, // Nehalem from http://www.agner.org/
4817 { ISD::FSQRT, MVT::v4f32, { 18, 18, 1, 1 } }, // Nehalem from http://www.agner.org/
4818 };
4819 static const CostKindTblEntry SSE41CostTbl[] = {
4820 { ISD::ABS, MVT::v2i64, { 3, 4, 3, 5 } }, // BLENDVPD(X,PSUBQ(0,X),X)
4821 { ISD::MULHS, MVT::v4i32, { 3, 9, 6, 7 } },
4822 { ISD::MULHU, MVT::v4i32, { 3, 9, 6, 7 } },
4823 { ISD::SADDSAT, MVT::v2i64, { 10, 14, 17, 21 } },
4824 { ISD::SADDSAT, MVT::v4i32, { 5, 11, 8, 10 } },
4825 { ISD::SSUBSAT, MVT::v2i64, { 12, 19, 25, 29 } },
4826 { ISD::SSUBSAT, MVT::v4i32, { 6, 14, 10, 12 } },
4827 { ISD::SMAX, MVT::v2i64, { 3, 7, 2, 3 } },
4828 { ISD::SMAX, MVT::v4i32, { 1, 1, 1, 1 } },
4829 { ISD::SMAX, MVT::v16i8, { 1, 1, 1, 1 } },
4830 { ISD::SMIN, MVT::v2i64, { 3, 7, 2, 3 } },
4831 { ISD::SMIN, MVT::v4i32, { 1, 1, 1, 1 } },
4832 { ISD::SMIN, MVT::v16i8, { 1, 1, 1, 1 } },
4833 { ISD::SMULO, MVT::v2i64, { 9, 11, 13, 17 } },
4834 { ISD::SMULO, MVT::v4i32, { 20, 24, 13, 19 } },
4835 { ISD::SMULO, MVT::v8i16, { 5, 9, 8, 8 } },
4836 { ISD::SMULO, MVT::v16i8, { 13, 22, 24, 25 } },
4837 { ISD::UADDSAT, MVT::v2i64, { 6, 13, 14, 14 } },
4838 { ISD::UADDSAT, MVT::v4i32, { 2, 2, 4, 4 } },
4839 { ISD::USUBSAT, MVT::v2i64, { 6, 10, 14, 14 } },
4840 { ISD::USUBSAT, MVT::v4i32, { 1, 2, 2, 2 } },
4841 { ISD::UMAX, MVT::v2i64, { 2, 11, 6, 7 } },
4842 { ISD::UMAX, MVT::v4i32, { 1, 1, 1, 1 } },
4843 { ISD::UMAX, MVT::v8i16, { 1, 1, 1, 1 } },
4844 { ISD::UMIN, MVT::v2i64, { 2, 11, 6, 7 } },
4845 { ISD::UMIN, MVT::v4i32, { 1, 1, 1, 1 } },
4846 { ISD::UMIN, MVT::v8i16, { 1, 1, 1, 1 } },
4847 { ISD::UMULO, MVT::v2i64, { 14, 20, 15, 20 } },
4848 { ISD::UMULO, MVT::v4i32, { 19, 22, 12, 18 } },
4849 { ISD::UMULO, MVT::v8i16, { 4, 9, 7, 7 } },
4850 { ISD::UMULO, MVT::v16i8, { 13, 19, 18, 20 } },
4851 };
4852 static const CostKindTblEntry SSSE3CostTbl[] = {
4853 { ISD::ABS, MVT::v4i32, { 1, 2, 1, 1 } },
4854 { ISD::ABS, MVT::v8i16, { 1, 2, 1, 1 } },
4855 { ISD::ABS, MVT::v16i8, { 1, 2, 1, 1 } },
4856 { ISD::BITREVERSE, MVT::v2i64, { 16, 20, 11, 21 } },
4857 { ISD::BITREVERSE, MVT::v4i32, { 16, 20, 11, 21 } },
4858 { ISD::BITREVERSE, MVT::v8i16, { 16, 20, 11, 21 } },
4859 { ISD::BITREVERSE, MVT::v16i8, { 11, 12, 10, 16 } },
4860 { ISD::BSWAP, MVT::v2i64, { 2, 3, 1, 5 } },
4861 { ISD::BSWAP, MVT::v4i32, { 2, 3, 1, 5 } },
4862 { ISD::BSWAP, MVT::v8i16, { 2, 3, 1, 5 } },
4863 { ISD::CTLZ, MVT::v2i64, { 18, 28, 28, 35 } },
4864 { ISD::CTLZ, MVT::v4i32, { 15, 20, 22, 28 } },
4865 { ISD::CTLZ, MVT::v8i16, { 13, 17, 16, 22 } },
4866 { ISD::CTLZ, MVT::v16i8, { 11, 15, 10, 16 } },
4867 { ISD::CTPOP, MVT::v2i64, { 13, 19, 12, 18 } },
4868 { ISD::CTPOP, MVT::v4i32, { 18, 24, 16, 22 } },
4869 { ISD::CTPOP, MVT::v8i16, { 13, 18, 14, 20 } },
4870 { ISD::CTPOP, MVT::v16i8, { 11, 12, 10, 16 } },
4871 { ISD::CTTZ, MVT::v2i64, { 13, 25, 15, 22 } },
4872 { ISD::CTTZ, MVT::v4i32, { 18, 26, 19, 25 } },
4873 { ISD::CTTZ, MVT::v8i16, { 13, 20, 17, 23 } },
4874 { ISD::CTTZ, MVT::v16i8, { 11, 16, 13, 19 } }
4875 };
4876 static const CostKindTblEntry SSE2CostTbl[] = {
4877 { ISD::ABS, MVT::v2i64, { 3, 6, 5, 5 } },
4878 { ISD::ABS, MVT::v4i32, { 1, 4, 4, 4 } },
4879 { ISD::ABS, MVT::v8i16, { 1, 2, 3, 3 } },
4880 { ISD::ABS, MVT::v16i8, { 1, 2, 3, 3 } },
4881 { ISD::BITREVERSE, MVT::v2i64, { 16, 20, 32, 32 } },
4882 { ISD::BITREVERSE, MVT::v4i32, { 16, 20, 30, 30 } },
4883 { ISD::BITREVERSE, MVT::v8i16, { 16, 20, 25, 25 } },
4884 { ISD::BITREVERSE, MVT::v16i8, { 11, 12, 21, 21 } },
4885 { ISD::BSWAP, MVT::v2i64, { 5, 6, 11, 11 } },
4886 { ISD::BSWAP, MVT::v4i32, { 5, 5, 9, 9 } },
4887 { ISD::BSWAP, MVT::v8i16, { 5, 5, 4, 5 } },
4888 { ISD::CTLZ, MVT::v2i64, { 10, 45, 36, 38 } },
4889 { ISD::CTLZ, MVT::v4i32, { 10, 45, 38, 40 } },
4890 { ISD::CTLZ, MVT::v8i16, { 9, 38, 32, 34 } },
4891 { ISD::CTLZ, MVT::v16i8, { 8, 39, 29, 32 } },
4892 { ISD::CTPOP, MVT::v2i64, { 12, 26, 16, 18 } },
4893 { ISD::CTPOP, MVT::v4i32, { 15, 29, 21, 23 } },
4894 { ISD::CTPOP, MVT::v8i16, { 13, 25, 18, 20 } },
4895 { ISD::CTPOP, MVT::v16i8, { 10, 21, 14, 16 } },
4896 { ISD::CTTZ, MVT::v2i64, { 14, 28, 19, 21 } },
4897 { ISD::CTTZ, MVT::v4i32, { 18, 31, 24, 26 } },
4898 { ISD::CTTZ, MVT::v8i16, { 16, 27, 21, 23 } },
4899 { ISD::CTTZ, MVT::v16i8, { 13, 23, 17, 19 } },
4900 { ISD::MULHS, MVT::v4i32, { 5, 11, 15, 15 } },
4901 { ISD::MULHS, MVT::v8i16, { 1, 5, 1, 1 } },
4902 { ISD::MULHU, MVT::v4i32, { 3, 9, 7, 7 } },
4903 { ISD::MULHU, MVT::v8i16, { 1, 5, 1, 1 } },
4904 { ISD::SADDSAT, MVT::v2i64, { 12, 14, 24, 24 } },
4905 { ISD::SADDSAT, MVT::v4i32, { 6, 11, 11, 12 } },
4906 { ISD::SADDSAT, MVT::v8i16, { 1, 2, 1, 1 } },
4907 { ISD::SADDSAT, MVT::v16i8, { 1, 2, 1, 1 } },
4908 { ISD::SMAX, MVT::v2i64, { 4, 8, 15, 15 } },
4909 { ISD::SMAX, MVT::v4i32, { 2, 4, 5, 5 } },
4910 { ISD::SMAX, MVT::v8i16, { 1, 1, 1, 1 } },
4911 { ISD::SMAX, MVT::v16i8, { 2, 4, 5, 5 } },
4912 { ISD::SMIN, MVT::v2i64, { 4, 8, 15, 15 } },
4913 { ISD::SMIN, MVT::v4i32, { 2, 4, 5, 5 } },
4914 { ISD::SMIN, MVT::v8i16, { 1, 1, 1, 1 } },
4915 { ISD::SMIN, MVT::v16i8, { 2, 4, 5, 5 } },
4916 { ISD::SMULO, MVT::v2i64, { 30, 33, 13, 23 } },
4917 { ISD::SMULO, MVT::v4i32, { 20, 24, 23, 23 } },
4918 { ISD::SMULO, MVT::v8i16, { 5, 10, 8, 8 } },
4919 { ISD::SMULO, MVT::v16i8, { 13, 23, 24, 25 } },
4920 { ISD::SSUBSAT, MVT::v2i64, { 16, 19, 31, 31 } },
4921 { ISD::SSUBSAT, MVT::v4i32, { 6, 14, 12, 13 } },
4922 { ISD::SSUBSAT, MVT::v8i16, { 1, 2, 1, 1 } },
4923 { ISD::SSUBSAT, MVT::v16i8, { 1, 2, 1, 1 } },
4924 { ISD::UADDSAT, MVT::v2i64, { 7, 13, 14, 14 } },
4925 { ISD::UADDSAT, MVT::v4i32, { 4, 5, 7, 7 } },
4926 { ISD::UADDSAT, MVT::v8i16, { 1, 2, 1, 1 } },
4927 { ISD::UADDSAT, MVT::v16i8, { 1, 2, 1, 1 } },
4928 { ISD::UMAX, MVT::v2i64, { 4, 8, 15, 15 } },
4929 { ISD::UMAX, MVT::v4i32, { 2, 5, 8, 8 } },
4930 { ISD::UMAX, MVT::v8i16, { 1, 3, 3, 3 } },
4931 { ISD::UMAX, MVT::v16i8, { 1, 1, 1, 1 } },
4932 { ISD::UMIN, MVT::v2i64, { 4, 8, 15, 15 } },
4933 { ISD::UMIN, MVT::v4i32, { 2, 5, 8, 8 } },
4934 { ISD::UMIN, MVT::v8i16, { 1, 3, 3, 3 } },
4935 { ISD::UMIN, MVT::v16i8, { 1, 1, 1, 1 } },
4936 { ISD::UMULO, MVT::v2i64, { 30, 33, 15, 29 } },
4937 { ISD::UMULO, MVT::v4i32, { 19, 22, 14, 18 } },
4938 { ISD::UMULO, MVT::v8i16, { 4, 9, 7, 7 } },
4939 { ISD::UMULO, MVT::v16i8, { 13, 19, 20, 20 } },
4940 { ISD::USUBSAT, MVT::v2i64, { 7, 10, 14, 14 } },
4941 { ISD::USUBSAT, MVT::v4i32, { 4, 4, 7, 7 } },
4942 { ISD::USUBSAT, MVT::v8i16, { 1, 2, 1, 1 } },
4943 { ISD::USUBSAT, MVT::v16i8, { 1, 2, 1, 1 } },
4944 { ISD::FMAXNUM, MVT::f64, { 5, 5, 7, 7 } },
4945 { ISD::FMAXNUM, MVT::v2f64, { 4, 6, 6, 6 } },
4946 { ISD::FSQRT, MVT::f64, { 32, 32, 1, 1 } }, // Nehalem from http://www.agner.org/
4947 { ISD::FSQRT, MVT::v2f64, { 32, 32, 1, 1 } }, // Nehalem from http://www.agner.org/
4948 };
4949 static const CostKindTblEntry SSE1CostTbl[] = {
4950 { ISD::FMAXNUM, MVT::f32, { 5, 5, 7, 7 } },
4951 { ISD::FMAXNUM, MVT::v4f32, { 4, 6, 6, 6 } },
4952 { ISD::FSQRT, MVT::f32, { 28, 30, 1, 2 } }, // Pentium III from http://www.agner.org/
4953 { ISD::FSQRT, MVT::v4f32, { 56, 56, 1, 2 } }, // Pentium III from http://www.agner.org/
4954 };
4955 static const CostKindTblEntry BMI64CostTbl[] = { // 64-bit targets
4956 { ISD::CTTZ, MVT::i64, { 1, 1, 1, 1 } },
4957 };
4958 static const CostKindTblEntry BMI32CostTbl[] = { // 32 or 64-bit targets
4959 { ISD::CTTZ, MVT::i32, { 1, 1, 1, 1 } },
4960 { ISD::CTTZ, MVT::i16, { 2, 1, 1, 1 } },
4961 { ISD::CTTZ, MVT::i8, { 2, 1, 1, 1 } },
4962 };
4963 static const CostKindTblEntry LZCNT64CostTbl[] = { // 64-bit targets
4964 { ISD::CTLZ, MVT::i64, { 1, 1, 1, 1 } },
4965 };
4966 static const CostKindTblEntry LZCNT32CostTbl[] = { // 32 or 64-bit targets
4967 { ISD::CTLZ, MVT::i32, { 1, 1, 1, 1 } },
4968 { ISD::CTLZ, MVT::i16, { 2, 1, 1, 1 } },
4969 { ISD::CTLZ, MVT::i8, { 2, 1, 1, 1 } },
4970 };
4971 static const CostKindTblEntry POPCNT64CostTbl[] = { // 64-bit targets
4972 { ISD::CTPOP, MVT::i64, { 1, 1, 1, 1 } }, // popcnt
4973 };
4974 static const CostKindTblEntry POPCNT32CostTbl[] = { // 32 or 64-bit targets
4975 { ISD::CTPOP, MVT::i32, { 1, 1, 1, 1 } }, // popcnt
4976 { ISD::CTPOP, MVT::i16, { 1, 1, 2, 2 } }, // popcnt(zext())
4977 { ISD::CTPOP, MVT::i8, { 1, 1, 2, 2 } }, // popcnt(zext())
4978 };
4979 static const CostKindTblEntry PCLMULCostTbl[] = {
4980 { ISD::CLMUL, MVT::v2i64, { 3, 12, 4, 8 } }, // MOV+2xPCLMUL+unpack
4981 { ISD::CLMUL, MVT::v4i32, { 8, 18, 12, 16 } }, // MOV+4xPCLMUL+unpack
4982 { ISD::CLMUL, MVT::i64, { 3, 12, 4, 8 } }, // MOV+PCLMUL+MOV
4983 { ISD::CLMUL, MVT::i32, { 3, 12, 4, 8 } }, // MOV+PCLMUL+MOV
4984 { ISD::CLMUL, MVT::i16, { 3, 12, 4, 8 } }, // MOV+PCLMUL+MOV
4985 { ISD::CLMUL, MVT::i8, { 3, 12, 4, 8 } }, // MOV+PCLMUL+MOV
4986 };
4987 static const CostKindTblEntry X64CostTbl[] = { // 64-bit targets
4988 { ISD::ABS, MVT::i64, { 1, 2, 3, 3 } }, // SUB+CMOV
4989 { ISD::BITREVERSE, MVT::i64, { 10, 12, 20, 22 } },
4990 { ISD::BSWAP, MVT::i64, { 1, 2, 1, 2 } },
4991 { ISD::CTLZ, MVT::i64, { 1, 2, 3, 3 } }, // MOV+BSR+XOR
4992 { ISD::CTLZ, MVT::i32, { 1, 2, 3, 3 } }, // MOV+BSR+XOR
4993 { ISD::CTLZ, MVT::i16, { 2, 2, 3, 3 } }, // MOV+BSR+XOR
4994 { ISD::CTLZ, MVT::i8, { 2, 2, 4, 3 } }, // MOV+BSR+XOR
4995 { ISD::CTLZ_ZERO_POISON,MVT::i64,{ 1, 2, 2, 2 } }, // BSR+XOR
4996 { ISD::CTTZ, MVT::i64, { 1, 2, 2, 2 } }, // MOV+BSF
4997 { ISD::CTTZ, MVT::i32, { 1, 2, 2, 2 } }, // MOV+BSF
4998 { ISD::CTTZ, MVT::i16, { 2, 2, 2, 2 } }, // MOV+BSF
4999 { ISD::CTTZ, MVT::i8, { 2, 2, 2, 2 } }, // MOV+BSF
5000 { ISD::CTTZ_ZERO_POISON,MVT::i64,{ 1, 2, 1, 2 } }, // BSF
5001 { ISD::CTPOP, MVT::i64, { 10, 6, 19, 19 } },
5002 { ISD::ROTL, MVT::i64, { 2, 3, 1, 3 } },
5003 { ISD::ROTR, MVT::i64, { 2, 3, 1, 3 } },
5004 { X86ISD::VROTLI, MVT::i64, { 1, 1, 1, 1 } },
5005 { ISD::FSHL, MVT::i64, { 4, 4, 1, 4 } },
5006 { ISD::SADDSAT, MVT::i64, { 4, 4, 7, 10 } },
5007 { ISD::SSUBSAT, MVT::i64, { 4, 5, 8, 11 } },
5008 { ISD::UADDSAT, MVT::i64, { 2, 3, 4, 7 } },
5009 { ISD::USUBSAT, MVT::i64, { 2, 3, 4, 7 } },
5010 { ISD::SMAX, MVT::i64, { 1, 3, 2, 3 } },
5011 { ISD::SMIN, MVT::i64, { 1, 3, 2, 3 } },
5012 { ISD::UMAX, MVT::i64, { 1, 3, 2, 3 } },
5013 { ISD::UMIN, MVT::i64, { 1, 3, 2, 3 } },
5014 { ISD::SADDO, MVT::i64, { 2, 2, 4, 6 } },
5015 { ISD::UADDO, MVT::i64, { 2, 2, 4, 6 } },
5016 { ISD::SMULO, MVT::i64, { 4, 4, 4, 6 } },
5017 { ISD::UMULO, MVT::i64, { 8, 8, 4, 7 } },
5018 };
5019 static const CostKindTblEntry X86CostTbl[] = { // 32 or 64-bit targets
5020 { ISD::ABS, MVT::i32, { 1, 2, 3, 3 } }, // SUB+XOR+SRA or SUB+CMOV
5021 { ISD::ABS, MVT::i16, { 2, 2, 3, 3 } }, // SUB+XOR+SRA or SUB+CMOV
5022 { ISD::ABS, MVT::i8, { 2, 4, 4, 3 } }, // SUB+XOR+SRA
5023 { ISD::BITREVERSE, MVT::i32, { 9, 12, 17, 19 } },
5024 { ISD::BITREVERSE, MVT::i16, { 9, 12, 17, 19 } },
5025 { ISD::BITREVERSE, MVT::i8, { 7, 9, 13, 14 } },
5026 { ISD::BSWAP, MVT::i32, { 1, 1, 1, 1 } },
5027 { ISD::BSWAP, MVT::i16, { 1, 2, 1, 2 } }, // ROL
5028 { ISD::CTLZ, MVT::i32, { 2, 2, 4, 5 } }, // BSR+XOR or BSR+XOR+CMOV
5029 { ISD::CTLZ, MVT::i16, { 2, 2, 4, 5 } }, // BSR+XOR or BSR+XOR+CMOV
5030 { ISD::CTLZ, MVT::i8, { 2, 2, 5, 6 } }, // BSR+XOR or BSR+XOR+CMOV
5031 { ISD::CTLZ_ZERO_POISON,MVT::i32,{ 1, 2, 2, 2 } }, // BSR+XOR
5032 { ISD::CTLZ_ZERO_POISON,MVT::i16,{ 2, 2, 2, 2 } }, // BSR+XOR
5033 { ISD::CTLZ_ZERO_POISON,MVT::i8, { 2, 2, 3, 3 } }, // BSR+XOR
5034 { ISD::CTTZ, MVT::i32, { 2, 2, 3, 3 } }, // TEST+BSF+CMOV/BRANCH
5035 { ISD::CTTZ, MVT::i16, { 2, 2, 2, 3 } }, // TEST+BSF+CMOV/BRANCH
5036 { ISD::CTTZ, MVT::i8, { 2, 2, 2, 3 } }, // TEST+BSF+CMOV/BRANCH
5037 { ISD::CTTZ_ZERO_POISON,MVT::i32,{ 1, 2, 1, 2 } }, // BSF
5038 { ISD::CTTZ_ZERO_POISON,MVT::i16,{ 2, 2, 1, 2 } }, // BSF
5039 { ISD::CTTZ_ZERO_POISON,MVT::i8, { 2, 2, 1, 2 } }, // BSF
5040 { ISD::CTPOP, MVT::i32, { 8, 7, 15, 15 } },
5041 { ISD::CTPOP, MVT::i16, { 9, 8, 17, 17 } },
5042 { ISD::CTPOP, MVT::i8, { 7, 6, 6, 6 } },
5043 { ISD::ROTL, MVT::i32, { 2, 3, 1, 3 } },
5044 { ISD::ROTL, MVT::i16, { 2, 3, 1, 3 } },
5045 { ISD::ROTL, MVT::i8, { 2, 3, 1, 3 } },
5046 { ISD::ROTR, MVT::i32, { 2, 3, 1, 3 } },
5047 { ISD::ROTR, MVT::i16, { 2, 3, 1, 3 } },
5048 { ISD::ROTR, MVT::i8, { 2, 3, 1, 3 } },
5049 { X86ISD::VROTLI, MVT::i32, { 1, 1, 1, 1 } },
5050 { X86ISD::VROTLI, MVT::i16, { 1, 1, 1, 1 } },
5051 { X86ISD::VROTLI, MVT::i8, { 1, 1, 1, 1 } },
5052 { ISD::FSHL, MVT::i32, { 4, 4, 1, 4 } },
5053 { ISD::FSHL, MVT::i16, { 4, 4, 2, 5 } },
5054 { ISD::FSHL, MVT::i8, { 4, 4, 2, 5 } },
5055 { ISD::SADDSAT, MVT::i32, { 3, 4, 6, 9 } },
5056 { ISD::SADDSAT, MVT::i16, { 4, 4, 7, 10 } },
5057 { ISD::SADDSAT, MVT::i8, { 4, 5, 8, 11 } },
5058 { ISD::SSUBSAT, MVT::i32, { 4, 4, 7, 10 } },
5059 { ISD::SSUBSAT, MVT::i16, { 4, 4, 7, 10 } },
5060 { ISD::SSUBSAT, MVT::i8, { 4, 5, 8, 11 } },
5061 { ISD::UADDSAT, MVT::i32, { 2, 3, 4, 7 } },
5062 { ISD::UADDSAT, MVT::i16, { 2, 3, 4, 7 } },
5063 { ISD::UADDSAT, MVT::i8, { 3, 3, 5, 8 } },
5064 { ISD::USUBSAT, MVT::i32, { 2, 3, 4, 7 } },
5065 { ISD::USUBSAT, MVT::i16, { 2, 3, 4, 7 } },
5066 { ISD::USUBSAT, MVT::i8, { 3, 3, 5, 8 } },
5067 { ISD::SMAX, MVT::i32, { 1, 2, 2, 3 } },
5068 { ISD::SMAX, MVT::i16, { 1, 4, 2, 4 } },
5069 { ISD::SMAX, MVT::i8, { 1, 4, 2, 4 } },
5070 { ISD::SMIN, MVT::i32, { 1, 2, 2, 3 } },
5071 { ISD::SMIN, MVT::i16, { 1, 4, 2, 4 } },
5072 { ISD::SMIN, MVT::i8, { 1, 4, 2, 4 } },
5073 { ISD::UMAX, MVT::i32, { 1, 2, 2, 3 } },
5074 { ISD::UMAX, MVT::i16, { 1, 4, 2, 4 } },
5075 { ISD::UMAX, MVT::i8, { 1, 4, 2, 4 } },
5076 { ISD::UMIN, MVT::i32, { 1, 2, 2, 3 } },
5077 { ISD::UMIN, MVT::i16, { 1, 4, 2, 4 } },
5078 { ISD::UMIN, MVT::i8, { 1, 4, 2, 4 } },
5079 { ISD::SADDO, MVT::i32, { 2, 2, 4, 6 } },
5080 { ISD::SADDO, MVT::i16, { 2, 2, 4, 6 } },
5081 { ISD::SADDO, MVT::i8, { 2, 2, 4, 6 } },
5082 { ISD::UADDO, MVT::i32, { 2, 2, 4, 6 } },
5083 { ISD::UADDO, MVT::i16, { 2, 2, 4, 6 } },
5084 { ISD::UADDO, MVT::i8, { 2, 2, 4, 6 } },
5085 { ISD::SMULO, MVT::i32, { 2, 2, 4, 6 } },
5086 { ISD::SMULO, MVT::i16, { 5, 5, 4, 6 } },
5087 { ISD::SMULO, MVT::i8, { 6, 6, 4, 6 } },
5088 { ISD::UMULO, MVT::i32, { 6, 6, 4, 8 } },
5089 { ISD::UMULO, MVT::i16, { 6, 6, 4, 9 } },
5090 { ISD::UMULO, MVT::i8, { 6, 6, 4, 6 } },
5091 };
5092
5093 Type *RetTy = ICA.getReturnType();
5094 Type *OpTy = RetTy;
5095 Intrinsic::ID IID = ICA.getID();
5096 unsigned ISD = ISD::DELETED_NODE;
5097 switch (IID) {
5098 default:
5099 break;
5100 case Intrinsic::abs:
5101 ISD = ISD::ABS;
5102 break;
5103 case Intrinsic::bitreverse:
5105 break;
5106 case Intrinsic::bswap:
5107 ISD = ISD::BSWAP;
5108 break;
5109 case Intrinsic::ctlz:
5110 ISD = ISD::CTLZ;
5111 break;
5112 case Intrinsic::ctpop:
5113 ISD = ISD::CTPOP;
5114 break;
5115 case Intrinsic::cttz:
5116 ISD = ISD::CTTZ;
5117 break;
5118 case Intrinsic::fshl:
5119 ISD = ISD::FSHL;
5120 if (!ICA.isTypeBasedOnly()) {
5121 const SmallVectorImpl<const Value *> &Args = ICA.getArgs();
5122 if (Args[0] == Args[1]) {
5123 ISD = ISD::ROTL;
5124 // Handle uniform constant rotation amounts.
5125 // TODO: Handle funnel-shift cases.
5126 const APInt *Amt;
5127 if (Args[2] &&
5129 ISD = X86ISD::VROTLI;
5130 }
5131 }
5132 break;
5133 case Intrinsic::fshr:
5134 // FSHR has same costs so don't duplicate.
5135 ISD = ISD::FSHL;
5136 if (!ICA.isTypeBasedOnly()) {
5137 const SmallVectorImpl<const Value *> &Args = ICA.getArgs();
5138 if (Args[0] == Args[1]) {
5139 ISD = ISD::ROTR;
5140 // Handle uniform constant rotation amount.
5141 // TODO: Handle funnel-shift cases.
5142 const APInt *Amt;
5143 if (Args[2] &&
5145 ISD = X86ISD::VROTLI;
5146 }
5147 }
5148 break;
5149 case Intrinsic::lrint:
5150 case Intrinsic::llrint: {
5151 // X86 can use the CVTP2SI instructions to lower lrint/llrint calls, which
5152 // have the same costs as the CVTTP2SI (fptosi) instructions
5153 const SmallVectorImpl<Type *> &ArgTys = ICA.getArgTypes();
5154 return getCastInstrCost(Instruction::FPToSI, RetTy, ArgTys[0],
5156 }
5157 case Intrinsic::maxnum:
5158 case Intrinsic::minnum:
5159 // FMINNUM has same costs so don't duplicate.
5160 ISD = ISD::FMAXNUM;
5161 break;
5162 case Intrinsic::sadd_sat:
5163 ISD = ISD::SADDSAT;
5164 break;
5165 case Intrinsic::smax:
5166 ISD = ISD::SMAX;
5167 break;
5168 case Intrinsic::smin:
5169 ISD = ISD::SMIN;
5170 break;
5171 case Intrinsic::smulh:
5172 ISD = ISD::MULHS;
5173 break;
5174 case Intrinsic::ssub_sat:
5175 ISD = ISD::SSUBSAT;
5176 break;
5177 case Intrinsic::uadd_sat:
5178 ISD = ISD::UADDSAT;
5179 break;
5180 case Intrinsic::umax:
5181 ISD = ISD::UMAX;
5182 break;
5183 case Intrinsic::umin:
5184 ISD = ISD::UMIN;
5185 break;
5186 case Intrinsic::usub_sat:
5187 ISD = ISD::USUBSAT;
5188 break;
5189 case Intrinsic::umulh:
5190 ISD = ISD::MULHU;
5191 break;
5192 case Intrinsic::sqrt:
5193 // The estimate sequence is costed with the division it is folded into.
5196 isFoldedIntoRsqrtEstimate(ICA, *TLI, DL))
5197 return TTI::TCC_Free;
5198 ISD = ISD::FSQRT;
5199 break;
5200 case Intrinsic::sadd_with_overflow:
5201 case Intrinsic::ssub_with_overflow:
5202 // SSUBO has same costs so don't duplicate.
5203 ISD = ISD::SADDO;
5204 OpTy = RetTy->getContainedType(0);
5205 break;
5206 case Intrinsic::uadd_with_overflow:
5207 case Intrinsic::usub_with_overflow:
5208 // USUBO has same costs so don't duplicate.
5209 ISD = ISD::UADDO;
5210 OpTy = RetTy->getContainedType(0);
5211 break;
5212 case Intrinsic::smul_with_overflow:
5213 ISD = ISD::SMULO;
5214 OpTy = RetTy->getContainedType(0);
5215 break;
5216 case Intrinsic::umul_with_overflow:
5217 ISD = ISD::UMULO;
5218 OpTy = RetTy->getContainedType(0);
5219 break;
5220 case Intrinsic::clmul:
5221 ISD = ISD::CLMUL;
5222 break;
5223 }
5224
5225 if (ISD != ISD::DELETED_NODE) {
5226 auto adjustTableCost = [&](int ISD, unsigned Cost,
5227 std::pair<InstructionCost, MVT> LT,
5229 InstructionCost LegalizationCost = LT.first;
5230 MVT MTy = LT.second;
5231
5232 // If there are no NANs to deal with, then these are reduced to a
5233 // single MIN** or MAX** instruction instead of the MIN/CMP/SELECT that we
5234 // assume is used in the non-fast case.
5235 if (ISD == ISD::FMAXNUM || ISD == ISD::FMINNUM) {
5236 if (FMF.noNaNs())
5237 return LegalizationCost * 1;
5238 }
5239
5240 // For cases where some ops can be folded into a load/store, assume free.
5241 if (MTy.isScalarInteger()) {
5242 if (ISD == ISD::BSWAP && ST->hasMOVBE() && ST->hasFastMOVBE()) {
5243 if (const Instruction *II = ICA.getInst()) {
5244 if (II->hasOneUse() && isa<StoreInst>(II->user_back()))
5245 return TTI::TCC_Free;
5246 if (auto *LI = dyn_cast<LoadInst>(II->getOperand(0))) {
5247 if (LI->hasOneUse())
5248 return TTI::TCC_Free;
5249 }
5250 }
5251 }
5252 }
5253
5254 return LegalizationCost * (int)Cost;
5255 };
5256
5257 // Legalize the type.
5258 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(OpTy);
5259 MVT MTy = LT.second;
5260
5261 // Without BMI/LZCNT see if we're only looking for a *_ZERO_POISON cost.
5262 if (((ISD == ISD::CTTZ && !ST->hasBMI()) ||
5263 (ISD == ISD::CTLZ && !ST->hasLZCNT())) &&
5264 !MTy.isVector() && !ICA.isTypeBasedOnly()) {
5265 const SmallVectorImpl<const Value *> &Args = ICA.getArgs();
5266 if (auto *Cst = dyn_cast<ConstantInt>(Args[1]))
5267 if (Cst->isAllOnesValue())
5268 ISD =
5270 }
5271
5272 // FSQRT is a single instruction.
5274 return LT.first;
5275
5276 if (ST->useGLMDivSqrtCosts())
5277 if (const auto *Entry = CostTableLookup(GLMCostTbl, ISD, MTy))
5278 if (auto KindCost = Entry->Cost[CostKind])
5279 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5280
5281 if (ST->useSLMArithCosts())
5282 if (const auto *Entry = CostTableLookup(SLMCostTbl, ISD, MTy))
5283 if (auto KindCost = Entry->Cost[CostKind])
5284 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5285
5286 if (ST->hasVBMI2())
5287 if (const auto *Entry = CostTableLookup(AVX512VBMI2CostTbl, ISD, MTy))
5288 if (auto KindCost = Entry->Cost[CostKind])
5289 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5290
5291 if (ST->hasBITALG())
5292 if (const auto *Entry = CostTableLookup(AVX512BITALGCostTbl, ISD, MTy))
5293 if (auto KindCost = Entry->Cost[CostKind])
5294 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5295
5296 if (ST->hasVPOPCNTDQ())
5297 if (const auto *Entry = CostTableLookup(AVX512VPOPCNTDQCostTbl, ISD, MTy))
5298 if (auto KindCost = Entry->Cost[CostKind])
5299 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5300
5301 if (ST->hasGFNI())
5302 if (const auto *Entry = CostTableLookup(GFNICostTbl, ISD, MTy))
5303 if (auto KindCost = Entry->Cost[CostKind])
5304 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5305
5306 if (ST->hasCDI())
5307 if (const auto *Entry = CostTableLookup(AVX512CDCostTbl, ISD, MTy))
5308 if (auto KindCost = Entry->Cost[CostKind])
5309 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5310
5311 if (ST->hasBWI())
5312 if (const auto *Entry = CostTableLookup(AVX512BWCostTbl, ISD, MTy))
5313 if (auto KindCost = Entry->Cost[CostKind])
5314 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5315
5316 if (ST->hasAVX512())
5317 if (const auto *Entry = CostTableLookup(AVX512CostTbl, ISD, MTy))
5318 if (auto KindCost = Entry->Cost[CostKind])
5319 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5320
5321 if (ST->hasXOP())
5322 if (const auto *Entry = CostTableLookup(XOPCostTbl, ISD, MTy))
5323 if (auto KindCost = Entry->Cost[CostKind])
5324 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5325
5326 if (ST->hasAVX2())
5327 if (const auto *Entry = CostTableLookup(AVX2CostTbl, ISD, MTy))
5328 if (auto KindCost = Entry->Cost[CostKind])
5329 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5330
5331 if (ST->hasAVX())
5332 if (const auto *Entry = CostTableLookup(AVX1CostTbl, ISD, MTy))
5333 if (auto KindCost = Entry->Cost[CostKind])
5334 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5335
5336 if (ST->hasSSE42())
5337 if (const auto *Entry = CostTableLookup(SSE42CostTbl, ISD, MTy))
5338 if (auto KindCost = Entry->Cost[CostKind])
5339 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5340
5341 if (ST->hasSSE41())
5342 if (const auto *Entry = CostTableLookup(SSE41CostTbl, ISD, MTy))
5343 if (auto KindCost = Entry->Cost[CostKind])
5344 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5345
5346 if (ST->hasSSSE3())
5347 if (const auto *Entry = CostTableLookup(SSSE3CostTbl, ISD, MTy))
5348 if (auto KindCost = Entry->Cost[CostKind])
5349 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5350
5351 if (ST->hasSSE2())
5352 if (const auto *Entry = CostTableLookup(SSE2CostTbl, ISD, MTy))
5353 if (auto KindCost = Entry->Cost[CostKind])
5354 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5355
5356 if (ST->hasSSE1())
5357 if (const auto *Entry = CostTableLookup(SSE1CostTbl, ISD, MTy))
5358 if (auto KindCost = Entry->Cost[CostKind])
5359 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5360
5361 if (ST->hasBMI()) {
5362 if (ST->is64Bit())
5363 if (const auto *Entry = CostTableLookup(BMI64CostTbl, ISD, MTy))
5364 if (auto KindCost = Entry->Cost[CostKind])
5365 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5366
5367 if (const auto *Entry = CostTableLookup(BMI32CostTbl, ISD, MTy))
5368 if (auto KindCost = Entry->Cost[CostKind])
5369 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5370 }
5371
5372 if (ST->hasLZCNT()) {
5373 if (ST->is64Bit())
5374 if (const auto *Entry = CostTableLookup(LZCNT64CostTbl, ISD, MTy))
5375 if (auto KindCost = Entry->Cost[CostKind])
5376 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5377
5378 if (const auto *Entry = CostTableLookup(LZCNT32CostTbl, ISD, MTy))
5379 if (auto KindCost = Entry->Cost[CostKind])
5380 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5381 }
5382
5383 if (ST->hasPOPCNT()) {
5384 if (ST->is64Bit())
5385 if (const auto *Entry = CostTableLookup(POPCNT64CostTbl, ISD, MTy))
5386 if (auto KindCost = Entry->Cost[CostKind])
5387 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5388
5389 if (const auto *Entry = CostTableLookup(POPCNT32CostTbl, ISD, MTy))
5390 if (auto KindCost = Entry->Cost[CostKind])
5391 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5392 }
5393
5394 // FIXME: PCLMUL w/ AVX/AVX512 and VPCLMULQDQ are not handled properly.
5395 if (ST->hasPCLMUL())
5396 if (const auto *Entry = CostTableLookup(PCLMULCostTbl, ISD, MTy))
5397 if (auto KindCost = Entry->Cost[CostKind])
5398 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5399
5400 if (ST->is64Bit())
5401 if (const auto *Entry = CostTableLookup(X64CostTbl, ISD, MTy))
5402 if (auto KindCost = Entry->Cost[CostKind])
5403 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5404
5405 if (const auto *Entry = CostTableLookup(X86CostTbl, ISD, MTy))
5406 if (auto KindCost = Entry->Cost[CostKind])
5407 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5408
5409 // Without arg data, we need to compute the expanded costs of custom lowered
5410 // intrinsics to prevent use of the (very low) default costs.
5411 if (ICA.isTypeBasedOnly() &&
5412 (IID == Intrinsic::fshl || IID == Intrinsic::fshr)) {
5413 Type *CondTy = RetTy->getWithNewBitWidth(1);
5415 Cost += getArithmeticInstrCost(BinaryOperator::Or, RetTy, CostKind);
5416 Cost += getArithmeticInstrCost(BinaryOperator::Sub, RetTy, CostKind);
5417 Cost += getArithmeticInstrCost(BinaryOperator::Shl, RetTy, CostKind);
5418 Cost += getArithmeticInstrCost(BinaryOperator::LShr, RetTy, CostKind);
5419 Cost += getArithmeticInstrCost(BinaryOperator::And, RetTy, CostKind);
5420 Cost += getCmpSelInstrCost(BinaryOperator::ICmp, RetTy, CondTy,
5422 Cost += getCmpSelInstrCost(BinaryOperator::Select, RetTy, CondTy,
5424 return Cost;
5425 }
5426 }
5427
5429}
5430
5432 unsigned Opcode, Type *Val, TTI::TargetCostKind CostKind, unsigned Index,
5433 const Value *Op0, const Value *Op1, TTI::VectorInstrContext VIC) const {
5434 static const CostTblEntry SLMCostTbl[] = {
5435 { ISD::EXTRACT_VECTOR_ELT, MVT::i8, 4 },
5436 { ISD::EXTRACT_VECTOR_ELT, MVT::i16, 4 },
5437 { ISD::EXTRACT_VECTOR_ELT, MVT::i32, 4 },
5438 { ISD::EXTRACT_VECTOR_ELT, MVT::i64, 7 }
5439 };
5440
5441 assert(Val->isVectorTy() && "This must be a vector type");
5442 auto *VT = cast<VectorType>(Val);
5443 if (VT->isScalableTy())
5445
5446 Type *ScalarType = Val->getScalarType();
5447 InstructionCost RegisterFileMoveCost = 0;
5448
5449 // Non-immediate extraction/insertion can be handled as a sequence of
5450 // aliased loads+stores via the stack.
5451 if (Index == -1U && (Opcode == Instruction::ExtractElement ||
5452 Opcode == Instruction::InsertElement)) {
5453 // TODO: On some SSE41+ targets, we expand to cmp+splat+select patterns:
5454 // inselt N0, N1, N2 --> select (SplatN2 == {0,1,2...}) ? SplatN1 : N0.
5455
5456 // TODO: Move this to BasicTTIImpl.h? We'd need better gep + index handling.
5457 assert(isa<FixedVectorType>(Val) && "Fixed vector type expected");
5458 Align VecAlign = DL.getPrefTypeAlign(Val);
5459 Align SclAlign = DL.getPrefTypeAlign(ScalarType);
5460
5461 // Extract - store vector to stack, load scalar.
5462 if (Opcode == Instruction::ExtractElement) {
5463 return getMemoryOpCost(Instruction::Store, Val, VecAlign, 0, CostKind) +
5464 getMemoryOpCost(Instruction::Load, ScalarType, SclAlign, 0,
5465 CostKind);
5466 }
5467 // Insert - store vector to stack, store scalar, load vector.
5468 if (Opcode == Instruction::InsertElement) {
5469 return getMemoryOpCost(Instruction::Store, Val, VecAlign, 0, CostKind) +
5470 getMemoryOpCost(Instruction::Store, ScalarType, SclAlign, 0,
5471 CostKind) +
5472 getMemoryOpCost(Instruction::Load, Val, VecAlign, 0, CostKind);
5473 }
5474 }
5475
5476 if (Index != -1U && (Opcode == Instruction::ExtractElement ||
5477 Opcode == Instruction::InsertElement)) {
5478 // Extraction of vXi1 elements are now efficiently handled by MOVMSK.
5479 if (Opcode == Instruction::ExtractElement &&
5480 ScalarType->getScalarSizeInBits() == 1 &&
5481 cast<FixedVectorType>(Val)->getNumElements() > 1)
5482 return 1;
5483
5484 // Legalize the type.
5485 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Val);
5486
5487 // This type is legalized to a scalar type.
5488 if (!LT.second.isVector())
5489 return TTI::TCC_Free;
5490
5491 // The type may be split. Normalize the index to the new type.
5492 unsigned SizeInBits = LT.second.getSizeInBits();
5493 unsigned NumElts = LT.second.getVectorNumElements();
5494 unsigned SubNumElts = NumElts;
5495 Index = Index % NumElts;
5496
5497 // For >128-bit vectors, we need to extract higher 128-bit subvectors.
5498 // For inserts, we also need to insert the subvector back.
5499 if (SizeInBits > 128) {
5500 assert((SizeInBits % 128) == 0 && "Illegal vector");
5501 unsigned NumSubVecs = SizeInBits / 128;
5502 SubNumElts = NumElts / NumSubVecs;
5503 if (SubNumElts <= Index) {
5504 RegisterFileMoveCost += (Opcode == Instruction::InsertElement ? 2 : 1);
5505 Index %= SubNumElts;
5506 }
5507 }
5508
5509 MVT MScalarTy = LT.second.getScalarType();
5510 auto IsCheapPInsrPExtrInsertPS = [&]() {
5511 // Assume pinsr/pextr XMM <-> GPR is relatively cheap on all targets.
5512 // Inserting f32 into index0 is just movss.
5513 // Also, assume insertps is relatively cheap on all >= SSE41 targets.
5514 return (MScalarTy == MVT::i16 && ST->hasSSE2()) ||
5515 (MScalarTy.isInteger() && ST->hasSSE41()) ||
5516 (MScalarTy == MVT::f32 && ST->hasSSE1() && Index == 0 &&
5517 Opcode == Instruction::InsertElement) ||
5518 (MScalarTy == MVT::f32 && ST->hasSSE41() &&
5519 Opcode == Instruction::InsertElement);
5520 };
5521
5522 if (Index == 0) {
5523 // Floating point scalars are already located in index #0.
5524 // Many insertions to #0 can fold away for scalar fp-ops, so let's assume
5525 // true for all.
5526 if (ScalarType->isFloatingPointTy() &&
5527 (Opcode != Instruction::InsertElement || !Op0 ||
5528 isa<UndefValue>(Op0)))
5529 return RegisterFileMoveCost;
5530
5531 if (Opcode == Instruction::InsertElement &&
5533 // Consider the gather cost to be cheap.
5535 return RegisterFileMoveCost;
5536 if (!IsCheapPInsrPExtrInsertPS()) {
5537 // mov constant-to-GPR + movd/movq GPR -> XMM.
5538 if (isa_and_nonnull<Constant>(Op1) && Op1->getType()->isIntegerTy())
5539 return 2 + RegisterFileMoveCost;
5540 // Assume movd/movq GPR -> XMM is relatively cheap on all targets.
5541 return 1 + RegisterFileMoveCost;
5542 }
5543 }
5544
5545 // Assume movd/movq XMM -> GPR is relatively cheap on all targets.
5546 if (ScalarType->isIntegerTy() && Opcode == Instruction::ExtractElement)
5547 return 1 + RegisterFileMoveCost;
5548 }
5549
5550 int ISD = TLI->InstructionOpcodeToISD(Opcode);
5551 assert(ISD && "Unexpected vector opcode");
5552 if (ST->useSLMArithCosts())
5553 if (auto *Entry = CostTableLookup(SLMCostTbl, ISD, MScalarTy))
5554 return Entry->Cost + RegisterFileMoveCost;
5555
5556 // Consider cheap cases.
5557 if (IsCheapPInsrPExtrInsertPS())
5558 return 1 + RegisterFileMoveCost;
5559
5560 // For extractions we just need to shuffle the element to index 0, which
5561 // should be very cheap (assume cost = 1). For insertions we need to shuffle
5562 // the elements to its destination. In both cases we must handle the
5563 // subvector move(s).
5564 // If the vector type is already less than 128-bits then don't reduce it.
5565 // TODO: Under what circumstances should we shuffle using the full width?
5566 InstructionCost ShuffleCost = 1;
5567 if (Opcode == Instruction::InsertElement) {
5568 auto *SubTy = cast<VectorType>(Val);
5569 EVT VT = TLI->getValueType(DL, Val);
5570 if (VT.getScalarType() != MScalarTy || VT.getSizeInBits() >= 128)
5571 SubTy = FixedVectorType::get(ScalarType, SubNumElts);
5572 ShuffleCost = getShuffleCost(TTI::SK_PermuteTwoSrc, SubTy, SubTy,
5573 CostKind, {}, 0, SubTy);
5574 }
5575 int IntOrFpCost = ScalarType->isFloatingPointTy() ? 0 : 1;
5576 return ShuffleCost + IntOrFpCost + RegisterFileMoveCost;
5577 }
5578
5579 return BaseT::getVectorInstrCost(Opcode, Val, CostKind, Index, Op0, Op1,
5580 VIC) +
5581 RegisterFileMoveCost;
5582}
5583
5585 VectorType *Ty, const APInt &DemandedElts, bool Insert, bool Extract,
5586 TTI::TargetCostKind CostKind, bool ForPoisonSrc, ArrayRef<Value *> VL,
5587 TTI::VectorInstrContext VIC) const {
5588 assert(DemandedElts.getBitWidth() ==
5589 cast<FixedVectorType>(Ty)->getNumElements() &&
5590 "Vector size mismatch");
5591
5592 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Ty);
5593 MVT MScalarTy = LT.second.getScalarType();
5594 unsigned LegalVectorBitWidth = LT.second.getSizeInBits();
5596
5597 constexpr unsigned LaneBitWidth = 128;
5598 assert((LegalVectorBitWidth < LaneBitWidth ||
5599 (LegalVectorBitWidth % LaneBitWidth) == 0) &&
5600 "Illegal vector");
5601
5602 const int NumLegalVectors = LT.first.getValue();
5603 assert(NumLegalVectors >= 0 && "Negative cost!");
5604
5605 // For insertions, a ISD::BUILD_VECTOR style vector initialization can be much
5606 // cheaper than an accumulation of ISD::INSERT_VECTOR_ELT. SLPVectorizer has
5607 // a special heuristic regarding poison input which is passed here in
5608 // ForPoisonSrc.
5609 if (Insert && !ForPoisonSrc) {
5610 // This is nearly identical to BaseT::getScalarizationOverhead(), except
5611 // it is passing nullptr to getVectorInstrCost() for Op0 (instead of
5612 // Constant::getNullValue()), which makes the X86TTIImpl
5613 // getVectorInstrCost() return 0 instead of 1.
5614 for (unsigned I : seq(DemandedElts.getBitWidth())) {
5615 if (!DemandedElts[I])
5616 continue;
5617 Cost += getVectorInstrCost(Instruction::InsertElement, Ty, CostKind, I,
5619 VL.empty() ? nullptr : VL[I],
5621 }
5622 return Cost;
5623 }
5624
5625 if (Insert) {
5626 if ((MScalarTy == MVT::i16 && ST->hasSSE2()) ||
5627 (MScalarTy.isInteger() && ST->hasSSE41()) ||
5628 (MScalarTy == MVT::f32 && ST->hasSSE41())) {
5629 // For types we can insert directly, insertion into 128-bit sub vectors is
5630 // cheap, followed by a cheap chain of concatenations.
5631 if (LegalVectorBitWidth <= LaneBitWidth) {
5632 Cost += BaseT::getScalarizationOverhead(Ty, DemandedElts, Insert,
5633 /*Extract*/ false, CostKind);
5634 } else {
5635 // In each 128-lane, if at least one index is demanded but not all
5636 // indices are demanded and this 128-lane is not the first 128-lane of
5637 // the legalized-vector, then this 128-lane needs a extracti128; If in
5638 // each 128-lane, there is at least one demanded index, this 128-lane
5639 // needs a inserti128.
5640
5641 // The following cases will help you build a better understanding:
5642 // Assume we insert several elements into a v8i32 vector in avx2,
5643 // Case#1: inserting into 1th index needs vpinsrd + inserti128.
5644 // Case#2: inserting into 5th index needs extracti128 + vpinsrd +
5645 // inserti128.
5646 // Case#3: inserting into 4,5,6,7 index needs 4*vpinsrd + inserti128.
5647 assert((LegalVectorBitWidth % LaneBitWidth) == 0 && "Illegal vector");
5648 unsigned NumLegalLanes = LegalVectorBitWidth / LaneBitWidth;
5649 unsigned NumLanesTotal = NumLegalLanes * NumLegalVectors;
5650 unsigned NumLegalElts =
5651 LT.second.getVectorNumElements() * NumLegalVectors;
5652 assert(NumLegalElts >= DemandedElts.getBitWidth() &&
5653 "Vector has been legalized to smaller element count");
5654 assert((NumLegalElts % NumLanesTotal) == 0 &&
5655 "Unexpected elts per lane");
5656 unsigned NumEltsPerLane = NumLegalElts / NumLanesTotal;
5657
5658 APInt WidenedDemandedElts = DemandedElts.zext(NumLegalElts);
5659 auto *LaneTy =
5660 FixedVectorType::get(Ty->getElementType(), NumEltsPerLane);
5661
5662 for (unsigned I = 0; I != NumLanesTotal; ++I) {
5663 APInt LaneEltMask = WidenedDemandedElts.extractBits(
5664 NumEltsPerLane, NumEltsPerLane * I);
5665 if (LaneEltMask.isZero())
5666 continue;
5667 // FIXME: we don't need to extract if all non-demanded elements
5668 // are legalization-inserted padding.
5669 if (!LaneEltMask.isAllOnes())
5671 {}, I * NumEltsPerLane, LaneTy);
5672 Cost += BaseT::getScalarizationOverhead(LaneTy, LaneEltMask, Insert,
5673 /*Extract*/ false, CostKind);
5674 }
5675
5676 APInt AffectedLanes =
5677 APIntOps::ScaleBitMask(WidenedDemandedElts, NumLanesTotal);
5678 APInt FullyAffectedLegalVectors = APIntOps::ScaleBitMask(
5679 AffectedLanes, NumLegalVectors, /*MatchAllBits=*/true);
5680 for (int LegalVec = 0; LegalVec != NumLegalVectors; ++LegalVec) {
5681 for (unsigned Lane = 0; Lane != NumLegalLanes; ++Lane) {
5682 unsigned I = NumLegalLanes * LegalVec + Lane;
5683 // No need to insert unaffected lane; or lane 0 of each legal vector
5684 // iff ALL lanes of that vector were affected and will be inserted.
5685 if (!AffectedLanes[I] ||
5686 (Lane == 0 && FullyAffectedLegalVectors[LegalVec]))
5687 continue;
5689 {}, I * NumEltsPerLane, LaneTy);
5690 }
5691 }
5692 }
5693 } else if (LT.second.isVector()) {
5694 // Without fast insertion, we need to use MOVD/MOVQ to pass each demanded
5695 // integer element as a SCALAR_TO_VECTOR, then we build the vector as a
5696 // series of UNPCK followed by CONCAT_VECTORS - all of these can be
5697 // considered cheap.
5698 if (Ty->isIntOrIntVectorTy())
5699 Cost += DemandedElts.popcount();
5700
5701 // Get the smaller of the legalized or original pow2-extended number of
5702 // vector elements, which represents the number of unpacks we'll end up
5703 // performing.
5704 unsigned NumElts = LT.second.getVectorNumElements();
5705 unsigned Pow2Elts =
5706 PowerOf2Ceil(cast<FixedVectorType>(Ty)->getNumElements());
5707 Cost += (std::min<unsigned>(NumElts, Pow2Elts) - 1) * LT.first;
5708 }
5709 }
5710
5711 if (Extract) {
5712 // vXi1 can be efficiently extracted with MOVMSK.
5713 // TODO: AVX512 predicate mask handling.
5714 // NOTE: This doesn't work well for roundtrip scalarization.
5715 if (!Insert && Ty->getScalarSizeInBits() == 1 && !ST->hasAVX512()) {
5716 unsigned NumElts = cast<FixedVectorType>(Ty)->getNumElements();
5717 unsigned MaxElts = ST->hasAVX2() ? 32 : 16;
5718 unsigned MOVMSKCost = (NumElts + MaxElts - 1) / MaxElts;
5719 return MOVMSKCost;
5720 }
5721
5722 if (LT.second.isVector()) {
5723 unsigned NumLegalElts =
5724 LT.second.getVectorNumElements() * NumLegalVectors;
5725 assert(NumLegalElts >= DemandedElts.getBitWidth() &&
5726 "Vector has been legalized to smaller element count");
5727
5728 // If we're extracting elements from a 128-bit subvector lane,
5729 // we only need to extract each lane once, not for every element.
5730 if (LegalVectorBitWidth > LaneBitWidth) {
5731 unsigned NumLegalLanes = LegalVectorBitWidth / LaneBitWidth;
5732 unsigned NumLanesTotal = NumLegalLanes * NumLegalVectors;
5733 assert((NumLegalElts % NumLanesTotal) == 0 &&
5734 "Unexpected elts per lane");
5735 unsigned NumEltsPerLane = NumLegalElts / NumLanesTotal;
5736
5737 // Add cost for each demanded 128-bit subvector extraction.
5738 // Luckily this is a lot easier than for insertion.
5739 APInt WidenedDemandedElts = DemandedElts.zext(NumLegalElts);
5740 auto *LaneTy =
5741 FixedVectorType::get(Ty->getElementType(), NumEltsPerLane);
5742
5743 for (unsigned I = 0; I != NumLanesTotal; ++I) {
5744 APInt LaneEltMask = WidenedDemandedElts.extractBits(
5745 NumEltsPerLane, I * NumEltsPerLane);
5746 if (LaneEltMask.isZero())
5747 continue;
5749 I * NumEltsPerLane, LaneTy);
5751 LaneTy, LaneEltMask, /*Insert*/ false, Extract, CostKind);
5752 }
5753
5754 return Cost;
5755 }
5756 }
5757
5758 // Fallback to default extraction.
5759 Cost += BaseT::getScalarizationOverhead(Ty, DemandedElts, /*Insert*/ false,
5760 Extract, CostKind);
5761 }
5762
5763 return Cost;
5764}
5765
5767X86TTIImpl::getReplicationShuffleCost(Type *EltTy, int ReplicationFactor,
5768 int VF, const APInt &DemandedDstElts,
5770 const unsigned EltTyBits = DL.getTypeSizeInBits(EltTy);
5771 // We don't differentiate element types here, only element bit width.
5772 EltTy = IntegerType::getIntNTy(EltTy->getContext(), EltTyBits);
5773
5774 auto bailout = [&]() {
5775 return BaseT::getReplicationShuffleCost(EltTy, ReplicationFactor, VF,
5776 DemandedDstElts, CostKind);
5777 };
5778
5779 // For now, only deal with AVX512 cases.
5780 if (!ST->hasAVX512())
5781 return bailout();
5782
5783 // Do we have a native shuffle for this element type, or should we promote?
5784 unsigned PromEltTyBits = EltTyBits;
5785 switch (EltTyBits) {
5786 case 32:
5787 case 64:
5788 break; // AVX512F.
5789 case 16:
5790 if (!ST->hasBWI())
5791 PromEltTyBits = 32; // promote to i32, AVX512F.
5792 break; // AVX512BW
5793 case 8:
5794 if (!ST->hasVBMI())
5795 PromEltTyBits = 32; // promote to i32, AVX512F.
5796 break; // AVX512VBMI
5797 case 1:
5798 // There is no support for shuffling i1 elements. We *must* promote.
5799 if (ST->hasBWI()) {
5800 if (ST->hasVBMI())
5801 PromEltTyBits = 8; // promote to i8, AVX512VBMI.
5802 else
5803 PromEltTyBits = 16; // promote to i16, AVX512BW.
5804 break;
5805 }
5806 PromEltTyBits = 32; // promote to i32, AVX512F.
5807 break;
5808 default:
5809 return bailout();
5810 }
5811 auto *PromEltTy = IntegerType::getIntNTy(EltTy->getContext(), PromEltTyBits);
5812
5813 auto *SrcVecTy = FixedVectorType::get(EltTy, VF);
5814 auto *PromSrcVecTy = FixedVectorType::get(PromEltTy, VF);
5815
5816 int NumDstElements = VF * ReplicationFactor;
5817 auto *PromDstVecTy = FixedVectorType::get(PromEltTy, NumDstElements);
5818 auto *DstVecTy = FixedVectorType::get(EltTy, NumDstElements);
5819
5820 // Legalize the types.
5821 MVT LegalSrcVecTy = getTypeLegalizationCost(SrcVecTy).second;
5822 MVT LegalPromSrcVecTy = getTypeLegalizationCost(PromSrcVecTy).second;
5823 MVT LegalPromDstVecTy = getTypeLegalizationCost(PromDstVecTy).second;
5824 MVT LegalDstVecTy = getTypeLegalizationCost(DstVecTy).second;
5825 // They should have legalized into vector types.
5826 if (!LegalSrcVecTy.isVector() || !LegalPromSrcVecTy.isVector() ||
5827 !LegalPromDstVecTy.isVector() || !LegalDstVecTy.isVector())
5828 return bailout();
5829
5830 if (PromEltTyBits != EltTyBits) {
5831 // If we have to perform the shuffle with wider elt type than our data type,
5832 // then we will first need to anyext (we don't care about the new bits)
5833 // the source elements, and then truncate Dst elements.
5834 InstructionCost PromotionCost;
5835 PromotionCost += getCastInstrCost(
5836 Instruction::SExt, /*Dst=*/PromSrcVecTy, /*Src=*/SrcVecTy,
5838 PromotionCost +=
5839 getCastInstrCost(Instruction::Trunc, /*Dst=*/DstVecTy,
5840 /*Src=*/PromDstVecTy,
5842 return PromotionCost + getReplicationShuffleCost(PromEltTy,
5843 ReplicationFactor, VF,
5844 DemandedDstElts, CostKind);
5845 }
5846
5847 assert(LegalSrcVecTy.getScalarSizeInBits() == EltTyBits &&
5848 LegalSrcVecTy.getScalarType() == LegalDstVecTy.getScalarType() &&
5849 "We expect that the legalization doesn't affect the element width, "
5850 "doesn't coalesce/split elements.");
5851
5852 unsigned NumEltsPerDstVec = LegalDstVecTy.getVectorNumElements();
5853 unsigned NumDstVectors =
5854 divideCeil(DstVecTy->getNumElements(), NumEltsPerDstVec);
5855
5856 auto *SingleDstVecTy = FixedVectorType::get(EltTy, NumEltsPerDstVec);
5857
5858 // Not all the produced Dst elements may be demanded. In our case,
5859 // given that a single Dst vector is formed by a single shuffle,
5860 // if all elements that will form a single Dst vector aren't demanded,
5861 // then we won't need to do that shuffle, so adjust the cost accordingly.
5862 APInt DemandedDstVectors = APIntOps::ScaleBitMask(
5863 DemandedDstElts.zext(NumDstVectors * NumEltsPerDstVec), NumDstVectors);
5864 unsigned NumDstVectorsDemanded = DemandedDstVectors.popcount();
5865
5866 InstructionCost SingleShuffleCost =
5867 getShuffleCost(TTI::SK_PermuteSingleSrc, SingleDstVecTy, SingleDstVecTy,
5868 CostKind, /*Mask=*/{},
5869 /*Index=*/0, /*SubTp=*/nullptr);
5870 return NumDstVectorsDemanded * SingleShuffleCost;
5871}
5872
5874 Align Alignment,
5875 unsigned AddressSpace,
5877 TTI::OperandValueInfo OpInfo,
5878 const Instruction *I) const {
5879 // FIXME: Load latency isn't handled here
5880 if (Opcode == Instruction::Load && CostKind == TTI::TCK_Latency)
5881 return BaseT::getMemoryOpCost(Opcode, Src, Alignment, AddressSpace,
5882 CostKind, OpInfo, I);
5883
5884 // TODO: Handle other cost kinds.
5886 if (auto *SI = dyn_cast_or_null<StoreInst>(I)) {
5887 // Store instruction with index and scale costs 2 Uops.
5888 // Check the preceding GEP to identify non-const indices.
5889 if (auto *GEP = dyn_cast<GetElementPtrInst>(SI->getPointerOperand())) {
5890 if (!all_of(GEP->indices(), [](Value *V) { return isa<Constant>(V); }))
5891 return TTI::TCC_Basic * 2;
5892 }
5893 }
5894 return TTI::TCC_Basic;
5895 }
5896
5897 assert((Opcode == Instruction::Load || Opcode == Instruction::Store) &&
5898 "Invalid Opcode");
5899 // Type legalization can't handle structs
5900 if (TLI->getValueType(DL, Src, true) == MVT::Other)
5901 return BaseT::getMemoryOpCost(Opcode, Src, Alignment, AddressSpace,
5902 CostKind, OpInfo, I);
5903
5904 // Legalize the type.
5905 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Src);
5906
5907 auto *VTy = dyn_cast<FixedVectorType>(Src);
5908
5910
5911 // Add a cost for constant load to vector.
5912 if (Opcode == Instruction::Store && OpInfo.isConstant())
5913 Cost += getMemoryOpCost(Instruction::Load, Src, DL.getABITypeAlign(Src),
5914 /*AddressSpace=*/0, CostKind, OpInfo);
5915
5916 // Handle the simple case of non-vectors.
5917 // NOTE: this assumes that legalization never creates vector from scalars!
5918 if (!VTy || !LT.second.isVector()) {
5919 // Each load/store unit costs 1.
5920 return (LT.second.isFloatingPoint() ? Cost : 0) + LT.first * 1;
5921 }
5922
5923 bool IsLoad = Opcode == Instruction::Load;
5924
5925 Type *EltTy = VTy->getElementType();
5926
5927 const int EltTyBits = DL.getTypeSizeInBits(EltTy);
5928
5929 // Source of truth: how many elements were there in the original IR vector?
5930 const unsigned SrcNumElt = VTy->getNumElements();
5931
5932 // How far have we gotten?
5933 int NumEltRemaining = SrcNumElt;
5934 // Note that we intentionally capture by-reference, NumEltRemaining changes.
5935 auto NumEltDone = [&]() { return SrcNumElt - NumEltRemaining; };
5936
5937 const int MaxLegalOpSizeBytes = divideCeil(LT.second.getSizeInBits(), 8);
5938
5939 // Note that even if we can store 64 bits of an XMM, we still operate on XMM.
5940 const unsigned XMMBits = 128;
5941 if (XMMBits % EltTyBits != 0)
5942 // Vector size must be a multiple of the element size. I.e. no padding.
5943 return BaseT::getMemoryOpCost(Opcode, Src, Alignment, AddressSpace,
5944 CostKind, OpInfo, I);
5945 const int NumEltPerXMM = XMMBits / EltTyBits;
5946
5947 auto *XMMVecTy = FixedVectorType::get(EltTy, NumEltPerXMM);
5948
5949 for (int CurrOpSizeBytes = MaxLegalOpSizeBytes, SubVecEltsLeft = 0;
5950 NumEltRemaining > 0; CurrOpSizeBytes /= 2) {
5951 // How many elements would a single op deal with at once?
5952 if ((8 * CurrOpSizeBytes) % EltTyBits != 0)
5953 // Vector size must be a multiple of the element size. I.e. no padding.
5954 return BaseT::getMemoryOpCost(Opcode, Src, Alignment, AddressSpace,
5955 CostKind, OpInfo, I);
5956 int CurrNumEltPerOp = (8 * CurrOpSizeBytes) / EltTyBits;
5957
5958 assert(CurrOpSizeBytes > 0 && CurrNumEltPerOp > 0 && "How'd we get here?");
5959 assert((((NumEltRemaining * EltTyBits) < (2 * 8 * CurrOpSizeBytes)) ||
5960 (CurrOpSizeBytes == MaxLegalOpSizeBytes)) &&
5961 "Unless we haven't halved the op size yet, "
5962 "we have less than two op's sized units of work left.");
5963
5964 auto *CurrVecTy = CurrNumEltPerOp > NumEltPerXMM
5965 ? FixedVectorType::get(EltTy, CurrNumEltPerOp)
5966 : XMMVecTy;
5967
5968 assert(CurrVecTy->getNumElements() % CurrNumEltPerOp == 0 &&
5969 "After halving sizes, the vector elt count is no longer a multiple "
5970 "of number of elements per operation?");
5971 auto *CoalescedVecTy =
5972 CurrNumEltPerOp == 1
5973 ? CurrVecTy
5975 IntegerType::get(Src->getContext(),
5976 EltTyBits * CurrNumEltPerOp),
5977 CurrVecTy->getNumElements() / CurrNumEltPerOp);
5978 assert(DL.getTypeSizeInBits(CoalescedVecTy) ==
5979 DL.getTypeSizeInBits(CurrVecTy) &&
5980 "coalesciing elements doesn't change vector width.");
5981
5982 while (NumEltRemaining > 0) {
5983 assert(SubVecEltsLeft >= 0 && "Subreg element count overconsumtion?");
5984
5985 // Can we use this vector size, as per the remaining element count?
5986 // Iff the vector is naturally aligned, we can do a wide load regardless.
5987 if (NumEltRemaining < CurrNumEltPerOp &&
5988 (!IsLoad || Alignment < CurrOpSizeBytes) && CurrOpSizeBytes != 1)
5989 break; // Try smalled vector size.
5990
5991 // This isn't exactly right. We're using slow unaligned 32-byte accesses
5992 // as a proxy for a double-pumped AVX memory interface such as on
5993 // Sandybridge.
5994 // Sub-32-bit loads/stores will be slower either with PINSR*/PEXTR* or
5995 // will be scalarized.
5996 //
5997 // For a vector load, each non-0th 1/2/4-byte in-lane remainder chunk is
5998 // materialized by a *single* folded PINSR*(mem) that both loads and
5999 // inserts the lane (1B->PINSRB, 2B->PINSRW, 4B->PINSRD; the byte and
6000 // dword folds need SSE4.1, the word fold only SSE2).
6001 // When that fold is available the chunk is one instruction, so it must be
6002 // priced once here (as a plain load) and the separate lane-insert charge
6003 // below must be skipped - otherwise the folded insert is double-counted.
6004 // Stores (the symmetric PEXTR*(mem) fold) are left unchanged here.
6005 bool Is0thSubVec = (NumEltDone() % LT.second.getVectorNumElements()) == 0;
6006 bool FoldedInLaneInsert = IsLoad && !Is0thSubVec &&
6007 ((CurrOpSizeBytes == 1 && ST->hasSSE41()) ||
6008 (CurrOpSizeBytes == 2 && ST->hasSSE2()) ||
6009 (CurrOpSizeBytes == 4 && ST->hasSSE41()));
6010 if (CurrOpSizeBytes == 32 && ST->isUnalignedMem32Slow())
6011 Cost += 2;
6012 else if (CurrOpSizeBytes < 4 && !FoldedInLaneInsert)
6013 Cost += 2;
6014 else
6015 Cost += 1;
6016
6017 // If we're loading a uniform value, then we don't need to split the load,
6018 // loading just a single (widest) vector can be reused by all splits.
6019 if (IsLoad && OpInfo.isUniform())
6020 return Cost;
6021
6022 // If we have fully processed the previous reg, we need to replenish it.
6023 if (SubVecEltsLeft == 0) {
6024 SubVecEltsLeft += CurrVecTy->getNumElements();
6025 // And that's free only for the 0'th subvector of a legalized vector.
6026 if (!Is0thSubVec)
6027 Cost +=
6030 VTy, VTy, CostKind, {}, NumEltDone(), CurrVecTy);
6031 }
6032
6033 // While we can directly load/store ZMM, YMM, and 64-bit halves of XMM,
6034 // for smaller widths (32/16/8) we have to insert/extract them separately.
6035 // Again, it's free for the 0'th subreg (if op is 32/64 bit wide,
6036 // but let's pretend that it is also true for 16/8 bit wide ops...)
6037 if (CurrOpSizeBytes <= 32 / 8 && !Is0thSubVec && !FoldedInLaneInsert) {
6038 int NumEltDoneInCurrXMM = NumEltDone() % NumEltPerXMM;
6039 assert(NumEltDoneInCurrXMM % CurrNumEltPerOp == 0 && "");
6040 int CoalescedVecEltIdx = NumEltDoneInCurrXMM / CurrNumEltPerOp;
6041 APInt DemandedElts =
6042 APInt::getBitsSet(CoalescedVecTy->getNumElements(),
6043 CoalescedVecEltIdx, CoalescedVecEltIdx + 1);
6044 assert(DemandedElts.popcount() == 1 && "Inserting single value");
6045 Cost += getScalarizationOverhead(CoalescedVecTy, DemandedElts, IsLoad,
6046 !IsLoad, CostKind);
6047 }
6048
6049 SubVecEltsLeft -= CurrNumEltPerOp;
6050 NumEltRemaining -= CurrNumEltPerOp;
6051 Alignment = commonAlignment(Alignment, CurrOpSizeBytes);
6052 }
6053 }
6054
6055 assert(NumEltRemaining <= 0 && "Should have processed all the elements.");
6056
6057 return Cost;
6058}
6059
6063 switch (MICA.getID()) {
6064 case Intrinsic::masked_scatter:
6065 case Intrinsic::masked_gather:
6066 return getGatherScatterOpCost(MICA, CostKind);
6067 case Intrinsic::masked_load:
6068 case Intrinsic::masked_store:
6069 return getMaskedMemoryOpCost(MICA, CostKind);
6070 case Intrinsic::masked_compressstore:
6071 // Fallback to scalarization for slow compressstore targets (e.g. znver4).
6072 if (ST->isVecCompressStoreSlow())
6074 break;
6075 }
6076
6077 static const CostKindTblEntry AVX512VBMI2CostTable[] = {
6078 { Intrinsic::masked_expandload, MVT::v16i8, { 2, 7, 1, 3 } },
6079 { Intrinsic::masked_expandload, MVT::v32i8, { 2, 8, 1, 3 } },
6080 { Intrinsic::masked_expandload, MVT::v64i8, { 2, 9, 1, 3 } },
6081
6082 { Intrinsic::masked_expandload, MVT::v8i16, { 2, 7, 1, 3 } },
6083 { Intrinsic::masked_expandload, MVT::v16i16, { 2, 8, 1, 3 } },
6084 { Intrinsic::masked_expandload, MVT::v32i16, { 2, 9, 1, 3 } },
6085
6086 { Intrinsic::masked_compressstore, MVT::v16i8, { 3,10, 1, 7 } },
6087 { Intrinsic::masked_compressstore, MVT::v32i8, { 3,11, 1, 7 } },
6088 { Intrinsic::masked_compressstore, MVT::v64i8, { 3,12, 1, 8 } },
6089
6090 { Intrinsic::masked_compressstore, MVT::v8i16, { 3,10, 1, 7 } },
6091 { Intrinsic::masked_compressstore, MVT::v16i16, { 3,11, 1, 7 } },
6092 { Intrinsic::masked_compressstore, MVT::v32i16, { 3,12, 1, 8 } },
6093 };
6094
6095 static const CostKindTblEntry AVX512CostTable[] = {
6096 { Intrinsic::masked_expandload, MVT::v4i32, { 2, 7, 1, 3 } },
6097 { Intrinsic::masked_expandload, MVT::v4f32, { 2, 7, 1, 3 } },
6098 { Intrinsic::masked_expandload, MVT::v8i32, { 2, 8, 1, 3 } },
6099 { Intrinsic::masked_expandload, MVT::v8f32, { 2, 8, 1, 3 } },
6100 { Intrinsic::masked_expandload, MVT::v16i32, { 2, 9, 1, 3 } },
6101 { Intrinsic::masked_expandload, MVT::v16f32, { 2, 9, 1, 3 } },
6102
6103 { Intrinsic::masked_expandload, MVT::v2i64, { 2, 7, 1, 3 } },
6104 { Intrinsic::masked_expandload, MVT::v2f64, { 2, 7, 1, 3 } },
6105 { Intrinsic::masked_expandload, MVT::v4i64, { 2, 8, 1, 3 } },
6106 { Intrinsic::masked_expandload, MVT::v4f64, { 2, 8, 1, 3 } },
6107 { Intrinsic::masked_expandload, MVT::v8i64, { 2, 9, 1, 3 } },
6108 { Intrinsic::masked_expandload, MVT::v8f64, { 2, 9, 1, 3 } },
6109
6110 { Intrinsic::masked_compressstore, MVT::v4i32, { 3,10, 1, 7 } },
6111 { Intrinsic::masked_compressstore, MVT::v4f32, { 3,10, 1, 7 } },
6112 { Intrinsic::masked_compressstore, MVT::v8i32, { 3,11, 1, 7 } },
6113 { Intrinsic::masked_compressstore, MVT::v8f32, { 3,11, 1, 7 } },
6114 { Intrinsic::masked_compressstore, MVT::v16i32, { 3,12, 1, 8 } },
6115 { Intrinsic::masked_compressstore, MVT::v16f32, { 3,12, 1, 8 } },
6116
6117 { Intrinsic::masked_compressstore, MVT::v2i64, { 3,10, 1, 7 } },
6118 { Intrinsic::masked_compressstore, MVT::v2f64, { 3,10, 1, 7 } },
6119 { Intrinsic::masked_compressstore, MVT::v4i64, { 3,11, 1, 7 } },
6120 { Intrinsic::masked_compressstore, MVT::v4f64, { 3,11, 1, 7 } },
6121 { Intrinsic::masked_compressstore, MVT::v8i64, { 3,12, 1, 8 } },
6122 { Intrinsic::masked_compressstore, MVT::v8f64, { 3,12, 1, 8 } },
6123 };
6124
6125 std::pair<InstructionCost, MVT> LT =
6127
6128 if (ST->hasVBMI2())
6129 if (const auto *Entry =
6130 CostTableLookup(AVX512VBMI2CostTable, MICA.getID(), LT.second))
6131 if (auto KindCost = Entry->Cost[CostKind])
6132 return LT.first * *KindCost;
6133
6134 if (ST->hasAVX512())
6135 if (const auto *Entry =
6136 CostTableLookup(AVX512CostTable, MICA.getID(), LT.second))
6137 if (auto KindCost = Entry->Cost[CostKind])
6138 return LT.first * *KindCost;
6139
6141}
6142
6146 unsigned Opcode = MICA.getID() == Intrinsic::masked_load ? Instruction::Load
6147 : Instruction::Store;
6148 Type *SrcTy = MICA.getDataType();
6149 Align Alignment = MICA.getAlignment();
6150 unsigned AddressSpace = MICA.getAddressSpace();
6151
6152 bool IsLoad = (Instruction::Load == Opcode);
6153 bool IsStore = (Instruction::Store == Opcode);
6154
6155 auto *SrcVTy = dyn_cast<FixedVectorType>(SrcTy);
6156 if (!SrcVTy)
6157 // To calculate scalar take the regular cost, without mask
6158 return getMemoryOpCost(Opcode, SrcTy, Alignment, AddressSpace, CostKind);
6159
6160 unsigned NumElem = SrcVTy->getNumElements();
6161 auto *MaskTy =
6162 FixedVectorType::get(Type::getInt8Ty(SrcVTy->getContext()), NumElem);
6163 if ((IsLoad && !isLegalMaskedLoad(SrcVTy, Alignment, AddressSpace)) ||
6164 (IsStore && !isLegalMaskedStore(SrcVTy, Alignment, AddressSpace))) {
6165 // Scalarization
6166 APInt DemandedElts = APInt::getAllOnes(NumElem);
6168 MaskTy, DemandedElts, /*Insert*/ false, /*Extract*/ true, CostKind);
6169 InstructionCost ScalarCompareCost = getCmpSelInstrCost(
6170 Instruction::ICmp, Type::getInt8Ty(SrcVTy->getContext()), nullptr,
6172 InstructionCost BranchCost = getCFInstrCost(Instruction::CondBr, CostKind);
6173 InstructionCost MaskCmpCost = NumElem * (BranchCost + ScalarCompareCost);
6175 SrcVTy, DemandedElts, IsLoad, IsStore, CostKind);
6176 InstructionCost MemopCost =
6177 NumElem * BaseT::getMemoryOpCost(Opcode, SrcVTy->getScalarType(),
6178 Alignment, AddressSpace, CostKind);
6179 return MemopCost + ValueSplitCost + MaskSplitCost + MaskCmpCost;
6180 }
6181
6182 // Legalize the type.
6183 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(SrcVTy);
6184 auto VT = TLI->getValueType(DL, SrcVTy);
6186 MVT Ty = LT.second;
6187 if (Ty == MVT::i16 || Ty == MVT::i32 || Ty == MVT::i64)
6188 // APX masked load/store for scalar is cheap.
6189 return Cost + LT.first;
6190
6191 if (VT.isSimple() && Ty != VT.getSimpleVT() &&
6192 LT.second.getVectorNumElements() == NumElem)
6193 // Promotion requires extend/truncate for data and a shuffle for mask.
6194 Cost += getShuffleCost(TTI::SK_PermuteTwoSrc, SrcVTy, SrcVTy, CostKind, {},
6195 0, nullptr) +
6196 getShuffleCost(TTI::SK_PermuteTwoSrc, MaskTy, MaskTy, CostKind, {},
6197 0, nullptr);
6198
6199 else if (LT.first * Ty.getVectorNumElements() > NumElem) {
6200 auto *NewMaskTy = FixedVectorType::get(MaskTy->getElementType(),
6201 (unsigned)LT.first.getValue() *
6202 Ty.getVectorNumElements());
6203 // Expanding requires fill mask with zeroes
6204 Cost += getShuffleCost(TTI::SK_InsertSubvector, NewMaskTy, NewMaskTy,
6205 CostKind, {}, 0, MaskTy);
6206 }
6207
6208 // Predicate fanout (see getPredicateFanoutCost): only a variable mask needs
6209 // a per-part sub-mask; a constant mask is folded by codegen and pays nothing.
6210 InstructionCost MaskExpCost = 0;
6211 if (MICA.getVariableMask()) {
6212 auto *MaskVecTy =
6213 FixedVectorType::get(Type::getInt1Ty(SrcVTy->getContext()), NumElem);
6214 MaskExpCost = getPredicateFanoutCost(*this, SrcVTy, MaskVecTy);
6215 }
6216
6217 // Pre-AVX512 - each maskmov load costs 2 + store costs ~8.
6218 if (!ST->hasAVX512())
6219 return Cost + LT.first * (IsLoad ? 2 : 8) + MaskExpCost;
6220
6221 // AVX-512 masked load/store is cheaper.
6222 return Cost + LT.first + MaskExpCost;
6223}
6224
6226 ArrayRef<const Value *> Ptrs, const Value *Base,
6227 const TTI::PointersChainInfo &Info, Type *AccessTy,
6228 const TTI::TargetCostKind CostKind) const {
6229 if (Info.isSameBase() && Info.isKnownStride()) {
6230 // If all the pointers have known stride all the differences are translated
6231 // into constants. X86 memory addressing allows encoding it into
6232 // displacement. So we just need to take the base GEP cost.
6233 if (const auto *BaseGEP = dyn_cast<GetElementPtrInst>(Base)) {
6234 SmallVector<const Value *> Indices(BaseGEP->indices());
6235 return getGEPCost(BaseGEP->getSourceElementType(),
6236 BaseGEP->getPointerOperand(), Indices, CostKind,
6237 nullptr);
6238 }
6239 return TTI::TCC_Free;
6240 }
6241 return BaseT::getPointersChainCost(Ptrs, Base, Info, AccessTy, CostKind);
6242}
6243
6246 const SCEV *Ptr,
6248 // Address computations in vectorized code with non-consecutive addresses will
6249 // likely result in more instructions compared to scalar code where the
6250 // computation can more often be merged into the index mode. The resulting
6251 // extra micro-ops can significantly decrease throughput.
6252 const unsigned NumVectorInstToHideOverhead = 10;
6253
6254 // Cost modeling of Strided Access Computation is hidden by the indexing
6255 // modes of X86 regardless of the stride value. We dont believe that there
6256 // is a difference between constant strided access in gerenal and constant
6257 // strided value which is less than or equal to 64.
6258 // Even in the case of (loop invariant) stride whose value is not known at
6259 // compile time, the address computation will not incur more than one extra
6260 // ADD instruction.
6261 if (PtrTy->isVectorTy() && SE) {
6263 return 1;
6264 if (!ST->hasAVX2()) {
6265 // TODO: AVX2 is the current cut-off because we don't have correct
6266 // interleaving costs for prior ISA's.
6267 if (!BaseT::isStridedAccess(Ptr))
6268 return NumVectorInstToHideOverhead;
6269 }
6270 }
6271
6272 return BaseT::getAddressComputationCost(PtrTy, SE, Ptr, CostKind);
6273}
6274
6276 unsigned Opcode, Type *InputTypeA, Type *InputTypeB, Type *AccumType,
6278 TTI::PartialReductionExtendKind OpBExtend, std::optional<unsigned> BinOp,
6279 TTI::TargetCostKind CostKind, std::optional<FastMathFlags> FMF) const {
6280 auto ExpandCost = [&]() {
6281 return BaseT::getPartialReductionCost(Opcode, InputTypeA, InputTypeB,
6282 AccumType, VF, OpAExtend, OpBExtend,
6283 BinOp, CostKind, FMF);
6284 };
6285
6286 // The dot product instructions multiply-accumulate i8 x i8 -> i32,
6287 // i16 x i16 -> i32, bf16 x bf16 -> f32 or f16 x f16 -> f32. Partial
6288 // reductions may also multiply inputs extended from different types, which
6289 // they can't handle.
6290 if (VF.isScalable() || !BinOp || OpAExtend == TTI::PR_None ||
6291 OpBExtend == TTI::PR_None || InputTypeA != InputTypeB)
6292 return ExpandCost();
6293
6294 unsigned Opc;
6295 if (Opcode == Instruction::Add && *BinOp == Instruction::Mul &&
6296 AccumType->isIntegerTy(32) &&
6297 (InputTypeA->isIntegerTy(8) || InputTypeA->isIntegerTy(16))) {
6298 if (OpAExtend != OpBExtend)
6300 else if (OpAExtend == TTI::PR_SignExtend)
6302 else
6304 } else if (Opcode == Instruction::FAdd && *BinOp == Instruction::FMul &&
6305 AccumType->isFloatTy() &&
6306 (InputTypeA->isBFloatTy() || InputTypeA->isHalfTy())) {
6307 // VDPBF16PS and VDPPHPS, like the expansion, reassociate the additions and
6308 // fuse the multiplications.
6309 if (!FMF || !FMF->allowReassoc() || !FMF->allowContract())
6312 } else {
6313 return ExpandCost();
6314 }
6315
6316 unsigned Ratio =
6317 AccumType->getScalarSizeInBits() / InputTypeA->getScalarSizeInBits();
6318 if (!VF.isKnownMultipleOf(Ratio))
6319 return ExpandCost();
6320
6321 // One dot product per legal accumulator vector. Accumulators narrower than
6322 // a legal vector are widened by expanding the partial reduction instead.
6323 auto *AccVecTy = VectorType::get(AccumType, VF.divideCoefficientBy(Ratio));
6324 auto *InputVecTy = VectorType::get(InputTypeA, VF);
6325 std::pair<InstructionCost, MVT> AccLT = getTypeLegalizationCost(AccVecTy);
6326 std::pair<InstructionCost, MVT> InputLT = getTypeLegalizationCost(InputVecTy);
6327 if (AccLT.second.getFixedSizeInBits() >
6328 AccVecTy->getPrimitiveSizeInBits().getFixedValue() ||
6329 !TLI->isPartialReduceMLALegalOrCustom(Opc, AccLT.second, InputLT.second))
6330 return ExpandCost();
6331
6332 return AccLT.first;
6333}
6334
6337 std::optional<FastMathFlags> FMF,
6340 return BaseT::getArithmeticReductionCost(Opcode, ValTy, FMF, CostKind);
6341
6342 // We use llvm-mca across all supported CPUs to measure the logic cost stats.
6343 // We use the Intel Architecture Code Analyzer(IACA) to measure the throughput
6344 // and make it as the cost. TODO: Update old IACA numbers to llvm-mca.
6345
6346 static const CostKindTblEntry SLMCostTbl[] = {
6347 { ISD::FADD, MVT::v2f64, {3, 3, 3, 3} },
6348 { ISD::ADD, MVT::v2i64, {5, 5, 5, 5} },
6349 };
6350
6351 static const CostKindTblEntry SSE2CostTbl[] = {
6352 { ISD::FADD, MVT::v2f64, {2, 2, 2, 2} },
6353 { ISD::FADD, MVT::v2f32, {2, 2, 2, 2} },
6354 { ISD::FADD, MVT::v4f32, {4, 4, 4, 4} },
6355 { ISD::ADD, MVT::v2i64, {2, 2, 2, 2} }, // The data reported by the IACA tool is "1.6".
6356 { ISD::ADD, MVT::v2i32, {2, 2, 2, 2} }, // FIXME: chosen to be less than v4i32
6357 { ISD::ADD, MVT::v4i32, {3, 3, 3, 3} }, // The data reported by the IACA tool is "3.3".
6358 { ISD::ADD, MVT::v2i16, {2, 2, 2, 2} }, // The data reported by the IACA tool is "4.3".
6359 { ISD::ADD, MVT::v4i16, {3, 3, 3, 3} }, // The data reported by the IACA tool is "4.3".
6360 { ISD::ADD, MVT::v8i16, {4, 4, 4, 4} }, // The data reported by the IACA tool is "4.3".
6361 { ISD::ADD, MVT::v2i8, {2, 2, 2, 2} },
6362 { ISD::ADD, MVT::v4i8, {2, 2, 2, 2} },
6363 { ISD::ADD, MVT::v8i8, {2, 2, 2, 2} },
6364 { ISD::ADD, MVT::v16i8, {3, 3, 3, 3} },
6365
6366 { ISD::AND, MVT::v2i64, {2, 2, 3, 3} },
6367 { ISD::AND, MVT::v4i32, {3, 4, 5, 5} },
6368 { ISD::AND, MVT::v8i16, {4, 7, 8, 8} },
6369 { ISD::AND, MVT::v16i8, {6,10,11,11} },
6370 { ISD::OR, MVT::v2i64, {2, 2, 3, 3} },
6371 { ISD::OR, MVT::v4i32, {3, 4, 5, 5} },
6372 { ISD::OR, MVT::v8i16, {4, 7, 8, 8} },
6373 { ISD::OR, MVT::v16i8, {6,10,11,11} },
6374 { ISD::XOR, MVT::v2i64, {2, 2, 3, 3} },
6375 { ISD::XOR, MVT::v4i32, {3, 4, 5, 5} },
6376 { ISD::XOR, MVT::v8i16, {4, 7, 8, 8} },
6377 { ISD::XOR, MVT::v16i8, {6,10,11,11} },
6378 };
6379
6380 static const CostKindTblEntry AVX1CostTbl[] = {
6381 { ISD::FADD, MVT::v4f64, {3, 3, 3, 3} },
6382 { ISD::FADD, MVT::v4f32, {3, 3, 3, 3} },
6383 { ISD::FADD, MVT::v8f32, {4, 4, 4, 4} },
6384 { ISD::ADD, MVT::v2i64, {1, 1, 1, 1} }, // The data reported by the IACA tool is "1.5".
6385 { ISD::ADD, MVT::v4i64, {3, 3, 3, 3} },
6386 { ISD::ADD, MVT::v8i32, {5, 5, 5, 5} },
6387 { ISD::ADD, MVT::v16i16, {5, 5, 5, 5} },
6388 { ISD::ADD, MVT::v32i8, {4, 4, 4, 4} },
6389
6390 { ISD::AND, MVT::v4i64, {3, 7, 5, 5} },
6391 { ISD::AND, MVT::v8i32, {4, 9, 7, 7} },
6392 { ISD::AND, MVT::v16i16, {5,11, 9, 9} },
6393 { ISD::AND, MVT::v8i16, {4, 7, 7, 7} },
6394 { ISD::AND, MVT::v32i8, {6,13,11,11} },
6395 { ISD::AND, MVT::v16i8, {5,10, 9, 9} },
6396 { ISD::OR, MVT::v4i64, {3, 7, 5, 5} },
6397 { ISD::OR, MVT::v8i32, {4, 9, 7, 7} },
6398 { ISD::OR, MVT::v16i16, {5,11, 9, 9} },
6399 { ISD::OR, MVT::v8i16, {4, 7, 7, 7} },
6400 { ISD::OR, MVT::v32i8, {6,13,11,11} },
6401 { ISD::OR, MVT::v16i8, {5,10, 9, 9} },
6402 { ISD::XOR, MVT::v4i64, {3, 7, 5, 5} },
6403 { ISD::XOR, MVT::v8i32, {4, 9, 7, 7} },
6404 { ISD::XOR, MVT::v16i16, {5,11, 9, 9} },
6405 { ISD::XOR, MVT::v8i16, {4, 7, 7, 7} },
6406 { ISD::XOR, MVT::v32i8, {6,13,11,11} },
6407 { ISD::XOR, MVT::v16i8, {5,10, 9, 9} },
6408 };
6409
6410 static const CostKindTblEntry AVX2CostTbl[] = {
6411 { ISD::AND, MVT::v4i64, {2, 7, 5, 5} },
6412 { ISD::AND, MVT::v2i64, {1, 2, 3, 3} },
6413 { ISD::AND, MVT::v8i32, {3, 9, 7, 7} },
6414 { ISD::AND, MVT::v4i32, {2, 4, 5, 5} },
6415 { ISD::AND, MVT::v16i16, {3,11, 9, 9} },
6416 { ISD::AND, MVT::v8i16, {2, 6, 7, 7} },
6417 { ISD::AND, MVT::v32i8, {3,13,11,11} },
6418 { ISD::AND, MVT::v16i8, {3, 8, 9, 9} },
6419 { ISD::OR, MVT::v4i64, {2, 7, 5, 5} },
6420 { ISD::OR, MVT::v2i64, {1, 2, 3, 3} },
6421 { ISD::OR, MVT::v8i32, {3, 9, 7, 7} },
6422 { ISD::OR, MVT::v4i32, {2, 4, 5, 5} },
6423 { ISD::OR, MVT::v16i16, {3,11, 9, 9} },
6424 { ISD::OR, MVT::v8i16, {2, 6, 7, 7} },
6425 { ISD::OR, MVT::v32i8, {3,13,11,11} },
6426 { ISD::OR, MVT::v16i8, {3, 8, 9, 9} },
6427 { ISD::XOR, MVT::v4i64, {2, 7, 5, 5} },
6428 { ISD::XOR, MVT::v2i64, {1, 2, 3, 3} },
6429 { ISD::XOR, MVT::v8i32, {3, 9, 7, 7} },
6430 { ISD::XOR, MVT::v4i32, {2, 4, 5, 5} },
6431 { ISD::XOR, MVT::v16i16, {3,11, 9, 9} },
6432 { ISD::XOR, MVT::v8i16, {2, 6, 7, 7} },
6433 { ISD::XOR, MVT::v32i8, {3,13,11,11} },
6434 { ISD::XOR, MVT::v16i8, {3, 8, 9, 9} },
6435 };
6436
6437 static const CostKindTblEntry AVX512FCostTbl[] = {
6438 { ISD::FADD, MVT::v8f64, {4, 4, 4, 4} },
6439 { ISD::FADD, MVT::v16f32, {5, 5, 5, 5} },
6440 { ISD::ADD, MVT::v8i64, {4, 4, 4, 4} },
6441 { ISD::ADD, MVT::v16i32, {6, 6, 6, 6} },
6442
6443 { ISD::AND, MVT::v8i64, {3,10, 7, 7} },
6444 { ISD::AND, MVT::v16i32, {4,12, 9, 9} },
6445 { ISD::AND, MVT::v32i16, {4,14,11,11} },
6446 { ISD::AND, MVT::v64i8, {4,16,13,13} },
6447 { ISD::AND, MVT::v16i8, {2, 8, 9, 9} },
6448 { ISD::OR, MVT::v8i64, {3,10, 7, 7} },
6449 { ISD::OR, MVT::v16i32, {4,12, 9, 9} },
6450 { ISD::OR, MVT::v32i16, {4,14,11,11} },
6451 { ISD::OR, MVT::v64i8, {4,16,13,13} },
6452 { ISD::OR, MVT::v16i8, {2, 8, 9, 9} },
6453 { ISD::XOR, MVT::v8i64, {3,10, 7, 7} },
6454 { ISD::XOR, MVT::v16i32, {4,12, 9, 9} },
6455 { ISD::XOR, MVT::v32i16, {4,14,11,11} },
6456 { ISD::XOR, MVT::v64i8, {4,16,13,13} },
6457 { ISD::XOR, MVT::v16i8, {2, 8, 9, 9} },
6458 };
6459
6460 static const CostKindTblEntry AVX512BWCostTbl[] = {
6461 { ISD::ADD, MVT::v32i16, {7, 7, 7, 7} },
6462 { ISD::ADD, MVT::v64i8, {4, 4, 4, 4} },
6463 };
6464
6465 int ISD = TLI->InstructionOpcodeToISD(Opcode);
6466 assert(ISD && "Invalid opcode");
6467
6468 // Before legalizing the type, give a chance to look up illegal narrow types
6469 // in the table.
6470 // FIXME: Is there a better way to do this?
6471 EVT VT = TLI->getValueType(DL, ValTy);
6472 if (VT.isSimple()) {
6473 MVT MTy = VT.getSimpleVT();
6474 if (ST->useSLMArithCosts())
6475 if (const auto *Entry = CostTableLookup(SLMCostTbl, ISD, MTy))
6476 if (auto KindCost = Entry->Cost[CostKind])
6477 return *KindCost;
6478
6479 if (ST->hasBWI())
6480 if (const auto *Entry = CostTableLookup(AVX512BWCostTbl, ISD, MTy))
6481 if (auto KindCost = Entry->Cost[CostKind])
6482 return *KindCost;
6483
6484 if (ST->hasAVX512())
6485 if (const auto *Entry = CostTableLookup(AVX512FCostTbl, ISD, MTy))
6486 if (auto KindCost = Entry->Cost[CostKind])
6487 return *KindCost;
6488
6489 if (ST->hasAVX2())
6490 if (const auto *Entry = CostTableLookup(AVX2CostTbl, ISD, MTy))
6491 if (auto KindCost = Entry->Cost[CostKind])
6492 return *KindCost;
6493
6494 if (ST->hasAVX())
6495 if (const auto *Entry = CostTableLookup(AVX1CostTbl, ISD, MTy))
6496 if (auto KindCost = Entry->Cost[CostKind])
6497 return *KindCost;
6498
6499 if (ST->hasSSE2())
6500 if (const auto *Entry = CostTableLookup(SSE2CostTbl, ISD, MTy))
6501 if (auto KindCost = Entry->Cost[CostKind])
6502 return *KindCost;
6503 }
6504
6505 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(ValTy);
6506
6507 MVT MTy = LT.second;
6508
6509 auto *ValVTy = cast<FixedVectorType>(ValTy);
6510
6511 InstructionCost ArithmeticCost = 0;
6512 if (LT.first != 1 && MTy.isVector() &&
6513 MTy.getVectorNumElements() < ValVTy->getNumElements()) {
6514 // Type needs to be split. We need LT.first - 1 arithmetic ops.
6515 auto *SingleOpTy = FixedVectorType::get(ValVTy->getElementType(),
6516 MTy.getVectorNumElements());
6517 ArithmeticCost = getArithmeticInstrCost(Opcode, SingleOpTy, CostKind);
6518 ArithmeticCost *= LT.first - 1;
6519 }
6520
6521 // FIXME: These assume a naive kshift+binop lowering, which is probably
6522 // conservative in most cases.
6523 static const CostKindTblEntry AVX512BoolReduction[] = {
6524 { ISD::AND, MVT::v2i1, { 3, 3, 3, 3} },
6525 { ISD::AND, MVT::v4i1, { 5, 5, 5, 5} },
6526 { ISD::AND, MVT::v8i1, { 7, 7, 7, 7} },
6527 { ISD::AND, MVT::v16i1, { 9, 9, 9, 9} },
6528 { ISD::AND, MVT::v32i1, {11,11,11,11} },
6529 { ISD::AND, MVT::v64i1, {13,13,13,13} },
6530 { ISD::OR, MVT::v2i1, { 3, 3, 3, 3} },
6531 { ISD::OR, MVT::v4i1, { 5, 5, 5, 5} },
6532 { ISD::OR, MVT::v8i1, { 7, 7, 7, 7} },
6533 { ISD::OR, MVT::v16i1, { 9, 9, 9, 9} },
6534 { ISD::OR, MVT::v32i1, {11,11,11,11} },
6535 { ISD::OR, MVT::v64i1, {13,13,13,13} },
6536 };
6537
6538 static const CostKindTblEntry AVX2BoolReduction[] = {
6539 { ISD::AND, MVT::v16i16, { 2, 2, 2, 2} }, // vpmovmskb + cmp
6540 { ISD::AND, MVT::v32i8, { 2, 2, 2, 2} }, // vpmovmskb + cmp
6541 { ISD::OR, MVT::v16i16, { 2, 2, 2, 2} }, // vpmovmskb + cmp
6542 { ISD::OR, MVT::v32i8, { 2, 2, 2, 2} }, // vpmovmskb + cmp
6543 };
6544
6545 static const CostKindTblEntry AVX1BoolReduction[] = {
6546 { ISD::AND, MVT::v4i64, {2, 2, 2, 2} }, // vmovmskpd + cmp
6547 { ISD::AND, MVT::v8i32, {2, 2, 2, 2} }, // vmovmskps + cmp
6548 { ISD::AND, MVT::v16i16, {4, 4, 4, 4} }, // vextractf128 + vpand + vpmovmskb + cmp
6549 { ISD::AND, MVT::v32i8, {4, 4, 4, 4} }, // vextractf128 + vpand + vpmovmskb + cmp
6550 { ISD::OR, MVT::v4i64, {2, 2, 2, 2} }, // vmovmskpd + cmp
6551 { ISD::OR, MVT::v8i32, {2, 2, 2, 2} }, // vmovmskps + cmp
6552 { ISD::OR, MVT::v16i16, {4, 4, 4, 4} }, // vextractf128 + vpor + vpmovmskb + cmp
6553 { ISD::OR, MVT::v32i8, {4, 4, 4, 4} }, // vextractf128 + vpor + vpmovmskb + cmp
6554 };
6555
6556 static const CostKindTblEntry SSE2BoolReduction[] = {
6557 { ISD::AND, MVT::v2i64, {2, 2, 2, 2} }, // movmskpd + cmp
6558 { ISD::AND, MVT::v4i32, {2, 2, 2, 2} }, // movmskps + cmp
6559 { ISD::AND, MVT::v8i16, {2, 2, 2, 2} }, // pmovmskb + cmp
6560 { ISD::AND, MVT::v16i8, {2, 2, 2, 2} }, // pmovmskb + cmp
6561 { ISD::OR, MVT::v2i64, {2, 2, 2, 2} }, // movmskpd + cmp
6562 { ISD::OR, MVT::v4i32, {2, 2, 2, 2} }, // movmskps + cmp
6563 { ISD::OR, MVT::v8i16, {2, 2, 2, 2} }, // pmovmskb + cmp
6564 { ISD::OR, MVT::v16i8, {2, 2, 2, 2} }, // pmovmskb + cmp
6565 };
6566
6567 // Handle bool allof/anyof vXi1 patterns before we check legal types.
6568 if (ValVTy->getElementType()->isIntegerTy(1)) {
6569 if (ISD == ISD::ADD) {
6570 // vXi1 addition reduction will bitcast to scalar and perform a popcount.
6571 auto *IntTy = IntegerType::getIntNTy(ValVTy->getContext(),
6572 ValVTy->getNumElements());
6573 IntrinsicCostAttributes ICA(Intrinsic::ctpop, IntTy, {IntTy});
6574 return getCastInstrCost(Instruction::BitCast, IntTy, ValVTy,
6576 CostKind) +
6578 }
6579
6580 if (ST->hasAVX512())
6581 if (const auto *Entry = CostTableLookup(AVX512BoolReduction, ISD, MTy))
6582 if (auto KindCost = Entry->Cost[CostKind])
6583 return ArithmeticCost + *KindCost;
6584 if (ST->hasAVX2())
6585 if (const auto *Entry = CostTableLookup(AVX2BoolReduction, ISD, MTy))
6586 if (auto KindCost = Entry->Cost[CostKind])
6587 return ArithmeticCost + *KindCost;
6588 if (ST->hasAVX())
6589 if (const auto *Entry = CostTableLookup(AVX1BoolReduction, ISD, MTy))
6590 if (auto KindCost = Entry->Cost[CostKind])
6591 return ArithmeticCost + *KindCost;
6592 if (ST->hasSSE2())
6593 if (const auto *Entry = CostTableLookup(SSE2BoolReduction, ISD, MTy))
6594 if (auto KindCost = Entry->Cost[CostKind])
6595 return ArithmeticCost + *KindCost;
6596
6597 return BaseT::getArithmeticReductionCost(Opcode, ValVTy, FMF, CostKind);
6598 }
6599
6600 // Special case: vXi8 mul reductions are performed as vXi16.
6601 if (ISD == ISD::MUL && MTy.getScalarType() == MVT::i8) {
6602 auto *WideSclTy = IntegerType::get(ValVTy->getContext(), 16);
6603 auto *WideVecTy = FixedVectorType::get(WideSclTy, ValVTy->getNumElements());
6604 return getCastInstrCost(Instruction::ZExt, WideVecTy, ValTy,
6606 CostKind) +
6607 getArithmeticReductionCost(Opcode, WideVecTy, FMF, CostKind);
6608 }
6609
6610 if (ST->useSLMArithCosts())
6611 if (const auto *Entry = CostTableLookup(SLMCostTbl, ISD, MTy))
6612 if (auto KindCost = Entry->Cost[CostKind])
6613 return ArithmeticCost + *KindCost;
6614
6615 if (ST->hasBWI())
6616 if (const auto *Entry = CostTableLookup(AVX512BWCostTbl, ISD, MTy))
6617 if (auto KindCost = Entry->Cost[CostKind])
6618 return ArithmeticCost + *KindCost;
6619
6620 if (ST->hasAVX512())
6621 if (const auto *Entry = CostTableLookup(AVX512FCostTbl, ISD, MTy))
6622 if (auto KindCost = Entry->Cost[CostKind])
6623 return ArithmeticCost + *KindCost;
6624
6625 if (ST->hasAVX2())
6626 if (const auto *Entry = CostTableLookup(AVX2CostTbl, ISD, MTy))
6627 if (auto KindCost = Entry->Cost[CostKind])
6628 return ArithmeticCost + *KindCost;
6629
6630 if (ST->hasAVX())
6631 if (const auto *Entry = CostTableLookup(AVX1CostTbl, ISD, MTy))
6632 if (auto KindCost = Entry->Cost[CostKind])
6633 return ArithmeticCost + *KindCost;
6634
6635 if (ST->hasSSE2())
6636 if (const auto *Entry = CostTableLookup(SSE2CostTbl, ISD, MTy))
6637 if (auto KindCost = Entry->Cost[CostKind])
6638 return ArithmeticCost + *KindCost;
6639
6640 unsigned NumVecElts = ValVTy->getNumElements();
6641 unsigned ScalarSize = ValVTy->getScalarSizeInBits();
6642
6643 // Special case power of 2 reductions where the scalar type isn't changed
6644 // by type legalization.
6645 if (!isPowerOf2_32(NumVecElts) || ScalarSize != MTy.getScalarSizeInBits())
6646 return BaseT::getArithmeticReductionCost(Opcode, ValVTy, FMF, CostKind);
6647
6648 InstructionCost ReductionCost = 0;
6649
6650 auto *Ty = ValVTy;
6651 if (LT.first != 1 && MTy.isVector() &&
6652 MTy.getVectorNumElements() < ValVTy->getNumElements()) {
6653 // Type needs to be split. We need LT.first - 1 arithmetic ops.
6654 Ty = FixedVectorType::get(ValVTy->getElementType(),
6655 MTy.getVectorNumElements());
6656 ReductionCost = getArithmeticInstrCost(Opcode, Ty, CostKind);
6657 ReductionCost *= LT.first - 1;
6658 NumVecElts = MTy.getVectorNumElements();
6659 }
6660
6661 // Now handle reduction with the legal type, taking into account size changes
6662 // at each level.
6663 while (NumVecElts > 1) {
6664 // Determine the size of the remaining vector we need to reduce.
6665 unsigned Size = NumVecElts * ScalarSize;
6666 NumVecElts /= 2;
6667 // If we're reducing from 256/512 bits, use an extract_subvector.
6668 if (Size > 128) {
6669 auto *SubTy = FixedVectorType::get(ValVTy->getElementType(), NumVecElts);
6670 ReductionCost += getShuffleCost(TTI::SK_ExtractSubvector, Ty, Ty,
6671 CostKind, {}, NumVecElts, SubTy);
6672 Ty = SubTy;
6673 } else if (Size == 128) {
6674 // Reducing from 128 bits is a permute of v2f64/v2i64.
6675 FixedVectorType *ShufTy;
6676 if (ValVTy->isFloatingPointTy())
6677 ShufTy =
6678 FixedVectorType::get(Type::getDoubleTy(ValVTy->getContext()), 2);
6679 else
6680 ShufTy =
6681 FixedVectorType::get(Type::getInt64Ty(ValVTy->getContext()), 2);
6682 ReductionCost += getShuffleCost(TTI::SK_PermuteSingleSrc, ShufTy, ShufTy,
6683 CostKind, {}, 0, nullptr);
6684 } else if (Size == 64) {
6685 // Reducing from 64 bits is a shuffle of v4f32/v4i32.
6686 FixedVectorType *ShufTy;
6687 if (ValVTy->isFloatingPointTy())
6688 ShufTy =
6689 FixedVectorType::get(Type::getFloatTy(ValVTy->getContext()), 4);
6690 else
6691 ShufTy =
6692 FixedVectorType::get(Type::getInt32Ty(ValVTy->getContext()), 4);
6693 ReductionCost += getShuffleCost(TTI::SK_PermuteSingleSrc, ShufTy, ShufTy,
6694 CostKind, {}, 0, nullptr);
6695 } else {
6696 // Reducing from smaller size is a shift by immediate.
6697 auto *ShiftTy = FixedVectorType::get(
6698 Type::getIntNTy(ValVTy->getContext(), Size), 128 / Size);
6699 ReductionCost += getArithmeticInstrCost(
6700 Instruction::LShr, ShiftTy, CostKind,
6703 }
6704
6705 // Add the arithmetic op for this level.
6706 ReductionCost += getArithmeticInstrCost(Opcode, Ty, CostKind);
6707 }
6708
6709 // Add the final extract element to the cost.
6710 return ReductionCost + getVectorInstrCost(Instruction::ExtractElement, Ty,
6711 CostKind, 0, nullptr, nullptr,
6713}
6714
6717 FastMathFlags FMF) const {
6718 IntrinsicCostAttributes ICA(IID, Ty, {Ty, Ty}, FMF);
6719 return getIntrinsicInstrCost(ICA, CostKind);
6720}
6721
6724 FastMathFlags FMF,
6726 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(ValTy);
6727
6728 MVT MTy = LT.second;
6729
6731 if (ValTy->isIntOrIntVectorTy()) {
6732 ISD = (IID == Intrinsic::umin || IID == Intrinsic::umax) ? ISD::UMIN
6733 : ISD::SMIN;
6734 } else {
6735 assert(ValTy->isFPOrFPVectorTy() &&
6736 "Expected float point or integer vector type.");
6737 ISD = (IID == Intrinsic::minnum || IID == Intrinsic::maxnum)
6738 ? ISD::FMINNUM
6739 : ISD::FMINIMUM;
6740 }
6741
6742 // We use llvm-mca across all supported CPUs to measure the cost stats.
6743 static const CostKindTblEntry SSE2CostTbl[] = {
6744 {ISD::SMIN, MVT::v2i64, {3, 4, 5, 6}},
6745 {ISD::UMIN, MVT::v2i64, {3, 4, 5, 6}},
6746 {ISD::SMIN, MVT::v2i32, {2, 2, 5, 6}},
6747 {ISD::UMIN, MVT::v2i32, {2, 2, 5, 6}},
6748 {ISD::SMIN, MVT::v4i32, {3, 7,11,12}},
6749 {ISD::UMIN, MVT::v4i32, {4, 7,14,15}},
6750 {ISD::SMIN, MVT::v2i16, {2, 3, 4, 4}},
6751 {ISD::UMIN, MVT::v2i16, {2, 3, 4, 6}},
6752 {ISD::SMIN, MVT::v4i16, {3, 5, 6, 6}},
6753 {ISD::UMIN, MVT::v4i16, {3, 5, 8, 10}},
6754 {ISD::SMIN, MVT::v8i16, {3, 8, 8, 8}},
6755 {ISD::UMIN, MVT::v8i16, {4, 8,12,14}},
6756 {ISD::SMIN, MVT::v2i8, {2, 3, 5, 6}},
6757 {ISD::UMIN, MVT::v2i8, {2, 3, 4, 4}},
6758 {ISD::SMIN, MVT::v4i8, {4, 6,12,13}},
6759 {ISD::UMIN, MVT::v4i8, {3, 6, 7, 7}},
6760 {ISD::SMIN, MVT::v8i8, {5, 9,18,19}},
6761 {ISD::UMIN, MVT::v8i8, {4, 8, 9, 9}},
6762 {ISD::SMIN, MVT::v16i8, {7,13,24,25}},
6763 {ISD::UMIN, MVT::v16i8, {3,10,11,11}},
6764 };
6765
6766 static const CostKindTblEntry SSE41CostTbl[] = {
6767 {ISD::SMIN, MVT::v2i64, {3, 4, 4, 6}},
6768 {ISD::UMIN, MVT::v2i64, {3, 4, 4, 6}},
6769 {ISD::SMIN, MVT::v2i32, {2, 2, 3, 3}},
6770 {ISD::UMIN, MVT::v2i32, {2, 2, 3, 3}},
6771 {ISD::SMIN, MVT::v4i32, {3, 4, 5, 5}},
6772 {ISD::UMIN, MVT::v4i32, {3, 4, 5, 5}},
6773 {ISD::UMIN, MVT::v2i16, {2, 3, 4, 4}},
6774 {ISD::SMIN, MVT::v4i16, {3, 5, 6, 6}},
6775 {ISD::UMIN, MVT::v4i16, {3, 5, 6, 6}},
6776 {ISD::SMIN, MVT::v8i16, {2, 8, 4, 5}},
6777 {ISD::UMIN, MVT::v8i16, {2, 5, 2, 2}},
6778 {ISD::SMIN, MVT::v2i8, {2, 3, 4, 4}},
6779 {ISD::SMIN, MVT::v4i8, {3, 6, 7, 7}},
6780 {ISD::SMIN, MVT::v8i8, {4, 8, 9, 9}},
6781 {ISD::SMIN, MVT::v16i8, {3,10, 7, 8}},
6782 {ISD::UMIN, MVT::v16i8, {3, 8, 5, 5}},
6783 };
6784
6785 static const CostKindTblEntry AVX1CostTbl[] = {
6786 {ISD::SMIN, MVT::v4i64, {5,11, 7,10}},
6787 {ISD::UMIN, MVT::v4i64, {6,12,10,13}},
6788 {ISD::SMIN, MVT::v8i32, {4, 9, 7, 7}},
6789 {ISD::UMIN, MVT::v8i32, {4, 9, 7, 7}},
6790 {ISD::SMIN, MVT::v16i16, {3,15, 6, 7}},
6791 {ISD::UMIN, MVT::v16i16, {2, 9, 4, 4}},
6792 {ISD::SMIN, MVT::v32i8, {4,17, 8, 9}},
6793 {ISD::UMIN, MVT::v32i8, {3,11, 6, 6}},
6794 };
6795
6796 static const CostKindTblEntry AVX2CostTbl[] = {
6797 {ISD::SMIN, MVT::v4i64, {4,11, 7,10}},
6798 {ISD::UMIN, MVT::v4i64, {4,12,10,13}},
6799 {ISD::SMIN, MVT::v2i32, {1, 2, 3, 3}},
6800 {ISD::UMIN, MVT::v2i32, {1, 2, 3, 3}},
6801 {ISD::UMIN, MVT::v4i32, {2, 4, 5, 5}},
6802 {ISD::SMIN, MVT::v4i32, {2, 4, 5, 5}},
6803 {ISD::SMIN, MVT::v8i32, {3, 9, 7, 7}},
6804 {ISD::UMIN, MVT::v8i32, {3, 9, 7, 7}},
6805 {ISD::SMIN, MVT::v4i16, {2, 4, 5, 5}},
6806 {ISD::UMIN, MVT::v4i16, {2, 4, 5, 5}},
6807 {ISD::SMIN, MVT::v16i16, {2,15, 6, 7}},
6808 {ISD::SMIN, MVT::v8i8, {3, 6, 7, 7}},
6809 {ISD::UMIN, MVT::v8i8, {3, 6, 7, 7}},
6810 {ISD::SMIN, MVT::v32i8, {3,17, 8, 9}},
6811 };
6812
6813 static const CostKindTblEntry AVX512FCostTbl[] = {
6814 {ISD::SMIN, MVT::v2i64, {2, 4, 3, 3}},
6815 {ISD::UMIN, MVT::v2i64, {2, 4, 3, 3}},
6816 {ISD::SMIN, MVT::v4i64, {3,10, 5, 5}},
6817 {ISD::UMIN, MVT::v4i64, {3,10, 5, 5}},
6818 {ISD::SMIN, MVT::v8i64, {5,16, 7, 7}},
6819 {ISD::UMIN, MVT::v8i64, {5,16, 7, 7}},
6820 {ISD::SMIN, MVT::v16i32, {4,12, 9, 9}},
6821 {ISD::UMIN, MVT::v16i32, {4,12, 9, 9}},
6822 };
6823
6824 static const CostKindTblEntry AVX512BWCostTbl[] = {
6825 {ISD::SMIN, MVT::v2i16, {1, 2, 3, 3}},
6826 {ISD::UMIN, MVT::v2i16, {1, 2, 3, 3}},
6827 {ISD::SMIN, MVT::v32i16, {2,19, 8, 9}},
6828 {ISD::UMIN, MVT::v32i16, {2,12, 6, 6}},
6829 {ISD::SMIN, MVT::v2i8, {1, 2, 3, 3}},
6830 {ISD::UMIN, MVT::v2i8, {1, 2, 3, 3}},
6831 {ISD::SMIN, MVT::v4i8, {2, 4, 5, 5}},
6832 {ISD::UMIN, MVT::v4i8, {2, 4, 5, 5}},
6833 {ISD::SMIN, MVT::v16i8, {2,10, 6, 7}},
6834 {ISD::UMIN, MVT::v16i8, {2, 6, 4, 4}},
6835 {ISD::SMIN, MVT::v32i8, {2,17, 8, 9}},
6836 {ISD::UMIN, MVT::v32i8, {2,10, 6, 6}},
6837 {ISD::SMIN, MVT::v64i8, {2,21,10,11}},
6838 {ISD::UMIN, MVT::v64i8, {2,14, 8, 8}},
6839 };
6840
6841 // Before legalizing the type, give a chance to look up illegal narrow types
6842 // in the table.
6843 // FIXME: Is there a better way to do this?
6844 EVT VT = TLI->getValueType(DL, ValTy);
6845 if (VT.isSimple()) {
6846 MVT MTy = VT.getSimpleVT();
6847 if (ST->hasBWI())
6848 if (const auto *Entry = CostTableLookup(AVX512BWCostTbl, ISD, MTy))
6849 if (auto KindCost = Entry->Cost[CostKind])
6850 return *KindCost;
6851
6852 if (ST->hasAVX512())
6853 if (const auto *Entry = CostTableLookup(AVX512FCostTbl, ISD, MTy))
6854 if (auto KindCost = Entry->Cost[CostKind])
6855 return *KindCost;
6856
6857 if (ST->hasAVX2())
6858 if (const auto *Entry = CostTableLookup(AVX2CostTbl, ISD, MTy))
6859 if (auto KindCost = Entry->Cost[CostKind])
6860 return *KindCost;
6861
6862 if (ST->hasAVX())
6863 if (const auto *Entry = CostTableLookup(AVX1CostTbl, ISD, MTy))
6864 if (auto KindCost = Entry->Cost[CostKind])
6865 return *KindCost;
6866
6867 if (ST->hasSSE41())
6868 if (const auto *Entry = CostTableLookup(SSE41CostTbl, ISD, MTy))
6869 if (auto KindCost = Entry->Cost[CostKind])
6870 return *KindCost;
6871
6872 if (ST->hasSSE2())
6873 if (const auto *Entry = CostTableLookup(SSE2CostTbl, ISD, MTy))
6874 if (auto KindCost = Entry->Cost[CostKind])
6875 return *KindCost;
6876 }
6877
6878 auto *ValVTy = cast<FixedVectorType>(ValTy);
6879 unsigned NumVecElts = ValVTy->getNumElements();
6880
6881 auto *Ty = ValVTy;
6882 InstructionCost MinMaxCost = 0;
6883 if (LT.first != 1 && MTy.isVector() &&
6884 MTy.getVectorNumElements() < ValVTy->getNumElements()) {
6885 // Type needs to be split. We need LT.first - 1 operations ops.
6886 Ty = FixedVectorType::get(ValVTy->getElementType(),
6887 MTy.getVectorNumElements());
6888 MinMaxCost = getMinMaxCost(IID, Ty, CostKind, FMF);
6889 MinMaxCost *= LT.first - 1;
6890 NumVecElts = MTy.getVectorNumElements();
6891 }
6892
6893 if (ST->hasBWI())
6894 if (const auto *Entry = CostTableLookup(AVX512BWCostTbl, ISD, MTy))
6895 if (auto KindCost = Entry->Cost[CostKind])
6896 return MinMaxCost + *KindCost;
6897
6898 if (ST->hasAVX512())
6899 if (const auto *Entry = CostTableLookup(AVX512FCostTbl, ISD, MTy))
6900 if (auto KindCost = Entry->Cost[CostKind])
6901 return MinMaxCost + *KindCost;
6902
6903 if (ST->hasAVX2())
6904 if (const auto *Entry = CostTableLookup(AVX2CostTbl, ISD, MTy))
6905 if (auto KindCost = Entry->Cost[CostKind])
6906 return MinMaxCost + *KindCost;
6907
6908 if (ST->hasAVX())
6909 if (const auto *Entry = CostTableLookup(AVX1CostTbl, ISD, MTy))
6910 if (auto KindCost = Entry->Cost[CostKind])
6911 return MinMaxCost + *KindCost;
6912
6913 if (ST->hasSSE41())
6914 if (const auto *Entry = CostTableLookup(SSE41CostTbl, ISD, MTy))
6915 if (auto KindCost = Entry->Cost[CostKind])
6916 return MinMaxCost + *KindCost;
6917
6918 if (ST->hasSSE2())
6919 if (const auto *Entry = CostTableLookup(SSE2CostTbl, ISD, MTy))
6920 if (auto KindCost = Entry->Cost[CostKind])
6921 return MinMaxCost + *KindCost;
6922
6923 unsigned ScalarSize = ValTy->getScalarSizeInBits();
6924
6925 // Special case power of 2 reductions where the scalar type isn't changed
6926 // by type legalization.
6927 if (!isPowerOf2_32(ValVTy->getNumElements()) ||
6928 ScalarSize != MTy.getScalarSizeInBits())
6929 return BaseT::getMinMaxReductionCost(IID, ValTy, FMF, CostKind);
6930
6931 // Now handle reduction with the legal type, taking into account size changes
6932 // at each level.
6933 while (NumVecElts > 1) {
6934 // Determine the size of the remaining vector we need to reduce.
6935 unsigned Size = NumVecElts * ScalarSize;
6936 NumVecElts /= 2;
6937 // If we're reducing from 256/512 bits, use an extract_subvector.
6938 if (Size > 128) {
6939 auto *SubTy = FixedVectorType::get(ValVTy->getElementType(), NumVecElts);
6940 MinMaxCost += getShuffleCost(TTI::SK_ExtractSubvector, Ty, Ty, CostKind,
6941 {}, NumVecElts, SubTy);
6942 Ty = SubTy;
6943 } else if (Size == 128) {
6944 // Reducing from 128 bits is a permute of v2f64/v2i64.
6945 VectorType *ShufTy;
6946 if (ValTy->isFloatingPointTy())
6947 ShufTy =
6949 else
6950 ShufTy = FixedVectorType::get(Type::getInt64Ty(ValTy->getContext()), 2);
6951 MinMaxCost += getShuffleCost(TTI::SK_PermuteSingleSrc, ShufTy, ShufTy,
6952 CostKind, {}, 0, nullptr);
6953 } else if (Size == 64) {
6954 // Reducing from 64 bits is a shuffle of v4f32/v4i32.
6955 FixedVectorType *ShufTy;
6956 if (ValTy->isFloatingPointTy())
6957 ShufTy = FixedVectorType::get(Type::getFloatTy(ValTy->getContext()), 4);
6958 else
6959 ShufTy = FixedVectorType::get(Type::getInt32Ty(ValTy->getContext()), 4);
6960 MinMaxCost += getShuffleCost(TTI::SK_PermuteSingleSrc, ShufTy, ShufTy,
6961 CostKind, {}, 0, nullptr);
6962 } else {
6963 // Reducing from smaller size is a shift by immediate.
6964 auto *ShiftTy = FixedVectorType::get(
6965 Type::getIntNTy(ValTy->getContext(), Size), 128 / Size);
6966 MinMaxCost += getArithmeticInstrCost(
6967 Instruction::LShr, ShiftTy, TTI::TCK_RecipThroughput,
6970 }
6971
6972 // Add the arithmetic op for this level.
6973 MinMaxCost += getMinMaxCost(IID, Ty, CostKind, FMF);
6974 }
6975
6976 // Add the final extract element to the cost.
6977 return MinMaxCost + getVectorInstrCost(Instruction::ExtractElement, Ty,
6978 CostKind, 0, nullptr, nullptr,
6980}
6981
6982/// Calculate the cost of materializing a 64-bit value. This helper
6983/// method might only calculate a fraction of a larger immediate. Therefore it
6984/// is valid to return a cost of ZERO.
6986 if (Val == 0)
6987 return TTI::TCC_Free;
6988
6989 if (isInt<32>(Val))
6990 return TTI::TCC_Basic;
6991
6992 return 2 * TTI::TCC_Basic;
6993}
6994
6997 assert(Ty->isIntegerTy());
6998
6999 unsigned BitSize = Ty->getPrimitiveSizeInBits();
7000 if (BitSize == 0)
7001 return ~0U;
7002
7003 // Never hoist constants larger than 128bit, because this might lead to
7004 // incorrect code generation or assertions in codegen.
7005 // Fixme: Create a cost model for types larger than i128 once the codegen
7006 // issues have been fixed.
7007 if (BitSize > 128)
7008 return TTI::TCC_Free;
7009
7010 if (Imm == 0)
7011 return TTI::TCC_Free;
7012
7013 // Sign-extend all constants to a multiple of 64-bit.
7014 APInt ImmVal = Imm;
7015 if (BitSize % 64 != 0)
7016 ImmVal = Imm.sext(alignTo(BitSize, 64));
7017
7018 // Split the constant into 64-bit chunks and calculate the cost for each
7019 // chunk.
7021 for (unsigned ShiftVal = 0; ShiftVal < BitSize; ShiftVal += 64) {
7022 APInt Tmp = ImmVal.ashr(ShiftVal).sextOrTrunc(64);
7023 int64_t Val = Tmp.getSExtValue();
7024 Cost += getIntImmCost(Val);
7025 }
7026 // We need at least one instruction to materialize the constant.
7027 return std::max<InstructionCost>(1, Cost);
7028}
7029
7031 const APInt &Imm, Type *Ty,
7033 Instruction *Inst) const {
7034 assert(Ty->isIntegerTy());
7035
7036 unsigned BitSize = Ty->getPrimitiveSizeInBits();
7037 unsigned ImmBitWidth = Imm.getBitWidth();
7038
7039 // There is no cost model for constants with a bit size of 0. Return TCC_Free
7040 // here, so that constant hoisting will ignore this constant.
7041 if (BitSize == 0)
7042 return TTI::TCC_Free;
7043
7044 unsigned ImmIdx = ~0U;
7045 switch (Opcode) {
7046 default:
7047 return TTI::TCC_Free;
7048 case Instruction::GetElementPtr:
7049 // Always hoist the base address of a GetElementPtr. This prevents the
7050 // creation of new constants for every base constant that gets constant
7051 // folded with the offset.
7052 if (Idx == 0)
7053 return 2 * TTI::TCC_Basic;
7054 return TTI::TCC_Free;
7055 case Instruction::Store:
7056 ImmIdx = 0;
7057 break;
7058 case Instruction::ICmp:
7059 // This is an imperfect hack to prevent constant hoisting of
7060 // compares that might be trying to check if a 64-bit value fits in
7061 // 32-bits. The backend can optimize these cases using a right shift by 32.
7062 // There are other predicates and immediates the backend can use shifts for.
7063 if (Idx == 1 && ImmBitWidth == 64) {
7064 uint64_t ImmVal = Imm.getZExtValue();
7065 if (ImmVal == 0x100000000ULL || ImmVal == 0xffffffff)
7066 return TTI::TCC_Free;
7067
7068 if (auto *Cmp = dyn_cast_or_null<CmpInst>(Inst)) {
7069 if (Cmp->isEquality()) {
7070 KnownBits Known = computeKnownBits(Cmp->getOperand(0), DL);
7071 if (Known.countMinTrailingZeros() >= 32)
7072 return TTI::TCC_Free;
7073 }
7074 }
7075 }
7076 ImmIdx = 1;
7077 break;
7078 case Instruction::And:
7079 // We support 64-bit ANDs with immediates with 32-bits of leading zeroes
7080 // by using a 32-bit operation with implicit zero extension. Detect such
7081 // immediates here as the normal path expects bit 31 to be sign extended.
7082 if (Idx == 1 && ImmBitWidth == 64 && Imm.isIntN(32))
7083 return TTI::TCC_Free;
7084 // If we have BMI then we can use BEXTR/BZHI to mask out upper i64 bits.
7085 if (Idx == 1 && ImmBitWidth == 64 && ST->is64Bit() && ST->hasBMI() &&
7086 Imm.isMask())
7087 return X86TTIImpl::getIntImmCost(ST->hasBMI2() ? 255 : 65535);
7088 ImmIdx = 1;
7089 break;
7090 case Instruction::Add:
7091 case Instruction::Sub:
7092 // For add/sub, we can use the opposite instruction for INT32_MIN.
7093 if (Idx == 1 && ImmBitWidth == 64 && Imm.getZExtValue() == 0x80000000)
7094 return TTI::TCC_Free;
7095 ImmIdx = 1;
7096 break;
7097 case Instruction::UDiv:
7098 case Instruction::SDiv:
7099 case Instruction::URem:
7100 case Instruction::SRem:
7101 // Division by constant is typically expanded later into a different
7102 // instruction sequence. This completely changes the constants.
7103 // Report them as "free" to stop ConstantHoist from marking them as opaque.
7104 return TTI::TCC_Free;
7105 case Instruction::Mul:
7106 case Instruction::Or:
7107 case Instruction::Xor:
7108 ImmIdx = 1;
7109 break;
7110 // Always return TCC_Free for the shift value of a shift instruction.
7111 case Instruction::Shl:
7112 case Instruction::LShr:
7113 case Instruction::AShr:
7114 if (Idx == 1)
7115 return TTI::TCC_Free;
7116 break;
7117 case Instruction::Trunc:
7118 case Instruction::ZExt:
7119 case Instruction::SExt:
7120 case Instruction::IntToPtr:
7121 case Instruction::PtrToInt:
7122 case Instruction::BitCast:
7123 case Instruction::PHI:
7124 case Instruction::Call:
7125 case Instruction::Select:
7126 case Instruction::Ret:
7127 case Instruction::Load:
7128 break;
7129 }
7130
7131 if (Idx == ImmIdx) {
7132 uint64_t NumConstants = divideCeil(BitSize, 64);
7134 return (Cost <= NumConstants * TTI::TCC_Basic)
7135 ? static_cast<int>(TTI::TCC_Free)
7136 : Cost;
7137 }
7138
7140}
7141
7144 const APInt &Imm, Type *Ty,
7146 assert(Ty->isIntegerTy());
7147
7148 unsigned BitSize = Ty->getPrimitiveSizeInBits();
7149 // There is no cost model for constants with a bit size of 0. Return TCC_Free
7150 // here, so that constant hoisting will ignore this constant.
7151 if (BitSize == 0)
7152 return TTI::TCC_Free;
7153
7154 switch (IID) {
7155 default:
7156 return TTI::TCC_Free;
7157 case Intrinsic::sadd_with_overflow:
7158 case Intrinsic::uadd_with_overflow:
7159 case Intrinsic::ssub_with_overflow:
7160 case Intrinsic::usub_with_overflow:
7161 case Intrinsic::smul_with_overflow:
7162 case Intrinsic::umul_with_overflow:
7163 if ((Idx == 1) && Imm.getBitWidth() <= 64 && Imm.isSignedIntN(32))
7164 return TTI::TCC_Free;
7165 break;
7166 case Intrinsic::experimental_stackmap:
7167 if ((Idx < 2) || (Imm.getBitWidth() <= 64 && Imm.isSignedIntN(64)))
7168 return TTI::TCC_Free;
7169 break;
7170 case Intrinsic::experimental_patchpoint_void:
7171 case Intrinsic::experimental_patchpoint:
7172 if ((Idx < 4) || (Imm.getBitWidth() <= 64 && Imm.isSignedIntN(64)))
7173 return TTI::TCC_Free;
7174 break;
7175 }
7177}
7178
7181 const Instruction *I) const {
7183 return Opcode == Instruction::PHI ? TTI::TCC_Free : TTI::TCC_Basic;
7184 // Branches are assumed to be predicted.
7185 return TTI::TCC_Free;
7186}
7187
7188int X86TTIImpl::getGatherOverhead() const {
7189 // Some CPUs have more overhead for gather. The specified overhead is relative
7190 // to the Load operation. "2" is the number provided by Intel architects. This
7191 // parameter is used for cost estimation of Gather Op and comparison with
7192 // other alternatives.
7193 // TODO: Remove the explicit hasAVX512()?, That would mean we would only
7194 // enable gather with a -march.
7195 if (ST->hasAVX512() || (ST->hasAVX2() && ST->hasFastGather()))
7196 return 2;
7197
7198 return 1024;
7199}
7200
7201int X86TTIImpl::getScatterOverhead() const {
7202 if (ST->hasAVX512())
7203 return 2;
7204
7205 return 1024;
7206}
7207
7208// Return an average cost of Gather / Scatter instruction, maybe improved later.
7209InstructionCost X86TTIImpl::getGSVectorCost(unsigned Opcode,
7211 Type *SrcVTy, const Value *Ptr,
7212 Align Alignment,
7213 unsigned AddressSpace) const {
7214
7215 assert(isa<VectorType>(SrcVTy) && "Unexpected type in getGSVectorCost");
7216 unsigned VF = cast<FixedVectorType>(SrcVTy)->getNumElements();
7217
7218 // Try to reduce index size from 64 bit (default for GEP)
7219 // to 32. It is essential for VF 16. If the index can't be reduced to 32, the
7220 // operation will use 16 x 64 indices which do not fit in a zmm and needs
7221 // to split. Also check that the base pointer is the same for all lanes,
7222 // and that there's at most one variable index.
7223 auto getIndexSizeInBits = [](const Value *Ptr, const DataLayout &DL) {
7224 unsigned IndexSize = DL.getPointerSizeInBits();
7225 const GetElementPtrInst *GEP = dyn_cast_or_null<GetElementPtrInst>(Ptr);
7226 if (IndexSize < 64 || !GEP)
7227 return IndexSize;
7228
7229 unsigned NumOfVarIndices = 0;
7230 const Value *Ptrs = GEP->getPointerOperand();
7231 if (Ptrs->getType()->isVectorTy() && !getSplatValue(Ptrs))
7232 return IndexSize;
7233 for (unsigned I = 1, E = GEP->getNumOperands(); I != E; ++I) {
7234 if (isa<Constant>(GEP->getOperand(I)))
7235 continue;
7236 Type *IndxTy = GEP->getOperand(I)->getType();
7237 if (auto *IndexVTy = dyn_cast<VectorType>(IndxTy))
7238 IndxTy = IndexVTy->getElementType();
7239 if ((IndxTy->getPrimitiveSizeInBits() == 64 &&
7240 !isa<SExtInst>(GEP->getOperand(I))) ||
7241 ++NumOfVarIndices > 1)
7242 return IndexSize; // 64
7243 }
7244 return (unsigned)32;
7245 };
7246
7247 // Trying to reduce IndexSize to 32 bits for vector 16.
7248 // By default the IndexSize is equal to pointer size.
7249 unsigned IndexSize = (ST->hasAVX512() && VF >= 16)
7250 ? getIndexSizeInBits(Ptr, DL)
7251 : DL.getPointerSizeInBits();
7252
7253 auto *IndexVTy = FixedVectorType::get(
7254 IntegerType::get(SrcVTy->getContext(), IndexSize), VF);
7255 std::pair<InstructionCost, MVT> IdxsLT = getTypeLegalizationCost(IndexVTy);
7256 std::pair<InstructionCost, MVT> SrcLT = getTypeLegalizationCost(SrcVTy);
7257 InstructionCost::CostType SplitFactor =
7258 std::max(IdxsLT.first, SrcLT.first).getValue();
7259 if (SplitFactor > 1) {
7260 // Handle splitting of vector of pointers
7261 auto *SplitSrcTy =
7262 FixedVectorType::get(SrcVTy->getScalarType(), VF / SplitFactor);
7263 return SplitFactor * getGSVectorCost(Opcode, CostKind, SplitSrcTy, Ptr,
7264 Alignment, AddressSpace);
7265 }
7266
7267 // If we didn't split, this will be a single gather/scatter instruction.
7269 return 1;
7270
7271 // The gather / scatter cost is given by Intel architects. It is a rough
7272 // number since we are looking at one instruction in a time.
7273 const int GSOverhead = (Opcode == Instruction::Load) ? getGatherOverhead()
7274 : getScatterOverhead();
7275 return GSOverhead + VF * getMemoryOpCost(Opcode, SrcVTy->getScalarType(),
7276 Alignment, AddressSpace, CostKind);
7277}
7278
7279/// Calculate the cost of Gather / Scatter operation
7283 bool IsLoad = MICA.getID() == Intrinsic::masked_gather ||
7284 MICA.getID() == Intrinsic::vp_gather;
7285 unsigned Opcode = IsLoad ? Instruction::Load : Instruction::Store;
7286 Type *SrcVTy = MICA.getDataType();
7287 const Value *Ptr = MICA.getPointer();
7288 Align Alignment = MICA.getAlignment();
7289 if ((Opcode == Instruction::Load &&
7290 (!isLegalMaskedGather(SrcVTy, Align(Alignment)) ||
7292 Align(Alignment)))) ||
7293 (Opcode == Instruction::Store &&
7294 (!isLegalMaskedScatter(SrcVTy, Align(Alignment)) ||
7296 Align(Alignment)))))
7298
7299 assert(SrcVTy->isVectorTy() && "Unexpected data type for Gather/Scatter");
7300 unsigned AddressSpace = MICA.getAddressSpace();
7302 getGSVectorCost(Opcode, CostKind, SrcVTy, Ptr, Alignment, AddressSpace);
7303
7304 // Predicate fanout (see getPredicateFanoutCost); variable mask only.
7305 if (MICA.getVariableMask()) {
7306 auto *MaskVecTy =
7308 cast<FixedVectorType>(SrcVTy)->getNumElements());
7309 Cost += getPredicateFanoutCost(*this, SrcVTy, MaskVecTy);
7310 }
7311 return Cost;
7312}
7313
7315 const TargetTransformInfo::LSRCost &C2) const {
7316 // X86 specific here are "instruction number 1st priority".
7317 return std::tie(C1.Insns, C1.NumRegs, C1.AddRecCost, C1.NumIVMuls,
7318 C1.NumBaseAdds, C1.ScaleCost, C1.ImmCost, C1.SetupCost) <
7319 std::tie(C2.Insns, C2.NumRegs, C2.AddRecCost, C2.NumIVMuls,
7320 C2.NumBaseAdds, C2.ScaleCost, C2.ImmCost, C2.SetupCost);
7321}
7322
7324 return ST->hasMacroFusion() || ST->hasBranchFusion();
7325}
7326
7327static bool isLegalMaskedLoadStore(Type *ScalarTy, const X86Subtarget *ST) {
7328 if (!ST->hasAVX())
7329 return false;
7330
7331 if (ScalarTy->isPointerTy())
7332 return true;
7333
7334 if (ScalarTy->isFloatTy() || ScalarTy->isDoubleTy())
7335 return true;
7336
7337 if (ScalarTy->isHalfTy() && ST->hasBWI())
7338 return true;
7339
7340 if (ScalarTy->isBFloatTy() && ST->hasBF16())
7341 return true;
7342
7343 if (!ScalarTy->isIntegerTy())
7344 return false;
7345
7346 unsigned IntWidth = ScalarTy->getIntegerBitWidth();
7347 return IntWidth == 32 || IntWidth == 64 ||
7348 ((IntWidth == 8 || IntWidth == 16) && ST->hasBWI());
7349}
7350
7352 unsigned AddressSpace,
7353 TTI::MaskKind MaskKind) const {
7354 Type *ScalarTy = DataTy->getScalarType();
7355
7356 // The backend can't handle a single element vector w/o CFCMOV.
7357 if (isa<VectorType>(DataTy) &&
7358 cast<FixedVectorType>(DataTy)->getNumElements() == 1)
7359 return ST->hasCF() &&
7360 hasConditionalLoadStoreForType(ScalarTy, /*IsStore=*/false);
7361
7362 return isLegalMaskedLoadStore(ScalarTy, ST);
7363}
7364
7366 unsigned AddressSpace,
7367 TTI::MaskKind MaskKind) const {
7368 Type *ScalarTy = DataTy->getScalarType();
7369
7370 // The backend can't handle a single element vector w/o CFCMOV.
7371 if (isa<VectorType>(DataTy) &&
7372 cast<FixedVectorType>(DataTy)->getNumElements() == 1)
7373 return ST->hasCF() &&
7374 hasConditionalLoadStoreForType(ScalarTy, /*IsStore=*/true);
7375
7376 return isLegalMaskedLoadStore(ScalarTy, ST);
7377}
7378
7379bool X86TTIImpl::isLegalNTLoad(Type *DataType, Align Alignment) const {
7380 unsigned DataSize = DL.getTypeStoreSize(DataType);
7381 // The only supported nontemporal loads are for aligned vectors of 16 or 32
7382 // bytes. Note that 32-byte nontemporal vector loads are supported by AVX2
7383 // (the equivalent stores only require AVX).
7384 if (Alignment >= DataSize && (DataSize == 16 || DataSize == 32))
7385 return DataSize == 16 ? ST->hasSSE1() : ST->hasAVX2();
7386
7387 return false;
7388}
7389
7390bool X86TTIImpl::isLegalNTStore(Type *DataType, Align Alignment) const {
7391 unsigned DataSize = DL.getTypeStoreSize(DataType);
7392
7393 // SSE4A supports nontemporal stores of float and double at arbitrary
7394 // alignment.
7395 if (ST->hasSSE4A() && (DataType->isFloatTy() || DataType->isDoubleTy()))
7396 return true;
7397
7398 // Besides the SSE4A subtarget exception above, only aligned stores are
7399 // available nontemporaly on any other subtarget. And only stores with a size
7400 // of 4..32 bytes (powers of 2, only) are permitted.
7401 if (Alignment < DataSize || DataSize < 4 || DataSize > 32 ||
7402 !isPowerOf2_32(DataSize))
7403 return false;
7404
7405 // 32-byte vector nontemporal stores are supported by AVX (the equivalent
7406 // loads require AVX2).
7407 if (DataSize == 32)
7408 return ST->hasAVX();
7409 if (DataSize == 16)
7410 return ST->hasSSE1();
7411 return true;
7412}
7413
7415 ElementCount NumElements) const {
7416 // movddup
7417 return ST->hasSSE3() && !NumElements.isScalable() &&
7418 NumElements.getFixedValue() == 2 &&
7419 ElementTy == Type::getDoubleTy(ElementTy->getContext());
7420}
7421
7422bool X86TTIImpl::isLegalMaskedExpandLoad(Type *DataTy, Align Alignment) const {
7423 if (!isa<VectorType>(DataTy))
7424 return false;
7425
7426 if (!ST->hasAVX512())
7427 return false;
7428
7429 // The backend can't handle a single element vector.
7430 if (cast<FixedVectorType>(DataTy)->getNumElements() == 1)
7431 return false;
7432
7433 Type *ScalarTy = cast<VectorType>(DataTy)->getElementType();
7434
7435 if (ScalarTy->isFloatTy() || ScalarTy->isDoubleTy())
7436 return true;
7437
7438 if (!ScalarTy->isIntegerTy())
7439 return false;
7440
7441 unsigned IntWidth = ScalarTy->getIntegerBitWidth();
7442 return IntWidth == 32 || IntWidth == 64 ||
7443 ((IntWidth == 8 || IntWidth == 16) && ST->hasVBMI2());
7444}
7445
7447 Align Alignment) const {
7448 return isLegalMaskedExpandLoad(DataTy, Alignment);
7449}
7450
7451bool X86TTIImpl::supportsGather() const {
7452 // Some CPUs have better gather performance than others.
7453 // TODO: Remove the explicit ST->hasAVX512()?, That would mean we would only
7454 // enable gather with a -march.
7455 return ST->hasAVX512() || (ST->hasFastGather() && ST->hasAVX2());
7456}
7457
7459 Align Alignment) const {
7460 // Gather / Scatter for vector 2 is not profitable on KNL / SKX
7461 // Vector-4 of gather/scatter instruction does not exist on KNL. We can extend
7462 // it to 8 elements, but zeroing upper bits of the mask vector will add more
7463 // instructions. Right now we give the scalar cost of vector-4 for KNL. TODO:
7464 // Check, maybe the gather/scatter instruction is better in the VariableMask
7465 // case.
7466 unsigned NumElts = cast<FixedVectorType>(VTy)->getNumElements();
7467 return NumElts == 1 ||
7468 (ST->hasAVX512() && (NumElts == 2 || (NumElts == 4 && !ST->hasVLX())));
7469}
7470
7472 Align Alignment) const {
7473 Type *ScalarTy = DataTy->getScalarType();
7474 if (ScalarTy->isPointerTy())
7475 return true;
7476
7477 if (ScalarTy->isFloatTy() || ScalarTy->isDoubleTy())
7478 return true;
7479
7480 if (!ScalarTy->isIntegerTy())
7481 return false;
7482
7483 unsigned IntWidth = ScalarTy->getIntegerBitWidth();
7484 return IntWidth == 32 || IntWidth == 64;
7485}
7486
7487bool X86TTIImpl::isLegalMaskedGather(Type *DataTy, Align Alignment) const {
7488 if (!supportsGather() || !ST->preferGather())
7489 return false;
7490 return isLegalMaskedGatherScatter(DataTy, Alignment);
7491}
7492
7493bool X86TTIImpl::isLegalAltInstr(VectorType *VecTy, unsigned Opcode0,
7494 unsigned Opcode1,
7495 const SmallBitVector &OpcodeMask,
7496 ArrayRef<const Value *> Scalars) const {
7497 // ADDSUBPS 4xf32 SSE3
7498 // VADDSUBPS 4xf32 AVX
7499 // VADDSUBPS 8xf32 AVX2
7500 // ADDSUBPD 2xf64 SSE3
7501 // VADDSUBPD 2xf64 AVX
7502 // VADDSUBPD 4xf64 AVX2
7503
7504 unsigned NumElements = cast<FixedVectorType>(VecTy)->getNumElements();
7505 assert(OpcodeMask.size() == NumElements && "Mask and VecTy are incompatible");
7506 if (!isPowerOf2_32(NumElements))
7507 return false;
7508 // Check the opcode pattern. We apply the mask on the opcode arguments and
7509 // then check if it is what we expect.
7510 auto IsLaneOrder = [&](unsigned EvenOpc, unsigned OddOpc) {
7511 return all_of(seq<unsigned>(0, NumElements), [&](unsigned Lane) {
7512 return (OpcodeMask.test(Lane) ? Opcode1 : Opcode0) ==
7513 (Lane % 2 == 0 ? EvenOpc : OddOpc);
7514 });
7515 };
7516 // We expect FSub for even lanes and FAdd for odd lanes.
7517 const bool IsAddSub = IsLaneOrder(Instruction::FSub, Instruction::FAdd);
7518 // Now check that the pattern is supported by the target ISA.
7519 Type *ElemTy = cast<VectorType>(VecTy)->getElementType();
7520 if (IsAddSub && ST->hasSSE3() &&
7521 ((ElemTy->isFloatTy() && NumElements % 4 == 0) ||
7522 (ElemTy->isDoubleTy() && NumElements % 2 == 0)))
7523 return true;
7524 // The multiplication is fused into every lane: fmaddsub (the even lanes
7525 // subtract and the odd lanes add the product) or fmsubadd (the other way
7526 // round). The subtracted product is the first operand of the subtraction.
7527 using namespace PatternMatch;
7528 auto IsFusedWithFMul = [](const Value *V) {
7529 const auto *I = dyn_cast<Instruction>(V);
7530 if (!I || !I->hasAllowContract())
7531 return false;
7532 auto IsFMul = [&](const Value *Op) {
7533 return match(Op,
7535 cast<Instruction>(Op)->getParent() == I->getParent();
7536 };
7537 return IsFMul(I->getOperand(0)) ||
7538 (I->getOpcode() == Instruction::FAdd && IsFMul(I->getOperand(1)));
7539 };
7540 return ST->hasFMA() && !Scalars.empty() &&
7541 (ElemTy->isFloatTy() || ElemTy->isDoubleTy()) &&
7542 (IsAddSub || IsLaneOrder(Instruction::FAdd, Instruction::FSub)) &&
7543 all_of(Scalars, IsFusedWithFMul);
7544}
7545
7546bool X86TTIImpl::isLegalMaskedScatter(Type *DataType, Align Alignment) const {
7547 // AVX2 doesn't support scatter
7548 if (!ST->hasAVX512() || !ST->preferScatter())
7549 return false;
7550 return isLegalMaskedGatherScatter(DataType, Alignment);
7551}
7552
7553bool X86TTIImpl::hasDivRemOp(Type *DataType, bool IsSigned) const {
7554 EVT VT = TLI->getValueType(DL, DataType);
7555 return TLI->isOperationLegal(IsSigned ? ISD::SDIVREM : ISD::UDIVREM, VT);
7556}
7557
7559 // FDIV is always expensive, even if it has a very low uop count.
7560 // TODO: Still necessary for recent CPUs with low latency/throughput fdiv?
7561 if (I->getOpcode() == Instruction::FDiv)
7562 return true;
7563
7565}
7566
7567bool X86TTIImpl::isFCmpOrdCheaperThanFCmpZero(Type *Ty) const { return false; }
7568
7570 const Function *Callee) const {
7571 const TargetMachine &TM = getTLI()->getTargetMachine();
7572
7573 // Work this as a subsetting of subtarget features.
7574 const X86Subtarget &CallerSubtarget = TM.getSubtarget<X86Subtarget>(*Caller);
7575 const X86Subtarget &CalleeSubtarget = TM.getSubtarget<X86Subtarget>(*Callee);
7576 const FeatureBitset &CallerBits = CallerSubtarget.getFeatureBits();
7577 const FeatureBitset &CalleeBits = CalleeSubtarget.getFeatureBits();
7578
7579 // Check whether callee features are a subset of caller features
7580 // (apart from the ignore list).
7581 const FeatureBitset &InlineIgnoreFeatures =
7582 CallerSubtarget.getInlineIgnoreFeatures();
7583 FeatureBitset RealCallerBits = CallerBits & ~InlineIgnoreFeatures;
7584 FeatureBitset RealCalleeBits = CalleeBits & ~InlineIgnoreFeatures;
7585 if ((RealCallerBits & RealCalleeBits) != RealCalleeBits)
7586 return false;
7587
7588 // If the features are not exactly the same (or there is a difference in
7589 // AVX512 register usage), we need to additionally check for calls
7590 // that may become ABI-incompatible as a result of inlining.
7591 if (RealCallerBits == RealCalleeBits &&
7592 CallerSubtarget.useAVX512Regs() == CalleeSubtarget.useAVX512Regs())
7593 return true;
7594
7595 for (const Instruction &I : instructions(Callee)) {
7596 if (const auto *CB = dyn_cast<CallBase>(&I)) {
7597 // Having more target features is fine for inline ASM and intrinsics.
7598 if (CB->isInlineAsm() || CB->getIntrinsicID() != Intrinsic::not_intrinsic)
7599 continue;
7600
7602 for (Value *Arg : CB->args())
7603 Types.push_back(Arg->getType());
7604 if (!CB->getType()->isVoidTy())
7605 Types.push_back(CB->getType());
7606
7607 // Simple types are always ABI compatible.
7608 auto IsSimpleTy = [](Type *Ty) {
7609 return !Ty->isVectorTy() && !Ty->isAggregateType();
7610 };
7611 if (all_of(Types, IsSimpleTy))
7612 continue;
7613
7614 // Do a precise compatibility check.
7615 if (!areTypesABICompatible(Caller, Callee, Types))
7616 return false;
7617 }
7618 }
7619 return true;
7620}
7621
7623 const Function *Callee,
7624 ArrayRef<Type *> Types) const {
7625 const TargetMachine &TM = getTLI()->getTargetMachine();
7626 const TargetLowering *CallerTLI =
7627 TM.getSubtargetImpl(*Caller)->getTargetLowering();
7628 const TargetLowering *CalleeTLI =
7629 TM.getSubtargetImpl(*Callee)->getTargetLowering();
7630
7631 LLVMContext &Ctx = Caller->getContext();
7632 const DataLayout &DL = Caller->getDataLayout();
7633 CallingConv::ID CC = Callee->getCallingConv();
7634 return all_of(Types, [&](Type *Ty) {
7635 SmallVector<EVT> VTs;
7636 ComputeValueVTs(*CallerTLI, DL, Ty, VTs);
7637 return all_of(VTs, [&](EVT VT) {
7638 return CallerTLI->getRegisterTypeForCallingConv(Ctx, CC, VT) ==
7639 CalleeTLI->getRegisterTypeForCallingConv(Ctx, CC, VT);
7640 });
7641 });
7642}
7643
7645X86TTIImpl::enableMemCmpExpansion(bool OptSize, bool IsZeroCmp) const {
7647 Options.MaxNumLoads = TLI->getMaxExpandSizeMemcmp(OptSize);
7648 Options.NumLoadsPerBlock = IsZeroCmp ? 2 : 1;
7649 // All GPR and vector loads can be unaligned.
7650 Options.AllowOverlappingLoads = true;
7651 if (IsZeroCmp) {
7652 // Only enable vector loads for equality comparison. Right now the vector
7653 // version is not as fast for three way compare (see #33329).
7654 const unsigned PreferredWidth = ST->getPreferVectorWidth();
7655 if (PreferredWidth >= 512 && ST->hasAVX512())
7656 Options.LoadSizes.push_back(64);
7657 if (PreferredWidth >= 256 && ST->hasAVX()) Options.LoadSizes.push_back(32);
7658 if (PreferredWidth >= 128 && ST->hasSSE2()) Options.LoadSizes.push_back(16);
7659 }
7660 if (ST->is64Bit()) {
7661 Options.LoadSizes.push_back(8);
7662 }
7663 Options.LoadSizes.push_back(4);
7664 Options.LoadSizes.push_back(2);
7665 Options.LoadSizes.push_back(1);
7666 return Options;
7667}
7668
7670 return supportsGather();
7671}
7672
7674 return false;
7675}
7676
7678 // TODO: We expect this to be beneficial regardless of arch,
7679 // but there are currently some unexplained performance artifacts on Atom.
7680 // As a temporary solution, disable on Atom.
7681 return !(ST->isAtom());
7682}
7683
7685 switch (II->getIntrinsicID()) {
7686 default:
7687 return true;
7688 case Intrinsic::vector_reduce_and:
7689 case Intrinsic::vector_reduce_or:
7690 case Intrinsic::vector_reduce_xor:
7691 case Intrinsic::vector_reduce_mul:
7692 case Intrinsic::vector_reduce_smax:
7693 case Intrinsic::vector_reduce_smin:
7694 case Intrinsic::vector_reduce_umax:
7695 case Intrinsic::vector_reduce_umin:
7696 return false;
7697 }
7698}
7699
7700// Get estimation for interleaved load/store operations and strided load.
7701// \p Indices contains indices for strided load.
7702// \p Factor - the factor of interleaving.
7703// AVX-512 provides 3-src shuffles that significantly reduces the cost.
7705 unsigned Opcode, FixedVectorType *VecTy, unsigned Factor,
7706 ArrayRef<unsigned> Indices, Align Alignment, unsigned AddressSpace,
7707 TTI::TargetCostKind CostKind, bool UseMaskForCond,
7708 bool UseMaskForGaps) const {
7709 // VecTy for interleave memop is <VF*Factor x Elt>.
7710 // So, for VF=4, Interleave Factor = 3, Element type = i32 we have
7711 // VecTy = <12 x i32>.
7712
7713 // Calculate the number of memory operations (NumOfMemOps), required
7714 // for load/store the VecTy.
7715 MVT LegalVT = getTypeLegalizationCost(VecTy).second;
7716 unsigned VecTySize = DL.getTypeStoreSize(VecTy);
7717 unsigned LegalVTSize = LegalVT.getStoreSize();
7718 unsigned NumOfMemOps = (VecTySize + LegalVTSize - 1) / LegalVTSize;
7719
7720 // Get the cost of one memory operation.
7721 auto *SingleMemOpTy = FixedVectorType::get(VecTy->getElementType(),
7722 LegalVT.getVectorNumElements());
7723 InstructionCost MemOpCost;
7724 bool UseMaskedMemOp = UseMaskForCond || UseMaskForGaps;
7725 if (UseMaskedMemOp) {
7726 unsigned IID = Opcode == Instruction::Load ? Intrinsic::masked_load
7727 : Intrinsic::masked_store;
7728 MemOpCost = getMaskedMemoryOpCost(
7729 {IID, SingleMemOpTy, Alignment, AddressSpace}, CostKind);
7730 } else
7731 MemOpCost = getMemoryOpCost(Opcode, SingleMemOpTy, Alignment, AddressSpace,
7732 CostKind);
7733
7734 unsigned VF = VecTy->getNumElements() / Factor;
7735 MVT VT =
7736 MVT::getVectorVT(TLI->getSimpleValueType(DL, VecTy->getScalarType()), VF);
7737
7738 InstructionCost MaskCost;
7739 if (UseMaskedMemOp) {
7740 APInt DemandedLoadStoreElts = APInt::getZero(VecTy->getNumElements());
7741 for (unsigned Index : Indices) {
7742 assert(Index < Factor && "Invalid index for interleaved memory op");
7743 for (unsigned Elm = 0; Elm < VF; Elm++)
7744 DemandedLoadStoreElts.setBit(Index + Elm * Factor);
7745 }
7746
7747 Type *I1Type = Type::getInt1Ty(VecTy->getContext());
7748
7749 MaskCost = getReplicationShuffleCost(
7750 I1Type, Factor, VF,
7751 UseMaskForGaps ? DemandedLoadStoreElts
7753 CostKind);
7754
7755 // The Gaps mask is invariant and created outside the loop, therefore the
7756 // cost of creating it is not accounted for here. However if we have both
7757 // a MaskForGaps and some other mask that guards the execution of the
7758 // memory access, we need to account for the cost of And-ing the two masks
7759 // inside the loop.
7760 if (UseMaskForGaps) {
7761 auto *MaskVT = FixedVectorType::get(I1Type, VecTy->getNumElements());
7762 MaskCost += getArithmeticInstrCost(BinaryOperator::And, MaskVT, CostKind);
7763 }
7764 }
7765
7766 if (Opcode == Instruction::Load) {
7767 // The tables (AVX512InterleavedLoadTbl and AVX512InterleavedStoreTbl)
7768 // contain the cost of the optimized shuffle sequence that the
7769 // X86InterleavedAccess pass will generate.
7770 // The cost of loads and stores are computed separately from the table.
7771
7772 // X86InterleavedAccess support only the following interleaved-access group.
7773 static const CostTblEntry AVX512InterleavedLoadTbl[] = {
7774 {3, MVT::v16i8, 12}, //(load 48i8 and) deinterleave into 3 x 16i8
7775 {3, MVT::v32i8, 14}, //(load 96i8 and) deinterleave into 3 x 32i8
7776 {3, MVT::v64i8, 22}, //(load 96i8 and) deinterleave into 3 x 32i8
7777 };
7778
7779 if (const auto *Entry =
7780 CostTableLookup(AVX512InterleavedLoadTbl, Factor, VT))
7781 return MaskCost + NumOfMemOps * MemOpCost + Entry->Cost;
7782 //If an entry does not exist, fallback to the default implementation.
7783
7784 // Kind of shuffle depends on number of loaded values.
7785 // If we load the entire data in one register, we can use a 1-src shuffle.
7786 // Otherwise, we'll merge 2 sources in each operation.
7787 TTI::ShuffleKind ShuffleKind =
7788 (NumOfMemOps > 1) ? TTI::SK_PermuteTwoSrc : TTI::SK_PermuteSingleSrc;
7789
7790 InstructionCost ShuffleCost = getShuffleCost(
7791 ShuffleKind, SingleMemOpTy, SingleMemOpTy, CostKind, {}, 0, nullptr);
7792
7793 unsigned NumOfLoadsInInterleaveGrp =
7794 Indices.size() ? Indices.size() : Factor;
7795 auto *ResultTy = FixedVectorType::get(VecTy->getElementType(),
7796 VecTy->getNumElements() / Factor);
7797 InstructionCost NumOfResults =
7798 getTypeLegalizationCost(ResultTy).first * NumOfLoadsInInterleaveGrp;
7799
7800 // About a half of the loads may be folded in shuffles when we have only
7801 // one result. If we have more than one result, or the loads are masked,
7802 // we do not fold loads at all.
7803 unsigned NumOfUnfoldedLoads =
7804 UseMaskedMemOp || NumOfResults > 1 ? NumOfMemOps : NumOfMemOps / 2;
7805
7806 // Get a number of shuffle operations per result.
7807 unsigned NumOfShufflesPerResult =
7808 std::max((unsigned)1, (unsigned)(NumOfMemOps - 1));
7809
7810 // The SK_MergeTwoSrc shuffle clobbers one of src operands.
7811 // When we have more than one destination, we need additional instructions
7812 // to keep sources.
7813 InstructionCost NumOfMoves = 0;
7814 if (NumOfResults > 1 && ShuffleKind == TTI::SK_PermuteTwoSrc)
7815 NumOfMoves = NumOfResults * NumOfShufflesPerResult / 2;
7816
7817 InstructionCost Cost = NumOfResults * NumOfShufflesPerResult * ShuffleCost +
7818 MaskCost + NumOfUnfoldedLoads * MemOpCost +
7819 NumOfMoves;
7820
7821 return Cost;
7822 }
7823
7824 // Store.
7825 assert(Opcode == Instruction::Store &&
7826 "Expected Store Instruction at this point");
7827 // X86InterleavedAccess support only the following interleaved-access group.
7828 static const CostTblEntry AVX512InterleavedStoreTbl[] = {
7829 {3, MVT::v16i8, 12}, // interleave 3 x 16i8 into 48i8 (and store)
7830 {3, MVT::v32i8, 14}, // interleave 3 x 32i8 into 96i8 (and store)
7831 {3, MVT::v64i8, 26}, // interleave 3 x 64i8 into 96i8 (and store)
7832
7833 {4, MVT::v8i8, 10}, // interleave 4 x 8i8 into 32i8 (and store)
7834 {4, MVT::v16i8, 11}, // interleave 4 x 16i8 into 64i8 (and store)
7835 {4, MVT::v32i8, 14}, // interleave 4 x 32i8 into 128i8 (and store)
7836 {4, MVT::v64i8, 24} // interleave 4 x 32i8 into 256i8 (and store)
7837 };
7838
7839 if (const auto *Entry =
7840 CostTableLookup(AVX512InterleavedStoreTbl, Factor, VT))
7841 return MaskCost + NumOfMemOps * MemOpCost + Entry->Cost;
7842 //If an entry does not exist, fallback to the default implementation.
7843
7844 // There is no strided stores meanwhile. And store can't be folded in
7845 // shuffle.
7846 unsigned NumOfSources = Factor; // The number of values to be merged.
7847 InstructionCost ShuffleCost =
7848 getShuffleCost(TTI::SK_PermuteTwoSrc, SingleMemOpTy, SingleMemOpTy,
7849 CostKind, {}, 0, nullptr);
7850 unsigned NumOfShufflesPerStore = NumOfSources - 1;
7851
7852 // The SK_MergeTwoSrc shuffle clobbers one of src operands.
7853 // We need additional instructions to keep sources.
7854 unsigned NumOfMoves = NumOfMemOps * NumOfShufflesPerStore / 2;
7856 MaskCost +
7857 NumOfMemOps * (MemOpCost + NumOfShufflesPerStore * ShuffleCost) +
7858 NumOfMoves;
7859 return Cost;
7860}
7861
7863 unsigned Opcode, Type *BaseTy, unsigned Factor, ArrayRef<unsigned> Indices,
7864 Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind,
7865 bool UseMaskForCond, bool UseMaskForGaps) const {
7866 auto *VecTy = cast<FixedVectorType>(BaseTy);
7867
7868 auto isSupportedOnAVX512 = [&](Type *VecTy) {
7869 Type *EltTy = cast<VectorType>(VecTy)->getElementType();
7870 if (EltTy->isFloatTy() || EltTy->isDoubleTy() || EltTy->isIntegerTy(64) ||
7871 EltTy->isIntegerTy(32) || EltTy->isPointerTy())
7872 return true;
7873 if (EltTy->isIntegerTy(16) || EltTy->isIntegerTy(8) || EltTy->isHalfTy())
7874 return ST->hasBWI();
7875 if (EltTy->isBFloatTy())
7876 return ST->hasBF16();
7877 return false;
7878 };
7879 if (ST->hasAVX512() && isSupportedOnAVX512(VecTy))
7881 Opcode, VecTy, Factor, Indices, Alignment,
7882 AddressSpace, CostKind, UseMaskForCond, UseMaskForGaps);
7883
7884 if (UseMaskForCond || UseMaskForGaps)
7885 return BaseT::getInterleavedMemoryOpCost(Opcode, VecTy, Factor, Indices,
7886 Alignment, AddressSpace, CostKind,
7887 UseMaskForCond, UseMaskForGaps);
7888
7889 // Get estimation for interleaved load/store operations for SSE-AVX2.
7890 // As opposed to AVX-512, SSE-AVX2 do not have generic shuffles that allow
7891 // computing the cost using a generic formula as a function of generic
7892 // shuffles. We therefore use a lookup table instead, filled according to
7893 // the instruction sequences that codegen currently generates.
7894
7895 // VecTy for interleave memop is <VF*Factor x Elt>.
7896 // So, for VF=4, Interleave Factor = 3, Element type = i32 we have
7897 // VecTy = <12 x i32>.
7898 MVT LegalVT = getTypeLegalizationCost(VecTy).second;
7899
7900 // This function can be called with VecTy=<6xi128>, Factor=3, in which case
7901 // the VF=2, while v2i128 is an unsupported MVT vector type
7902 // (see MachineValueType.h::getVectorVT()).
7903 if (!LegalVT.isVector())
7904 return BaseT::getInterleavedMemoryOpCost(Opcode, VecTy, Factor, Indices,
7905 Alignment, AddressSpace, CostKind);
7906
7907 unsigned VF = VecTy->getNumElements() / Factor;
7908 Type *ScalarTy = VecTy->getElementType();
7909 // Deduplicate entries, model floats/pointers as appropriately-sized integers.
7910 if (!ScalarTy->isIntegerTy())
7911 ScalarTy =
7912 Type::getIntNTy(ScalarTy->getContext(), DL.getTypeSizeInBits(ScalarTy));
7913
7914 // Get the cost of all the memory operations.
7915 // FIXME: discount dead loads.
7916 InstructionCost MemOpCosts =
7917 getMemoryOpCost(Opcode, VecTy, Alignment, AddressSpace, CostKind);
7918
7919 auto *VT = FixedVectorType::get(ScalarTy, VF);
7920 EVT ETy = TLI->getValueType(DL, VT);
7921 if (!ETy.isSimple())
7922 return BaseT::getInterleavedMemoryOpCost(Opcode, VecTy, Factor, Indices,
7923 Alignment, AddressSpace, CostKind);
7924
7925 // TODO: Complete for other data-types and strides.
7926 // Each combination of Stride, element bit width and VF results in a different
7927 // sequence; The cost tables are therefore accessed with:
7928 // Factor (stride) and VectorType=VFxiN.
7929 // The Cost accounts only for the shuffle sequence;
7930 // The cost of the loads/stores is accounted for separately.
7931 //
7932 static const CostTblEntry AVX2InterleavedLoadTbl[] = {
7933 {2, MVT::v2i8, 2}, // (load 4i8 and) deinterleave into 2 x 2i8
7934 {2, MVT::v4i8, 2}, // (load 8i8 and) deinterleave into 2 x 4i8
7935 {2, MVT::v8i8, 2}, // (load 16i8 and) deinterleave into 2 x 8i8
7936 {2, MVT::v16i8, 4}, // (load 32i8 and) deinterleave into 2 x 16i8
7937 {2, MVT::v32i8, 6}, // (load 64i8 and) deinterleave into 2 x 32i8
7938
7939 {2, MVT::v8i16, 6}, // (load 16i16 and) deinterleave into 2 x 8i16
7940 {2, MVT::v16i16, 9}, // (load 32i16 and) deinterleave into 2 x 16i16
7941 {2, MVT::v32i16, 18}, // (load 64i16 and) deinterleave into 2 x 32i16
7942
7943 {2, MVT::v8i32, 4}, // (load 16i32 and) deinterleave into 2 x 8i32
7944 {2, MVT::v16i32, 8}, // (load 32i32 and) deinterleave into 2 x 16i32
7945 {2, MVT::v32i32, 16}, // (load 64i32 and) deinterleave into 2 x 32i32
7946
7947 {2, MVT::v4i64, 4}, // (load 8i64 and) deinterleave into 2 x 4i64
7948 {2, MVT::v8i64, 8}, // (load 16i64 and) deinterleave into 2 x 8i64
7949 {2, MVT::v16i64, 16}, // (load 32i64 and) deinterleave into 2 x 16i64
7950 {2, MVT::v32i64, 32}, // (load 64i64 and) deinterleave into 2 x 32i64
7951
7952 {3, MVT::v2i8, 3}, // (load 6i8 and) deinterleave into 3 x 2i8
7953 {3, MVT::v4i8, 3}, // (load 12i8 and) deinterleave into 3 x 4i8
7954 {3, MVT::v8i8, 6}, // (load 24i8 and) deinterleave into 3 x 8i8
7955 {3, MVT::v16i8, 11}, // (load 48i8 and) deinterleave into 3 x 16i8
7956 {3, MVT::v32i8, 14}, // (load 96i8 and) deinterleave into 3 x 32i8
7957
7958 {3, MVT::v2i16, 5}, // (load 6i16 and) deinterleave into 3 x 2i16
7959 {3, MVT::v4i16, 7}, // (load 12i16 and) deinterleave into 3 x 4i16
7960 {3, MVT::v8i16, 9}, // (load 24i16 and) deinterleave into 3 x 8i16
7961 {3, MVT::v16i16, 28}, // (load 48i16 and) deinterleave into 3 x 16i16
7962 {3, MVT::v32i16, 56}, // (load 96i16 and) deinterleave into 3 x 32i16
7963
7964 {3, MVT::v2i32, 3}, // (load 6i32 and) deinterleave into 3 x 2i32
7965 {3, MVT::v4i32, 3}, // (load 12i32 and) deinterleave into 3 x 4i32
7966 {3, MVT::v8i32, 7}, // (load 24i32 and) deinterleave into 3 x 8i32
7967 {3, MVT::v16i32, 14}, // (load 48i32 and) deinterleave into 3 x 16i32
7968 {3, MVT::v32i32, 32}, // (load 96i32 and) deinterleave into 3 x 32i32
7969
7970 {3, MVT::v2i64, 1}, // (load 6i64 and) deinterleave into 3 x 2i64
7971 {3, MVT::v4i64, 5}, // (load 12i64 and) deinterleave into 3 x 4i64
7972 {3, MVT::v8i64, 10}, // (load 24i64 and) deinterleave into 3 x 8i64
7973 {3, MVT::v16i64, 20}, // (load 48i64 and) deinterleave into 3 x 16i64
7974
7975 {4, MVT::v2i8, 4}, // (load 8i8 and) deinterleave into 4 x 2i8
7976 {4, MVT::v4i8, 4}, // (load 16i8 and) deinterleave into 4 x 4i8
7977 {4, MVT::v8i8, 12}, // (load 32i8 and) deinterleave into 4 x 8i8
7978 {4, MVT::v16i8, 24}, // (load 64i8 and) deinterleave into 4 x 16i8
7979 {4, MVT::v32i8, 56}, // (load 128i8 and) deinterleave into 4 x 32i8
7980
7981 {4, MVT::v2i16, 6}, // (load 8i16 and) deinterleave into 4 x 2i16
7982 {4, MVT::v4i16, 17}, // (load 16i16 and) deinterleave into 4 x 4i16
7983 {4, MVT::v8i16, 33}, // (load 32i16 and) deinterleave into 4 x 8i16
7984 {4, MVT::v16i16, 75}, // (load 64i16 and) deinterleave into 4 x 16i16
7985 {4, MVT::v32i16, 150}, // (load 128i16 and) deinterleave into 4 x 32i16
7986
7987 {4, MVT::v2i32, 4}, // (load 8i32 and) deinterleave into 4 x 2i32
7988 {4, MVT::v4i32, 8}, // (load 16i32 and) deinterleave into 4 x 4i32
7989 {4, MVT::v8i32, 16}, // (load 32i32 and) deinterleave into 4 x 8i32
7990 {4, MVT::v16i32, 32}, // (load 64i32 and) deinterleave into 4 x 16i32
7991 {4, MVT::v32i32, 68}, // (load 128i32 and) deinterleave into 4 x 32i32
7992
7993 {4, MVT::v2i64, 6}, // (load 8i64 and) deinterleave into 4 x 2i64
7994 {4, MVT::v4i64, 8}, // (load 16i64 and) deinterleave into 4 x 4i64
7995 {4, MVT::v8i64, 20}, // (load 32i64 and) deinterleave into 4 x 8i64
7996 {4, MVT::v16i64, 40}, // (load 64i64 and) deinterleave into 4 x 16i64
7997
7998 {6, MVT::v2i8, 6}, // (load 12i8 and) deinterleave into 6 x 2i8
7999 {6, MVT::v4i8, 14}, // (load 24i8 and) deinterleave into 6 x 4i8
8000 {6, MVT::v8i8, 18}, // (load 48i8 and) deinterleave into 6 x 8i8
8001 {6, MVT::v16i8, 43}, // (load 96i8 and) deinterleave into 6 x 16i8
8002 {6, MVT::v32i8, 82}, // (load 192i8 and) deinterleave into 6 x 32i8
8003
8004 {6, MVT::v2i16, 13}, // (load 12i16 and) deinterleave into 6 x 2i16
8005 {6, MVT::v4i16, 9}, // (load 24i16 and) deinterleave into 6 x 4i16
8006 {6, MVT::v8i16, 39}, // (load 48i16 and) deinterleave into 6 x 8i16
8007 {6, MVT::v16i16, 106}, // (load 96i16 and) deinterleave into 6 x 16i16
8008 {6, MVT::v32i16, 212}, // (load 192i16 and) deinterleave into 6 x 32i16
8009
8010 {6, MVT::v2i32, 6}, // (load 12i32 and) deinterleave into 6 x 2i32
8011 {6, MVT::v4i32, 15}, // (load 24i32 and) deinterleave into 6 x 4i32
8012 {6, MVT::v8i32, 31}, // (load 48i32 and) deinterleave into 6 x 8i32
8013 {6, MVT::v16i32, 64}, // (load 96i32 and) deinterleave into 6 x 16i32
8014
8015 {6, MVT::v2i64, 6}, // (load 12i64 and) deinterleave into 6 x 2i64
8016 {6, MVT::v4i64, 18}, // (load 24i64 and) deinterleave into 6 x 4i64
8017 {6, MVT::v8i64, 36}, // (load 48i64 and) deinterleave into 6 x 8i64
8018
8019 {8, MVT::v8i32, 40} // (load 64i32 and) deinterleave into 8 x 8i32
8020 };
8021
8022 static const CostTblEntry SSSE3InterleavedLoadTbl[] = {
8023 {2, MVT::v4i16, 2}, // (load 8i16 and) deinterleave into 2 x 4i16
8024 };
8025
8026 static const CostTblEntry SSE2InterleavedLoadTbl[] = {
8027 {2, MVT::v2i16, 2}, // (load 4i16 and) deinterleave into 2 x 2i16
8028 {2, MVT::v4i16, 7}, // (load 8i16 and) deinterleave into 2 x 4i16
8029
8030 {2, MVT::v2i32, 2}, // (load 4i32 and) deinterleave into 2 x 2i32
8031 {2, MVT::v4i32, 2}, // (load 8i32 and) deinterleave into 2 x 4i32
8032
8033 {2, MVT::v2i64, 2}, // (load 4i64 and) deinterleave into 2 x 2i64
8034 };
8035
8036 static const CostTblEntry AVX2InterleavedStoreTbl[] = {
8037 {2, MVT::v16i8, 3}, // interleave 2 x 16i8 into 32i8 (and store)
8038 {2, MVT::v32i8, 4}, // interleave 2 x 32i8 into 64i8 (and store)
8039
8040 {2, MVT::v8i16, 3}, // interleave 2 x 8i16 into 16i16 (and store)
8041 {2, MVT::v16i16, 4}, // interleave 2 x 16i16 into 32i16 (and store)
8042 {2, MVT::v32i16, 8}, // interleave 2 x 32i16 into 64i16 (and store)
8043
8044 {2, MVT::v4i32, 2}, // interleave 2 x 4i32 into 8i32 (and store)
8045 {2, MVT::v8i32, 4}, // interleave 2 x 8i32 into 16i32 (and store)
8046 {2, MVT::v16i32, 8}, // interleave 2 x 16i32 into 32i32 (and store)
8047 {2, MVT::v32i32, 16}, // interleave 2 x 32i32 into 64i32 (and store)
8048
8049 {2, MVT::v2i64, 2}, // interleave 2 x 2i64 into 4i64 (and store)
8050 {2, MVT::v4i64, 4}, // interleave 2 x 4i64 into 8i64 (and store)
8051 {2, MVT::v8i64, 8}, // interleave 2 x 8i64 into 16i64 (and store)
8052 {2, MVT::v16i64, 16}, // interleave 2 x 16i64 into 32i64 (and store)
8053 {2, MVT::v32i64, 32}, // interleave 2 x 32i64 into 64i64 (and store)
8054
8055 {3, MVT::v2i8, 4}, // interleave 3 x 2i8 into 6i8 (and store)
8056 {3, MVT::v4i8, 4}, // interleave 3 x 4i8 into 12i8 (and store)
8057 {3, MVT::v8i8, 6}, // interleave 3 x 8i8 into 24i8 (and store)
8058 {3, MVT::v16i8, 11}, // interleave 3 x 16i8 into 48i8 (and store)
8059 {3, MVT::v32i8, 13}, // interleave 3 x 32i8 into 96i8 (and store)
8060
8061 {3, MVT::v2i16, 4}, // interleave 3 x 2i16 into 6i16 (and store)
8062 {3, MVT::v4i16, 6}, // interleave 3 x 4i16 into 12i16 (and store)
8063 {3, MVT::v8i16, 12}, // interleave 3 x 8i16 into 24i16 (and store)
8064 {3, MVT::v16i16, 27}, // interleave 3 x 16i16 into 48i16 (and store)
8065 {3, MVT::v32i16, 54}, // interleave 3 x 32i16 into 96i16 (and store)
8066
8067 {3, MVT::v2i32, 4}, // interleave 3 x 2i32 into 6i32 (and store)
8068 {3, MVT::v4i32, 5}, // interleave 3 x 4i32 into 12i32 (and store)
8069 {3, MVT::v8i32, 11}, // interleave 3 x 8i32 into 24i32 (and store)
8070 {3, MVT::v16i32, 22}, // interleave 3 x 16i32 into 48i32 (and store)
8071 {3, MVT::v32i32, 48}, // interleave 3 x 32i32 into 96i32 (and store)
8072
8073 {3, MVT::v2i64, 4}, // interleave 3 x 2i64 into 6i64 (and store)
8074 {3, MVT::v4i64, 6}, // interleave 3 x 4i64 into 12i64 (and store)
8075 {3, MVT::v8i64, 12}, // interleave 3 x 8i64 into 24i64 (and store)
8076 {3, MVT::v16i64, 24}, // interleave 3 x 16i64 into 48i64 (and store)
8077
8078 {4, MVT::v2i8, 4}, // interleave 4 x 2i8 into 8i8 (and store)
8079 {4, MVT::v4i8, 4}, // interleave 4 x 4i8 into 16i8 (and store)
8080 {4, MVT::v8i8, 4}, // interleave 4 x 8i8 into 32i8 (and store)
8081 {4, MVT::v16i8, 8}, // interleave 4 x 16i8 into 64i8 (and store)
8082 {4, MVT::v32i8, 12}, // interleave 4 x 32i8 into 128i8 (and store)
8083
8084 {4, MVT::v2i16, 2}, // interleave 4 x 2i16 into 8i16 (and store)
8085 {4, MVT::v4i16, 6}, // interleave 4 x 4i16 into 16i16 (and store)
8086 {4, MVT::v8i16, 10}, // interleave 4 x 8i16 into 32i16 (and store)
8087 {4, MVT::v16i16, 32}, // interleave 4 x 16i16 into 64i16 (and store)
8088 {4, MVT::v32i16, 64}, // interleave 4 x 32i16 into 128i16 (and store)
8089
8090 {4, MVT::v2i32, 5}, // interleave 4 x 2i32 into 8i32 (and store)
8091 {4, MVT::v4i32, 6}, // interleave 4 x 4i32 into 16i32 (and store)
8092 {4, MVT::v8i32, 16}, // interleave 4 x 8i32 into 32i32 (and store)
8093 {4, MVT::v16i32, 32}, // interleave 4 x 16i32 into 64i32 (and store)
8094 {4, MVT::v32i32, 64}, // interleave 4 x 32i32 into 128i32 (and store)
8095
8096 {4, MVT::v2i64, 6}, // interleave 4 x 2i64 into 8i64 (and store)
8097 {4, MVT::v4i64, 8}, // interleave 4 x 4i64 into 16i64 (and store)
8098 {4, MVT::v8i64, 20}, // interleave 4 x 8i64 into 32i64 (and store)
8099 {4, MVT::v16i64, 40}, // interleave 4 x 16i64 into 64i64 (and store)
8100
8101 {6, MVT::v2i8, 7}, // interleave 6 x 2i8 into 12i8 (and store)
8102 {6, MVT::v4i8, 9}, // interleave 6 x 4i8 into 24i8 (and store)
8103 {6, MVT::v8i8, 16}, // interleave 6 x 8i8 into 48i8 (and store)
8104 {6, MVT::v16i8, 27}, // interleave 6 x 16i8 into 96i8 (and store)
8105 {6, MVT::v32i8, 90}, // interleave 6 x 32i8 into 192i8 (and store)
8106
8107 {6, MVT::v2i16, 10}, // interleave 6 x 2i16 into 12i16 (and store)
8108 {6, MVT::v4i16, 15}, // interleave 6 x 4i16 into 24i16 (and store)
8109 {6, MVT::v8i16, 21}, // interleave 6 x 8i16 into 48i16 (and store)
8110 {6, MVT::v16i16, 58}, // interleave 6 x 16i16 into 96i16 (and store)
8111 {6, MVT::v32i16, 90}, // interleave 6 x 32i16 into 192i16 (and store)
8112
8113 {6, MVT::v2i32, 9}, // interleave 6 x 2i32 into 12i32 (and store)
8114 {6, MVT::v4i32, 12}, // interleave 6 x 4i32 into 24i32 (and store)
8115 {6, MVT::v8i32, 33}, // interleave 6 x 8i32 into 48i32 (and store)
8116 {6, MVT::v16i32, 66}, // interleave 6 x 16i32 into 96i32 (and store)
8117
8118 {6, MVT::v2i64, 8}, // interleave 6 x 2i64 into 12i64 (and store)
8119 {6, MVT::v4i64, 15}, // interleave 6 x 4i64 into 24i64 (and store)
8120 {6, MVT::v8i64, 30}, // interleave 6 x 8i64 into 48i64 (and store)
8121 };
8122
8123 static const CostTblEntry SSE2InterleavedStoreTbl[] = {
8124 {2, MVT::v2i8, 1}, // interleave 2 x 2i8 into 4i8 (and store)
8125 {2, MVT::v4i8, 1}, // interleave 2 x 4i8 into 8i8 (and store)
8126 {2, MVT::v8i8, 1}, // interleave 2 x 8i8 into 16i8 (and store)
8127
8128 {2, MVT::v2i16, 1}, // interleave 2 x 2i16 into 4i16 (and store)
8129 {2, MVT::v4i16, 1}, // interleave 2 x 4i16 into 8i16 (and store)
8130
8131 {2, MVT::v2i32, 1}, // interleave 2 x 2i32 into 4i32 (and store)
8132 };
8133
8134 if (Opcode == Instruction::Load) {
8135 auto GetDiscountedCost = [Factor, NumMembers = Indices.size(),
8136 MemOpCosts](const CostTblEntry *Entry) {
8137 // NOTE: this is just an approximation!
8138 // It can over/under -estimate the cost!
8139 return MemOpCosts + divideCeil(NumMembers * Entry->Cost, Factor);
8140 };
8141
8142 if (ST->hasAVX2())
8143 if (const auto *Entry = CostTableLookup(AVX2InterleavedLoadTbl, Factor,
8144 ETy.getSimpleVT()))
8145 return GetDiscountedCost(Entry);
8146
8147 if (ST->hasSSSE3())
8148 if (const auto *Entry = CostTableLookup(SSSE3InterleavedLoadTbl, Factor,
8149 ETy.getSimpleVT()))
8150 return GetDiscountedCost(Entry);
8151
8152 if (ST->hasSSE2())
8153 if (const auto *Entry = CostTableLookup(SSE2InterleavedLoadTbl, Factor,
8154 ETy.getSimpleVT()))
8155 return GetDiscountedCost(Entry);
8156 } else {
8157 assert(Opcode == Instruction::Store &&
8158 "Expected Store Instruction at this point");
8159 assert((!Indices.size() || Indices.size() == Factor) &&
8160 "Interleaved store only supports fully-interleaved groups.");
8161 if (ST->hasAVX2())
8162 if (const auto *Entry = CostTableLookup(AVX2InterleavedStoreTbl, Factor,
8163 ETy.getSimpleVT()))
8164 return MemOpCosts + Entry->Cost;
8165
8166 if (ST->hasSSE2())
8167 if (const auto *Entry = CostTableLookup(SSE2InterleavedStoreTbl, Factor,
8168 ETy.getSimpleVT()))
8169 return MemOpCosts + Entry->Cost;
8170 }
8171
8172 return BaseT::getInterleavedMemoryOpCost(Opcode, VecTy, Factor, Indices,
8173 Alignment, AddressSpace, CostKind,
8174 UseMaskForCond, UseMaskForGaps);
8175}
8176
8178 StackOffset BaseOffset,
8179 bool HasBaseReg, int64_t Scale,
8180 unsigned AddrSpace) const {
8181 // Scaling factors are not free at all.
8182 // An indexed folded instruction, i.e., inst (reg1, reg2, scale),
8183 // will take 2 allocations in the out of order engine instead of 1
8184 // for plain addressing mode, i.e. inst (reg1).
8185 // E.g.,
8186 // vaddps (%rsi,%rdx), %ymm0, %ymm1
8187 // Requires two allocations (one for the load, one for the computation)
8188 // whereas:
8189 // vaddps (%rsi), %ymm0, %ymm1
8190 // Requires just 1 allocation, i.e., freeing allocations for other operations
8191 // and having less micro operations to execute.
8192 //
8193 // For some X86 architectures, this is even worse because for instance for
8194 // stores, the complex addressing mode forces the instruction to use the
8195 // "load" ports instead of the dedicated "store" port.
8196 // E.g., on Haswell:
8197 // vmovaps %ymm1, (%r8, %rdi) can use port 2 or 3.
8198 // vmovaps %ymm1, (%r8) can use port 2, 3, or 7.
8200 AM.BaseGV = BaseGV;
8201 AM.BaseOffs = BaseOffset.getFixed();
8202 AM.HasBaseReg = HasBaseReg;
8203 AM.Scale = Scale;
8204 AM.ScalableOffset = BaseOffset.getScalable();
8205 if (getTLI()->isLegalAddressingMode(DL, AM, Ty, AddrSpace))
8206 // Scale represents reg2 * scale, thus account for 1
8207 // as soon as we use a second register.
8208 return AM.Scale != 0;
8210}
8211
8213 // TODO: Hook MispredictPenalty of SchedMachineModel into this.
8214 return 14;
8215}
8216
8218 unsigned Bits = Ty->getScalarSizeInBits();
8219
8220 // XOP has v16i8/v8i16/v4i32/v2i64 variable vector shifts.
8221 // Splitting for v32i8/v16i16 on XOP+AVX2 targets is still preferred.
8222 if (ST->hasXOP() && (Bits == 8 || Bits == 16 || Bits == 32 || Bits == 64))
8223 return false;
8224
8225 // AVX2 has vpsllv[dq] instructions (and other shifts) that make variable
8226 // shifts just as cheap as scalar ones.
8227 if (ST->hasAVX2() && (Bits == 32 || Bits == 64))
8228 return false;
8229
8230 // AVX512BW has shifts such as vpsllvw.
8231 if (ST->hasBWI() && Bits == 16)
8232 return false;
8233
8234 // Otherwise, it's significantly cheaper to shift by a scalar amount than by a
8235 // fully general vector.
8236 return true;
8237}
8238
8239unsigned X86TTIImpl::getStoreMinimumVF(unsigned VF, Type *ScalarMemTy,
8240 Type *ScalarValTy, Align Alignment,
8241 unsigned AddrSpace) const {
8242 if (ST->hasF16C() && ScalarMemTy->isHalfTy()) {
8243 return 4;
8244 }
8245 return BaseT::getStoreMinimumVF(VF, ScalarMemTy, ScalarValTy, Alignment,
8246 AddrSpace);
8247}
8248
8250 SmallVectorImpl<Use *> &Ops) const {
8251 using namespace llvm::PatternMatch;
8252
8253 if (I->getOpcode() == Instruction::And &&
8254 (ST->hasBMI() || (I->getType()->isVectorTy() && ST->hasSSE2()))) {
8255 for (auto &Op : I->operands()) {
8256 // (and X, (not Y)) -> (andn X, Y)
8257 if (match(Op.get(), m_Not(m_Value())) && !I->getType()->isIntegerTy(8)) {
8258 Ops.push_back(&Op);
8259 return true;
8260 }
8261 // (and X, (splat (not Y))) -> (andn X, (splat Y))
8262 if (match(Op.get(),
8264 m_Value(), m_ZeroMask()))) {
8265 Use &InsertElt = cast<Instruction>(Op)->getOperandUse(0);
8266 Use &Not = cast<Instruction>(InsertElt)->getOperandUse(1);
8267 Ops.push_back(&Not);
8268 Ops.push_back(&InsertElt);
8269 Ops.push_back(&Op);
8270 return true;
8271 }
8272 }
8273 }
8274
8275 FixedVectorType *VTy = dyn_cast<FixedVectorType>(I->getType());
8276 if (!VTy)
8277 return false;
8278
8279 if (I->getOpcode() == Instruction::Mul &&
8280 VTy->getElementType()->isIntegerTy(64)) {
8281 for (auto &Op : I->operands()) {
8282 // Make sure we are not already sinking this operand
8283 if (any_of(Ops, [&](Use *U) { return U->get() == Op; }))
8284 continue;
8285
8286 // Look for PMULDQ pattern where the input is a sext_inreg from vXi32 or
8287 // the PMULUDQ pattern where the input is a zext_inreg from vXi32.
8288 if (ST->hasSSE41() &&
8289 match(Op.get(), m_AShr(m_Shl(m_Value(), m_SpecificInt(32)),
8290 m_SpecificInt(32)))) {
8291 Ops.push_back(&cast<Instruction>(Op)->getOperandUse(0));
8292 Ops.push_back(&Op);
8293 } else if (ST->hasSSE2() &&
8294 match(Op.get(),
8295 m_And(m_Value(), m_SpecificInt(UINT64_C(0xffffffff))))) {
8296 Ops.push_back(&Op);
8297 }
8298 }
8299
8300 return !Ops.empty();
8301 }
8302
8303 // A uniform shift amount in a vector shift or funnel shift may be much
8304 // cheaper than a generic variable vector shift, so make that pattern visible
8305 // to SDAG by sinking the shuffle instruction next to the shift.
8306 int ShiftAmountOpNum = -1;
8307 if (I->isShift())
8308 ShiftAmountOpNum = 1;
8309 else if (auto *II = dyn_cast<IntrinsicInst>(I)) {
8310 if (II->getIntrinsicID() == Intrinsic::fshl ||
8311 II->getIntrinsicID() == Intrinsic::fshr)
8312 ShiftAmountOpNum = 2;
8313 }
8314
8315 if (ShiftAmountOpNum == -1)
8316 return false;
8317
8318 auto *Shuf = dyn_cast<ShuffleVectorInst>(I->getOperand(ShiftAmountOpNum));
8319 if (Shuf && getSplatIndex(Shuf->getShuffleMask()) >= 0 &&
8320 isVectorShiftByScalarCheap(I->getType())) {
8321 Ops.push_back(&I->getOperandUse(ShiftAmountOpNum));
8322 return true;
8323 }
8324
8325 return false;
8326}
8327
8329 bool HasEGPR = ST->hasEGPR();
8330 const TargetMachine &TM = getTLI()->getTargetMachine();
8331
8332 for (User *U : F.users()) {
8334 if (!CB || CB->getCalledOperand() != &F)
8335 continue;
8336 Function *CallerFunc = CB->getFunction();
8337 if (TM.getSubtarget<X86Subtarget>(*CallerFunc).hasEGPR() != HasEGPR)
8338 return false;
8339 }
8340
8341 return true;
8342}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
unsigned Imm
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
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:857
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
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
CostTblEntryT< CostKindCosts > CostKindTblEntry
#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.
static bool isFoldedIntoRsqrtEstimate(const IntrinsicCostAttributes &ICA, const X86TargetLowering &TLI, const DataLayout &DL)
Returns true if the square root is divided into with the reciprocal allowed and the target replaces t...
static InstructionCost getPredicateFanoutCost(const X86TTIImpl &TTI, Type *DataVTy, Type *MaskVTy)
static bool isLegalMaskedLoadStore(Type *ScalarTy, const X86Subtarget *ST)
TypeConversionCostTblEntryT< CostKindCosts > TypeConversionCostKindTblEntry
This file a TargetTransformInfoImplBase conforming object specific to the X86 target machine.
static const fltSemantics & IEEEsingle()
Definition APFloat.h:304
static const fltSemantics & IEEEdouble()
Definition APFloat.h:305
static LLVM_ABI unsigned int semanticsPrecision(const fltSemantics &)
Definition APFloat.cpp:335
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:230
LLVM_ABI APInt zext(unsigned width) const
Zero extend to a new width.
Definition APInt.cpp:1057
unsigned popcount() const
Count the number of bits set.
Definition APInt.h:1690
void setBit(unsigned BitPosition)
Set the given bit to 1 whose position is given as "bitPosition".
Definition APInt.h:1350
bool isAllOnes() const
Determine if all bits are set. This is true for zero-width values.
Definition APInt.h:367
static APInt getBitsSet(unsigned numBits, unsigned loBit, unsigned hiBit)
Get a value with a block of bits set.
Definition APInt.h:254
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
Definition APInt.h:376
unsigned getBitWidth() const
Return the number of bits in the APInt.
Definition APInt.h:1508
LLVM_ABI APInt sextOrTrunc(unsigned width) const
Sign extend or truncate to width.
Definition APInt.cpp:1086
APInt ashr(unsigned ShiftAmt) const
Arithmetic right-shift function.
Definition APInt.h:829
static APInt getZero(unsigned numBits)
Get the '0' value for the specified bit-width.
Definition APInt.h:196
LLVM_ABI APInt extractBits(unsigned numBits, unsigned bitPosition) const
Return an APInt with the extracted bits [bitPosition,bitPosition+numBits).
Definition APInt.cpp:478
int64_t getSExtValue() const
Get sign extended value.
Definition APInt.h:1582
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 getMinMaxReductionCost(Intrinsic::ID IID, VectorType *Ty, FastMathFlags FMF, 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
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 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 *CtxI=nullptr) const override
InstructionCost getShuffleCost(TTI::ShuffleKind Kind, VectorType *DstTy, VectorType *SrcTy, TTI::TargetCostKind CostKind, ArrayRef< int > Mask, int Index, VectorType *SubTp, ArrayRef< const Value * > Args={}, const Instruction *CtxI=nullptr, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) 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 getPartialReductionCost(unsigned Opcode, Type *InputTypeA, Type *InputTypeB, Type *AccumType, ElementCount VF, TTI::PartialReductionExtendKind OpAExtend, TTI::PartialReductionExtendKind OpBExtend, std::optional< unsigned > BinOp, TTI::TargetCostKind CostKind, std::optional< FastMathFlags > FMF) const override
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 getGEPCost(Type *PointeeType, const Value *Ptr, ArrayRef< const Value * > Operands, TTI::TargetCostKind CostKind, Type *AccessType) 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:316
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:843
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition Function.cpp:734
static unsigned getPointerOperandIndex()
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.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module 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:338
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:71
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
EVT getValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Return the EVT corresponding to this LLVM type.
int getRecipEstimateSqrtEnabled(EVT VT, const Function &F) const
Return a ReciprocalEstimate enum value for a square root of the given type based on the function's at...
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
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
virtual InstructionCost getPointersChainCost(ArrayRef< const Value * > Ptrs, const Value *Base, const TTI::PointersChainInfo &Info, Type *AccessTy, const TTI::TargetCostKind CostKind) 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:339
static constexpr TypeSize getScalable(ScalarTy MinimumSize)
Definition TypeSize.h:342
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:300
LLVM_ABI unsigned getIntegerBitWidth() const
bool isVectorTy() const
True if this is an instance of VectorType.
Definition Type.h:283
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
Definition Type.cpp:299
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
Definition Type.h:258
bool isPointerTy() const
True if this is an instance of PointerType.
Definition Type.h:277
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:297
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Definition Type.h:363
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
Definition Type.cpp:187
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:222
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:296
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
Definition Type.h:186
LLVM_ABI bool isScalableTy() const
Return true if this is a type whose size is a known multiple of vscale.
Definition Type.cpp:61
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:252
static LLVM_ABI IntegerType * getIntNTy(LLVMContext &C, unsigned N)
Definition Type.cpp:303
static LLVM_ABI Type * getDoubleTy(LLVMContext &C)
Definition Type.cpp:277
bool isFPOrFPVectorTy() const
Return true if this is a FP type or a vector of FP.
Definition Type.h:222
Type * getContainedType(unsigned i) const
This method is used to implement the type iterator (defined at the end of the file).
Definition Type.h:392
static LLVM_ABI Type * getFloatTy(LLVMContext &C)
Definition Type.cpp:276
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
Value * getOperand(unsigned i) const
Definition User.h:207
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:257
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 LLVM_ABI VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
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
bool isLegalAltInstr(VectorType *VecTy, unsigned Opcode0, unsigned Opcode1, const SmallBitVector &OpcodeMask, ArrayRef< const Value * > Scalars) 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 getPartialReductionCost(unsigned Opcode, Type *InputTypeA, Type *InputTypeB, Type *AccumType, ElementCount VF, TTI::PartialReductionExtendKind OpAExtend, TTI::PartialReductionExtendKind OpBExtend, std::optional< unsigned > BinOp, TTI::TargetCostKind CostKind, std::optional< FastMathFlags > FMF) 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
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 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 *CtxI=nullptr) 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
InstructionCost getAltInstrCost(VectorType *VecTy, unsigned Opcode0, unsigned Opcode1, const SmallBitVector &OpcodeMask, TTI::TargetCostKind CostKind, ArrayRef< const Value * > Scalars) 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
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
InstructionCost getShuffleCost(TTI::ShuffleKind Kind, VectorType *DstTy, VectorType *SrcTy, TTI::TargetCostKind CostKind, ArrayRef< int > Mask, int Index, VectorType *SubTp, ArrayRef< const Value * > Args={}, const Instruction *CtxI=nullptr, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) 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 getPointersChainCost(ArrayRef< const Value * > Ptrs, const Value *Base, const TTI::PointersChainInfo &Info, Type *AccessTy, const TTI::TargetCostKind CostKind) 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
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
bool hasSqrtEstimate(EVT VT, bool Reciprocal) const
Return true if VT has the rsqrt* based estimate of the square root, or of its reciprocal if Reciproca...
constexpr bool isKnownMultipleOf(ScalarTy RHS) const
This function tells the caller whether the element count is known at compile time to be a multiple of...
Definition TypeSize.h:180
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
constexpr LeafTy divideCoefficientBy(ScalarTy RHS) const
We do not provide the '/' operator here because division for polynomial types does not work in the sa...
Definition TypeSize.h:252
#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:3043
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:26
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
Definition ISDOpcodes.h:43
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
Definition ISDOpcodes.h:837
@ DELETED_NODE
DELETED_NODE - This is an illegal value that is used to catch errors.
Definition ISDOpcodes.h:47
@ PARTIAL_REDUCE_SMLA
PARTIAL_REDUCE_[U|S]MLA(Accumulator, Input1, Input2) The partial reduction nodes sign or zero extend ...
@ BSWAP
Byte Swap and Counting operators.
Definition ISDOpcodes.h:797
@ ADD
Simple integer binary arithmetic operators.
Definition ISDOpcodes.h:266
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
Definition ISDOpcodes.h:898
@ FADD
Simple binary floating point operators.
Definition ISDOpcodes.h:420
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
Definition ISDOpcodes.h:757
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
Definition ISDOpcodes.h:282
@ CLMUL
Carry-less multiplication operations.
Definition ISDOpcodes.h:788
@ CTLZ_ZERO_POISON
Definition ISDOpcodes.h:806
@ PARTIAL_REDUCE_UMLA
@ SIGN_EXTEND
Conversion operators.
Definition ISDOpcodes.h:862
@ PARTIAL_REDUCE_FMLA
@ 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:377
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
Definition ISDOpcodes.h:814
@ SADDO
RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
Definition ISDOpcodes.h:351
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
Definition ISDOpcodes.h:714
@ SHL
Shift and rotation operations.
Definition ISDOpcodes.h:779
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
Definition ISDOpcodes.h:581
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
Definition ISDOpcodes.h:868
@ FMINNUM
FMINNUM/FMAXNUM - Perform floating-point minimum maximum on two values, following IEEE-754 definition...
@ SMULO
Same for multiplication.
Definition ISDOpcodes.h:359
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
Definition ISDOpcodes.h:737
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
Definition ISDOpcodes.h:996
@ 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:944
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition ISDOpcodes.h:749
@ CTTZ_ZERO_POISON
Bit counting operators with a poisoned result for zero inputs.
Definition ISDOpcodes.h:805
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
Definition ISDOpcodes.h:977
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
Definition ISDOpcodes.h:874
@ PARTIAL_REDUCE_SUMLA
@ SADDSAT
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
Definition ISDOpcodes.h:368
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.
BinaryOp_match< LHS, RHS, Instruction::FMul > m_FMul(const LHS &L, const RHS &R)
bool match(Val *V, const Pattern &P)
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
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)
BinaryOp_match< LHS, RHS, Instruction::FDiv > m_FDiv(const LHS &L, const RHS &R)
AllowFmf_match< T, FastMathFlags::AllowContract > m_AllowContract(const T &SubPattern)
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:2196
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:1755
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:121
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:2570
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
LLVM_ABI void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CtxI=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 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:541
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
LLVM_ABI unsigned ComputeNumSignBits(const Value *Op, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true, unsigned Depth=0)
Return the number of times the sign bit of the register is replicated into the other bits.
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:380
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:1762
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition MathExtras.h:280
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition Alignment.h:149
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:389
TargetTransformInfo TTI
DWARFExpression::Operation Op
OutputIt copy(R &&Range, OutputIt Out)
Definition STLExtras.h:1901
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:2035
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:206
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