LLVM 24.0.0git
X86TargetTransformInfo.cpp
Go to the documentation of this file.
1//===-- X86TargetTransformInfo.cpp - X86 specific TTI pass ----------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8/// \file
9/// This file implements a TargetTransformInfo analysis pass specific to the
10/// X86 target machine. It uses the target's detailed information to provide
11/// more precise answers to certain TTI queries, while letting the target
12/// independent and default TTI implementations handle the rest.
13///
14//===----------------------------------------------------------------------===//
15/// About Cost Model numbers used below it's necessary to say the following:
16/// the numbers correspond to some "generic" X86 CPU instead of usage of a
17/// specific CPU model. Usually the numbers correspond to the CPU where the
18/// feature first appeared. For example, if we do Subtarget.hasSSE42() in
19/// the lookups below the cost is based on Nehalem as that was the first CPU
20/// to support that feature level and thus has most likely the worst case cost,
21/// although we may discard an outlying worst cost from one CPU (e.g. Atom).
22///
23/// Some examples of other technologies/CPUs:
24/// SSE 3 - Pentium4 / Athlon64
25/// SSE 4.1 - Penryn
26/// SSE 4.2 - Nehalem / Silvermont
27/// AVX - Sandy Bridge / Jaguar / Bulldozer
28/// AVX2 - Haswell / Ryzen
29/// AVX-512 - Xeon Phi / Skylake
30///
31/// And some examples of instruction target dependent costs (latency)
32/// divss sqrtss rsqrtss
33/// AMD K7 11-16 19 3
34/// Piledriver 9-24 13-15 5
35/// Jaguar 14 16 2
36/// Pentium II,III 18 30 2
37/// Nehalem 7-14 7-18 3
38/// Haswell 10-13 11 5
39///
40/// Interpreting the 4 TargetCostKind types:
41/// TCK_RecipThroughput and TCK_Latency should try to match the worst case
42/// values reported by the CPU scheduler models (and llvm-mca).
43/// TCK_CodeSize should match the instruction count (e.g. divss = 1), NOT the
44/// actual encoding size of the instruction.
45/// TCK_SizeAndLatency should match the worst case micro-op counts reported by
46/// by the CPU scheduler models (and llvm-mca), to ensure that they are
47/// compatible with the MicroOpBufferSize and LoopMicroOpBufferSize values which are
48/// often used as the cost thresholds where TCK_SizeAndLatency is requested.
49//===----------------------------------------------------------------------===//
50
60#include <optional>
61
62using namespace llvm;
63
64#define DEBUG_TYPE "x86tti"
65
66//===----------------------------------------------------------------------===//
67//
68// X86 cost model.
69//
70//===----------------------------------------------------------------------===//
71
72// Helper struct to store/access costs for each cost kind.
73// TODO: Move this to allow other targets to use it?
75 unsigned RecipThroughputCost = ~0U;
76 unsigned LatencyCost = ~0U;
77 unsigned CodeSizeCost = ~0U;
78 unsigned SizeAndLatencyCost = ~0U;
79
80 std::optional<unsigned>
82 unsigned Cost = ~0U;
83 switch (Kind) {
86 break;
89 break;
92 break;
95 break;
96 }
97 if (Cost == ~0U)
98 return std::nullopt;
99 return Cost;
100 }
101};
104
106X86TTIImpl::getPopcntSupport(unsigned TyWidth) const {
107 assert(isPowerOf2_32(TyWidth) && "Ty width must be power of 2");
108 // TODO: Currently the __builtin_popcount() implementation using SSE3
109 // instructions is inefficient. Once the problem is fixed, we should
110 // call ST->hasSSE3() instead of ST->hasPOPCNT().
111 return ST->hasPOPCNT() ? TTI::PSK_FastHardware : TTI::PSK_Software;
112}
113
114std::optional<unsigned> X86TTIImpl::getCacheSize(
116 switch (Level) {
118 // - Penryn
119 // - Nehalem
120 // - Westmere
121 // - Sandy Bridge
122 // - Ivy Bridge
123 // - Haswell
124 // - Broadwell
125 // - Skylake
126 // - Kabylake
127 return 32 * 1024; // 32 KiB
129 // - Penryn
130 // - Nehalem
131 // - Westmere
132 // - Sandy Bridge
133 // - Ivy Bridge
134 // - Haswell
135 // - Broadwell
136 // - Skylake
137 // - Kabylake
138 return 256 * 1024; // 256 KiB
139 }
140
141 llvm_unreachable("Unknown TargetTransformInfo::CacheLevel");
142}
143
144std::optional<unsigned> X86TTIImpl::getCacheAssociativity(
146 // - Penryn
147 // - Nehalem
148 // - Westmere
149 // - Sandy Bridge
150 // - Ivy Bridge
151 // - Haswell
152 // - Broadwell
153 // - Skylake
154 // - Kabylake
155 switch (Level) {
157 [[fallthrough]];
159 return 8;
160 }
161
162 llvm_unreachable("Unknown TargetTransformInfo::CacheLevel");
163}
164
166
168 return Vector ? VectorClass
169 : Ty && Ty->isFloatingPointTy() ? ScalarFPClass
170 : GPRClass;
171}
172
173unsigned X86TTIImpl::getNumberOfRegisters(unsigned ClassID) const {
174 if (ClassID == VectorClass && !ST->hasSSE1())
175 return 0;
176
177 if (!ST->is64Bit())
178 return 8;
179
180 if ((ClassID == GPRClass && ST->hasEGPR()) ||
181 (ClassID != GPRClass && ST->hasAVX512()))
182 return 32;
183
184 return 16;
185}
186
188 if (!ST->hasCF())
189 return false;
190 if (!Ty)
191 return true;
192 // Conditional faulting is supported by CFCMOV, which only accepts
193 // 16/32/64-bit operands.
194 // TODO: Support f32/f64 with VMOVSS/VMOVSD with zero mask when it's
195 // profitable.
196 auto *VTy = dyn_cast<FixedVectorType>(Ty);
197 if (!Ty->isIntegerTy() && (!VTy || VTy->getNumElements() != 1))
198 return false;
199 auto *ScalarTy = Ty->getScalarType();
200 switch (cast<IntegerType>(ScalarTy)->getBitWidth()) {
201 default:
202 return false;
203 case 16:
204 case 32:
205 case 64:
206 return true;
207 }
208}
209
212 unsigned PreferVectorWidth = ST->getPreferVectorWidth();
213 switch (K) {
215 return TypeSize::getFixed(ST->is64Bit() ? 64 : 32);
217 if (ST->hasAVX512() && PreferVectorWidth >= 512)
218 return TypeSize::getFixed(512);
219 if (ST->hasAVX() && PreferVectorWidth >= 256)
220 return TypeSize::getFixed(256);
221 if (ST->hasSSE1() && PreferVectorWidth >= 128)
222 return TypeSize::getFixed(128);
223 return TypeSize::getFixed(0);
225 return TypeSize::getScalable(0);
226 }
227
228 llvm_unreachable("Unsupported register kind");
229}
230
235
237 bool HasUnorderedReductions) const {
238 // If the loop will not be vectorized, don't interleave the loop.
239 // Let regular unroll to unroll the loop, which saves the overflow
240 // check and memory check cost.
241 if (VF.isScalar())
242 return 1;
243
244 if (ST->isAtom())
245 return 1;
246
247 // Sandybridge and Haswell have multiple execution ports and pipelined
248 // vector units.
249 if (ST->hasAVX())
250 return 4;
251
252 return 2;
253}
254
256 unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind,
258 ArrayRef<const Value *> Args, const Instruction *CxtI) const {
259
260 // vXi8 multiplications are always promoted to vXi16.
261 // Sub-128-bit types can be extended/packed more efficiently.
262 if (Opcode == Instruction::Mul && Ty->isVectorTy() &&
263 Ty->getPrimitiveSizeInBits() <= 64 && Ty->getScalarSizeInBits() == 8) {
264 Type *WideVecTy =
266 return getCastInstrCost(Instruction::ZExt, WideVecTy, Ty,
268 CostKind) +
269 getCastInstrCost(Instruction::Trunc, Ty, WideVecTy,
271 CostKind) +
272 getArithmeticInstrCost(Opcode, WideVecTy, CostKind, Op1Info, Op2Info);
273 }
274
275 // Legalize the type.
276 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Ty);
277
278 int ISD = TLI->InstructionOpcodeToISD(Opcode);
279 assert(ISD && "Invalid opcode");
280
281 if (ISD == ISD::MUL && Args.size() == 2 && LT.second.isVector() &&
282 (LT.second.getScalarType() == MVT::i32 ||
283 LT.second.getScalarType() == MVT::i64)) {
284 // Check if the operands can be represented as a smaller datatype.
285 bool Op1Signed = false, Op2Signed = false;
286 unsigned Op1MinSize = BaseT::minRequiredElementSize(Args[0], Op1Signed);
287 unsigned Op2MinSize = BaseT::minRequiredElementSize(Args[1], Op2Signed);
288 unsigned OpMinSize = std::max(Op1MinSize, Op2MinSize);
289 bool SignedMode = Op1Signed || Op2Signed;
290
291 // If both vXi32 are representable as i15 and at least one is constant,
292 // zero-extended, or sign-extended from vXi16 (or less pre-SSE41) then we
293 // can treat this as PMADDWD which has the same costs as a vXi16 multiply.
294 if (OpMinSize <= 15 && !ST->isPMADDWDSlow() &&
295 LT.second.getScalarType() == MVT::i32) {
296 bool Op1Constant =
297 isa<ConstantDataVector>(Args[0]) || isa<ConstantVector>(Args[0]);
298 bool Op2Constant =
299 isa<ConstantDataVector>(Args[1]) || isa<ConstantVector>(Args[1]);
300 bool Op1Sext = isa<SExtInst>(Args[0]) &&
301 (Op1MinSize == 15 || (Op1MinSize < 15 && !ST->hasSSE41()));
302 bool Op2Sext = isa<SExtInst>(Args[1]) &&
303 (Op2MinSize == 15 || (Op2MinSize < 15 && !ST->hasSSE41()));
304
305 bool IsZeroExtended = !Op1Signed || !Op2Signed;
306 bool IsConstant = Op1Constant || Op2Constant;
307 bool IsSext = Op1Sext || Op2Sext;
308 if (IsConstant || IsZeroExtended || IsSext)
309 LT.second =
310 MVT::getVectorVT(MVT::i16, 2 * LT.second.getVectorNumElements());
311 }
312
313 // Check if the vXi32 operands can be shrunk into a smaller datatype.
314 // This should match the codegen from reduceVMULWidth.
315 // TODO: Make this generic (!ST->SSE41 || ST->isPMULLDSlow()).
316 if (ST->useSLMArithCosts() && LT.second == MVT::v4i32) {
317 if (OpMinSize <= 7)
318 return LT.first * 3; // pmullw/sext
319 if (!SignedMode && OpMinSize <= 8)
320 return LT.first * 3; // pmullw/zext
321 if (OpMinSize <= 15)
322 return LT.first * 5; // pmullw/pmulhw/pshuf
323 if (!SignedMode && OpMinSize <= 16)
324 return LT.first * 5; // pmullw/pmulhw/pshuf
325 }
326
327 // If both vXi64 are representable as (unsigned) i32, then we can perform
328 // the multiple with a single PMULUDQ instruction.
329 // TODO: Add (SSE41+) PMULDQ handling for signed extensions.
330 if (!SignedMode && OpMinSize <= 32 && LT.second.getScalarType() == MVT::i64)
331 ISD = X86ISD::PMULUDQ;
332 }
333
334 // Vector multiply by pow2 will be simplified to shifts.
335 // Vector multiply by -pow2 will be simplified to shifts/negates.
336 if (ISD == ISD::MUL && Op2Info.isConstant() &&
337 (Op2Info.isPowerOf2() || Op2Info.isNegatedPowerOf2())) {
339 getArithmeticInstrCost(Instruction::Shl, Ty, CostKind,
340 Op1Info.getNoProps(), Op2Info.getNoProps());
341 if (Op2Info.isNegatedPowerOf2())
342 Cost += getArithmeticInstrCost(Instruction::Sub, Ty, CostKind);
343 return Cost;
344 }
345
346 // On X86, vector signed division by constants power-of-two are
347 // normally expanded to the sequence SRA + SRL + ADD + SRA.
348 // The OperandValue properties may not be the same as that of the previous
349 // operation; conservatively assume OP_None.
350 if ((ISD == ISD::SDIV || ISD == ISD::SREM) &&
351 Op2Info.isConstant() && Op2Info.isPowerOf2()) {
353 2 * getArithmeticInstrCost(Instruction::AShr, Ty, CostKind,
354 Op1Info.getNoProps(), Op2Info.getNoProps());
355 Cost += getArithmeticInstrCost(Instruction::LShr, Ty, CostKind,
356 Op1Info.getNoProps(), Op2Info.getNoProps());
357 Cost += getArithmeticInstrCost(Instruction::Add, Ty, CostKind,
358 Op1Info.getNoProps(), Op2Info.getNoProps());
359
360 if (ISD == ISD::SREM) {
361 // For SREM: (X % C) is the equivalent of (X - (X/C)*C)
362 Cost += getArithmeticInstrCost(Instruction::Mul, Ty, CostKind, Op1Info.getNoProps(),
363 Op2Info.getNoProps());
364 Cost += getArithmeticInstrCost(Instruction::Sub, Ty, CostKind, Op1Info.getNoProps(),
365 Op2Info.getNoProps());
366 }
367
368 return Cost;
369 }
370
371 // Vector unsigned division/remainder will be simplified to shifts/masks.
372 if ((ISD == ISD::UDIV || ISD == ISD::UREM) &&
373 Op2Info.isConstant() && Op2Info.isPowerOf2()) {
374 if (ISD == ISD::UDIV)
375 return getArithmeticInstrCost(Instruction::LShr, Ty, CostKind,
376 Op1Info.getNoProps(), Op2Info.getNoProps());
377 // UREM
378 return getArithmeticInstrCost(Instruction::And, Ty, CostKind,
379 Op1Info.getNoProps(), Op2Info.getNoProps());
380 }
381
382 // A scalar integer divide/remainder by a constant is not a hardware divide;
383 // it lowers to a magic-number multiply-high plus a few fixup ops. Cost it as
384 // that sequence rather than the generic single-instruction divide, so the
385 // vectorizers do not compare against an artificially cheap scalar lane. The
386 // power-of-two cases are handled above; negated powers of two are left to the
387 // generic handling.
388 if (!Ty->isVectorTy() && Op2Info.isConstant() && !Op2Info.isNegatedPowerOf2() &&
389 (ISD == ISD::UDIV || ISD == ISD::SDIV || ISD == ISD::UREM ||
390 ISD == ISD::SREM)) {
391 unsigned Cost = ISD == ISD::UREM || ISD == ISD::SREM ? 6 : 5;
393 Cost += 2;
394 return LT.first * Cost;
395 }
396
397 static const CostKindTblEntry GFNIUniformConstCostTable[] = {
398 { ISD::SHL, MVT::v16i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
399 { ISD::SRL, MVT::v16i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
400 { ISD::SRA, MVT::v16i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
401 { ISD::SHL, MVT::v32i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
402 { ISD::SRL, MVT::v32i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
403 { ISD::SRA, MVT::v32i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
404 { ISD::SHL, MVT::v64i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
405 { ISD::SRL, MVT::v64i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
406 { ISD::SRA, MVT::v64i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
407 };
408
409 if (Op2Info.isUniform() && Op2Info.isConstant() && ST->hasGFNI())
410 if (const auto *Entry =
411 CostTableLookup(GFNIUniformConstCostTable, ISD, LT.second))
412 if (auto KindCost = Entry->Cost[CostKind])
413 return LT.first * *KindCost;
414
415 static const CostKindTblEntry AVX512BWUniformConstCostTable[] = {
416 { ISD::SHL, MVT::v16i8, { 1, 7, 2, 3 } }, // psllw + pand.
417 { ISD::SRL, MVT::v16i8, { 1, 7, 2, 3 } }, // psrlw + pand.
418 { ISD::SRA, MVT::v16i8, { 1, 8, 4, 5 } }, // psrlw, pand, pxor, psubb.
419 { ISD::SHL, MVT::v32i8, { 1, 8, 2, 3 } }, // psllw + pand.
420 { ISD::SRL, MVT::v32i8, { 1, 8, 2, 3 } }, // psrlw + pand.
421 { ISD::SRA, MVT::v32i8, { 1, 9, 4, 5 } }, // psrlw, pand, pxor, psubb.
422 { ISD::SHL, MVT::v64i8, { 1, 8, 2, 3 } }, // psllw + pand.
423 { ISD::SRL, MVT::v64i8, { 1, 8, 2, 3 } }, // psrlw + pand.
424 { ISD::SRA, MVT::v64i8, { 1, 9, 4, 6 } }, // psrlw, pand, pxor, psubb.
425
426 { ISD::SHL, MVT::v16i16, { 1, 1, 1, 1 } }, // psllw
427 { ISD::SRL, MVT::v16i16, { 1, 1, 1, 1 } }, // psrlw
428 { ISD::SRA, MVT::v16i16, { 1, 1, 1, 1 } }, // psrlw
429 { ISD::SHL, MVT::v32i16, { 1, 1, 1, 1 } }, // psllw
430 { ISD::SRL, MVT::v32i16, { 1, 1, 1, 1 } }, // psrlw
431 { ISD::SRA, MVT::v32i16, { 1, 1, 1, 1 } }, // psrlw
432 };
433
434 if (Op2Info.isUniform() && Op2Info.isConstant() && ST->hasBWI())
435 if (const auto *Entry =
436 CostTableLookup(AVX512BWUniformConstCostTable, ISD, LT.second))
437 if (auto KindCost = Entry->Cost[CostKind])
438 return LT.first * *KindCost;
439
440 static const CostKindTblEntry AVX512DQUniformConstCostTable[] = {
441 { ISD::SDIV, MVT::v4i64, { 15 } }, // vpmullq-based MULHS sequence
442 { ISD::SREM, MVT::v4i64, { 17 } }, // vpmullq-based MULHS+mul+sub sequence
443 { ISD::SDIV, MVT::v8i64, { 15 } }, // vpmullq-based MULHS sequence
444 { ISD::SREM, MVT::v8i64, { 17 } }, // vpmullq-based MULHS+mul+sub sequence
445 // The remainder's multiply-back is a single vpmullq with DQ, just like the
446 // pmulld the vXi32 entries above rely on. Without DQ it is another
447 // vpmuludq schoolbook, so the AVX512/AVX2 tables charge more.
448 { ISD::UREM, MVT::v4i64, { 17 } }, // MULHU + vpmullq + sub sequence
449 { ISD::UREM, MVT::v8i64, { 17 } }, // MULHU + vpmullq + sub sequence
450 };
451
452 if (Op2Info.isUniform() && Op2Info.isConstant() && ST->hasDQI())
453 if (const auto *Entry =
454 CostTableLookup(AVX512DQUniformConstCostTable, ISD, LT.second))
455 if (auto KindCost = Entry->Cost[CostKind])
456 return LT.first * *KindCost;
457
458 static const CostKindTblEntry AVX512UniformConstCostTable[] = {
459 { ISD::SHL, MVT::v64i8, { 2, 12, 5, 6 } }, // psllw + pand.
460 { ISD::SRL, MVT::v64i8, { 2, 12, 5, 6 } }, // psrlw + pand.
461 { ISD::SRA, MVT::v64i8, { 3, 10, 12, 12 } }, // psrlw, pand, pxor, psubb.
462
463 { ISD::SHL, MVT::v16i16, { 2, 7, 4, 4 } }, // psllw + split.
464 { ISD::SRL, MVT::v16i16, { 2, 7, 4, 4 } }, // psrlw + split.
465 { ISD::SRA, MVT::v16i16, { 2, 7, 4, 4 } }, // psraw + split.
466
467 { ISD::SHL, MVT::v8i32, { 1, 1, 1, 1 } }, // pslld
468 { ISD::SRL, MVT::v8i32, { 1, 1, 1, 1 } }, // psrld
469 { ISD::SRA, MVT::v8i32, { 1, 1, 1, 1 } }, // psrad
470 { ISD::SHL, MVT::v16i32, { 1, 1, 1, 1 } }, // pslld
471 { ISD::SRL, MVT::v16i32, { 1, 1, 1, 1 } }, // psrld
472 { ISD::SRA, MVT::v16i32, { 1, 1, 1, 1 } }, // psrad
473
474 { ISD::SRA, MVT::v2i64, { 1, 1, 1, 1 } }, // psraq
475 { ISD::SHL, MVT::v4i64, { 1, 1, 1, 1 } }, // psllq
476 { ISD::SRL, MVT::v4i64, { 1, 1, 1, 1 } }, // psrlq
477 { ISD::SRA, MVT::v4i64, { 1, 1, 1, 1 } }, // psraq
478 { ISD::SHL, MVT::v8i64, { 1, 1, 1, 1 } }, // psllq
479 { ISD::SRL, MVT::v8i64, { 1, 1, 1, 1 } }, // psrlq
480 { ISD::SRA, MVT::v8i64, { 1, 1, 1, 1 } }, // psraq
481
482 { ISD::SDIV, MVT::v16i32, { 6 } }, // pmuludq sequence
483 { ISD::SREM, MVT::v16i32, { 8 } }, // pmuludq+mul+sub sequence
484 { ISD::UDIV, MVT::v16i32, { 5 } }, // pmuludq sequence
485 { ISD::UREM, MVT::v16i32, { 7 } }, // pmuludq+mul+sub sequence
486
487 { ISD::UDIV, MVT::v8i64, { 15 } }, // pmuludq-based MULHU sequence
488 { ISD::UREM, MVT::v8i64, { 21 } }, // pmuludq-based MULHU+mul+sub sequence
489 };
490
491 if (Op2Info.isUniform() && Op2Info.isConstant() && ST->hasAVX512())
492 if (const auto *Entry =
493 CostTableLookup(AVX512UniformConstCostTable, ISD, LT.second))
494 if (auto KindCost = Entry->Cost[CostKind])
495 return LT.first * *KindCost;
496
497 static const CostKindTblEntry AVX2UniformConstCostTable[] = {
498 { ISD::SHL, MVT::v16i8, { 1, 8, 2, 3 } }, // psllw + pand.
499 { ISD::SRL, MVT::v16i8, { 1, 8, 2, 3 } }, // psrlw + pand.
500 { ISD::SRA, MVT::v16i8, { 2, 10, 5, 6 } }, // psrlw, pand, pxor, psubb.
501 { ISD::SHL, MVT::v32i8, { 2, 8, 2, 4 } }, // psllw + pand.
502 { ISD::SRL, MVT::v32i8, { 2, 8, 2, 4 } }, // psrlw + pand.
503 { ISD::SRA, MVT::v32i8, { 3, 10, 5, 9 } }, // psrlw, pand, pxor, psubb.
504
505 { ISD::SHL, MVT::v8i16, { 1, 1, 1, 1 } }, // psllw
506 { ISD::SRL, MVT::v8i16, { 1, 1, 1, 1 } }, // psrlw
507 { ISD::SRA, MVT::v8i16, { 1, 1, 1, 1 } }, // psraw
508 { ISD::SHL, MVT::v16i16,{ 2, 2, 1, 2 } }, // psllw
509 { ISD::SRL, MVT::v16i16,{ 2, 2, 1, 2 } }, // psrlw
510 { ISD::SRA, MVT::v16i16,{ 2, 2, 1, 2 } }, // psraw
511
512 { ISD::SHL, MVT::v4i32, { 1, 1, 1, 1 } }, // pslld
513 { ISD::SRL, MVT::v4i32, { 1, 1, 1, 1 } }, // psrld
514 { ISD::SRA, MVT::v4i32, { 1, 1, 1, 1 } }, // psrad
515 { ISD::SHL, MVT::v8i32, { 2, 2, 1, 2 } }, // pslld
516 { ISD::SRL, MVT::v8i32, { 2, 2, 1, 2 } }, // psrld
517 { ISD::SRA, MVT::v8i32, { 2, 2, 1, 2 } }, // psrad
518
519 { ISD::SHL, MVT::v2i64, { 1, 1, 1, 1 } }, // psllq
520 { ISD::SRL, MVT::v2i64, { 1, 1, 1, 1 } }, // psrlq
521 { ISD::SRA, MVT::v2i64, { 2, 3, 3, 3 } }, // psrad + shuffle.
522 { ISD::SHL, MVT::v4i64, { 2, 2, 1, 2 } }, // psllq
523 { ISD::SRL, MVT::v4i64, { 2, 2, 1, 2 } }, // psrlq
524 { ISD::SRA, MVT::v4i64, { 4, 4, 3, 6 } }, // psrad + shuffle + split.
525
526 { ISD::SDIV, MVT::v8i32, { 6 } }, // pmuludq sequence
527 { ISD::SREM, MVT::v8i32, { 8 } }, // pmuludq+mul+sub sequence
528 { ISD::UDIV, MVT::v8i32, { 5 } }, // pmuludq sequence
529 { ISD::UREM, MVT::v8i32, { 7 } }, // pmuludq+mul+sub sequence
530
531 { ISD::UDIV, MVT::v4i64, { 15 } }, // pmuludq-based MULHU sequence
532 { ISD::UREM, MVT::v4i64, { 21 } }, // pmuludq-based MULHU+mul+sub sequence
533 };
534
535 if (Op2Info.isUniform() && Op2Info.isConstant() && ST->hasAVX2())
536 if (const auto *Entry =
537 CostTableLookup(AVX2UniformConstCostTable, ISD, LT.second))
538 if (auto KindCost = Entry->Cost[CostKind])
539 return LT.first * *KindCost;
540
541 static const CostKindTblEntry AVXUniformConstCostTable[] = {
542 { ISD::SHL, MVT::v16i8, { 2, 7, 2, 3 } }, // psllw + pand.
543 { ISD::SRL, MVT::v16i8, { 2, 7, 2, 3 } }, // psrlw + pand.
544 { ISD::SRA, MVT::v16i8, { 3, 9, 5, 6 } }, // psrlw, pand, pxor, psubb.
545 { ISD::SHL, MVT::v32i8, { 4, 7, 7, 8 } }, // 2*(psllw + pand) + split.
546 { ISD::SRL, MVT::v32i8, { 4, 7, 7, 8 } }, // 2*(psrlw + pand) + split.
547 { ISD::SRA, MVT::v32i8, { 7, 7, 12, 13 } }, // 2*(psrlw, pand, pxor, psubb) + split.
548
549 { ISD::SHL, MVT::v8i16, { 1, 2, 1, 1 } }, // psllw.
550 { ISD::SRL, MVT::v8i16, { 1, 2, 1, 1 } }, // psrlw.
551 { ISD::SRA, MVT::v8i16, { 1, 2, 1, 1 } }, // psraw.
552 { ISD::SHL, MVT::v16i16,{ 3, 6, 4, 5 } }, // psllw + split.
553 { ISD::SRL, MVT::v16i16,{ 3, 6, 4, 5 } }, // psrlw + split.
554 { ISD::SRA, MVT::v16i16,{ 3, 6, 4, 5 } }, // psraw + split.
555
556 { ISD::SHL, MVT::v4i32, { 1, 2, 1, 1 } }, // pslld.
557 { ISD::SRL, MVT::v4i32, { 1, 2, 1, 1 } }, // psrld.
558 { ISD::SRA, MVT::v4i32, { 1, 2, 1, 1 } }, // psrad.
559 { ISD::SHL, MVT::v8i32, { 3, 6, 4, 5 } }, // pslld + split.
560 { ISD::SRL, MVT::v8i32, { 3, 6, 4, 5 } }, // psrld + split.
561 { ISD::SRA, MVT::v8i32, { 3, 6, 4, 5 } }, // psrad + split.
562
563 { ISD::SHL, MVT::v2i64, { 1, 2, 1, 1 } }, // psllq.
564 { ISD::SRL, MVT::v2i64, { 1, 2, 1, 1 } }, // psrlq.
565 { ISD::SRA, MVT::v2i64, { 2, 3, 3, 3 } }, // psrad + shuffle.
566 { ISD::SHL, MVT::v4i64, { 3, 6, 4, 5 } }, // 2 x psllq + split.
567 { ISD::SRL, MVT::v4i64, { 3, 6, 4, 5 } }, // 2 x psllq + split.
568 { ISD::SRA, MVT::v4i64, { 5, 7, 8, 9 } }, // 2 x psrad + shuffle + split.
569
570 { ISD::SDIV, MVT::v8i32, { 14 } }, // 2*pmuludq sequence + split.
571 { ISD::SREM, MVT::v8i32, { 18 } }, // 2*pmuludq+mul+sub sequence + split.
572 { ISD::UDIV, MVT::v8i32, { 12 } }, // 2*pmuludq sequence + split.
573 { ISD::UREM, MVT::v8i32, { 16 } }, // 2*pmuludq+mul+sub sequence + split.
574 };
575
576 // XOP has faster vXi8 shifts.
577 if (Op2Info.isUniform() && Op2Info.isConstant() && ST->hasAVX() &&
578 (!ST->hasXOP() || LT.second.getScalarSizeInBits() != 8))
579 if (const auto *Entry =
580 CostTableLookup(AVXUniformConstCostTable, ISD, LT.second))
581 if (auto KindCost = Entry->Cost[CostKind])
582 return LT.first * *KindCost;
583
584 static const CostKindTblEntry SSE2UniformConstCostTable[] = {
585 { ISD::SHL, MVT::v16i8, { 1, 7, 2, 3 } }, // psllw + pand.
586 { ISD::SRL, MVT::v16i8, { 1, 7, 2, 3 } }, // psrlw + pand.
587 { ISD::SRA, MVT::v16i8, { 3, 9, 5, 6 } }, // psrlw, pand, pxor, psubb.
588
589 { ISD::SHL, MVT::v8i16, { 1, 1, 1, 1 } }, // psllw.
590 { ISD::SRL, MVT::v8i16, { 1, 1, 1, 1 } }, // psrlw.
591 { ISD::SRA, MVT::v8i16, { 1, 1, 1, 1 } }, // psraw.
592
593 { ISD::SHL, MVT::v4i32, { 1, 1, 1, 1 } }, // pslld
594 { ISD::SRL, MVT::v4i32, { 1, 1, 1, 1 } }, // psrld.
595 { ISD::SRA, MVT::v4i32, { 1, 1, 1, 1 } }, // psrad.
596
597 { ISD::SHL, MVT::v2i64, { 1, 1, 1, 1 } }, // psllq.
598 { ISD::SRL, MVT::v2i64, { 1, 1, 1, 1 } }, // psrlq.
599 { ISD::SRA, MVT::v2i64, { 3, 5, 6, 6 } }, // 2 x psrad + shuffle.
600
601 { ISD::SDIV, MVT::v4i32, { 6 } }, // pmuludq sequence
602 { ISD::SREM, MVT::v4i32, { 8 } }, // pmuludq+mul+sub sequence
603 { ISD::UDIV, MVT::v4i32, { 5 } }, // pmuludq sequence
604 { ISD::UREM, MVT::v4i32, { 7 } }, // pmuludq+mul+sub sequence
605 };
606
607 // XOP has faster vXi8 shifts.
608 if (Op2Info.isUniform() && Op2Info.isConstant() && ST->hasSSE2() &&
609 (!ST->hasXOP() || LT.second.getScalarSizeInBits() != 8))
610 if (const auto *Entry =
611 CostTableLookup(SSE2UniformConstCostTable, ISD, LT.second))
612 if (auto KindCost = Entry->Cost[CostKind])
613 return LT.first * *KindCost;
614
615 static const CostKindTblEntry AVX512BWConstCostTable[] = {
616 { ISD::SDIV, MVT::v64i8, { 14 } }, // 2*ext+2*pmulhw sequence
617 { ISD::SREM, MVT::v64i8, { 16 } }, // 2*ext+2*pmulhw+mul+sub sequence
618 { ISD::UDIV, MVT::v64i8, { 14 } }, // 2*ext+2*pmulhw sequence
619 { ISD::UREM, MVT::v64i8, { 16 } }, // 2*ext+2*pmulhw+mul+sub sequence
620
621 { ISD::SDIV, MVT::v32i16, { 6 } }, // vpmulhw sequence
622 { ISD::SREM, MVT::v32i16, { 8 } }, // vpmulhw+mul+sub sequence
623 { ISD::UDIV, MVT::v32i16, { 6 } }, // vpmulhuw sequence
624 { ISD::UREM, MVT::v32i16, { 8 } }, // vpmulhuw+mul+sub sequence
625 };
626
627 if (Op2Info.isConstant() && ST->hasBWI())
628 if (const auto *Entry =
629 CostTableLookup(AVX512BWConstCostTable, ISD, LT.second))
630 if (auto KindCost = Entry->Cost[CostKind])
631 return LT.first * *KindCost;
632
633 static const CostKindTblEntry AVX512DQConstCostTable[] = {
634 { ISD::SDIV, MVT::v4i64, { 19 } }, // vpmullq-based MULHS sequence
635 { ISD::SREM, MVT::v4i64, { 21 } }, // vpmullq-based MULHS+mul+sub sequence
636 { ISD::SDIV, MVT::v8i64, { 19 } }, // vpmullq-based MULHS sequence
637 { ISD::SREM, MVT::v8i64, { 21 } }, // vpmullq-based MULHS+mul+sub sequence
638 // The remainder's multiply-back is a single vpmullq with DQ, whereas the
639 // AVX512/AVX2 tables have to charge for another vpmuludq schoolbook.
640 { ISD::UREM, MVT::v4i64, { 24 } }, // MULHU + vpmullq + sub sequence
641 { ISD::UREM, MVT::v8i64, { 24 } }, // MULHU + vpmullq + sub sequence
642 };
643
644 if (Op2Info.isConstant() && ST->hasDQI())
645 if (const auto *Entry =
646 CostTableLookup(AVX512DQConstCostTable, ISD, LT.second))
647 if (auto KindCost = Entry->Cost[CostKind])
648 return LT.first * *KindCost;
649
650 static const CostKindTblEntry AVX512ConstCostTable[] = {
651 { ISD::SDIV, MVT::v64i8, { 28 } }, // 4*ext+4*pmulhw sequence
652 { ISD::SREM, MVT::v64i8, { 32 } }, // 4*ext+4*pmulhw+mul+sub sequence
653 { ISD::UDIV, MVT::v64i8, { 28 } }, // 4*ext+4*pmulhw sequence
654 { ISD::UREM, MVT::v64i8, { 32 } }, // 4*ext+4*pmulhw+mul+sub sequence
655
656 { ISD::SDIV, MVT::v32i16, { 12 } }, // 2*vpmulhw sequence
657 { ISD::SREM, MVT::v32i16, { 16 } }, // 2*vpmulhw+mul+sub sequence
658 { ISD::UDIV, MVT::v32i16, { 12 } }, // 2*vpmulhuw sequence
659 { ISD::UREM, MVT::v32i16, { 16 } }, // 2*vpmulhuw+mul+sub sequence
660
661 { ISD::SDIV, MVT::v16i32, { 15 } }, // vpmuldq sequence
662 { ISD::SREM, MVT::v16i32, { 17 } }, // vpmuldq+mul+sub sequence
663 { ISD::UDIV, MVT::v16i32, { 15 } }, // vpmuludq sequence
664 { ISD::UREM, MVT::v16i32, { 17 } }, // vpmuludq+mul+sub sequence
665
666 { ISD::UDIV, MVT::v8i64, { 22 } }, // vpmuludq-based MULHU sequence
667 { ISD::UREM, MVT::v8i64, { 28 } }, // vpmuludq-based MULHU+mul+sub sequence
668 };
669
670 if (Op2Info.isConstant() && ST->hasAVX512())
671 if (const auto *Entry =
672 CostTableLookup(AVX512ConstCostTable, ISD, LT.second))
673 if (auto KindCost = Entry->Cost[CostKind])
674 return LT.first * *KindCost;
675
676 static const CostKindTblEntry AVX2ConstCostTable[] = {
677 { ISD::SDIV, MVT::v32i8, { 14 } }, // 2*ext+2*pmulhw sequence
678 { ISD::SREM, MVT::v32i8, { 16 } }, // 2*ext+2*pmulhw+mul+sub sequence
679 { ISD::UDIV, MVT::v32i8, { 14 } }, // 2*ext+2*pmulhw sequence
680 { ISD::UREM, MVT::v32i8, { 16 } }, // 2*ext+2*pmulhw+mul+sub sequence
681
682 { ISD::SDIV, MVT::v16i16, { 6 } }, // vpmulhw sequence
683 { ISD::SREM, MVT::v16i16, { 8 } }, // vpmulhw+mul+sub sequence
684 { ISD::UDIV, MVT::v16i16, { 6 } }, // vpmulhuw sequence
685 { ISD::UREM, MVT::v16i16, { 8 } }, // vpmulhuw+mul+sub sequence
686
687 { ISD::SDIV, MVT::v8i32, { 15 } }, // vpmuldq sequence
688 { ISD::SREM, MVT::v8i32, { 19 } }, // vpmuldq+mul+sub sequence
689 { ISD::UDIV, MVT::v8i32, { 15 } }, // vpmuludq sequence
690 { ISD::UREM, MVT::v8i32, { 19 } }, // vpmuludq+mul+sub sequence
691
692 { ISD::UDIV, MVT::v4i64, { 22 } }, // vpmuludq-based MULHU sequence
693 { ISD::UREM, MVT::v4i64, { 28 } }, // vpmuludq-based MULHU+mul+sub sequence
694 };
695
696 if (Op2Info.isConstant() && ST->hasAVX2())
697 if (const auto *Entry = CostTableLookup(AVX2ConstCostTable, ISD, LT.second))
698 if (auto KindCost = Entry->Cost[CostKind])
699 return LT.first * *KindCost;
700
701 static const CostKindTblEntry AVXConstCostTable[] = {
702 { ISD::SDIV, MVT::v32i8, { 30 } }, // 4*ext+4*pmulhw sequence + split.
703 { ISD::SREM, MVT::v32i8, { 34 } }, // 4*ext+4*pmulhw+mul+sub sequence + split.
704 { ISD::UDIV, MVT::v32i8, { 30 } }, // 4*ext+4*pmulhw sequence + split.
705 { ISD::UREM, MVT::v32i8, { 34 } }, // 4*ext+4*pmulhw+mul+sub sequence + split.
706
707 { ISD::SDIV, MVT::v16i16, { 14 } }, // 2*pmulhw sequence + split.
708 { ISD::SREM, MVT::v16i16, { 18 } }, // 2*pmulhw+mul+sub sequence + split.
709 { ISD::UDIV, MVT::v16i16, { 14 } }, // 2*pmulhuw sequence + split.
710 { ISD::UREM, MVT::v16i16, { 18 } }, // 2*pmulhuw+mul+sub sequence + split.
711
712 { ISD::SDIV, MVT::v8i32, { 32 } }, // vpmuludq sequence
713 { ISD::SREM, MVT::v8i32, { 38 } }, // vpmuludq+mul+sub sequence
714 { ISD::UDIV, MVT::v8i32, { 32 } }, // 2*pmuludq sequence + split.
715 { ISD::UREM, MVT::v8i32, { 42 } }, // 2*pmuludq+mul+sub sequence + split.
716 };
717
718 if (Op2Info.isConstant() && ST->hasAVX())
719 if (const auto *Entry = CostTableLookup(AVXConstCostTable, ISD, LT.second))
720 if (auto KindCost = Entry->Cost[CostKind])
721 return LT.first * *KindCost;
722
723 static const CostKindTblEntry SSE41ConstCostTable[] = {
724 { ISD::SDIV, MVT::v4i32, { 15 } }, // vpmuludq sequence
725 { ISD::SREM, MVT::v4i32, { 20 } }, // vpmuludq+mul+sub sequence
726 };
727
728 if (Op2Info.isConstant() && ST->hasSSE41())
729 if (const auto *Entry =
730 CostTableLookup(SSE41ConstCostTable, ISD, LT.second))
731 if (auto KindCost = Entry->Cost[CostKind])
732 return LT.first * *KindCost;
733
734 static const CostKindTblEntry SSE2ConstCostTable[] = {
735 { ISD::SDIV, MVT::v16i8, { 14 } }, // 2*ext+2*pmulhw sequence
736 { ISD::SREM, MVT::v16i8, { 16 } }, // 2*ext+2*pmulhw+mul+sub sequence
737 { ISD::UDIV, MVT::v16i8, { 14 } }, // 2*ext+2*pmulhw sequence
738 { ISD::UREM, MVT::v16i8, { 16 } }, // 2*ext+2*pmulhw+mul+sub sequence
739
740 { ISD::SDIV, MVT::v8i16, { 6 } }, // pmulhw sequence
741 { ISD::SREM, MVT::v8i16, { 8 } }, // pmulhw+mul+sub sequence
742 { ISD::UDIV, MVT::v8i16, { 6 } }, // pmulhuw sequence
743 { ISD::UREM, MVT::v8i16, { 8 } }, // pmulhuw+mul+sub sequence
744
745 { ISD::SDIV, MVT::v4i32, { 19 } }, // pmuludq sequence
746 { ISD::SREM, MVT::v4i32, { 24 } }, // pmuludq+mul+sub sequence
747 { ISD::UDIV, MVT::v4i32, { 15 } }, // pmuludq sequence
748 { ISD::UREM, MVT::v4i32, { 20 } }, // pmuludq+mul+sub sequence
749 };
750
751 if (Op2Info.isConstant() && ST->hasSSE2())
752 if (const auto *Entry = CostTableLookup(SSE2ConstCostTable, ISD, LT.second))
753 if (auto KindCost = Entry->Cost[CostKind])
754 return LT.first * *KindCost;
755
756 // rem matches div because the divider returns the remainder for free.
757 static const CostKindTblEntry ScalarVarDivCostTable[] = {
758 { ISD::SDIV, MVT::i8, { 15, 20, 2, 4 } },
759 { ISD::UDIV, MVT::i8, { 15, 20, 2, 4 } },
760 { ISD::SREM, MVT::i8, { 15, 20, 2, 4 } },
761 { ISD::UREM, MVT::i8, { 15, 20, 2, 4 } },
762 { ISD::SDIV, MVT::i16, { 17, 20, 2, 4 } },
763 { ISD::UDIV, MVT::i16, { 17, 20, 2, 4 } },
764 { ISD::SREM, MVT::i16, { 17, 20, 2, 4 } },
765 { ISD::UREM, MVT::i16, { 17, 20, 2, 4 } },
766 { ISD::SDIV, MVT::i32, { 25, 22, 2, 4 } },
767 { ISD::UDIV, MVT::i32, { 25, 22, 2, 4 } },
768 { ISD::SREM, MVT::i32, { 25, 22, 2, 4 } },
769 { ISD::UREM, MVT::i32, { 25, 22, 2, 4 } },
770 { ISD::SDIV, MVT::i64, { 41, 24, 2, 4 } },
771 { ISD::UDIV, MVT::i64, { 41, 24, 2, 4 } },
772 { ISD::SREM, MVT::i64, { 41, 24, 2, 4 } },
773 { ISD::UREM, MVT::i64, { 41, 24, 2, 4 } },
774 };
775
776 if (!LT.second.isVector() && !Op2Info.isConstant())
777 if (const auto *Entry =
778 CostTableLookup(ScalarVarDivCostTable, ISD, LT.second))
779 if (auto KindCost = Entry->Cost[CostKind])
780 return LT.first * *KindCost;
781
782 // Variable divisors lower through a float divide. strictfp needs SAE
783 // rounding which is 512-bit only.
784 bool IsStrictFP =
785 CxtI && CxtI->getFunction()->hasFnAttribute(Attribute::StrictFP);
786 bool IsDivRem = ISD == ISD::UDIV || ISD == ISD::SDIV || ISD == ISD::UREM ||
787 ISD == ISD::SREM;
788 bool VarDivToFP = IsDivRem && !Op2Info.isConstant() &&
789 (!IsStrictFP || ST->useAVX512Regs());
790
791 // i64 needs the qq converts, which are AVX512DQ only. Two tables because the
792 // lowering picks by operand value and not by type.
793 static const CostKindTblEntry AVX512DQExactVarDivCostTable[] = {
794 { ISD::UDIV, MVT::v2i64, { 5 } }, // cvt+divpd sequence
795 { ISD::SDIV, MVT::v2i64, { 5 } },
796 { ISD::UREM, MVT::v2i64, { 5 } },
797 { ISD::SREM, MVT::v2i64, { 5 } },
798 { ISD::UDIV, MVT::v4i64, { 8 } },
799 { ISD::SDIV, MVT::v4i64, { 8 } },
800 { ISD::UREM, MVT::v4i64, { 8 } },
801 { ISD::SREM, MVT::v4i64, { 8 } },
802 { ISD::UDIV, MVT::v8i64, { 16 } },
803 { ISD::SDIV, MVT::v8i64, { 16 } },
804 { ISD::UREM, MVT::v8i64, { 16 } },
805 { ISD::SREM, MVT::v8i64, { 16 } },
806 };
807
808 static const CostKindTblEntry AVX512DQVarDivCostTable[] = {
809 { ISD::UDIV, MVT::v2i64, { 16 } },
810 { ISD::SDIV, MVT::v2i64, { 16 } },
811 { ISD::UREM, MVT::v2i64, { 16 } },
812 { ISD::SREM, MVT::v2i64, { 16 } },
813 { ISD::UDIV, MVT::v4i64, { 16 } },
814 { ISD::SDIV, MVT::v4i64, { 16 } },
815 { ISD::UREM, MVT::v4i64, { 16 } },
816 { ISD::SREM, MVT::v4i64, { 16 } },
817 { ISD::UDIV, MVT::v8i64, { 16 } },
818 { ISD::SDIV, MVT::v8i64, { 18 } },
819 { ISD::UREM, MVT::v8i64, { 16 } },
820 { ISD::SREM, MVT::v8i64, { 18 } },
821 };
822
823 // The DAG combine picks between the two sequences with these same two
824 // queries, so the cost cannot disagree with what codegen emits.
825 bool IsSignedDiv = ISD == ISD::SDIV || ISD == ISD::SREM;
826 auto OperandsFit = [&](unsigned Mantissa) {
827 if (Args.size() != 2 || !CxtI)
828 return false;
829 unsigned EltBits = LT.second.getScalarSizeInBits();
830 const DataLayout &DL = CxtI->getDataLayout();
831 auto Fits = [&](const Value *V) {
832 if (IsSignedDiv)
833 return ComputeNumSignBits(V, DL, /*AC=*/nullptr, CxtI) + Mantissa >
834 EltBits;
835 return computeKnownBits(V, DL, /*AC=*/nullptr, CxtI)
836 .countMaxActiveBits() <= Mantissa;
837 };
838 return Fits(Args[0]) && Fits(Args[1]);
839 };
840
841 // An i32 divide goes through f32 when both operands fit in 24 bits, and
842 // through f64 at twice the vector width when they do not.
843 bool ExactI32 =
844 VarDivToFP && LT.second.getScalarType() == MVT::i32 &&
846
847 if (VarDivToFP && ST->hasDQI() && ST->useAVX512Regs() &&
848 LT.second.getScalarType() == MVT::i64) {
849 bool ExactFPDiv =
851
852 // Only the reciprocal chain multiplies, so only it is vpmullq gated.
853 bool SlowMultiply =
854 !ExactFPDiv && LT.second == MVT::v2i64 && ST->isPMULLQSlow();
855
856 if (!SlowMultiply) {
858 ExactFPDiv ? AVX512DQExactVarDivCostTable : AVX512DQVarDivCostTable;
859 if (const auto *Entry = CostTableLookup(Tbl, ISD, LT.second))
860 if (auto KindCost = Entry->Cost[CostKind])
861 return LT.first * *KindCost;
862 }
863 }
864
865 static const CostKindTblEntry AVX512BWVarDivCostTable[] = {
866 { ISD::UDIV, MVT::v16i8, { 10 } }, // unpack+cvt+divps sequence
867 { ISD::SDIV, MVT::v16i8, { 10 } },
868 { ISD::UREM, MVT::v16i8, { 10 } },
869 { ISD::SREM, MVT::v16i8, { 10 } },
870 { ISD::UDIV, MVT::v32i8, { 20 } },
871 { ISD::SDIV, MVT::v32i8, { 20 } },
872 { ISD::UREM, MVT::v32i8, { 20 } },
873 { ISD::SREM, MVT::v32i8, { 20 } },
874 { ISD::UDIV, MVT::v64i8, { 40 } },
875 { ISD::SDIV, MVT::v64i8, { 40 } },
876 { ISD::UREM, MVT::v64i8, { 40 } },
877 { ISD::SREM, MVT::v64i8, { 40 } },
878 { ISD::UDIV, MVT::v8i16, { 5 } },
879 { ISD::SDIV, MVT::v8i16, { 5 } },
880 { ISD::UREM, MVT::v8i16, { 5 } },
881 { ISD::SREM, MVT::v8i16, { 5 } },
882 { ISD::UDIV, MVT::v16i16, { 10 } },
883 { ISD::SDIV, MVT::v16i16, { 10 } },
884 { ISD::UREM, MVT::v16i16, { 10 } },
885 { ISD::SREM, MVT::v16i16, { 10 } },
886 { ISD::UDIV, MVT::v32i16, { 20 } },
887 { ISD::SDIV, MVT::v32i16, { 20 } },
888 { ISD::UREM, MVT::v32i16, { 20 } },
889 { ISD::SREM, MVT::v32i16, { 20 } },
890 { ISD::UDIV, MVT::v4i32, { 8 } }, // cvt+divpd sequence
891 { ISD::SDIV, MVT::v4i32, { 8 } },
892 { ISD::UREM, MVT::v4i32, { 8 } },
893 { ISD::SREM, MVT::v4i32, { 8 } },
894 { ISD::UDIV, MVT::v8i32, { 16 } },
895 { ISD::SDIV, MVT::v8i32, { 16 } },
896 { ISD::UREM, MVT::v8i32, { 16 } },
897 { ISD::SREM, MVT::v8i32, { 16 } },
898 { ISD::UDIV, MVT::v16i32, { 32 } },
899 { ISD::SDIV, MVT::v16i32, { 32 } },
900 { ISD::UREM, MVT::v16i32, { 32 } },
901 { ISD::SREM, MVT::v16i32, { 32 } },
902 };
903
904 static const CostKindTblEntry AVX512BWExactVarDivCostTable[] = {
905 { ISD::UDIV, MVT::v4i32, { 3 } }, // cvt+divps sequence
906 { ISD::SDIV, MVT::v4i32, { 3 } },
907 { ISD::UREM, MVT::v4i32, { 3 } },
908 { ISD::SREM, MVT::v4i32, { 3 } },
909 { ISD::UDIV, MVT::v8i32, { 5 } },
910 { ISD::SDIV, MVT::v8i32, { 5 } },
911 { ISD::UREM, MVT::v8i32, { 5 } },
912 { ISD::SREM, MVT::v8i32, { 5 } },
913 { ISD::UDIV, MVT::v16i32, { 10 } },
914 { ISD::SDIV, MVT::v16i32, { 10 } },
915 { ISD::UREM, MVT::v16i32, { 10 } },
916 { ISD::SREM, MVT::v16i32, { 10 } },
917 };
918
919 if (VarDivToFP && ST->hasBWI()) {
920 ArrayRef<CostKindTblEntry> Tbl = AVX512BWVarDivCostTable;
921 if (ExactI32)
922 Tbl = AVX512BWExactVarDivCostTable;
923 if (const auto *Entry = CostTableLookup(Tbl, ISD, LT.second))
924 if (auto KindCost = Entry->Cost[CostKind])
925 return LT.first * *KindCost;
926 }
927
928 static const CostKindTblEntry AVX512VarDivCostTable[] = {
929 { ISD::UDIV, MVT::v16i8, { 14 } }, // unpack+cvt+divps sequence
930 { ISD::SDIV, MVT::v16i8, { 14 } },
931 { ISD::UREM, MVT::v16i8, { 14 } },
932 { ISD::SREM, MVT::v16i8, { 14 } },
933 { ISD::UDIV, MVT::v32i8, { 28 } },
934 { ISD::SDIV, MVT::v32i8, { 28 } },
935 { ISD::UREM, MVT::v32i8, { 28 } },
936 { ISD::SREM, MVT::v32i8, { 28 } },
937 { ISD::UDIV, MVT::v64i8, { 56 } },
938 { ISD::SDIV, MVT::v64i8, { 56 } },
939 { ISD::UREM, MVT::v64i8, { 56 } },
940 { ISD::SREM, MVT::v64i8, { 56 } },
941 { ISD::UDIV, MVT::v8i16, { 14 } },
942 { ISD::SDIV, MVT::v8i16, { 14 } },
943 { ISD::UREM, MVT::v8i16, { 14 } },
944 { ISD::SREM, MVT::v8i16, { 14 } },
945 { ISD::UDIV, MVT::v16i16, { 14 } },
946 { ISD::SDIV, MVT::v16i16, { 14 } },
947 { ISD::UREM, MVT::v16i16, { 14 } },
948 { ISD::SREM, MVT::v16i16, { 14 } },
949 { ISD::UDIV, MVT::v32i16, { 28 } },
950 { ISD::SDIV, MVT::v32i16, { 28 } },
951 { ISD::UREM, MVT::v32i16, { 28 } },
952 { ISD::SREM, MVT::v32i16, { 28 } },
953 { ISD::UDIV, MVT::v4i32, { 28 } }, // cvt+divpd sequence
954 { ISD::SDIV, MVT::v4i32, { 28 } },
955 { ISD::UREM, MVT::v4i32, { 28 } },
956 { ISD::SREM, MVT::v4i32, { 28 } },
957 { ISD::UDIV, MVT::v8i32, { 28 } },
958 { ISD::SDIV, MVT::v8i32, { 28 } },
959 { ISD::UREM, MVT::v8i32, { 28 } },
960 { ISD::SREM, MVT::v8i32, { 28 } },
961 { ISD::UDIV, MVT::v16i32, { 56 } },
962 { ISD::SDIV, MVT::v16i32, { 56 } },
963 { ISD::UREM, MVT::v16i32, { 56 } },
964 { ISD::SREM, MVT::v16i32, { 56 } },
965 };
966
967 static const CostKindTblEntry AVX512ExactVarDivCostTable[] = {
968 { ISD::UDIV, MVT::v4i32, { 7 } }, // cvt+divps sequence
969 { ISD::SDIV, MVT::v4i32, { 7 } },
970 { ISD::UREM, MVT::v4i32, { 7 } },
971 { ISD::SREM, MVT::v4i32, { 7 } },
972 { ISD::UDIV, MVT::v8i32, { 14 } },
973 { ISD::SDIV, MVT::v8i32, { 14 } },
974 { ISD::UREM, MVT::v8i32, { 14 } },
975 { ISD::SREM, MVT::v8i32, { 14 } },
976 { ISD::UDIV, MVT::v16i32, { 14 } },
977 { ISD::SDIV, MVT::v16i32, { 14 } },
978 { ISD::UREM, MVT::v16i32, { 14 } },
979 { ISD::SREM, MVT::v16i32, { 14 } },
980 };
981
982 if (VarDivToFP && ST->hasAVX512()) {
983 ArrayRef<CostKindTblEntry> Tbl = AVX512VarDivCostTable;
984 if (ExactI32)
985 Tbl = AVX512ExactVarDivCostTable;
986 if (const auto *Entry = CostTableLookup(Tbl, ISD, LT.second))
987 if (auto KindCost = Entry->Cost[CostKind])
988 return LT.first * *KindCost;
989 }
990
991 static const CostKindTblEntry AVX2VarDivCostTable[] = {
992 { ISD::UDIV, MVT::v16i8, { 28 } }, // unpack+cvt+divps sequence
993 { ISD::SDIV, MVT::v16i8, { 28 } },
994 { ISD::UREM, MVT::v16i8, { 28 } },
995 { ISD::SREM, MVT::v16i8, { 28 } },
996 { ISD::UDIV, MVT::v32i8, { 56 } },
997 { ISD::SDIV, MVT::v32i8, { 56 } },
998 { ISD::UREM, MVT::v32i8, { 56 } },
999 { ISD::SREM, MVT::v32i8, { 56 } },
1000 { ISD::UDIV, MVT::v8i16, { 14 } },
1001 { ISD::SDIV, MVT::v8i16, { 14 } },
1002 { ISD::UREM, MVT::v8i16, { 14 } },
1003 { ISD::SREM, MVT::v8i16, { 14 } },
1004 { ISD::UDIV, MVT::v16i16, { 28 } },
1005 { ISD::SDIV, MVT::v16i16, { 28 } },
1006 { ISD::UREM, MVT::v16i16, { 28 } },
1007 { ISD::SREM, MVT::v16i16, { 28 } },
1008 { ISD::UDIV, MVT::v4i32, { 28 } }, // cvt+divpd sequence
1009 { ISD::SDIV, MVT::v4i32, { 28 } },
1010 { ISD::UREM, MVT::v4i32, { 28 } },
1011 { ISD::SREM, MVT::v4i32, { 28 } },
1012 { ISD::UDIV, MVT::v8i32, { 56 } },
1013 { ISD::SDIV, MVT::v8i32, { 56 } },
1014 { ISD::UREM, MVT::v8i32, { 56 } },
1015 { ISD::SREM, MVT::v8i32, { 56 } },
1016 };
1017
1018 static const CostKindTblEntry AVX2ExactVarDivCostTable[] = {
1019 { ISD::UDIV, MVT::v4i32, { 9 } }, // cvt+divps sequence
1020 { ISD::SDIV, MVT::v4i32, { 8 } },
1021 { ISD::UREM, MVT::v4i32, { 9 } },
1022 { ISD::SREM, MVT::v4i32, { 8 } },
1023 { ISD::UDIV, MVT::v8i32, { 14 } },
1024 { ISD::SDIV, MVT::v8i32, { 14 } },
1025 { ISD::UREM, MVT::v8i32, { 14 } },
1026 { ISD::SREM, MVT::v8i32, { 14 } },
1027 };
1028
1029 if (VarDivToFP && ST->hasAVX2()) {
1030 ArrayRef<CostKindTblEntry> Tbl = AVX2VarDivCostTable;
1031 if (ExactI32)
1032 Tbl = AVX2ExactVarDivCostTable;
1033 if (const auto *Entry = CostTableLookup(Tbl, ISD, LT.second))
1034 if (auto KindCost = Entry->Cost[CostKind])
1035 return LT.first * *KindCost;
1036 }
1037
1038 // No unsigned i32 entries below AVX2, where the u32 to f64 converts are
1039 // emulated and the fold stays off.
1040 static const CostKindTblEntry AVX1VarDivCostTable[] = {
1041 { ISD::UDIV, MVT::v16i8, { 56 } }, // unpack+cvt+divps sequence
1042 { ISD::SDIV, MVT::v16i8, { 56 } },
1043 { ISD::UREM, MVT::v16i8, { 56 } },
1044 { ISD::SREM, MVT::v16i8, { 56 } },
1045 { ISD::UDIV, MVT::v32i8, { 112 } },
1046 { ISD::SDIV, MVT::v32i8, { 112 } },
1047 { ISD::UREM, MVT::v32i8, { 112 } },
1048 { ISD::SREM, MVT::v32i8, { 112 } },
1049 { ISD::UDIV, MVT::v8i16, { 28 } },
1050 { ISD::SDIV, MVT::v8i16, { 28 } },
1051 { ISD::UREM, MVT::v8i16, { 28 } },
1052 { ISD::SREM, MVT::v8i16, { 28 } },
1053 { ISD::UDIV, MVT::v16i16, { 56 } },
1054 { ISD::SDIV, MVT::v16i16, { 56 } },
1055 { ISD::UREM, MVT::v16i16, { 56 } },
1056 { ISD::SREM, MVT::v16i16, { 56 } },
1057 { ISD::SDIV, MVT::v4i32, { 44 } }, // cvt+divpd sequence
1058 { ISD::SREM, MVT::v4i32, { 44 } },
1059 { ISD::SDIV, MVT::v8i32, { 88 } },
1060 { ISD::SREM, MVT::v8i32, { 88 } },
1061 };
1062
1063 static const CostKindTblEntry AVX1ExactVarDivCostTable[] = {
1064 { ISD::SDIV, MVT::v4i32, { 14 } }, // cvt+divps sequence
1065 { ISD::SREM, MVT::v4i32, { 14 } },
1066 { ISD::SDIV, MVT::v8i32, { 28 } },
1067 { ISD::SREM, MVT::v8i32, { 28 } },
1068 };
1069
1070 if (VarDivToFP && ST->hasAVX()) {
1071 ArrayRef<CostKindTblEntry> Tbl = AVX1VarDivCostTable;
1072 if (ExactI32)
1073 Tbl = AVX1ExactVarDivCostTable;
1074 if (const auto *Entry = CostTableLookup(Tbl, ISD, LT.second))
1075 if (auto KindCost = Entry->Cost[CostKind])
1076 return LT.first * *KindCost;
1077 }
1078
1079 static const CostKindTblEntry SSE2VarDivCostTable[] = {
1080 { ISD::UDIV, MVT::v16i8, { 56 } }, // unpack+cvt+divps sequence
1081 { ISD::SDIV, MVT::v16i8, { 56 } },
1082 { ISD::UREM, MVT::v16i8, { 56 } },
1083 { ISD::SREM, MVT::v16i8, { 56 } },
1084 { ISD::UDIV, MVT::v8i16, { 28 } },
1085 { ISD::SDIV, MVT::v8i16, { 28 } },
1086 { ISD::UREM, MVT::v8i16, { 28 } },
1087 { ISD::SREM, MVT::v8i16, { 28 } },
1088 { ISD::SDIV, MVT::v4i32, { 44 } }, // cvt+divpd sequence
1089 { ISD::SREM, MVT::v4i32, { 44 } },
1090 };
1091
1092 static const CostKindTblEntry SSE2ExactVarDivCostTable[] = {
1093 { ISD::SDIV, MVT::v4i32, { 14 } }, // cvt+divps sequence
1094 { ISD::SREM, MVT::v4i32, { 14 } },
1095 };
1096
1097 if (VarDivToFP && ST->hasSSE2()) {
1098 ArrayRef<CostKindTblEntry> Tbl = SSE2VarDivCostTable;
1099 if (ExactI32)
1100 Tbl = SSE2ExactVarDivCostTable;
1101 if (const auto *Entry = CostTableLookup(Tbl, ISD, LT.second))
1102 if (auto KindCost = Entry->Cost[CostKind])
1103 return LT.first * *KindCost;
1104 }
1105
1106 static const CostKindTblEntry AVX512BWUniformCostTable[] = {
1107 { ISD::SHL, MVT::v16i8, { 3, 5, 5, 7 } }, // psllw + pand.
1108 { ISD::SRL, MVT::v16i8, { 3,10, 5, 8 } }, // psrlw + pand.
1109 { ISD::SRA, MVT::v16i8, { 4,12, 8,12 } }, // psrlw, pand, pxor, psubb.
1110 { ISD::SHL, MVT::v32i8, { 4, 7, 6, 8 } }, // psllw + pand.
1111 { ISD::SRL, MVT::v32i8, { 4, 8, 7, 9 } }, // psrlw + pand.
1112 { ISD::SRA, MVT::v32i8, { 5,10,10,13 } }, // psrlw, pand, pxor, psubb.
1113 { ISD::SHL, MVT::v64i8, { 4, 7, 6, 8 } }, // psllw + pand.
1114 { ISD::SRL, MVT::v64i8, { 4, 8, 7,10 } }, // psrlw + pand.
1115 { ISD::SRA, MVT::v64i8, { 5,10,10,15 } }, // psrlw, pand, pxor, psubb.
1116
1117 { ISD::SHL, MVT::v32i16, { 2, 4, 2, 3 } }, // psllw
1118 { ISD::SRL, MVT::v32i16, { 2, 4, 2, 3 } }, // psrlw
1119 { ISD::SRA, MVT::v32i16, { 2, 4, 2, 3 } }, // psrqw
1120 };
1121
1122 if (ST->hasBWI() && Op2Info.isUniform())
1123 if (const auto *Entry =
1124 CostTableLookup(AVX512BWUniformCostTable, ISD, LT.second))
1125 if (auto KindCost = Entry->Cost[CostKind])
1126 return LT.first * *KindCost;
1127
1128 static const CostKindTblEntry AVX512UniformCostTable[] = {
1129 { ISD::SHL, MVT::v32i16, { 5,10, 5, 7 } }, // psllw + split.
1130 { ISD::SRL, MVT::v32i16, { 5,10, 5, 7 } }, // psrlw + split.
1131 { ISD::SRA, MVT::v32i16, { 5,10, 5, 7 } }, // psraw + split.
1132
1133 { ISD::SHL, MVT::v16i32, { 2, 4, 2, 3 } }, // pslld
1134 { ISD::SRL, MVT::v16i32, { 2, 4, 2, 3 } }, // psrld
1135 { ISD::SRA, MVT::v16i32, { 2, 4, 2, 3 } }, // psrad
1136
1137 { ISD::SRA, MVT::v2i64, { 1, 2, 1, 2 } }, // psraq
1138 { ISD::SHL, MVT::v4i64, { 1, 4, 1, 2 } }, // psllq
1139 { ISD::SRL, MVT::v4i64, { 1, 4, 1, 2 } }, // psrlq
1140 { ISD::SRA, MVT::v4i64, { 1, 4, 1, 2 } }, // psraq
1141 { ISD::SHL, MVT::v8i64, { 1, 4, 1, 2 } }, // psllq
1142 { ISD::SRL, MVT::v8i64, { 1, 4, 1, 2 } }, // psrlq
1143 { ISD::SRA, MVT::v8i64, { 1, 4, 1, 2 } }, // psraq
1144 };
1145
1146 if (ST->hasAVX512() && Op2Info.isUniform())
1147 if (const auto *Entry =
1148 CostTableLookup(AVX512UniformCostTable, ISD, LT.second))
1149 if (auto KindCost = Entry->Cost[CostKind])
1150 return LT.first * *KindCost;
1151
1152 static const CostKindTblEntry AVX2UniformCostTable[] = {
1153 // Uniform splats are cheaper for the following instructions.
1154 { ISD::SHL, MVT::v16i8, { 3, 5, 5, 7 } }, // psllw + pand.
1155 { ISD::SRL, MVT::v16i8, { 3, 9, 5, 8 } }, // psrlw + pand.
1156 { ISD::SRA, MVT::v16i8, { 4, 5, 9,13 } }, // psrlw, pand, pxor, psubb.
1157 { ISD::SHL, MVT::v32i8, { 4, 7, 6, 8 } }, // psllw + pand.
1158 { ISD::SRL, MVT::v32i8, { 4, 8, 7, 9 } }, // psrlw + pand.
1159 { ISD::SRA, MVT::v32i8, { 6, 9,11,16 } }, // psrlw, pand, pxor, psubb.
1160
1161 { ISD::SHL, MVT::v8i16, { 1, 2, 1, 2 } }, // psllw.
1162 { ISD::SRL, MVT::v8i16, { 1, 2, 1, 2 } }, // psrlw.
1163 { ISD::SRA, MVT::v8i16, { 1, 2, 1, 2 } }, // psraw.
1164 { ISD::SHL, MVT::v16i16, { 2, 4, 2, 3 } }, // psllw.
1165 { ISD::SRL, MVT::v16i16, { 2, 4, 2, 3 } }, // psrlw.
1166 { ISD::SRA, MVT::v16i16, { 2, 4, 2, 3 } }, // psraw.
1167
1168 { ISD::SHL, MVT::v4i32, { 1, 2, 1, 2 } }, // pslld
1169 { ISD::SRL, MVT::v4i32, { 1, 2, 1, 2 } }, // psrld
1170 { ISD::SRA, MVT::v4i32, { 1, 2, 1, 2 } }, // psrad
1171 { ISD::SHL, MVT::v8i32, { 2, 4, 2, 3 } }, // pslld
1172 { ISD::SRL, MVT::v8i32, { 2, 4, 2, 3 } }, // psrld
1173 { ISD::SRA, MVT::v8i32, { 2, 4, 2, 3 } }, // psrad
1174
1175 { ISD::SHL, MVT::v2i64, { 1, 2, 1, 2 } }, // psllq
1176 { ISD::SRL, MVT::v2i64, { 1, 2, 1, 2 } }, // psrlq
1177 { ISD::SRA, MVT::v2i64, { 2, 4, 5, 7 } }, // 2 x psrad + shuffle.
1178 { ISD::SHL, MVT::v4i64, { 2, 4, 1, 2 } }, // psllq
1179 { ISD::SRL, MVT::v4i64, { 2, 4, 1, 2 } }, // psrlq
1180 { ISD::SRA, MVT::v4i64, { 4, 6, 5, 9 } }, // 2 x psrad + shuffle.
1181 };
1182
1183 if (ST->hasAVX2() && Op2Info.isUniform())
1184 if (const auto *Entry =
1185 CostTableLookup(AVX2UniformCostTable, ISD, LT.second))
1186 if (auto KindCost = Entry->Cost[CostKind])
1187 return LT.first * *KindCost;
1188
1189 static const CostKindTblEntry AVXUniformCostTable[] = {
1190 { ISD::SHL, MVT::v16i8, { 4, 4, 6, 8 } }, // psllw + pand.
1191 { ISD::SRL, MVT::v16i8, { 4, 8, 5, 8 } }, // psrlw + pand.
1192 { ISD::SRA, MVT::v16i8, { 6, 6, 9,13 } }, // psrlw, pand, pxor, psubb.
1193 { ISD::SHL, MVT::v32i8, { 7, 8,11,14 } }, // psllw + pand + split.
1194 { ISD::SRL, MVT::v32i8, { 7, 9,10,14 } }, // psrlw + pand + split.
1195 { ISD::SRA, MVT::v32i8, { 10,11,16,21 } }, // psrlw, pand, pxor, psubb + split.
1196
1197 { ISD::SHL, MVT::v8i16, { 1, 3, 1, 2 } }, // psllw.
1198 { ISD::SRL, MVT::v8i16, { 1, 3, 1, 2 } }, // psrlw.
1199 { ISD::SRA, MVT::v8i16, { 1, 3, 1, 2 } }, // psraw.
1200 { ISD::SHL, MVT::v16i16, { 3, 7, 5, 7 } }, // psllw + split.
1201 { ISD::SRL, MVT::v16i16, { 3, 7, 5, 7 } }, // psrlw + split.
1202 { ISD::SRA, MVT::v16i16, { 3, 7, 5, 7 } }, // psraw + split.
1203
1204 { ISD::SHL, MVT::v4i32, { 1, 3, 1, 2 } }, // pslld.
1205 { ISD::SRL, MVT::v4i32, { 1, 3, 1, 2 } }, // psrld.
1206 { ISD::SRA, MVT::v4i32, { 1, 3, 1, 2 } }, // psrad.
1207 { ISD::SHL, MVT::v8i32, { 3, 7, 5, 7 } }, // pslld + split.
1208 { ISD::SRL, MVT::v8i32, { 3, 7, 5, 7 } }, // psrld + split.
1209 { ISD::SRA, MVT::v8i32, { 3, 7, 5, 7 } }, // psrad + split.
1210
1211 { ISD::SHL, MVT::v2i64, { 1, 3, 1, 2 } }, // psllq.
1212 { ISD::SRL, MVT::v2i64, { 1, 3, 1, 2 } }, // psrlq.
1213 { ISD::SRA, MVT::v2i64, { 3, 4, 5, 7 } }, // 2 x psrad + shuffle.
1214 { ISD::SHL, MVT::v4i64, { 3, 7, 4, 6 } }, // psllq + split.
1215 { ISD::SRL, MVT::v4i64, { 3, 7, 4, 6 } }, // psrlq + split.
1216 { ISD::SRA, MVT::v4i64, { 6, 7,10,13 } }, // 2 x (2 x psrad + shuffle) + split.
1217 };
1218
1219 // XOP has faster vXi8 shifts.
1220 if (ST->hasAVX() && Op2Info.isUniform() &&
1221 (!ST->hasXOP() || LT.second.getScalarSizeInBits() != 8))
1222 if (const auto *Entry =
1223 CostTableLookup(AVXUniformCostTable, ISD, LT.second))
1224 if (auto KindCost = Entry->Cost[CostKind])
1225 return LT.first * *KindCost;
1226
1227 static const CostKindTblEntry SSE2UniformCostTable[] = {
1228 // Uniform splats are cheaper for the following instructions.
1229 { ISD::SHL, MVT::v16i8, { 9, 10, 6, 9 } }, // psllw + pand.
1230 { ISD::SRL, MVT::v16i8, { 9, 13, 5, 9 } }, // psrlw + pand.
1231 { ISD::SRA, MVT::v16i8, { 11, 15, 9,13 } }, // pcmpgtb sequence.
1232
1233 { ISD::SHL, MVT::v8i16, { 2, 2, 1, 2 } }, // psllw.
1234 { ISD::SRL, MVT::v8i16, { 2, 2, 1, 2 } }, // psrlw.
1235 { ISD::SRA, MVT::v8i16, { 2, 2, 1, 2 } }, // psraw.
1236
1237 { ISD::SHL, MVT::v4i32, { 2, 2, 1, 2 } }, // pslld
1238 { ISD::SRL, MVT::v4i32, { 2, 2, 1, 2 } }, // psrld.
1239 { ISD::SRA, MVT::v4i32, { 2, 2, 1, 2 } }, // psrad.
1240
1241 { ISD::SHL, MVT::v2i64, { 2, 2, 1, 2 } }, // psllq.
1242 { ISD::SRL, MVT::v2i64, { 2, 2, 1, 2 } }, // psrlq.
1243 { ISD::SRA, MVT::v2i64, { 5, 9, 5, 7 } }, // 2*psrlq + xor + sub.
1244 };
1245
1246 if (ST->hasSSE2() && Op2Info.isUniform() &&
1247 (!ST->hasXOP() || LT.second.getScalarSizeInBits() != 8))
1248 if (const auto *Entry =
1249 CostTableLookup(SSE2UniformCostTable, ISD, LT.second))
1250 if (auto KindCost = Entry->Cost[CostKind])
1251 return LT.first * *KindCost;
1252
1253 static const CostKindTblEntry AVX512DQCostTable[] = {
1254 { ISD::MUL, MVT::v2i64, { 2, 15, 1, 3 } }, // pmullq
1255 { ISD::MUL, MVT::v4i64, { 2, 15, 1, 3 } }, // pmullq
1256 { ISD::MUL, MVT::v8i64, { 3, 15, 1, 3 } } // pmullq
1257 };
1258
1259 // Look for AVX512DQ lowering tricks for custom cases.
1260 if (ST->hasDQI())
1261 if (const auto *Entry = CostTableLookup(AVX512DQCostTable, ISD, LT.second))
1262 if (auto KindCost = Entry->Cost[CostKind])
1263 return LT.first * *KindCost;
1264
1265 static const CostKindTblEntry AVX512BWCostTable[] = {
1266 { ISD::SHL, MVT::v16i8, { 4, 8, 4, 5 } }, // extend/vpsllvw/pack sequence.
1267 { ISD::SRL, MVT::v16i8, { 4, 8, 4, 5 } }, // extend/vpsrlvw/pack sequence.
1268 { ISD::SRA, MVT::v16i8, { 4, 8, 4, 5 } }, // extend/vpsravw/pack sequence.
1269 { ISD::SHL, MVT::v32i8, { 4, 23,11,16 } }, // extend/vpsllvw/pack sequence.
1270 { ISD::SRL, MVT::v32i8, { 4, 30,12,18 } }, // extend/vpsrlvw/pack sequence.
1271 { ISD::SRA, MVT::v32i8, { 6, 13,24,30 } }, // extend/vpsravw/pack sequence.
1272 { ISD::SHL, MVT::v64i8, { 6, 19,13,15 } }, // extend/vpsllvw/pack sequence.
1273 { ISD::SRL, MVT::v64i8, { 7, 27,15,18 } }, // extend/vpsrlvw/pack sequence.
1274 { ISD::SRA, MVT::v64i8, { 15, 15,30,30 } }, // extend/vpsravw/pack sequence.
1275
1276 { ISD::SHL, MVT::v8i16, { 1, 1, 1, 1 } }, // vpsllvw
1277 { ISD::SRL, MVT::v8i16, { 1, 1, 1, 1 } }, // vpsrlvw
1278 { ISD::SRA, MVT::v8i16, { 1, 1, 1, 1 } }, // vpsravw
1279 { ISD::SHL, MVT::v16i16, { 1, 1, 1, 1 } }, // vpsllvw
1280 { ISD::SRL, MVT::v16i16, { 1, 1, 1, 1 } }, // vpsrlvw
1281 { ISD::SRA, MVT::v16i16, { 1, 1, 1, 1 } }, // vpsravw
1282 { ISD::SHL, MVT::v32i16, { 1, 1, 1, 1 } }, // vpsllvw
1283 { ISD::SRL, MVT::v32i16, { 1, 1, 1, 1 } }, // vpsrlvw
1284 { ISD::SRA, MVT::v32i16, { 1, 1, 1, 1 } }, // vpsravw
1285
1286 { ISD::ADD, MVT::v64i8, { 1, 1, 1, 1 } }, // paddb
1287 { ISD::ADD, MVT::v32i16, { 1, 1, 1, 1 } }, // paddw
1288
1289 { ISD::ADD, MVT::v32i8, { 1, 1, 1, 1 } }, // paddb
1290 { ISD::ADD, MVT::v16i16, { 1, 1, 1, 1 } }, // paddw
1291 { ISD::ADD, MVT::v8i32, { 1, 1, 1, 1 } }, // paddd
1292 { ISD::ADD, MVT::v4i64, { 1, 1, 1, 1 } }, // paddq
1293
1294 { ISD::SUB, MVT::v64i8, { 1, 1, 1, 1 } }, // psubb
1295 { ISD::SUB, MVT::v32i16, { 1, 1, 1, 1 } }, // psubw
1296
1297 { ISD::MUL, MVT::v16i8, { 4, 12, 4, 5 } }, // extend/pmullw/trunc
1298 { ISD::MUL, MVT::v32i8, { 3, 10, 7,10 } }, // pmaddubsw
1299 { ISD::MUL, MVT::v64i8, { 3, 11, 7,10 } }, // pmaddubsw
1300 { ISD::MUL, MVT::v32i16, { 1, 5, 1, 1 } }, // pmullw
1301
1302 { ISD::SUB, MVT::v32i8, { 1, 1, 1, 1 } }, // psubb
1303 { ISD::SUB, MVT::v16i16, { 1, 1, 1, 1 } }, // psubw
1304 { ISD::SUB, MVT::v8i32, { 1, 1, 1, 1 } }, // psubd
1305 { ISD::SUB, MVT::v4i64, { 1, 1, 1, 1 } }, // psubq
1306 };
1307
1308 // Look for AVX512BW lowering tricks for custom cases.
1309 if (ST->hasBWI())
1310 if (const auto *Entry = CostTableLookup(AVX512BWCostTable, ISD, LT.second))
1311 if (auto KindCost = Entry->Cost[CostKind])
1312 return LT.first * *KindCost;
1313
1314 static const CostKindTblEntry AVX512CostTable[] = {
1315 { ISD::SHL, MVT::v64i8, { 15, 19,27,33 } }, // vpblendv+split sequence.
1316 { ISD::SRL, MVT::v64i8, { 15, 19,30,36 } }, // vpblendv+split sequence.
1317 { ISD::SRA, MVT::v64i8, { 37, 37,51,63 } }, // vpblendv+split sequence.
1318
1319 { ISD::SHL, MVT::v32i16, { 11, 16,11,15 } }, // 2*extend/vpsrlvd/pack sequence.
1320 { ISD::SRL, MVT::v32i16, { 11, 16,11,15 } }, // 2*extend/vpsrlvd/pack sequence.
1321 { ISD::SRA, MVT::v32i16, { 11, 16,11,15 } }, // 2*extend/vpsravd/pack sequence.
1322
1323 { ISD::SHL, MVT::v4i32, { 1, 1, 1, 1 } },
1324 { ISD::SRL, MVT::v4i32, { 1, 1, 1, 1 } },
1325 { ISD::SRA, MVT::v4i32, { 1, 1, 1, 1 } },
1326 { ISD::SHL, MVT::v8i32, { 1, 1, 1, 1 } },
1327 { ISD::SRL, MVT::v8i32, { 1, 1, 1, 1 } },
1328 { ISD::SRA, MVT::v8i32, { 1, 1, 1, 1 } },
1329 { ISD::SHL, MVT::v16i32, { 1, 1, 1, 1 } },
1330 { ISD::SRL, MVT::v16i32, { 1, 1, 1, 1 } },
1331 { ISD::SRA, MVT::v16i32, { 1, 1, 1, 1 } },
1332
1333 { ISD::SHL, MVT::v2i64, { 1, 1, 1, 1 } },
1334 { ISD::SRL, MVT::v2i64, { 1, 1, 1, 1 } },
1335 { ISD::SRA, MVT::v2i64, { 1, 1, 1, 1 } },
1336 { ISD::SHL, MVT::v4i64, { 1, 1, 1, 1 } },
1337 { ISD::SRL, MVT::v4i64, { 1, 1, 1, 1 } },
1338 { ISD::SRA, MVT::v4i64, { 1, 1, 1, 1 } },
1339 { ISD::SHL, MVT::v8i64, { 1, 1, 1, 1 } },
1340 { ISD::SRL, MVT::v8i64, { 1, 1, 1, 1 } },
1341 { ISD::SRA, MVT::v8i64, { 1, 1, 1, 1 } },
1342
1343 { ISD::ADD, MVT::v64i8, { 3, 7, 5, 5 } }, // 2*paddb + split
1344 { ISD::ADD, MVT::v32i16, { 3, 7, 5, 5 } }, // 2*paddw + split
1345
1346 { ISD::SUB, MVT::v64i8, { 3, 7, 5, 5 } }, // 2*psubb + split
1347 { ISD::SUB, MVT::v32i16, { 3, 7, 5, 5 } }, // 2*psubw + split
1348
1349 { ISD::AND, MVT::v32i8, { 1, 1, 1, 1 } },
1350 { ISD::AND, MVT::v16i16, { 1, 1, 1, 1 } },
1351 { ISD::AND, MVT::v8i32, { 1, 1, 1, 1 } },
1352 { ISD::AND, MVT::v4i64, { 1, 1, 1, 1 } },
1353
1354 { ISD::OR, MVT::v32i8, { 1, 1, 1, 1 } },
1355 { ISD::OR, MVT::v16i16, { 1, 1, 1, 1 } },
1356 { ISD::OR, MVT::v8i32, { 1, 1, 1, 1 } },
1357 { ISD::OR, MVT::v4i64, { 1, 1, 1, 1 } },
1358
1359 { ISD::XOR, MVT::v32i8, { 1, 1, 1, 1 } },
1360 { ISD::XOR, MVT::v16i16, { 1, 1, 1, 1 } },
1361 { ISD::XOR, MVT::v8i32, { 1, 1, 1, 1 } },
1362 { ISD::XOR, MVT::v4i64, { 1, 1, 1, 1 } },
1363
1364 { ISD::MUL, MVT::v16i32, { 1, 10, 1, 2 } }, // pmulld (Skylake from agner.org)
1365 { ISD::MUL, MVT::v8i32, { 1, 10, 1, 2 } }, // pmulld (Skylake from agner.org)
1366 { ISD::MUL, MVT::v4i32, { 1, 10, 1, 2 } }, // pmulld (Skylake from agner.org)
1367 { ISD::MUL, MVT::v8i64, { 6, 9, 8, 8 } }, // 3*pmuludq/3*shift/2*add
1368 { ISD::MUL, MVT::i64, { 1 } }, // Skylake from http://www.agner.org/
1369
1370 { X86ISD::PMULUDQ, MVT::v8i64, { 1, 5, 1, 1 } },
1371
1372 { ISD::FNEG, MVT::v8f64, { 1, 1, 1, 2 } }, // Skylake from http://www.agner.org/
1373 { ISD::FADD, MVT::v8f64, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1374 { ISD::FADD, MVT::v4f64, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1375 { ISD::FSUB, MVT::v8f64, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1376 { ISD::FSUB, MVT::v4f64, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1377 { ISD::FMUL, MVT::v8f64, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1378 { ISD::FMUL, MVT::v4f64, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1379 { ISD::FMUL, MVT::v2f64, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1380 { ISD::FMUL, MVT::f64, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1381
1382 { ISD::FDIV, MVT::f64, { 4, 14, 1, 1 } }, // Skylake from http://www.agner.org/
1383 { ISD::FDIV, MVT::v2f64, { 4, 14, 1, 1 } }, // Skylake from http://www.agner.org/
1384 { ISD::FDIV, MVT::v4f64, { 8, 14, 1, 1 } }, // Skylake from http://www.agner.org/
1385 { ISD::FDIV, MVT::v8f64, { 16, 23, 1, 3 } }, // Skylake from http://www.agner.org/
1386
1387 { ISD::FNEG, MVT::v16f32, { 1, 1, 1, 2 } }, // Skylake from http://www.agner.org/
1388 { ISD::FADD, MVT::v16f32, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1389 { ISD::FADD, MVT::v8f32, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1390 { ISD::FSUB, MVT::v16f32, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1391 { ISD::FSUB, MVT::v8f32, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1392 { ISD::FMUL, MVT::v16f32, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1393 { ISD::FMUL, MVT::v8f32, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1394 { ISD::FMUL, MVT::v4f32, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1395 { ISD::FMUL, MVT::f32, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1396
1397 { ISD::FDIV, MVT::f32, { 3, 11, 1, 1 } }, // Skylake from http://www.agner.org/
1398 { ISD::FDIV, MVT::v4f32, { 3, 11, 1, 1 } }, // Skylake from http://www.agner.org/
1399 { ISD::FDIV, MVT::v8f32, { 5, 11, 1, 1 } }, // Skylake from http://www.agner.org/
1400 { ISD::FDIV, MVT::v16f32, { 10, 18, 1, 3 } }, // Skylake from http://www.agner.org/
1401 };
1402
1403 if (ST->hasAVX512())
1404 if (const auto *Entry = CostTableLookup(AVX512CostTable, ISD, LT.second))
1405 if (auto KindCost = Entry->Cost[CostKind])
1406 return LT.first * *KindCost;
1407
1408 static const CostKindTblEntry AVX2ShiftCostTable[] = {
1409 // Shifts on vXi64/vXi32 on AVX2 is legal even though we declare to
1410 // customize them to detect the cases where shift amount is a scalar one.
1411 { ISD::SHL, MVT::v4i32, { 2, 3, 1, 3 } }, // vpsllvd (Haswell from agner.org)
1412 { ISD::SRL, MVT::v4i32, { 2, 3, 1, 3 } }, // vpsrlvd (Haswell from agner.org)
1413 { ISD::SRA, MVT::v4i32, { 2, 3, 1, 3 } }, // vpsravd (Haswell from agner.org)
1414 { ISD::SHL, MVT::v8i32, { 4, 4, 1, 3 } }, // vpsllvd (Haswell from agner.org)
1415 { ISD::SRL, MVT::v8i32, { 4, 4, 1, 3 } }, // vpsrlvd (Haswell from agner.org)
1416 { ISD::SRA, MVT::v8i32, { 4, 4, 1, 3 } }, // vpsravd (Haswell from agner.org)
1417 { ISD::SHL, MVT::v2i64, { 2, 3, 1, 1 } }, // vpsllvq (Haswell from agner.org)
1418 { ISD::SRL, MVT::v2i64, { 2, 3, 1, 1 } }, // vpsrlvq (Haswell from agner.org)
1419 { ISD::SHL, MVT::v4i64, { 4, 4, 1, 2 } }, // vpsllvq (Haswell from agner.org)
1420 { ISD::SRL, MVT::v4i64, { 4, 4, 1, 2 } }, // vpsrlvq (Haswell from agner.org)
1421 };
1422
1423 if (ST->hasAVX512()) {
1424 if (ISD == ISD::SHL && LT.second == MVT::v32i16 && Op2Info.isConstant())
1425 // On AVX512, a packed v32i16 shift left by a constant build_vector
1426 // is lowered into a vector multiply (vpmullw).
1427 return getArithmeticInstrCost(Instruction::Mul, Ty, CostKind,
1428 Op1Info.getNoProps(), Op2Info.getNoProps());
1429 }
1430
1431 // Look for AVX2 lowering tricks (XOP is always better at v4i32 shifts).
1432 if (ST->hasAVX2() && !(ST->hasXOP() && LT.second == MVT::v4i32)) {
1433 if (ISD == ISD::SHL && LT.second == MVT::v16i16 &&
1434 Op2Info.isConstant())
1435 // On AVX2, a packed v16i16 shift left by a constant build_vector
1436 // is lowered into a vector multiply (vpmullw).
1437 return getArithmeticInstrCost(Instruction::Mul, Ty, CostKind,
1438 Op1Info.getNoProps(), Op2Info.getNoProps());
1439
1440 if (const auto *Entry = CostTableLookup(AVX2ShiftCostTable, ISD, LT.second))
1441 if (auto KindCost = Entry->Cost[CostKind])
1442 return LT.first * *KindCost;
1443 }
1444
1445 static const CostKindTblEntry XOPShiftCostTable[] = {
1446 // 128bit shifts take 1cy, but right shifts require negation beforehand.
1447 { ISD::SHL, MVT::v16i8, { 1, 3, 1, 1 } },
1448 { ISD::SRL, MVT::v16i8, { 2, 3, 1, 1 } },
1449 { ISD::SRA, MVT::v16i8, { 2, 3, 1, 1 } },
1450 { ISD::SHL, MVT::v8i16, { 1, 3, 1, 1 } },
1451 { ISD::SRL, MVT::v8i16, { 2, 3, 1, 1 } },
1452 { ISD::SRA, MVT::v8i16, { 2, 3, 1, 1 } },
1453 { ISD::SHL, MVT::v4i32, { 1, 3, 1, 1 } },
1454 { ISD::SRL, MVT::v4i32, { 2, 3, 1, 1 } },
1455 { ISD::SRA, MVT::v4i32, { 2, 3, 1, 1 } },
1456 { ISD::SHL, MVT::v2i64, { 1, 3, 1, 1 } },
1457 { ISD::SRL, MVT::v2i64, { 2, 3, 1, 1 } },
1458 { ISD::SRA, MVT::v2i64, { 2, 3, 1, 1 } },
1459 // 256bit shifts require splitting if AVX2 didn't catch them above.
1460 { ISD::SHL, MVT::v32i8, { 4, 7, 5, 6 } },
1461 { ISD::SRL, MVT::v32i8, { 6, 7, 5, 6 } },
1462 { ISD::SRA, MVT::v32i8, { 6, 7, 5, 6 } },
1463 { ISD::SHL, MVT::v16i16, { 4, 7, 5, 6 } },
1464 { ISD::SRL, MVT::v16i16, { 6, 7, 5, 6 } },
1465 { ISD::SRA, MVT::v16i16, { 6, 7, 5, 6 } },
1466 { ISD::SHL, MVT::v8i32, { 4, 7, 5, 6 } },
1467 { ISD::SRL, MVT::v8i32, { 6, 7, 5, 6 } },
1468 { ISD::SRA, MVT::v8i32, { 6, 7, 5, 6 } },
1469 { ISD::SHL, MVT::v4i64, { 4, 7, 5, 6 } },
1470 { ISD::SRL, MVT::v4i64, { 6, 7, 5, 6 } },
1471 { ISD::SRA, MVT::v4i64, { 6, 7, 5, 6 } },
1472 };
1473
1474 // Look for XOP lowering tricks.
1475 if (ST->hasXOP()) {
1476 // If the right shift is constant then we'll fold the negation so
1477 // it's as cheap as a left shift.
1478 int ShiftISD = ISD;
1479 if ((ShiftISD == ISD::SRL || ShiftISD == ISD::SRA) && Op2Info.isConstant())
1480 ShiftISD = ISD::SHL;
1481 if (const auto *Entry =
1482 CostTableLookup(XOPShiftCostTable, ShiftISD, LT.second))
1483 if (auto KindCost = Entry->Cost[CostKind])
1484 return LT.first * *KindCost;
1485 }
1486
1487 if (ISD == ISD::SHL && !Op2Info.isUniform() && Op2Info.isConstant()) {
1488 MVT VT = LT.second;
1489 // Vector shift left by non uniform constant can be lowered
1490 // into vector multiply.
1491 if (((VT == MVT::v8i16 || VT == MVT::v4i32) && ST->hasSSE2()) ||
1492 ((VT == MVT::v16i16 || VT == MVT::v8i32) && ST->hasAVX()))
1493 ISD = ISD::MUL;
1494 }
1495
1496 static const CostKindTblEntry GLMCostTable[] = {
1497 { ISD::FDIV, MVT::f32, { 18, 19, 1, 1 } }, // divss
1498 { ISD::FDIV, MVT::v4f32, { 35, 36, 1, 1 } }, // divps
1499 { ISD::FDIV, MVT::f64, { 33, 34, 1, 1 } }, // divsd
1500 { ISD::FDIV, MVT::v2f64, { 65, 66, 1, 1 } }, // divpd
1501 };
1502
1503 if (ST->useGLMDivSqrtCosts())
1504 if (const auto *Entry = CostTableLookup(GLMCostTable, ISD, LT.second))
1505 if (auto KindCost = Entry->Cost[CostKind])
1506 return LT.first * *KindCost;
1507
1508 static const CostKindTblEntry SLMCostTable[] = {
1509 { ISD::MUL, MVT::v4i32, { 11, 11, 1, 7 } }, // pmulld
1510 { ISD::MUL, MVT::v8i16, { 2, 5, 1, 1 } }, // pmullw
1511 { ISD::FMUL, MVT::f64, { 2, 5, 1, 1 } }, // mulsd
1512 { ISD::FMUL, MVT::f32, { 1, 4, 1, 1 } }, // mulss
1513 { ISD::FMUL, MVT::v2f64, { 4, 7, 1, 1 } }, // mulpd
1514 { ISD::FMUL, MVT::v4f32, { 2, 5, 1, 1 } }, // mulps
1515 { ISD::FDIV, MVT::f32, { 17, 19, 1, 1 } }, // divss
1516 { ISD::FDIV, MVT::v4f32, { 39, 39, 1, 6 } }, // divps
1517 { ISD::FDIV, MVT::f64, { 32, 34, 1, 1 } }, // divsd
1518 { ISD::FDIV, MVT::v2f64, { 69, 69, 1, 6 } }, // divpd
1519 { ISD::FADD, MVT::v2f64, { 2, 4, 1, 1 } }, // addpd
1520 { ISD::FSUB, MVT::v2f64, { 2, 4, 1, 1 } }, // subpd
1521 // v2i64/v4i64 mul is custom lowered as a series of long:
1522 // multiplies(3), shifts(3) and adds(2)
1523 // slm muldq version throughput is 2 and addq throughput 4
1524 // thus: 3X2 (muldq throughput) + 3X1 (shift throughput) +
1525 // 3X4 (addq throughput) = 17
1526 { ISD::MUL, MVT::v2i64, { 17, 22, 9, 9 } },
1527 // slm addq\subq throughput is 4
1528 { ISD::ADD, MVT::v2i64, { 4, 2, 1, 2 } },
1529 { ISD::SUB, MVT::v2i64, { 4, 2, 1, 2 } },
1530 };
1531
1532 if (ST->useSLMArithCosts())
1533 if (const auto *Entry = CostTableLookup(SLMCostTable, ISD, LT.second))
1534 if (auto KindCost = Entry->Cost[CostKind])
1535 return LT.first * *KindCost;
1536
1537 static const CostKindTblEntry AVX2CostTable[] = {
1538 { ISD::SHL, MVT::v16i8, { 6, 21,11,16 } }, // vpblendvb sequence.
1539 { ISD::SHL, MVT::v32i8, { 6, 23,11,22 } }, // vpblendvb sequence.
1540 { ISD::SHL, MVT::v8i16, { 5, 18, 5,10 } }, // extend/vpsrlvd/pack sequence.
1541 { ISD::SHL, MVT::v16i16, { 8, 10,10,14 } }, // extend/vpsrlvd/pack sequence.
1542
1543 { ISD::SRL, MVT::v16i8, { 6, 27,12,18 } }, // vpblendvb sequence.
1544 { ISD::SRL, MVT::v32i8, { 8, 30,12,24 } }, // vpblendvb sequence.
1545 { ISD::SRL, MVT::v8i16, { 5, 11, 5,10 } }, // extend/vpsrlvd/pack sequence.
1546 { ISD::SRL, MVT::v16i16, { 8, 10,10,14 } }, // extend/vpsrlvd/pack sequence.
1547
1548 { ISD::SRA, MVT::v16i8, { 17, 17,24,30 } }, // vpblendvb sequence.
1549 { ISD::SRA, MVT::v32i8, { 18, 20,24,43 } }, // vpblendvb sequence.
1550 { ISD::SRA, MVT::v8i16, { 5, 11, 5,10 } }, // extend/vpsravd/pack sequence.
1551 { ISD::SRA, MVT::v16i16, { 8, 10,10,14 } }, // extend/vpsravd/pack sequence.
1552 { ISD::SRA, MVT::v2i64, { 4, 5, 5, 5 } }, // srl/xor/sub sequence.
1553 { ISD::SRA, MVT::v4i64, { 8, 8, 5, 9 } }, // srl/xor/sub sequence.
1554
1555 { ISD::SUB, MVT::v32i8, { 1, 1, 1, 2 } }, // psubb
1556 { ISD::ADD, MVT::v32i8, { 1, 1, 1, 2 } }, // paddb
1557 { ISD::SUB, MVT::v16i16, { 1, 1, 1, 2 } }, // psubw
1558 { ISD::ADD, MVT::v16i16, { 1, 1, 1, 2 } }, // paddw
1559 { ISD::SUB, MVT::v8i32, { 1, 1, 1, 2 } }, // psubd
1560 { ISD::ADD, MVT::v8i32, { 1, 1, 1, 2 } }, // paddd
1561 { ISD::SUB, MVT::v4i64, { 1, 1, 1, 2 } }, // psubq
1562 { ISD::ADD, MVT::v4i64, { 1, 1, 1, 2 } }, // paddq
1563
1564 { ISD::MUL, MVT::v16i8, { 5, 18, 6,12 } }, // extend/pmullw/pack
1565 { ISD::MUL, MVT::v32i8, { 4, 8, 8,16 } }, // pmaddubsw
1566 { ISD::MUL, MVT::v16i16, { 2, 5, 1, 2 } }, // pmullw
1567 { ISD::MUL, MVT::v8i32, { 4, 10, 1, 2 } }, // pmulld
1568 { ISD::MUL, MVT::v4i32, { 2, 10, 1, 2 } }, // pmulld
1569 { ISD::MUL, MVT::v4i64, { 6, 10, 8,13 } }, // 3*pmuludq/3*shift/2*add
1570 { ISD::MUL, MVT::v2i64, { 6, 10, 8, 8 } }, // 3*pmuludq/3*shift/2*add
1571
1572 { X86ISD::PMULUDQ, MVT::v4i64, { 1, 5, 1, 1 } },
1573
1574 { ISD::FNEG, MVT::v4f64, { 1, 1, 1, 2 } }, // vxorpd
1575 { ISD::FNEG, MVT::v8f32, { 1, 1, 1, 2 } }, // vxorps
1576
1577 { ISD::FADD, MVT::f64, { 1, 4, 1, 1 } }, // vaddsd
1578 { ISD::FADD, MVT::f32, { 1, 4, 1, 1 } }, // vaddss
1579 { ISD::FADD, MVT::v2f64, { 1, 4, 1, 1 } }, // vaddpd
1580 { ISD::FADD, MVT::v4f32, { 1, 4, 1, 1 } }, // vaddps
1581 { ISD::FADD, MVT::v4f64, { 1, 4, 1, 2 } }, // vaddpd
1582 { ISD::FADD, MVT::v8f32, { 1, 4, 1, 2 } }, // vaddps
1583
1584 { ISD::FSUB, MVT::f64, { 1, 4, 1, 1 } }, // vsubsd
1585 { ISD::FSUB, MVT::f32, { 1, 4, 1, 1 } }, // vsubss
1586 { ISD::FSUB, MVT::v2f64, { 1, 4, 1, 1 } }, // vsubpd
1587 { ISD::FSUB, MVT::v4f32, { 1, 4, 1, 1 } }, // vsubps
1588 { ISD::FSUB, MVT::v4f64, { 1, 4, 1, 2 } }, // vsubpd
1589 { ISD::FSUB, MVT::v8f32, { 1, 4, 1, 2 } }, // vsubps
1590
1591 { ISD::FMUL, MVT::f64, { 1, 5, 1, 1 } }, // vmulsd
1592 { ISD::FMUL, MVT::f32, { 1, 5, 1, 1 } }, // vmulss
1593 { ISD::FMUL, MVT::v2f64, { 1, 5, 1, 1 } }, // vmulpd
1594 { ISD::FMUL, MVT::v4f32, { 1, 5, 1, 1 } }, // vmulps
1595 { ISD::FMUL, MVT::v4f64, { 1, 5, 1, 2 } }, // vmulpd
1596 { ISD::FMUL, MVT::v8f32, { 1, 5, 1, 2 } }, // vmulps
1597
1598 { ISD::FDIV, MVT::f32, { 7, 13, 1, 1 } }, // vdivss
1599 { ISD::FDIV, MVT::v4f32, { 7, 13, 1, 1 } }, // vdivps
1600 { ISD::FDIV, MVT::v8f32, { 14, 21, 1, 3 } }, // vdivps
1601 { ISD::FDIV, MVT::f64, { 14, 20, 1, 1 } }, // vdivsd
1602 { ISD::FDIV, MVT::v2f64, { 14, 20, 1, 1 } }, // vdivpd
1603 { ISD::FDIV, MVT::v4f64, { 28, 35, 1, 3 } }, // vdivpd
1604 };
1605
1606 // Look for AVX2 lowering tricks for custom cases.
1607 if (ST->hasAVX2())
1608 if (const auto *Entry = CostTableLookup(AVX2CostTable, ISD, LT.second))
1609 if (auto KindCost = Entry->Cost[CostKind])
1610 return LT.first * *KindCost;
1611
1612 static const CostKindTblEntry AVX1CostTable[] = {
1613 // We don't have to scalarize unsupported ops. We can issue two half-sized
1614 // operations and we only need to extract the upper YMM half.
1615 // Two ops + 1 extract + 1 insert = 4.
1616 { ISD::MUL, MVT::v32i8, { 10, 11, 18, 19 } }, // pmaddubsw + split
1617 { ISD::MUL, MVT::v16i8, { 5, 6, 8, 12 } }, // 2*pmaddubsw/3*and/psllw/or
1618 { ISD::MUL, MVT::v16i16, { 4, 8, 5, 6 } }, // pmullw + split
1619 { ISD::MUL, MVT::v8i32, { 5, 8, 5, 10 } }, // pmulld + split
1620 { ISD::MUL, MVT::v4i32, { 2, 5, 1, 3 } }, // pmulld
1621 { ISD::MUL, MVT::v4i64, { 12, 15, 19, 20 } },
1622
1623 { X86ISD::PMULUDQ, MVT::v4i64, { 3, 5, 5, 6 } }, // pmuludq + split
1624
1625 { ISD::AND, MVT::v32i8, { 1, 1, 1, 2 } }, // vandps
1626 { ISD::AND, MVT::v16i16, { 1, 1, 1, 2 } }, // vandps
1627 { ISD::AND, MVT::v8i32, { 1, 1, 1, 2 } }, // vandps
1628 { ISD::AND, MVT::v4i64, { 1, 1, 1, 2 } }, // vandps
1629
1630 { ISD::OR, MVT::v32i8, { 1, 1, 1, 2 } }, // vorps
1631 { ISD::OR, MVT::v16i16, { 1, 1, 1, 2 } }, // vorps
1632 { ISD::OR, MVT::v8i32, { 1, 1, 1, 2 } }, // vorps
1633 { ISD::OR, MVT::v4i64, { 1, 1, 1, 2 } }, // vorps
1634
1635 { ISD::XOR, MVT::v32i8, { 1, 1, 1, 2 } }, // vxorps
1636 { ISD::XOR, MVT::v16i16, { 1, 1, 1, 2 } }, // vxorps
1637 { ISD::XOR, MVT::v8i32, { 1, 1, 1, 2 } }, // vxorps
1638 { ISD::XOR, MVT::v4i64, { 1, 1, 1, 2 } }, // vxorps
1639
1640 { ISD::SUB, MVT::v32i8, { 4, 2, 5, 6 } }, // psubb + split
1641 { ISD::ADD, MVT::v32i8, { 4, 2, 5, 6 } }, // paddb + split
1642 { ISD::SUB, MVT::v16i16, { 4, 2, 5, 6 } }, // psubw + split
1643 { ISD::ADD, MVT::v16i16, { 4, 2, 5, 6 } }, // paddw + split
1644 { ISD::SUB, MVT::v8i32, { 4, 2, 5, 6 } }, // psubd + split
1645 { ISD::ADD, MVT::v8i32, { 4, 2, 5, 6 } }, // paddd + split
1646 { ISD::SUB, MVT::v4i64, { 4, 2, 5, 6 } }, // psubq + split
1647 { ISD::ADD, MVT::v4i64, { 4, 2, 5, 6 } }, // paddq + split
1648 { ISD::SUB, MVT::v2i64, { 1, 1, 1, 1 } }, // psubq
1649 { ISD::ADD, MVT::v2i64, { 1, 1, 1, 1 } }, // paddq
1650
1651 { ISD::SHL, MVT::v16i8, { 10, 21,11,17 } }, // pblendvb sequence.
1652 { ISD::SHL, MVT::v32i8, { 22, 22,27,40 } }, // pblendvb sequence + split.
1653 { ISD::SHL, MVT::v8i16, { 6, 9,11,11 } }, // pblendvb sequence.
1654 { ISD::SHL, MVT::v16i16, { 13, 16,24,25 } }, // pblendvb sequence + split.
1655 { ISD::SHL, MVT::v4i32, { 3, 11, 4, 6 } }, // pslld/paddd/cvttps2dq/pmulld
1656 { ISD::SHL, MVT::v8i32, { 9, 11,12,17 } }, // pslld/paddd/cvttps2dq/pmulld + split
1657 { ISD::SHL, MVT::v2i64, { 2, 4, 4, 6 } }, // Shift each lane + blend.
1658 { ISD::SHL, MVT::v4i64, { 6, 7,11,15 } }, // Shift each lane + blend + split.
1659
1660 { ISD::SRL, MVT::v16i8, { 11, 27,12,18 } }, // pblendvb sequence.
1661 { ISD::SRL, MVT::v32i8, { 23, 23,30,43 } }, // pblendvb sequence + split.
1662 { ISD::SRL, MVT::v8i16, { 13, 16,14,22 } }, // pblendvb sequence.
1663 { ISD::SRL, MVT::v16i16, { 28, 30,31,48 } }, // pblendvb sequence + split.
1664 { ISD::SRL, MVT::v4i32, { 6, 7,12,16 } }, // Shift each lane + blend.
1665 { ISD::SRL, MVT::v8i32, { 14, 14,26,34 } }, // Shift each lane + blend + split.
1666 { ISD::SRL, MVT::v2i64, { 2, 4, 4, 6 } }, // Shift each lane + blend.
1667 { ISD::SRL, MVT::v4i64, { 6, 7,11,15 } }, // Shift each lane + blend + split.
1668
1669 { ISD::SRA, MVT::v16i8, { 21, 22,24,36 } }, // pblendvb sequence.
1670 { ISD::SRA, MVT::v32i8, { 44, 45,51,76 } }, // pblendvb sequence + split.
1671 { ISD::SRA, MVT::v8i16, { 13, 16,14,22 } }, // pblendvb sequence.
1672 { ISD::SRA, MVT::v16i16, { 28, 30,31,48 } }, // pblendvb sequence + split.
1673 { ISD::SRA, MVT::v4i32, { 6, 7,12,16 } }, // Shift each lane + blend.
1674 { ISD::SRA, MVT::v8i32, { 14, 14,26,34 } }, // Shift each lane + blend + split.
1675 { ISD::SRA, MVT::v2i64, { 5, 6,10,14 } }, // Shift each lane + blend.
1676 { ISD::SRA, MVT::v4i64, { 12, 12,22,30 } }, // Shift each lane + blend + split.
1677
1678 { ISD::FNEG, MVT::v4f64, { 2, 2, 1, 2 } }, // BTVER2 from http://www.agner.org/
1679 { ISD::FNEG, MVT::v8f32, { 2, 2, 1, 2 } }, // BTVER2 from http://www.agner.org/
1680
1681 { ISD::FADD, MVT::f64, { 1, 5, 1, 1 } }, // BDVER2 from http://www.agner.org/
1682 { ISD::FADD, MVT::f32, { 1, 5, 1, 1 } }, // BDVER2 from http://www.agner.org/
1683 { ISD::FADD, MVT::v2f64, { 1, 5, 1, 1 } }, // BDVER2 from http://www.agner.org/
1684 { ISD::FADD, MVT::v4f32, { 1, 5, 1, 1 } }, // BDVER2 from http://www.agner.org/
1685 { ISD::FADD, MVT::v4f64, { 2, 5, 1, 2 } }, // BDVER2 from http://www.agner.org/
1686 { ISD::FADD, MVT::v8f32, { 2, 5, 1, 2 } }, // BDVER2 from http://www.agner.org/
1687
1688 { ISD::FSUB, MVT::f64, { 1, 5, 1, 1 } }, // BDVER2 from http://www.agner.org/
1689 { ISD::FSUB, MVT::f32, { 1, 5, 1, 1 } }, // BDVER2 from http://www.agner.org/
1690 { ISD::FSUB, MVT::v2f64, { 1, 5, 1, 1 } }, // BDVER2 from http://www.agner.org/
1691 { ISD::FSUB, MVT::v4f32, { 1, 5, 1, 1 } }, // BDVER2 from http://www.agner.org/
1692 { ISD::FSUB, MVT::v4f64, { 2, 5, 1, 2 } }, // BDVER2 from http://www.agner.org/
1693 { ISD::FSUB, MVT::v8f32, { 2, 5, 1, 2 } }, // BDVER2 from http://www.agner.org/
1694
1695 { ISD::FMUL, MVT::f64, { 2, 5, 1, 1 } }, // BTVER2 from http://www.agner.org/
1696 { ISD::FMUL, MVT::f32, { 1, 5, 1, 1 } }, // BTVER2 from http://www.agner.org/
1697 { ISD::FMUL, MVT::v2f64, { 2, 5, 1, 1 } }, // BTVER2 from http://www.agner.org/
1698 { ISD::FMUL, MVT::v4f32, { 1, 5, 1, 1 } }, // BTVER2 from http://www.agner.org/
1699 { ISD::FMUL, MVT::v4f64, { 4, 5, 1, 2 } }, // BTVER2 from http://www.agner.org/
1700 { ISD::FMUL, MVT::v8f32, { 2, 5, 1, 2 } }, // BTVER2 from http://www.agner.org/
1701
1702 { ISD::FDIV, MVT::f32, { 14, 14, 1, 1 } }, // SNB from http://www.agner.org/
1703 { ISD::FDIV, MVT::v4f32, { 14, 14, 1, 1 } }, // SNB from http://www.agner.org/
1704 { ISD::FDIV, MVT::v8f32, { 28, 29, 1, 3 } }, // SNB from http://www.agner.org/
1705 { ISD::FDIV, MVT::f64, { 22, 22, 1, 1 } }, // SNB from http://www.agner.org/
1706 { ISD::FDIV, MVT::v2f64, { 22, 22, 1, 1 } }, // SNB from http://www.agner.org/
1707 { ISD::FDIV, MVT::v4f64, { 44, 45, 1, 3 } }, // SNB from http://www.agner.org/
1708 };
1709
1710 if (ST->hasAVX())
1711 if (const auto *Entry = CostTableLookup(AVX1CostTable, ISD, LT.second))
1712 if (auto KindCost = Entry->Cost[CostKind])
1713 return LT.first * *KindCost;
1714
1715 static const CostKindTblEntry SSE42CostTable[] = {
1716 { ISD::FADD, MVT::f64, { 1, 3, 1, 1 } }, // Nehalem from http://www.agner.org/
1717 { ISD::FADD, MVT::f32, { 1, 3, 1, 1 } }, // Nehalem from http://www.agner.org/
1718 { ISD::FADD, MVT::v2f64, { 1, 3, 1, 1 } }, // Nehalem from http://www.agner.org/
1719 { ISD::FADD, MVT::v4f32, { 1, 3, 1, 1 } }, // Nehalem from http://www.agner.org/
1720
1721 { ISD::FSUB, MVT::f64, { 1, 3, 1, 1 } }, // Nehalem from http://www.agner.org/
1722 { ISD::FSUB, MVT::f32 , { 1, 3, 1, 1 } }, // Nehalem from http://www.agner.org/
1723 { ISD::FSUB, MVT::v2f64, { 1, 3, 1, 1 } }, // Nehalem from http://www.agner.org/
1724 { ISD::FSUB, MVT::v4f32, { 1, 3, 1, 1 } }, // Nehalem from http://www.agner.org/
1725
1726 { ISD::FMUL, MVT::f64, { 1, 5, 1, 1 } }, // Nehalem from http://www.agner.org/
1727 { ISD::FMUL, MVT::f32, { 1, 5, 1, 1 } }, // Nehalem from http://www.agner.org/
1728 { ISD::FMUL, MVT::v2f64, { 1, 5, 1, 1 } }, // Nehalem from http://www.agner.org/
1729 { ISD::FMUL, MVT::v4f32, { 1, 5, 1, 1 } }, // Nehalem from http://www.agner.org/
1730
1731 { ISD::FDIV, MVT::f32, { 14, 14, 1, 1 } }, // Nehalem from http://www.agner.org/
1732 { ISD::FDIV, MVT::v4f32, { 14, 14, 1, 1 } }, // Nehalem from http://www.agner.org/
1733 { ISD::FDIV, MVT::f64, { 22, 22, 1, 1 } }, // Nehalem from http://www.agner.org/
1734 { ISD::FDIV, MVT::v2f64, { 22, 22, 1, 1 } }, // Nehalem from http://www.agner.org/
1735
1736 { ISD::MUL, MVT::v2i64, { 6, 10,10,10 } } // 3*pmuludq/3*shift/2*add
1737 };
1738
1739 if (ST->hasSSE42())
1740 if (const auto *Entry = CostTableLookup(SSE42CostTable, ISD, LT.second))
1741 if (auto KindCost = Entry->Cost[CostKind])
1742 return LT.first * *KindCost;
1743
1744 static const CostKindTblEntry SSE41CostTable[] = {
1745 { ISD::SHL, MVT::v16i8, { 15, 24,17,22 } }, // pblendvb sequence.
1746 { ISD::SHL, MVT::v8i16, { 11, 14,11,11 } }, // pblendvb sequence.
1747 { ISD::SHL, MVT::v4i32, { 14, 20, 4,10 } }, // pslld/paddd/cvttps2dq/pmulld
1748
1749 { ISD::SRL, MVT::v16i8, { 16, 27,18,24 } }, // pblendvb sequence.
1750 { ISD::SRL, MVT::v8i16, { 22, 26,23,27 } }, // pblendvb sequence.
1751 { ISD::SRL, MVT::v4i32, { 16, 17,15,19 } }, // Shift each lane + blend.
1752 { ISD::SRL, MVT::v2i64, { 4, 6, 5, 7 } }, // splat+shuffle sequence.
1753
1754 { ISD::SRA, MVT::v16i8, { 38, 41,30,36 } }, // pblendvb sequence.
1755 { ISD::SRA, MVT::v8i16, { 22, 26,23,27 } }, // pblendvb sequence.
1756 { ISD::SRA, MVT::v4i32, { 16, 17,15,19 } }, // Shift each lane + blend.
1757 { ISD::SRA, MVT::v2i64, { 8, 17, 5, 7 } }, // splat+shuffle sequence.
1758
1759 { ISD::MUL, MVT::v4i32, { 2, 11, 1, 1 } } // pmulld (Nehalem from agner.org)
1760 };
1761
1762 if (ST->hasSSE41())
1763 if (const auto *Entry = CostTableLookup(SSE41CostTable, ISD, LT.second))
1764 if (auto KindCost = Entry->Cost[CostKind])
1765 return LT.first * *KindCost;
1766
1767 static const CostKindTblEntry SSSE3CostTable[] = {
1768 { ISD::MUL, MVT::v16i8, { 5, 18,10,12 } }, // 2*pmaddubsw/3*and/psllw/or
1769 };
1770
1771 if (ST->hasSSSE3())
1772 if (const auto *Entry = CostTableLookup(SSSE3CostTable, ISD, LT.second))
1773 if (auto KindCost = Entry->Cost[CostKind])
1774 return LT.first * *KindCost;
1775
1776 static const CostKindTblEntry SSE2CostTable[] = {
1777 // We don't correctly identify costs of casts because they are marked as
1778 // custom.
1779 { ISD::SHL, MVT::v16i8, { 13, 21,26,28 } }, // cmpgtb sequence.
1780 { ISD::SHL, MVT::v8i16, { 24, 27,16,20 } }, // cmpgtw sequence.
1781 { ISD::SHL, MVT::v4i32, { 17, 19,10,12 } }, // pslld/paddd/cvttps2dq/pmuludq.
1782 { ISD::SHL, MVT::v2i64, { 4, 6, 5, 7 } }, // splat+shuffle sequence.
1783
1784 { ISD::SRL, MVT::v16i8, { 14, 28,27,30 } }, // cmpgtb sequence.
1785 { ISD::SRL, MVT::v8i16, { 16, 19,31,31 } }, // cmpgtw sequence.
1786 { ISD::SRL, MVT::v4i32, { 12, 12,15,19 } }, // Shift each lane + blend.
1787 { ISD::SRL, MVT::v2i64, { 4, 6, 5, 7 } }, // splat+shuffle sequence.
1788
1789 { ISD::SRA, MVT::v16i8, { 27, 30,54,54 } }, // unpacked cmpgtb sequence.
1790 { ISD::SRA, MVT::v8i16, { 16, 19,31,31 } }, // cmpgtw sequence.
1791 { ISD::SRA, MVT::v4i32, { 12, 12,15,19 } }, // Shift each lane + blend.
1792 { ISD::SRA, MVT::v2i64, { 8, 11,12,16 } }, // srl/xor/sub splat+shuffle sequence.
1793
1794 { ISD::AND, MVT::v16i8, { 1, 1, 1, 1 } }, // pand
1795 { ISD::AND, MVT::v8i16, { 1, 1, 1, 1 } }, // pand
1796 { ISD::AND, MVT::v4i32, { 1, 1, 1, 1 } }, // pand
1797 { ISD::AND, MVT::v2i64, { 1, 1, 1, 1 } }, // pand
1798
1799 { ISD::OR, MVT::v16i8, { 1, 1, 1, 1 } }, // por
1800 { ISD::OR, MVT::v8i16, { 1, 1, 1, 1 } }, // por
1801 { ISD::OR, MVT::v4i32, { 1, 1, 1, 1 } }, // por
1802 { ISD::OR, MVT::v2i64, { 1, 1, 1, 1 } }, // por
1803
1804 { ISD::XOR, MVT::v16i8, { 1, 1, 1, 1 } }, // pxor
1805 { ISD::XOR, MVT::v8i16, { 1, 1, 1, 1 } }, // pxor
1806 { ISD::XOR, MVT::v4i32, { 1, 1, 1, 1 } }, // pxor
1807 { ISD::XOR, MVT::v2i64, { 1, 1, 1, 1 } }, // pxor
1808
1809 { ISD::ADD, MVT::v2i64, { 1, 2, 1, 2 } }, // paddq
1810 { ISD::SUB, MVT::v2i64, { 1, 2, 1, 2 } }, // psubq
1811
1812 { ISD::MUL, MVT::v16i8, { 6, 18,12,12 } }, // 2*unpack/2*pmullw/2*and/pack
1813 { ISD::MUL, MVT::v8i16, { 1, 5, 1, 1 } }, // pmullw
1814 { ISD::MUL, MVT::v4i32, { 6, 8, 7, 7 } }, // 3*pmuludq/4*shuffle
1815 { ISD::MUL, MVT::v2i64, { 7, 10,10,10 } }, // 3*pmuludq/3*shift/2*add
1816
1817 { X86ISD::PMULUDQ, MVT::v2i64, { 1, 5, 1, 1 } },
1818
1819 { ISD::FDIV, MVT::f32, { 23, 23, 1, 1 } }, // Pentium IV from http://www.agner.org/
1820 { ISD::FDIV, MVT::v4f32, { 39, 39, 1, 1 } }, // Pentium IV from http://www.agner.org/
1821 { ISD::FDIV, MVT::f64, { 38, 38, 1, 1 } }, // Pentium IV from http://www.agner.org/
1822 { ISD::FDIV, MVT::v2f64, { 69, 69, 1, 1 } }, // Pentium IV from http://www.agner.org/
1823
1824 { ISD::FNEG, MVT::f32, { 1, 1, 1, 1 } }, // Pentium IV from http://www.agner.org/
1825 { ISD::FNEG, MVT::f64, { 1, 1, 1, 1 } }, // Pentium IV from http://www.agner.org/
1826 { ISD::FNEG, MVT::v4f32, { 1, 1, 1, 1 } }, // Pentium IV from http://www.agner.org/
1827 { ISD::FNEG, MVT::v2f64, { 1, 1, 1, 1 } }, // Pentium IV from http://www.agner.org/
1828
1829 { ISD::FADD, MVT::f32, { 2, 3, 1, 1 } }, // Pentium IV from http://www.agner.org/
1830 { ISD::FADD, MVT::f64, { 2, 3, 1, 1 } }, // Pentium IV from http://www.agner.org/
1831 { ISD::FADD, MVT::v2f64, { 2, 3, 1, 1 } }, // Pentium IV from http://www.agner.org/
1832
1833 { ISD::FSUB, MVT::f32, { 2, 3, 1, 1 } }, // Pentium IV from http://www.agner.org/
1834 { ISD::FSUB, MVT::f64, { 2, 3, 1, 1 } }, // Pentium IV from http://www.agner.org/
1835 { ISD::FSUB, MVT::v2f64, { 2, 3, 1, 1 } }, // Pentium IV from http://www.agner.org/
1836
1837 { ISD::FMUL, MVT::f64, { 2, 5, 1, 1 } }, // Pentium IV from http://www.agner.org/
1838 { ISD::FMUL, MVT::v2f64, { 2, 5, 1, 1 } }, // Pentium IV from http://www.agner.org/
1839 };
1840
1841 if (ST->hasSSE2())
1842 if (const auto *Entry = CostTableLookup(SSE2CostTable, ISD, LT.second))
1843 if (auto KindCost = Entry->Cost[CostKind])
1844 return LT.first * *KindCost;
1845
1846 static const CostKindTblEntry SSE1CostTable[] = {
1847 { ISD::FDIV, MVT::f32, { 17, 18, 1, 1 } }, // Pentium III from http://www.agner.org/
1848 { ISD::FDIV, MVT::v4f32, { 34, 48, 1, 1 } }, // Pentium III from http://www.agner.org/
1849
1850 { ISD::FNEG, MVT::f32, { 2, 2, 1, 2 } }, // Pentium III from http://www.agner.org/
1851 { ISD::FNEG, MVT::v4f32, { 2, 2, 1, 2 } }, // Pentium III from http://www.agner.org/
1852
1853 { ISD::FADD, MVT::f32, { 1, 3, 1, 1 } }, // Pentium III from http://www.agner.org/
1854 { ISD::FADD, MVT::v4f32, { 2, 3, 1, 1 } }, // Pentium III from http://www.agner.org/
1855
1856 { ISD::FSUB, MVT::f32, { 1, 3, 1, 1 } }, // Pentium III from http://www.agner.org/
1857 { ISD::FSUB, MVT::v4f32, { 2, 3, 1, 1 } }, // Pentium III from http://www.agner.org/
1858
1859 { ISD::FMUL, MVT::f32, { 2, 5, 1, 1 } }, // Pentium III from http://www.agner.org/
1860 { ISD::FMUL, MVT::v4f32, { 2, 5, 1, 1 } }, // Pentium III from http://www.agner.org/
1861 };
1862
1863 if (ST->hasSSE1())
1864 if (const auto *Entry = CostTableLookup(SSE1CostTable, ISD, LT.second))
1865 if (auto KindCost = Entry->Cost[CostKind])
1866 return LT.first * *KindCost;
1867
1868 static const CostKindTblEntry X64CostTbl[] = { // 64-bit targets
1869 { ISD::ADD, MVT::i64, { 1 } }, // Core (Merom) from http://www.agner.org/
1870 { ISD::SUB, MVT::i64, { 1 } }, // Core (Merom) from http://www.agner.org/
1871 { ISD::MUL, MVT::i64, { 2, 6, 1, 2 } },
1872 };
1873
1874 if (ST->is64Bit())
1875 if (const auto *Entry = CostTableLookup(X64CostTbl, ISD, LT.second))
1876 if (auto KindCost = Entry->Cost[CostKind])
1877 return LT.first * *KindCost;
1878
1879 static const CostKindTblEntry X86CostTbl[] = { // 32 or 64-bit targets
1880 { ISD::ADD, MVT::i8, { 1 } }, // Pentium III from http://www.agner.org/
1881 { ISD::ADD, MVT::i16, { 1 } }, // Pentium III from http://www.agner.org/
1882 { ISD::ADD, MVT::i32, { 1 } }, // Pentium III from http://www.agner.org/
1883
1884 { ISD::SUB, MVT::i8, { 1 } }, // Pentium III from http://www.agner.org/
1885 { ISD::SUB, MVT::i16, { 1 } }, // Pentium III from http://www.agner.org/
1886 { ISD::SUB, MVT::i32, { 1 } }, // Pentium III from http://www.agner.org/
1887
1888 { ISD::MUL, MVT::i8, { 3, 4, 1, 1 } },
1889 { ISD::MUL, MVT::i16, { 2, 4, 1, 1 } },
1890 { ISD::MUL, MVT::i32, { 1, 4, 1, 1 } },
1891
1892 { ISD::FNEG, MVT::f64, { 2, 2, 1, 3 } }, // (x87)
1893 { ISD::FADD, MVT::f64, { 2, 3, 1, 1 } }, // (x87)
1894 { ISD::FSUB, MVT::f64, { 2, 3, 1, 1 } }, // (x87)
1895 { ISD::FMUL, MVT::f64, { 2, 5, 1, 1 } }, // (x87)
1896 { ISD::FDIV, MVT::f64, { 38, 38, 1, 1 } }, // (x87)
1897 };
1898
1899 if (const auto *Entry = CostTableLookup(X86CostTbl, ISD, LT.second))
1900 if (auto KindCost = Entry->Cost[CostKind])
1901 return LT.first * *KindCost;
1902
1903 // It is not a good idea to vectorize division. We have to scalarize it and
1904 // in the process we will often end up having to spilling regular
1905 // registers. The overhead of division is going to dominate most kernels
1906 // anyways so try hard to prevent vectorization of division - it is
1907 // generally a bad idea. Assume somewhat arbitrarily that we have to be able
1908 // to hide "20 cycles" for each lane.
1909 if (CostKind == TTI::TCK_RecipThroughput && LT.second.isVector() &&
1910 (ISD == ISD::SDIV || ISD == ISD::SREM || ISD == ISD::UDIV ||
1911 ISD == ISD::UREM)) {
1912 InstructionCost ScalarCost =
1913 getArithmeticInstrCost(Opcode, Ty->getScalarType(), CostKind,
1914 Op1Info.getNoProps(), Op2Info.getNoProps());
1915 return 20 * LT.first * LT.second.getVectorNumElements() * ScalarCost;
1916 }
1917
1918 // Handle some basic single instruction code size cases.
1919 if (CostKind == TTI::TCK_CodeSize) {
1920 switch (ISD) {
1921 case ISD::FADD:
1922 case ISD::FSUB:
1923 case ISD::FMUL:
1924 case ISD::FDIV:
1925 case ISD::FNEG:
1926 case ISD::AND:
1927 case ISD::OR:
1928 case ISD::XOR:
1929 return LT.first;
1930 break;
1931 }
1932 }
1933
1934 // Fallback to the default implementation.
1935 return BaseT::getArithmeticInstrCost(Opcode, Ty, CostKind, Op1Info, Op2Info,
1936 Args, CxtI);
1937}
1938
1941 unsigned Opcode1, const SmallBitVector &OpcodeMask,
1943 if (isLegalAltInstr(VecTy, Opcode0, Opcode1, OpcodeMask))
1944 return TTI::TCC_Basic;
1946}
1947
1949 VectorType *DstTy, VectorType *SrcTy,
1951 ArrayRef<int> Mask, int Index,
1952 VectorType *SubTp,
1954 const Instruction *CxtI) const {
1955 assert((Mask.empty() || DstTy->isScalableTy() ||
1956 Mask.size() == DstTy->getElementCount().getKnownMinValue()) &&
1957 "Expected the Mask to match the return size if given");
1958 assert(SrcTy->getScalarType() == DstTy->getScalarType() &&
1959 "Expected the same scalar types");
1960
1961 // 64-bit packed float vectors (v2f32) are widened to type v4f32.
1962 // 64-bit packed integer vectors (v2i32) are widened to type v4i32.
1963 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(SrcTy);
1964
1965 Kind = improveShuffleKindFromMask(Kind, Mask, SrcTy, Index, SubTp);
1966
1967 // If all args are constant than this will be constant folded away.
1968 if (!Args.empty() &&
1969 all_of(Args, [](const Value *Arg) { return isa<Constant>(Arg); }))
1970 return TTI::TCC_Free;
1971
1972 // Recognize a basic concat_vector shuffle.
1973 if (Kind == TTI::SK_PermuteTwoSrc &&
1974 Mask.size() == (2 * SrcTy->getElementCount().getKnownMinValue()) &&
1975 ShuffleVectorInst::isIdentityMask(Mask, Mask.size()))
1979 CostKind, Mask, Mask.size() / 2, SrcTy);
1980
1981 // Treat Transpose as 2-op shuffles - there's no difference in lowering.
1982 if (Kind == TTI::SK_Transpose)
1983 if (LT.second != MVT::v4f64 && LT.second != MVT::v4i64)
1984 Kind = TTI::SK_PermuteTwoSrc;
1985
1986 if (Kind == TTI::SK_Broadcast) {
1987 // For Broadcasts we are splatting the first element from the first input
1988 // register, so only need to reference that input and all the output
1989 // registers are the same.
1990 LT.first = 1;
1991
1992 // If we're broadcasting a load then AVX/AVX2 can do this for free.
1993 // If many-used-load whose every use is one of a small set of operations
1994 // that SLP can rewrite into a single vector lane, codegen can fold it into
1995 // the free broadcast.
1996 using namespace PatternMatch;
1997 auto IsBroadcastLoadFoldUser = [&](const User *U) {
1998 if (isa<InsertElementInst>(U) && U->getOperand(1) == Args[0])
1999 return true;
2000 if (U->getType()->isVectorTy())
2001 return false;
2002 // Terminators (return/branch/switch/indirectbr/resume/invoke EH)
2003 // and phis carry the value across control flow.
2004 if (const auto *I = dyn_cast<Instruction>(U))
2005 if (I->isTerminator() ||
2007 return false;
2008 // Only pure calls can be folded.
2009 if (const auto *CB = dyn_cast<CallBase>(U))
2010 return CB->doesNotAccessMemory() && !CB->mayHaveSideEffects();
2011 return true;
2012 };
2013 auto IsFoldableSLPBroadcastLoad = [&]() {
2014 if (!match(Args[0], m_Load(m_Value())))
2015 return false;
2016 auto *FVT = dyn_cast<FixedVectorType>(DstTy);
2017 if (!FVT)
2018 return false;
2019 // getNumUses() counts each Use, matching the per-lane broadcast
2020 // accounting (a use like `op %x, %x` consumes two broadcast lanes).
2021 if (Args[0]->getNumUses() != FVT->getNumElements())
2022 return false;
2023 return all_of(Args[0]->users(), IsBroadcastLoadFoldUser);
2024 };
2025 if (!Args.empty() &&
2026 (match(Args[0], m_OneUse(m_Load(m_Value()))) ||
2027 IsFoldableSLPBroadcastLoad()) &&
2028 (ST->hasAVX2() ||
2029 (ST->hasAVX() && LT.second.getScalarSizeInBits() >= 32)))
2030 return TTI::TCC_Free;
2031 }
2032
2033 // Attempt to detect a cheaper inlane shuffle, avoiding 128-bit subvector
2034 // permutation.
2035 // Attempt to detect a shuffle mask with a single defined element.
2036 bool IsInLaneShuffle = false;
2037 bool IsSingleElementMask = false;
2038 if (SrcTy->getPrimitiveSizeInBits() > 0 &&
2039 (SrcTy->getPrimitiveSizeInBits() % 128) == 0 &&
2040 SrcTy->getScalarSizeInBits() == LT.second.getScalarSizeInBits() &&
2041 Mask.size() == SrcTy->getElementCount().getKnownMinValue()) {
2042 unsigned NumLanes = SrcTy->getPrimitiveSizeInBits() / 128;
2043 unsigned NumEltsPerLane = Mask.size() / NumLanes;
2044 if ((Mask.size() % NumLanes) == 0) {
2045 IsInLaneShuffle = all_of(enumerate(Mask), [&](const auto &P) {
2046 return P.value() == PoisonMaskElem ||
2047 ((P.value() % Mask.size()) / NumEltsPerLane) ==
2048 (P.index() / NumEltsPerLane);
2049 });
2050 IsSingleElementMask =
2051 (Mask.size() - 1) == static_cast<unsigned>(count_if(Mask, [](int M) {
2052 return M == PoisonMaskElem;
2053 }));
2054 }
2055 }
2056
2057 // Treat <X x bfloat> shuffles as <X x half>.
2058 if (LT.second.isVectorOf(MVT::bf16))
2059 LT.second = LT.second.changeVectorElementType(MVT::f16);
2060
2061 // Subvector extractions are free if they start at the beginning of a
2062 // vector and cheap if the subvectors are aligned.
2063 if (Kind == TTI::SK_ExtractSubvector && LT.second.isVector()) {
2064 int NumElts = LT.second.getVectorNumElements();
2065 if ((Index % NumElts) == 0)
2066 return TTI::TCC_Free;
2067 std::pair<InstructionCost, MVT> SubLT = getTypeLegalizationCost(SubTp);
2068 if (SubLT.second.isVector()) {
2069 int NumSubElts = SubLT.second.getVectorNumElements();
2070 if ((Index % NumSubElts) == 0 && (NumElts % NumSubElts) == 0)
2071 return SubLT.first;
2072 // Handle some cases for widening legalization. For now we only handle
2073 // cases where the original subvector was naturally aligned and evenly
2074 // fit in its legalized subvector type.
2075 // FIXME: Remove some of the alignment restrictions.
2076 // FIXME: We can use permq for 64-bit or larger extracts from 256-bit
2077 // vectors.
2078 int OrigSubElts = cast<FixedVectorType>(SubTp)->getNumElements();
2079 if (NumSubElts > OrigSubElts && (Index % OrigSubElts) == 0 &&
2080 (NumSubElts % OrigSubElts) == 0 &&
2081 LT.second.getVectorElementType() ==
2082 SubLT.second.getVectorElementType() &&
2083 LT.second.getVectorElementType().getSizeInBits() ==
2084 SrcTy->getElementType()->getPrimitiveSizeInBits()) {
2085 assert(NumElts >= NumSubElts && NumElts > OrigSubElts &&
2086 "Unexpected number of elements!");
2087 auto *VecTy = FixedVectorType::get(SrcTy->getElementType(),
2088 LT.second.getVectorNumElements());
2089 auto *SubTy = FixedVectorType::get(SrcTy->getElementType(),
2090 SubLT.second.getVectorNumElements());
2091 int ExtractIndex = alignDown((Index % NumElts), NumSubElts);
2092 InstructionCost ExtractCost =
2094 ExtractIndex, SubTy);
2095
2096 // If the original size is 32-bits or more, we can use pshufd. Otherwise
2097 // if we have SSSE3 we can use pshufb.
2098 if (SubTp->getPrimitiveSizeInBits() >= 32 || ST->hasSSSE3())
2099 return ExtractCost + 1; // pshufd or pshufb
2100
2101 assert(SubTp->getPrimitiveSizeInBits() == 16 &&
2102 "Unexpected vector size");
2103
2104 return ExtractCost + 2; // worst case pshufhw + pshufd
2105 }
2106 }
2107 // If the extract subvector is not optimal, treat it as single op shuffle.
2109 }
2110
2111 // Subvector insertions are cheap if the subvectors are aligned.
2112 // Note that in general, the insertion starting at the beginning of a vector
2113 // isn't free, because we need to preserve the rest of the wide vector,
2114 // but if the destination vector legalizes to the same width as the subvector
2115 // then the insertion will simplify to a (free) register copy.
2116 if (Kind == TTI::SK_InsertSubvector && LT.second.isVector()) {
2117 std::pair<InstructionCost, MVT> DstLT = getTypeLegalizationCost(DstTy);
2118 int NumElts = DstLT.second.getVectorNumElements();
2119 std::pair<InstructionCost, MVT> SubLT = getTypeLegalizationCost(SubTp);
2120 if (SubLT.second.isVector()) {
2121 int NumSubElts = SubLT.second.getVectorNumElements();
2122 bool MatchingTypes =
2123 NumElts == NumSubElts &&
2124 (SubTp->getElementCount().getKnownMinValue() % NumSubElts) == 0;
2125 if ((Index % NumSubElts) == 0 && (NumElts % NumSubElts) == 0)
2126 return MatchingTypes ? TTI::TCC_Free : SubLT.first;
2127 }
2128
2129 // Attempt to match MOVSS (Idx == 0) or INSERTPS pattern. This will have
2130 // been matched by improveShuffleKindFromMask as a SK_InsertSubvector of
2131 // v1f32 (legalised to f32) into a v4f32.
2132 if (LT.first == 1 && LT.second == MVT::v4f32 && SubLT.first == 1 &&
2133 SubLT.second == MVT::f32 && (Index == 0 || ST->hasSSE41()))
2134 return 1;
2135
2136 // If the insertion is the lowest subvector then it will be blended
2137 // otherwise treat it like a 2-op shuffle.
2138 Kind =
2139 (Index == 0 && LT.first == 1) ? TTI::SK_Select : TTI::SK_PermuteTwoSrc;
2140 }
2141
2142 // Handle some common (illegal) sub-vector types as they are often very cheap
2143 // to shuffle even on targets without PSHUFB.
2144 EVT VT = TLI->getValueType(DL, SrcTy);
2145 if (VT.isSimple() && VT.isVector() && VT.getSizeInBits() < 128 &&
2146 !ST->hasSSSE3()) {
2147 static const CostKindTblEntry SSE2SubVectorShuffleTbl[] = {
2148 {TTI::SK_Broadcast, MVT::v4i16, {1,1,1,1}}, // pshuflw
2149 {TTI::SK_Broadcast, MVT::v2i16, {1,1,1,1}}, // pshuflw
2150 {TTI::SK_Broadcast, MVT::v8i8, {2,2,2,2}}, // punpck/pshuflw
2151 {TTI::SK_Broadcast, MVT::v4i8, {2,2,2,2}}, // punpck/pshuflw
2152 {TTI::SK_Broadcast, MVT::v2i8, {1,1,1,1}}, // punpck
2153
2154 {TTI::SK_Reverse, MVT::v4i16, {1,1,1,1}}, // pshuflw
2155 {TTI::SK_Reverse, MVT::v2i16, {1,1,1,1}}, // pshuflw
2156 {TTI::SK_Reverse, MVT::v4i8, {3,3,3,3}}, // punpck/pshuflw/packus
2157 {TTI::SK_Reverse, MVT::v2i8, {1,1,1,1}}, // punpck
2158
2159 {TTI::SK_Splice, MVT::v4i16, {2,2,2,2}}, // punpck+psrldq
2160 {TTI::SK_Splice, MVT::v2i16, {2,2,2,2}}, // punpck+psrldq
2161 {TTI::SK_Splice, MVT::v4i8, {2,2,2,2}}, // punpck+psrldq
2162 {TTI::SK_Splice, MVT::v2i8, {2,2,2,2}}, // punpck+psrldq
2163
2164 {TTI::SK_PermuteTwoSrc, MVT::v4i16, {2,2,2,2}}, // punpck/pshuflw
2165 {TTI::SK_PermuteTwoSrc, MVT::v2i16, {2,2,2,2}}, // punpck/pshuflw
2166 {TTI::SK_PermuteTwoSrc, MVT::v8i8, {7,7,7,7}}, // punpck/pshuflw
2167 {TTI::SK_PermuteTwoSrc, MVT::v4i8, {4,4,4,4}}, // punpck/pshuflw
2168 {TTI::SK_PermuteTwoSrc, MVT::v2i8, {2,2,2,2}}, // punpck
2169
2170 {TTI::SK_PermuteSingleSrc, MVT::v4i16, {1,1,1,1}}, // pshuflw
2171 {TTI::SK_PermuteSingleSrc, MVT::v2i16, {1,1,1,1}}, // pshuflw
2172 {TTI::SK_PermuteSingleSrc, MVT::v8i8, {5,5,5,5}}, // punpck/pshuflw
2173 {TTI::SK_PermuteSingleSrc, MVT::v4i8, {3,3,3,3}}, // punpck/pshuflw
2174 {TTI::SK_PermuteSingleSrc, MVT::v2i8, {1,1,1,1}}, // punpck
2175 };
2176
2177 if (ST->hasSSE2())
2178 if (const auto *Entry =
2179 CostTableLookup(SSE2SubVectorShuffleTbl, Kind, VT.getSimpleVT()))
2180 if (auto KindCost = Entry->Cost[CostKind])
2181 return LT.first * *KindCost;
2182 }
2183
2184 // We are going to permute multiple sources and the result will be in multiple
2185 // destinations. Providing an accurate cost only for splits where the element
2186 // type remains the same.
2187 if (LT.first != 1) {
2188 MVT LegalVT = LT.second;
2189 if (LegalVT.isVector() &&
2190 LegalVT.getVectorElementType().getSizeInBits() ==
2191 SrcTy->getElementType()->getPrimitiveSizeInBits() &&
2192 LegalVT.getVectorNumElements() <
2193 cast<FixedVectorType>(SrcTy)->getNumElements()) {
2194 unsigned VecTySize = DL.getTypeStoreSize(SrcTy);
2195 unsigned LegalVTSize = LegalVT.getStoreSize();
2196 // Number of source vectors after legalization:
2197 unsigned NumOfSrcs = (VecTySize + LegalVTSize - 1) / LegalVTSize;
2198 // Number of destination vectors after legalization:
2199 InstructionCost NumOfDests = LT.first;
2200
2201 auto *SingleOpTy = FixedVectorType::get(SrcTy->getElementType(),
2202 LegalVT.getVectorNumElements());
2203
2204 if (!Mask.empty() && NumOfDests.isValid()) {
2205 // Try to perform better estimation of the permutation.
2206 // 1. Split the source/destination vectors into real registers.
2207 // 2. Do the mask analysis to identify which real registers are
2208 // permuted. If more than 1 source registers are used for the
2209 // destination register building, the cost for this destination register
2210 // is (Number_of_source_register - 1) * Cost_PermuteTwoSrc. If only one
2211 // source register is used, build mask and calculate the cost as a cost
2212 // of PermuteSingleSrc.
2213 // Also, for the single register permute we try to identify if the
2214 // destination register is just a copy of the source register or the
2215 // copy of the previous destination register (the cost is
2216 // TTI::TCC_Basic). If the source register is just reused, the cost for
2217 // this operation is TTI::TCC_Free.
2218 NumOfDests =
2220 FixedVectorType::get(SrcTy->getElementType(), Mask.size()))
2221 .first;
2222 unsigned E = NumOfDests.getValue();
2223 unsigned NormalizedVF =
2224 LegalVT.getVectorNumElements() * std::max(NumOfSrcs, E);
2225 unsigned NumOfSrcRegs = NormalizedVF / LegalVT.getVectorNumElements();
2226 unsigned NumOfDestRegs = NormalizedVF / LegalVT.getVectorNumElements();
2227 SmallVector<int> NormalizedMask(NormalizedVF, PoisonMaskElem);
2228 copy(Mask, NormalizedMask.begin());
2229 unsigned PrevSrcReg = 0;
2230 ArrayRef<int> PrevRegMask;
2233 NormalizedMask, NumOfSrcRegs, NumOfDestRegs, NumOfDestRegs, []() {},
2234 [this, SingleOpTy, CostKind, &PrevSrcReg, &PrevRegMask,
2235 &Cost](ArrayRef<int> RegMask, unsigned SrcReg, unsigned DestReg) {
2236 if (!ShuffleVectorInst::isIdentityMask(RegMask, RegMask.size())) {
2237 // Check if the previous register can be just copied to the next
2238 // one.
2239 if (PrevRegMask.empty() || PrevSrcReg != SrcReg ||
2240 PrevRegMask != RegMask)
2241 Cost +=
2243 SingleOpTy, CostKind, RegMask, 0, nullptr);
2244 else
2245 // Just a copy of previous destination register.
2247 return;
2248 }
2249 if (SrcReg != DestReg &&
2250 any_of(RegMask, not_equal_to(PoisonMaskElem))) {
2251 // Just a copy of the source register.
2253 }
2254 PrevSrcReg = SrcReg;
2255 PrevRegMask = RegMask;
2256 },
2257 [this, SingleOpTy, CostKind,
2258 &Cost](ArrayRef<int> RegMask, unsigned /*Unused*/,
2259 unsigned /*Unused*/, bool /*Unused*/) {
2261 SingleOpTy, CostKind, RegMask, 0, nullptr);
2262 });
2263 return Cost;
2264 }
2265
2266 InstructionCost NumOfShuffles = (NumOfSrcs - 1) * NumOfDests;
2267 return NumOfShuffles * getShuffleCost(TTI::SK_PermuteTwoSrc, SingleOpTy,
2268 SingleOpTy, CostKind, {}, 0,
2269 nullptr);
2270 }
2271
2272 return BaseT::getShuffleCost(Kind, DstTy, SrcTy, CostKind, Mask, Index,
2273 SubTp);
2274 }
2275
2276 // If we're just moving a single element around (probably as an alternative to
2277 // extracting it), we can assume this is cheap.
2278 if (LT.first == 1 && IsInLaneShuffle && IsSingleElementMask)
2279 return TTI::TCC_Basic;
2280
2281 static const CostKindTblEntry AVX512VBMIShuffleTbl[] = {
2282 { TTI::SK_Reverse, MVT::v64i8, { 1, 1, 1, 1 } }, // vpermb
2283 { TTI::SK_Reverse, MVT::v32i8, { 1, 1, 1, 1 } }, // vpermb
2284 { TTI::SK_PermuteSingleSrc, MVT::v64i8, { 1, 1, 1, 1 } }, // vpermb
2285 { TTI::SK_PermuteSingleSrc, MVT::v32i8, { 1, 1, 1, 1 } }, // vpermb
2286 { TTI::SK_PermuteTwoSrc, MVT::v64i8, { 2, 2, 2, 2 } }, // vpermt2b
2287 { TTI::SK_PermuteTwoSrc, MVT::v32i8, { 2, 2, 2, 2 } }, // vpermt2b
2288 { TTI::SK_PermuteTwoSrc, MVT::v16i8, { 2, 2, 2, 2 } } // vpermt2b
2289 };
2290
2291 if (ST->hasVBMI())
2292 if (const auto *Entry =
2293 CostTableLookup(AVX512VBMIShuffleTbl, Kind, LT.second))
2294 if (auto KindCost = Entry->Cost[CostKind])
2295 return LT.first * *KindCost;
2296
2297 static const CostKindTblEntry AVX512BWShuffleTbl[] = {
2298 { TTI::SK_Broadcast, MVT::v32i16, { 1, 3, 1, 1 } }, // vpbroadcastw
2299 { TTI::SK_Broadcast, MVT::v32f16, { 1, 3, 1, 1 } }, // vpbroadcastw
2300 { TTI::SK_Broadcast, MVT::v64i8, { 1, 3, 1, 1 } }, // vpbroadcastb
2301
2302 { TTI::SK_Reverse, MVT::v32i16, { 2, 6, 2, 4 } }, // vpermw
2303 { TTI::SK_Reverse, MVT::v32f16, { 2, 6, 2, 4 } }, // vpermw
2304 { TTI::SK_Reverse, MVT::v16i16, { 2, 2, 2, 2 } }, // vpermw
2305 { TTI::SK_Reverse, MVT::v16f16, { 2, 2, 2, 2 } }, // vpermw
2306 { TTI::SK_Reverse, MVT::v64i8, { 2, 9, 2, 3 } }, // pshufb + vshufi64x2
2307
2308 { TTI::SK_PermuteSingleSrc, MVT::v32i16, { 2, 2, 2, 2 } }, // vpermw
2309 { TTI::SK_PermuteSingleSrc, MVT::v32f16, { 2, 2, 2, 2 } }, // vpermw
2310 { TTI::SK_PermuteSingleSrc, MVT::v16i16, { 2, 2, 2, 2 } }, // vpermw
2311 { TTI::SK_PermuteSingleSrc, MVT::v16f16, { 2, 2, 2, 2 } }, // vpermw
2312 { TTI::SK_PermuteSingleSrc, MVT::v64i8, { 8, 8, 8, 8 } }, // extend to v32i16
2313
2314 { TTI::SK_PermuteTwoSrc, MVT::v32i16,{ 2, 2, 2, 2 } }, // vpermt2w
2315 { TTI::SK_PermuteTwoSrc, MVT::v32f16,{ 2, 2, 2, 2 } }, // vpermt2w
2316 { TTI::SK_PermuteTwoSrc, MVT::v16i16,{ 2, 2, 2, 2 } }, // vpermt2w
2317 { TTI::SK_PermuteTwoSrc, MVT::v8i16, { 2, 2, 2, 2 } }, // vpermt2w
2318 { TTI::SK_PermuteTwoSrc, MVT::v64i8, { 19, 19, 19, 19 } }, // 6 * v32i8 + 1
2319
2320 { TTI::SK_Select, MVT::v32i16, { 1, 1, 1, 1 } }, // vblendmw
2321 { TTI::SK_Select, MVT::v64i8, { 1, 1, 1, 1 } }, // vblendmb
2322
2323 { TTI::SK_Splice, MVT::v32i16, { 2, 2, 2, 2 } }, // vshufi64x2 + palignr
2324 { TTI::SK_Splice, MVT::v32f16, { 2, 2, 2, 2 } }, // vshufi64x2 + palignr
2325 { TTI::SK_Splice, MVT::v64i8, { 2, 2, 2, 2 } }, // vshufi64x2 + palignr
2326 };
2327
2328 if (ST->hasBWI())
2329 if (const auto *Entry =
2330 CostTableLookup(AVX512BWShuffleTbl, Kind, LT.second))
2331 if (auto KindCost = Entry->Cost[CostKind])
2332 return LT.first * *KindCost;
2333
2334 static const CostKindTblEntry AVX512InLaneShuffleTbl[] = {
2335 {TTI::SK_PermuteTwoSrc, MVT::v8f64, { 1, 3, 1, 1 } },
2336 {TTI::SK_PermuteTwoSrc, MVT::v16f32, { 1, 3, 1, 1 } },
2337 {TTI::SK_PermuteTwoSrc, MVT::v8i64, { 1, 3, 1, 1 } },
2338 {TTI::SK_PermuteTwoSrc, MVT::v16i32, { 1, 3, 1, 1 } },
2339 {TTI::SK_PermuteTwoSrc, MVT::v4f64, { 1, 3, 1, 1 } },
2340 {TTI::SK_PermuteTwoSrc, MVT::v8f32, { 1, 3, 1, 1 } },
2341 {TTI::SK_PermuteTwoSrc, MVT::v4i64, { 1, 3, 1, 1 } },
2342 {TTI::SK_PermuteTwoSrc, MVT::v8i32, { 1, 3, 1, 1 } },
2343 };
2344
2345 if (IsInLaneShuffle && ST->hasAVX512())
2346 if (const auto *Entry =
2347 CostTableLookup(AVX512InLaneShuffleTbl, Kind, LT.second))
2348 if (auto KindCost = Entry->Cost[CostKind])
2349 return LT.first * *KindCost;
2350
2351 static const CostKindTblEntry AVX512ShuffleTbl[] = {
2352 {TTI::SK_Broadcast, MVT::v8f64, { 1, 3, 1, 1 } }, // vbroadcastsd
2353 {TTI::SK_Broadcast, MVT::v4f64, { 1, 3, 1, 1 } }, // vbroadcastsd
2354 {TTI::SK_Broadcast, MVT::v16f32, { 1, 3, 1, 1 } }, // vbroadcastss
2355 {TTI::SK_Broadcast, MVT::v8f32, { 1, 3, 1, 1 } }, // vbroadcastss
2356 {TTI::SK_Broadcast, MVT::v8i64, { 1, 3, 1, 1 } }, // vpbroadcastq
2357 {TTI::SK_Broadcast, MVT::v4i64, { 1, 3, 1, 1 } }, // vpbroadcastq
2358 {TTI::SK_Broadcast, MVT::v16i32, { 1, 3, 1, 1 } }, // vpbroadcastd
2359 {TTI::SK_Broadcast, MVT::v8i32, { 1, 3, 1, 1 } }, // vpbroadcastd
2360 {TTI::SK_Broadcast, MVT::v32i16, { 1, 3, 1, 1 } }, // vpbroadcastw
2361 {TTI::SK_Broadcast, MVT::v16i16, { 1, 3, 1, 1 } }, // vpbroadcastw
2362 {TTI::SK_Broadcast, MVT::v32f16, { 1, 3, 1, 1 } }, // vpbroadcastw
2363 {TTI::SK_Broadcast, MVT::v16f16, { 1, 3, 1, 1 } }, // vpbroadcastw
2364 {TTI::SK_Broadcast, MVT::v64i8, { 1, 3, 1, 1 } }, // vpbroadcastb
2365 {TTI::SK_Broadcast, MVT::v32i8, { 1, 3, 1, 1 }}, // vpbroadcastb
2366
2367 {TTI::SK_Reverse, MVT::v8f64, { 1, 5, 2, 3 } }, // vpermpd
2368 {TTI::SK_Reverse, MVT::v16f32, { 1, 3, 2, 3 } }, // vpermps
2369 {TTI::SK_Reverse, MVT::v8i64, { 1, 5, 2, 3 } }, // vpermq
2370 {TTI::SK_Reverse, MVT::v16i32, { 1, 3, 2, 3 } }, // vpermd
2371 {TTI::SK_Reverse, MVT::v32i16, { 7, 7, 7, 7 } }, // per mca
2372 {TTI::SK_Reverse, MVT::v32f16, { 7, 7, 7, 7 } }, // per mca
2373 {TTI::SK_Reverse, MVT::v64i8, { 7, 7, 7, 7 } }, // per mca
2374
2375 {TTI::SK_Splice, MVT::v8f64, { 1, 1, 1, 1 } }, // vpalignd
2376 {TTI::SK_Splice, MVT::v4f64, { 1, 1, 1, 1 } }, // vpalignd
2377 {TTI::SK_Splice, MVT::v16f32, { 1, 1, 1, 1 } }, // vpalignd
2378 {TTI::SK_Splice, MVT::v8f32, { 1, 1, 1, 1 } }, // vpalignd
2379 {TTI::SK_Splice, MVT::v8i64, { 1, 1, 1, 1 } }, // vpalignd
2380 {TTI::SK_Splice, MVT::v4i64, { 1, 1, 1, 1 } }, // vpalignd
2381 {TTI::SK_Splice, MVT::v16i32, { 1, 1, 1, 1 } }, // vpalignd
2382 {TTI::SK_Splice, MVT::v8i32, { 1, 1, 1, 1 } }, // vpalignd
2383 {TTI::SK_Splice, MVT::v32i16, { 4, 4, 4, 4 } }, // split + palignr
2384 {TTI::SK_Splice, MVT::v32f16, { 4, 4, 4, 4 } }, // split + palignr
2385 {TTI::SK_Splice, MVT::v64i8, { 4, 4, 4, 4 } }, // split + palignr
2386
2387 {TTI::SK_PermuteSingleSrc, MVT::v8f64, { 1, 3, 1, 1 } }, // vpermpd
2388 {TTI::SK_PermuteSingleSrc, MVT::v4f64, { 1, 3, 1, 1 } }, // vpermpd
2389 {TTI::SK_PermuteSingleSrc, MVT::v2f64, { 1, 3, 1, 1 } }, // vpermpd
2390 {TTI::SK_PermuteSingleSrc, MVT::v16f32, { 1, 3, 1, 1 } }, // vpermps
2391 {TTI::SK_PermuteSingleSrc, MVT::v8f32, { 1, 3, 1, 1 } }, // vpermps
2392 {TTI::SK_PermuteSingleSrc, MVT::v4f32, { 1, 3, 1, 1 } }, // vpermps
2393 {TTI::SK_PermuteSingleSrc, MVT::v8i64, { 1, 3, 1, 1 } }, // vpermq
2394 {TTI::SK_PermuteSingleSrc, MVT::v4i64, { 1, 3, 1, 1 } }, // vpermq
2395 {TTI::SK_PermuteSingleSrc, MVT::v2i64, { 1, 3, 1, 1 } }, // vpermq
2396 {TTI::SK_PermuteSingleSrc, MVT::v16i32, { 1, 3, 1, 1 } }, // vpermd
2397 {TTI::SK_PermuteSingleSrc, MVT::v8i32, { 1, 3, 1, 1 } }, // vpermd
2398 {TTI::SK_PermuteSingleSrc, MVT::v4i32, { 1, 3, 1, 1 } }, // vpermd
2399 {TTI::SK_PermuteSingleSrc, MVT::v16i8, { 1, 3, 1, 1 } }, // pshufb
2400
2401 {TTI::SK_PermuteTwoSrc, MVT::v8f64, { 2, 3, 1, 1 } }, // vpermt2pd
2402 {TTI::SK_PermuteTwoSrc, MVT::v16f32, { 2, 3, 1, 1 } }, // vpermt2ps
2403 {TTI::SK_PermuteTwoSrc, MVT::v8i64, { 2, 3, 1, 1 } }, // vpermt2q
2404 {TTI::SK_PermuteTwoSrc, MVT::v16i32, { 2, 3, 1, 1 } }, // vpermt2d
2405 {TTI::SK_PermuteTwoSrc, MVT::v4f64, { 2, 3, 1, 1 } }, // vpermt2pd
2406 {TTI::SK_PermuteTwoSrc, MVT::v8f32, { 2, 3, 1, 1 } }, // vpermt2ps
2407 {TTI::SK_PermuteTwoSrc, MVT::v4i64, { 2, 3, 1, 1 } }, // vpermt2q
2408 {TTI::SK_PermuteTwoSrc, MVT::v8i32, { 2, 3, 1, 1 } }, // vpermt2d
2409 {TTI::SK_PermuteTwoSrc, MVT::v2f64, { 1, 3, 1, 1 } },
2410 {TTI::SK_PermuteTwoSrc, MVT::v4f32, { 1, 3, 1, 1 } },
2411 {TTI::SK_PermuteTwoSrc, MVT::v2i64, { 1, 3, 1, 1 } },
2412 {TTI::SK_PermuteTwoSrc, MVT::v4i32, { 1, 3, 1, 1 } },
2413
2414 // FIXME: This just applies the type legalization cost rules above
2415 // assuming these completely split.
2416 {TTI::SK_PermuteSingleSrc, MVT::v32i16, { 14, 14, 14, 14 } },
2417 {TTI::SK_PermuteSingleSrc, MVT::v32f16, { 14, 14, 14, 14 } },
2418 {TTI::SK_PermuteSingleSrc, MVT::v64i8, { 14, 14, 14, 14 } },
2419 {TTI::SK_PermuteTwoSrc, MVT::v32i16, { 42, 42, 42, 42 } },
2420 {TTI::SK_PermuteTwoSrc, MVT::v32f16, { 42, 42, 42, 42 } },
2421 {TTI::SK_PermuteTwoSrc, MVT::v64i8, { 42, 42, 42, 42 } },
2422
2423 {TTI::SK_Select, MVT::v32i16, { 1, 1, 1, 1 } }, // vpternlogq
2424 {TTI::SK_Select, MVT::v32f16, { 1, 1, 1, 1 } }, // vpternlogq
2425 {TTI::SK_Select, MVT::v64i8, { 1, 1, 1, 1 } }, // vpternlogq
2426 {TTI::SK_Select, MVT::v8f64, { 1, 1, 1, 1 } }, // vblendmpd
2427 {TTI::SK_Select, MVT::v16f32, { 1, 1, 1, 1 } }, // vblendmps
2428 {TTI::SK_Select, MVT::v8i64, { 1, 1, 1, 1 } }, // vblendmq
2429 {TTI::SK_Select, MVT::v16i32, { 1, 1, 1, 1 } }, // vblendmd
2430 };
2431
2432 if (ST->hasAVX512())
2433 if (const auto *Entry = CostTableLookup(AVX512ShuffleTbl, Kind, LT.second))
2434 if (auto KindCost = Entry->Cost[CostKind])
2435 return LT.first * *KindCost;
2436
2437 static const CostKindTblEntry AVX2InLaneShuffleTbl[] = {
2438 { TTI::SK_PermuteSingleSrc, MVT::v16i16, { 1, 1, 1, 1 } }, // vpshufb
2439 { TTI::SK_PermuteSingleSrc, MVT::v16f16, { 1, 1, 1, 1 } }, // vpshufb
2440 { TTI::SK_PermuteSingleSrc, MVT::v32i8, { 1, 1, 1, 1 } }, // vpshufb
2441
2442 { TTI::SK_Transpose, MVT::v4f64, { 1, 1, 1, 1 } }, // vshufpd/vunpck
2443 { TTI::SK_Transpose, MVT::v4i64, { 1, 1, 1, 1 } }, // vshufpd/vunpck
2444
2445 { TTI::SK_PermuteTwoSrc, MVT::v4f64, { 2, 2, 2, 2 } }, // 2*vshufpd + vblendpd
2446 { TTI::SK_PermuteTwoSrc, MVT::v8f32, { 2, 2, 2, 2 } }, // 2*vshufps + vblendps
2447 { TTI::SK_PermuteTwoSrc, MVT::v4i64, { 2, 2, 2, 2 } }, // 2*vpshufd + vpblendd
2448 { TTI::SK_PermuteTwoSrc, MVT::v8i32, { 2, 2, 2, 2 } }, // 2*vpshufd + vpblendd
2449 { TTI::SK_PermuteTwoSrc, MVT::v16i16, { 2, 2, 2, 2 } }, // 2*vpshufb + vpor
2450 { TTI::SK_PermuteTwoSrc, MVT::v16f16, { 2, 2, 2, 2 } }, // 2*vpshufb + vpor
2451 { TTI::SK_PermuteTwoSrc, MVT::v32i8, { 2, 2, 2, 2 } }, // 2*vpshufb + vpor
2452 };
2453
2454 if (IsInLaneShuffle && ST->hasAVX2())
2455 if (const auto *Entry =
2456 CostTableLookup(AVX2InLaneShuffleTbl, Kind, LT.second))
2457 if (auto KindCost = Entry->Cost[CostKind])
2458 return LT.first * *KindCost;
2459
2460 static const CostKindTblEntry AVX2ShuffleTbl[] = {
2461 { TTI::SK_Broadcast, MVT::v4f64, { 1, 3, 1, 2 } }, // vbroadcastpd
2462 { TTI::SK_Broadcast, MVT::v8f32, { 1, 3, 1, 2 } }, // vbroadcastps
2463 { TTI::SK_Broadcast, MVT::v4i64, { 1, 3, 1, 2 } }, // vpbroadcastq
2464 { TTI::SK_Broadcast, MVT::v8i32, { 1, 3, 1, 2 } }, // vpbroadcastd
2465 { TTI::SK_Broadcast, MVT::v16i16, { 1, 3, 1, 2 } }, // vpbroadcastw
2466 { TTI::SK_Broadcast, MVT::v8i16, { 1, 3, 1, 1 } }, // vpbroadcastw
2467 { TTI::SK_Broadcast, MVT::v16f16, { 1, 3, 1, 2 } }, // vpbroadcastw
2468 { TTI::SK_Broadcast, MVT::v8f16, { 1, 3, 1, 1 } }, // vpbroadcastw
2469 { TTI::SK_Broadcast, MVT::v32i8, { 1, 3, 1, 2 } }, // vpbroadcastb
2470 { TTI::SK_Broadcast, MVT::v16i8, { 1, 3, 1, 1 } }, // vpbroadcastb
2471
2472 { TTI::SK_Reverse, MVT::v4f64, { 1, 6, 1, 2 } }, // vpermpd
2473 { TTI::SK_Reverse, MVT::v8f32, { 2, 7, 2, 4 } }, // vpermps
2474 { TTI::SK_Reverse, MVT::v4i64, { 1, 6, 1, 2 } }, // vpermq
2475 { TTI::SK_Reverse, MVT::v8i32, { 2, 7, 2, 4 } }, // vpermd
2476 { TTI::SK_Reverse, MVT::v16i16, { 2, 9, 2, 4 } }, // vperm2i128 + pshufb
2477 { TTI::SK_Reverse, MVT::v16f16, { 2, 9, 2, 4 } }, // vperm2i128 + pshufb
2478 { TTI::SK_Reverse, MVT::v32i8, { 2, 9, 2, 4 } }, // vperm2i128 + pshufb
2479
2480 { TTI::SK_Select, MVT::v16i16, { 1, 1, 1, 1 } }, // vpblendvb
2481 { TTI::SK_Select, MVT::v16f16, { 1, 1, 1, 1 } }, // vpblendvb
2482 { TTI::SK_Select, MVT::v32i8, { 1, 1, 1, 1 } }, // vpblendvb
2483
2484 { TTI::SK_Splice, MVT::v8i32, { 2, 2, 2, 2 } }, // vperm2i128 + vpalignr
2485 { TTI::SK_Splice, MVT::v8f32, { 2, 2, 2, 2 } }, // vperm2i128 + vpalignr
2486 { TTI::SK_Splice, MVT::v16i16, { 2, 2, 2, 2 } }, // vperm2i128 + vpalignr
2487 { TTI::SK_Splice, MVT::v16f16, { 2, 2, 2, 2 } }, // vperm2i128 + vpalignr
2488 { TTI::SK_Splice, MVT::v32i8, { 2, 2, 2, 2 } }, // vperm2i128 + vpalignr
2489
2490 { TTI::SK_PermuteSingleSrc, MVT::v4f64, { 1, 1, 1, 1 } }, // vpermpd
2491 { TTI::SK_PermuteSingleSrc, MVT::v8f32, { 1, 1, 1, 1 } }, // vpermps
2492 { TTI::SK_PermuteSingleSrc, MVT::v4i64, { 1, 1, 1, 1 } }, // vpermq
2493 { TTI::SK_PermuteSingleSrc, MVT::v8i32, { 1, 1, 1, 1 } }, // vpermd
2494 { TTI::SK_PermuteSingleSrc, MVT::v16i16, { 4, 4, 4, 4 } },
2495 { TTI::SK_PermuteSingleSrc, MVT::v16f16, { 4, 4, 4, 4 } },
2496 { TTI::SK_PermuteSingleSrc, MVT::v32i8, { 4, 4, 4, 4 } },
2497
2498 { TTI::SK_PermuteTwoSrc, MVT::v4f64, { 3, 3, 3, 3 } }, // 2*vpermpd + vblendpd
2499 { TTI::SK_PermuteTwoSrc, MVT::v8f32, { 3, 3, 3, 3 } }, // 2*vpermps + vblendps
2500 { TTI::SK_PermuteTwoSrc, MVT::v4i64, { 3, 3, 3, 3 } }, // 2*vpermq + vpblendd
2501 { TTI::SK_PermuteTwoSrc, MVT::v8i32, { 3, 3, 3, 3 } }, // 2*vpermd + vpblendd
2502 { TTI::SK_PermuteTwoSrc, MVT::v16i16, { 7, 7, 7, 7 } },
2503 { TTI::SK_PermuteTwoSrc, MVT::v16f16, { 7, 7, 7, 7 } },
2504 { TTI::SK_PermuteTwoSrc, MVT::v32i8, { 7, 7, 7, 7 } },
2505 };
2506
2507 if (ST->hasAVX2())
2508 if (const auto *Entry = CostTableLookup(AVX2ShuffleTbl, Kind, LT.second))
2509 if (auto KindCost = Entry->Cost[CostKind])
2510 return LT.first * *KindCost;
2511
2512 static const CostKindTblEntry XOPShuffleTbl[] = {
2513 { TTI::SK_PermuteSingleSrc, MVT::v4f64, { 2, 2, 2, 2 } }, // vperm2f128 + vpermil2pd
2514 { TTI::SK_PermuteSingleSrc, MVT::v8f32, { 2, 2, 2, 2 } }, // vperm2f128 + vpermil2ps
2515 { TTI::SK_PermuteSingleSrc, MVT::v4i64, { 2, 2, 2, 2 } }, // vperm2f128 + vpermil2pd
2516 { TTI::SK_PermuteSingleSrc, MVT::v8i32, { 2, 2, 2, 2 } }, // vperm2f128 + vpermil2ps
2517 { TTI::SK_PermuteSingleSrc, MVT::v16i16,{ 4, 4, 4, 4 } }, // vextractf128 + 2*vpperm
2518 // + vinsertf128
2519 { TTI::SK_PermuteSingleSrc, MVT::v32i8, { 4, 4, 4, 4 } }, // vextractf128 + 2*vpperm
2520 // + vinsertf128
2521
2522 { TTI::SK_PermuteTwoSrc, MVT::v16i16, { 9, 9, 9, 9 } }, // 2*vextractf128 + 6*vpperm
2523 // + vinsertf128
2524
2525 { TTI::SK_PermuteTwoSrc, MVT::v8i16, { 1, 1, 1, 1 } }, // vpperm
2526 { TTI::SK_PermuteTwoSrc, MVT::v32i8, { 9, 9, 9, 9 } }, // 2*vextractf128 + 6*vpperm
2527 // + vinsertf128
2528 { TTI::SK_PermuteTwoSrc, MVT::v16i8, { 1, 1, 1, 1 } }, // vpperm
2529 };
2530
2531 if (ST->hasXOP())
2532 if (const auto *Entry = CostTableLookup(XOPShuffleTbl, Kind, LT.second))
2533 if (auto KindCost = Entry->Cost[CostKind])
2534 return LT.first * *KindCost;
2535
2536 static const CostKindTblEntry AVX1InLaneShuffleTbl[] = {
2537 { TTI::SK_PermuteSingleSrc, MVT::v4f64, { 1, 1, 1, 1 } }, // vpermilpd
2538 { TTI::SK_PermuteSingleSrc, MVT::v4i64, { 1, 1, 1, 1 } }, // vpermilpd
2539 { TTI::SK_PermuteSingleSrc, MVT::v8f32, { 1, 1, 1, 1 } }, // vpermilps
2540 { TTI::SK_PermuteSingleSrc, MVT::v8i32, { 1, 1, 1, 1 } }, // vpermilps
2541
2542 { TTI::SK_PermuteSingleSrc, MVT::v16i16, { 4, 4, 4, 4 } }, // vextractf128 + 2*pshufb
2543 // + vpor + vinsertf128
2544 { TTI::SK_PermuteSingleSrc, MVT::v16f16, { 4, 4, 4, 4 } }, // vextractf128 + 2*pshufb
2545 // + vpor + vinsertf128
2546 { TTI::SK_PermuteSingleSrc, MVT::v32i8, { 4, 4, 4, 4 } }, // vextractf128 + 2*pshufb
2547 // + vpor + vinsertf128
2548
2549 { TTI::SK_Transpose, MVT::v4f64, { 1, 1, 1, 1 } }, // vshufpd/vunpck
2550 { TTI::SK_Transpose, MVT::v4i64, { 1, 1, 1, 1 } }, // vshufpd/vunpck
2551
2552 { TTI::SK_PermuteTwoSrc, MVT::v4f64, { 2, 2, 2, 2 } }, // 2*vshufpd + vblendpd
2553 { TTI::SK_PermuteTwoSrc, MVT::v8f32, { 2, 2, 2, 2 } }, // 2*vshufps + vblendps
2554 { TTI::SK_PermuteTwoSrc, MVT::v4i64, { 2, 2, 2, 2 } }, // 2*vpermilpd + vblendpd
2555 { TTI::SK_PermuteTwoSrc, MVT::v8i32, { 2, 2, 2, 2 } }, // 2*vpermilps + vblendps
2556 { TTI::SK_PermuteTwoSrc, MVT::v16i16, { 9, 9, 9, 9 } }, // 2*vextractf128 + 4*pshufb
2557 // + 2*vpor + vinsertf128
2558 { TTI::SK_PermuteTwoSrc, MVT::v16f16, { 9, 9, 9, 9 } }, // 2*vextractf128 + 4*pshufb
2559 // + 2*vpor + vinsertf128
2560 { TTI::SK_PermuteTwoSrc, MVT::v32i8, { 9, 9, 9, 9 } }, // 2*vextractf128 + 4*pshufb
2561 // + 2*vpor + vinsertf128
2562 };
2563
2564 if (IsInLaneShuffle && ST->hasAVX())
2565 if (const auto *Entry =
2566 CostTableLookup(AVX1InLaneShuffleTbl, Kind, LT.second))
2567 if (auto KindCost = Entry->Cost[CostKind])
2568 return LT.first * *KindCost;
2569
2570 static const CostKindTblEntry AVX1ShuffleTbl[] = {
2571 {TTI::SK_Broadcast, MVT::v4f64, {2,3,2,3}}, // vperm2f128 + vpermilpd
2572 {TTI::SK_Broadcast, MVT::v8f32, {2,3,2,3}}, // vperm2f128 + vpermilps
2573 {TTI::SK_Broadcast, MVT::v4i64, {2,3,2,3}}, // vperm2f128 + vpermilpd
2574 {TTI::SK_Broadcast, MVT::v8i32, {2,3,2,3}}, // vperm2f128 + vpermilps
2575 {TTI::SK_Broadcast, MVT::v16i16, {2,3,3,4}}, // vpshuflw + vpshufd + vinsertf128
2576 {TTI::SK_Broadcast, MVT::v16f16, {2,3,3,4}}, // vpshuflw + vpshufd + vinsertf128
2577 {TTI::SK_Broadcast, MVT::v32i8, {3,4,3,6}}, // vpshufb + vinsertf128
2578
2579 {TTI::SK_Reverse, MVT::v4f64, {2,6,2,2}}, // vperm2f128 + vpermilpd
2580 {TTI::SK_Reverse, MVT::v8f32, {2,7,2,4}}, // vperm2f128 + vpermilps
2581 {TTI::SK_Reverse, MVT::v4i64, {2,6,2,2}}, // vperm2f128 + vpermilpd
2582 {TTI::SK_Reverse, MVT::v8i32, {2,7,2,4}}, // vperm2f128 + vpermilps
2583 {TTI::SK_Reverse, MVT::v16i16, {2,9,5,5}}, // vextractf128 + 2*pshufb
2584 // + vinsertf128
2585 {TTI::SK_Reverse, MVT::v16f16, {2,9,5,5}}, // vextractf128 + 2*pshufb
2586 // + vinsertf128
2587 {TTI::SK_Reverse, MVT::v32i8, {2,9,5,5}}, // vextractf128 + 2*pshufb
2588 // + vinsertf128
2589
2590 {TTI::SK_Select, MVT::v4i64, {1,1,1,1}}, // vblendpd
2591 {TTI::SK_Select, MVT::v4f64, {1,1,1,1}}, // vblendpd
2592 {TTI::SK_Select, MVT::v8i32, {1,1,1,1}}, // vblendps
2593 {TTI::SK_Select, MVT::v8f32, {1,1,1,1}}, // vblendps
2594 {TTI::SK_Select, MVT::v16i16, {3,3,3,3}}, // vpand + vpandn + vpor
2595 {TTI::SK_Select, MVT::v16f16, {3,3,3,3}}, // vpand + vpandn + vpor
2596 {TTI::SK_Select, MVT::v32i8, {3,3,3,3}}, // vpand + vpandn + vpor
2597
2598 {TTI::SK_Splice, MVT::v4i64, {2,2,2,2}}, // vperm2f128 + shufpd
2599 {TTI::SK_Splice, MVT::v4f64, {2,2,2,2}}, // vperm2f128 + shufpd
2600 {TTI::SK_Splice, MVT::v8i32, {4,4,4,4}}, // 2*vperm2f128 + 2*vshufps
2601 {TTI::SK_Splice, MVT::v8f32, {4,4,4,4}}, // 2*vperm2f128 + 2*vshufps
2602 {TTI::SK_Splice, MVT::v16i16, {5,5,5,5}}, // 2*vperm2f128 + 2*vpalignr + vinsertf128
2603 {TTI::SK_Splice, MVT::v16f16, {5,5,5,5}}, // 2*vperm2f128 + 2*vpalignr + vinsertf128
2604 {TTI::SK_Splice, MVT::v32i8, {5,5,5,5}}, // 2*vperm2f128 + 2*vpalignr + vinsertf128
2605
2606 {TTI::SK_PermuteSingleSrc, MVT::v4f64, {2,2,2,2}}, // vperm2f128 + vshufpd
2607 {TTI::SK_PermuteSingleSrc, MVT::v4i64, {2,2,2,2}}, // vperm2f128 + vshufpd
2608 {TTI::SK_PermuteSingleSrc, MVT::v8f32, {4,4,4,4}}, // 2*vperm2f128 + 2*vshufps
2609 {TTI::SK_PermuteSingleSrc, MVT::v8i32, {4,4,4,4}}, // 2*vperm2f128 + 2*vshufps
2610 {TTI::SK_PermuteSingleSrc, MVT::v16i16,{8,8,8,8}}, // vextractf128 + 4*pshufb
2611 // + 2*por + vinsertf128
2612 {TTI::SK_PermuteSingleSrc, MVT::v16f16,{8,8,8,8}}, // vextractf128 + 4*pshufb
2613 // + 2*por + vinsertf128
2614 {TTI::SK_PermuteSingleSrc, MVT::v32i8, {8,8,8,8}}, // vextractf128 + 4*pshufb
2615 // + 2*por + vinsertf128
2616
2617 {TTI::SK_PermuteTwoSrc, MVT::v4f64, {3,3,3,3}}, // 2*vperm2f128 + vshufpd
2618 {TTI::SK_PermuteTwoSrc, MVT::v4i64, {3,3,3,3}}, // 2*vperm2f128 + vshufpd
2619 {TTI::SK_PermuteTwoSrc, MVT::v8f32, {4,4,4,4}}, // 2*vperm2f128 + 2*vshufps
2620 {TTI::SK_PermuteTwoSrc, MVT::v8i32, {4,4,4,4}}, // 2*vperm2f128 + 2*vshufps
2621 {TTI::SK_PermuteTwoSrc, MVT::v16i16,{15,15,15,15}}, // 2*vextractf128 + 8*pshufb
2622 // + 4*por + vinsertf128
2623 {TTI::SK_PermuteTwoSrc, MVT::v16f16,{15,15,15,15}}, // 2*vextractf128 + 8*pshufb
2624 // + 4*por + vinsertf128
2625 {TTI::SK_PermuteTwoSrc, MVT::v32i8, {15,15,15,15}}, // 2*vextractf128 + 8*pshufb
2626 // + 4*por + vinsertf128
2627 };
2628
2629 if (ST->hasAVX())
2630 if (const auto *Entry = CostTableLookup(AVX1ShuffleTbl, Kind, LT.second))
2631 if (auto KindCost = Entry->Cost[CostKind])
2632 return LT.first * *KindCost;
2633
2634 static const CostKindTblEntry SSE41ShuffleTbl[] = {
2635 {TTI::SK_Select, MVT::v2i64, {1,1,1,1}}, // pblendw
2636 {TTI::SK_Select, MVT::v2f64, {1,1,1,1}}, // movsd
2637 {TTI::SK_Select, MVT::v4i32, {1,1,1,1}}, // pblendw
2638 {TTI::SK_Select, MVT::v4f32, {1,1,1,1}}, // blendps
2639 {TTI::SK_Select, MVT::v8i16, {1,1,1,1}}, // pblendw
2640 {TTI::SK_Select, MVT::v8f16, {1,1,1,1}}, // pblendw
2641 {TTI::SK_Select, MVT::v16i8, {1,1,1,1}} // pblendvb
2642 };
2643
2644 if (ST->hasSSE41())
2645 if (const auto *Entry = CostTableLookup(SSE41ShuffleTbl, Kind, LT.second))
2646 if (auto KindCost = Entry->Cost[CostKind])
2647 return LT.first * *KindCost;
2648
2649 static const CostKindTblEntry SSSE3ShuffleTbl[] = {
2650 {TTI::SK_Broadcast, MVT::v8i16, {1, 3, 2, 2}}, // pshufb
2651 {TTI::SK_Broadcast, MVT::v8f16, {1, 3, 2, 2}}, // pshufb
2652 {TTI::SK_Broadcast, MVT::v16i8, {1, 3, 2, 2}}, // pshufb
2653
2654 {TTI::SK_Reverse, MVT::v8i16, {1, 2, 1, 2}}, // pshufb
2655 {TTI::SK_Reverse, MVT::v8f16, {1, 2, 1, 2}}, // pshufb
2656 {TTI::SK_Reverse, MVT::v16i8, {1, 2, 1, 2}}, // pshufb
2657
2658 {TTI::SK_Splice, MVT::v4i32, {1, 1, 1, 1}}, // palignr
2659 {TTI::SK_Splice, MVT::v4f32, {1, 1, 1, 1}}, // palignr
2660 {TTI::SK_Splice, MVT::v8i16, {1, 1, 1, 1}}, // palignr
2661 {TTI::SK_Splice, MVT::v8f16, {1, 1, 1, 1}}, // palignr
2662 {TTI::SK_Splice, MVT::v16i8, {1, 1, 1, 1}}, // palignr
2663
2664 {TTI::SK_PermuteSingleSrc, MVT::v8i16, {1, 1, 1, 1}}, // pshufb
2665 {TTI::SK_PermuteSingleSrc, MVT::v8f16, {1, 1, 1, 1}}, // pshufb
2666 {TTI::SK_PermuteSingleSrc, MVT::v16i8, {1, 1, 1, 1}}, // pshufb
2667
2668 {TTI::SK_PermuteTwoSrc, MVT::v8i16, {3, 3, 3, 3}}, // 2*pshufb + por
2669 {TTI::SK_PermuteTwoSrc, MVT::v8f16, {3, 3, 3, 3}}, // 2*pshufb + por
2670 {TTI::SK_PermuteTwoSrc, MVT::v16i8, {3, 3, 3, 3}}, // 2*pshufb + por
2671 };
2672
2673 if (ST->hasSSSE3())
2674 if (const auto *Entry = CostTableLookup(SSSE3ShuffleTbl, Kind, LT.second))
2675 if (auto KindCost = Entry->Cost[CostKind])
2676 return LT.first * *KindCost;
2677
2678 static const CostKindTblEntry SSE2ShuffleTbl[] = {
2679 {TTI::SK_Broadcast, MVT::v2f64, {1, 1, 1, 1}}, // shufpd
2680 {TTI::SK_Broadcast, MVT::v2i64, {1, 1, 1, 1}}, // pshufd
2681 {TTI::SK_Broadcast, MVT::v4i32, {1, 1, 1, 1}}, // pshufd
2682 {TTI::SK_Broadcast, MVT::v8i16, {1, 2, 2, 2}}, // pshuflw + pshufd
2683 {TTI::SK_Broadcast, MVT::v8f16, {1, 2, 2, 2}}, // pshuflw + pshufd
2684 {TTI::SK_Broadcast, MVT::v16i8, {2, 3, 3, 4}}, // unpck + pshuflw + pshufd
2685
2686 {TTI::SK_Reverse, MVT::v2f64, {1, 1, 1, 1}}, // shufpd
2687 {TTI::SK_Reverse, MVT::v2i64, {1, 1, 1, 1}}, // pshufd
2688 {TTI::SK_Reverse, MVT::v4i32, {1, 1, 1, 1}}, // pshufd
2689 {TTI::SK_Reverse, MVT::v8i16, {2, 3, 3, 3}}, // pshuflw + pshufhw + pshufd
2690 {TTI::SK_Reverse, MVT::v8f16, {2, 3, 3, 3}}, // pshuflw + pshufhw + pshufd
2691 {TTI::SK_Reverse, MVT::v16i8, {5, 6,11,11}}, // 2*pshuflw + 2*pshufhw
2692 // + 2*pshufd + 2*unpck + packus
2693
2694 {TTI::SK_Select, MVT::v2i64, {1, 1, 1, 1}}, // movsd
2695 {TTI::SK_Select, MVT::v2f64, {1, 1, 1, 1}}, // movsd
2696 {TTI::SK_Select, MVT::v4i32, {2, 2, 2, 2}}, // 2*shufps
2697 {TTI::SK_Select, MVT::v8i16, {2, 2, 3, 3}}, // pand + pandn + por
2698 {TTI::SK_Select, MVT::v8f16, {2, 2, 3, 3}}, // pand + pandn + por
2699 {TTI::SK_Select, MVT::v16i8, {2, 2, 3, 3}}, // pand + pandn + por
2700
2701 {TTI::SK_Splice, MVT::v2i64, {1, 1, 1, 1}}, // shufpd
2702 {TTI::SK_Splice, MVT::v2f64, {1, 1, 1, 1}}, // shufpd
2703 {TTI::SK_Splice, MVT::v4i32, {2, 2, 2, 2}}, // 2*{unpck,movsd,pshufd}
2704 {TTI::SK_Splice, MVT::v8i16, {3, 3, 3, 3}}, // psrldq + psrlldq + por
2705 {TTI::SK_Splice, MVT::v8f16, {3, 3, 3, 3}}, // psrldq + psrlldq + por
2706 {TTI::SK_Splice, MVT::v16i8, {3, 3, 3, 3}}, // psrldq + psrlldq + por
2707
2708 {TTI::SK_PermuteSingleSrc, MVT::v2f64, {1, 1, 1, 1}}, // shufpd
2709 {TTI::SK_PermuteSingleSrc, MVT::v2i64, {1, 1, 1, 1}}, // pshufd
2710 {TTI::SK_PermuteSingleSrc, MVT::v4i32, {1, 1, 1, 1}}, // pshufd
2711 {TTI::SK_PermuteSingleSrc, MVT::v8i16, {3, 5, 5, 5}}, // 2*pshuflw + 2*pshufhw
2712 // + pshufd/unpck
2713 {TTI::SK_PermuteSingleSrc, MVT::v8f16, {3, 5, 5, 5}}, // 2*pshuflw + 2*pshufhw
2714 // + pshufd/unpck
2715 {TTI::SK_PermuteSingleSrc, MVT::v16i8, {8, 10, 10, 10}}, // 2*pshuflw + 2*pshufhw
2716 // + 2*pshufd + 2*unpck + 2*packus
2717
2718 {TTI::SK_PermuteTwoSrc, MVT::v2f64, {1, 1, 1, 1}}, // shufpd
2719 {TTI::SK_PermuteTwoSrc, MVT::v2i64, {1, 1, 1, 1}}, // shufpd
2720 {TTI::SK_PermuteTwoSrc, MVT::v4i32, {2, 2, 2, 2}}, // 2*{unpck,movsd,pshufd}
2721 {TTI::SK_PermuteTwoSrc, MVT::v8i16, {6, 8, 8, 8}}, // blend+permute
2722 {TTI::SK_PermuteTwoSrc, MVT::v8f16, {6, 8, 8, 8}}, // blend+permute
2723 {TTI::SK_PermuteTwoSrc, MVT::v16i8, {11, 13, 13, 13}}, // blend+permute
2724 };
2725
2726 static const CostTblEntry SSE3BroadcastLoadTbl[] = {
2727 {TTI::SK_Broadcast, MVT::v2f64, 0}, // broadcast handled by movddup
2728 };
2729
2730 if (ST->hasSSE2()) {
2731 bool IsLoad =
2732 llvm::any_of(Args, [](const auto &V) { return isa<LoadInst>(V); });
2733 if (ST->hasSSE3() && IsLoad)
2734 if (const auto *Entry =
2735 CostTableLookup(SSE3BroadcastLoadTbl, Kind, LT.second)) {
2736 assert(isLegalBroadcastLoad(SrcTy->getElementType(),
2737 LT.second.getVectorElementCount()) &&
2738 "Table entry missing from isLegalBroadcastLoad()");
2739 return LT.first * Entry->Cost;
2740 }
2741
2742 if (const auto *Entry = CostTableLookup(SSE2ShuffleTbl, Kind, LT.second))
2743 if (auto KindCost = Entry->Cost[CostKind])
2744 return LT.first * *KindCost;
2745 }
2746
2747 static const CostKindTblEntry SSE1ShuffleTbl[] = {
2748 { TTI::SK_Broadcast, MVT::v4f32, {1,1,1,1} }, // shufps
2749 { TTI::SK_Reverse, MVT::v4f32, {1,1,1,1} }, // shufps
2750 { TTI::SK_Select, MVT::v4f32, {2,2,2,2} }, // 2*shufps
2751 { TTI::SK_Splice, MVT::v4f32, {2,2,2,2} }, // 2*shufps
2752 { TTI::SK_PermuteSingleSrc, MVT::v4f32, {1,1,1,1} }, // shufps
2753 { TTI::SK_PermuteTwoSrc, MVT::v4f32, {2,2,2,2} }, // 2*shufps
2754 };
2755
2756 if (ST->hasSSE1()) {
2757 if (LT.first == 1 && LT.second == MVT::v4f32 && Mask.size() == 4) {
2758 // SHUFPS: both pairs must come from the same source register.
2759 auto MatchSHUFPS = [](int X, int Y) {
2760 return X < 0 || Y < 0 || ((X & 4) == (Y & 4));
2761 };
2762 if (MatchSHUFPS(Mask[0], Mask[1]) && MatchSHUFPS(Mask[2], Mask[3]))
2763 return 1;
2764 }
2765 if (const auto *Entry = CostTableLookup(SSE1ShuffleTbl, Kind, LT.second))
2766 if (auto KindCost = Entry->Cost[CostKind])
2767 return LT.first * *KindCost;
2768 }
2769
2770 return BaseT::getShuffleCost(Kind, DstTy, SrcTy, CostKind, Mask, Index,
2771 SubTp);
2772}
2773
2775 Type *Src,
2778 const Instruction *I) const {
2779 int ISD = TLI->InstructionOpcodeToISD(Opcode);
2780 assert(ISD && "Invalid opcode");
2781
2782 // A narrow (i8/i16) zero-extension used as a GEP *index* can be folded into
2783 // the addressing mode of the consuming memory op, but only if the source is
2784 // already materialised zero-extended in a full register. X86's SIB form
2785 // [base + index*scale + disp] reads the index at full width and does NOT
2786 // zero-extend a narrow index (unlike AArch64's uxtw-extended addressing), so
2787 // a "dirty" narrow source (e.g. an i16 add result used only as an index)
2788 // still needs a dedicated movzx and is not free. Price it as free only with
2789 // positive evidence that no movzx is required.
2790 if (ISD == ISD::ZERO_EXTEND && I && I->hasOneUse() && Src->isIntegerTy() &&
2791 Src->getScalarSizeInBits() < 32) {
2792 const Use &U = *I->use_begin();
2793 if (isa<GetElementPtrInst>(U.getUser()) &&
2794 U.getOperandNo() != GetElementPtrInst::getPointerOperandIndex()) {
2795 const Value *Op = I->getOperand(0);
2796 // Clean sources: an extending load, a zeroext argument, or a value whose
2797 // high bits are provably zero (e.g. from a shift/mask). These mirror the
2798 // proof-based reasoning the middle end uses elsewhere (ValueTracking and
2799 // InstCombine's canEvaluateZExtd); we intentionally do NOT treat a merely
2800 // multiply-used operand as clean, since that is a guess rather than
2801 // proof.
2802 if (isa<LoadInst>(Op))
2803 return TTI::TCC_Free;
2804 if (const auto *A = dyn_cast<Argument>(Op))
2805 if (A->hasAttribute(Attribute::ZExt))
2806 return TTI::TCC_Free;
2807 if (computeKnownBits(Op, I->getDataLayout(), /*AC=*/nullptr, I)
2808 .countMinLeadingZeros() > 0)
2809 return TTI::TCC_Free;
2810 }
2811 }
2812
2813 // The cost tables include both specific, custom (non-legal) src/dst type
2814 // conversions and generic, legalized types. We test for customs first, before
2815 // falling back to legalization.
2816 // FIXME: Need a better design of the cost table to handle non-simple types of
2817 // potential massive combinations (elem_num x src_type x dst_type).
2818 static const TypeConversionCostKindTblEntry AVX512BWConversionTbl[]{
2819 { ISD::SIGN_EXTEND, MVT::v32i16, MVT::v32i8, { 1, 1, 1, 1 } },
2820 { ISD::ZERO_EXTEND, MVT::v32i16, MVT::v32i8, { 1, 1, 1, 1 } },
2821
2822 // Mask sign extend has an instruction.
2823 { ISD::SIGN_EXTEND, MVT::v2i8, MVT::v2i1, { 1, 1, 1, 1 } },
2824 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v2i1, { 1, 1, 1, 1 } },
2825 { ISD::SIGN_EXTEND, MVT::v2i16, MVT::v2i1, { 1, 1, 1, 1 } },
2826 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v2i1, { 1, 1, 1, 1 } },
2827 { ISD::SIGN_EXTEND, MVT::v4i8, MVT::v4i1, { 1, 1, 1, 1 } },
2828 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v4i1, { 1, 1, 1, 1 } },
2829 { ISD::SIGN_EXTEND, MVT::v4i16, MVT::v4i1, { 1, 1, 1, 1 } },
2830 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v4i1, { 1, 1, 1, 1 } },
2831 { ISD::SIGN_EXTEND, MVT::v8i8, MVT::v8i1, { 1, 1, 1, 1 } },
2832 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v8i1, { 1, 1, 1, 1 } },
2833 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v8i1, { 1, 1, 1, 1 } },
2834 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v16i1, { 1, 1, 1, 1 } },
2835 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i1, { 1, 1, 1, 1 } },
2836 { ISD::SIGN_EXTEND, MVT::v32i8, MVT::v32i1, { 1, 1, 1, 1 } },
2837 { ISD::SIGN_EXTEND, MVT::v32i16, MVT::v32i1, { 1, 1, 1, 1 } },
2838 { ISD::SIGN_EXTEND, MVT::v64i8, MVT::v64i1, { 1, 1, 1, 1 } },
2839 { ISD::SIGN_EXTEND, MVT::v32i16, MVT::v64i1, { 1, 1, 1, 1 } },
2840
2841 // Mask zero extend is a sext + shift.
2842 { ISD::ZERO_EXTEND, MVT::v2i8, MVT::v2i1, { 2, 1, 1, 1 } },
2843 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v2i1, { 2, 1, 1, 1 } },
2844 { ISD::ZERO_EXTEND, MVT::v2i16, MVT::v2i1, { 2, 1, 1, 1 } },
2845 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v2i1, { 2, 1, 1, 1 } },
2846 { ISD::ZERO_EXTEND, MVT::v4i8, MVT::v4i1, { 2, 1, 1, 1 } },
2847 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v4i1, { 2, 1, 1, 1 } },
2848 { ISD::ZERO_EXTEND, MVT::v4i16, MVT::v4i1, { 2, 1, 1, 1 } },
2849 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v4i1, { 2, 1, 1, 1 } },
2850 { ISD::ZERO_EXTEND, MVT::v8i8, MVT::v8i1, { 2, 1, 1, 1 } },
2851 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v8i1, { 2, 1, 1, 1 } },
2852 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v8i1, { 2, 1, 1, 1 } },
2853 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v16i1, { 2, 1, 1, 1 } },
2854 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i1, { 2, 1, 1, 1 } },
2855 { ISD::ZERO_EXTEND, MVT::v32i8, MVT::v32i1, { 2, 1, 1, 1 } },
2856 { ISD::ZERO_EXTEND, MVT::v32i16, MVT::v32i1, { 2, 1, 1, 1 } },
2857 { ISD::ZERO_EXTEND, MVT::v64i8, MVT::v64i1, { 2, 1, 1, 1 } },
2858 { ISD::ZERO_EXTEND, MVT::v32i16, MVT::v64i1, { 2, 1, 1, 1 } },
2859
2860 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i8, { 2, 1, 1, 1 } },
2861 { ISD::TRUNCATE, MVT::v2i1, MVT::v16i8, { 2, 1, 1, 1 } },
2862 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i16, { 2, 1, 1, 1 } },
2863 { ISD::TRUNCATE, MVT::v2i1, MVT::v8i16, { 2, 1, 1, 1 } },
2864 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i8, { 2, 1, 1, 1 } },
2865 { ISD::TRUNCATE, MVT::v4i1, MVT::v16i8, { 2, 1, 1, 1 } },
2866 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i16, { 2, 1, 1, 1 } },
2867 { ISD::TRUNCATE, MVT::v4i1, MVT::v8i16, { 2, 1, 1, 1 } },
2868 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i8, { 2, 1, 1, 1 } },
2869 { ISD::TRUNCATE, MVT::v8i1, MVT::v16i8, { 2, 1, 1, 1 } },
2870 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i16, { 2, 1, 1, 1 } },
2871 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i8, { 2, 1, 1, 1 } },
2872 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i16, { 2, 1, 1, 1 } },
2873 { ISD::TRUNCATE, MVT::v32i1, MVT::v32i8, { 2, 1, 1, 1 } },
2874 { ISD::TRUNCATE, MVT::v32i1, MVT::v32i16, { 2, 1, 1, 1 } },
2875 { ISD::TRUNCATE, MVT::v64i1, MVT::v64i8, { 2, 1, 1, 1 } },
2876 { ISD::TRUNCATE, MVT::v64i1, MVT::v32i16, { 2, 1, 1, 1 } },
2877
2878 { ISD::TRUNCATE, MVT::v32i8, MVT::v32i16, { 2, 1, 1, 1 } },
2879 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i16, { 2, 1, 1, 1 } }, // widen to zmm
2880 { ISD::TRUNCATE, MVT::v2i8, MVT::v2i16, { 2, 1, 1, 1 } }, // vpmovwb
2881 { ISD::TRUNCATE, MVT::v4i8, MVT::v4i16, { 2, 1, 1, 1 } }, // vpmovwb
2882 { ISD::TRUNCATE, MVT::v8i8, MVT::v8i16, { 2, 1, 1, 1 } }, // vpmovwb
2883 };
2884
2885 static const TypeConversionCostKindTblEntry AVX512DQConversionTbl[] = {
2886 // Mask sign extend has an instruction.
2887 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v2i1, { 1, 1, 1, 1 } },
2888 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v2i1, { 1, 1, 1, 1 } },
2889 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v4i1, { 1, 1, 1, 1 } },
2890 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i1, { 1, 1, 1, 1 } },
2891 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i1, { 1, 1, 1, 1 } },
2892 { ISD::SIGN_EXTEND, MVT::v8i64, MVT::v16i1, { 1, 1, 1, 1 } },
2893 { ISD::SIGN_EXTEND, MVT::v8i64, MVT::v8i1, { 1, 1, 1, 1 } },
2894 { ISD::SIGN_EXTEND, MVT::v16i32, MVT::v16i1, { 1, 1, 1, 1 } },
2895
2896 // Mask zero extend is a sext + shift.
2897 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v2i1, { 2, 1, 1, 1, } },
2898 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v2i1, { 2, 1, 1, 1, } },
2899 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v4i1, { 2, 1, 1, 1, } },
2900 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i1, { 2, 1, 1, 1, } },
2901 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i1, { 2, 1, 1, 1, } },
2902 { ISD::ZERO_EXTEND, MVT::v8i64, MVT::v16i1, { 2, 1, 1, 1, } },
2903 { ISD::ZERO_EXTEND, MVT::v8i64, MVT::v8i1, { 2, 1, 1, 1, } },
2904 { ISD::ZERO_EXTEND, MVT::v16i32, MVT::v16i1, { 2, 1, 1, 1, } },
2905
2906 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i64, { 2, 1, 1, 1 } },
2907 { ISD::TRUNCATE, MVT::v2i1, MVT::v4i32, { 2, 1, 1, 1 } },
2908 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i32, { 2, 1, 1, 1 } },
2909 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i64, { 2, 1, 1, 1 } },
2910 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i32, { 2, 1, 1, 1 } },
2911 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i64, { 2, 1, 1, 1 } },
2912 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i32, { 2, 1, 1, 1 } },
2913 { ISD::TRUNCATE, MVT::v16i1, MVT::v8i64, { 2, 1, 1, 1 } },
2914
2915 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v8i64, { 1, 1, 1, 1 } },
2916 { ISD::SINT_TO_FP, MVT::v8f64, MVT::v8i64, { 1, 1, 1, 1 } },
2917
2918 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i64, { 1, 1, 1, 1 } },
2919 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i64, { 1, 1, 1, 1 } },
2920
2921 { ISD::FP_TO_SINT, MVT::v8i64, MVT::v8f32, { 1, 1, 1, 1 } },
2922 { ISD::FP_TO_SINT, MVT::v8i64, MVT::v8f64, { 1, 1, 1, 1 } },
2923
2924 { ISD::FP_TO_UINT, MVT::v8i64, MVT::v8f32, { 1, 1, 1, 1 } },
2925 { ISD::FP_TO_UINT, MVT::v8i64, MVT::v8f64, { 1, 1, 1, 1 } },
2926 };
2927
2928 // TODO: For AVX512DQ + AVX512VL, we also have cheap casts for 128-bit and
2929 // 256-bit wide vectors.
2930
2931 static const TypeConversionCostKindTblEntry AVX512FConversionTbl[] = {
2932 { ISD::FP_EXTEND, MVT::v8f64, MVT::v8f32, { 1, 1, 1, 1 } },
2933 { ISD::FP_EXTEND, MVT::v8f64, MVT::v16f32, { 3, 1, 1, 1 } },
2934 { ISD::FP_EXTEND, MVT::v16f64, MVT::v16f32, { 4, 1, 1, 1 } }, // 2*vcvtps2pd+vextractf64x4
2935 { ISD::FP_EXTEND, MVT::v16f32, MVT::v16f16, { 1, 1, 1, 1 } }, // vcvtph2ps
2936 { ISD::FP_EXTEND, MVT::v8f64, MVT::v8f16, { 2, 1, 1, 1 } }, // vcvtph2ps+vcvtps2pd
2937 { ISD::FP_ROUND, MVT::v8f32, MVT::v8f64, { 1, 1, 1, 1 } },
2938 { ISD::FP_ROUND, MVT::v16f16, MVT::v16f32, { 1, 1, 1, 1 } }, // vcvtps2ph
2939
2940 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i8, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
2941 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i8, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
2942 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i8, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
2943 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i8, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
2944 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i16, { 3, 1, 1, 1 } }, // sext+vpsllq+vptestmq
2945 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i16, { 3, 1, 1, 1 } }, // sext+vpsllq+vptestmq
2946 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i16, { 3, 1, 1, 1 } }, // sext+vpsllq+vptestmq
2947 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i16, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
2948 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i32, { 2, 1, 1, 1 } }, // zmm vpslld+vptestmd
2949 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i32, { 2, 1, 1, 1 } }, // zmm vpslld+vptestmd
2950 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i32, { 2, 1, 1, 1 } }, // zmm vpslld+vptestmd
2951 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i32, { 2, 1, 1, 1 } }, // vpslld+vptestmd
2952 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i64, { 2, 1, 1, 1 } }, // zmm vpsllq+vptestmq
2953 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i64, { 2, 1, 1, 1 } }, // zmm vpsllq+vptestmq
2954 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i64, { 2, 1, 1, 1 } }, // vpsllq+vptestmq
2955 { ISD::TRUNCATE, MVT::v2i8, MVT::v2i32, { 2, 1, 1, 1 } }, // vpmovdb
2956 { ISD::TRUNCATE, MVT::v4i8, MVT::v4i32, { 2, 1, 1, 1 } }, // vpmovdb
2957 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i32, { 2, 1, 1, 1 } }, // vpmovdb
2958 { ISD::TRUNCATE, MVT::v32i8, MVT::v16i32, { 2, 1, 1, 1 } }, // vpmovdb
2959 { ISD::TRUNCATE, MVT::v64i8, MVT::v16i32, { 2, 1, 1, 1 } }, // vpmovdb
2960 { ISD::TRUNCATE, MVT::v16i16, MVT::v16i32, { 2, 1, 1, 1 } }, // vpmovdw
2961 { ISD::TRUNCATE, MVT::v32i16, MVT::v16i32, { 2, 1, 1, 1 } }, // vpmovdw
2962 { ISD::TRUNCATE, MVT::v2i8, MVT::v2i64, { 2, 1, 1, 1 } }, // vpmovqb
2963 { ISD::TRUNCATE, MVT::v2i16, MVT::v2i64, { 1, 1, 1, 1 } }, // vpshufb
2964 { ISD::TRUNCATE, MVT::v8i8, MVT::v8i64, { 2, 1, 1, 1 } }, // vpmovqb
2965 { ISD::TRUNCATE, MVT::v16i8, MVT::v8i64, { 2, 1, 1, 1 } }, // vpmovqb
2966 { ISD::TRUNCATE, MVT::v32i8, MVT::v8i64, { 2, 1, 1, 1 } }, // vpmovqb
2967 { ISD::TRUNCATE, MVT::v64i8, MVT::v8i64, { 2, 1, 1, 1 } }, // vpmovqb
2968 { ISD::TRUNCATE, MVT::v8i16, MVT::v8i64, { 2, 1, 1, 1 } }, // vpmovqw
2969 { ISD::TRUNCATE, MVT::v16i16, MVT::v8i64, { 2, 1, 1, 1 } }, // vpmovqw
2970 { ISD::TRUNCATE, MVT::v32i16, MVT::v8i64, { 2, 1, 1, 1 } }, // vpmovqw
2971 { ISD::TRUNCATE, MVT::v8i32, MVT::v8i64, { 1, 1, 1, 1 } }, // vpmovqd
2972 { ISD::TRUNCATE, MVT::v4i32, MVT::v4i64, { 1, 1, 1, 1 } }, // zmm vpmovqd
2973 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i64, { 5, 1, 1, 1 } },// 2*vpmovqd+concat+vpmovdb
2974
2975 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i16, { 3, 1, 1, 1 } }, // extend to v16i32
2976 { ISD::TRUNCATE, MVT::v32i8, MVT::v32i16, { 8, 1, 1, 1 } },
2977 { ISD::TRUNCATE, MVT::v64i8, MVT::v32i16, { 8, 1, 1, 1 } },
2978
2979 // Sign extend is zmm vpternlogd+vptruncdb.
2980 // Zero extend is zmm broadcast load+vptruncdw.
2981 { ISD::SIGN_EXTEND, MVT::v2i8, MVT::v2i1, { 3, 1, 1, 1 } },
2982 { ISD::ZERO_EXTEND, MVT::v2i8, MVT::v2i1, { 4, 1, 1, 1 } },
2983 { ISD::SIGN_EXTEND, MVT::v4i8, MVT::v4i1, { 3, 1, 1, 1 } },
2984 { ISD::ZERO_EXTEND, MVT::v4i8, MVT::v4i1, { 4, 1, 1, 1 } },
2985 { ISD::SIGN_EXTEND, MVT::v8i8, MVT::v8i1, { 3, 1, 1, 1 } },
2986 { ISD::ZERO_EXTEND, MVT::v8i8, MVT::v8i1, { 4, 1, 1, 1 } },
2987 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v16i1, { 3, 1, 1, 1 } },
2988 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v16i1, { 4, 1, 1, 1 } },
2989
2990 // Sign extend is zmm vpternlogd+vptruncdw.
2991 // Zero extend is zmm vpternlogd+vptruncdw+vpsrlw.
2992 { ISD::SIGN_EXTEND, MVT::v2i16, MVT::v2i1, { 3, 1, 1, 1 } },
2993 { ISD::ZERO_EXTEND, MVT::v2i16, MVT::v2i1, { 4, 1, 1, 1 } },
2994 { ISD::SIGN_EXTEND, MVT::v4i16, MVT::v4i1, { 3, 1, 1, 1 } },
2995 { ISD::ZERO_EXTEND, MVT::v4i16, MVT::v4i1, { 4, 1, 1, 1 } },
2996 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v8i1, { 3, 1, 1, 1 } },
2997 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v8i1, { 4, 1, 1, 1 } },
2998 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i1, { 3, 1, 1, 1 } },
2999 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i1, { 4, 1, 1, 1 } },
3000
3001 { ISD::SIGN_EXTEND, MVT::v2i32, MVT::v2i1, { 1, 1, 1, 1 } }, // zmm vpternlogd
3002 { ISD::ZERO_EXTEND, MVT::v2i32, MVT::v2i1, { 2, 1, 1, 1 } }, // zmm vpternlogd+psrld
3003 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v4i1, { 1, 1, 1, 1 } }, // zmm vpternlogd
3004 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v4i1, { 2, 1, 1, 1 } }, // zmm vpternlogd+psrld
3005 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i1, { 1, 1, 1, 1 } }, // zmm vpternlogd
3006 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i1, { 2, 1, 1, 1 } }, // zmm vpternlogd+psrld
3007 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v2i1, { 1, 1, 1, 1 } }, // zmm vpternlogq
3008 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v2i1, { 2, 1, 1, 1 } }, // zmm vpternlogq+psrlq
3009 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i1, { 1, 1, 1, 1 } }, // zmm vpternlogq
3010 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i1, { 2, 1, 1, 1 } }, // zmm vpternlogq+psrlq
3011
3012 { ISD::SIGN_EXTEND, MVT::v16i32, MVT::v16i1, { 1, 1, 1, 1 } }, // vpternlogd
3013 { ISD::ZERO_EXTEND, MVT::v16i32, MVT::v16i1, { 2, 1, 1, 1 } }, // vpternlogd+psrld
3014 { ISD::SIGN_EXTEND, MVT::v8i64, MVT::v8i1, { 1, 1, 1, 1 } }, // vpternlogq
3015 { ISD::ZERO_EXTEND, MVT::v8i64, MVT::v8i1, { 2, 1, 1, 1 } }, // vpternlogq+psrlq
3016
3017 { ISD::SIGN_EXTEND, MVT::v16i32, MVT::v16i8, { 1, 1, 1, 1 } },
3018 { ISD::ZERO_EXTEND, MVT::v16i32, MVT::v16i8, { 1, 1, 1, 1 } },
3019 { ISD::SIGN_EXTEND, MVT::v16i32, MVT::v16i16, { 1, 1, 1, 1 } },
3020 { ISD::ZERO_EXTEND, MVT::v16i32, MVT::v16i16, { 1, 1, 1, 1 } },
3021 { ISD::SIGN_EXTEND, MVT::v8i64, MVT::v8i8, { 1, 1, 1, 1 } },
3022 { ISD::ZERO_EXTEND, MVT::v8i64, MVT::v8i8, { 1, 1, 1, 1 } },
3023 { ISD::SIGN_EXTEND, MVT::v8i64, MVT::v8i16, { 1, 1, 1, 1 } },
3024 { ISD::ZERO_EXTEND, MVT::v8i64, MVT::v8i16, { 1, 1, 1, 1 } },
3025 { ISD::SIGN_EXTEND, MVT::v8i64, MVT::v8i32, { 1, 1, 1, 1 } },
3026 { ISD::ZERO_EXTEND, MVT::v8i64, MVT::v8i32, { 1, 1, 1, 1 } },
3027
3028 { ISD::SIGN_EXTEND, MVT::v32i16, MVT::v32i8, { 3, 1, 1, 1 } }, // FIXME: May not be right
3029 { ISD::ZERO_EXTEND, MVT::v32i16, MVT::v32i8, { 3, 1, 1, 1 } }, // FIXME: May not be right
3030
3031 { ISD::SINT_TO_FP, MVT::v8f64, MVT::v8i1, { 4, 1, 1, 1 } },
3032 { ISD::SINT_TO_FP, MVT::v16f32, MVT::v16i1, { 3, 1, 1, 1 } },
3033 { ISD::SINT_TO_FP, MVT::v8f64, MVT::v16i8, { 2, 1, 1, 1 } },
3034 { ISD::SINT_TO_FP, MVT::v16f32, MVT::v16i8, { 1, 1, 1, 1 } },
3035 { ISD::SINT_TO_FP, MVT::v8f64, MVT::v8i16, { 2, 1, 1, 1 } },
3036 { ISD::SINT_TO_FP, MVT::v16f32, MVT::v16i16, { 1, 1, 1, 1 } },
3037 { ISD::SINT_TO_FP, MVT::v8f64, MVT::v8i32, { 1, 1, 1, 1 } },
3038 { ISD::SINT_TO_FP, MVT::v16f32, MVT::v16i32, { 1, 1, 1, 1 } },
3039
3040 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i1, { 4, 1, 1, 1 } },
3041 { ISD::UINT_TO_FP, MVT::v16f32, MVT::v16i1, { 3, 1, 1, 1 } },
3042 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v16i8, { 2, 1, 1, 1 } },
3043 { ISD::UINT_TO_FP, MVT::v16f32, MVT::v16i8, { 1, 1, 1, 1 } },
3044 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i16, { 2, 1, 1, 1 } },
3045 { ISD::UINT_TO_FP, MVT::v16f32, MVT::v16i16, { 1, 1, 1, 1 } },
3046 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i32, { 1, 1, 1, 1 } },
3047 { ISD::UINT_TO_FP, MVT::v16f32, MVT::v16i32, { 1, 1, 1, 1 } },
3048 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i64, {26, 1, 1, 1 } },
3049 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i64, { 5, 1, 1, 1 } },
3050
3051 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v16f32, { 2, 1, 1, 1 } },
3052 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v16f64, { 7, 1, 1, 1 } },
3053 { ISD::FP_TO_SINT, MVT::v32i8, MVT::v32f64, {15, 1, 1, 1 } },
3054 { ISD::FP_TO_SINT, MVT::v64i8, MVT::v64f32, {11, 1, 1, 1 } },
3055 { ISD::FP_TO_SINT, MVT::v64i8, MVT::v64f64, {31, 1, 1, 1 } },
3056 { ISD::FP_TO_SINT, MVT::v8i16, MVT::v8f64, { 3, 1, 1, 1 } },
3057 { ISD::FP_TO_SINT, MVT::v16i16, MVT::v16f64, { 7, 1, 1, 1 } },
3058 { ISD::FP_TO_SINT, MVT::v32i16, MVT::v32f32, { 5, 1, 1, 1 } },
3059 { ISD::FP_TO_SINT, MVT::v32i16, MVT::v32f64, {15, 1, 1, 1 } },
3060 { ISD::FP_TO_SINT, MVT::v8i32, MVT::v8f64, { 1, 1, 1, 1 } },
3061 { ISD::FP_TO_SINT, MVT::v16i32, MVT::v16f64, { 3, 1, 1, 1 } },
3062
3063 { ISD::FP_TO_UINT, MVT::v8i32, MVT::v8f64, { 1, 1, 1, 1 } },
3064 { ISD::FP_TO_UINT, MVT::v8i16, MVT::v8f64, { 3, 1, 1, 1 } },
3065 { ISD::FP_TO_UINT, MVT::v8i8, MVT::v8f64, { 3, 1, 1, 1 } },
3066 { ISD::FP_TO_UINT, MVT::v16i32, MVT::v16f32, { 1, 1, 1, 1 } },
3067 { ISD::FP_TO_UINT, MVT::v16i16, MVT::v16f32, { 3, 1, 1, 1 } },
3068 { ISD::FP_TO_UINT, MVT::v16i8, MVT::v16f32, { 3, 1, 1, 1 } },
3069 };
3070
3071 static const TypeConversionCostKindTblEntry AVX512BWVLConversionTbl[] {
3072 // Mask sign extend has an instruction.
3073 { ISD::SIGN_EXTEND, MVT::v2i8, MVT::v2i1, { 1, 1, 1, 1 } },
3074 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v2i1, { 1, 1, 1, 1 } },
3075 { ISD::SIGN_EXTEND, MVT::v2i16, MVT::v2i1, { 1, 1, 1, 1 } },
3076 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v2i1, { 1, 1, 1, 1 } },
3077 { ISD::SIGN_EXTEND, MVT::v4i16, MVT::v4i1, { 1, 1, 1, 1 } },
3078 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v4i1, { 1, 1, 1, 1 } },
3079 { ISD::SIGN_EXTEND, MVT::v4i8, MVT::v4i1, { 1, 1, 1, 1 } },
3080 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v4i1, { 1, 1, 1, 1 } },
3081 { ISD::SIGN_EXTEND, MVT::v8i8, MVT::v8i1, { 1, 1, 1, 1 } },
3082 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v8i1, { 1, 1, 1, 1 } },
3083 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v8i1, { 1, 1, 1, 1 } },
3084 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v16i1, { 1, 1, 1, 1 } },
3085 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i1, { 1, 1, 1, 1 } },
3086 { ISD::SIGN_EXTEND, MVT::v32i8, MVT::v32i1, { 1, 1, 1, 1 } },
3087 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v32i1, { 1, 1, 1, 1 } },
3088 { ISD::SIGN_EXTEND, MVT::v32i8, MVT::v64i1, { 1, 1, 1, 1 } },
3089 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v64i1, { 1, 1, 1, 1 } },
3090
3091 // Mask zero extend is a sext + shift.
3092 { ISD::ZERO_EXTEND, MVT::v2i8, MVT::v2i1, { 2, 1, 1, 1 } },
3093 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v2i1, { 2, 1, 1, 1 } },
3094 { ISD::ZERO_EXTEND, MVT::v2i16, MVT::v2i1, { 2, 1, 1, 1 } },
3095 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v2i1, { 2, 1, 1, 1 } },
3096 { ISD::ZERO_EXTEND, MVT::v4i8, MVT::v4i1, { 2, 1, 1, 1 } },
3097 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v4i1, { 2, 1, 1, 1 } },
3098 { ISD::ZERO_EXTEND, MVT::v4i16, MVT::v4i1, { 2, 1, 1, 1 } },
3099 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v4i1, { 2, 1, 1, 1 } },
3100 { ISD::ZERO_EXTEND, MVT::v8i8, MVT::v8i1, { 2, 1, 1, 1 } },
3101 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v8i1, { 2, 1, 1, 1 } },
3102 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v8i1, { 2, 1, 1, 1 } },
3103 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v16i1, { 2, 1, 1, 1 } },
3104 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i1, { 2, 1, 1, 1 } },
3105 { ISD::ZERO_EXTEND, MVT::v32i8, MVT::v32i1, { 2, 1, 1, 1 } },
3106 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v32i1, { 2, 1, 1, 1 } },
3107 { ISD::ZERO_EXTEND, MVT::v32i8, MVT::v64i1, { 2, 1, 1, 1 } },
3108 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v64i1, { 2, 1, 1, 1 } },
3109
3110 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i8, { 2, 1, 1, 1 } },
3111 { ISD::TRUNCATE, MVT::v2i1, MVT::v16i8, { 2, 1, 1, 1 } },
3112 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i16, { 2, 1, 1, 1 } },
3113 { ISD::TRUNCATE, MVT::v2i1, MVT::v8i16, { 2, 1, 1, 1 } },
3114 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i8, { 2, 1, 1, 1 } },
3115 { ISD::TRUNCATE, MVT::v4i1, MVT::v16i8, { 2, 1, 1, 1 } },
3116 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i16, { 2, 1, 1, 1 } },
3117 { ISD::TRUNCATE, MVT::v4i1, MVT::v8i16, { 2, 1, 1, 1 } },
3118 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i8, { 2, 1, 1, 1 } },
3119 { ISD::TRUNCATE, MVT::v8i1, MVT::v16i8, { 2, 1, 1, 1 } },
3120 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i16, { 2, 1, 1, 1 } },
3121 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i8, { 2, 1, 1, 1 } },
3122 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i16, { 2, 1, 1, 1 } },
3123 { ISD::TRUNCATE, MVT::v32i1, MVT::v32i8, { 2, 1, 1, 1 } },
3124 { ISD::TRUNCATE, MVT::v32i1, MVT::v16i16, { 2, 1, 1, 1 } },
3125 { ISD::TRUNCATE, MVT::v64i1, MVT::v32i8, { 2, 1, 1, 1 } },
3126 { ISD::TRUNCATE, MVT::v64i1, MVT::v16i16, { 2, 1, 1, 1 } },
3127
3128 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i16, { 2, 1, 1, 1 } },
3129 };
3130
3131 static const TypeConversionCostKindTblEntry AVX512DQVLConversionTbl[] = {
3132 // Mask sign extend has an instruction.
3133 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v2i1, { 1, 1, 1, 1 } },
3134 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v2i1, { 1, 1, 1, 1 } },
3135 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v4i1, { 1, 1, 1, 1 } },
3136 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v16i1, { 1, 1, 1, 1 } },
3137 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i1, { 1, 1, 1, 1 } },
3138 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v8i1, { 1, 1, 1, 1 } },
3139 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v16i1, { 1, 1, 1, 1 } },
3140 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i1, { 1, 1, 1, 1 } },
3141
3142 // Mask zero extend is a sext + shift.
3143 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v2i1, { 2, 1, 1, 1 } },
3144 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v2i1, { 2, 1, 1, 1 } },
3145 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v4i1, { 2, 1, 1, 1 } },
3146 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v16i1, { 2, 1, 1, 1 } },
3147 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i1, { 2, 1, 1, 1 } },
3148 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v8i1, { 2, 1, 1, 1 } },
3149 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v16i1, { 2, 1, 1, 1 } },
3150 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i1, { 2, 1, 1, 1 } },
3151
3152 { ISD::TRUNCATE, MVT::v16i1, MVT::v4i64, { 2, 1, 1, 1 } },
3153 { ISD::TRUNCATE, MVT::v16i1, MVT::v8i32, { 2, 1, 1, 1 } },
3154 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i64, { 2, 1, 1, 1 } },
3155 { ISD::TRUNCATE, MVT::v2i1, MVT::v4i32, { 2, 1, 1, 1 } },
3156 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i32, { 2, 1, 1, 1 } },
3157 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i64, { 2, 1, 1, 1 } },
3158 { ISD::TRUNCATE, MVT::v8i1, MVT::v4i64, { 2, 1, 1, 1 } },
3159 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i32, { 2, 1, 1, 1 } },
3160
3161 { ISD::SINT_TO_FP, MVT::v2f32, MVT::v2i64, { 1, 1, 1, 1 } },
3162 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v2i64, { 1, 1, 1, 1 } },
3163 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v4i64, { 1, 1, 1, 1 } },
3164 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v4i64, { 1, 1, 1, 1 } },
3165
3166 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i64, { 1, 1, 1, 1 } },
3167 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i64, { 1, 1, 1, 1 } },
3168 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i64, { 1, 1, 1, 1 } },
3169 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i64, { 1, 1, 1, 1 } },
3170
3171 { ISD::FP_TO_SINT, MVT::v2i64, MVT::v4f32, { 1, 1, 1, 1 } },
3172 { ISD::FP_TO_SINT, MVT::v4i64, MVT::v4f32, { 1, 1, 1, 1 } },
3173 { ISD::FP_TO_SINT, MVT::v2i64, MVT::v2f64, { 1, 1, 1, 1 } },
3174 { ISD::FP_TO_SINT, MVT::v4i64, MVT::v4f64, { 1, 1, 1, 1 } },
3175
3176 { ISD::FP_TO_UINT, MVT::v2i64, MVT::v4f32, { 1, 1, 1, 1 } },
3177 { ISD::FP_TO_UINT, MVT::v4i64, MVT::v4f32, { 1, 1, 1, 1 } },
3178 { ISD::FP_TO_UINT, MVT::v2i64, MVT::v2f64, { 1, 1, 1, 1 } },
3179 { ISD::FP_TO_UINT, MVT::v4i64, MVT::v4f64, { 1, 1, 1, 1 } },
3180 };
3181
3182 static const TypeConversionCostKindTblEntry AVX512VLConversionTbl[] = {
3183 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i8, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
3184 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i8, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
3185 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i8, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
3186 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i8, { 8, 1, 1, 1 } }, // split+2*v8i8
3187 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i16, { 3, 1, 1, 1 } }, // sext+vpsllq+vptestmq
3188 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i16, { 3, 1, 1, 1 } }, // sext+vpsllq+vptestmq
3189 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i16, { 3, 1, 1, 1 } }, // sext+vpsllq+vptestmq
3190 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i16, { 8, 1, 1, 1 } }, // split+2*v8i16
3191 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i32, { 2, 1, 1, 1 } }, // vpslld+vptestmd
3192 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i32, { 2, 1, 1, 1 } }, // vpslld+vptestmd
3193 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i32, { 2, 1, 1, 1 } }, // vpslld+vptestmd
3194 { ISD::TRUNCATE, MVT::v16i1, MVT::v8i32, { 2, 1, 1, 1 } }, // vpslld+vptestmd
3195 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i64, { 2, 1, 1, 1 } }, // vpsllq+vptestmq
3196 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i64, { 2, 1, 1, 1 } }, // vpsllq+vptestmq
3197 { ISD::TRUNCATE, MVT::v4i32, MVT::v4i64, { 1, 1, 1, 1 } }, // vpmovqd
3198 { ISD::TRUNCATE, MVT::v4i8, MVT::v4i64, { 2, 1, 1, 1 } }, // vpmovqb
3199 { ISD::TRUNCATE, MVT::v4i16, MVT::v4i64, { 2, 1, 1, 1 } }, // vpmovqw
3200 { ISD::TRUNCATE, MVT::v8i8, MVT::v8i32, { 2, 1, 1, 1 } }, // vpmovwb
3201
3202 // sign extend is vpcmpeq+maskedmove+vpmovdw+vpacksswb
3203 // zero extend is vpcmpeq+maskedmove+vpmovdw+vpsrlw+vpackuswb
3204 { ISD::SIGN_EXTEND, MVT::v2i8, MVT::v2i1, { 5, 1, 1, 1 } },
3205 { ISD::ZERO_EXTEND, MVT::v2i8, MVT::v2i1, { 6, 1, 1, 1 } },
3206 { ISD::SIGN_EXTEND, MVT::v4i8, MVT::v4i1, { 5, 1, 1, 1 } },
3207 { ISD::ZERO_EXTEND, MVT::v4i8, MVT::v4i1, { 6, 1, 1, 1 } },
3208 { ISD::SIGN_EXTEND, MVT::v8i8, MVT::v8i1, { 5, 1, 1, 1 } },
3209 { ISD::ZERO_EXTEND, MVT::v8i8, MVT::v8i1, { 6, 1, 1, 1 } },
3210 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v16i1, {10, 1, 1, 1 } },
3211 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v16i1, {12, 1, 1, 1 } },
3212
3213 // sign extend is vpcmpeq+maskedmove+vpmovdw
3214 // zero extend is vpcmpeq+maskedmove+vpmovdw+vpsrlw
3215 { ISD::SIGN_EXTEND, MVT::v2i16, MVT::v2i1, { 4, 1, 1, 1 } },
3216 { ISD::ZERO_EXTEND, MVT::v2i16, MVT::v2i1, { 5, 1, 1, 1 } },
3217 { ISD::SIGN_EXTEND, MVT::v4i16, MVT::v4i1, { 4, 1, 1, 1 } },
3218 { ISD::ZERO_EXTEND, MVT::v4i16, MVT::v4i1, { 5, 1, 1, 1 } },
3219 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v8i1, { 4, 1, 1, 1 } },
3220 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v8i1, { 5, 1, 1, 1 } },
3221 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i1, {10, 1, 1, 1 } },
3222 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i1, {12, 1, 1, 1 } },
3223
3224 { ISD::SIGN_EXTEND, MVT::v2i32, MVT::v2i1, { 1, 1, 1, 1 } }, // vpternlogd
3225 { ISD::ZERO_EXTEND, MVT::v2i32, MVT::v2i1, { 2, 1, 1, 1 } }, // vpternlogd+psrld
3226 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v4i1, { 1, 1, 1, 1 } }, // vpternlogd
3227 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v4i1, { 2, 1, 1, 1 } }, // vpternlogd+psrld
3228 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i1, { 1, 1, 1, 1 } }, // vpternlogd
3229 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i1, { 2, 1, 1, 1 } }, // vpternlogd+psrld
3230 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v16i1, { 1, 1, 1, 1 } }, // vpternlogd
3231 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v16i1, { 2, 1, 1, 1 } }, // vpternlogd+psrld
3232
3233 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v2i1, { 1, 1, 1, 1 } }, // vpternlogq
3234 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v2i1, { 2, 1, 1, 1 } }, // vpternlogq+psrlq
3235 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i1, { 1, 1, 1, 1 } }, // vpternlogq
3236 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i1, { 2, 1, 1, 1 } }, // vpternlogq+psrlq
3237
3238 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v16i8, { 1, 1, 1, 1 } },
3239 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v16i8, { 1, 1, 1, 1 } },
3240 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v16i8, { 1, 1, 1, 1 } },
3241 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v16i8, { 1, 1, 1, 1 } },
3242 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i8, { 1, 1, 1, 1 } },
3243 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i8, { 1, 1, 1, 1 } },
3244 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v8i16, { 1, 1, 1, 1 } },
3245 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v8i16, { 1, 1, 1, 1 } },
3246 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i16, { 1, 1, 1, 1 } },
3247 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i16, { 1, 1, 1, 1 } },
3248 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i32, { 1, 1, 1, 1 } },
3249 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i32, { 1, 1, 1, 1 } },
3250
3251 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v16i8, { 1, 1, 1, 1 } },
3252 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v16i8, { 1, 1, 1, 1 } },
3253 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v8i16, { 1, 1, 1, 1 } },
3254 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v8i16, { 1, 1, 1, 1 } },
3255
3256 { ISD::UINT_TO_FP, MVT::f32, MVT::i64, { 1, 1, 1, 1 } },
3257 { ISD::UINT_TO_FP, MVT::f64, MVT::i64, { 1, 1, 1, 1 } },
3258 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v16i8, { 1, 1, 1, 1 } },
3259 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v16i8, { 1, 1, 1, 1 } },
3260 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v8i16, { 1, 1, 1, 1 } },
3261 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i16, { 1, 1, 1, 1 } },
3262 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i32, { 1, 1, 1, 1 } },
3263 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i32, { 1, 1, 1, 1 } },
3264 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i32, { 1, 1, 1, 1 } },
3265 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i32, { 1, 1, 1, 1 } },
3266 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i64, { 5, 1, 1, 1 } },
3267 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i64, { 5, 1, 1, 1 } },
3268 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i64, { 5, 1, 1, 1 } },
3269
3270 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v8f32, { 2, 1, 1, 1 } },
3271 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v16f32, { 2, 1, 1, 1 } },
3272 { ISD::FP_TO_SINT, MVT::v32i8, MVT::v32f32, { 5, 1, 1, 1 } },
3273
3274 { ISD::FP_TO_UINT, MVT::i64, MVT::f32, { 1, 1, 1, 1 } },
3275 { ISD::FP_TO_UINT, MVT::i64, MVT::f64, { 1, 1, 1, 1 } },
3276 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f32, { 1, 1, 1, 1 } },
3277 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v2f64, { 1, 1, 1, 1 } },
3278 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f64, { 1, 1, 1, 1 } },
3279 { ISD::FP_TO_UINT, MVT::v8i32, MVT::v8f32, { 1, 1, 1, 1 } },
3280 { ISD::FP_TO_UINT, MVT::v8i32, MVT::v8f64, { 1, 1, 1, 1 } },
3281 };
3282
3283 static const TypeConversionCostKindTblEntry AVX2ConversionTbl[] = {
3284 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i1, { 3, 1, 1, 1 } },
3285 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i1, { 3, 1, 1, 1 } },
3286 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i1, { 3, 1, 1, 1 } },
3287 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i1, { 3, 1, 1, 1 } },
3288 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i1, { 1, 1, 1, 1 } },
3289 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i1, { 1, 1, 1, 1 } },
3290
3291 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v16i8, { 2, 1, 1, 1 } },
3292 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v16i8, { 2, 1, 1, 1 } },
3293 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v16i8, { 2, 1, 1, 1 } },
3294 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v16i8, { 2, 1, 1, 1 } },
3295 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i8, { 2, 1, 1, 1 } },
3296 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i8, { 2, 1, 1, 1 } },
3297 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v8i16, { 2, 1, 1, 1 } },
3298 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v8i16, { 2, 1, 1, 1 } },
3299 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i16, { 2, 1, 1, 1 } },
3300 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i16, { 2, 1, 1, 1 } },
3301 { ISD::ZERO_EXTEND, MVT::v16i32, MVT::v16i16, { 3, 1, 1, 1 } },
3302 { ISD::SIGN_EXTEND, MVT::v16i32, MVT::v16i16, { 3, 1, 1, 1 } },
3303 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i32, { 2, 1, 1, 1 } },
3304 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i32, { 2, 1, 1, 1 } },
3305
3306 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i32, { 2, 1, 1, 1 } },
3307
3308 { ISD::TRUNCATE, MVT::v16i16, MVT::v16i32, { 4, 1, 1, 1 } },
3309 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i32, { 4, 1, 1, 1 } },
3310 { ISD::TRUNCATE, MVT::v16i8, MVT::v8i16, { 1, 1, 1, 1 } },
3311 { ISD::TRUNCATE, MVT::v16i8, MVT::v4i32, { 1, 1, 1, 1 } },
3312 { ISD::TRUNCATE, MVT::v16i8, MVT::v2i64, { 1, 1, 1, 1 } },
3313 { ISD::TRUNCATE, MVT::v16i8, MVT::v8i32, { 4, 1, 1, 1 } },
3314 { ISD::TRUNCATE, MVT::v16i8, MVT::v4i64, { 4, 1, 1, 1 } },
3315 { ISD::TRUNCATE, MVT::v8i16, MVT::v4i32, { 1, 1, 1, 1 } },
3316 { ISD::TRUNCATE, MVT::v8i16, MVT::v2i64, { 1, 1, 1, 1 } },
3317 { ISD::TRUNCATE, MVT::v8i16, MVT::v4i64, { 5, 1, 1, 1 } },
3318 { ISD::TRUNCATE, MVT::v4i32, MVT::v4i64, { 1, 1, 1, 1 } },
3319 { ISD::TRUNCATE, MVT::v8i16, MVT::v8i32, { 2, 1, 1, 1 } },
3320
3321 { ISD::FP_EXTEND, MVT::v8f64, MVT::v8f32, { 3, 1, 1, 1 } },
3322 { ISD::FP_ROUND, MVT::v8f32, MVT::v8f64, { 3, 1, 1, 1 } },
3323
3324 { ISD::FP_TO_SINT, MVT::v16i16, MVT::v8f32, { 1, 1, 1, 1 } },
3325 { ISD::FP_TO_SINT, MVT::v4i32, MVT::v4f64, { 1, 1, 1, 1 } },
3326 { ISD::FP_TO_SINT, MVT::v8i32, MVT::v8f32, { 1, 1, 1, 1 } },
3327 { ISD::FP_TO_SINT, MVT::v8i32, MVT::v8f64, { 3, 1, 1, 1 } },
3328
3329 { ISD::FP_TO_UINT, MVT::i64, MVT::f32, { 3, 1, 1, 1 } },
3330 { ISD::FP_TO_UINT, MVT::i64, MVT::f64, { 3, 1, 1, 1 } },
3331 { ISD::FP_TO_UINT, MVT::v16i16, MVT::v8f32, { 1, 1, 1, 1 } },
3332 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f32, { 3, 1, 1, 1 } },
3333 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v2f64, { 4, 1, 1, 1 } },
3334 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f64, { 4, 1, 1, 1 } },
3335 { ISD::FP_TO_UINT, MVT::v8i32, MVT::v8f32, { 3, 1, 1, 1 } },
3336 { ISD::FP_TO_UINT, MVT::v8i32, MVT::v4f64, { 4, 1, 1, 1 } },
3337
3338 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v16i8, { 2, 1, 1, 1 } },
3339 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v16i8, { 2, 1, 1, 1 } },
3340 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v8i16, { 2, 1, 1, 1 } },
3341 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v8i16, { 2, 1, 1, 1 } },
3342 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v4i32, { 1, 1, 1, 1 } },
3343 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v8i32, { 1, 1, 1, 1 } },
3344 { ISD::SINT_TO_FP, MVT::v8f64, MVT::v8i32, { 3, 1, 1, 1 } },
3345
3346 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v16i8, { 2, 1, 1, 1 } },
3347 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v16i8, { 2, 1, 1, 1 } },
3348 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v8i16, { 2, 1, 1, 1 } },
3349 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i16, { 2, 1, 1, 1 } },
3350 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i32, { 2, 1, 1, 1 } },
3351 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i32, { 1, 1, 1, 1 } },
3352 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i32, { 2, 1, 1, 1 } },
3353 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i32, { 2, 1, 1, 1 } },
3354 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i32, { 2, 1, 1, 1 } },
3355 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i32, { 4, 1, 1, 1 } },
3356 };
3357
3358 static const TypeConversionCostKindTblEntry AVXConversionTbl[] = {
3359 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i1, { 4, 1, 1, 1 } },
3360 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i1, { 4, 1, 1, 1 } },
3361 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i1, { 4, 1, 1, 1 } },
3362 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i1, { 4, 1, 1, 1 } },
3363 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i1, { 4, 1, 1, 1 } },
3364 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i1, { 4, 1, 1, 1 } },
3365
3366 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v16i8, { 3, 1, 1, 1 } },
3367 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v16i8, { 3, 1, 1, 1 } },
3368 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v16i8, { 3, 1, 1, 1 } },
3369 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v16i8, { 3, 1, 1, 1 } },
3370 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i8, { 3, 1, 1, 1 } },
3371 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i8, { 3, 1, 1, 1 } },
3372 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v8i16, { 3, 1, 1, 1 } },
3373 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v8i16, { 3, 1, 1, 1 } },
3374 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i16, { 3, 1, 1, 1 } },
3375 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i16, { 3, 1, 1, 1 } },
3376 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i32, { 3, 1, 1, 1 } },
3377 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i32, { 3, 1, 1, 1 } },
3378
3379 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i64, { 4, 1, 1, 1 } },
3380 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i32, { 5, 1, 1, 1 } },
3381 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i16, { 4, 1, 1, 1 } },
3382 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i64, { 9, 1, 1, 1 } },
3383 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i64, {11, 1, 1, 1 } },
3384
3385 { ISD::TRUNCATE, MVT::v16i16, MVT::v16i32, { 6, 1, 1, 1 } },
3386 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i32, { 6, 1, 1, 1 } },
3387 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i16, { 2, 1, 1, 1 } }, // and+extract+packuswb
3388 { ISD::TRUNCATE, MVT::v16i8, MVT::v8i32, { 5, 1, 1, 1 } },
3389 { ISD::TRUNCATE, MVT::v8i16, MVT::v8i32, { 5, 1, 1, 1 } },
3390 { ISD::TRUNCATE, MVT::v16i8, MVT::v4i64, { 5, 1, 1, 1 } },
3391 { ISD::TRUNCATE, MVT::v8i16, MVT::v4i64, { 3, 1, 1, 1 } }, // and+extract+2*packusdw
3392 { ISD::TRUNCATE, MVT::v4i32, MVT::v4i64, { 2, 1, 1, 1 } },
3393
3394 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v4i1, { 3, 1, 1, 1 } },
3395 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v4i1, { 3, 1, 1, 1 } },
3396 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v8i1, { 8, 1, 1, 1 } },
3397 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v16i8, { 4, 1, 1, 1 } },
3398 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v16i8, { 2, 1, 1, 1 } },
3399 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v8i16, { 4, 1, 1, 1 } },
3400 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v8i16, { 2, 1, 1, 1 } },
3401 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v4i32, { 2, 1, 1, 1 } },
3402 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v8i32, { 2, 1, 1, 1 } },
3403 { ISD::SINT_TO_FP, MVT::v8f64, MVT::v8i32, { 4, 1, 1, 1 } },
3404 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v2i64, { 5, 1, 1, 1 } },
3405 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v4i64, { 8, 1, 1, 1 } },
3406
3407 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i1, { 7, 1, 1, 1 } },
3408 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i1, { 7, 1, 1, 1 } },
3409 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i1, { 6, 1, 1, 1 } },
3410 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v16i8, { 4, 1, 1, 1 } },
3411 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v16i8, { 2, 1, 1, 1 } },
3412 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i16, { 4, 1, 1, 1 } },
3413 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v8i16, { 2, 1, 1, 1 } },
3414 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i32, { 4, 1, 1, 1 } },
3415 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i32, { 4, 1, 1, 1 } },
3416 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i32, { 5, 1, 1, 1 } },
3417 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i32, { 6, 1, 1, 1 } },
3418 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i32, { 8, 1, 1, 1 } },
3419 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i32, {10, 1, 1, 1 } },
3420 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i64, {10, 1, 1, 1 } },
3421 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i64, {18, 1, 1, 1 } },
3422 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i64, { 5, 1, 1, 1 } },
3423 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i64, {10, 1, 1, 1 } },
3424
3425 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v8f32, { 2, 1, 1, 1 } },
3426 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v4f64, { 2, 1, 1, 1 } },
3427 { ISD::FP_TO_SINT, MVT::v32i8, MVT::v8f32, { 2, 1, 1, 1 } },
3428 { ISD::FP_TO_SINT, MVT::v32i8, MVT::v4f64, { 2, 1, 1, 1 } },
3429 { ISD::FP_TO_SINT, MVT::v8i16, MVT::v8f32, { 2, 1, 1, 1 } },
3430 { ISD::FP_TO_SINT, MVT::v8i16, MVT::v4f64, { 2, 1, 1, 1 } },
3431 { ISD::FP_TO_SINT, MVT::v16i16, MVT::v8f32, { 2, 1, 1, 1 } },
3432 { ISD::FP_TO_SINT, MVT::v16i16, MVT::v4f64, { 2, 1, 1, 1 } },
3433 { ISD::FP_TO_SINT, MVT::v4i32, MVT::v4f64, { 2, 1, 1, 1 } },
3434 { ISD::FP_TO_SINT, MVT::v8i32, MVT::v8f32, { 2, 1, 1, 1 } },
3435 { ISD::FP_TO_SINT, MVT::v8i32, MVT::v8f64, { 5, 1, 1, 1 } },
3436
3437 { ISD::FP_TO_UINT, MVT::v16i8, MVT::v8f32, { 2, 1, 1, 1 } },
3438 { ISD::FP_TO_UINT, MVT::v16i8, MVT::v4f64, { 2, 1, 1, 1 } },
3439 { ISD::FP_TO_UINT, MVT::v32i8, MVT::v8f32, { 2, 1, 1, 1 } },
3440 { ISD::FP_TO_UINT, MVT::v32i8, MVT::v4f64, { 2, 1, 1, 1 } },
3441 { ISD::FP_TO_UINT, MVT::v8i16, MVT::v8f32, { 2, 1, 1, 1 } },
3442 { ISD::FP_TO_UINT, MVT::v8i16, MVT::v4f64, { 2, 1, 1, 1 } },
3443 { ISD::FP_TO_UINT, MVT::v16i16, MVT::v8f32, { 2, 1, 1, 1 } },
3444 { ISD::FP_TO_UINT, MVT::v16i16, MVT::v4f64, { 2, 1, 1, 1 } },
3445 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f32, { 3, 1, 1, 1 } },
3446 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v2f64, { 4, 1, 1, 1 } },
3447 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f64, { 6, 1, 1, 1 } },
3448 { ISD::FP_TO_UINT, MVT::v8i32, MVT::v8f32, { 7, 1, 1, 1 } },
3449 { ISD::FP_TO_UINT, MVT::v8i32, MVT::v4f64, { 7, 1, 1, 1 } },
3450
3451 { ISD::FP_EXTEND, MVT::v4f64, MVT::v4f32, { 1, 1, 1, 1 } },
3452 { ISD::FP_ROUND, MVT::v4f32, MVT::v4f64, { 1, 1, 1, 1 } },
3453 };
3454
3455 static const TypeConversionCostKindTblEntry SSE41ConversionTbl[] = {
3456 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v16i8, { 1, 1, 1, 1 } },
3457 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v16i8, { 1, 1, 1, 1 } },
3458 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v16i8, { 1, 1, 1, 1 } },
3459 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v16i8, { 1, 1, 1, 1 } },
3460 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v16i8, { 1, 1, 1, 1 } },
3461 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v16i8, { 1, 1, 1, 1 } },
3462 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v8i16, { 1, 1, 1, 1 } },
3463 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v8i16, { 1, 1, 1, 1 } },
3464 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v8i16, { 1, 1, 1, 1 } },
3465 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v8i16, { 1, 1, 1, 1 } },
3466 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v4i32, { 1, 1, 1, 1 } },
3467 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v4i32, { 1, 1, 1, 1 } },
3468
3469 // These truncates end up widening elements.
3470 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i8, { 1, 1, 1, 1 } }, // PMOVXZBQ
3471 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i16, { 1, 1, 1, 1 } }, // PMOVXZWQ
3472 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i8, { 1, 1, 1, 1 } }, // PMOVXZBD
3473
3474 { ISD::TRUNCATE, MVT::v16i8, MVT::v4i32, { 2, 1, 1, 1 } },
3475 { ISD::TRUNCATE, MVT::v8i16, MVT::v4i32, { 2, 1, 1, 1 } },
3476 { ISD::TRUNCATE, MVT::v16i8, MVT::v2i64, { 2, 1, 1, 1 } },
3477
3478 { ISD::SINT_TO_FP, MVT::f32, MVT::i32, { 1, 1, 1, 1 } },
3479 { ISD::SINT_TO_FP, MVT::f64, MVT::i32, { 1, 1, 1, 1 } },
3480 { ISD::SINT_TO_FP, MVT::f32, MVT::i64, { 1, 1, 1, 1 } },
3481 { ISD::SINT_TO_FP, MVT::f64, MVT::i64, { 1, 1, 1, 1 } },
3482 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v16i8, { 1, 1, 1, 1 } },
3483 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v16i8, { 1, 1, 1, 1 } },
3484 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v8i16, { 1, 1, 1, 1 } },
3485 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v8i16, { 1, 1, 1, 1 } },
3486 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v4i32, { 1, 1, 1, 1 } },
3487 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v4i32, { 1, 1, 1, 1 } },
3488 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v4i32, { 2, 1, 1, 1 } },
3489
3490 { ISD::UINT_TO_FP, MVT::f32, MVT::i32, { 1, 1, 1, 1 } },
3491 { ISD::UINT_TO_FP, MVT::f64, MVT::i32, { 1, 1, 1, 1 } },
3492 { ISD::UINT_TO_FP, MVT::f32, MVT::i64, { 4, 1, 1, 1 } },
3493 { ISD::UINT_TO_FP, MVT::f64, MVT::i64, { 4, 1, 1, 1 } },
3494 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v16i8, { 1, 1, 1, 1 } },
3495 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v16i8, { 1, 1, 1, 1 } },
3496 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v8i16, { 1, 1, 1, 1 } },
3497 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v8i16, { 1, 1, 1, 1 } },
3498 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i32, { 3, 1, 1, 1 } },
3499 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i32, { 3, 1, 1, 1 } },
3500 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v4i32, { 2, 1, 1, 1 } },
3501 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v2i64, {12, 1, 1, 1 } },
3502 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i64, {22, 1, 1, 1 } },
3503 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i64, { 4, 1, 1, 1 } },
3504
3505 { ISD::FP_TO_SINT, MVT::i32, MVT::f32, { 1, 1, 1, 1 } },
3506 { ISD::FP_TO_SINT, MVT::i64, MVT::f32, { 1, 1, 1, 1 } },
3507 { ISD::FP_TO_SINT, MVT::i32, MVT::f64, { 1, 1, 1, 1 } },
3508 { ISD::FP_TO_SINT, MVT::i64, MVT::f64, { 1, 1, 1, 1 } },
3509 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v4f32, { 2, 1, 1, 1 } },
3510 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v2f64, { 2, 1, 1, 1 } },
3511 { ISD::FP_TO_SINT, MVT::v8i16, MVT::v4f32, { 1, 1, 1, 1 } },
3512 { ISD::FP_TO_SINT, MVT::v8i16, MVT::v2f64, { 1, 1, 1, 1 } },
3513 { ISD::FP_TO_SINT, MVT::v4i32, MVT::v4f32, { 1, 1, 1, 1 } },
3514 { ISD::FP_TO_SINT, MVT::v4i32, MVT::v2f64, { 1, 1, 1, 1 } },
3515
3516 { ISD::FP_TO_UINT, MVT::i32, MVT::f32, { 1, 1, 1, 1 } },
3517 { ISD::FP_TO_UINT, MVT::i64, MVT::f32, { 4, 1, 1, 1 } },
3518 { ISD::FP_TO_UINT, MVT::i32, MVT::f64, { 1, 1, 1, 1 } },
3519 { ISD::FP_TO_UINT, MVT::i64, MVT::f64, { 4, 1, 1, 1 } },
3520 { ISD::FP_TO_UINT, MVT::v16i8, MVT::v4f32, { 2, 1, 1, 1 } },
3521 { ISD::FP_TO_UINT, MVT::v16i8, MVT::v2f64, { 2, 1, 1, 1 } },
3522 { ISD::FP_TO_UINT, MVT::v8i16, MVT::v4f32, { 1, 1, 1, 1 } },
3523 { ISD::FP_TO_UINT, MVT::v8i16, MVT::v2f64, { 1, 1, 1, 1 } },
3524 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f32, { 4, 1, 1, 1 } },
3525 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v2f64, { 4, 1, 1, 1 } },
3526 };
3527
3528 static const TypeConversionCostKindTblEntry SSE2ConversionTbl[] = {
3529 // These are somewhat magic numbers justified by comparing the
3530 // output of llvm-mca for our various supported scheduler models
3531 // and basing it off the worst case scenario.
3532 { ISD::SINT_TO_FP, MVT::f32, MVT::i32, { 3, 1, 1, 1 } },
3533 { ISD::SINT_TO_FP, MVT::f64, MVT::i32, { 3, 1, 1, 1 } },
3534 { ISD::SINT_TO_FP, MVT::f32, MVT::i64, { 3, 1, 1, 1 } },
3535 { ISD::SINT_TO_FP, MVT::f64, MVT::i64, { 3, 1, 1, 1 } },
3536 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v16i8, { 3, 1, 1, 1 } },
3537 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v16i8, { 4, 1, 1, 1 } },
3538 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v8i16, { 3, 1, 1, 1 } },
3539 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v8i16, { 4, 1, 1, 1 } },
3540 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v4i32, { 3, 1, 1, 1 } },
3541 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v4i32, { 4, 1, 1, 1 } },
3542 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v2i64, { 8, 1, 1, 1 } },
3543 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v2i64, { 8, 1, 1, 1 } },
3544
3545 { ISD::UINT_TO_FP, MVT::f32, MVT::i32, { 3, 1, 1, 1 } },
3546 { ISD::UINT_TO_FP, MVT::f64, MVT::i32, { 3, 1, 1, 1 } },
3547 { ISD::UINT_TO_FP, MVT::f32, MVT::i64, { 8, 1, 1, 1 } },
3548 { ISD::UINT_TO_FP, MVT::f64, MVT::i64, { 9, 1, 1, 1 } },
3549 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v16i8, { 4, 1, 1, 1 } },
3550 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v16i8, { 4, 1, 1, 1 } },
3551 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v8i16, { 4, 1, 1, 1 } },
3552 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v8i16, { 4, 1, 1, 1 } },
3553 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i32, { 7, 1, 1, 1 } },
3554 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v4i32, { 7, 1, 1, 1 } },
3555 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i32, { 5, 1, 1, 1 } },
3556 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i64, {15, 1, 1, 1 } },
3557 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v2i64, {18, 1, 1, 1 } },
3558
3559 { ISD::FP_TO_SINT, MVT::i32, MVT::f32, { 4, 1, 1, 1 } },
3560 { ISD::FP_TO_SINT, MVT::i64, MVT::f32, { 4, 1, 1, 1 } },
3561 { ISD::FP_TO_SINT, MVT::i32, MVT::f64, { 4, 1, 1, 1 } },
3562 { ISD::FP_TO_SINT, MVT::i64, MVT::f64, { 4, 1, 1, 1 } },
3563 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v4f32, { 6, 1, 1, 1 } },
3564 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v2f64, { 6, 1, 1, 1 } },
3565 { ISD::FP_TO_SINT, MVT::v8i16, MVT::v4f32, { 5, 1, 1, 1 } },
3566 { ISD::FP_TO_SINT, MVT::v8i16, MVT::v2f64, { 5, 1, 1, 1 } },
3567 { ISD::FP_TO_SINT, MVT::v4i32, MVT::v4f32, { 4, 1, 1, 1 } },
3568 { ISD::FP_TO_SINT, MVT::v4i32, MVT::v2f64, { 4, 1, 1, 1 } },
3569
3570 { ISD::FP_TO_UINT, MVT::i32, MVT::f32, { 4, 1, 1, 1 } },
3571 { ISD::FP_TO_UINT, MVT::i64, MVT::f32, { 4, 1, 1, 1 } },
3572 { ISD::FP_TO_UINT, MVT::i32, MVT::f64, { 4, 1, 1, 1 } },
3573 { ISD::FP_TO_UINT, MVT::i64, MVT::f64, {15, 1, 1, 1 } },
3574 { ISD::FP_TO_UINT, MVT::v16i8, MVT::v4f32, { 6, 1, 1, 1 } },
3575 { ISD::FP_TO_UINT, MVT::v16i8, MVT::v2f64, { 6, 1, 1, 1 } },
3576 { ISD::FP_TO_UINT, MVT::v8i16, MVT::v4f32, { 5, 1, 1, 1 } },
3577 { ISD::FP_TO_UINT, MVT::v8i16, MVT::v2f64, { 5, 1, 1, 1 } },
3578 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f32, { 8, 1, 1, 1 } },
3579 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v2f64, { 8, 1, 1, 1 } },
3580
3581 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v16i8, { 4, 1, 1, 1 } },
3582 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v16i8, { 4, 1, 1, 1 } },
3583 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v16i8, { 2, 1, 1, 1 } },
3584 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v16i8, { 3, 1, 1, 1 } },
3585 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v16i8, { 1, 1, 1, 1 } },
3586 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v16i8, { 2, 1, 1, 1 } },
3587 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v8i16, { 2, 1, 1, 1 } },
3588 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v8i16, { 3, 1, 1, 1 } },
3589 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v8i16, { 1, 1, 1, 1 } },
3590 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v8i16, { 2, 1, 1, 1 } },
3591 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v4i32, { 1, 1, 1, 1 } },
3592 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v4i32, { 2, 1, 1, 1 } },
3593
3594 // These truncates are really widening elements.
3595 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i32, { 1, 1, 1, 1 } }, // PSHUFD
3596 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i16, { 2, 1, 1, 1 } }, // PUNPCKLWD+DQ
3597 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i8, { 3, 1, 1, 1 } }, // PUNPCKLBW+WD+PSHUFD
3598 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i16, { 1, 1, 1, 1 } }, // PUNPCKLWD
3599 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i8, { 2, 1, 1, 1 } }, // PUNPCKLBW+WD
3600 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i8, { 1, 1, 1, 1 } }, // PUNPCKLBW
3601
3602 { ISD::TRUNCATE, MVT::v16i8, MVT::v8i16, { 2, 1, 1, 1 } }, // PAND+PACKUSWB
3603 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i16, { 3, 1, 1, 1 } },
3604 { ISD::TRUNCATE, MVT::v16i8, MVT::v4i32, { 3, 1, 1, 1 } }, // PAND+2*PACKUSWB
3605 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i32, { 7, 1, 1, 1 } },
3606 { ISD::TRUNCATE, MVT::v2i16, MVT::v2i32, { 1, 1, 1, 1 } },
3607 { ISD::TRUNCATE, MVT::v8i16, MVT::v4i32, { 3, 1, 1, 1 } },
3608 { ISD::TRUNCATE, MVT::v8i16, MVT::v8i32, { 5, 1, 1, 1 } },
3609 { ISD::TRUNCATE, MVT::v16i16, MVT::v16i32, {10, 1, 1, 1 } },
3610 { ISD::TRUNCATE, MVT::v16i8, MVT::v2i64, { 4, 1, 1, 1 } }, // PAND+3*PACKUSWB
3611 { ISD::TRUNCATE, MVT::v8i16, MVT::v2i64, { 2, 1, 1, 1 } }, // PSHUFD+PSHUFLW
3612 { ISD::TRUNCATE, MVT::v4i32, MVT::v2i64, { 1, 1, 1, 1 } }, // PSHUFD
3613 };
3614
3615 static const TypeConversionCostKindTblEntry F16ConversionTbl[] = {
3616 { ISD::FP_ROUND, MVT::f16, MVT::f32, { 1, 1, 1, 1 } },
3617 { ISD::FP_ROUND, MVT::v8f16, MVT::v8f32, { 1, 1, 1, 1 } },
3618 { ISD::FP_ROUND, MVT::v4f16, MVT::v4f32, { 1, 1, 1, 1 } },
3619 { ISD::FP_EXTEND, MVT::f32, MVT::f16, { 1, 1, 1, 1 } },
3620 { ISD::FP_EXTEND, MVT::f64, MVT::f16, { 2, 1, 1, 1 } }, // vcvtph2ps+vcvtps2pd
3621 { ISD::FP_EXTEND, MVT::v8f32, MVT::v8f16, { 1, 1, 1, 1 } },
3622 { ISD::FP_EXTEND, MVT::v4f32, MVT::v4f16, { 1, 1, 1, 1 } },
3623 { ISD::FP_EXTEND, MVT::v4f64, MVT::v4f16, { 2, 1, 1, 1 } }, // vcvtph2ps+vcvtps2pd
3624 };
3625
3626 // Attempt to map directly to (simple) MVT types to let us match custom entries.
3627 EVT SrcTy = TLI->getValueType(DL, Src);
3628 EVT DstTy = TLI->getValueType(DL, Dst);
3629
3630 // If we're sign-extending a vector comparison result back to the comparison
3631 // width, this will be free without AVX512 (or for 8/16-bit types without
3632 // BWI).
3633 if (!ST->hasAVX512() || (!ST->hasBWI() && DstTy.getScalarSizeInBits() < 32)) {
3634 if (I && Opcode == Instruction::CastOps::SExt &&
3635 SrcTy.isFixedLengthVectorOf(MVT::i1)) {
3636 if (auto *CmpI = dyn_cast<CmpInst>(I->getOperand(0))) {
3637 Type *CmpTy = CmpI->getOperand(0)->getType();
3638 if (CmpTy->getScalarSizeInBits() == DstTy.getScalarSizeInBits())
3639 return TTI::TCC_Free;
3640 }
3641 }
3642 }
3643
3644 // The function getSimpleVT only handles simple value types.
3645 if (SrcTy.isSimple() && DstTy.isSimple()) {
3646 MVT SimpleSrcTy = SrcTy.getSimpleVT();
3647 MVT SimpleDstTy = DstTy.getSimpleVT();
3648
3649 if (ST->useAVX512Regs()) {
3650 if (ST->hasBWI())
3651 if (const auto *Entry = ConvertCostTableLookup(
3652 AVX512BWConversionTbl, ISD, SimpleDstTy, SimpleSrcTy))
3653 if (auto KindCost = Entry->Cost[CostKind])
3654 return *KindCost;
3655
3656 if (ST->hasDQI())
3657 if (const auto *Entry = ConvertCostTableLookup(
3658 AVX512DQConversionTbl, ISD, SimpleDstTy, SimpleSrcTy))
3659 if (auto KindCost = Entry->Cost[CostKind])
3660 return *KindCost;
3661
3662 if (ST->hasAVX512())
3663 if (const auto *Entry = ConvertCostTableLookup(
3664 AVX512FConversionTbl, ISD, SimpleDstTy, SimpleSrcTy))
3665 if (auto KindCost = Entry->Cost[CostKind])
3666 return *KindCost;
3667 }
3668
3669 if (ST->hasBWI())
3670 if (const auto *Entry = ConvertCostTableLookup(
3671 AVX512BWVLConversionTbl, ISD, SimpleDstTy, SimpleSrcTy))
3672 if (auto KindCost = Entry->Cost[CostKind])
3673 return *KindCost;
3674
3675 if (ST->hasDQI())
3676 if (const auto *Entry = ConvertCostTableLookup(
3677 AVX512DQVLConversionTbl, ISD, SimpleDstTy, SimpleSrcTy))
3678 if (auto KindCost = Entry->Cost[CostKind])
3679 return *KindCost;
3680
3681 if (ST->hasAVX512())
3682 if (const auto *Entry = ConvertCostTableLookup(AVX512VLConversionTbl, ISD,
3683 SimpleDstTy, SimpleSrcTy))
3684 if (auto KindCost = Entry->Cost[CostKind])
3685 return *KindCost;
3686
3687 if (ST->hasAVX2()) {
3688 if (const auto *Entry = ConvertCostTableLookup(AVX2ConversionTbl, ISD,
3689 SimpleDstTy, SimpleSrcTy))
3690 if (auto KindCost = Entry->Cost[CostKind])
3691 return *KindCost;
3692 }
3693
3694 if (ST->hasAVX()) {
3695 if (const auto *Entry = ConvertCostTableLookup(AVXConversionTbl, ISD,
3696 SimpleDstTy, SimpleSrcTy))
3697 if (auto KindCost = Entry->Cost[CostKind])
3698 return *KindCost;
3699 }
3700
3701 if (ST->hasF16C()) {
3702 if (const auto *Entry = ConvertCostTableLookup(F16ConversionTbl, ISD,
3703 SimpleDstTy, SimpleSrcTy))
3704 if (auto KindCost = Entry->Cost[CostKind])
3705 return *KindCost;
3706 }
3707
3708 if (ST->hasSSE41()) {
3709 if (const auto *Entry = ConvertCostTableLookup(SSE41ConversionTbl, ISD,
3710 SimpleDstTy, SimpleSrcTy))
3711 if (auto KindCost = Entry->Cost[CostKind])
3712 return *KindCost;
3713 }
3714
3715 if (ST->hasSSE2()) {
3716 if (const auto *Entry = ConvertCostTableLookup(SSE2ConversionTbl, ISD,
3717 SimpleDstTy, SimpleSrcTy))
3718 if (auto KindCost = Entry->Cost[CostKind])
3719 return *KindCost;
3720 }
3721
3722 if ((ISD == ISD::FP_ROUND && SimpleDstTy == MVT::f16) ||
3723 (ISD == ISD::FP_EXTEND && SimpleSrcTy == MVT::f16)) {
3724 // fp16 conversions not covered by any table entries require a libcall.
3725 // Return a large (arbitrary) number to model this.
3726 return InstructionCost(64);
3727 }
3728 }
3729
3730 // Fall back to legalized types.
3731 std::pair<InstructionCost, MVT> LTSrc = getTypeLegalizationCost(Src);
3732 std::pair<InstructionCost, MVT> LTDest = getTypeLegalizationCost(Dst);
3733
3734 // If we're truncating to the same legalized type - just assume its free.
3735 if (ISD == ISD::TRUNCATE && LTSrc.second == LTDest.second)
3736 return TTI::TCC_Free;
3737
3738 if (ST->useAVX512Regs()) {
3739 if (ST->hasBWI())
3740 if (const auto *Entry = ConvertCostTableLookup(
3741 AVX512BWConversionTbl, ISD, LTDest.second, LTSrc.second))
3742 if (auto KindCost = Entry->Cost[CostKind])
3743 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3744
3745 if (ST->hasDQI())
3746 if (const auto *Entry = ConvertCostTableLookup(
3747 AVX512DQConversionTbl, ISD, LTDest.second, LTSrc.second))
3748 if (auto KindCost = Entry->Cost[CostKind])
3749 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3750
3751 if (ST->hasAVX512())
3752 if (const auto *Entry = ConvertCostTableLookup(
3753 AVX512FConversionTbl, ISD, LTDest.second, LTSrc.second))
3754 if (auto KindCost = Entry->Cost[CostKind])
3755 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3756 }
3757
3758 if (ST->hasBWI())
3759 if (const auto *Entry = ConvertCostTableLookup(AVX512BWVLConversionTbl, ISD,
3760 LTDest.second, LTSrc.second))
3761 if (auto KindCost = Entry->Cost[CostKind])
3762 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3763
3764 if (ST->hasDQI())
3765 if (const auto *Entry = ConvertCostTableLookup(AVX512DQVLConversionTbl, ISD,
3766 LTDest.second, LTSrc.second))
3767 if (auto KindCost = Entry->Cost[CostKind])
3768 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3769
3770 if (ST->hasAVX512())
3771 if (const auto *Entry = ConvertCostTableLookup(AVX512VLConversionTbl, ISD,
3772 LTDest.second, LTSrc.second))
3773 if (auto KindCost = Entry->Cost[CostKind])
3774 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3775
3776 if (ST->hasAVX2())
3777 if (const auto *Entry = ConvertCostTableLookup(AVX2ConversionTbl, ISD,
3778 LTDest.second, LTSrc.second))
3779 if (auto KindCost = Entry->Cost[CostKind])
3780 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3781
3782 if (ST->hasAVX())
3783 if (const auto *Entry = ConvertCostTableLookup(AVXConversionTbl, ISD,
3784 LTDest.second, LTSrc.second))
3785 if (auto KindCost = Entry->Cost[CostKind])
3786 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3787
3788 if (ST->hasF16C()) {
3789 if (const auto *Entry = ConvertCostTableLookup(F16ConversionTbl, ISD,
3790 LTDest.second, LTSrc.second))
3791 if (auto KindCost = Entry->Cost[CostKind])
3792 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3793 }
3794
3795 if (ST->hasSSE41())
3796 if (const auto *Entry = ConvertCostTableLookup(SSE41ConversionTbl, ISD,
3797 LTDest.second, LTSrc.second))
3798 if (auto KindCost = Entry->Cost[CostKind])
3799 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3800
3801 if (ST->hasSSE2())
3802 if (const auto *Entry = ConvertCostTableLookup(SSE2ConversionTbl, ISD,
3803 LTDest.second, LTSrc.second))
3804 if (auto KindCost = Entry->Cost[CostKind])
3805 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3806
3807 // Fallback, for i8/i16 sitofp/uitofp cases we need to extend to i32 for
3808 // sitofp.
3809 if ((ISD == ISD::SINT_TO_FP || ISD == ISD::UINT_TO_FP) &&
3810 1 < Src->getScalarSizeInBits() && Src->getScalarSizeInBits() < 32) {
3811 Type *ExtSrc = Src->getWithNewBitWidth(32);
3812 unsigned ExtOpc =
3813 (ISD == ISD::SINT_TO_FP) ? Instruction::SExt : Instruction::ZExt;
3814
3815 // For scalar loads the extend would be free.
3816 InstructionCost ExtCost = 0;
3817 if (!(Src->isIntegerTy() && I && isa<LoadInst>(I->getOperand(0))))
3818 ExtCost = getCastInstrCost(ExtOpc, ExtSrc, Src, CCH, CostKind);
3819
3820 return ExtCost + getCastInstrCost(Instruction::SIToFP, Dst, ExtSrc,
3822 }
3823
3824 // Fallback for fptosi/fptoui i8/i16 cases we need to truncate from fptosi
3825 // i32.
3826 if ((ISD == ISD::FP_TO_SINT || ISD == ISD::FP_TO_UINT) &&
3827 1 < Dst->getScalarSizeInBits() && Dst->getScalarSizeInBits() < 32) {
3828 Type *TruncDst = Dst->getWithNewBitWidth(32);
3829 return getCastInstrCost(Instruction::FPToSI, TruncDst, Src, CCH, CostKind) +
3830 getCastInstrCost(Instruction::Trunc, Dst, TruncDst,
3832 }
3833
3834 // TODO: Allow non-throughput costs that aren't binary.
3835 auto AdjustCost = [&CostKind](InstructionCost Cost,
3838 return Cost == 0 ? 0 : N;
3839 return Cost * N;
3840 };
3841 return AdjustCost(
3842 BaseT::getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I));
3843}
3844
3846 unsigned Opcode, Type *ValTy, Type *CondTy, CmpInst::Predicate VecPred,
3848 TTI::OperandValueInfo Op2Info, const Instruction *I) const {
3849 // Early out if this type isn't scalar/vector integer/float.
3850 if (!(ValTy->isIntOrIntVectorTy() || ValTy->isFPOrFPVectorTy()))
3851 return BaseT::getCmpSelInstrCost(Opcode, ValTy, CondTy, VecPred, CostKind,
3852 Op1Info, Op2Info, I);
3853
3854 // Legalize the type.
3855 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(ValTy);
3856
3857 MVT MTy = LT.second;
3858
3859 int ISD = TLI->InstructionOpcodeToISD(Opcode);
3860 assert(ISD && "Invalid opcode");
3861
3862 InstructionCost ExtraCost = 0;
3863 if (Opcode == Instruction::ICmp || Opcode == Instruction::FCmp) {
3864 // Some vector comparison predicates cost extra instructions.
3865 // TODO: Adjust ExtraCost based on CostKind?
3866 // TODO: Should we invert this and assume worst case cmp costs
3867 // and reduce for particular predicates?
3868 if (MTy.isVector() &&
3869 !((ST->hasXOP() && (!ST->hasAVX2() || MTy.is128BitVector())) ||
3870 (ST->hasAVX512() && 32 <= MTy.getScalarSizeInBits()) ||
3871 ST->hasBWI())) {
3872 // Fallback to I if a specific predicate wasn't specified.
3873 CmpInst::Predicate Pred = VecPred;
3874 if (I && (Pred == CmpInst::BAD_ICMP_PREDICATE ||
3876 Pred = cast<CmpInst>(I)->getPredicate();
3877
3878 bool CmpWithConstant = false;
3879 if (auto *CmpInstr = dyn_cast_or_null<CmpInst>(I))
3880 CmpWithConstant = isa<Constant>(CmpInstr->getOperand(1));
3881
3882 switch (Pred) {
3884 // xor(cmpeq(x,y),-1)
3885 ExtraCost = CmpWithConstant ? 0 : 1;
3886 break;
3889 // xor(cmpgt(x,y),-1)
3890 ExtraCost = CmpWithConstant ? 0 : 1;
3891 break;
3894 // cmpgt(xor(x,signbit),xor(y,signbit))
3895 // xor(cmpeq(pmaxu(x,y),x),-1)
3896 ExtraCost = CmpWithConstant ? 1 : 2;
3897 break;
3900 if ((ST->hasSSE41() && MTy.getScalarSizeInBits() == 32) ||
3901 (ST->hasSSE2() && MTy.getScalarSizeInBits() < 32)) {
3902 // cmpeq(psubus(x,y),0)
3903 // cmpeq(pminu(x,y),x)
3904 ExtraCost = 1;
3905 } else {
3906 // xor(cmpgt(xor(x,signbit),xor(y,signbit)),-1)
3907 ExtraCost = CmpWithConstant ? 2 : 3;
3908 }
3909 break;
3912 // Without AVX we need to expand FCMP_ONE/FCMP_UEQ cases.
3913 // Use FCMP_UEQ expansion - FCMP_ONE should be the same.
3914 if (CondTy && !ST->hasAVX())
3915 return getCmpSelInstrCost(Opcode, ValTy, CondTy,
3917 Op1Info, Op2Info) +
3918 getCmpSelInstrCost(Opcode, ValTy, CondTy,
3920 Op1Info, Op2Info) +
3921 getArithmeticInstrCost(Instruction::Or, CondTy, CostKind);
3922
3923 break;
3926 // Assume worst case scenario and add the maximum extra cost.
3927 ExtraCost = 3;
3928 break;
3929 default:
3930 break;
3931 }
3932 }
3933 }
3934
3935 static const CostKindTblEntry SLMCostTbl[] = {
3936 // slm pcmpeq/pcmpgt throughput is 2
3937 { ISD::SETCC, MVT::v2i64, { 2, 5, 1, 2 } },
3938 // slm pblendvb/blendvpd/blendvps throughput is 4
3939 { ISD::SELECT, MVT::v2f64, { 4, 4, 1, 3 } }, // vblendvpd
3940 { ISD::SELECT, MVT::v4f32, { 4, 4, 1, 3 } }, // vblendvps
3941 { ISD::SELECT, MVT::v2i64, { 4, 4, 1, 3 } }, // pblendvb
3942 { ISD::SELECT, MVT::v8i32, { 4, 4, 1, 3 } }, // pblendvb
3943 { ISD::SELECT, MVT::v8i16, { 4, 4, 1, 3 } }, // pblendvb
3944 { ISD::SELECT, MVT::v16i8, { 4, 4, 1, 3 } }, // pblendvb
3945 };
3946
3947 static const CostKindTblEntry AVX512BWCostTbl[] = {
3948 { ISD::SETCC, MVT::v32i16, { 1, 1, 1, 1 } },
3949 { ISD::SETCC, MVT::v16i16, { 1, 1, 1, 1 } },
3950 { ISD::SETCC, MVT::v64i8, { 1, 1, 1, 1 } },
3951 { ISD::SETCC, MVT::v32i8, { 1, 1, 1, 1 } },
3952
3953 { ISD::SELECT, MVT::v32i16, { 1, 1, 1, 1 } },
3954 { ISD::SELECT, MVT::v64i8, { 1, 1, 1, 1 } },
3955 };
3956
3957 static const CostKindTblEntry AVX512CostTbl[] = {
3958 { ISD::SETCC, MVT::v8f64, { 1, 4, 1, 1 } },
3959 { ISD::SETCC, MVT::v4f64, { 1, 4, 1, 1 } },
3960 { ISD::SETCC, MVT::v16f32, { 1, 4, 1, 1 } },
3961 { ISD::SETCC, MVT::v8f32, { 1, 4, 1, 1 } },
3962
3963 { ISD::SETCC, MVT::v8i64, { 1, 1, 1, 1 } },
3964 { ISD::SETCC, MVT::v4i64, { 1, 1, 1, 1 } },
3965 { ISD::SETCC, MVT::v2i64, { 1, 1, 1, 1 } },
3966 { ISD::SETCC, MVT::v16i32, { 1, 1, 1, 1 } },
3967 { ISD::SETCC, MVT::v8i32, { 1, 1, 1, 1 } },
3968 { ISD::SETCC, MVT::v32i16, { 3, 7, 5, 5 } },
3969 { ISD::SETCC, MVT::v64i8, { 3, 7, 5, 5 } },
3970
3971 { ISD::SELECT, MVT::v8i64, { 1, 1, 1, 1 } },
3972 { ISD::SELECT, MVT::v4i64, { 1, 1, 1, 1 } },
3973 { ISD::SELECT, MVT::v2i64, { 1, 1, 1, 1 } },
3974 { ISD::SELECT, MVT::v16i32, { 1, 1, 1, 1 } },
3975 { ISD::SELECT, MVT::v8i32, { 1, 1, 1, 1 } },
3976 { ISD::SELECT, MVT::v4i32, { 1, 1, 1, 1 } },
3977 { ISD::SELECT, MVT::v8f64, { 1, 1, 1, 1 } },
3978 { ISD::SELECT, MVT::v4f64, { 1, 1, 1, 1 } },
3979 { ISD::SELECT, MVT::v2f64, { 1, 1, 1, 1 } },
3980 { ISD::SELECT, MVT::f64, { 1, 1, 1, 1 } },
3981 { ISD::SELECT, MVT::v16f32, { 1, 1, 1, 1 } },
3982 { ISD::SELECT, MVT::v8f32 , { 1, 1, 1, 1 } },
3983 { ISD::SELECT, MVT::v4f32, { 1, 1, 1, 1 } },
3984 { ISD::SELECT, MVT::f32 , { 1, 1, 1, 1 } },
3985
3986 { ISD::SELECT, MVT::v32i16, { 2, 2, 4, 4 } },
3987 { ISD::SELECT, MVT::v16i16, { 1, 1, 1, 1 } },
3988 { ISD::SELECT, MVT::v8i16, { 1, 1, 1, 1 } },
3989 { ISD::SELECT, MVT::v64i8, { 2, 2, 4, 4 } },
3990 { ISD::SELECT, MVT::v32i8, { 1, 1, 1, 1 } },
3991 { ISD::SELECT, MVT::v16i8, { 1, 1, 1, 1 } },
3992 };
3993
3994 static const CostKindTblEntry AVX2CostTbl[] = {
3995 { ISD::SETCC, MVT::v4f64, { 1, 4, 1, 2 } },
3996 { ISD::SETCC, MVT::v2f64, { 1, 4, 1, 1 } },
3997 { ISD::SETCC, MVT::f64, { 1, 4, 1, 1 } },
3998 { ISD::SETCC, MVT::v8f32, { 1, 4, 1, 2 } },
3999 { ISD::SETCC, MVT::v4f32, { 1, 4, 1, 1 } },
4000 { ISD::SETCC, MVT::f32, { 1, 4, 1, 1 } },
4001
4002 { ISD::SETCC, MVT::v4i64, { 1, 1, 1, 2 } },
4003 { ISD::SETCC, MVT::v8i32, { 1, 1, 1, 2 } },
4004 { ISD::SETCC, MVT::v16i16, { 1, 1, 1, 2 } },
4005 { ISD::SETCC, MVT::v32i8, { 1, 1, 1, 2 } },
4006
4007 { ISD::SELECT, MVT::v4f64, { 2, 2, 1, 2 } }, // vblendvpd
4008 { ISD::SELECT, MVT::v8f32, { 2, 2, 1, 2 } }, // vblendvps
4009 { ISD::SELECT, MVT::v4i64, { 2, 2, 1, 2 } }, // pblendvb
4010 { ISD::SELECT, MVT::v8i32, { 2, 2, 1, 2 } }, // pblendvb
4011 { ISD::SELECT, MVT::v16i16, { 2, 2, 1, 2 } }, // pblendvb
4012 { ISD::SELECT, MVT::v32i8, { 2, 2, 1, 2 } }, // pblendvb
4013 };
4014
4015 static const CostKindTblEntry XOPCostTbl[] = {
4016 { ISD::SETCC, MVT::v4i64, { 4, 2, 5, 6 } },
4017 { ISD::SETCC, MVT::v2i64, { 1, 1, 1, 1 } },
4018 };
4019
4020 static const CostKindTblEntry AVX1CostTbl[] = {
4021 { ISD::SETCC, MVT::v4f64, { 2, 3, 1, 2 } },
4022 { ISD::SETCC, MVT::v2f64, { 1, 3, 1, 1 } },
4023 { ISD::SETCC, MVT::f64, { 1, 3, 1, 1 } },
4024 { ISD::SETCC, MVT::v8f32, { 2, 3, 1, 2 } },
4025 { ISD::SETCC, MVT::v4f32, { 1, 3, 1, 1 } },
4026 { ISD::SETCC, MVT::f32, { 1, 3, 1, 1 } },
4027
4028 // AVX1 does not support 8-wide integer compare.
4029 { ISD::SETCC, MVT::v4i64, { 4, 2, 5, 6 } },
4030 { ISD::SETCC, MVT::v8i32, { 4, 2, 5, 6 } },
4031 { ISD::SETCC, MVT::v16i16, { 4, 2, 5, 6 } },
4032 { ISD::SETCC, MVT::v32i8, { 4, 2, 5, 6 } },
4033
4034 { ISD::SELECT, MVT::v4f64, { 3, 3, 1, 2 } }, // vblendvpd
4035 { ISD::SELECT, MVT::v8f32, { 3, 3, 1, 2 } }, // vblendvps
4036 { ISD::SELECT, MVT::v4i64, { 3, 3, 1, 2 } }, // vblendvpd
4037 { ISD::SELECT, MVT::v8i32, { 3, 3, 1, 2 } }, // vblendvps
4038 { ISD::SELECT, MVT::v16i16, { 3, 3, 3, 3 } }, // vandps + vandnps + vorps
4039 { ISD::SELECT, MVT::v32i8, { 3, 3, 3, 3 } }, // vandps + vandnps + vorps
4040 };
4041
4042 static const CostKindTblEntry SSE42CostTbl[] = {
4043 { ISD::SETCC, MVT::v2i64, { 1, 2, 1, 2 } },
4044 };
4045
4046 static const CostKindTblEntry SSE41CostTbl[] = {
4047 { ISD::SETCC, MVT::v2f64, { 1, 5, 1, 1 } },
4048 { ISD::SETCC, MVT::v4f32, { 1, 5, 1, 1 } },
4049
4050 { ISD::SELECT, MVT::v2f64, { 2, 2, 1, 2 } }, // blendvpd
4051 { ISD::SELECT, MVT::f64, { 2, 2, 1, 2 } }, // blendvpd
4052 { ISD::SELECT, MVT::v4f32, { 2, 2, 1, 2 } }, // blendvps
4053 { ISD::SELECT, MVT::f32 , { 2, 2, 1, 2 } }, // blendvps
4054 { ISD::SELECT, MVT::v2i64, { 2, 2, 1, 2 } }, // pblendvb
4055 { ISD::SELECT, MVT::v4i32, { 2, 2, 1, 2 } }, // pblendvb
4056 { ISD::SELECT, MVT::v8i16, { 2, 2, 1, 2 } }, // pblendvb
4057 { ISD::SELECT, MVT::v16i8, { 2, 2, 1, 2 } }, // pblendvb
4058 };
4059
4060 static const CostKindTblEntry SSE2CostTbl[] = {
4061 { ISD::SETCC, MVT::v2f64, { 2, 5, 1, 1 } },
4062 { ISD::SETCC, MVT::f64, { 1, 5, 1, 1 } },
4063
4064 { ISD::SETCC, MVT::v2i64, { 5, 4, 5, 5 } }, // pcmpeqd/pcmpgtd expansion
4065 { ISD::SETCC, MVT::v4i32, { 1, 1, 1, 1 } },
4066 { ISD::SETCC, MVT::v8i16, { 1, 1, 1, 1 } },
4067 { ISD::SETCC, MVT::v16i8, { 1, 1, 1, 1 } },
4068
4069 { ISD::SELECT, MVT::v2f64, { 2, 2, 3, 3 } }, // andpd + andnpd + orpd
4070 { ISD::SELECT, MVT::f64, { 2, 2, 3, 3 } }, // andpd + andnpd + orpd
4071 { ISD::SELECT, MVT::v2i64, { 2, 2, 3, 3 } }, // pand + pandn + por
4072 { ISD::SELECT, MVT::v4i32, { 2, 2, 3, 3 } }, // pand + pandn + por
4073 { ISD::SELECT, MVT::v8i16, { 2, 2, 3, 3 } }, // pand + pandn + por
4074 { ISD::SELECT, MVT::v16i8, { 2, 2, 3, 3 } }, // pand + pandn + por
4075 };
4076
4077 static const CostKindTblEntry SSE1CostTbl[] = {
4078 { ISD::SETCC, MVT::v4f32, { 2, 5, 1, 1 } },
4079 { ISD::SETCC, MVT::f32, { 1, 5, 1, 1 } },
4080
4081 { ISD::SELECT, MVT::v4f32, { 2, 2, 3, 3 } }, // andps + andnps + orps
4082 { ISD::SELECT, MVT::f32, { 2, 2, 3, 3 } }, // andps + andnps + orps
4083 };
4084
4085 if (ST->useSLMArithCosts())
4086 if (const auto *Entry = CostTableLookup(SLMCostTbl, ISD, MTy))
4087 if (auto KindCost = Entry->Cost[CostKind])
4088 return LT.first * (ExtraCost + *KindCost);
4089
4090 if (ST->hasBWI())
4091 if (const auto *Entry = CostTableLookup(AVX512BWCostTbl, ISD, MTy))
4092 if (auto KindCost = Entry->Cost[CostKind])
4093 return LT.first * (ExtraCost + *KindCost);
4094
4095 if (ST->hasAVX512())
4096 if (const auto *Entry = CostTableLookup(AVX512CostTbl, ISD, MTy))
4097 if (auto KindCost = Entry->Cost[CostKind])
4098 return LT.first * (ExtraCost + *KindCost);
4099
4100 if (ST->hasAVX2())
4101 if (const auto *Entry = CostTableLookup(AVX2CostTbl, ISD, MTy))
4102 if (auto KindCost = Entry->Cost[CostKind])
4103 return LT.first * (ExtraCost + *KindCost);
4104
4105 if (ST->hasXOP())
4106 if (const auto *Entry = CostTableLookup(XOPCostTbl, ISD, MTy))
4107 if (auto KindCost = Entry->Cost[CostKind])
4108 return LT.first * (ExtraCost + *KindCost);
4109
4110 if (ST->hasAVX())
4111 if (const auto *Entry = CostTableLookup(AVX1CostTbl, ISD, MTy))
4112 if (auto KindCost = Entry->Cost[CostKind])
4113 return LT.first * (ExtraCost + *KindCost);
4114
4115 if (ST->hasSSE42())
4116 if (const auto *Entry = CostTableLookup(SSE42CostTbl, ISD, MTy))
4117 if (auto KindCost = Entry->Cost[CostKind])
4118 return LT.first * (ExtraCost + *KindCost);
4119
4120 if (ST->hasSSE41())
4121 if (const auto *Entry = CostTableLookup(SSE41CostTbl, ISD, MTy))
4122 if (auto KindCost = Entry->Cost[CostKind])
4123 return LT.first * (ExtraCost + *KindCost);
4124
4125 if (ST->hasSSE2())
4126 if (const auto *Entry = CostTableLookup(SSE2CostTbl, ISD, MTy))
4127 if (auto KindCost = Entry->Cost[CostKind])
4128 return LT.first * (ExtraCost + *KindCost);
4129
4130 if (ST->hasSSE1())
4131 if (const auto *Entry = CostTableLookup(SSE1CostTbl, ISD, MTy))
4132 if (auto KindCost = Entry->Cost[CostKind])
4133 return LT.first * (ExtraCost + *KindCost);
4134
4135 // Assume a 3cy latency for fp select ops.
4136 if (CostKind == TTI::TCK_Latency && Opcode == Instruction::Select)
4137 if (ValTy->getScalarType()->isFloatingPointTy())
4138 return 3;
4139
4140 return BaseT::getCmpSelInstrCost(Opcode, ValTy, CondTy, VecPred, CostKind,
4141 Op1Info, Op2Info, I);
4142}
4143
4145
4149 // Costs should match the codegen from:
4150 // BITREVERSE: llvm\test\CodeGen\X86\vector-bitreverse.ll
4151 // BSWAP: llvm\test\CodeGen\X86\bswap-vector.ll
4152 // CTLZ: llvm\test\CodeGen\X86\vector-lzcnt-*.ll
4153 // CTPOP: llvm\test\CodeGen\X86\vector-popcnt-*.ll
4154 // CTTZ: llvm\test\CodeGen\X86\vector-tzcnt-*.ll
4155
4156 // TODO: Overflow intrinsics (*ADDO, *SUBO, *MULO) with vector types are not
4157 // specialized in these tables yet.
4158 static const CostKindTblEntry AVX512VBMI2CostTbl[] = {
4159 { ISD::FSHL, MVT::v8i64, { 1, 1, 1, 1 } },
4160 { ISD::FSHL, MVT::v4i64, { 1, 1, 1, 1 } },
4161 { ISD::FSHL, MVT::v2i64, { 1, 1, 1, 1 } },
4162 { ISD::FSHL, MVT::v16i32, { 1, 1, 1, 1 } },
4163 { ISD::FSHL, MVT::v8i32, { 1, 1, 1, 1 } },
4164 { ISD::FSHL, MVT::v4i32, { 1, 1, 1, 1 } },
4165 { ISD::FSHL, MVT::v32i16, { 1, 1, 1, 1 } },
4166 { ISD::FSHL, MVT::v16i16, { 1, 1, 1, 1 } },
4167 { ISD::FSHL, MVT::v8i16, { 1, 1, 1, 1 } },
4168 { ISD::ROTL, MVT::v32i16, { 1, 1, 1, 1 } },
4169 { ISD::ROTL, MVT::v16i16, { 1, 1, 1, 1 } },
4170 { ISD::ROTL, MVT::v8i16, { 1, 1, 1, 1 } },
4171 { ISD::ROTR, MVT::v32i16, { 1, 1, 1, 1 } },
4172 { ISD::ROTR, MVT::v16i16, { 1, 1, 1, 1 } },
4173 { ISD::ROTR, MVT::v8i16, { 1, 1, 1, 1 } },
4174 { X86ISD::VROTLI, MVT::v32i16, { 1, 1, 1, 1 } },
4175 { X86ISD::VROTLI, MVT::v16i16, { 1, 1, 1, 1 } },
4176 { X86ISD::VROTLI, MVT::v8i16, { 1, 1, 1, 1 } },
4177 };
4178 static const CostKindTblEntry AVX512BITALGCostTbl[] = {
4179 { ISD::CTPOP, MVT::v32i16, { 1, 1, 1, 1 } },
4180 { ISD::CTPOP, MVT::v64i8, { 1, 1, 1, 1 } },
4181 { ISD::CTPOP, MVT::v16i16, { 1, 1, 1, 1 } },
4182 { ISD::CTPOP, MVT::v32i8, { 1, 1, 1, 1 } },
4183 { ISD::CTPOP, MVT::v8i16, { 1, 1, 1, 1 } },
4184 { ISD::CTPOP, MVT::v16i8, { 1, 1, 1, 1 } },
4185 };
4186 static const CostKindTblEntry AVX512VPOPCNTDQCostTbl[] = {
4187 { ISD::CTPOP, MVT::v8i64, { 1, 1, 1, 1 } },
4188 { ISD::CTPOP, MVT::v16i32, { 1, 1, 1, 1 } },
4189 { ISD::CTPOP, MVT::v4i64, { 1, 1, 1, 1 } },
4190 { ISD::CTPOP, MVT::v8i32, { 1, 1, 1, 1 } },
4191 { ISD::CTPOP, MVT::v2i64, { 1, 1, 1, 1 } },
4192 { ISD::CTPOP, MVT::v4i32, { 1, 1, 1, 1 } },
4193 };
4194 static const CostKindTblEntry AVX512CDCostTbl[] = {
4195 { ISD::CTLZ, MVT::v8i64, { 1, 5, 1, 1 } },
4196 { ISD::CTLZ, MVT::v16i32, { 1, 5, 1, 1 } },
4197 { ISD::CTLZ, MVT::v32i16, { 18, 27, 23, 27 } },
4198 { ISD::CTLZ, MVT::v64i8, { 3, 16, 9, 11 } },
4199 { ISD::CTLZ, MVT::v4i64, { 1, 5, 1, 1 } },
4200 { ISD::CTLZ, MVT::v8i32, { 1, 5, 1, 1 } },
4201 { ISD::CTLZ, MVT::v16i16, { 8, 19, 11, 13 } },
4202 { ISD::CTLZ, MVT::v32i8, { 2, 11, 9, 10 } },
4203 { ISD::CTLZ, MVT::v2i64, { 1, 5, 1, 1 } },
4204 { ISD::CTLZ, MVT::v4i32, { 1, 5, 1, 1 } },
4205 { ISD::CTLZ, MVT::v8i16, { 3, 15, 4, 6 } },
4206 { ISD::CTLZ, MVT::v16i8, { 2, 10, 9, 10 } },
4207
4208 { ISD::CTTZ, MVT::v8i64, { 2, 8, 6, 7 } },
4209 { ISD::CTTZ, MVT::v16i32, { 2, 8, 6, 7 } },
4210 { ISD::CTTZ, MVT::v4i64, { 1, 8, 6, 6 } },
4211 { ISD::CTTZ, MVT::v8i32, { 1, 8, 6, 6 } },
4212 { ISD::CTTZ, MVT::v2i64, { 1, 8, 6, 6 } },
4213 { ISD::CTTZ, MVT::v4i32, { 1, 8, 6, 6 } },
4214 };
4215 static const CostKindTblEntry AVX512BWCostTbl[] = {
4216 { ISD::ABS, MVT::v32i16, { 1, 1, 1, 1 } },
4217 { ISD::ABS, MVT::v64i8, { 1, 1, 1, 1 } },
4218 { ISD::BITREVERSE, MVT::v2i64, { 3, 10, 10, 11 } },
4219 { ISD::BITREVERSE, MVT::v4i64, { 3, 11, 10, 11 } },
4220 { ISD::BITREVERSE, MVT::v8i64, { 3, 12, 10, 14 } },
4221 { ISD::BITREVERSE, MVT::v4i32, { 3, 10, 10, 11 } },
4222 { ISD::BITREVERSE, MVT::v8i32, { 3, 11, 10, 11 } },
4223 { ISD::BITREVERSE, MVT::v16i32, { 3, 12, 10, 14 } },
4224 { ISD::BITREVERSE, MVT::v8i16, { 3, 10, 10, 11 } },
4225 { ISD::BITREVERSE, MVT::v16i16, { 3, 11, 10, 11 } },
4226 { ISD::BITREVERSE, MVT::v32i16, { 3, 12, 10, 14 } },
4227 { ISD::BITREVERSE, MVT::v16i8, { 2, 5, 9, 9 } },
4228 { ISD::BITREVERSE, MVT::v32i8, { 2, 5, 9, 9 } },
4229 { ISD::BITREVERSE, MVT::v64i8, { 2, 5, 9, 12 } },
4230 { ISD::BSWAP, MVT::v2i64, { 1, 1, 1, 2 } },
4231 { ISD::BSWAP, MVT::v4i64, { 1, 1, 1, 2 } },
4232 { ISD::BSWAP, MVT::v8i64, { 1, 1, 1, 2 } },
4233 { ISD::BSWAP, MVT::v4i32, { 1, 1, 1, 2 } },
4234 { ISD::BSWAP, MVT::v8i32, { 1, 1, 1, 2 } },
4235 { ISD::BSWAP, MVT::v16i32, { 1, 1, 1, 2 } },
4236 { ISD::BSWAP, MVT::v8i16, { 1, 1, 1, 2 } },
4237 { ISD::BSWAP, MVT::v16i16, { 1, 1, 1, 2 } },
4238 { ISD::BSWAP, MVT::v32i16, { 1, 1, 1, 2 } },
4239 { ISD::CTLZ, MVT::v8i64, { 8, 22, 23, 23 } },
4240 { ISD::CTLZ, MVT::v16i32, { 8, 23, 25, 25 } },
4241 { ISD::CTLZ, MVT::v32i16, { 4, 15, 15, 16 } },
4242 { ISD::CTLZ, MVT::v64i8, { 3, 12, 10, 9 } },
4243 { ISD::CTPOP, MVT::v2i64, { 3, 7, 10, 10 } },
4244 { ISD::CTPOP, MVT::v4i64, { 3, 7, 10, 10 } },
4245 { ISD::CTPOP, MVT::v8i64, { 3, 8, 10, 12 } },
4246 { ISD::CTPOP, MVT::v4i32, { 7, 11, 14, 14 } },
4247 { ISD::CTPOP, MVT::v8i32, { 7, 11, 14, 14 } },
4248 { ISD::CTPOP, MVT::v16i32, { 7, 12, 14, 16 } },
4249 { ISD::CTPOP, MVT::v8i16, { 2, 7, 11, 11 } },
4250 { ISD::CTPOP, MVT::v16i16, { 2, 7, 11, 11 } },
4251 { ISD::CTPOP, MVT::v32i16, { 3, 7, 11, 13 } },
4252 { ISD::CTPOP, MVT::v16i8, { 2, 4, 8, 8 } },
4253 { ISD::CTPOP, MVT::v32i8, { 2, 4, 8, 8 } },
4254 { ISD::CTPOP, MVT::v64i8, { 2, 5, 8, 10 } },
4255 { ISD::CTTZ, MVT::v8i16, { 3, 9, 14, 14 } },
4256 { ISD::CTTZ, MVT::v16i16, { 3, 9, 14, 14 } },
4257 { ISD::CTTZ, MVT::v32i16, { 3, 10, 14, 16 } },
4258 { ISD::CTTZ, MVT::v16i8, { 2, 6, 11, 11 } },
4259 { ISD::CTTZ, MVT::v32i8, { 2, 6, 11, 11 } },
4260 { ISD::CTTZ, MVT::v64i8, { 3, 7, 11, 13 } },
4261 { ISD::MULHS, MVT::v32i16, { 1, 5, 1, 1 } },
4262 { ISD::MULHU, MVT::v32i16, { 1, 5, 1, 1 } },
4263 { ISD::ROTL, MVT::v32i16, { 2, 8, 6, 8 } },
4264 { ISD::ROTL, MVT::v16i16, { 2, 8, 6, 7 } },
4265 { ISD::ROTL, MVT::v8i16, { 2, 7, 6, 7 } },
4266 { ISD::ROTL, MVT::v64i8, { 5, 6, 11, 12 } },
4267 { ISD::ROTL, MVT::v32i8, { 5, 15, 7, 10 } },
4268 { ISD::ROTL, MVT::v16i8, { 5, 15, 7, 10 } },
4269 { ISD::ROTR, MVT::v32i16, { 2, 8, 6, 8 } },
4270 { ISD::ROTR, MVT::v16i16, { 2, 8, 6, 7 } },
4271 { ISD::ROTR, MVT::v8i16, { 2, 7, 6, 7 } },
4272 { ISD::ROTR, MVT::v64i8, { 5, 6, 12, 14 } },
4273 { ISD::ROTR, MVT::v32i8, { 5, 14, 6, 9 } },
4274 { ISD::ROTR, MVT::v16i8, { 5, 14, 6, 9 } },
4275 { X86ISD::VROTLI, MVT::v32i16, { 2, 5, 3, 3 } },
4276 { X86ISD::VROTLI, MVT::v16i16, { 1, 5, 3, 3 } },
4277 { X86ISD::VROTLI, MVT::v8i16, { 1, 5, 3, 3 } },
4278 { X86ISD::VROTLI, MVT::v64i8, { 2, 9, 3, 4 } },
4279 { X86ISD::VROTLI, MVT::v32i8, { 1, 9, 3, 4 } },
4280 { X86ISD::VROTLI, MVT::v16i8, { 1, 8, 3, 4 } },
4281 { ISD::SADDSAT, MVT::v32i16, { 1, 1, 1, 1 } },
4282 { ISD::SADDSAT, MVT::v64i8, { 1, 1, 1, 1 } },
4283 { ISD::SMAX, MVT::v32i16, { 1, 1, 1, 1 } },
4284 { ISD::SMAX, MVT::v64i8, { 1, 1, 1, 1 } },
4285 { ISD::SMIN, MVT::v32i16, { 1, 1, 1, 1 } },
4286 { ISD::SMIN, MVT::v64i8, { 1, 1, 1, 1 } },
4287 { ISD::SMULO, MVT::v32i16, { 3, 6, 4, 4 } },
4288 { ISD::SMULO, MVT::v64i8, { 8, 21, 17, 18 } },
4289 { ISD::UMULO, MVT::v32i16, { 2, 5, 3, 3 } },
4290 { ISD::UMULO, MVT::v64i8, { 8, 15, 15, 16 } },
4291 { ISD::SSUBSAT, MVT::v32i16, { 1, 1, 1, 1 } },
4292 { ISD::SSUBSAT, MVT::v64i8, { 1, 1, 1, 1 } },
4293 { ISD::UADDSAT, MVT::v32i16, { 1, 1, 1, 1 } },
4294 { ISD::UADDSAT, MVT::v64i8, { 1, 1, 1, 1 } },
4295 { ISD::UMAX, MVT::v32i16, { 1, 1, 1, 1 } },
4296 { ISD::UMAX, MVT::v64i8, { 1, 1, 1, 1 } },
4297 { ISD::UMIN, MVT::v32i16, { 1, 1, 1, 1 } },
4298 { ISD::UMIN, MVT::v64i8, { 1, 1, 1, 1 } },
4299 { ISD::USUBSAT, MVT::v32i16, { 1, 1, 1, 1 } },
4300 { ISD::USUBSAT, MVT::v64i8, { 1, 1, 1, 1 } },
4301 };
4302 static const CostKindTblEntry AVX512CostTbl[] = {
4303 { ISD::ABS, MVT::v8i64, { 1, 1, 1, 1 } },
4304 { ISD::ABS, MVT::v4i64, { 1, 1, 1, 1 } },
4305 { ISD::ABS, MVT::v2i64, { 1, 1, 1, 1 } },
4306 { ISD::ABS, MVT::v16i32, { 1, 1, 1, 1 } },
4307 { ISD::ABS, MVT::v8i32, { 1, 1, 1, 1 } },
4308 { ISD::ABS, MVT::v32i16, { 2, 7, 4, 4 } },
4309 { ISD::ABS, MVT::v16i16, { 1, 1, 1, 1 } },
4310 { ISD::ABS, MVT::v64i8, { 2, 7, 4, 4 } },
4311 { ISD::ABS, MVT::v32i8, { 1, 1, 1, 1 } },
4312 { ISD::BITREVERSE, MVT::v8i64, { 9, 13, 20, 20 } },
4313 { ISD::BITREVERSE, MVT::v16i32, { 9, 13, 20, 20 } },
4314 { ISD::BITREVERSE, MVT::v32i16, { 9, 13, 20, 20 } },
4315 { ISD::BITREVERSE, MVT::v64i8, { 6, 11, 17, 17 } },
4316 { ISD::BSWAP, MVT::v8i64, { 4, 7, 5, 5 } },
4317 { ISD::BSWAP, MVT::v16i32, { 4, 7, 5, 5 } },
4318 { ISD::BSWAP, MVT::v32i16, { 4, 7, 5, 5 } },
4319 { ISD::CTLZ, MVT::v8i64, { 10, 28, 32, 32 } },
4320 { ISD::CTLZ, MVT::v16i32, { 12, 30, 38, 38 } },
4321 { ISD::CTLZ, MVT::v32i16, { 8, 15, 29, 29 } },
4322 { ISD::CTLZ, MVT::v64i8, { 6, 11, 19, 19 } },
4323 { ISD::CTPOP, MVT::v8i64, { 16, 16, 19, 19 } },
4324 { ISD::CTPOP, MVT::v16i32, { 24, 19, 27, 27 } },
4325 { ISD::CTPOP, MVT::v32i16, { 18, 15, 22, 22 } },
4326 { ISD::CTPOP, MVT::v64i8, { 12, 11, 16, 16 } },
4327 { ISD::CTTZ, MVT::v8i64, { 2, 8, 6, 7 } },
4328 { ISD::CTTZ, MVT::v16i32, { 2, 8, 6, 7 } },
4329 { ISD::CTTZ, MVT::v32i16, { 7, 17, 27, 27 } },
4330 { ISD::CTTZ, MVT::v64i8, { 6, 13, 21, 21 } },
4331 { ISD::MULHS, MVT::v16i32, { 3, 10, 6, 7 } },
4332 { ISD::MULHS, MVT::v8i32, { 3, 9, 6, 6 } },
4333 { ISD::MULHS, MVT::v32i16, { 3, 7, 5, 5 } },
4334 { ISD::MULHS, MVT::v16i16, { 1, 5, 1, 1 } },
4335 { ISD::MULHU, MVT::v16i32, { 3, 10, 6, 7 } },
4336 { ISD::MULHU, MVT::v8i32, { 3, 9, 6, 6 } },
4337 { ISD::MULHU, MVT::v32i16, { 3, 7, 5, 5 } },
4338 { ISD::MULHU, MVT::v16i16, { 1, 5, 1, 1 } },
4339 { ISD::ROTL, MVT::v8i64, { 1, 1, 1, 1 } },
4340 { ISD::ROTL, MVT::v4i64, { 1, 1, 1, 1 } },
4341 { ISD::ROTL, MVT::v2i64, { 1, 1, 1, 1 } },
4342 { ISD::ROTL, MVT::v16i32, { 1, 1, 1, 1 } },
4343 { ISD::ROTL, MVT::v8i32, { 1, 1, 1, 1 } },
4344 { ISD::ROTL, MVT::v4i32, { 1, 1, 1, 1 } },
4345 { ISD::ROTR, MVT::v8i64, { 1, 1, 1, 1 } },
4346 { ISD::ROTR, MVT::v4i64, { 1, 1, 1, 1 } },
4347 { ISD::ROTR, MVT::v2i64, { 1, 1, 1, 1 } },
4348 { ISD::ROTR, MVT::v16i32, { 1, 1, 1, 1 } },
4349 { ISD::ROTR, MVT::v8i32, { 1, 1, 1, 1 } },
4350 { ISD::ROTR, MVT::v4i32, { 1, 1, 1, 1 } },
4351 { X86ISD::VROTLI, MVT::v8i64, { 1, 1, 1, 1 } },
4352 { X86ISD::VROTLI, MVT::v4i64, { 1, 1, 1, 1 } },
4353 { X86ISD::VROTLI, MVT::v2i64, { 1, 1, 1, 1 } },
4354 { X86ISD::VROTLI, MVT::v16i32, { 1, 1, 1, 1 } },
4355 { X86ISD::VROTLI, MVT::v8i32, { 1, 1, 1, 1 } },
4356 { X86ISD::VROTLI, MVT::v4i32, { 1, 1, 1, 1 } },
4357 { ISD::SADDSAT, MVT::v2i64, { 3, 3, 8, 9 } },
4358 { ISD::SADDSAT, MVT::v4i64, { 2, 2, 6, 7 } },
4359 { ISD::SADDSAT, MVT::v8i64, { 3, 3, 6, 7 } },
4360 { ISD::SADDSAT, MVT::v4i32, { 2, 2, 6, 7 } },
4361 { ISD::SADDSAT, MVT::v8i32, { 2, 2, 6, 7 } },
4362 { ISD::SADDSAT, MVT::v16i32, { 3, 3, 6, 7 } },
4363 { ISD::SADDSAT, MVT::v32i16, { 2, 2, 2, 2 } },
4364 { ISD::SADDSAT, MVT::v64i8, { 2, 2, 2, 2 } },
4365 { ISD::SMAX, MVT::v8i64, { 1, 3, 1, 1 } },
4366 { ISD::SMAX, MVT::v16i32, { 1, 1, 1, 1 } },
4367 { ISD::SMAX, MVT::v32i16, { 3, 7, 5, 5 } },
4368 { ISD::SMAX, MVT::v64i8, { 3, 7, 5, 5 } },
4369 { ISD::SMAX, MVT::v4i64, { 1, 3, 1, 1 } },
4370 { ISD::SMAX, MVT::v2i64, { 1, 3, 1, 1 } },
4371 { ISD::SMIN, MVT::v8i64, { 1, 3, 1, 1 } },
4372 { ISD::SMIN, MVT::v16i32, { 1, 1, 1, 1 } },
4373 { ISD::SMIN, MVT::v32i16, { 3, 7, 5, 5 } },
4374 { ISD::SMIN, MVT::v64i8, { 3, 7, 5, 5 } },
4375 { ISD::SMIN, MVT::v4i64, { 1, 3, 1, 1 } },
4376 { ISD::SMIN, MVT::v2i64, { 1, 3, 1, 1 } },
4377 { ISD::SMULO, MVT::v8i64, { 44, 44, 81, 93 } },
4378 { ISD::SMULO, MVT::v16i32, { 5, 12, 9, 11 } },
4379 { ISD::SMULO, MVT::v32i16, { 6, 12, 17, 17 } },
4380 { ISD::SMULO, MVT::v64i8, { 22, 28, 42, 42 } },
4381 { ISD::SSUBSAT, MVT::v2i64, { 2, 13, 9, 10 } },
4382 { ISD::SSUBSAT, MVT::v4i64, { 2, 15, 7, 8 } },
4383 { ISD::SSUBSAT, MVT::v8i64, { 2, 14, 7, 8 } },
4384 { ISD::SSUBSAT, MVT::v4i32, { 2, 14, 7, 8 } },
4385 { ISD::SSUBSAT, MVT::v8i32, { 2, 15, 7, 8 } },
4386 { ISD::SSUBSAT, MVT::v16i32, { 2, 14, 7, 8 } },
4387 { ISD::SSUBSAT, MVT::v32i16, { 2, 2, 2, 2 } },
4388 { ISD::SSUBSAT, MVT::v64i8, { 2, 2, 2, 2 } },
4389 { ISD::UMAX, MVT::v8i64, { 1, 3, 1, 1 } },
4390 { ISD::UMAX, MVT::v16i32, { 1, 1, 1, 1 } },
4391 { ISD::UMAX, MVT::v32i16, { 3, 7, 5, 5 } },
4392 { ISD::UMAX, MVT::v64i8, { 3, 7, 5, 5 } },
4393 { ISD::UMAX, MVT::v4i64, { 1, 3, 1, 1 } },
4394 { ISD::UMAX, MVT::v2i64, { 1, 3, 1, 1 } },
4395 { ISD::UMIN, MVT::v8i64, { 1, 3, 1, 1 } },
4396 { ISD::UMIN, MVT::v16i32, { 1, 1, 1, 1 } },
4397 { ISD::UMIN, MVT::v32i16, { 3, 7, 5, 5 } },
4398 { ISD::UMIN, MVT::v64i8, { 3, 7, 5, 5 } },
4399 { ISD::UMIN, MVT::v4i64, { 1, 3, 1, 1 } },
4400 { ISD::UMIN, MVT::v2i64, { 1, 3, 1, 1 } },
4401 { ISD::UMULO, MVT::v8i64, { 52, 52, 95, 104} },
4402 { ISD::UMULO, MVT::v16i32, { 5, 12, 8, 10 } },
4403 { ISD::UMULO, MVT::v32i16, { 5, 13, 16, 16 } },
4404 { ISD::UMULO, MVT::v64i8, { 18, 24, 30, 30 } },
4405 { ISD::UADDSAT, MVT::v2i64, { 1, 4, 4, 4 } },
4406 { ISD::UADDSAT, MVT::v4i64, { 1, 4, 4, 4 } },
4407 { ISD::UADDSAT, MVT::v8i64, { 1, 4, 4, 4 } },
4408 { ISD::UADDSAT, MVT::v4i32, { 1, 2, 4, 4 } },
4409 { ISD::UADDSAT, MVT::v8i32, { 1, 2, 4, 4 } },
4410 { ISD::UADDSAT, MVT::v16i32, { 2, 2, 4, 4 } },
4411 { ISD::UADDSAT, MVT::v32i16, { 2, 2, 2, 2 } },
4412 { ISD::UADDSAT, MVT::v64i8, { 2, 2, 2, 2 } },
4413 { ISD::USUBSAT, MVT::v2i64, { 1, 4, 2, 2 } },
4414 { ISD::USUBSAT, MVT::v4i64, { 1, 4, 2, 2 } },
4415 { ISD::USUBSAT, MVT::v8i64, { 1, 4, 2, 2 } },
4416 { ISD::USUBSAT, MVT::v8i32, { 1, 2, 2, 2 } },
4417 { ISD::USUBSAT, MVT::v16i32, { 1, 2, 2, 2 } },
4418 { ISD::USUBSAT, MVT::v32i16, { 2, 2, 2, 2 } },
4419 { ISD::USUBSAT, MVT::v64i8, { 2, 2, 2, 2 } },
4420 { ISD::FMAXNUM, MVT::f32, { 2, 2, 3, 3 } },
4421 { ISD::FMAXNUM, MVT::v4f32, { 1, 1, 3, 3 } },
4422 { ISD::FMAXNUM, MVT::v8f32, { 2, 2, 3, 3 } },
4423 { ISD::FMAXNUM, MVT::v16f32, { 4, 4, 3, 3 } },
4424 { ISD::FMAXNUM, MVT::f64, { 2, 2, 3, 3 } },
4425 { ISD::FMAXNUM, MVT::v2f64, { 1, 1, 3, 3 } },
4426 { ISD::FMAXNUM, MVT::v4f64, { 2, 2, 3, 3 } },
4427 { ISD::FMAXNUM, MVT::v8f64, { 3, 3, 3, 3 } },
4428 { ISD::FSQRT, MVT::f32, { 3, 12, 1, 1 } }, // Skylake from http://www.agner.org/
4429 { ISD::FSQRT, MVT::v4f32, { 3, 12, 1, 1 } }, // Skylake from http://www.agner.org/
4430 { ISD::FSQRT, MVT::v8f32, { 6, 12, 1, 1 } }, // Skylake from http://www.agner.org/
4431 { ISD::FSQRT, MVT::v16f32, { 12, 20, 1, 3 } }, // Skylake from http://www.agner.org/
4432 { ISD::FSQRT, MVT::f64, { 6, 18, 1, 1 } }, // Skylake from http://www.agner.org/
4433 { ISD::FSQRT, MVT::v2f64, { 6, 18, 1, 1 } }, // Skylake from http://www.agner.org/
4434 { ISD::FSQRT, MVT::v4f64, { 12, 18, 1, 1 } }, // Skylake from http://www.agner.org/
4435 { ISD::FSQRT, MVT::v8f64, { 24, 32, 1, 3 } }, // Skylake from http://www.agner.org/
4436 };
4437 static const CostKindTblEntry XOPCostTbl[] = {
4438 { ISD::BITREVERSE, MVT::v4i64, { 3, 6, 5, 6 } },
4439 { ISD::BITREVERSE, MVT::v8i32, { 3, 6, 5, 6 } },
4440 { ISD::BITREVERSE, MVT::v16i16, { 3, 6, 5, 6 } },
4441 { ISD::BITREVERSE, MVT::v32i8, { 3, 6, 5, 6 } },
4442 { ISD::BITREVERSE, MVT::v2i64, { 2, 7, 1, 1 } },
4443 { ISD::BITREVERSE, MVT::v4i32, { 2, 7, 1, 1 } },
4444 { ISD::BITREVERSE, MVT::v8i16, { 2, 7, 1, 1 } },
4445 { ISD::BITREVERSE, MVT::v16i8, { 2, 7, 1, 1 } },
4446 { ISD::BITREVERSE, MVT::i64, { 2, 2, 3, 4 } },
4447 { ISD::BITREVERSE, MVT::i32, { 2, 2, 3, 4 } },
4448 { ISD::BITREVERSE, MVT::i16, { 2, 2, 3, 4 } },
4449 { ISD::BITREVERSE, MVT::i8, { 2, 2, 3, 4 } },
4450 // XOP: ROTL = VPROT(X,Y), ROTR = VPROT(X,SUB(0,Y))
4451 { ISD::ROTL, MVT::v4i64, { 4, 7, 5, 6 } },
4452 { ISD::ROTL, MVT::v8i32, { 4, 7, 5, 6 } },
4453 { ISD::ROTL, MVT::v16i16, { 4, 7, 5, 6 } },
4454 { ISD::ROTL, MVT::v32i8, { 4, 7, 5, 6 } },
4455 { ISD::ROTL, MVT::v2i64, { 1, 3, 1, 1 } },
4456 { ISD::ROTL, MVT::v4i32, { 1, 3, 1, 1 } },
4457 { ISD::ROTL, MVT::v8i16, { 1, 3, 1, 1 } },
4458 { ISD::ROTL, MVT::v16i8, { 1, 3, 1, 1 } },
4459 { ISD::ROTR, MVT::v4i64, { 4, 7, 8, 9 } },
4460 { ISD::ROTR, MVT::v8i32, { 4, 7, 8, 9 } },
4461 { ISD::ROTR, MVT::v16i16, { 4, 7, 8, 9 } },
4462 { ISD::ROTR, MVT::v32i8, { 4, 7, 8, 9 } },
4463 { ISD::ROTR, MVT::v2i64, { 1, 3, 3, 3 } },
4464 { ISD::ROTR, MVT::v4i32, { 1, 3, 3, 3 } },
4465 { ISD::ROTR, MVT::v8i16, { 1, 3, 3, 3 } },
4466 { ISD::ROTR, MVT::v16i8, { 1, 3, 3, 3 } },
4467 { X86ISD::VROTLI, MVT::v4i64, { 4, 7, 5, 6 } },
4468 { X86ISD::VROTLI, MVT::v8i32, { 4, 7, 5, 6 } },
4469 { X86ISD::VROTLI, MVT::v16i16, { 4, 7, 5, 6 } },
4470 { X86ISD::VROTLI, MVT::v32i8, { 4, 7, 5, 6 } },
4471 { X86ISD::VROTLI, MVT::v2i64, { 1, 3, 1, 1 } },
4472 { X86ISD::VROTLI, MVT::v4i32, { 1, 3, 1, 1 } },
4473 { X86ISD::VROTLI, MVT::v8i16, { 1, 3, 1, 1 } },
4474 { X86ISD::VROTLI, MVT::v16i8, { 1, 3, 1, 1 } },
4475 };
4476 static const CostKindTblEntry AVX2CostTbl[] = {
4477 { ISD::ABS, MVT::v2i64, { 2, 4, 3, 5 } }, // VBLENDVPD(X,VPSUBQ(0,X),X)
4478 { ISD::ABS, MVT::v4i64, { 2, 4, 3, 5 } }, // VBLENDVPD(X,VPSUBQ(0,X),X)
4479 { ISD::ABS, MVT::v4i32, { 1, 1, 1, 1 } },
4480 { ISD::ABS, MVT::v8i32, { 1, 1, 1, 2 } },
4481 { ISD::ABS, MVT::v8i16, { 1, 1, 1, 1 } },
4482 { ISD::ABS, MVT::v16i16, { 1, 1, 1, 2 } },
4483 { ISD::ABS, MVT::v16i8, { 1, 1, 1, 1 } },
4484 { ISD::ABS, MVT::v32i8, { 1, 1, 1, 2 } },
4485 { ISD::BITREVERSE, MVT::v2i64, { 3, 11, 10, 11 } },
4486 { ISD::BITREVERSE, MVT::v4i64, { 5, 11, 10, 17 } },
4487 { ISD::BITREVERSE, MVT::v4i32, { 3, 11, 10, 11 } },
4488 { ISD::BITREVERSE, MVT::v8i32, { 5, 11, 10, 17 } },
4489 { ISD::BITREVERSE, MVT::v8i16, { 3, 11, 10, 11 } },
4490 { ISD::BITREVERSE, MVT::v16i16, { 5, 11, 10, 17 } },
4491 { ISD::BITREVERSE, MVT::v16i8, { 3, 6, 9, 9 } },
4492 { ISD::BITREVERSE, MVT::v32i8, { 4, 5, 9, 15 } },
4493 { ISD::BSWAP, MVT::v2i64, { 1, 2, 1, 2 } },
4494 { ISD::BSWAP, MVT::v4i64, { 1, 3, 1, 2 } },
4495 { ISD::BSWAP, MVT::v4i32, { 1, 2, 1, 2 } },
4496 { ISD::BSWAP, MVT::v8i32, { 1, 3, 1, 2 } },
4497 { ISD::BSWAP, MVT::v8i16, { 1, 2, 1, 2 } },
4498 { ISD::BSWAP, MVT::v16i16, { 1, 3, 1, 2 } },
4499 { ISD::CTLZ, MVT::v2i64, { 7, 18, 24, 25 } },
4500 { ISD::CTLZ, MVT::v4i64, { 14, 18, 24, 44 } },
4501 { ISD::CTLZ, MVT::v4i32, { 5, 16, 19, 20 } },
4502 { ISD::CTLZ, MVT::v8i32, { 10, 16, 19, 34 } },
4503 { ISD::CTLZ, MVT::v8i16, { 4, 13, 14, 15 } },
4504 { ISD::CTLZ, MVT::v16i16, { 6, 14, 14, 24 } },
4505 { ISD::CTLZ, MVT::v16i8, { 3, 12, 9, 10 } },
4506 { ISD::CTLZ, MVT::v32i8, { 4, 12, 9, 14 } },
4507 { ISD::CTPOP, MVT::v2i64, { 3, 9, 10, 10 } },
4508 { ISD::CTPOP, MVT::v4i64, { 4, 9, 10, 14 } },
4509 { ISD::CTPOP, MVT::v4i32, { 7, 12, 14, 14 } },
4510 { ISD::CTPOP, MVT::v8i32, { 7, 12, 14, 18 } },
4511 { ISD::CTPOP, MVT::v8i16, { 3, 7, 11, 11 } },
4512 { ISD::CTPOP, MVT::v16i16, { 6, 8, 11, 18 } },
4513 { ISD::CTPOP, MVT::v16i8, { 2, 5, 8, 8 } },
4514 { ISD::CTPOP, MVT::v32i8, { 3, 5, 8, 12 } },
4515 { ISD::CTTZ, MVT::v2i64, { 4, 11, 13, 13 } },
4516 { ISD::CTTZ, MVT::v4i64, { 5, 11, 13, 20 } },
4517 { ISD::CTTZ, MVT::v4i32, { 7, 14, 17, 17 } },
4518 { ISD::CTTZ, MVT::v8i32, { 7, 15, 17, 24 } },
4519 { ISD::CTTZ, MVT::v8i16, { 4, 9, 14, 14 } },
4520 { ISD::CTTZ, MVT::v16i16, { 6, 9, 14, 24 } },
4521 { ISD::CTTZ, MVT::v16i8, { 3, 7, 11, 11 } },
4522 { ISD::CTTZ, MVT::v32i8, { 5, 7, 11, 18 } },
4523 { ISD::MULHS, MVT::v8i32, { 4, 9, 6, 12 } },
4524 { ISD::MULHS, MVT::v16i16, { 2, 5, 1, 2 } },
4525 { ISD::MULHU, MVT::v8i32, { 4, 9, 6, 12 } },
4526 { ISD::MULHU, MVT::v16i16, { 2, 5, 1, 2 } },
4527 { ISD::SADDSAT, MVT::v2i64, { 4, 13, 8, 11 } },
4528 { ISD::SADDSAT, MVT::v4i64, { 3, 10, 8, 12 } },
4529 { ISD::SADDSAT, MVT::v4i32, { 2, 6, 7, 9 } },
4530 { ISD::SADDSAT, MVT::v8i32, { 4, 6, 7, 13 } },
4531 { ISD::SADDSAT, MVT::v16i16, { 1, 1, 1, 2 } },
4532 { ISD::SADDSAT, MVT::v32i8, { 1, 1, 1, 2 } },
4533 { ISD::SMAX, MVT::v2i64, { 2, 7, 2, 3 } },
4534 { ISD::SMAX, MVT::v4i64, { 2, 7, 2, 3 } },
4535 { ISD::SMAX, MVT::v8i32, { 1, 1, 1, 2 } },
4536 { ISD::SMAX, MVT::v16i16, { 1, 1, 1, 2 } },
4537 { ISD::SMAX, MVT::v32i8, { 1, 1, 1, 2 } },
4538 { ISD::SMIN, MVT::v2i64, { 2, 7, 2, 3 } },
4539 { ISD::SMIN, MVT::v4i64, { 2, 7, 2, 3 } },
4540 { ISD::SMIN, MVT::v8i32, { 1, 1, 1, 2 } },
4541 { ISD::SMIN, MVT::v16i16, { 1, 1, 1, 2 } },
4542 { ISD::SMIN, MVT::v32i8, { 1, 1, 1, 2 } },
4543 { ISD::SMULO, MVT::v4i64, { 20, 20, 33, 37 } },
4544 { ISD::SMULO, MVT::v2i64, { 8, 8, 13, 15 } },
4545 { ISD::SMULO, MVT::v8i32, { 8, 20, 13, 24 } },
4546 { ISD::SMULO, MVT::v4i32, { 5, 15, 11, 12 } },
4547 { ISD::SMULO, MVT::v16i16, { 4, 14, 8, 14 } },
4548 { ISD::SMULO, MVT::v8i16, { 3, 9, 6, 6 } },
4549 { ISD::SMULO, MVT::v32i8, { 9, 15, 18, 35 } },
4550 { ISD::SMULO, MVT::v16i8, { 6, 22, 14, 21 } },
4551 { ISD::SSUBSAT, MVT::v2i64, { 4, 13, 9, 13 } },
4552 { ISD::SSUBSAT, MVT::v4i64, { 4, 15, 9, 13 } },
4553 { ISD::SSUBSAT, MVT::v4i32, { 3, 14, 9, 11 } },
4554 { ISD::SSUBSAT, MVT::v8i32, { 4, 15, 9, 16 } },
4555 { ISD::SSUBSAT, MVT::v16i16, { 1, 1, 1, 2 } },
4556 { ISD::SSUBSAT, MVT::v32i8, { 1, 1, 1, 2 } },
4557 { ISD::UADDSAT, MVT::v2i64, { 2, 8, 6, 6 } },
4558 { ISD::UADDSAT, MVT::v4i64, { 3, 8, 6, 10 } },
4559 { ISD::UADDSAT, MVT::v8i32, { 2, 2, 4, 8 } },
4560 { ISD::UADDSAT, MVT::v16i16, { 1, 1, 1, 2 } },
4561 { ISD::UADDSAT, MVT::v32i8, { 1, 1, 1, 2 } },
4562 { ISD::UMAX, MVT::v2i64, { 2, 8, 5, 6 } },
4563 { ISD::UMAX, MVT::v4i64, { 2, 8, 5, 8 } },
4564 { ISD::UMAX, MVT::v8i32, { 1, 1, 1, 2 } },
4565 { ISD::UMAX, MVT::v16i16, { 1, 1, 1, 2 } },
4566 { ISD::UMAX, MVT::v32i8, { 1, 1, 1, 2 } },
4567 { ISD::UMIN, MVT::v2i64, { 2, 8, 5, 6 } },
4568 { ISD::UMIN, MVT::v4i64, { 2, 8, 5, 8 } },
4569 { ISD::UMIN, MVT::v8i32, { 1, 1, 1, 2 } },
4570 { ISD::UMIN, MVT::v16i16, { 1, 1, 1, 2 } },
4571 { ISD::UMIN, MVT::v32i8, { 1, 1, 1, 2 } },
4572 { ISD::UMULO, MVT::v4i64, { 24, 24, 39, 43 } },
4573 { ISD::UMULO, MVT::v2i64, { 10, 10, 15, 19 } },
4574 { ISD::UMULO, MVT::v8i32, { 8, 11, 13, 23 } },
4575 { ISD::UMULO, MVT::v4i32, { 5, 12, 11, 12 } },
4576 { ISD::UMULO, MVT::v16i16, { 4, 6, 8, 13 } },
4577 { ISD::UMULO, MVT::v8i16, { 2, 8, 6, 6 } },
4578 { ISD::UMULO, MVT::v32i8, { 9, 13, 17, 33 } },
4579 { ISD::UMULO, MVT::v16i8, { 6, 19, 13, 20 } },
4580 { ISD::USUBSAT, MVT::v2i64, { 2, 7, 6, 6 } },
4581 { ISD::USUBSAT, MVT::v4i64, { 3, 7, 6, 10 } },
4582 { ISD::USUBSAT, MVT::v8i32, { 2, 2, 2, 4 } },
4583 { ISD::USUBSAT, MVT::v16i16, { 1, 1, 1, 2 } },
4584 { ISD::USUBSAT, MVT::v32i8, { 1, 1, 1, 2 } },
4585 { ISD::FMAXNUM, MVT::f32, { 2, 7, 3, 5 } }, // MAXSS + CMPUNORDSS + BLENDVPS
4586 { ISD::FMAXNUM, MVT::v4f32, { 2, 7, 3, 5 } }, // MAXPS + CMPUNORDPS + BLENDVPS
4587 { ISD::FMAXNUM, MVT::v8f32, { 3, 7, 3, 6 } }, // MAXPS + CMPUNORDPS + BLENDVPS
4588 { ISD::FMAXNUM, MVT::f64, { 2, 7, 3, 5 } }, // MAXSD + CMPUNORDSD + BLENDVPD
4589 { ISD::FMAXNUM, MVT::v2f64, { 2, 7, 3, 5 } }, // MAXPD + CMPUNORDPD + BLENDVPD
4590 { ISD::FMAXNUM, MVT::v4f64, { 3, 7, 3, 6 } }, // MAXPD + CMPUNORDPD + BLENDVPD
4591 { ISD::FSQRT, MVT::f32, { 7, 15, 1, 1 } }, // vsqrtss
4592 { ISD::FSQRT, MVT::v4f32, { 7, 15, 1, 1 } }, // vsqrtps
4593 { ISD::FSQRT, MVT::v8f32, { 14, 21, 1, 3 } }, // vsqrtps
4594 { ISD::FSQRT, MVT::f64, { 14, 21, 1, 1 } }, // vsqrtsd
4595 { ISD::FSQRT, MVT::v2f64, { 14, 21, 1, 1 } }, // vsqrtpd
4596 { ISD::FSQRT, MVT::v4f64, { 28, 35, 1, 3 } }, // vsqrtpd
4597 };
4598 static const CostKindTblEntry AVX1CostTbl[] = {
4599 { ISD::ABS, MVT::v4i64, { 6, 8, 6, 12 } }, // VBLENDVPD(X,VPSUBQ(0,X),X)
4600 { ISD::ABS, MVT::v8i32, { 3, 6, 4, 5 } },
4601 { ISD::ABS, MVT::v16i16, { 3, 6, 4, 5 } },
4602 { ISD::ABS, MVT::v32i8, { 3, 6, 4, 5 } },
4603 { ISD::BITREVERSE, MVT::v4i64, { 17, 20, 20, 33 } }, // 2 x 128-bit Op + extract/insert
4604 { ISD::BITREVERSE, MVT::v2i64, { 8, 13, 10, 16 } },
4605 { ISD::BITREVERSE, MVT::v8i32, { 17, 20, 20, 33 } }, // 2 x 128-bit Op + extract/insert
4606 { ISD::BITREVERSE, MVT::v4i32, { 8, 13, 10, 16 } },
4607 { ISD::BITREVERSE, MVT::v16i16, { 17, 20, 20, 33 } }, // 2 x 128-bit Op + extract/insert
4608 { ISD::BITREVERSE, MVT::v8i16, { 8, 13, 10, 16 } },
4609 { ISD::BITREVERSE, MVT::v32i8, { 13, 15, 17, 26 } }, // 2 x 128-bit Op + extract/insert
4610 { ISD::BITREVERSE, MVT::v16i8, { 7, 7, 9, 13 } },
4611 { ISD::BSWAP, MVT::v4i64, { 5, 6, 5, 10 } },
4612 { ISD::BSWAP, MVT::v2i64, { 2, 2, 1, 3 } },
4613 { ISD::BSWAP, MVT::v8i32, { 5, 6, 5, 10 } },
4614 { ISD::BSWAP, MVT::v4i32, { 2, 2, 1, 3 } },
4615 { ISD::BSWAP, MVT::v16i16, { 5, 6, 5, 10 } },
4616 { ISD::BSWAP, MVT::v8i16, { 2, 2, 1, 3 } },
4617 { ISD::CTLZ, MVT::v4i64, { 29, 33, 49, 58 } }, // 2 x 128-bit Op + extract/insert
4618 { ISD::CTLZ, MVT::v2i64, { 14, 24, 24, 28 } },
4619 { ISD::CTLZ, MVT::v8i32, { 24, 28, 39, 48 } }, // 2 x 128-bit Op + extract/insert
4620 { ISD::CTLZ, MVT::v4i32, { 12, 20, 19, 23 } },
4621 { ISD::CTLZ, MVT::v16i16, { 19, 22, 29, 38 } }, // 2 x 128-bit Op + extract/insert
4622 { ISD::CTLZ, MVT::v8i16, { 9, 16, 14, 18 } },
4623 { ISD::CTLZ, MVT::v32i8, { 14, 15, 19, 28 } }, // 2 x 128-bit Op + extract/insert
4624 { ISD::CTLZ, MVT::v16i8, { 7, 12, 9, 13 } },
4625 { ISD::CTPOP, MVT::v4i64, { 14, 18, 19, 28 } }, // 2 x 128-bit Op + extract/insert
4626 { ISD::CTPOP, MVT::v2i64, { 7, 14, 10, 14 } },
4627 { ISD::CTPOP, MVT::v8i32, { 18, 24, 27, 36 } }, // 2 x 128-bit Op + extract/insert
4628 { ISD::CTPOP, MVT::v4i32, { 9, 20, 14, 18 } },
4629 { ISD::CTPOP, MVT::v16i16, { 16, 21, 22, 31 } }, // 2 x 128-bit Op + extract/insert
4630 { ISD::CTPOP, MVT::v8i16, { 8, 18, 11, 15 } },
4631 { ISD::CTPOP, MVT::v32i8, { 13, 15, 16, 25 } }, // 2 x 128-bit Op + extract/insert
4632 { ISD::CTPOP, MVT::v16i8, { 6, 12, 8, 12 } },
4633 { ISD::CTTZ, MVT::v4i64, { 17, 22, 24, 33 } }, // 2 x 128-bit Op + extract/insert
4634 { ISD::CTTZ, MVT::v2i64, { 9, 19, 13, 17 } },
4635 { ISD::CTTZ, MVT::v8i32, { 21, 27, 32, 41 } }, // 2 x 128-bit Op + extract/insert
4636 { ISD::CTTZ, MVT::v4i32, { 11, 24, 17, 21 } },
4637 { ISD::CTTZ, MVT::v16i16, { 18, 24, 27, 36 } }, // 2 x 128-bit Op + extract/insert
4638 { ISD::CTTZ, MVT::v8i16, { 9, 21, 14, 18 } },
4639 { ISD::CTTZ, MVT::v32i8, { 15, 18, 21, 30 } }, // 2 x 128-bit Op + extract/insert
4640 { ISD::CTTZ, MVT::v16i8, { 8, 16, 11, 15 } },
4641 { ISD::MULHS, MVT::v8i32, { 9, 11, 14, 18 } },
4642 { ISD::MULHS, MVT::v16i16, { 3, 7, 5, 6 } },
4643 { ISD::MULHU, MVT::v8i32, { 9, 11, 14, 18 } },
4644 { ISD::MULHU, MVT::v16i16, { 3, 7, 5, 6 } },
4645 { ISD::SADDSAT, MVT::v2i64, { 6, 13, 8, 11 } },
4646 { ISD::SADDSAT, MVT::v4i64, { 13, 20, 15, 25 } }, // 2 x 128-bit Op + extract/insert
4647 { ISD::SADDSAT, MVT::v8i32, { 12, 18, 14, 24 } }, // 2 x 128-bit Op + extract/insert
4648 { ISD::SADDSAT, MVT::v16i16, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4649 { ISD::SADDSAT, MVT::v32i8, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4650 { ISD::SMAX, MVT::v4i64, { 6, 9, 6, 12 } }, // 2 x 128-bit Op + extract/insert
4651 { ISD::SMAX, MVT::v2i64, { 3, 7, 2, 4 } },
4652 { ISD::SMAX, MVT::v8i32, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4653 { ISD::SMAX, MVT::v16i16, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4654 { ISD::SMAX, MVT::v32i8, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4655 { ISD::SMIN, MVT::v4i64, { 6, 9, 6, 12 } }, // 2 x 128-bit Op + extract/insert
4656 { ISD::SMIN, MVT::v2i64, { 3, 7, 2, 3 } },
4657 { ISD::SMIN, MVT::v8i32, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4658 { ISD::SMIN, MVT::v16i16, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4659 { ISD::SMIN, MVT::v32i8, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4660 { ISD::SMULO, MVT::v4i64, { 20, 20, 33, 37 } },
4661 { ISD::SMULO, MVT::v2i64, { 9, 9, 13, 17 } },
4662 { ISD::SMULO, MVT::v8i32, { 15, 20, 24, 29 } },
4663 { ISD::SMULO, MVT::v4i32, { 7, 15, 11, 13 } },
4664 { ISD::SMULO, MVT::v16i16, { 8, 14, 14, 15 } },
4665 { ISD::SMULO, MVT::v8i16, { 3, 9, 6, 6 } },
4666 { ISD::SMULO, MVT::v32i8, { 20, 20, 37, 39 } },
4667 { ISD::SMULO, MVT::v16i8, { 9, 22, 18, 21 } },
4668 { ISD::SSUBSAT, MVT::v2i64, { 7, 13, 9, 13 } },
4669 { ISD::SSUBSAT, MVT::v4i64, { 15, 21, 18, 29 } }, // 2 x 128-bit Op + extract/insert
4670 { ISD::SSUBSAT, MVT::v8i32, { 15, 19, 18, 29 } }, // 2 x 128-bit Op + extract/insert
4671 { ISD::SSUBSAT, MVT::v16i16, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4672 { ISD::SSUBSAT, MVT::v32i8, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4673 { ISD::UADDSAT, MVT::v2i64, { 3, 8, 6, 6 } },
4674 { ISD::UADDSAT, MVT::v4i64, { 8, 11, 14, 15 } }, // 2 x 128-bit Op + extract/insert
4675 { ISD::UADDSAT, MVT::v8i32, { 6, 6, 10, 11 } }, // 2 x 128-bit Op + extract/insert
4676 { ISD::UADDSAT, MVT::v16i16, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4677 { ISD::UADDSAT, MVT::v32i8, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4678 { ISD::UMAX, MVT::v4i64, { 9, 10, 11, 17 } }, // 2 x 128-bit Op + extract/insert
4679 { ISD::UMAX, MVT::v2i64, { 4, 8, 5, 7 } },
4680 { ISD::UMAX, MVT::v8i32, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4681 { ISD::UMAX, MVT::v16i16, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4682 { ISD::UMAX, MVT::v32i8, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4683 { ISD::UMIN, MVT::v4i64, { 9, 10, 11, 17 } }, // 2 x 128-bit Op + extract/insert
4684 { ISD::UMIN, MVT::v2i64, { 4, 8, 5, 7 } },
4685 { ISD::UMIN, MVT::v8i32, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4686 { ISD::UMIN, MVT::v16i16, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4687 { ISD::UMIN, MVT::v32i8, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4688 { ISD::UMULO, MVT::v4i64, { 24, 26, 39, 45 } },
4689 { ISD::UMULO, MVT::v2i64, { 10, 12, 15, 20 } },
4690 { ISD::UMULO, MVT::v8i32, { 14, 15, 23, 28 } },
4691 { ISD::UMULO, MVT::v4i32, { 7, 12, 11, 13 } },
4692 { ISD::UMULO, MVT::v16i16, { 7, 11, 13, 14 } },
4693 { ISD::UMULO, MVT::v8i16, { 3, 8, 6, 6 } },
4694 { ISD::UMULO, MVT::v32i8, { 19, 19, 35, 37 } },
4695 { ISD::UMULO, MVT::v16i8, { 9, 19, 17, 20 } },
4696 { ISD::USUBSAT, MVT::v2i64, { 3, 7, 6, 6 } },
4697 { ISD::USUBSAT, MVT::v4i64, { 8, 10, 14, 15 } }, // 2 x 128-bit Op + extract/insert
4698 { ISD::USUBSAT, MVT::v8i32, { 4, 4, 7, 8 } }, // 2 x 128-bit Op + extract/insert
4699 { ISD::USUBSAT, MVT::v8i32, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4700 { ISD::USUBSAT, MVT::v16i16, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4701 { ISD::USUBSAT, MVT::v32i8, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4702 { ISD::FMAXNUM, MVT::f32, { 3, 6, 3, 5 } }, // MAXSS + CMPUNORDSS + BLENDVPS
4703 { ISD::FMAXNUM, MVT::v4f32, { 3, 6, 3, 5 } }, // MAXPS + CMPUNORDPS + BLENDVPS
4704 { ISD::FMAXNUM, MVT::v8f32, { 5, 7, 3, 10 } }, // MAXPS + CMPUNORDPS + BLENDVPS
4705 { ISD::FMAXNUM, MVT::f64, { 3, 6, 3, 5 } }, // MAXSD + CMPUNORDSD + BLENDVPD
4706 { ISD::FMAXNUM, MVT::v2f64, { 3, 6, 3, 5 } }, // MAXPD + CMPUNORDPD + BLENDVPD
4707 { ISD::FMAXNUM, MVT::v4f64, { 5, 7, 3, 10 } }, // MAXPD + CMPUNORDPD + BLENDVPD
4708 { ISD::FSQRT, MVT::f32, { 21, 21, 1, 1 } }, // vsqrtss
4709 { ISD::FSQRT, MVT::v4f32, { 21, 21, 1, 1 } }, // vsqrtps
4710 { ISD::FSQRT, MVT::v8f32, { 42, 42, 1, 3 } }, // vsqrtps
4711 { ISD::FSQRT, MVT::f64, { 27, 27, 1, 1 } }, // vsqrtsd
4712 { ISD::FSQRT, MVT::v2f64, { 27, 27, 1, 1 } }, // vsqrtpd
4713 { ISD::FSQRT, MVT::v4f64, { 54, 54, 1, 3 } }, // vsqrtpd
4714 };
4715 static const CostKindTblEntry GFNICostTbl[] = {
4716 { ISD::BITREVERSE, MVT::i8, { 3, 3, 3, 4 } }, // gf2p8affineqb
4717 { ISD::BITREVERSE, MVT::i16, { 3, 3, 4, 6 } }, // gf2p8affineqb
4718 { ISD::BITREVERSE, MVT::i32, { 3, 3, 4, 5 } }, // gf2p8affineqb
4719 { ISD::BITREVERSE, MVT::i64, { 3, 3, 4, 6 } }, // gf2p8affineqb
4720 { ISD::BITREVERSE, MVT::v16i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
4721 { ISD::BITREVERSE, MVT::v32i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
4722 { ISD::BITREVERSE, MVT::v64i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
4723 { ISD::BITREVERSE, MVT::v8i16, { 1, 8, 2, 4 } }, // gf2p8affineqb
4724 { ISD::BITREVERSE, MVT::v16i16, { 1, 9, 2, 4 } }, // gf2p8affineqb
4725 { ISD::BITREVERSE, MVT::v32i16, { 1, 9, 2, 4 } }, // gf2p8affineqb
4726 { ISD::BITREVERSE, MVT::v4i32, { 1, 8, 2, 4 } }, // gf2p8affineqb
4727 { ISD::BITREVERSE, MVT::v8i32, { 1, 9, 2, 4 } }, // gf2p8affineqb
4728 { ISD::BITREVERSE, MVT::v16i32, { 1, 9, 2, 4 } }, // gf2p8affineqb
4729 { ISD::BITREVERSE, MVT::v2i64, { 1, 8, 2, 4 } }, // gf2p8affineqb
4730 { ISD::BITREVERSE, MVT::v4i64, { 1, 9, 2, 4 } }, // gf2p8affineqb
4731 { ISD::BITREVERSE, MVT::v8i64, { 1, 9, 2, 4 } }, // gf2p8affineqb
4732 { X86ISD::VROTLI, MVT::v16i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
4733 { X86ISD::VROTLI, MVT::v32i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
4734 { X86ISD::VROTLI, MVT::v64i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
4735 };
4736 static const CostKindTblEntry GLMCostTbl[] = {
4737 { ISD::FSQRT, MVT::f32, { 19, 20, 1, 1 } }, // sqrtss
4738 { ISD::FSQRT, MVT::v4f32, { 37, 41, 1, 5 } }, // sqrtps
4739 { ISD::FSQRT, MVT::f64, { 34, 35, 1, 1 } }, // sqrtsd
4740 { ISD::FSQRT, MVT::v2f64, { 67, 71, 1, 5 } }, // sqrtpd
4741 };
4742 static const CostKindTblEntry SLMCostTbl[] = {
4743 { ISD::BSWAP, MVT::v2i64, { 5, 5, 1, 5 } },
4744 { ISD::BSWAP, MVT::v4i32, { 5, 5, 1, 5 } },
4745 { ISD::BSWAP, MVT::v8i16, { 5, 5, 1, 5 } },
4746 { ISD::FSQRT, MVT::f32, { 20, 20, 1, 1 } }, // sqrtss
4747 { ISD::FSQRT, MVT::v4f32, { 40, 41, 1, 5 } }, // sqrtps
4748 { ISD::FSQRT, MVT::f64, { 35, 35, 1, 1 } }, // sqrtsd
4749 { ISD::FSQRT, MVT::v2f64, { 70, 71, 1, 5 } }, // sqrtpd
4750 };
4751 static const CostKindTblEntry SSE42CostTbl[] = {
4752 { ISD::FMAXNUM, MVT::f32, { 5, 5, 7, 7 } }, // MAXSS + CMPUNORDSS + BLENDVPS
4753 { ISD::FMAXNUM, MVT::v4f32, { 4, 4, 4, 5 } }, // MAXPS + CMPUNORDPS + BLENDVPS
4754 { ISD::FMAXNUM, MVT::f64, { 5, 5, 7, 7 } }, // MAXSD + CMPUNORDSD + BLENDVPD
4755 { ISD::FMAXNUM, MVT::v2f64, { 4, 4, 4, 5 } }, // MAXPD + CMPUNORDPD + BLENDVPD
4756 { ISD::FSQRT, MVT::f32, { 18, 18, 1, 1 } }, // Nehalem from http://www.agner.org/
4757 { ISD::FSQRT, MVT::v4f32, { 18, 18, 1, 1 } }, // Nehalem from http://www.agner.org/
4758 };
4759 static const CostKindTblEntry SSE41CostTbl[] = {
4760 { ISD::ABS, MVT::v2i64, { 3, 4, 3, 5 } }, // BLENDVPD(X,PSUBQ(0,X),X)
4761 { ISD::MULHS, MVT::v4i32, { 3, 9, 6, 7 } },
4762 { ISD::MULHU, MVT::v4i32, { 3, 9, 6, 7 } },
4763 { ISD::SADDSAT, MVT::v2i64, { 10, 14, 17, 21 } },
4764 { ISD::SADDSAT, MVT::v4i32, { 5, 11, 8, 10 } },
4765 { ISD::SSUBSAT, MVT::v2i64, { 12, 19, 25, 29 } },
4766 { ISD::SSUBSAT, MVT::v4i32, { 6, 14, 10, 12 } },
4767 { ISD::SMAX, MVT::v2i64, { 3, 7, 2, 3 } },
4768 { ISD::SMAX, MVT::v4i32, { 1, 1, 1, 1 } },
4769 { ISD::SMAX, MVT::v16i8, { 1, 1, 1, 1 } },
4770 { ISD::SMIN, MVT::v2i64, { 3, 7, 2, 3 } },
4771 { ISD::SMIN, MVT::v4i32, { 1, 1, 1, 1 } },
4772 { ISD::SMIN, MVT::v16i8, { 1, 1, 1, 1 } },
4773 { ISD::SMULO, MVT::v2i64, { 9, 11, 13, 17 } },
4774 { ISD::SMULO, MVT::v4i32, { 20, 24, 13, 19 } },
4775 { ISD::SMULO, MVT::v8i16, { 5, 9, 8, 8 } },
4776 { ISD::SMULO, MVT::v16i8, { 13, 22, 24, 25 } },
4777 { ISD::UADDSAT, MVT::v2i64, { 6, 13, 14, 14 } },
4778 { ISD::UADDSAT, MVT::v4i32, { 2, 2, 4, 4 } },
4779 { ISD::USUBSAT, MVT::v2i64, { 6, 10, 14, 14 } },
4780 { ISD::USUBSAT, MVT::v4i32, { 1, 2, 2, 2 } },
4781 { ISD::UMAX, MVT::v2i64, { 2, 11, 6, 7 } },
4782 { ISD::UMAX, MVT::v4i32, { 1, 1, 1, 1 } },
4783 { ISD::UMAX, MVT::v8i16, { 1, 1, 1, 1 } },
4784 { ISD::UMIN, MVT::v2i64, { 2, 11, 6, 7 } },
4785 { ISD::UMIN, MVT::v4i32, { 1, 1, 1, 1 } },
4786 { ISD::UMIN, MVT::v8i16, { 1, 1, 1, 1 } },
4787 { ISD::UMULO, MVT::v2i64, { 14, 20, 15, 20 } },
4788 { ISD::UMULO, MVT::v4i32, { 19, 22, 12, 18 } },
4789 { ISD::UMULO, MVT::v8i16, { 4, 9, 7, 7 } },
4790 { ISD::UMULO, MVT::v16i8, { 13, 19, 18, 20 } },
4791 };
4792 static const CostKindTblEntry SSSE3CostTbl[] = {
4793 { ISD::ABS, MVT::v4i32, { 1, 2, 1, 1 } },
4794 { ISD::ABS, MVT::v8i16, { 1, 2, 1, 1 } },
4795 { ISD::ABS, MVT::v16i8, { 1, 2, 1, 1 } },
4796 { ISD::BITREVERSE, MVT::v2i64, { 16, 20, 11, 21 } },
4797 { ISD::BITREVERSE, MVT::v4i32, { 16, 20, 11, 21 } },
4798 { ISD::BITREVERSE, MVT::v8i16, { 16, 20, 11, 21 } },
4799 { ISD::BITREVERSE, MVT::v16i8, { 11, 12, 10, 16 } },
4800 { ISD::BSWAP, MVT::v2i64, { 2, 3, 1, 5 } },
4801 { ISD::BSWAP, MVT::v4i32, { 2, 3, 1, 5 } },
4802 { ISD::BSWAP, MVT::v8i16, { 2, 3, 1, 5 } },
4803 { ISD::CTLZ, MVT::v2i64, { 18, 28, 28, 35 } },
4804 { ISD::CTLZ, MVT::v4i32, { 15, 20, 22, 28 } },
4805 { ISD::CTLZ, MVT::v8i16, { 13, 17, 16, 22 } },
4806 { ISD::CTLZ, MVT::v16i8, { 11, 15, 10, 16 } },
4807 { ISD::CTPOP, MVT::v2i64, { 13, 19, 12, 18 } },
4808 { ISD::CTPOP, MVT::v4i32, { 18, 24, 16, 22 } },
4809 { ISD::CTPOP, MVT::v8i16, { 13, 18, 14, 20 } },
4810 { ISD::CTPOP, MVT::v16i8, { 11, 12, 10, 16 } },
4811 { ISD::CTTZ, MVT::v2i64, { 13, 25, 15, 22 } },
4812 { ISD::CTTZ, MVT::v4i32, { 18, 26, 19, 25 } },
4813 { ISD::CTTZ, MVT::v8i16, { 13, 20, 17, 23 } },
4814 { ISD::CTTZ, MVT::v16i8, { 11, 16, 13, 19 } }
4815 };
4816 static const CostKindTblEntry SSE2CostTbl[] = {
4817 { ISD::ABS, MVT::v2i64, { 3, 6, 5, 5 } },
4818 { ISD::ABS, MVT::v4i32, { 1, 4, 4, 4 } },
4819 { ISD::ABS, MVT::v8i16, { 1, 2, 3, 3 } },
4820 { ISD::ABS, MVT::v16i8, { 1, 2, 3, 3 } },
4821 { ISD::BITREVERSE, MVT::v2i64, { 16, 20, 32, 32 } },
4822 { ISD::BITREVERSE, MVT::v4i32, { 16, 20, 30, 30 } },
4823 { ISD::BITREVERSE, MVT::v8i16, { 16, 20, 25, 25 } },
4824 { ISD::BITREVERSE, MVT::v16i8, { 11, 12, 21, 21 } },
4825 { ISD::BSWAP, MVT::v2i64, { 5, 6, 11, 11 } },
4826 { ISD::BSWAP, MVT::v4i32, { 5, 5, 9, 9 } },
4827 { ISD::BSWAP, MVT::v8i16, { 5, 5, 4, 5 } },
4828 { ISD::CTLZ, MVT::v2i64, { 10, 45, 36, 38 } },
4829 { ISD::CTLZ, MVT::v4i32, { 10, 45, 38, 40 } },
4830 { ISD::CTLZ, MVT::v8i16, { 9, 38, 32, 34 } },
4831 { ISD::CTLZ, MVT::v16i8, { 8, 39, 29, 32 } },
4832 { ISD::CTPOP, MVT::v2i64, { 12, 26, 16, 18 } },
4833 { ISD::CTPOP, MVT::v4i32, { 15, 29, 21, 23 } },
4834 { ISD::CTPOP, MVT::v8i16, { 13, 25, 18, 20 } },
4835 { ISD::CTPOP, MVT::v16i8, { 10, 21, 14, 16 } },
4836 { ISD::CTTZ, MVT::v2i64, { 14, 28, 19, 21 } },
4837 { ISD::CTTZ, MVT::v4i32, { 18, 31, 24, 26 } },
4838 { ISD::CTTZ, MVT::v8i16, { 16, 27, 21, 23 } },
4839 { ISD::CTTZ, MVT::v16i8, { 13, 23, 17, 19 } },
4840 { ISD::MULHS, MVT::v4i32, { 5, 11, 15, 15 } },
4841 { ISD::MULHS, MVT::v8i16, { 1, 5, 1, 1 } },
4842 { ISD::MULHU, MVT::v4i32, { 3, 9, 7, 7 } },
4843 { ISD::MULHU, MVT::v8i16, { 1, 5, 1, 1 } },
4844 { ISD::SADDSAT, MVT::v2i64, { 12, 14, 24, 24 } },
4845 { ISD::SADDSAT, MVT::v4i32, { 6, 11, 11, 12 } },
4846 { ISD::SADDSAT, MVT::v8i16, { 1, 2, 1, 1 } },
4847 { ISD::SADDSAT, MVT::v16i8, { 1, 2, 1, 1 } },
4848 { ISD::SMAX, MVT::v2i64, { 4, 8, 15, 15 } },
4849 { ISD::SMAX, MVT::v4i32, { 2, 4, 5, 5 } },
4850 { ISD::SMAX, MVT::v8i16, { 1, 1, 1, 1 } },
4851 { ISD::SMAX, MVT::v16i8, { 2, 4, 5, 5 } },
4852 { ISD::SMIN, MVT::v2i64, { 4, 8, 15, 15 } },
4853 { ISD::SMIN, MVT::v4i32, { 2, 4, 5, 5 } },
4854 { ISD::SMIN, MVT::v8i16, { 1, 1, 1, 1 } },
4855 { ISD::SMIN, MVT::v16i8, { 2, 4, 5, 5 } },
4856 { ISD::SMULO, MVT::v2i64, { 30, 33, 13, 23 } },
4857 { ISD::SMULO, MVT::v4i32, { 20, 24, 23, 23 } },
4858 { ISD::SMULO, MVT::v8i16, { 5, 10, 8, 8 } },
4859 { ISD::SMULO, MVT::v16i8, { 13, 23, 24, 25 } },
4860 { ISD::SSUBSAT, MVT::v2i64, { 16, 19, 31, 31 } },
4861 { ISD::SSUBSAT, MVT::v4i32, { 6, 14, 12, 13 } },
4862 { ISD::SSUBSAT, MVT::v8i16, { 1, 2, 1, 1 } },
4863 { ISD::SSUBSAT, MVT::v16i8, { 1, 2, 1, 1 } },
4864 { ISD::UADDSAT, MVT::v2i64, { 7, 13, 14, 14 } },
4865 { ISD::UADDSAT, MVT::v4i32, { 4, 5, 7, 7 } },
4866 { ISD::UADDSAT, MVT::v8i16, { 1, 2, 1, 1 } },
4867 { ISD::UADDSAT, MVT::v16i8, { 1, 2, 1, 1 } },
4868 { ISD::UMAX, MVT::v2i64, { 4, 8, 15, 15 } },
4869 { ISD::UMAX, MVT::v4i32, { 2, 5, 8, 8 } },
4870 { ISD::UMAX, MVT::v8i16, { 1, 3, 3, 3 } },
4871 { ISD::UMAX, MVT::v16i8, { 1, 1, 1, 1 } },
4872 { ISD::UMIN, MVT::v2i64, { 4, 8, 15, 15 } },
4873 { ISD::UMIN, MVT::v4i32, { 2, 5, 8, 8 } },
4874 { ISD::UMIN, MVT::v8i16, { 1, 3, 3, 3 } },
4875 { ISD::UMIN, MVT::v16i8, { 1, 1, 1, 1 } },
4876 { ISD::UMULO, MVT::v2i64, { 30, 33, 15, 29 } },
4877 { ISD::UMULO, MVT::v4i32, { 19, 22, 14, 18 } },
4878 { ISD::UMULO, MVT::v8i16, { 4, 9, 7, 7 } },
4879 { ISD::UMULO, MVT::v16i8, { 13, 19, 20, 20 } },
4880 { ISD::USUBSAT, MVT::v2i64, { 7, 10, 14, 14 } },
4881 { ISD::USUBSAT, MVT::v4i32, { 4, 4, 7, 7 } },
4882 { ISD::USUBSAT, MVT::v8i16, { 1, 2, 1, 1 } },
4883 { ISD::USUBSAT, MVT::v16i8, { 1, 2, 1, 1 } },
4884 { ISD::FMAXNUM, MVT::f64, { 5, 5, 7, 7 } },
4885 { ISD::FMAXNUM, MVT::v2f64, { 4, 6, 6, 6 } },
4886 { ISD::FSQRT, MVT::f64, { 32, 32, 1, 1 } }, // Nehalem from http://www.agner.org/
4887 { ISD::FSQRT, MVT::v2f64, { 32, 32, 1, 1 } }, // Nehalem from http://www.agner.org/
4888 };
4889 static const CostKindTblEntry SSE1CostTbl[] = {
4890 { ISD::FMAXNUM, MVT::f32, { 5, 5, 7, 7 } },
4891 { ISD::FMAXNUM, MVT::v4f32, { 4, 6, 6, 6 } },
4892 { ISD::FSQRT, MVT::f32, { 28, 30, 1, 2 } }, // Pentium III from http://www.agner.org/
4893 { ISD::FSQRT, MVT::v4f32, { 56, 56, 1, 2 } }, // Pentium III from http://www.agner.org/
4894 };
4895 static const CostKindTblEntry BMI64CostTbl[] = { // 64-bit targets
4896 { ISD::CTTZ, MVT::i64, { 1, 1, 1, 1 } },
4897 };
4898 static const CostKindTblEntry BMI32CostTbl[] = { // 32 or 64-bit targets
4899 { ISD::CTTZ, MVT::i32, { 1, 1, 1, 1 } },
4900 { ISD::CTTZ, MVT::i16, { 2, 1, 1, 1 } },
4901 { ISD::CTTZ, MVT::i8, { 2, 1, 1, 1 } },
4902 };
4903 static const CostKindTblEntry LZCNT64CostTbl[] = { // 64-bit targets
4904 { ISD::CTLZ, MVT::i64, { 1, 1, 1, 1 } },
4905 };
4906 static const CostKindTblEntry LZCNT32CostTbl[] = { // 32 or 64-bit targets
4907 { ISD::CTLZ, MVT::i32, { 1, 1, 1, 1 } },
4908 { ISD::CTLZ, MVT::i16, { 2, 1, 1, 1 } },
4909 { ISD::CTLZ, MVT::i8, { 2, 1, 1, 1 } },
4910 };
4911 static const CostKindTblEntry POPCNT64CostTbl[] = { // 64-bit targets
4912 { ISD::CTPOP, MVT::i64, { 1, 1, 1, 1 } }, // popcnt
4913 };
4914 static const CostKindTblEntry POPCNT32CostTbl[] = { // 32 or 64-bit targets
4915 { ISD::CTPOP, MVT::i32, { 1, 1, 1, 1 } }, // popcnt
4916 { ISD::CTPOP, MVT::i16, { 1, 1, 2, 2 } }, // popcnt(zext())
4917 { ISD::CTPOP, MVT::i8, { 1, 1, 2, 2 } }, // popcnt(zext())
4918 };
4919 static const CostKindTblEntry PCLMULCostTbl[] = {
4920 { ISD::CLMUL, MVT::v2i64, { 3, 12, 4, 8 } }, // MOV+2xPCLMUL+unpack
4921 { ISD::CLMUL, MVT::v4i32, { 8, 18, 12, 16 } }, // MOV+4xPCLMUL+unpack
4922 { ISD::CLMUL, MVT::i64, { 3, 12, 4, 8 } }, // MOV+PCLMUL+MOV
4923 { ISD::CLMUL, MVT::i32, { 3, 12, 4, 8 } }, // MOV+PCLMUL+MOV
4924 { ISD::CLMUL, MVT::i16, { 3, 12, 4, 8 } }, // MOV+PCLMUL+MOV
4925 { ISD::CLMUL, MVT::i8, { 3, 12, 4, 8 } }, // MOV+PCLMUL+MOV
4926 };
4927 static const CostKindTblEntry X64CostTbl[] = { // 64-bit targets
4928 { ISD::ABS, MVT::i64, { 1, 2, 3, 3 } }, // SUB+CMOV
4929 { ISD::BITREVERSE, MVT::i64, { 10, 12, 20, 22 } },
4930 { ISD::BSWAP, MVT::i64, { 1, 2, 1, 2 } },
4931 { ISD::CTLZ, MVT::i64, { 1, 2, 3, 3 } }, // MOV+BSR+XOR
4932 { ISD::CTLZ, MVT::i32, { 1, 2, 3, 3 } }, // MOV+BSR+XOR
4933 { ISD::CTLZ, MVT::i16, { 2, 2, 3, 3 } }, // MOV+BSR+XOR
4934 { ISD::CTLZ, MVT::i8, { 2, 2, 4, 3 } }, // MOV+BSR+XOR
4935 { ISD::CTLZ_ZERO_POISON,MVT::i64,{ 1, 2, 2, 2 } }, // BSR+XOR
4936 { ISD::CTTZ, MVT::i64, { 1, 2, 2, 2 } }, // MOV+BSF
4937 { ISD::CTTZ, MVT::i32, { 1, 2, 2, 2 } }, // MOV+BSF
4938 { ISD::CTTZ, MVT::i16, { 2, 2, 2, 2 } }, // MOV+BSF
4939 { ISD::CTTZ, MVT::i8, { 2, 2, 2, 2 } }, // MOV+BSF
4940 { ISD::CTTZ_ZERO_POISON,MVT::i64,{ 1, 2, 1, 2 } }, // BSF
4941 { ISD::CTPOP, MVT::i64, { 10, 6, 19, 19 } },
4942 { ISD::ROTL, MVT::i64, { 2, 3, 1, 3 } },
4943 { ISD::ROTR, MVT::i64, { 2, 3, 1, 3 } },
4944 { X86ISD::VROTLI, MVT::i64, { 1, 1, 1, 1 } },
4945 { ISD::FSHL, MVT::i64, { 4, 4, 1, 4 } },
4946 { ISD::SADDSAT, MVT::i64, { 4, 4, 7, 10 } },
4947 { ISD::SSUBSAT, MVT::i64, { 4, 5, 8, 11 } },
4948 { ISD::UADDSAT, MVT::i64, { 2, 3, 4, 7 } },
4949 { ISD::USUBSAT, MVT::i64, { 2, 3, 4, 7 } },
4950 { ISD::SMAX, MVT::i64, { 1, 3, 2, 3 } },
4951 { ISD::SMIN, MVT::i64, { 1, 3, 2, 3 } },
4952 { ISD::UMAX, MVT::i64, { 1, 3, 2, 3 } },
4953 { ISD::UMIN, MVT::i64, { 1, 3, 2, 3 } },
4954 { ISD::SADDO, MVT::i64, { 2, 2, 4, 6 } },
4955 { ISD::UADDO, MVT::i64, { 2, 2, 4, 6 } },
4956 { ISD::SMULO, MVT::i64, { 4, 4, 4, 6 } },
4957 { ISD::UMULO, MVT::i64, { 8, 8, 4, 7 } },
4958 };
4959 static const CostKindTblEntry X86CostTbl[] = { // 32 or 64-bit targets
4960 { ISD::ABS, MVT::i32, { 1, 2, 3, 3 } }, // SUB+XOR+SRA or SUB+CMOV
4961 { ISD::ABS, MVT::i16, { 2, 2, 3, 3 } }, // SUB+XOR+SRA or SUB+CMOV
4962 { ISD::ABS, MVT::i8, { 2, 4, 4, 3 } }, // SUB+XOR+SRA
4963 { ISD::BITREVERSE, MVT::i32, { 9, 12, 17, 19 } },
4964 { ISD::BITREVERSE, MVT::i16, { 9, 12, 17, 19 } },
4965 { ISD::BITREVERSE, MVT::i8, { 7, 9, 13, 14 } },
4966 { ISD::BSWAP, MVT::i32, { 1, 1, 1, 1 } },
4967 { ISD::BSWAP, MVT::i16, { 1, 2, 1, 2 } }, // ROL
4968 { ISD::CTLZ, MVT::i32, { 2, 2, 4, 5 } }, // BSR+XOR or BSR+XOR+CMOV
4969 { ISD::CTLZ, MVT::i16, { 2, 2, 4, 5 } }, // BSR+XOR or BSR+XOR+CMOV
4970 { ISD::CTLZ, MVT::i8, { 2, 2, 5, 6 } }, // BSR+XOR or BSR+XOR+CMOV
4971 { ISD::CTLZ_ZERO_POISON,MVT::i32,{ 1, 2, 2, 2 } }, // BSR+XOR
4972 { ISD::CTLZ_ZERO_POISON,MVT::i16,{ 2, 2, 2, 2 } }, // BSR+XOR
4973 { ISD::CTLZ_ZERO_POISON,MVT::i8, { 2, 2, 3, 3 } }, // BSR+XOR
4974 { ISD::CTTZ, MVT::i32, { 2, 2, 3, 3 } }, // TEST+BSF+CMOV/BRANCH
4975 { ISD::CTTZ, MVT::i16, { 2, 2, 2, 3 } }, // TEST+BSF+CMOV/BRANCH
4976 { ISD::CTTZ, MVT::i8, { 2, 2, 2, 3 } }, // TEST+BSF+CMOV/BRANCH
4977 { ISD::CTTZ_ZERO_POISON,MVT::i32,{ 1, 2, 1, 2 } }, // BSF
4978 { ISD::CTTZ_ZERO_POISON,MVT::i16,{ 2, 2, 1, 2 } }, // BSF
4979 { ISD::CTTZ_ZERO_POISON,MVT::i8, { 2, 2, 1, 2 } }, // BSF
4980 { ISD::CTPOP, MVT::i32, { 8, 7, 15, 15 } },
4981 { ISD::CTPOP, MVT::i16, { 9, 8, 17, 17 } },
4982 { ISD::CTPOP, MVT::i8, { 7, 6, 6, 6 } },
4983 { ISD::ROTL, MVT::i32, { 2, 3, 1, 3 } },
4984 { ISD::ROTL, MVT::i16, { 2, 3, 1, 3 } },
4985 { ISD::ROTL, MVT::i8, { 2, 3, 1, 3 } },
4986 { ISD::ROTR, MVT::i32, { 2, 3, 1, 3 } },
4987 { ISD::ROTR, MVT::i16, { 2, 3, 1, 3 } },
4988 { ISD::ROTR, MVT::i8, { 2, 3, 1, 3 } },
4989 { X86ISD::VROTLI, MVT::i32, { 1, 1, 1, 1 } },
4990 { X86ISD::VROTLI, MVT::i16, { 1, 1, 1, 1 } },
4991 { X86ISD::VROTLI, MVT::i8, { 1, 1, 1, 1 } },
4992 { ISD::FSHL, MVT::i32, { 4, 4, 1, 4 } },
4993 { ISD::FSHL, MVT::i16, { 4, 4, 2, 5 } },
4994 { ISD::FSHL, MVT::i8, { 4, 4, 2, 5 } },
4995 { ISD::SADDSAT, MVT::i32, { 3, 4, 6, 9 } },
4996 { ISD::SADDSAT, MVT::i16, { 4, 4, 7, 10 } },
4997 { ISD::SADDSAT, MVT::i8, { 4, 5, 8, 11 } },
4998 { ISD::SSUBSAT, MVT::i32, { 4, 4, 7, 10 } },
4999 { ISD::SSUBSAT, MVT::i16, { 4, 4, 7, 10 } },
5000 { ISD::SSUBSAT, MVT::i8, { 4, 5, 8, 11 } },
5001 { ISD::UADDSAT, MVT::i32, { 2, 3, 4, 7 } },
5002 { ISD::UADDSAT, MVT::i16, { 2, 3, 4, 7 } },
5003 { ISD::UADDSAT, MVT::i8, { 3, 3, 5, 8 } },
5004 { ISD::USUBSAT, MVT::i32, { 2, 3, 4, 7 } },
5005 { ISD::USUBSAT, MVT::i16, { 2, 3, 4, 7 } },
5006 { ISD::USUBSAT, MVT::i8, { 3, 3, 5, 8 } },
5007 { ISD::SMAX, MVT::i32, { 1, 2, 2, 3 } },
5008 { ISD::SMAX, MVT::i16, { 1, 4, 2, 4 } },
5009 { ISD::SMAX, MVT::i8, { 1, 4, 2, 4 } },
5010 { ISD::SMIN, MVT::i32, { 1, 2, 2, 3 } },
5011 { ISD::SMIN, MVT::i16, { 1, 4, 2, 4 } },
5012 { ISD::SMIN, MVT::i8, { 1, 4, 2, 4 } },
5013 { ISD::UMAX, MVT::i32, { 1, 2, 2, 3 } },
5014 { ISD::UMAX, MVT::i16, { 1, 4, 2, 4 } },
5015 { ISD::UMAX, MVT::i8, { 1, 4, 2, 4 } },
5016 { ISD::UMIN, MVT::i32, { 1, 2, 2, 3 } },
5017 { ISD::UMIN, MVT::i16, { 1, 4, 2, 4 } },
5018 { ISD::UMIN, MVT::i8, { 1, 4, 2, 4 } },
5019 { ISD::SADDO, MVT::i32, { 2, 2, 4, 6 } },
5020 { ISD::SADDO, MVT::i16, { 2, 2, 4, 6 } },
5021 { ISD::SADDO, MVT::i8, { 2, 2, 4, 6 } },
5022 { ISD::UADDO, MVT::i32, { 2, 2, 4, 6 } },
5023 { ISD::UADDO, MVT::i16, { 2, 2, 4, 6 } },
5024 { ISD::UADDO, MVT::i8, { 2, 2, 4, 6 } },
5025 { ISD::SMULO, MVT::i32, { 2, 2, 4, 6 } },
5026 { ISD::SMULO, MVT::i16, { 5, 5, 4, 6 } },
5027 { ISD::SMULO, MVT::i8, { 6, 6, 4, 6 } },
5028 { ISD::UMULO, MVT::i32, { 6, 6, 4, 8 } },
5029 { ISD::UMULO, MVT::i16, { 6, 6, 4, 9 } },
5030 { ISD::UMULO, MVT::i8, { 6, 6, 4, 6 } },
5031 };
5032
5033 Type *RetTy = ICA.getReturnType();
5034 Type *OpTy = RetTy;
5035 Intrinsic::ID IID = ICA.getID();
5036 unsigned ISD = ISD::DELETED_NODE;
5037 switch (IID) {
5038 default:
5039 break;
5040 case Intrinsic::abs:
5041 ISD = ISD::ABS;
5042 break;
5043 case Intrinsic::bitreverse:
5045 break;
5046 case Intrinsic::bswap:
5047 ISD = ISD::BSWAP;
5048 break;
5049 case Intrinsic::ctlz:
5050 ISD = ISD::CTLZ;
5051 break;
5052 case Intrinsic::ctpop:
5053 ISD = ISD::CTPOP;
5054 break;
5055 case Intrinsic::cttz:
5056 ISD = ISD::CTTZ;
5057 break;
5058 case Intrinsic::fshl:
5059 ISD = ISD::FSHL;
5060 if (!ICA.isTypeBasedOnly()) {
5061 const SmallVectorImpl<const Value *> &Args = ICA.getArgs();
5062 if (Args[0] == Args[1]) {
5063 ISD = ISD::ROTL;
5064 // Handle uniform constant rotation amounts.
5065 // TODO: Handle funnel-shift cases.
5066 const APInt *Amt;
5067 if (Args[2] &&
5069 ISD = X86ISD::VROTLI;
5070 }
5071 }
5072 break;
5073 case Intrinsic::fshr:
5074 // FSHR has same costs so don't duplicate.
5075 ISD = ISD::FSHL;
5076 if (!ICA.isTypeBasedOnly()) {
5077 const SmallVectorImpl<const Value *> &Args = ICA.getArgs();
5078 if (Args[0] == Args[1]) {
5079 ISD = ISD::ROTR;
5080 // Handle uniform constant rotation amount.
5081 // TODO: Handle funnel-shift cases.
5082 const APInt *Amt;
5083 if (Args[2] &&
5085 ISD = X86ISD::VROTLI;
5086 }
5087 }
5088 break;
5089 case Intrinsic::lrint:
5090 case Intrinsic::llrint: {
5091 // X86 can use the CVTP2SI instructions to lower lrint/llrint calls, which
5092 // have the same costs as the CVTTP2SI (fptosi) instructions
5093 const SmallVectorImpl<Type *> &ArgTys = ICA.getArgTypes();
5094 return getCastInstrCost(Instruction::FPToSI, RetTy, ArgTys[0],
5096 }
5097 case Intrinsic::maxnum:
5098 case Intrinsic::minnum:
5099 // FMINNUM has same costs so don't duplicate.
5100 ISD = ISD::FMAXNUM;
5101 break;
5102 case Intrinsic::sadd_sat:
5103 ISD = ISD::SADDSAT;
5104 break;
5105 case Intrinsic::smax:
5106 ISD = ISD::SMAX;
5107 break;
5108 case Intrinsic::smin:
5109 ISD = ISD::SMIN;
5110 break;
5111 case Intrinsic::smulh:
5112 ISD = ISD::MULHS;
5113 break;
5114 case Intrinsic::ssub_sat:
5115 ISD = ISD::SSUBSAT;
5116 break;
5117 case Intrinsic::uadd_sat:
5118 ISD = ISD::UADDSAT;
5119 break;
5120 case Intrinsic::umax:
5121 ISD = ISD::UMAX;
5122 break;
5123 case Intrinsic::umin:
5124 ISD = ISD::UMIN;
5125 break;
5126 case Intrinsic::usub_sat:
5127 ISD = ISD::USUBSAT;
5128 break;
5129 case Intrinsic::umulh:
5130 ISD = ISD::MULHU;
5131 break;
5132 case Intrinsic::sqrt:
5133 ISD = ISD::FSQRT;
5134 break;
5135 case Intrinsic::sadd_with_overflow:
5136 case Intrinsic::ssub_with_overflow:
5137 // SSUBO has same costs so don't duplicate.
5138 ISD = ISD::SADDO;
5139 OpTy = RetTy->getContainedType(0);
5140 break;
5141 case Intrinsic::uadd_with_overflow:
5142 case Intrinsic::usub_with_overflow:
5143 // USUBO has same costs so don't duplicate.
5144 ISD = ISD::UADDO;
5145 OpTy = RetTy->getContainedType(0);
5146 break;
5147 case Intrinsic::smul_with_overflow:
5148 ISD = ISD::SMULO;
5149 OpTy = RetTy->getContainedType(0);
5150 break;
5151 case Intrinsic::umul_with_overflow:
5152 ISD = ISD::UMULO;
5153 OpTy = RetTy->getContainedType(0);
5154 break;
5155 case Intrinsic::clmul:
5156 ISD = ISD::CLMUL;
5157 break;
5158 }
5159
5160 if (ISD != ISD::DELETED_NODE) {
5161 auto adjustTableCost = [&](int ISD, unsigned Cost,
5162 std::pair<InstructionCost, MVT> LT,
5164 InstructionCost LegalizationCost = LT.first;
5165 MVT MTy = LT.second;
5166
5167 // If there are no NANs to deal with, then these are reduced to a
5168 // single MIN** or MAX** instruction instead of the MIN/CMP/SELECT that we
5169 // assume is used in the non-fast case.
5170 if (ISD == ISD::FMAXNUM || ISD == ISD::FMINNUM) {
5171 if (FMF.noNaNs())
5172 return LegalizationCost * 1;
5173 }
5174
5175 // For cases where some ops can be folded into a load/store, assume free.
5176 if (MTy.isScalarInteger()) {
5177 if (ISD == ISD::BSWAP && ST->hasMOVBE() && ST->hasFastMOVBE()) {
5178 if (const Instruction *II = ICA.getInst()) {
5179 if (II->hasOneUse() && isa<StoreInst>(II->user_back()))
5180 return TTI::TCC_Free;
5181 if (auto *LI = dyn_cast<LoadInst>(II->getOperand(0))) {
5182 if (LI->hasOneUse())
5183 return TTI::TCC_Free;
5184 }
5185 }
5186 }
5187 }
5188
5189 return LegalizationCost * (int)Cost;
5190 };
5191
5192 // Legalize the type.
5193 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(OpTy);
5194 MVT MTy = LT.second;
5195
5196 // Without BMI/LZCNT see if we're only looking for a *_ZERO_POISON cost.
5197 if (((ISD == ISD::CTTZ && !ST->hasBMI()) ||
5198 (ISD == ISD::CTLZ && !ST->hasLZCNT())) &&
5199 !MTy.isVector() && !ICA.isTypeBasedOnly()) {
5200 const SmallVectorImpl<const Value *> &Args = ICA.getArgs();
5201 if (auto *Cst = dyn_cast<ConstantInt>(Args[1]))
5202 if (Cst->isAllOnesValue())
5203 ISD =
5205 }
5206
5207 // FSQRT is a single instruction.
5209 return LT.first;
5210
5211 if (ST->useGLMDivSqrtCosts())
5212 if (const auto *Entry = CostTableLookup(GLMCostTbl, ISD, MTy))
5213 if (auto KindCost = Entry->Cost[CostKind])
5214 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5215
5216 if (ST->useSLMArithCosts())
5217 if (const auto *Entry = CostTableLookup(SLMCostTbl, ISD, MTy))
5218 if (auto KindCost = Entry->Cost[CostKind])
5219 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5220
5221 if (ST->hasVBMI2())
5222 if (const auto *Entry = CostTableLookup(AVX512VBMI2CostTbl, ISD, MTy))
5223 if (auto KindCost = Entry->Cost[CostKind])
5224 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5225
5226 if (ST->hasBITALG())
5227 if (const auto *Entry = CostTableLookup(AVX512BITALGCostTbl, ISD, MTy))
5228 if (auto KindCost = Entry->Cost[CostKind])
5229 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5230
5231 if (ST->hasVPOPCNTDQ())
5232 if (const auto *Entry = CostTableLookup(AVX512VPOPCNTDQCostTbl, ISD, MTy))
5233 if (auto KindCost = Entry->Cost[CostKind])
5234 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5235
5236 if (ST->hasGFNI())
5237 if (const auto *Entry = CostTableLookup(GFNICostTbl, ISD, MTy))
5238 if (auto KindCost = Entry->Cost[CostKind])
5239 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5240
5241 if (ST->hasCDI())
5242 if (const auto *Entry = CostTableLookup(AVX512CDCostTbl, ISD, MTy))
5243 if (auto KindCost = Entry->Cost[CostKind])
5244 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5245
5246 if (ST->hasBWI())
5247 if (const auto *Entry = CostTableLookup(AVX512BWCostTbl, ISD, MTy))
5248 if (auto KindCost = Entry->Cost[CostKind])
5249 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5250
5251 if (ST->hasAVX512())
5252 if (const auto *Entry = CostTableLookup(AVX512CostTbl, ISD, MTy))
5253 if (auto KindCost = Entry->Cost[CostKind])
5254 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5255
5256 if (ST->hasXOP())
5257 if (const auto *Entry = CostTableLookup(XOPCostTbl, ISD, MTy))
5258 if (auto KindCost = Entry->Cost[CostKind])
5259 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5260
5261 if (ST->hasAVX2())
5262 if (const auto *Entry = CostTableLookup(AVX2CostTbl, ISD, MTy))
5263 if (auto KindCost = Entry->Cost[CostKind])
5264 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5265
5266 if (ST->hasAVX())
5267 if (const auto *Entry = CostTableLookup(AVX1CostTbl, ISD, MTy))
5268 if (auto KindCost = Entry->Cost[CostKind])
5269 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5270
5271 if (ST->hasSSE42())
5272 if (const auto *Entry = CostTableLookup(SSE42CostTbl, ISD, MTy))
5273 if (auto KindCost = Entry->Cost[CostKind])
5274 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5275
5276 if (ST->hasSSE41())
5277 if (const auto *Entry = CostTableLookup(SSE41CostTbl, ISD, MTy))
5278 if (auto KindCost = Entry->Cost[CostKind])
5279 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5280
5281 if (ST->hasSSSE3())
5282 if (const auto *Entry = CostTableLookup(SSSE3CostTbl, ISD, MTy))
5283 if (auto KindCost = Entry->Cost[CostKind])
5284 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5285
5286 if (ST->hasSSE2())
5287 if (const auto *Entry = CostTableLookup(SSE2CostTbl, ISD, MTy))
5288 if (auto KindCost = Entry->Cost[CostKind])
5289 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5290
5291 if (ST->hasSSE1())
5292 if (const auto *Entry = CostTableLookup(SSE1CostTbl, ISD, MTy))
5293 if (auto KindCost = Entry->Cost[CostKind])
5294 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5295
5296 if (ST->hasBMI()) {
5297 if (ST->is64Bit())
5298 if (const auto *Entry = CostTableLookup(BMI64CostTbl, ISD, MTy))
5299 if (auto KindCost = Entry->Cost[CostKind])
5300 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5301
5302 if (const auto *Entry = CostTableLookup(BMI32CostTbl, ISD, MTy))
5303 if (auto KindCost = Entry->Cost[CostKind])
5304 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5305 }
5306
5307 if (ST->hasLZCNT()) {
5308 if (ST->is64Bit())
5309 if (const auto *Entry = CostTableLookup(LZCNT64CostTbl, ISD, MTy))
5310 if (auto KindCost = Entry->Cost[CostKind])
5311 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5312
5313 if (const auto *Entry = CostTableLookup(LZCNT32CostTbl, ISD, MTy))
5314 if (auto KindCost = Entry->Cost[CostKind])
5315 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5316 }
5317
5318 if (ST->hasPOPCNT()) {
5319 if (ST->is64Bit())
5320 if (const auto *Entry = CostTableLookup(POPCNT64CostTbl, ISD, MTy))
5321 if (auto KindCost = Entry->Cost[CostKind])
5322 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5323
5324 if (const auto *Entry = CostTableLookup(POPCNT32CostTbl, ISD, MTy))
5325 if (auto KindCost = Entry->Cost[CostKind])
5326 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5327 }
5328
5329 // FIXME: PCLMUL w/ AVX/AVX512 and VPCLMULQDQ are not handled properly.
5330 if (ST->hasPCLMUL())
5331 if (const auto *Entry = CostTableLookup(PCLMULCostTbl, ISD, MTy))
5332 if (auto KindCost = Entry->Cost[CostKind])
5333 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5334
5335 if (ST->is64Bit())
5336 if (const auto *Entry = CostTableLookup(X64CostTbl, ISD, MTy))
5337 if (auto KindCost = Entry->Cost[CostKind])
5338 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5339
5340 if (const auto *Entry = CostTableLookup(X86CostTbl, ISD, MTy))
5341 if (auto KindCost = Entry->Cost[CostKind])
5342 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5343
5344 // Without arg data, we need to compute the expanded costs of custom lowered
5345 // intrinsics to prevent use of the (very low) default costs.
5346 if (ICA.isTypeBasedOnly() &&
5347 (IID == Intrinsic::fshl || IID == Intrinsic::fshr)) {
5348 Type *CondTy = RetTy->getWithNewBitWidth(1);
5350 Cost += getArithmeticInstrCost(BinaryOperator::Or, RetTy, CostKind);
5351 Cost += getArithmeticInstrCost(BinaryOperator::Sub, RetTy, CostKind);
5352 Cost += getArithmeticInstrCost(BinaryOperator::Shl, RetTy, CostKind);
5353 Cost += getArithmeticInstrCost(BinaryOperator::LShr, RetTy, CostKind);
5354 Cost += getArithmeticInstrCost(BinaryOperator::And, RetTy, CostKind);
5355 Cost += getCmpSelInstrCost(BinaryOperator::ICmp, RetTy, CondTy,
5357 Cost += getCmpSelInstrCost(BinaryOperator::Select, RetTy, CondTy,
5359 return Cost;
5360 }
5361 }
5362
5364}
5365
5367 unsigned Opcode, Type *Val, TTI::TargetCostKind CostKind, unsigned Index,
5368 const Value *Op0, const Value *Op1, TTI::VectorInstrContext VIC) const {
5369 static const CostTblEntry SLMCostTbl[] = {
5370 { ISD::EXTRACT_VECTOR_ELT, MVT::i8, 4 },
5371 { ISD::EXTRACT_VECTOR_ELT, MVT::i16, 4 },
5372 { ISD::EXTRACT_VECTOR_ELT, MVT::i32, 4 },
5373 { ISD::EXTRACT_VECTOR_ELT, MVT::i64, 7 }
5374 };
5375
5376 assert(Val->isVectorTy() && "This must be a vector type");
5377 auto *VT = cast<VectorType>(Val);
5378 if (VT->isScalableTy())
5380
5381 Type *ScalarType = Val->getScalarType();
5382 InstructionCost RegisterFileMoveCost = 0;
5383
5384 // Non-immediate extraction/insertion can be handled as a sequence of
5385 // aliased loads+stores via the stack.
5386 if (Index == -1U && (Opcode == Instruction::ExtractElement ||
5387 Opcode == Instruction::InsertElement)) {
5388 // TODO: On some SSE41+ targets, we expand to cmp+splat+select patterns:
5389 // inselt N0, N1, N2 --> select (SplatN2 == {0,1,2...}) ? SplatN1 : N0.
5390
5391 // TODO: Move this to BasicTTIImpl.h? We'd need better gep + index handling.
5392 assert(isa<FixedVectorType>(Val) && "Fixed vector type expected");
5393 Align VecAlign = DL.getPrefTypeAlign(Val);
5394 Align SclAlign = DL.getPrefTypeAlign(ScalarType);
5395
5396 // Extract - store vector to stack, load scalar.
5397 if (Opcode == Instruction::ExtractElement) {
5398 return getMemoryOpCost(Instruction::Store, Val, VecAlign, 0, CostKind) +
5399 getMemoryOpCost(Instruction::Load, ScalarType, SclAlign, 0,
5400 CostKind);
5401 }
5402 // Insert - store vector to stack, store scalar, load vector.
5403 if (Opcode == Instruction::InsertElement) {
5404 return getMemoryOpCost(Instruction::Store, Val, VecAlign, 0, CostKind) +
5405 getMemoryOpCost(Instruction::Store, ScalarType, SclAlign, 0,
5406 CostKind) +
5407 getMemoryOpCost(Instruction::Load, Val, VecAlign, 0, CostKind);
5408 }
5409 }
5410
5411 if (Index != -1U && (Opcode == Instruction::ExtractElement ||
5412 Opcode == Instruction::InsertElement)) {
5413 // Extraction of vXi1 elements are now efficiently handled by MOVMSK.
5414 if (Opcode == Instruction::ExtractElement &&
5415 ScalarType->getScalarSizeInBits() == 1 &&
5416 cast<FixedVectorType>(Val)->getNumElements() > 1)
5417 return 1;
5418
5419 // Legalize the type.
5420 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Val);
5421
5422 // This type is legalized to a scalar type.
5423 if (!LT.second.isVector())
5424 return TTI::TCC_Free;
5425
5426 // The type may be split. Normalize the index to the new type.
5427 unsigned SizeInBits = LT.second.getSizeInBits();
5428 unsigned NumElts = LT.second.getVectorNumElements();
5429 unsigned SubNumElts = NumElts;
5430 Index = Index % NumElts;
5431
5432 // For >128-bit vectors, we need to extract higher 128-bit subvectors.
5433 // For inserts, we also need to insert the subvector back.
5434 if (SizeInBits > 128) {
5435 assert((SizeInBits % 128) == 0 && "Illegal vector");
5436 unsigned NumSubVecs = SizeInBits / 128;
5437 SubNumElts = NumElts / NumSubVecs;
5438 if (SubNumElts <= Index) {
5439 RegisterFileMoveCost += (Opcode == Instruction::InsertElement ? 2 : 1);
5440 Index %= SubNumElts;
5441 }
5442 }
5443
5444 MVT MScalarTy = LT.second.getScalarType();
5445 auto IsCheapPInsrPExtrInsertPS = [&]() {
5446 // Assume pinsr/pextr XMM <-> GPR is relatively cheap on all targets.
5447 // Inserting f32 into index0 is just movss.
5448 // Also, assume insertps is relatively cheap on all >= SSE41 targets.
5449 return (MScalarTy == MVT::i16 && ST->hasSSE2()) ||
5450 (MScalarTy.isInteger() && ST->hasSSE41()) ||
5451 (MScalarTy == MVT::f32 && ST->hasSSE1() && Index == 0 &&
5452 Opcode == Instruction::InsertElement) ||
5453 (MScalarTy == MVT::f32 && ST->hasSSE41() &&
5454 Opcode == Instruction::InsertElement);
5455 };
5456
5457 if (Index == 0) {
5458 // Floating point scalars are already located in index #0.
5459 // Many insertions to #0 can fold away for scalar fp-ops, so let's assume
5460 // true for all.
5461 if (ScalarType->isFloatingPointTy() &&
5462 (Opcode != Instruction::InsertElement || !Op0 ||
5463 isa<UndefValue>(Op0)))
5464 return RegisterFileMoveCost;
5465
5466 if (Opcode == Instruction::InsertElement &&
5468 // Consider the gather cost to be cheap.
5470 return RegisterFileMoveCost;
5471 if (!IsCheapPInsrPExtrInsertPS()) {
5472 // mov constant-to-GPR + movd/movq GPR -> XMM.
5473 if (isa_and_nonnull<Constant>(Op1) && Op1->getType()->isIntegerTy())
5474 return 2 + RegisterFileMoveCost;
5475 // Assume movd/movq GPR -> XMM is relatively cheap on all targets.
5476 return 1 + RegisterFileMoveCost;
5477 }
5478 }
5479
5480 // Assume movd/movq XMM -> GPR is relatively cheap on all targets.
5481 if (ScalarType->isIntegerTy() && Opcode == Instruction::ExtractElement)
5482 return 1 + RegisterFileMoveCost;
5483 }
5484
5485 int ISD = TLI->InstructionOpcodeToISD(Opcode);
5486 assert(ISD && "Unexpected vector opcode");
5487 if (ST->useSLMArithCosts())
5488 if (auto *Entry = CostTableLookup(SLMCostTbl, ISD, MScalarTy))
5489 return Entry->Cost + RegisterFileMoveCost;
5490
5491 // Consider cheap cases.
5492 if (IsCheapPInsrPExtrInsertPS())
5493 return 1 + RegisterFileMoveCost;
5494
5495 // For extractions we just need to shuffle the element to index 0, which
5496 // should be very cheap (assume cost = 1). For insertions we need to shuffle
5497 // the elements to its destination. In both cases we must handle the
5498 // subvector move(s).
5499 // If the vector type is already less than 128-bits then don't reduce it.
5500 // TODO: Under what circumstances should we shuffle using the full width?
5501 InstructionCost ShuffleCost = 1;
5502 if (Opcode == Instruction::InsertElement) {
5503 auto *SubTy = cast<VectorType>(Val);
5504 EVT VT = TLI->getValueType(DL, Val);
5505 if (VT.getScalarType() != MScalarTy || VT.getSizeInBits() >= 128)
5506 SubTy = FixedVectorType::get(ScalarType, SubNumElts);
5507 ShuffleCost = getShuffleCost(TTI::SK_PermuteTwoSrc, SubTy, SubTy,
5508 CostKind, {}, 0, SubTy);
5509 }
5510 int IntOrFpCost = ScalarType->isFloatingPointTy() ? 0 : 1;
5511 return ShuffleCost + IntOrFpCost + RegisterFileMoveCost;
5512 }
5513
5514 return BaseT::getVectorInstrCost(Opcode, Val, CostKind, Index, Op0, Op1,
5515 VIC) +
5516 RegisterFileMoveCost;
5517}
5518
5520 VectorType *Ty, const APInt &DemandedElts, bool Insert, bool Extract,
5521 TTI::TargetCostKind CostKind, bool ForPoisonSrc, ArrayRef<Value *> VL,
5522 TTI::VectorInstrContext VIC) const {
5523 assert(DemandedElts.getBitWidth() ==
5524 cast<FixedVectorType>(Ty)->getNumElements() &&
5525 "Vector size mismatch");
5526
5527 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Ty);
5528 MVT MScalarTy = LT.second.getScalarType();
5529 unsigned LegalVectorBitWidth = LT.second.getSizeInBits();
5531
5532 constexpr unsigned LaneBitWidth = 128;
5533 assert((LegalVectorBitWidth < LaneBitWidth ||
5534 (LegalVectorBitWidth % LaneBitWidth) == 0) &&
5535 "Illegal vector");
5536
5537 const int NumLegalVectors = LT.first.getValue();
5538 assert(NumLegalVectors >= 0 && "Negative cost!");
5539
5540 // For insertions, a ISD::BUILD_VECTOR style vector initialization can be much
5541 // cheaper than an accumulation of ISD::INSERT_VECTOR_ELT. SLPVectorizer has
5542 // a special heuristic regarding poison input which is passed here in
5543 // ForPoisonSrc.
5544 if (Insert && !ForPoisonSrc) {
5545 // This is nearly identical to BaseT::getScalarizationOverhead(), except
5546 // it is passing nullptr to getVectorInstrCost() for Op0 (instead of
5547 // Constant::getNullValue()), which makes the X86TTIImpl
5548 // getVectorInstrCost() return 0 instead of 1.
5549 for (unsigned I : seq(DemandedElts.getBitWidth())) {
5550 if (!DemandedElts[I])
5551 continue;
5552 Cost += getVectorInstrCost(Instruction::InsertElement, Ty, CostKind, I,
5554 VL.empty() ? nullptr : VL[I],
5556 }
5557 return Cost;
5558 }
5559
5560 if (Insert) {
5561 if ((MScalarTy == MVT::i16 && ST->hasSSE2()) ||
5562 (MScalarTy.isInteger() && ST->hasSSE41()) ||
5563 (MScalarTy == MVT::f32 && ST->hasSSE41())) {
5564 // For types we can insert directly, insertion into 128-bit sub vectors is
5565 // cheap, followed by a cheap chain of concatenations.
5566 if (LegalVectorBitWidth <= LaneBitWidth) {
5567 Cost += BaseT::getScalarizationOverhead(Ty, DemandedElts, Insert,
5568 /*Extract*/ false, CostKind);
5569 } else {
5570 // In each 128-lane, if at least one index is demanded but not all
5571 // indices are demanded and this 128-lane is not the first 128-lane of
5572 // the legalized-vector, then this 128-lane needs a extracti128; If in
5573 // each 128-lane, there is at least one demanded index, this 128-lane
5574 // needs a inserti128.
5575
5576 // The following cases will help you build a better understanding:
5577 // Assume we insert several elements into a v8i32 vector in avx2,
5578 // Case#1: inserting into 1th index needs vpinsrd + inserti128.
5579 // Case#2: inserting into 5th index needs extracti128 + vpinsrd +
5580 // inserti128.
5581 // Case#3: inserting into 4,5,6,7 index needs 4*vpinsrd + inserti128.
5582 assert((LegalVectorBitWidth % LaneBitWidth) == 0 && "Illegal vector");
5583 unsigned NumLegalLanes = LegalVectorBitWidth / LaneBitWidth;
5584 unsigned NumLanesTotal = NumLegalLanes * NumLegalVectors;
5585 unsigned NumLegalElts =
5586 LT.second.getVectorNumElements() * NumLegalVectors;
5587 assert(NumLegalElts >= DemandedElts.getBitWidth() &&
5588 "Vector has been legalized to smaller element count");
5589 assert((NumLegalElts % NumLanesTotal) == 0 &&
5590 "Unexpected elts per lane");
5591 unsigned NumEltsPerLane = NumLegalElts / NumLanesTotal;
5592
5593 APInt WidenedDemandedElts = DemandedElts.zext(NumLegalElts);
5594 auto *LaneTy =
5595 FixedVectorType::get(Ty->getElementType(), NumEltsPerLane);
5596
5597 for (unsigned I = 0; I != NumLanesTotal; ++I) {
5598 APInt LaneEltMask = WidenedDemandedElts.extractBits(
5599 NumEltsPerLane, NumEltsPerLane * I);
5600 if (LaneEltMask.isZero())
5601 continue;
5602 // FIXME: we don't need to extract if all non-demanded elements
5603 // are legalization-inserted padding.
5604 if (!LaneEltMask.isAllOnes())
5606 {}, I * NumEltsPerLane, LaneTy);
5607 Cost += BaseT::getScalarizationOverhead(LaneTy, LaneEltMask, Insert,
5608 /*Extract*/ false, CostKind);
5609 }
5610
5611 APInt AffectedLanes =
5612 APIntOps::ScaleBitMask(WidenedDemandedElts, NumLanesTotal);
5613 APInt FullyAffectedLegalVectors = APIntOps::ScaleBitMask(
5614 AffectedLanes, NumLegalVectors, /*MatchAllBits=*/true);
5615 for (int LegalVec = 0; LegalVec != NumLegalVectors; ++LegalVec) {
5616 for (unsigned Lane = 0; Lane != NumLegalLanes; ++Lane) {
5617 unsigned I = NumLegalLanes * LegalVec + Lane;
5618 // No need to insert unaffected lane; or lane 0 of each legal vector
5619 // iff ALL lanes of that vector were affected and will be inserted.
5620 if (!AffectedLanes[I] ||
5621 (Lane == 0 && FullyAffectedLegalVectors[LegalVec]))
5622 continue;
5624 {}, I * NumEltsPerLane, LaneTy);
5625 }
5626 }
5627 }
5628 } else if (LT.second.isVector()) {
5629 // Without fast insertion, we need to use MOVD/MOVQ to pass each demanded
5630 // integer element as a SCALAR_TO_VECTOR, then we build the vector as a
5631 // series of UNPCK followed by CONCAT_VECTORS - all of these can be
5632 // considered cheap.
5633 if (Ty->isIntOrIntVectorTy())
5634 Cost += DemandedElts.popcount();
5635
5636 // Get the smaller of the legalized or original pow2-extended number of
5637 // vector elements, which represents the number of unpacks we'll end up
5638 // performing.
5639 unsigned NumElts = LT.second.getVectorNumElements();
5640 unsigned Pow2Elts =
5641 PowerOf2Ceil(cast<FixedVectorType>(Ty)->getNumElements());
5642 Cost += (std::min<unsigned>(NumElts, Pow2Elts) - 1) * LT.first;
5643 }
5644 }
5645
5646 if (Extract) {
5647 // vXi1 can be efficiently extracted with MOVMSK.
5648 // TODO: AVX512 predicate mask handling.
5649 // NOTE: This doesn't work well for roundtrip scalarization.
5650 if (!Insert && Ty->getScalarSizeInBits() == 1 && !ST->hasAVX512()) {
5651 unsigned NumElts = cast<FixedVectorType>(Ty)->getNumElements();
5652 unsigned MaxElts = ST->hasAVX2() ? 32 : 16;
5653 unsigned MOVMSKCost = (NumElts + MaxElts - 1) / MaxElts;
5654 return MOVMSKCost;
5655 }
5656
5657 if (LT.second.isVector()) {
5658 unsigned NumLegalElts =
5659 LT.second.getVectorNumElements() * NumLegalVectors;
5660 assert(NumLegalElts >= DemandedElts.getBitWidth() &&
5661 "Vector has been legalized to smaller element count");
5662
5663 // If we're extracting elements from a 128-bit subvector lane,
5664 // we only need to extract each lane once, not for every element.
5665 if (LegalVectorBitWidth > LaneBitWidth) {
5666 unsigned NumLegalLanes = LegalVectorBitWidth / LaneBitWidth;
5667 unsigned NumLanesTotal = NumLegalLanes * NumLegalVectors;
5668 assert((NumLegalElts % NumLanesTotal) == 0 &&
5669 "Unexpected elts per lane");
5670 unsigned NumEltsPerLane = NumLegalElts / NumLanesTotal;
5671
5672 // Add cost for each demanded 128-bit subvector extraction.
5673 // Luckily this is a lot easier than for insertion.
5674 APInt WidenedDemandedElts = DemandedElts.zext(NumLegalElts);
5675 auto *LaneTy =
5676 FixedVectorType::get(Ty->getElementType(), NumEltsPerLane);
5677
5678 for (unsigned I = 0; I != NumLanesTotal; ++I) {
5679 APInt LaneEltMask = WidenedDemandedElts.extractBits(
5680 NumEltsPerLane, I * NumEltsPerLane);
5681 if (LaneEltMask.isZero())
5682 continue;
5684 I * NumEltsPerLane, LaneTy);
5686 LaneTy, LaneEltMask, /*Insert*/ false, Extract, CostKind);
5687 }
5688
5689 return Cost;
5690 }
5691 }
5692
5693 // Fallback to default extraction.
5694 Cost += BaseT::getScalarizationOverhead(Ty, DemandedElts, /*Insert*/ false,
5695 Extract, CostKind);
5696 }
5697
5698 return Cost;
5699}
5700
5702X86TTIImpl::getReplicationShuffleCost(Type *EltTy, int ReplicationFactor,
5703 int VF, const APInt &DemandedDstElts,
5705 const unsigned EltTyBits = DL.getTypeSizeInBits(EltTy);
5706 // We don't differentiate element types here, only element bit width.
5707 EltTy = IntegerType::getIntNTy(EltTy->getContext(), EltTyBits);
5708
5709 auto bailout = [&]() {
5710 return BaseT::getReplicationShuffleCost(EltTy, ReplicationFactor, VF,
5711 DemandedDstElts, CostKind);
5712 };
5713
5714 // For now, only deal with AVX512 cases.
5715 if (!ST->hasAVX512())
5716 return bailout();
5717
5718 // Do we have a native shuffle for this element type, or should we promote?
5719 unsigned PromEltTyBits = EltTyBits;
5720 switch (EltTyBits) {
5721 case 32:
5722 case 64:
5723 break; // AVX512F.
5724 case 16:
5725 if (!ST->hasBWI())
5726 PromEltTyBits = 32; // promote to i32, AVX512F.
5727 break; // AVX512BW
5728 case 8:
5729 if (!ST->hasVBMI())
5730 PromEltTyBits = 32; // promote to i32, AVX512F.
5731 break; // AVX512VBMI
5732 case 1:
5733 // There is no support for shuffling i1 elements. We *must* promote.
5734 if (ST->hasBWI()) {
5735 if (ST->hasVBMI())
5736 PromEltTyBits = 8; // promote to i8, AVX512VBMI.
5737 else
5738 PromEltTyBits = 16; // promote to i16, AVX512BW.
5739 break;
5740 }
5741 PromEltTyBits = 32; // promote to i32, AVX512F.
5742 break;
5743 default:
5744 return bailout();
5745 }
5746 auto *PromEltTy = IntegerType::getIntNTy(EltTy->getContext(), PromEltTyBits);
5747
5748 auto *SrcVecTy = FixedVectorType::get(EltTy, VF);
5749 auto *PromSrcVecTy = FixedVectorType::get(PromEltTy, VF);
5750
5751 int NumDstElements = VF * ReplicationFactor;
5752 auto *PromDstVecTy = FixedVectorType::get(PromEltTy, NumDstElements);
5753 auto *DstVecTy = FixedVectorType::get(EltTy, NumDstElements);
5754
5755 // Legalize the types.
5756 MVT LegalSrcVecTy = getTypeLegalizationCost(SrcVecTy).second;
5757 MVT LegalPromSrcVecTy = getTypeLegalizationCost(PromSrcVecTy).second;
5758 MVT LegalPromDstVecTy = getTypeLegalizationCost(PromDstVecTy).second;
5759 MVT LegalDstVecTy = getTypeLegalizationCost(DstVecTy).second;
5760 // They should have legalized into vector types.
5761 if (!LegalSrcVecTy.isVector() || !LegalPromSrcVecTy.isVector() ||
5762 !LegalPromDstVecTy.isVector() || !LegalDstVecTy.isVector())
5763 return bailout();
5764
5765 if (PromEltTyBits != EltTyBits) {
5766 // If we have to perform the shuffle with wider elt type than our data type,
5767 // then we will first need to anyext (we don't care about the new bits)
5768 // the source elements, and then truncate Dst elements.
5769 InstructionCost PromotionCost;
5770 PromotionCost += getCastInstrCost(
5771 Instruction::SExt, /*Dst=*/PromSrcVecTy, /*Src=*/SrcVecTy,
5773 PromotionCost +=
5774 getCastInstrCost(Instruction::Trunc, /*Dst=*/DstVecTy,
5775 /*Src=*/PromDstVecTy,
5777 return PromotionCost + getReplicationShuffleCost(PromEltTy,
5778 ReplicationFactor, VF,
5779 DemandedDstElts, CostKind);
5780 }
5781
5782 assert(LegalSrcVecTy.getScalarSizeInBits() == EltTyBits &&
5783 LegalSrcVecTy.getScalarType() == LegalDstVecTy.getScalarType() &&
5784 "We expect that the legalization doesn't affect the element width, "
5785 "doesn't coalesce/split elements.");
5786
5787 unsigned NumEltsPerDstVec = LegalDstVecTy.getVectorNumElements();
5788 unsigned NumDstVectors =
5789 divideCeil(DstVecTy->getNumElements(), NumEltsPerDstVec);
5790
5791 auto *SingleDstVecTy = FixedVectorType::get(EltTy, NumEltsPerDstVec);
5792
5793 // Not all the produced Dst elements may be demanded. In our case,
5794 // given that a single Dst vector is formed by a single shuffle,
5795 // if all elements that will form a single Dst vector aren't demanded,
5796 // then we won't need to do that shuffle, so adjust the cost accordingly.
5797 APInt DemandedDstVectors = APIntOps::ScaleBitMask(
5798 DemandedDstElts.zext(NumDstVectors * NumEltsPerDstVec), NumDstVectors);
5799 unsigned NumDstVectorsDemanded = DemandedDstVectors.popcount();
5800
5801 InstructionCost SingleShuffleCost =
5802 getShuffleCost(TTI::SK_PermuteSingleSrc, SingleDstVecTy, SingleDstVecTy,
5803 CostKind, /*Mask=*/{},
5804 /*Index=*/0, /*SubTp=*/nullptr);
5805 return NumDstVectorsDemanded * SingleShuffleCost;
5806}
5807
5809 Align Alignment,
5810 unsigned AddressSpace,
5812 TTI::OperandValueInfo OpInfo,
5813 const Instruction *I) const {
5814 // FIXME: Load latency isn't handled here
5815 if (Opcode == Instruction::Load && CostKind == TTI::TCK_Latency)
5816 return BaseT::getMemoryOpCost(Opcode, Src, Alignment, AddressSpace,
5817 CostKind, OpInfo, I);
5818
5819 // TODO: Handle other cost kinds.
5821 if (auto *SI = dyn_cast_or_null<StoreInst>(I)) {
5822 // Store instruction with index and scale costs 2 Uops.
5823 // Check the preceding GEP to identify non-const indices.
5824 if (auto *GEP = dyn_cast<GetElementPtrInst>(SI->getPointerOperand())) {
5825 if (!all_of(GEP->indices(), [](Value *V) { return isa<Constant>(V); }))
5826 return TTI::TCC_Basic * 2;
5827 }
5828 }
5829 return TTI::TCC_Basic;
5830 }
5831
5832 assert((Opcode == Instruction::Load || Opcode == Instruction::Store) &&
5833 "Invalid Opcode");
5834 // Type legalization can't handle structs
5835 if (TLI->getValueType(DL, Src, true) == MVT::Other)
5836 return BaseT::getMemoryOpCost(Opcode, Src, Alignment, AddressSpace,
5837 CostKind, OpInfo, I);
5838
5839 // Legalize the type.
5840 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Src);
5841
5842 auto *VTy = dyn_cast<FixedVectorType>(Src);
5843
5845
5846 // Add a cost for constant load to vector.
5847 if (Opcode == Instruction::Store && OpInfo.isConstant())
5848 Cost += getMemoryOpCost(Instruction::Load, Src, DL.getABITypeAlign(Src),
5849 /*AddressSpace=*/0, CostKind, OpInfo);
5850
5851 // Handle the simple case of non-vectors.
5852 // NOTE: this assumes that legalization never creates vector from scalars!
5853 if (!VTy || !LT.second.isVector()) {
5854 // Each load/store unit costs 1.
5855 return (LT.second.isFloatingPoint() ? Cost : 0) + LT.first * 1;
5856 }
5857
5858 bool IsLoad = Opcode == Instruction::Load;
5859
5860 Type *EltTy = VTy->getElementType();
5861
5862 const int EltTyBits = DL.getTypeSizeInBits(EltTy);
5863
5864 // Source of truth: how many elements were there in the original IR vector?
5865 const unsigned SrcNumElt = VTy->getNumElements();
5866
5867 // How far have we gotten?
5868 int NumEltRemaining = SrcNumElt;
5869 // Note that we intentionally capture by-reference, NumEltRemaining changes.
5870 auto NumEltDone = [&]() { return SrcNumElt - NumEltRemaining; };
5871
5872 const int MaxLegalOpSizeBytes = divideCeil(LT.second.getSizeInBits(), 8);
5873
5874 // Note that even if we can store 64 bits of an XMM, we still operate on XMM.
5875 const unsigned XMMBits = 128;
5876 if (XMMBits % EltTyBits != 0)
5877 // Vector size must be a multiple of the element size. I.e. no padding.
5878 return BaseT::getMemoryOpCost(Opcode, Src, Alignment, AddressSpace,
5879 CostKind, OpInfo, I);
5880 const int NumEltPerXMM = XMMBits / EltTyBits;
5881
5882 auto *XMMVecTy = FixedVectorType::get(EltTy, NumEltPerXMM);
5883
5884 for (int CurrOpSizeBytes = MaxLegalOpSizeBytes, SubVecEltsLeft = 0;
5885 NumEltRemaining > 0; CurrOpSizeBytes /= 2) {
5886 // How many elements would a single op deal with at once?
5887 if ((8 * CurrOpSizeBytes) % EltTyBits != 0)
5888 // Vector size must be a multiple of the element size. I.e. no padding.
5889 return BaseT::getMemoryOpCost(Opcode, Src, Alignment, AddressSpace,
5890 CostKind, OpInfo, I);
5891 int CurrNumEltPerOp = (8 * CurrOpSizeBytes) / EltTyBits;
5892
5893 assert(CurrOpSizeBytes > 0 && CurrNumEltPerOp > 0 && "How'd we get here?");
5894 assert((((NumEltRemaining * EltTyBits) < (2 * 8 * CurrOpSizeBytes)) ||
5895 (CurrOpSizeBytes == MaxLegalOpSizeBytes)) &&
5896 "Unless we haven't halved the op size yet, "
5897 "we have less than two op's sized units of work left.");
5898
5899 auto *CurrVecTy = CurrNumEltPerOp > NumEltPerXMM
5900 ? FixedVectorType::get(EltTy, CurrNumEltPerOp)
5901 : XMMVecTy;
5902
5903 assert(CurrVecTy->getNumElements() % CurrNumEltPerOp == 0 &&
5904 "After halving sizes, the vector elt count is no longer a multiple "
5905 "of number of elements per operation?");
5906 auto *CoalescedVecTy =
5907 CurrNumEltPerOp == 1
5908 ? CurrVecTy
5910 IntegerType::get(Src->getContext(),
5911 EltTyBits * CurrNumEltPerOp),
5912 CurrVecTy->getNumElements() / CurrNumEltPerOp);
5913 assert(DL.getTypeSizeInBits(CoalescedVecTy) ==
5914 DL.getTypeSizeInBits(CurrVecTy) &&
5915 "coalesciing elements doesn't change vector width.");
5916
5917 while (NumEltRemaining > 0) {
5918 assert(SubVecEltsLeft >= 0 && "Subreg element count overconsumtion?");
5919
5920 // Can we use this vector size, as per the remaining element count?
5921 // Iff the vector is naturally aligned, we can do a wide load regardless.
5922 if (NumEltRemaining < CurrNumEltPerOp &&
5923 (!IsLoad || Alignment < CurrOpSizeBytes) && CurrOpSizeBytes != 1)
5924 break; // Try smalled vector size.
5925
5926 // This isn't exactly right. We're using slow unaligned 32-byte accesses
5927 // as a proxy for a double-pumped AVX memory interface such as on
5928 // Sandybridge.
5929 // Sub-32-bit loads/stores will be slower either with PINSR*/PEXTR* or
5930 // will be scalarized.
5931 if (CurrOpSizeBytes == 32 && ST->isUnalignedMem32Slow())
5932 Cost += 2;
5933 else if (CurrOpSizeBytes < 4)
5934 Cost += 2;
5935 else
5936 Cost += 1;
5937
5938 // If we're loading a uniform value, then we don't need to split the load,
5939 // loading just a single (widest) vector can be reused by all splits.
5940 if (IsLoad && OpInfo.isUniform())
5941 return Cost;
5942
5943 bool Is0thSubVec = (NumEltDone() % LT.second.getVectorNumElements()) == 0;
5944
5945 // If we have fully processed the previous reg, we need to replenish it.
5946 if (SubVecEltsLeft == 0) {
5947 SubVecEltsLeft += CurrVecTy->getNumElements();
5948 // And that's free only for the 0'th subvector of a legalized vector.
5949 if (!Is0thSubVec)
5950 Cost +=
5953 VTy, VTy, CostKind, {}, NumEltDone(), CurrVecTy);
5954 }
5955
5956 // While we can directly load/store ZMM, YMM, and 64-bit halves of XMM,
5957 // for smaller widths (32/16/8) we have to insert/extract them separately.
5958 // Again, it's free for the 0'th subreg (if op is 32/64 bit wide,
5959 // but let's pretend that it is also true for 16/8 bit wide ops...)
5960 if (CurrOpSizeBytes <= 32 / 8 && !Is0thSubVec) {
5961 int NumEltDoneInCurrXMM = NumEltDone() % NumEltPerXMM;
5962 assert(NumEltDoneInCurrXMM % CurrNumEltPerOp == 0 && "");
5963 int CoalescedVecEltIdx = NumEltDoneInCurrXMM / CurrNumEltPerOp;
5964 APInt DemandedElts =
5965 APInt::getBitsSet(CoalescedVecTy->getNumElements(),
5966 CoalescedVecEltIdx, CoalescedVecEltIdx + 1);
5967 assert(DemandedElts.popcount() == 1 && "Inserting single value");
5968 Cost += getScalarizationOverhead(CoalescedVecTy, DemandedElts, IsLoad,
5969 !IsLoad, CostKind);
5970 }
5971
5972 SubVecEltsLeft -= CurrNumEltPerOp;
5973 NumEltRemaining -= CurrNumEltPerOp;
5974 Alignment = commonAlignment(Alignment, CurrOpSizeBytes);
5975 }
5976 }
5977
5978 assert(NumEltRemaining <= 0 && "Should have processed all the elements.");
5979
5980 return Cost;
5981}
5982
5986 switch (MICA.getID()) {
5987 case Intrinsic::masked_scatter:
5988 case Intrinsic::masked_gather:
5989 return getGatherScatterOpCost(MICA, CostKind);
5990 case Intrinsic::masked_load:
5991 case Intrinsic::masked_store:
5992 return getMaskedMemoryOpCost(MICA, CostKind);
5993 }
5995}
5996
6000 unsigned Opcode = MICA.getID() == Intrinsic::masked_load ? Instruction::Load
6001 : Instruction::Store;
6002 Type *SrcTy = MICA.getDataType();
6003 Align Alignment = MICA.getAlignment();
6004 unsigned AddressSpace = MICA.getAddressSpace();
6005
6006 bool IsLoad = (Instruction::Load == Opcode);
6007 bool IsStore = (Instruction::Store == Opcode);
6008
6009 auto *SrcVTy = dyn_cast<FixedVectorType>(SrcTy);
6010 if (!SrcVTy)
6011 // To calculate scalar take the regular cost, without mask
6012 return getMemoryOpCost(Opcode, SrcTy, Alignment, AddressSpace, CostKind);
6013
6014 unsigned NumElem = SrcVTy->getNumElements();
6015 auto *MaskTy =
6016 FixedVectorType::get(Type::getInt8Ty(SrcVTy->getContext()), NumElem);
6017 if ((IsLoad && !isLegalMaskedLoad(SrcVTy, Alignment, AddressSpace)) ||
6018 (IsStore && !isLegalMaskedStore(SrcVTy, Alignment, AddressSpace))) {
6019 // Scalarization
6020 APInt DemandedElts = APInt::getAllOnes(NumElem);
6022 MaskTy, DemandedElts, /*Insert*/ false, /*Extract*/ true, CostKind);
6023 InstructionCost ScalarCompareCost = getCmpSelInstrCost(
6024 Instruction::ICmp, Type::getInt8Ty(SrcVTy->getContext()), nullptr,
6026 InstructionCost BranchCost = getCFInstrCost(Instruction::CondBr, CostKind);
6027 InstructionCost MaskCmpCost = NumElem * (BranchCost + ScalarCompareCost);
6029 SrcVTy, DemandedElts, IsLoad, IsStore, CostKind);
6030 InstructionCost MemopCost =
6031 NumElem * BaseT::getMemoryOpCost(Opcode, SrcVTy->getScalarType(),
6032 Alignment, AddressSpace, CostKind);
6033 return MemopCost + ValueSplitCost + MaskSplitCost + MaskCmpCost;
6034 }
6035
6036 // Legalize the type.
6037 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(SrcVTy);
6038 auto VT = TLI->getValueType(DL, SrcVTy);
6040 MVT Ty = LT.second;
6041 if (Ty == MVT::i16 || Ty == MVT::i32 || Ty == MVT::i64)
6042 // APX masked load/store for scalar is cheap.
6043 return Cost + LT.first;
6044
6045 if (VT.isSimple() && Ty != VT.getSimpleVT() &&
6046 LT.second.getVectorNumElements() == NumElem)
6047 // Promotion requires extend/truncate for data and a shuffle for mask.
6048 Cost += getShuffleCost(TTI::SK_PermuteTwoSrc, SrcVTy, SrcVTy, CostKind, {},
6049 0, nullptr) +
6050 getShuffleCost(TTI::SK_PermuteTwoSrc, MaskTy, MaskTy, CostKind, {},
6051 0, nullptr);
6052
6053 else if (LT.first * Ty.getVectorNumElements() > NumElem) {
6054 auto *NewMaskTy = FixedVectorType::get(MaskTy->getElementType(),
6055 (unsigned)LT.first.getValue() *
6056 Ty.getVectorNumElements());
6057 // Expanding requires fill mask with zeroes
6058 Cost += getShuffleCost(TTI::SK_InsertSubvector, NewMaskTy, NewMaskTy,
6059 CostKind, {}, 0, MaskTy);
6060 }
6061
6062 // Pre-AVX512 - each maskmov load costs 2 + store costs ~8.
6063 if (!ST->hasAVX512())
6064 return Cost + LT.first * (IsLoad ? 2 : 8);
6065
6066 // AVX-512 masked load/store is cheaper
6067 return Cost + LT.first;
6068}
6069
6071 ArrayRef<const Value *> Ptrs, const Value *Base,
6072 const TTI::PointersChainInfo &Info, Type *AccessTy,
6073 const TTI::TargetCostKind CostKind) const {
6074 if (Info.isSameBase() && Info.isKnownStride()) {
6075 // If all the pointers have known stride all the differences are translated
6076 // into constants. X86 memory addressing allows encoding it into
6077 // displacement. So we just need to take the base GEP cost.
6078 if (const auto *BaseGEP = dyn_cast<GetElementPtrInst>(Base)) {
6079 SmallVector<const Value *> Indices(BaseGEP->indices());
6080 return getGEPCost(BaseGEP->getSourceElementType(),
6081 BaseGEP->getPointerOperand(), Indices, CostKind,
6082 nullptr);
6083 }
6084 return TTI::TCC_Free;
6085 }
6086 return BaseT::getPointersChainCost(Ptrs, Base, Info, AccessTy, CostKind);
6087}
6088
6091 const SCEV *Ptr,
6093 // Address computations in vectorized code with non-consecutive addresses will
6094 // likely result in more instructions compared to scalar code where the
6095 // computation can more often be merged into the index mode. The resulting
6096 // extra micro-ops can significantly decrease throughput.
6097 const unsigned NumVectorInstToHideOverhead = 10;
6098
6099 // Cost modeling of Strided Access Computation is hidden by the indexing
6100 // modes of X86 regardless of the stride value. We dont believe that there
6101 // is a difference between constant strided access in gerenal and constant
6102 // strided value which is less than or equal to 64.
6103 // Even in the case of (loop invariant) stride whose value is not known at
6104 // compile time, the address computation will not incur more than one extra
6105 // ADD instruction.
6106 if (PtrTy->isVectorTy() && SE) {
6108 return 1;
6109 if (!ST->hasAVX2()) {
6110 // TODO: AVX2 is the current cut-off because we don't have correct
6111 // interleaving costs for prior ISA's.
6112 if (!BaseT::isStridedAccess(Ptr))
6113 return NumVectorInstToHideOverhead;
6114 }
6115 }
6116
6117 return BaseT::getAddressComputationCost(PtrTy, SE, Ptr, CostKind);
6118}
6119
6121 unsigned Opcode, Type *InputTypeA, Type *InputTypeB, Type *AccumType,
6123 TTI::PartialReductionExtendKind OpBExtend, std::optional<unsigned> BinOp,
6124 TTI::TargetCostKind CostKind, std::optional<FastMathFlags> FMF) const {
6125 auto ExpandCost = [&]() {
6126 return BaseT::getPartialReductionCost(Opcode, InputTypeA, InputTypeB,
6127 AccumType, VF, OpAExtend, OpBExtend,
6128 BinOp, CostKind, FMF);
6129 };
6130
6131 // The dot product instructions multiply-accumulate i8 x i8 -> i32,
6132 // i16 x i16 -> i32, bf16 x bf16 -> f32 or f16 x f16 -> f32. Partial
6133 // reductions may also multiply inputs extended from different types, which
6134 // they can't handle.
6135 if (VF.isScalable() || !BinOp || OpAExtend == TTI::PR_None ||
6136 OpBExtend == TTI::PR_None || InputTypeA != InputTypeB)
6137 return ExpandCost();
6138
6139 unsigned Opc;
6140 if (Opcode == Instruction::Add && *BinOp == Instruction::Mul &&
6141 AccumType->isIntegerTy(32) &&
6142 (InputTypeA->isIntegerTy(8) || InputTypeA->isIntegerTy(16))) {
6143 if (OpAExtend != OpBExtend)
6145 else if (OpAExtend == TTI::PR_SignExtend)
6147 else
6149 } else if (Opcode == Instruction::FAdd && *BinOp == Instruction::FMul &&
6150 AccumType->isFloatTy() &&
6151 (InputTypeA->isBFloatTy() || InputTypeA->isHalfTy())) {
6152 // VDPBF16PS and VDPPHPS, like the expansion, reassociate the additions and
6153 // fuse the multiplications.
6154 if (!FMF || !FMF->allowReassoc() || !FMF->allowContract())
6157 } else {
6158 return ExpandCost();
6159 }
6160
6161 unsigned Ratio =
6162 AccumType->getScalarSizeInBits() / InputTypeA->getScalarSizeInBits();
6163 if (!VF.isKnownMultipleOf(Ratio))
6164 return ExpandCost();
6165
6166 // One dot product per legal accumulator vector. Accumulators narrower than
6167 // a legal vector are widened by expanding the partial reduction instead.
6168 auto *AccVecTy = VectorType::get(AccumType, VF.divideCoefficientBy(Ratio));
6169 auto *InputVecTy = VectorType::get(InputTypeA, VF);
6170 std::pair<InstructionCost, MVT> AccLT = getTypeLegalizationCost(AccVecTy);
6171 std::pair<InstructionCost, MVT> InputLT = getTypeLegalizationCost(InputVecTy);
6172 if (AccLT.second.getFixedSizeInBits() >
6173 AccVecTy->getPrimitiveSizeInBits().getFixedValue() ||
6174 !TLI->isPartialReduceMLALegalOrCustom(Opc, AccLT.second, InputLT.second))
6175 return ExpandCost();
6176
6177 return AccLT.first;
6178}
6179
6182 std::optional<FastMathFlags> FMF,
6185 return BaseT::getArithmeticReductionCost(Opcode, ValTy, FMF, CostKind);
6186
6187 // We use llvm-mca across all supported CPUs to measure the logic cost stats.
6188 // We use the Intel Architecture Code Analyzer(IACA) to measure the throughput
6189 // and make it as the cost. TODO: Update old IACA numbers to llvm-mca.
6190
6191 static const CostKindTblEntry SLMCostTbl[] = {
6192 { ISD::FADD, MVT::v2f64, {3, 3, 3, 3} },
6193 { ISD::ADD, MVT::v2i64, {5, 5, 5, 5} },
6194 };
6195
6196 static const CostKindTblEntry SSE2CostTbl[] = {
6197 { ISD::FADD, MVT::v2f64, {2, 2, 2, 2} },
6198 { ISD::FADD, MVT::v2f32, {2, 2, 2, 2} },
6199 { ISD::FADD, MVT::v4f32, {4, 4, 4, 4} },
6200 { ISD::ADD, MVT::v2i64, {2, 2, 2, 2} }, // The data reported by the IACA tool is "1.6".
6201 { ISD::ADD, MVT::v2i32, {2, 2, 2, 2} }, // FIXME: chosen to be less than v4i32
6202 { ISD::ADD, MVT::v4i32, {3, 3, 3, 3} }, // The data reported by the IACA tool is "3.3".
6203 { ISD::ADD, MVT::v2i16, {2, 2, 2, 2} }, // The data reported by the IACA tool is "4.3".
6204 { ISD::ADD, MVT::v4i16, {3, 3, 3, 3} }, // The data reported by the IACA tool is "4.3".
6205 { ISD::ADD, MVT::v8i16, {4, 4, 4, 4} }, // The data reported by the IACA tool is "4.3".
6206 { ISD::ADD, MVT::v2i8, {2, 2, 2, 2} },
6207 { ISD::ADD, MVT::v4i8, {2, 2, 2, 2} },
6208 { ISD::ADD, MVT::v8i8, {2, 2, 2, 2} },
6209 { ISD::ADD, MVT::v16i8, {3, 3, 3, 3} },
6210
6211 { ISD::AND, MVT::v2i64, {2, 2, 3, 3} },
6212 { ISD::AND, MVT::v4i32, {3, 4, 5, 5} },
6213 { ISD::AND, MVT::v8i16, {4, 7, 8, 8} },
6214 { ISD::AND, MVT::v16i8, {6,10,11,11} },
6215 { ISD::OR, MVT::v2i64, {2, 2, 3, 3} },
6216 { ISD::OR, MVT::v4i32, {3, 4, 5, 5} },
6217 { ISD::OR, MVT::v8i16, {4, 7, 8, 8} },
6218 { ISD::OR, MVT::v16i8, {6,10,11,11} },
6219 { ISD::XOR, MVT::v2i64, {2, 2, 3, 3} },
6220 { ISD::XOR, MVT::v4i32, {3, 4, 5, 5} },
6221 { ISD::XOR, MVT::v8i16, {4, 7, 8, 8} },
6222 { ISD::XOR, MVT::v16i8, {6,10,11,11} },
6223 };
6224
6225 static const CostKindTblEntry AVX1CostTbl[] = {
6226 { ISD::FADD, MVT::v4f64, {3, 3, 3, 3} },
6227 { ISD::FADD, MVT::v4f32, {3, 3, 3, 3} },
6228 { ISD::FADD, MVT::v8f32, {4, 4, 4, 4} },
6229 { ISD::ADD, MVT::v2i64, {1, 1, 1, 1} }, // The data reported by the IACA tool is "1.5".
6230 { ISD::ADD, MVT::v4i64, {3, 3, 3, 3} },
6231 { ISD::ADD, MVT::v8i32, {5, 5, 5, 5} },
6232 { ISD::ADD, MVT::v16i16, {5, 5, 5, 5} },
6233 { ISD::ADD, MVT::v32i8, {4, 4, 4, 4} },
6234
6235 { ISD::AND, MVT::v4i64, {3, 7, 5, 5} },
6236 { ISD::AND, MVT::v8i32, {4, 9, 7, 7} },
6237 { ISD::AND, MVT::v16i16, {5,11, 9, 9} },
6238 { ISD::AND, MVT::v8i16, {4, 7, 7, 7} },
6239 { ISD::AND, MVT::v32i8, {6,13,11,11} },
6240 { ISD::AND, MVT::v16i8, {5,10, 9, 9} },
6241 { ISD::OR, MVT::v4i64, {3, 7, 5, 5} },
6242 { ISD::OR, MVT::v8i32, {4, 9, 7, 7} },
6243 { ISD::OR, MVT::v16i16, {5,11, 9, 9} },
6244 { ISD::OR, MVT::v8i16, {4, 7, 7, 7} },
6245 { ISD::OR, MVT::v32i8, {6,13,11,11} },
6246 { ISD::OR, MVT::v16i8, {5,10, 9, 9} },
6247 { ISD::XOR, MVT::v4i64, {3, 7, 5, 5} },
6248 { ISD::XOR, MVT::v8i32, {4, 9, 7, 7} },
6249 { ISD::XOR, MVT::v16i16, {5,11, 9, 9} },
6250 { ISD::XOR, MVT::v8i16, {4, 7, 7, 7} },
6251 { ISD::XOR, MVT::v32i8, {6,13,11,11} },
6252 { ISD::XOR, MVT::v16i8, {5,10, 9, 9} },
6253 };
6254
6255 static const CostKindTblEntry AVX2CostTbl[] = {
6256 { ISD::AND, MVT::v4i64, {2, 7, 5, 5} },
6257 { ISD::AND, MVT::v2i64, {1, 2, 3, 3} },
6258 { ISD::AND, MVT::v8i32, {3, 9, 7, 7} },
6259 { ISD::AND, MVT::v4i32, {2, 4, 5, 5} },
6260 { ISD::AND, MVT::v16i16, {3,11, 9, 9} },
6261 { ISD::AND, MVT::v8i16, {2, 6, 7, 7} },
6262 { ISD::AND, MVT::v32i8, {3,13,11,11} },
6263 { ISD::AND, MVT::v16i8, {3, 8, 9, 9} },
6264 { ISD::OR, MVT::v4i64, {2, 7, 5, 5} },
6265 { ISD::OR, MVT::v2i64, {1, 2, 3, 3} },
6266 { ISD::OR, MVT::v8i32, {3, 9, 7, 7} },
6267 { ISD::OR, MVT::v4i32, {2, 4, 5, 5} },
6268 { ISD::OR, MVT::v16i16, {3,11, 9, 9} },
6269 { ISD::OR, MVT::v8i16, {2, 6, 7, 7} },
6270 { ISD::OR, MVT::v32i8, {3,13,11,11} },
6271 { ISD::OR, MVT::v16i8, {3, 8, 9, 9} },
6272 { ISD::XOR, MVT::v4i64, {2, 7, 5, 5} },
6273 { ISD::XOR, MVT::v2i64, {1, 2, 3, 3} },
6274 { ISD::XOR, MVT::v8i32, {3, 9, 7, 7} },
6275 { ISD::XOR, MVT::v4i32, {2, 4, 5, 5} },
6276 { ISD::XOR, MVT::v16i16, {3,11, 9, 9} },
6277 { ISD::XOR, MVT::v8i16, {2, 6, 7, 7} },
6278 { ISD::XOR, MVT::v32i8, {3,13,11,11} },
6279 { ISD::XOR, MVT::v16i8, {3, 8, 9, 9} },
6280 };
6281
6282 static const CostKindTblEntry AVX512FCostTbl[] = {
6283 { ISD::FADD, MVT::v8f64, {4, 4, 4, 4} },
6284 { ISD::FADD, MVT::v16f32, {5, 5, 5, 5} },
6285 { ISD::ADD, MVT::v8i64, {4, 4, 4, 4} },
6286 { ISD::ADD, MVT::v16i32, {6, 6, 6, 6} },
6287
6288 { ISD::AND, MVT::v8i64, {3,10, 7, 7} },
6289 { ISD::AND, MVT::v16i32, {4,12, 9, 9} },
6290 { ISD::AND, MVT::v32i16, {4,14,11,11} },
6291 { ISD::AND, MVT::v64i8, {4,16,13,13} },
6292 { ISD::AND, MVT::v16i8, {2, 8, 9, 9} },
6293 { ISD::OR, MVT::v8i64, {3,10, 7, 7} },
6294 { ISD::OR, MVT::v16i32, {4,12, 9, 9} },
6295 { ISD::OR, MVT::v32i16, {4,14,11,11} },
6296 { ISD::OR, MVT::v64i8, {4,16,13,13} },
6297 { ISD::OR, MVT::v16i8, {2, 8, 9, 9} },
6298 { ISD::XOR, MVT::v8i64, {3,10, 7, 7} },
6299 { ISD::XOR, MVT::v16i32, {4,12, 9, 9} },
6300 { ISD::XOR, MVT::v32i16, {4,14,11,11} },
6301 { ISD::XOR, MVT::v64i8, {4,16,13,13} },
6302 { ISD::XOR, MVT::v16i8, {2, 8, 9, 9} },
6303 };
6304
6305 static const CostKindTblEntry AVX512BWCostTbl[] = {
6306 { ISD::ADD, MVT::v32i16, {7, 7, 7, 7} },
6307 { ISD::ADD, MVT::v64i8, {4, 4, 4, 4} },
6308 };
6309
6310 int ISD = TLI->InstructionOpcodeToISD(Opcode);
6311 assert(ISD && "Invalid opcode");
6312
6313 // Before legalizing the type, give a chance to look up illegal narrow types
6314 // in the table.
6315 // FIXME: Is there a better way to do this?
6316 EVT VT = TLI->getValueType(DL, ValTy);
6317 if (VT.isSimple()) {
6318 MVT MTy = VT.getSimpleVT();
6319 if (ST->useSLMArithCosts())
6320 if (const auto *Entry = CostTableLookup(SLMCostTbl, ISD, MTy))
6321 if (auto KindCost = Entry->Cost[CostKind])
6322 return *KindCost;
6323
6324 if (ST->hasBWI())
6325 if (const auto *Entry = CostTableLookup(AVX512BWCostTbl, ISD, MTy))
6326 if (auto KindCost = Entry->Cost[CostKind])
6327 return *KindCost;
6328
6329 if (ST->hasAVX512())
6330 if (const auto *Entry = CostTableLookup(AVX512FCostTbl, ISD, MTy))
6331 if (auto KindCost = Entry->Cost[CostKind])
6332 return *KindCost;
6333
6334 if (ST->hasAVX2())
6335 if (const auto *Entry = CostTableLookup(AVX2CostTbl, ISD, MTy))
6336 if (auto KindCost = Entry->Cost[CostKind])
6337 return *KindCost;
6338
6339 if (ST->hasAVX())
6340 if (const auto *Entry = CostTableLookup(AVX1CostTbl, ISD, MTy))
6341 if (auto KindCost = Entry->Cost[CostKind])
6342 return *KindCost;
6343
6344 if (ST->hasSSE2())
6345 if (const auto *Entry = CostTableLookup(SSE2CostTbl, ISD, MTy))
6346 if (auto KindCost = Entry->Cost[CostKind])
6347 return *KindCost;
6348 }
6349
6350 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(ValTy);
6351
6352 MVT MTy = LT.second;
6353
6354 auto *ValVTy = cast<FixedVectorType>(ValTy);
6355
6356 InstructionCost ArithmeticCost = 0;
6357 if (LT.first != 1 && MTy.isVector() &&
6358 MTy.getVectorNumElements() < ValVTy->getNumElements()) {
6359 // Type needs to be split. We need LT.first - 1 arithmetic ops.
6360 auto *SingleOpTy = FixedVectorType::get(ValVTy->getElementType(),
6361 MTy.getVectorNumElements());
6362 ArithmeticCost = getArithmeticInstrCost(Opcode, SingleOpTy, CostKind);
6363 ArithmeticCost *= LT.first - 1;
6364 }
6365
6366 // FIXME: These assume a naive kshift+binop lowering, which is probably
6367 // conservative in most cases.
6368 static const CostKindTblEntry AVX512BoolReduction[] = {
6369 { ISD::AND, MVT::v2i1, { 3, 3, 3, 3} },
6370 { ISD::AND, MVT::v4i1, { 5, 5, 5, 5} },
6371 { ISD::AND, MVT::v8i1, { 7, 7, 7, 7} },
6372 { ISD::AND, MVT::v16i1, { 9, 9, 9, 9} },
6373 { ISD::AND, MVT::v32i1, {11,11,11,11} },
6374 { ISD::AND, MVT::v64i1, {13,13,13,13} },
6375 { ISD::OR, MVT::v2i1, { 3, 3, 3, 3} },
6376 { ISD::OR, MVT::v4i1, { 5, 5, 5, 5} },
6377 { ISD::OR, MVT::v8i1, { 7, 7, 7, 7} },
6378 { ISD::OR, MVT::v16i1, { 9, 9, 9, 9} },
6379 { ISD::OR, MVT::v32i1, {11,11,11,11} },
6380 { ISD::OR, MVT::v64i1, {13,13,13,13} },
6381 };
6382
6383 static const CostKindTblEntry AVX2BoolReduction[] = {
6384 { ISD::AND, MVT::v16i16, { 2, 2, 2, 2} }, // vpmovmskb + cmp
6385 { ISD::AND, MVT::v32i8, { 2, 2, 2, 2} }, // vpmovmskb + cmp
6386 { ISD::OR, MVT::v16i16, { 2, 2, 2, 2} }, // vpmovmskb + cmp
6387 { ISD::OR, MVT::v32i8, { 2, 2, 2, 2} }, // vpmovmskb + cmp
6388 };
6389
6390 static const CostKindTblEntry AVX1BoolReduction[] = {
6391 { ISD::AND, MVT::v4i64, {2, 2, 2, 2} }, // vmovmskpd + cmp
6392 { ISD::AND, MVT::v8i32, {2, 2, 2, 2} }, // vmovmskps + cmp
6393 { ISD::AND, MVT::v16i16, {4, 4, 4, 4} }, // vextractf128 + vpand + vpmovmskb + cmp
6394 { ISD::AND, MVT::v32i8, {4, 4, 4, 4} }, // vextractf128 + vpand + vpmovmskb + cmp
6395 { ISD::OR, MVT::v4i64, {2, 2, 2, 2} }, // vmovmskpd + cmp
6396 { ISD::OR, MVT::v8i32, {2, 2, 2, 2} }, // vmovmskps + cmp
6397 { ISD::OR, MVT::v16i16, {4, 4, 4, 4} }, // vextractf128 + vpor + vpmovmskb + cmp
6398 { ISD::OR, MVT::v32i8, {4, 4, 4, 4} }, // vextractf128 + vpor + vpmovmskb + cmp
6399 };
6400
6401 static const CostKindTblEntry SSE2BoolReduction[] = {
6402 { ISD::AND, MVT::v2i64, {2, 2, 2, 2} }, // movmskpd + cmp
6403 { ISD::AND, MVT::v4i32, {2, 2, 2, 2} }, // movmskps + cmp
6404 { ISD::AND, MVT::v8i16, {2, 2, 2, 2} }, // pmovmskb + cmp
6405 { ISD::AND, MVT::v16i8, {2, 2, 2, 2} }, // pmovmskb + cmp
6406 { ISD::OR, MVT::v2i64, {2, 2, 2, 2} }, // movmskpd + cmp
6407 { ISD::OR, MVT::v4i32, {2, 2, 2, 2} }, // movmskps + cmp
6408 { ISD::OR, MVT::v8i16, {2, 2, 2, 2} }, // pmovmskb + cmp
6409 { ISD::OR, MVT::v16i8, {2, 2, 2, 2} }, // pmovmskb + cmp
6410 };
6411
6412 // Handle bool allof/anyof vXi1 patterns before we check legal types.
6413 if (ValVTy->getElementType()->isIntegerTy(1)) {
6414 if (ISD == ISD::ADD) {
6415 // vXi1 addition reduction will bitcast to scalar and perform a popcount.
6416 auto *IntTy = IntegerType::getIntNTy(ValVTy->getContext(),
6417 ValVTy->getNumElements());
6418 IntrinsicCostAttributes ICA(Intrinsic::ctpop, IntTy, {IntTy});
6419 return getCastInstrCost(Instruction::BitCast, IntTy, ValVTy,
6421 CostKind) +
6423 }
6424
6425 if (ST->hasAVX512())
6426 if (const auto *Entry = CostTableLookup(AVX512BoolReduction, ISD, MTy))
6427 if (auto KindCost = Entry->Cost[CostKind])
6428 return ArithmeticCost + *KindCost;
6429 if (ST->hasAVX2())
6430 if (const auto *Entry = CostTableLookup(AVX2BoolReduction, ISD, MTy))
6431 if (auto KindCost = Entry->Cost[CostKind])
6432 return ArithmeticCost + *KindCost;
6433 if (ST->hasAVX())
6434 if (const auto *Entry = CostTableLookup(AVX1BoolReduction, ISD, MTy))
6435 if (auto KindCost = Entry->Cost[CostKind])
6436 return ArithmeticCost + *KindCost;
6437 if (ST->hasSSE2())
6438 if (const auto *Entry = CostTableLookup(SSE2BoolReduction, ISD, MTy))
6439 if (auto KindCost = Entry->Cost[CostKind])
6440 return ArithmeticCost + *KindCost;
6441
6442 return BaseT::getArithmeticReductionCost(Opcode, ValVTy, FMF, CostKind);
6443 }
6444
6445 // Special case: vXi8 mul reductions are performed as vXi16.
6446 if (ISD == ISD::MUL && MTy.getScalarType() == MVT::i8) {
6447 auto *WideSclTy = IntegerType::get(ValVTy->getContext(), 16);
6448 auto *WideVecTy = FixedVectorType::get(WideSclTy, ValVTy->getNumElements());
6449 return getCastInstrCost(Instruction::ZExt, WideVecTy, ValTy,
6451 CostKind) +
6452 getArithmeticReductionCost(Opcode, WideVecTy, FMF, CostKind);
6453 }
6454
6455 if (ST->useSLMArithCosts())
6456 if (const auto *Entry = CostTableLookup(SLMCostTbl, ISD, MTy))
6457 if (auto KindCost = Entry->Cost[CostKind])
6458 return ArithmeticCost + *KindCost;
6459
6460 if (ST->hasBWI())
6461 if (const auto *Entry = CostTableLookup(AVX512BWCostTbl, ISD, MTy))
6462 if (auto KindCost = Entry->Cost[CostKind])
6463 return ArithmeticCost + *KindCost;
6464
6465 if (ST->hasAVX512())
6466 if (const auto *Entry = CostTableLookup(AVX512FCostTbl, ISD, MTy))
6467 if (auto KindCost = Entry->Cost[CostKind])
6468 return ArithmeticCost + *KindCost;
6469
6470 if (ST->hasAVX2())
6471 if (const auto *Entry = CostTableLookup(AVX2CostTbl, ISD, MTy))
6472 if (auto KindCost = Entry->Cost[CostKind])
6473 return ArithmeticCost + *KindCost;
6474
6475 if (ST->hasAVX())
6476 if (const auto *Entry = CostTableLookup(AVX1CostTbl, ISD, MTy))
6477 if (auto KindCost = Entry->Cost[CostKind])
6478 return ArithmeticCost + *KindCost;
6479
6480 if (ST->hasSSE2())
6481 if (const auto *Entry = CostTableLookup(SSE2CostTbl, ISD, MTy))
6482 if (auto KindCost = Entry->Cost[CostKind])
6483 return ArithmeticCost + *KindCost;
6484
6485 unsigned NumVecElts = ValVTy->getNumElements();
6486 unsigned ScalarSize = ValVTy->getScalarSizeInBits();
6487
6488 // Special case power of 2 reductions where the scalar type isn't changed
6489 // by type legalization.
6490 if (!isPowerOf2_32(NumVecElts) || ScalarSize != MTy.getScalarSizeInBits())
6491 return BaseT::getArithmeticReductionCost(Opcode, ValVTy, FMF, CostKind);
6492
6493 InstructionCost ReductionCost = 0;
6494
6495 auto *Ty = ValVTy;
6496 if (LT.first != 1 && MTy.isVector() &&
6497 MTy.getVectorNumElements() < ValVTy->getNumElements()) {
6498 // Type needs to be split. We need LT.first - 1 arithmetic ops.
6499 Ty = FixedVectorType::get(ValVTy->getElementType(),
6500 MTy.getVectorNumElements());
6501 ReductionCost = getArithmeticInstrCost(Opcode, Ty, CostKind);
6502 ReductionCost *= LT.first - 1;
6503 NumVecElts = MTy.getVectorNumElements();
6504 }
6505
6506 // Now handle reduction with the legal type, taking into account size changes
6507 // at each level.
6508 while (NumVecElts > 1) {
6509 // Determine the size of the remaining vector we need to reduce.
6510 unsigned Size = NumVecElts * ScalarSize;
6511 NumVecElts /= 2;
6512 // If we're reducing from 256/512 bits, use an extract_subvector.
6513 if (Size > 128) {
6514 auto *SubTy = FixedVectorType::get(ValVTy->getElementType(), NumVecElts);
6515 ReductionCost += getShuffleCost(TTI::SK_ExtractSubvector, Ty, Ty,
6516 CostKind, {}, NumVecElts, SubTy);
6517 Ty = SubTy;
6518 } else if (Size == 128) {
6519 // Reducing from 128 bits is a permute of v2f64/v2i64.
6520 FixedVectorType *ShufTy;
6521 if (ValVTy->isFloatingPointTy())
6522 ShufTy =
6523 FixedVectorType::get(Type::getDoubleTy(ValVTy->getContext()), 2);
6524 else
6525 ShufTy =
6526 FixedVectorType::get(Type::getInt64Ty(ValVTy->getContext()), 2);
6527 ReductionCost += getShuffleCost(TTI::SK_PermuteSingleSrc, ShufTy, ShufTy,
6528 CostKind, {}, 0, nullptr);
6529 } else if (Size == 64) {
6530 // Reducing from 64 bits is a shuffle of v4f32/v4i32.
6531 FixedVectorType *ShufTy;
6532 if (ValVTy->isFloatingPointTy())
6533 ShufTy =
6534 FixedVectorType::get(Type::getFloatTy(ValVTy->getContext()), 4);
6535 else
6536 ShufTy =
6537 FixedVectorType::get(Type::getInt32Ty(ValVTy->getContext()), 4);
6538 ReductionCost += getShuffleCost(TTI::SK_PermuteSingleSrc, ShufTy, ShufTy,
6539 CostKind, {}, 0, nullptr);
6540 } else {
6541 // Reducing from smaller size is a shift by immediate.
6542 auto *ShiftTy = FixedVectorType::get(
6543 Type::getIntNTy(ValVTy->getContext(), Size), 128 / Size);
6544 ReductionCost += getArithmeticInstrCost(
6545 Instruction::LShr, ShiftTy, CostKind,
6548 }
6549
6550 // Add the arithmetic op for this level.
6551 ReductionCost += getArithmeticInstrCost(Opcode, Ty, CostKind);
6552 }
6553
6554 // Add the final extract element to the cost.
6555 return ReductionCost + getVectorInstrCost(Instruction::ExtractElement, Ty,
6556 CostKind, 0, nullptr, nullptr,
6558}
6559
6562 FastMathFlags FMF) const {
6563 IntrinsicCostAttributes ICA(IID, Ty, {Ty, Ty}, FMF);
6564 return getIntrinsicInstrCost(ICA, CostKind);
6565}
6566
6569 FastMathFlags FMF,
6571 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(ValTy);
6572
6573 MVT MTy = LT.second;
6574
6576 if (ValTy->isIntOrIntVectorTy()) {
6577 ISD = (IID == Intrinsic::umin || IID == Intrinsic::umax) ? ISD::UMIN
6578 : ISD::SMIN;
6579 } else {
6580 assert(ValTy->isFPOrFPVectorTy() &&
6581 "Expected float point or integer vector type.");
6582 ISD = (IID == Intrinsic::minnum || IID == Intrinsic::maxnum)
6583 ? ISD::FMINNUM
6584 : ISD::FMINIMUM;
6585 }
6586
6587 // We use llvm-mca across all supported CPUs to measure the cost stats.
6588 static const CostKindTblEntry SSE2CostTbl[] = {
6589 {ISD::SMIN, MVT::v2i64, {3, 4, 5, 6}},
6590 {ISD::UMIN, MVT::v2i64, {3, 4, 5, 6}},
6591 {ISD::SMIN, MVT::v2i32, {2, 2, 5, 6}},
6592 {ISD::UMIN, MVT::v2i32, {2, 2, 5, 6}},
6593 {ISD::SMIN, MVT::v4i32, {3, 7,11,12}},
6594 {ISD::UMIN, MVT::v4i32, {4, 7,14,15}},
6595 {ISD::SMIN, MVT::v2i16, {2, 3, 4, 4}},
6596 {ISD::UMIN, MVT::v2i16, {2, 3, 4, 6}},
6597 {ISD::SMIN, MVT::v4i16, {3, 5, 6, 6}},
6598 {ISD::UMIN, MVT::v4i16, {3, 5, 8, 10}},
6599 {ISD::SMIN, MVT::v8i16, {3, 8, 8, 8}},
6600 {ISD::UMIN, MVT::v8i16, {4, 8,12,14}},
6601 {ISD::SMIN, MVT::v2i8, {2, 3, 5, 6}},
6602 {ISD::UMIN, MVT::v2i8, {2, 3, 4, 4}},
6603 {ISD::SMIN, MVT::v4i8, {4, 6,12,13}},
6604 {ISD::UMIN, MVT::v4i8, {3, 6, 7, 7}},
6605 {ISD::SMIN, MVT::v8i8, {5, 9,18,19}},
6606 {ISD::UMIN, MVT::v8i8, {4, 8, 9, 9}},
6607 {ISD::SMIN, MVT::v16i8, {7,13,24,25}},
6608 {ISD::UMIN, MVT::v16i8, {3,10,11,11}},
6609 };
6610
6611 static const CostKindTblEntry SSE41CostTbl[] = {
6612 {ISD::SMIN, MVT::v2i64, {3, 4, 4, 6}},
6613 {ISD::UMIN, MVT::v2i64, {3, 4, 4, 6}},
6614 {ISD::SMIN, MVT::v2i32, {2, 2, 3, 3}},
6615 {ISD::UMIN, MVT::v2i32, {2, 2, 3, 3}},
6616 {ISD::SMIN, MVT::v4i32, {3, 4, 5, 5}},
6617 {ISD::UMIN, MVT::v4i32, {3, 4, 5, 5}},
6618 {ISD::UMIN, MVT::v2i16, {2, 3, 4, 4}},
6619 {ISD::SMIN, MVT::v4i16, {3, 5, 6, 6}},
6620 {ISD::UMIN, MVT::v4i16, {3, 5, 6, 6}},
6621 {ISD::SMIN, MVT::v8i16, {2, 8, 4, 5}},
6622 {ISD::UMIN, MVT::v8i16, {2, 5, 2, 2}},
6623 {ISD::SMIN, MVT::v2i8, {2, 3, 4, 4}},
6624 {ISD::SMIN, MVT::v4i8, {3, 6, 7, 7}},
6625 {ISD::SMIN, MVT::v8i8, {4, 8, 9, 9}},
6626 {ISD::SMIN, MVT::v16i8, {3,10, 7, 8}},
6627 {ISD::UMIN, MVT::v16i8, {3, 8, 5, 5}},
6628 };
6629
6630 static const CostKindTblEntry AVX1CostTbl[] = {
6631 {ISD::SMIN, MVT::v4i64, {5,11, 7,10}},
6632 {ISD::UMIN, MVT::v4i64, {6,12,10,13}},
6633 {ISD::SMIN, MVT::v8i32, {4, 9, 7, 7}},
6634 {ISD::UMIN, MVT::v8i32, {4, 9, 7, 7}},
6635 {ISD::SMIN, MVT::v16i16, {3,15, 6, 7}},
6636 {ISD::UMIN, MVT::v16i16, {2, 9, 4, 4}},
6637 {ISD::SMIN, MVT::v32i8, {4,17, 8, 9}},
6638 {ISD::UMIN, MVT::v32i8, {3,11, 6, 6}},
6639 };
6640
6641 static const CostKindTblEntry AVX2CostTbl[] = {
6642 {ISD::SMIN, MVT::v4i64, {4,11, 7,10}},
6643 {ISD::UMIN, MVT::v4i64, {4,12,10,13}},
6644 {ISD::SMIN, MVT::v2i32, {1, 2, 3, 3}},
6645 {ISD::UMIN, MVT::v2i32, {1, 2, 3, 3}},
6646 {ISD::UMIN, MVT::v4i32, {2, 4, 5, 5}},
6647 {ISD::SMIN, MVT::v4i32, {2, 4, 5, 5}},
6648 {ISD::SMIN, MVT::v8i32, {3, 9, 7, 7}},
6649 {ISD::UMIN, MVT::v8i32, {3, 9, 7, 7}},
6650 {ISD::SMIN, MVT::v4i16, {2, 4, 5, 5}},
6651 {ISD::UMIN, MVT::v4i16, {2, 4, 5, 5}},
6652 {ISD::SMIN, MVT::v16i16, {2,15, 6, 7}},
6653 {ISD::SMIN, MVT::v8i8, {3, 6, 7, 7}},
6654 {ISD::UMIN, MVT::v8i8, {3, 6, 7, 7}},
6655 {ISD::SMIN, MVT::v32i8, {3,17, 8, 9}},
6656 };
6657
6658 static const CostKindTblEntry AVX512FCostTbl[] = {
6659 {ISD::SMIN, MVT::v2i64, {2, 4, 3, 3}},
6660 {ISD::UMIN, MVT::v2i64, {2, 4, 3, 3}},
6661 {ISD::SMIN, MVT::v4i64, {3,10, 5, 5}},
6662 {ISD::UMIN, MVT::v4i64, {3,10, 5, 5}},
6663 {ISD::SMIN, MVT::v8i64, {5,16, 7, 7}},
6664 {ISD::UMIN, MVT::v8i64, {5,16, 7, 7}},
6665 {ISD::SMIN, MVT::v16i32, {4,12, 9, 9}},
6666 {ISD::UMIN, MVT::v16i32, {4,12, 9, 9}},
6667 };
6668
6669 static const CostKindTblEntry AVX512BWCostTbl[] = {
6670 {ISD::SMIN, MVT::v2i16, {1, 2, 3, 3}},
6671 {ISD::UMIN, MVT::v2i16, {1, 2, 3, 3}},
6672 {ISD::SMIN, MVT::v32i16, {2,19, 8, 9}},
6673 {ISD::UMIN, MVT::v32i16, {2,12, 6, 6}},
6674 {ISD::SMIN, MVT::v2i8, {1, 2, 3, 3}},
6675 {ISD::UMIN, MVT::v2i8, {1, 2, 3, 3}},
6676 {ISD::SMIN, MVT::v4i8, {2, 4, 5, 5}},
6677 {ISD::UMIN, MVT::v4i8, {2, 4, 5, 5}},
6678 {ISD::SMIN, MVT::v16i8, {2,10, 6, 7}},
6679 {ISD::UMIN, MVT::v16i8, {2, 6, 4, 4}},
6680 {ISD::SMIN, MVT::v32i8, {2,17, 8, 9}},
6681 {ISD::UMIN, MVT::v32i8, {2,10, 6, 6}},
6682 {ISD::SMIN, MVT::v64i8, {2,21,10,11}},
6683 {ISD::UMIN, MVT::v64i8, {2,14, 8, 8}},
6684 };
6685
6686 // Before legalizing the type, give a chance to look up illegal narrow types
6687 // in the table.
6688 // FIXME: Is there a better way to do this?
6689 EVT VT = TLI->getValueType(DL, ValTy);
6690 if (VT.isSimple()) {
6691 MVT MTy = VT.getSimpleVT();
6692 if (ST->hasBWI())
6693 if (const auto *Entry = CostTableLookup(AVX512BWCostTbl, ISD, MTy))
6694 if (auto KindCost = Entry->Cost[CostKind])
6695 return *KindCost;
6696
6697 if (ST->hasAVX512())
6698 if (const auto *Entry = CostTableLookup(AVX512FCostTbl, ISD, MTy))
6699 if (auto KindCost = Entry->Cost[CostKind])
6700 return *KindCost;
6701
6702 if (ST->hasAVX2())
6703 if (const auto *Entry = CostTableLookup(AVX2CostTbl, ISD, MTy))
6704 if (auto KindCost = Entry->Cost[CostKind])
6705 return *KindCost;
6706
6707 if (ST->hasAVX())
6708 if (const auto *Entry = CostTableLookup(AVX1CostTbl, ISD, MTy))
6709 if (auto KindCost = Entry->Cost[CostKind])
6710 return *KindCost;
6711
6712 if (ST->hasSSE41())
6713 if (const auto *Entry = CostTableLookup(SSE41CostTbl, ISD, MTy))
6714 if (auto KindCost = Entry->Cost[CostKind])
6715 return *KindCost;
6716
6717 if (ST->hasSSE2())
6718 if (const auto *Entry = CostTableLookup(SSE2CostTbl, ISD, MTy))
6719 if (auto KindCost = Entry->Cost[CostKind])
6720 return *KindCost;
6721 }
6722
6723 auto *ValVTy = cast<FixedVectorType>(ValTy);
6724 unsigned NumVecElts = ValVTy->getNumElements();
6725
6726 auto *Ty = ValVTy;
6727 InstructionCost MinMaxCost = 0;
6728 if (LT.first != 1 && MTy.isVector() &&
6729 MTy.getVectorNumElements() < ValVTy->getNumElements()) {
6730 // Type needs to be split. We need LT.first - 1 operations ops.
6731 Ty = FixedVectorType::get(ValVTy->getElementType(),
6732 MTy.getVectorNumElements());
6733 MinMaxCost = getMinMaxCost(IID, Ty, CostKind, FMF);
6734 MinMaxCost *= LT.first - 1;
6735 NumVecElts = MTy.getVectorNumElements();
6736 }
6737
6738 if (ST->hasBWI())
6739 if (const auto *Entry = CostTableLookup(AVX512BWCostTbl, ISD, MTy))
6740 if (auto KindCost = Entry->Cost[CostKind])
6741 return MinMaxCost + *KindCost;
6742
6743 if (ST->hasAVX512())
6744 if (const auto *Entry = CostTableLookup(AVX512FCostTbl, ISD, MTy))
6745 if (auto KindCost = Entry->Cost[CostKind])
6746 return MinMaxCost + *KindCost;
6747
6748 if (ST->hasAVX2())
6749 if (const auto *Entry = CostTableLookup(AVX2CostTbl, ISD, MTy))
6750 if (auto KindCost = Entry->Cost[CostKind])
6751 return MinMaxCost + *KindCost;
6752
6753 if (ST->hasAVX())
6754 if (const auto *Entry = CostTableLookup(AVX1CostTbl, ISD, MTy))
6755 if (auto KindCost = Entry->Cost[CostKind])
6756 return MinMaxCost + *KindCost;
6757
6758 if (ST->hasSSE41())
6759 if (const auto *Entry = CostTableLookup(SSE41CostTbl, ISD, MTy))
6760 if (auto KindCost = Entry->Cost[CostKind])
6761 return MinMaxCost + *KindCost;
6762
6763 if (ST->hasSSE2())
6764 if (const auto *Entry = CostTableLookup(SSE2CostTbl, ISD, MTy))
6765 if (auto KindCost = Entry->Cost[CostKind])
6766 return MinMaxCost + *KindCost;
6767
6768 unsigned ScalarSize = ValTy->getScalarSizeInBits();
6769
6770 // Special case power of 2 reductions where the scalar type isn't changed
6771 // by type legalization.
6772 if (!isPowerOf2_32(ValVTy->getNumElements()) ||
6773 ScalarSize != MTy.getScalarSizeInBits())
6774 return BaseT::getMinMaxReductionCost(IID, ValTy, FMF, CostKind);
6775
6776 // Now handle reduction with the legal type, taking into account size changes
6777 // at each level.
6778 while (NumVecElts > 1) {
6779 // Determine the size of the remaining vector we need to reduce.
6780 unsigned Size = NumVecElts * ScalarSize;
6781 NumVecElts /= 2;
6782 // If we're reducing from 256/512 bits, use an extract_subvector.
6783 if (Size > 128) {
6784 auto *SubTy = FixedVectorType::get(ValVTy->getElementType(), NumVecElts);
6785 MinMaxCost += getShuffleCost(TTI::SK_ExtractSubvector, Ty, Ty, CostKind,
6786 {}, NumVecElts, SubTy);
6787 Ty = SubTy;
6788 } else if (Size == 128) {
6789 // Reducing from 128 bits is a permute of v2f64/v2i64.
6790 VectorType *ShufTy;
6791 if (ValTy->isFloatingPointTy())
6792 ShufTy =
6794 else
6795 ShufTy = FixedVectorType::get(Type::getInt64Ty(ValTy->getContext()), 2);
6796 MinMaxCost += getShuffleCost(TTI::SK_PermuteSingleSrc, ShufTy, ShufTy,
6797 CostKind, {}, 0, nullptr);
6798 } else if (Size == 64) {
6799 // Reducing from 64 bits is a shuffle of v4f32/v4i32.
6800 FixedVectorType *ShufTy;
6801 if (ValTy->isFloatingPointTy())
6802 ShufTy = FixedVectorType::get(Type::getFloatTy(ValTy->getContext()), 4);
6803 else
6804 ShufTy = FixedVectorType::get(Type::getInt32Ty(ValTy->getContext()), 4);
6805 MinMaxCost += getShuffleCost(TTI::SK_PermuteSingleSrc, ShufTy, ShufTy,
6806 CostKind, {}, 0, nullptr);
6807 } else {
6808 // Reducing from smaller size is a shift by immediate.
6809 auto *ShiftTy = FixedVectorType::get(
6810 Type::getIntNTy(ValTy->getContext(), Size), 128 / Size);
6811 MinMaxCost += getArithmeticInstrCost(
6812 Instruction::LShr, ShiftTy, TTI::TCK_RecipThroughput,
6815 }
6816
6817 // Add the arithmetic op for this level.
6818 MinMaxCost += getMinMaxCost(IID, Ty, CostKind, FMF);
6819 }
6820
6821 // Add the final extract element to the cost.
6822 return MinMaxCost + getVectorInstrCost(Instruction::ExtractElement, Ty,
6823 CostKind, 0, nullptr, nullptr,
6825}
6826
6827/// Calculate the cost of materializing a 64-bit value. This helper
6828/// method might only calculate a fraction of a larger immediate. Therefore it
6829/// is valid to return a cost of ZERO.
6831 if (Val == 0)
6832 return TTI::TCC_Free;
6833
6834 if (isInt<32>(Val))
6835 return TTI::TCC_Basic;
6836
6837 return 2 * TTI::TCC_Basic;
6838}
6839
6842 assert(Ty->isIntegerTy());
6843
6844 unsigned BitSize = Ty->getPrimitiveSizeInBits();
6845 if (BitSize == 0)
6846 return ~0U;
6847
6848 // Never hoist constants larger than 128bit, because this might lead to
6849 // incorrect code generation or assertions in codegen.
6850 // Fixme: Create a cost model for types larger than i128 once the codegen
6851 // issues have been fixed.
6852 if (BitSize > 128)
6853 return TTI::TCC_Free;
6854
6855 if (Imm == 0)
6856 return TTI::TCC_Free;
6857
6858 // Sign-extend all constants to a multiple of 64-bit.
6859 APInt ImmVal = Imm;
6860 if (BitSize % 64 != 0)
6861 ImmVal = Imm.sext(alignTo(BitSize, 64));
6862
6863 // Split the constant into 64-bit chunks and calculate the cost for each
6864 // chunk.
6866 for (unsigned ShiftVal = 0; ShiftVal < BitSize; ShiftVal += 64) {
6867 APInt Tmp = ImmVal.ashr(ShiftVal).sextOrTrunc(64);
6868 int64_t Val = Tmp.getSExtValue();
6869 Cost += getIntImmCost(Val);
6870 }
6871 // We need at least one instruction to materialize the constant.
6872 return std::max<InstructionCost>(1, Cost);
6873}
6874
6876 const APInt &Imm, Type *Ty,
6878 Instruction *Inst) const {
6879 assert(Ty->isIntegerTy());
6880
6881 unsigned BitSize = Ty->getPrimitiveSizeInBits();
6882 unsigned ImmBitWidth = Imm.getBitWidth();
6883
6884 // There is no cost model for constants with a bit size of 0. Return TCC_Free
6885 // here, so that constant hoisting will ignore this constant.
6886 if (BitSize == 0)
6887 return TTI::TCC_Free;
6888
6889 unsigned ImmIdx = ~0U;
6890 switch (Opcode) {
6891 default:
6892 return TTI::TCC_Free;
6893 case Instruction::GetElementPtr:
6894 // Always hoist the base address of a GetElementPtr. This prevents the
6895 // creation of new constants for every base constant that gets constant
6896 // folded with the offset.
6897 if (Idx == 0)
6898 return 2 * TTI::TCC_Basic;
6899 return TTI::TCC_Free;
6900 case Instruction::Store:
6901 ImmIdx = 0;
6902 break;
6903 case Instruction::ICmp:
6904 // This is an imperfect hack to prevent constant hoisting of
6905 // compares that might be trying to check if a 64-bit value fits in
6906 // 32-bits. The backend can optimize these cases using a right shift by 32.
6907 // There are other predicates and immediates the backend can use shifts for.
6908 if (Idx == 1 && ImmBitWidth == 64) {
6909 uint64_t ImmVal = Imm.getZExtValue();
6910 if (ImmVal == 0x100000000ULL || ImmVal == 0xffffffff)
6911 return TTI::TCC_Free;
6912
6913 if (auto *Cmp = dyn_cast_or_null<CmpInst>(Inst)) {
6914 if (Cmp->isEquality()) {
6915 KnownBits Known = computeKnownBits(Cmp->getOperand(0), DL);
6916 if (Known.countMinTrailingZeros() >= 32)
6917 return TTI::TCC_Free;
6918 }
6919 }
6920 }
6921 ImmIdx = 1;
6922 break;
6923 case Instruction::And:
6924 // We support 64-bit ANDs with immediates with 32-bits of leading zeroes
6925 // by using a 32-bit operation with implicit zero extension. Detect such
6926 // immediates here as the normal path expects bit 31 to be sign extended.
6927 if (Idx == 1 && ImmBitWidth == 64 && Imm.isIntN(32))
6928 return TTI::TCC_Free;
6929 // If we have BMI then we can use BEXTR/BZHI to mask out upper i64 bits.
6930 if (Idx == 1 && ImmBitWidth == 64 && ST->is64Bit() && ST->hasBMI() &&
6931 Imm.isMask())
6932 return X86TTIImpl::getIntImmCost(ST->hasBMI2() ? 255 : 65535);
6933 ImmIdx = 1;
6934 break;
6935 case Instruction::Add:
6936 case Instruction::Sub:
6937 // For add/sub, we can use the opposite instruction for INT32_MIN.
6938 if (Idx == 1 && ImmBitWidth == 64 && Imm.getZExtValue() == 0x80000000)
6939 return TTI::TCC_Free;
6940 ImmIdx = 1;
6941 break;
6942 case Instruction::UDiv:
6943 case Instruction::SDiv:
6944 case Instruction::URem:
6945 case Instruction::SRem:
6946 // Division by constant is typically expanded later into a different
6947 // instruction sequence. This completely changes the constants.
6948 // Report them as "free" to stop ConstantHoist from marking them as opaque.
6949 return TTI::TCC_Free;
6950 case Instruction::Mul:
6951 case Instruction::Or:
6952 case Instruction::Xor:
6953 ImmIdx = 1;
6954 break;
6955 // Always return TCC_Free for the shift value of a shift instruction.
6956 case Instruction::Shl:
6957 case Instruction::LShr:
6958 case Instruction::AShr:
6959 if (Idx == 1)
6960 return TTI::TCC_Free;
6961 break;
6962 case Instruction::Trunc:
6963 case Instruction::ZExt:
6964 case Instruction::SExt:
6965 case Instruction::IntToPtr:
6966 case Instruction::PtrToInt:
6967 case Instruction::BitCast:
6968 case Instruction::PHI:
6969 case Instruction::Call:
6970 case Instruction::Select:
6971 case Instruction::Ret:
6972 case Instruction::Load:
6973 break;
6974 }
6975
6976 if (Idx == ImmIdx) {
6977 uint64_t NumConstants = divideCeil(BitSize, 64);
6979 return (Cost <= NumConstants * TTI::TCC_Basic)
6980 ? static_cast<int>(TTI::TCC_Free)
6981 : Cost;
6982 }
6983
6985}
6986
6989 const APInt &Imm, Type *Ty,
6991 assert(Ty->isIntegerTy());
6992
6993 unsigned BitSize = Ty->getPrimitiveSizeInBits();
6994 // There is no cost model for constants with a bit size of 0. Return TCC_Free
6995 // here, so that constant hoisting will ignore this constant.
6996 if (BitSize == 0)
6997 return TTI::TCC_Free;
6998
6999 switch (IID) {
7000 default:
7001 return TTI::TCC_Free;
7002 case Intrinsic::sadd_with_overflow:
7003 case Intrinsic::uadd_with_overflow:
7004 case Intrinsic::ssub_with_overflow:
7005 case Intrinsic::usub_with_overflow:
7006 case Intrinsic::smul_with_overflow:
7007 case Intrinsic::umul_with_overflow:
7008 if ((Idx == 1) && Imm.getBitWidth() <= 64 && Imm.isSignedIntN(32))
7009 return TTI::TCC_Free;
7010 break;
7011 case Intrinsic::experimental_stackmap:
7012 if ((Idx < 2) || (Imm.getBitWidth() <= 64 && Imm.isSignedIntN(64)))
7013 return TTI::TCC_Free;
7014 break;
7015 case Intrinsic::experimental_patchpoint_void:
7016 case Intrinsic::experimental_patchpoint:
7017 if ((Idx < 4) || (Imm.getBitWidth() <= 64 && Imm.isSignedIntN(64)))
7018 return TTI::TCC_Free;
7019 break;
7020 }
7022}
7023
7026 const Instruction *I) const {
7028 return Opcode == Instruction::PHI ? TTI::TCC_Free : TTI::TCC_Basic;
7029 // Branches are assumed to be predicted.
7030 return TTI::TCC_Free;
7031}
7032
7033int X86TTIImpl::getGatherOverhead() const {
7034 // Some CPUs have more overhead for gather. The specified overhead is relative
7035 // to the Load operation. "2" is the number provided by Intel architects. This
7036 // parameter is used for cost estimation of Gather Op and comparison with
7037 // other alternatives.
7038 // TODO: Remove the explicit hasAVX512()?, That would mean we would only
7039 // enable gather with a -march.
7040 if (ST->hasAVX512() || (ST->hasAVX2() && ST->hasFastGather()))
7041 return 2;
7042
7043 return 1024;
7044}
7045
7046int X86TTIImpl::getScatterOverhead() const {
7047 if (ST->hasAVX512())
7048 return 2;
7049
7050 return 1024;
7051}
7052
7053// Return an average cost of Gather / Scatter instruction, maybe improved later.
7054InstructionCost X86TTIImpl::getGSVectorCost(unsigned Opcode,
7056 Type *SrcVTy, const Value *Ptr,
7057 Align Alignment,
7058 unsigned AddressSpace) const {
7059
7060 assert(isa<VectorType>(SrcVTy) && "Unexpected type in getGSVectorCost");
7061 unsigned VF = cast<FixedVectorType>(SrcVTy)->getNumElements();
7062
7063 // Try to reduce index size from 64 bit (default for GEP)
7064 // to 32. It is essential for VF 16. If the index can't be reduced to 32, the
7065 // operation will use 16 x 64 indices which do not fit in a zmm and needs
7066 // to split. Also check that the base pointer is the same for all lanes,
7067 // and that there's at most one variable index.
7068 auto getIndexSizeInBits = [](const Value *Ptr, const DataLayout &DL) {
7069 unsigned IndexSize = DL.getPointerSizeInBits();
7070 const GetElementPtrInst *GEP = dyn_cast_or_null<GetElementPtrInst>(Ptr);
7071 if (IndexSize < 64 || !GEP)
7072 return IndexSize;
7073
7074 unsigned NumOfVarIndices = 0;
7075 const Value *Ptrs = GEP->getPointerOperand();
7076 if (Ptrs->getType()->isVectorTy() && !getSplatValue(Ptrs))
7077 return IndexSize;
7078 for (unsigned I = 1, E = GEP->getNumOperands(); I != E; ++I) {
7079 if (isa<Constant>(GEP->getOperand(I)))
7080 continue;
7081 Type *IndxTy = GEP->getOperand(I)->getType();
7082 if (auto *IndexVTy = dyn_cast<VectorType>(IndxTy))
7083 IndxTy = IndexVTy->getElementType();
7084 if ((IndxTy->getPrimitiveSizeInBits() == 64 &&
7085 !isa<SExtInst>(GEP->getOperand(I))) ||
7086 ++NumOfVarIndices > 1)
7087 return IndexSize; // 64
7088 }
7089 return (unsigned)32;
7090 };
7091
7092 // Trying to reduce IndexSize to 32 bits for vector 16.
7093 // By default the IndexSize is equal to pointer size.
7094 unsigned IndexSize = (ST->hasAVX512() && VF >= 16)
7095 ? getIndexSizeInBits(Ptr, DL)
7096 : DL.getPointerSizeInBits();
7097
7098 auto *IndexVTy = FixedVectorType::get(
7099 IntegerType::get(SrcVTy->getContext(), IndexSize), VF);
7100 std::pair<InstructionCost, MVT> IdxsLT = getTypeLegalizationCost(IndexVTy);
7101 std::pair<InstructionCost, MVT> SrcLT = getTypeLegalizationCost(SrcVTy);
7102 InstructionCost::CostType SplitFactor =
7103 std::max(IdxsLT.first, SrcLT.first).getValue();
7104 if (SplitFactor > 1) {
7105 // Handle splitting of vector of pointers
7106 auto *SplitSrcTy =
7107 FixedVectorType::get(SrcVTy->getScalarType(), VF / SplitFactor);
7108 return SplitFactor * getGSVectorCost(Opcode, CostKind, SplitSrcTy, Ptr,
7109 Alignment, AddressSpace);
7110 }
7111
7112 // If we didn't split, this will be a single gather/scatter instruction.
7114 return 1;
7115
7116 // The gather / scatter cost is given by Intel architects. It is a rough
7117 // number since we are looking at one instruction in a time.
7118 const int GSOverhead = (Opcode == Instruction::Load) ? getGatherOverhead()
7119 : getScatterOverhead();
7120 return GSOverhead + VF * getMemoryOpCost(Opcode, SrcVTy->getScalarType(),
7121 Alignment, AddressSpace, CostKind);
7122}
7123
7124/// Calculate the cost of Gather / Scatter operation
7128 bool IsLoad = MICA.getID() == Intrinsic::masked_gather ||
7129 MICA.getID() == Intrinsic::vp_gather;
7130 unsigned Opcode = IsLoad ? Instruction::Load : Instruction::Store;
7131 Type *SrcVTy = MICA.getDataType();
7132 const Value *Ptr = MICA.getPointer();
7133 Align Alignment = MICA.getAlignment();
7134 if ((Opcode == Instruction::Load &&
7135 (!isLegalMaskedGather(SrcVTy, Align(Alignment)) ||
7137 Align(Alignment)))) ||
7138 (Opcode == Instruction::Store &&
7139 (!isLegalMaskedScatter(SrcVTy, Align(Alignment)) ||
7141 Align(Alignment)))))
7143
7144 assert(SrcVTy->isVectorTy() && "Unexpected data type for Gather/Scatter");
7145 unsigned AddressSpace = MICA.getAddressSpace();
7146 return getGSVectorCost(Opcode, CostKind, SrcVTy, Ptr, Alignment,
7147 AddressSpace);
7148}
7149
7151 const TargetTransformInfo::LSRCost &C2) const {
7152 // X86 specific here are "instruction number 1st priority".
7153 return std::tie(C1.Insns, C1.NumRegs, C1.AddRecCost, C1.NumIVMuls,
7154 C1.NumBaseAdds, C1.ScaleCost, C1.ImmCost, C1.SetupCost) <
7155 std::tie(C2.Insns, C2.NumRegs, C2.AddRecCost, C2.NumIVMuls,
7156 C2.NumBaseAdds, C2.ScaleCost, C2.ImmCost, C2.SetupCost);
7157}
7158
7160 return ST->hasMacroFusion() || ST->hasBranchFusion();
7161}
7162
7163static bool isLegalMaskedLoadStore(Type *ScalarTy, const X86Subtarget *ST) {
7164 if (!ST->hasAVX())
7165 return false;
7166
7167 if (ScalarTy->isPointerTy())
7168 return true;
7169
7170 if (ScalarTy->isFloatTy() || ScalarTy->isDoubleTy())
7171 return true;
7172
7173 if (ScalarTy->isHalfTy() && ST->hasBWI())
7174 return true;
7175
7176 if (ScalarTy->isBFloatTy() && ST->hasBF16())
7177 return true;
7178
7179 if (!ScalarTy->isIntegerTy())
7180 return false;
7181
7182 unsigned IntWidth = ScalarTy->getIntegerBitWidth();
7183 return IntWidth == 32 || IntWidth == 64 ||
7184 ((IntWidth == 8 || IntWidth == 16) && ST->hasBWI());
7185}
7186
7188 unsigned AddressSpace,
7189 TTI::MaskKind MaskKind) const {
7190 Type *ScalarTy = DataTy->getScalarType();
7191
7192 // The backend can't handle a single element vector w/o CFCMOV.
7193 if (isa<VectorType>(DataTy) &&
7194 cast<FixedVectorType>(DataTy)->getNumElements() == 1)
7195 return ST->hasCF() &&
7196 hasConditionalLoadStoreForType(ScalarTy, /*IsStore=*/false);
7197
7198 return isLegalMaskedLoadStore(ScalarTy, ST);
7199}
7200
7202 unsigned AddressSpace,
7203 TTI::MaskKind MaskKind) const {
7204 Type *ScalarTy = DataTy->getScalarType();
7205
7206 // The backend can't handle a single element vector w/o CFCMOV.
7207 if (isa<VectorType>(DataTy) &&
7208 cast<FixedVectorType>(DataTy)->getNumElements() == 1)
7209 return ST->hasCF() &&
7210 hasConditionalLoadStoreForType(ScalarTy, /*IsStore=*/true);
7211
7212 return isLegalMaskedLoadStore(ScalarTy, ST);
7213}
7214
7215bool X86TTIImpl::isLegalNTLoad(Type *DataType, Align Alignment) const {
7216 unsigned DataSize = DL.getTypeStoreSize(DataType);
7217 // The only supported nontemporal loads are for aligned vectors of 16 or 32
7218 // bytes. Note that 32-byte nontemporal vector loads are supported by AVX2
7219 // (the equivalent stores only require AVX).
7220 if (Alignment >= DataSize && (DataSize == 16 || DataSize == 32))
7221 return DataSize == 16 ? ST->hasSSE1() : ST->hasAVX2();
7222
7223 return false;
7224}
7225
7226bool X86TTIImpl::isLegalNTStore(Type *DataType, Align Alignment) const {
7227 unsigned DataSize = DL.getTypeStoreSize(DataType);
7228
7229 // SSE4A supports nontemporal stores of float and double at arbitrary
7230 // alignment.
7231 if (ST->hasSSE4A() && (DataType->isFloatTy() || DataType->isDoubleTy()))
7232 return true;
7233
7234 // Besides the SSE4A subtarget exception above, only aligned stores are
7235 // available nontemporaly on any other subtarget. And only stores with a size
7236 // of 4..32 bytes (powers of 2, only) are permitted.
7237 if (Alignment < DataSize || DataSize < 4 || DataSize > 32 ||
7238 !isPowerOf2_32(DataSize))
7239 return false;
7240
7241 // 32-byte vector nontemporal stores are supported by AVX (the equivalent
7242 // loads require AVX2).
7243 if (DataSize == 32)
7244 return ST->hasAVX();
7245 if (DataSize == 16)
7246 return ST->hasSSE1();
7247 return true;
7248}
7249
7251 ElementCount NumElements) const {
7252 // movddup
7253 return ST->hasSSE3() && !NumElements.isScalable() &&
7254 NumElements.getFixedValue() == 2 &&
7255 ElementTy == Type::getDoubleTy(ElementTy->getContext());
7256}
7257
7258bool X86TTIImpl::isLegalMaskedExpandLoad(Type *DataTy, Align Alignment) const {
7259 if (!isa<VectorType>(DataTy))
7260 return false;
7261
7262 if (!ST->hasAVX512())
7263 return false;
7264
7265 // The backend can't handle a single element vector.
7266 if (cast<FixedVectorType>(DataTy)->getNumElements() == 1)
7267 return false;
7268
7269 Type *ScalarTy = cast<VectorType>(DataTy)->getElementType();
7270
7271 if (ScalarTy->isFloatTy() || ScalarTy->isDoubleTy())
7272 return true;
7273
7274 if (!ScalarTy->isIntegerTy())
7275 return false;
7276
7277 unsigned IntWidth = ScalarTy->getIntegerBitWidth();
7278 return IntWidth == 32 || IntWidth == 64 ||
7279 ((IntWidth == 8 || IntWidth == 16) && ST->hasVBMI2());
7280}
7281
7283 Align Alignment) const {
7284 return isLegalMaskedExpandLoad(DataTy, Alignment);
7285}
7286
7287bool X86TTIImpl::supportsGather() const {
7288 // Some CPUs have better gather performance than others.
7289 // TODO: Remove the explicit ST->hasAVX512()?, That would mean we would only
7290 // enable gather with a -march.
7291 return ST->hasAVX512() || (ST->hasFastGather() && ST->hasAVX2());
7292}
7293
7295 Align Alignment) const {
7296 // Gather / Scatter for vector 2 is not profitable on KNL / SKX
7297 // Vector-4 of gather/scatter instruction does not exist on KNL. We can extend
7298 // it to 8 elements, but zeroing upper bits of the mask vector will add more
7299 // instructions. Right now we give the scalar cost of vector-4 for KNL. TODO:
7300 // Check, maybe the gather/scatter instruction is better in the VariableMask
7301 // case.
7302 unsigned NumElts = cast<FixedVectorType>(VTy)->getNumElements();
7303 return NumElts == 1 ||
7304 (ST->hasAVX512() && (NumElts == 2 || (NumElts == 4 && !ST->hasVLX())));
7305}
7306
7308 Align Alignment) const {
7309 Type *ScalarTy = DataTy->getScalarType();
7310 if (ScalarTy->isPointerTy())
7311 return true;
7312
7313 if (ScalarTy->isFloatTy() || ScalarTy->isDoubleTy())
7314 return true;
7315
7316 if (!ScalarTy->isIntegerTy())
7317 return false;
7318
7319 unsigned IntWidth = ScalarTy->getIntegerBitWidth();
7320 return IntWidth == 32 || IntWidth == 64;
7321}
7322
7323bool X86TTIImpl::isLegalMaskedGather(Type *DataTy, Align Alignment) const {
7324 if (!supportsGather() || !ST->preferGather())
7325 return false;
7326 return isLegalMaskedGatherScatter(DataTy, Alignment);
7327}
7328
7329bool X86TTIImpl::isLegalAltInstr(VectorType *VecTy, unsigned Opcode0,
7330 unsigned Opcode1,
7331 const SmallBitVector &OpcodeMask) const {
7332 // ADDSUBPS 4xf32 SSE3
7333 // VADDSUBPS 4xf32 AVX
7334 // VADDSUBPS 8xf32 AVX2
7335 // ADDSUBPD 2xf64 SSE3
7336 // VADDSUBPD 2xf64 AVX
7337 // VADDSUBPD 4xf64 AVX2
7338
7339 unsigned NumElements = cast<FixedVectorType>(VecTy)->getNumElements();
7340 assert(OpcodeMask.size() == NumElements && "Mask and VecTy are incompatible");
7341 if (!isPowerOf2_32(NumElements))
7342 return false;
7343 // Check the opcode pattern. We apply the mask on the opcode arguments and
7344 // then check if it is what we expect.
7345 for (int Lane : seq<int>(0, NumElements)) {
7346 unsigned Opc = OpcodeMask.test(Lane) ? Opcode1 : Opcode0;
7347 // We expect FSub for even lanes and FAdd for odd lanes.
7348 if (Lane % 2 == 0 && Opc != Instruction::FSub)
7349 return false;
7350 if (Lane % 2 == 1 && Opc != Instruction::FAdd)
7351 return false;
7352 }
7353 // Now check that the pattern is supported by the target ISA.
7354 Type *ElemTy = cast<VectorType>(VecTy)->getElementType();
7355 if (ElemTy->isFloatTy())
7356 return ST->hasSSE3() && NumElements % 4 == 0;
7357 if (ElemTy->isDoubleTy())
7358 return ST->hasSSE3() && NumElements % 2 == 0;
7359 return false;
7360}
7361
7362bool X86TTIImpl::isLegalMaskedScatter(Type *DataType, Align Alignment) const {
7363 // AVX2 doesn't support scatter
7364 if (!ST->hasAVX512() || !ST->preferScatter())
7365 return false;
7366 return isLegalMaskedGatherScatter(DataType, Alignment);
7367}
7368
7369bool X86TTIImpl::hasDivRemOp(Type *DataType, bool IsSigned) const {
7370 EVT VT = TLI->getValueType(DL, DataType);
7371 return TLI->isOperationLegal(IsSigned ? ISD::SDIVREM : ISD::UDIVREM, VT);
7372}
7373
7375 // FDIV is always expensive, even if it has a very low uop count.
7376 // TODO: Still necessary for recent CPUs with low latency/throughput fdiv?
7377 if (I->getOpcode() == Instruction::FDiv)
7378 return true;
7379
7381}
7382
7383bool X86TTIImpl::isFCmpOrdCheaperThanFCmpZero(Type *Ty) const { return false; }
7384
7386 const Function *Callee) const {
7387 const TargetMachine &TM = getTLI()->getTargetMachine();
7388
7389 // Work this as a subsetting of subtarget features.
7390 const X86Subtarget &CallerSubtarget = TM.getSubtarget<X86Subtarget>(*Caller);
7391 const X86Subtarget &CalleeSubtarget = TM.getSubtarget<X86Subtarget>(*Callee);
7392 const FeatureBitset &CallerBits = CallerSubtarget.getFeatureBits();
7393 const FeatureBitset &CalleeBits = CalleeSubtarget.getFeatureBits();
7394
7395 // Check whether callee features are a subset of caller features
7396 // (apart from the ignore list).
7397 const FeatureBitset &InlineIgnoreFeatures =
7398 CallerSubtarget.getInlineIgnoreFeatures();
7399 FeatureBitset RealCallerBits = CallerBits & ~InlineIgnoreFeatures;
7400 FeatureBitset RealCalleeBits = CalleeBits & ~InlineIgnoreFeatures;
7401 if ((RealCallerBits & RealCalleeBits) != RealCalleeBits)
7402 return false;
7403
7404 // If the features are not exactly the same (or there is a difference in
7405 // AVX512 register usage), we need to additionally check for calls
7406 // that may become ABI-incompatible as a result of inlining.
7407 if (RealCallerBits == RealCalleeBits &&
7408 CallerSubtarget.useAVX512Regs() == CalleeSubtarget.useAVX512Regs())
7409 return true;
7410
7411 for (const Instruction &I : instructions(Callee)) {
7412 if (const auto *CB = dyn_cast<CallBase>(&I)) {
7413 // Having more target features is fine for inline ASM and intrinsics.
7414 if (CB->isInlineAsm() || CB->getIntrinsicID() != Intrinsic::not_intrinsic)
7415 continue;
7416
7418 for (Value *Arg : CB->args())
7419 Types.push_back(Arg->getType());
7420 if (!CB->getType()->isVoidTy())
7421 Types.push_back(CB->getType());
7422
7423 // Simple types are always ABI compatible.
7424 auto IsSimpleTy = [](Type *Ty) {
7425 return !Ty->isVectorTy() && !Ty->isAggregateType();
7426 };
7427 if (all_of(Types, IsSimpleTy))
7428 continue;
7429
7430 // Do a precise compatibility check.
7431 if (!areTypesABICompatible(Caller, Callee, Types))
7432 return false;
7433 }
7434 }
7435 return true;
7436}
7437
7439 const Function *Callee,
7440 ArrayRef<Type *> Types) const {
7441 const TargetMachine &TM = getTLI()->getTargetMachine();
7442 const TargetLowering *CallerTLI =
7443 TM.getSubtargetImpl(*Caller)->getTargetLowering();
7444 const TargetLowering *CalleeTLI =
7445 TM.getSubtargetImpl(*Callee)->getTargetLowering();
7446
7447 LLVMContext &Ctx = Caller->getContext();
7448 const DataLayout &DL = Caller->getDataLayout();
7449 CallingConv::ID CC = Callee->getCallingConv();
7450 return all_of(Types, [&](Type *Ty) {
7451 SmallVector<EVT> VTs;
7452 ComputeValueVTs(*CallerTLI, DL, Ty, VTs);
7453 return all_of(VTs, [&](EVT VT) {
7454 return CallerTLI->getRegisterTypeForCallingConv(Ctx, CC, VT) ==
7455 CalleeTLI->getRegisterTypeForCallingConv(Ctx, CC, VT);
7456 });
7457 });
7458}
7459
7461X86TTIImpl::enableMemCmpExpansion(bool OptSize, bool IsZeroCmp) const {
7463 Options.MaxNumLoads = TLI->getMaxExpandSizeMemcmp(OptSize);
7464 Options.NumLoadsPerBlock = IsZeroCmp ? 2 : 1;
7465 // All GPR and vector loads can be unaligned.
7466 Options.AllowOverlappingLoads = true;
7467 if (IsZeroCmp) {
7468 // Only enable vector loads for equality comparison. Right now the vector
7469 // version is not as fast for three way compare (see #33329).
7470 const unsigned PreferredWidth = ST->getPreferVectorWidth();
7471 if (PreferredWidth >= 512 && ST->hasAVX512())
7472 Options.LoadSizes.push_back(64);
7473 if (PreferredWidth >= 256 && ST->hasAVX()) Options.LoadSizes.push_back(32);
7474 if (PreferredWidth >= 128 && ST->hasSSE2()) Options.LoadSizes.push_back(16);
7475 }
7476 if (ST->is64Bit()) {
7477 Options.LoadSizes.push_back(8);
7478 }
7479 Options.LoadSizes.push_back(4);
7480 Options.LoadSizes.push_back(2);
7481 Options.LoadSizes.push_back(1);
7482 return Options;
7483}
7484
7486 return supportsGather();
7487}
7488
7490 return false;
7491}
7492
7494 // TODO: We expect this to be beneficial regardless of arch,
7495 // but there are currently some unexplained performance artifacts on Atom.
7496 // As a temporary solution, disable on Atom.
7497 return !(ST->isAtom());
7498}
7499
7501 switch (II->getIntrinsicID()) {
7502 default:
7503 return true;
7504 case Intrinsic::vector_reduce_and:
7505 case Intrinsic::vector_reduce_or:
7506 case Intrinsic::vector_reduce_xor:
7507 case Intrinsic::vector_reduce_mul:
7508 case Intrinsic::vector_reduce_smax:
7509 case Intrinsic::vector_reduce_smin:
7510 case Intrinsic::vector_reduce_umax:
7511 case Intrinsic::vector_reduce_umin:
7512 return false;
7513 }
7514}
7515
7516// Get estimation for interleaved load/store operations and strided load.
7517// \p Indices contains indices for strided load.
7518// \p Factor - the factor of interleaving.
7519// AVX-512 provides 3-src shuffles that significantly reduces the cost.
7521 unsigned Opcode, FixedVectorType *VecTy, unsigned Factor,
7522 ArrayRef<unsigned> Indices, Align Alignment, unsigned AddressSpace,
7523 TTI::TargetCostKind CostKind, bool UseMaskForCond,
7524 bool UseMaskForGaps) const {
7525 // VecTy for interleave memop is <VF*Factor x Elt>.
7526 // So, for VF=4, Interleave Factor = 3, Element type = i32 we have
7527 // VecTy = <12 x i32>.
7528
7529 // Calculate the number of memory operations (NumOfMemOps), required
7530 // for load/store the VecTy.
7531 MVT LegalVT = getTypeLegalizationCost(VecTy).second;
7532 unsigned VecTySize = DL.getTypeStoreSize(VecTy);
7533 unsigned LegalVTSize = LegalVT.getStoreSize();
7534 unsigned NumOfMemOps = (VecTySize + LegalVTSize - 1) / LegalVTSize;
7535
7536 // Get the cost of one memory operation.
7537 auto *SingleMemOpTy = FixedVectorType::get(VecTy->getElementType(),
7538 LegalVT.getVectorNumElements());
7539 InstructionCost MemOpCost;
7540 bool UseMaskedMemOp = UseMaskForCond || UseMaskForGaps;
7541 if (UseMaskedMemOp) {
7542 unsigned IID = Opcode == Instruction::Load ? Intrinsic::masked_load
7543 : Intrinsic::masked_store;
7544 MemOpCost = getMaskedMemoryOpCost(
7545 {IID, SingleMemOpTy, Alignment, AddressSpace}, CostKind);
7546 } else
7547 MemOpCost = getMemoryOpCost(Opcode, SingleMemOpTy, Alignment, AddressSpace,
7548 CostKind);
7549
7550 unsigned VF = VecTy->getNumElements() / Factor;
7551 MVT VT =
7552 MVT::getVectorVT(TLI->getSimpleValueType(DL, VecTy->getScalarType()), VF);
7553
7554 InstructionCost MaskCost;
7555 if (UseMaskedMemOp) {
7556 APInt DemandedLoadStoreElts = APInt::getZero(VecTy->getNumElements());
7557 for (unsigned Index : Indices) {
7558 assert(Index < Factor && "Invalid index for interleaved memory op");
7559 for (unsigned Elm = 0; Elm < VF; Elm++)
7560 DemandedLoadStoreElts.setBit(Index + Elm * Factor);
7561 }
7562
7563 Type *I1Type = Type::getInt1Ty(VecTy->getContext());
7564
7565 MaskCost = getReplicationShuffleCost(
7566 I1Type, Factor, VF,
7567 UseMaskForGaps ? DemandedLoadStoreElts
7569 CostKind);
7570
7571 // The Gaps mask is invariant and created outside the loop, therefore the
7572 // cost of creating it is not accounted for here. However if we have both
7573 // a MaskForGaps and some other mask that guards the execution of the
7574 // memory access, we need to account for the cost of And-ing the two masks
7575 // inside the loop.
7576 if (UseMaskForGaps) {
7577 auto *MaskVT = FixedVectorType::get(I1Type, VecTy->getNumElements());
7578 MaskCost += getArithmeticInstrCost(BinaryOperator::And, MaskVT, CostKind);
7579 }
7580 }
7581
7582 if (Opcode == Instruction::Load) {
7583 // The tables (AVX512InterleavedLoadTbl and AVX512InterleavedStoreTbl)
7584 // contain the cost of the optimized shuffle sequence that the
7585 // X86InterleavedAccess pass will generate.
7586 // The cost of loads and stores are computed separately from the table.
7587
7588 // X86InterleavedAccess support only the following interleaved-access group.
7589 static const CostTblEntry AVX512InterleavedLoadTbl[] = {
7590 {3, MVT::v16i8, 12}, //(load 48i8 and) deinterleave into 3 x 16i8
7591 {3, MVT::v32i8, 14}, //(load 96i8 and) deinterleave into 3 x 32i8
7592 {3, MVT::v64i8, 22}, //(load 96i8 and) deinterleave into 3 x 32i8
7593 };
7594
7595 if (const auto *Entry =
7596 CostTableLookup(AVX512InterleavedLoadTbl, Factor, VT))
7597 return MaskCost + NumOfMemOps * MemOpCost + Entry->Cost;
7598 //If an entry does not exist, fallback to the default implementation.
7599
7600 // Kind of shuffle depends on number of loaded values.
7601 // If we load the entire data in one register, we can use a 1-src shuffle.
7602 // Otherwise, we'll merge 2 sources in each operation.
7603 TTI::ShuffleKind ShuffleKind =
7604 (NumOfMemOps > 1) ? TTI::SK_PermuteTwoSrc : TTI::SK_PermuteSingleSrc;
7605
7606 InstructionCost ShuffleCost = getShuffleCost(
7607 ShuffleKind, SingleMemOpTy, SingleMemOpTy, CostKind, {}, 0, nullptr);
7608
7609 unsigned NumOfLoadsInInterleaveGrp =
7610 Indices.size() ? Indices.size() : Factor;
7611 auto *ResultTy = FixedVectorType::get(VecTy->getElementType(),
7612 VecTy->getNumElements() / Factor);
7613 InstructionCost NumOfResults =
7614 getTypeLegalizationCost(ResultTy).first * NumOfLoadsInInterleaveGrp;
7615
7616 // About a half of the loads may be folded in shuffles when we have only
7617 // one result. If we have more than one result, or the loads are masked,
7618 // we do not fold loads at all.
7619 unsigned NumOfUnfoldedLoads =
7620 UseMaskedMemOp || NumOfResults > 1 ? NumOfMemOps : NumOfMemOps / 2;
7621
7622 // Get a number of shuffle operations per result.
7623 unsigned NumOfShufflesPerResult =
7624 std::max((unsigned)1, (unsigned)(NumOfMemOps - 1));
7625
7626 // The SK_MergeTwoSrc shuffle clobbers one of src operands.
7627 // When we have more than one destination, we need additional instructions
7628 // to keep sources.
7629 InstructionCost NumOfMoves = 0;
7630 if (NumOfResults > 1 && ShuffleKind == TTI::SK_PermuteTwoSrc)
7631 NumOfMoves = NumOfResults * NumOfShufflesPerResult / 2;
7632
7633 InstructionCost Cost = NumOfResults * NumOfShufflesPerResult * ShuffleCost +
7634 MaskCost + NumOfUnfoldedLoads * MemOpCost +
7635 NumOfMoves;
7636
7637 return Cost;
7638 }
7639
7640 // Store.
7641 assert(Opcode == Instruction::Store &&
7642 "Expected Store Instruction at this point");
7643 // X86InterleavedAccess support only the following interleaved-access group.
7644 static const CostTblEntry AVX512InterleavedStoreTbl[] = {
7645 {3, MVT::v16i8, 12}, // interleave 3 x 16i8 into 48i8 (and store)
7646 {3, MVT::v32i8, 14}, // interleave 3 x 32i8 into 96i8 (and store)
7647 {3, MVT::v64i8, 26}, // interleave 3 x 64i8 into 96i8 (and store)
7648
7649 {4, MVT::v8i8, 10}, // interleave 4 x 8i8 into 32i8 (and store)
7650 {4, MVT::v16i8, 11}, // interleave 4 x 16i8 into 64i8 (and store)
7651 {4, MVT::v32i8, 14}, // interleave 4 x 32i8 into 128i8 (and store)
7652 {4, MVT::v64i8, 24} // interleave 4 x 32i8 into 256i8 (and store)
7653 };
7654
7655 if (const auto *Entry =
7656 CostTableLookup(AVX512InterleavedStoreTbl, Factor, VT))
7657 return MaskCost + NumOfMemOps * MemOpCost + Entry->Cost;
7658 //If an entry does not exist, fallback to the default implementation.
7659
7660 // There is no strided stores meanwhile. And store can't be folded in
7661 // shuffle.
7662 unsigned NumOfSources = Factor; // The number of values to be merged.
7663 InstructionCost ShuffleCost =
7664 getShuffleCost(TTI::SK_PermuteTwoSrc, SingleMemOpTy, SingleMemOpTy,
7665 CostKind, {}, 0, nullptr);
7666 unsigned NumOfShufflesPerStore = NumOfSources - 1;
7667
7668 // The SK_MergeTwoSrc shuffle clobbers one of src operands.
7669 // We need additional instructions to keep sources.
7670 unsigned NumOfMoves = NumOfMemOps * NumOfShufflesPerStore / 2;
7672 MaskCost +
7673 NumOfMemOps * (MemOpCost + NumOfShufflesPerStore * ShuffleCost) +
7674 NumOfMoves;
7675 return Cost;
7676}
7677
7679 unsigned Opcode, Type *BaseTy, unsigned Factor, ArrayRef<unsigned> Indices,
7680 Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind,
7681 bool UseMaskForCond, bool UseMaskForGaps) const {
7682 auto *VecTy = cast<FixedVectorType>(BaseTy);
7683
7684 auto isSupportedOnAVX512 = [&](Type *VecTy) {
7685 Type *EltTy = cast<VectorType>(VecTy)->getElementType();
7686 if (EltTy->isFloatTy() || EltTy->isDoubleTy() || EltTy->isIntegerTy(64) ||
7687 EltTy->isIntegerTy(32) || EltTy->isPointerTy())
7688 return true;
7689 if (EltTy->isIntegerTy(16) || EltTy->isIntegerTy(8) || EltTy->isHalfTy())
7690 return ST->hasBWI();
7691 if (EltTy->isBFloatTy())
7692 return ST->hasBF16();
7693 return false;
7694 };
7695 if (ST->hasAVX512() && isSupportedOnAVX512(VecTy))
7697 Opcode, VecTy, Factor, Indices, Alignment,
7698 AddressSpace, CostKind, UseMaskForCond, UseMaskForGaps);
7699
7700 if (UseMaskForCond || UseMaskForGaps)
7701 return BaseT::getInterleavedMemoryOpCost(Opcode, VecTy, Factor, Indices,
7702 Alignment, AddressSpace, CostKind,
7703 UseMaskForCond, UseMaskForGaps);
7704
7705 // Get estimation for interleaved load/store operations for SSE-AVX2.
7706 // As opposed to AVX-512, SSE-AVX2 do not have generic shuffles that allow
7707 // computing the cost using a generic formula as a function of generic
7708 // shuffles. We therefore use a lookup table instead, filled according to
7709 // the instruction sequences that codegen currently generates.
7710
7711 // VecTy for interleave memop is <VF*Factor x Elt>.
7712 // So, for VF=4, Interleave Factor = 3, Element type = i32 we have
7713 // VecTy = <12 x i32>.
7714 MVT LegalVT = getTypeLegalizationCost(VecTy).second;
7715
7716 // This function can be called with VecTy=<6xi128>, Factor=3, in which case
7717 // the VF=2, while v2i128 is an unsupported MVT vector type
7718 // (see MachineValueType.h::getVectorVT()).
7719 if (!LegalVT.isVector())
7720 return BaseT::getInterleavedMemoryOpCost(Opcode, VecTy, Factor, Indices,
7721 Alignment, AddressSpace, CostKind);
7722
7723 unsigned VF = VecTy->getNumElements() / Factor;
7724 Type *ScalarTy = VecTy->getElementType();
7725 // Deduplicate entries, model floats/pointers as appropriately-sized integers.
7726 if (!ScalarTy->isIntegerTy())
7727 ScalarTy =
7728 Type::getIntNTy(ScalarTy->getContext(), DL.getTypeSizeInBits(ScalarTy));
7729
7730 // Get the cost of all the memory operations.
7731 // FIXME: discount dead loads.
7732 InstructionCost MemOpCosts =
7733 getMemoryOpCost(Opcode, VecTy, Alignment, AddressSpace, CostKind);
7734
7735 auto *VT = FixedVectorType::get(ScalarTy, VF);
7736 EVT ETy = TLI->getValueType(DL, VT);
7737 if (!ETy.isSimple())
7738 return BaseT::getInterleavedMemoryOpCost(Opcode, VecTy, Factor, Indices,
7739 Alignment, AddressSpace, CostKind);
7740
7741 // TODO: Complete for other data-types and strides.
7742 // Each combination of Stride, element bit width and VF results in a different
7743 // sequence; The cost tables are therefore accessed with:
7744 // Factor (stride) and VectorType=VFxiN.
7745 // The Cost accounts only for the shuffle sequence;
7746 // The cost of the loads/stores is accounted for separately.
7747 //
7748 static const CostTblEntry AVX2InterleavedLoadTbl[] = {
7749 {2, MVT::v2i8, 2}, // (load 4i8 and) deinterleave into 2 x 2i8
7750 {2, MVT::v4i8, 2}, // (load 8i8 and) deinterleave into 2 x 4i8
7751 {2, MVT::v8i8, 2}, // (load 16i8 and) deinterleave into 2 x 8i8
7752 {2, MVT::v16i8, 4}, // (load 32i8 and) deinterleave into 2 x 16i8
7753 {2, MVT::v32i8, 6}, // (load 64i8 and) deinterleave into 2 x 32i8
7754
7755 {2, MVT::v8i16, 6}, // (load 16i16 and) deinterleave into 2 x 8i16
7756 {2, MVT::v16i16, 9}, // (load 32i16 and) deinterleave into 2 x 16i16
7757 {2, MVT::v32i16, 18}, // (load 64i16 and) deinterleave into 2 x 32i16
7758
7759 {2, MVT::v8i32, 4}, // (load 16i32 and) deinterleave into 2 x 8i32
7760 {2, MVT::v16i32, 8}, // (load 32i32 and) deinterleave into 2 x 16i32
7761 {2, MVT::v32i32, 16}, // (load 64i32 and) deinterleave into 2 x 32i32
7762
7763 {2, MVT::v4i64, 4}, // (load 8i64 and) deinterleave into 2 x 4i64
7764 {2, MVT::v8i64, 8}, // (load 16i64 and) deinterleave into 2 x 8i64
7765 {2, MVT::v16i64, 16}, // (load 32i64 and) deinterleave into 2 x 16i64
7766 {2, MVT::v32i64, 32}, // (load 64i64 and) deinterleave into 2 x 32i64
7767
7768 {3, MVT::v2i8, 3}, // (load 6i8 and) deinterleave into 3 x 2i8
7769 {3, MVT::v4i8, 3}, // (load 12i8 and) deinterleave into 3 x 4i8
7770 {3, MVT::v8i8, 6}, // (load 24i8 and) deinterleave into 3 x 8i8
7771 {3, MVT::v16i8, 11}, // (load 48i8 and) deinterleave into 3 x 16i8
7772 {3, MVT::v32i8, 14}, // (load 96i8 and) deinterleave into 3 x 32i8
7773
7774 {3, MVT::v2i16, 5}, // (load 6i16 and) deinterleave into 3 x 2i16
7775 {3, MVT::v4i16, 7}, // (load 12i16 and) deinterleave into 3 x 4i16
7776 {3, MVT::v8i16, 9}, // (load 24i16 and) deinterleave into 3 x 8i16
7777 {3, MVT::v16i16, 28}, // (load 48i16 and) deinterleave into 3 x 16i16
7778 {3, MVT::v32i16, 56}, // (load 96i16 and) deinterleave into 3 x 32i16
7779
7780 {3, MVT::v2i32, 3}, // (load 6i32 and) deinterleave into 3 x 2i32
7781 {3, MVT::v4i32, 3}, // (load 12i32 and) deinterleave into 3 x 4i32
7782 {3, MVT::v8i32, 7}, // (load 24i32 and) deinterleave into 3 x 8i32
7783 {3, MVT::v16i32, 14}, // (load 48i32 and) deinterleave into 3 x 16i32
7784 {3, MVT::v32i32, 32}, // (load 96i32 and) deinterleave into 3 x 32i32
7785
7786 {3, MVT::v2i64, 1}, // (load 6i64 and) deinterleave into 3 x 2i64
7787 {3, MVT::v4i64, 5}, // (load 12i64 and) deinterleave into 3 x 4i64
7788 {3, MVT::v8i64, 10}, // (load 24i64 and) deinterleave into 3 x 8i64
7789 {3, MVT::v16i64, 20}, // (load 48i64 and) deinterleave into 3 x 16i64
7790
7791 {4, MVT::v2i8, 4}, // (load 8i8 and) deinterleave into 4 x 2i8
7792 {4, MVT::v4i8, 4}, // (load 16i8 and) deinterleave into 4 x 4i8
7793 {4, MVT::v8i8, 12}, // (load 32i8 and) deinterleave into 4 x 8i8
7794 {4, MVT::v16i8, 24}, // (load 64i8 and) deinterleave into 4 x 16i8
7795 {4, MVT::v32i8, 56}, // (load 128i8 and) deinterleave into 4 x 32i8
7796
7797 {4, MVT::v2i16, 6}, // (load 8i16 and) deinterleave into 4 x 2i16
7798 {4, MVT::v4i16, 17}, // (load 16i16 and) deinterleave into 4 x 4i16
7799 {4, MVT::v8i16, 33}, // (load 32i16 and) deinterleave into 4 x 8i16
7800 {4, MVT::v16i16, 75}, // (load 64i16 and) deinterleave into 4 x 16i16
7801 {4, MVT::v32i16, 150}, // (load 128i16 and) deinterleave into 4 x 32i16
7802
7803 {4, MVT::v2i32, 4}, // (load 8i32 and) deinterleave into 4 x 2i32
7804 {4, MVT::v4i32, 8}, // (load 16i32 and) deinterleave into 4 x 4i32
7805 {4, MVT::v8i32, 16}, // (load 32i32 and) deinterleave into 4 x 8i32
7806 {4, MVT::v16i32, 32}, // (load 64i32 and) deinterleave into 4 x 16i32
7807 {4, MVT::v32i32, 68}, // (load 128i32 and) deinterleave into 4 x 32i32
7808
7809 {4, MVT::v2i64, 6}, // (load 8i64 and) deinterleave into 4 x 2i64
7810 {4, MVT::v4i64, 8}, // (load 16i64 and) deinterleave into 4 x 4i64
7811 {4, MVT::v8i64, 20}, // (load 32i64 and) deinterleave into 4 x 8i64
7812 {4, MVT::v16i64, 40}, // (load 64i64 and) deinterleave into 4 x 16i64
7813
7814 {6, MVT::v2i8, 6}, // (load 12i8 and) deinterleave into 6 x 2i8
7815 {6, MVT::v4i8, 14}, // (load 24i8 and) deinterleave into 6 x 4i8
7816 {6, MVT::v8i8, 18}, // (load 48i8 and) deinterleave into 6 x 8i8
7817 {6, MVT::v16i8, 43}, // (load 96i8 and) deinterleave into 6 x 16i8
7818 {6, MVT::v32i8, 82}, // (load 192i8 and) deinterleave into 6 x 32i8
7819
7820 {6, MVT::v2i16, 13}, // (load 12i16 and) deinterleave into 6 x 2i16
7821 {6, MVT::v4i16, 9}, // (load 24i16 and) deinterleave into 6 x 4i16
7822 {6, MVT::v8i16, 39}, // (load 48i16 and) deinterleave into 6 x 8i16
7823 {6, MVT::v16i16, 106}, // (load 96i16 and) deinterleave into 6 x 16i16
7824 {6, MVT::v32i16, 212}, // (load 192i16 and) deinterleave into 6 x 32i16
7825
7826 {6, MVT::v2i32, 6}, // (load 12i32 and) deinterleave into 6 x 2i32
7827 {6, MVT::v4i32, 15}, // (load 24i32 and) deinterleave into 6 x 4i32
7828 {6, MVT::v8i32, 31}, // (load 48i32 and) deinterleave into 6 x 8i32
7829 {6, MVT::v16i32, 64}, // (load 96i32 and) deinterleave into 6 x 16i32
7830
7831 {6, MVT::v2i64, 6}, // (load 12i64 and) deinterleave into 6 x 2i64
7832 {6, MVT::v4i64, 18}, // (load 24i64 and) deinterleave into 6 x 4i64
7833 {6, MVT::v8i64, 36}, // (load 48i64 and) deinterleave into 6 x 8i64
7834
7835 {8, MVT::v8i32, 40} // (load 64i32 and) deinterleave into 8 x 8i32
7836 };
7837
7838 static const CostTblEntry SSSE3InterleavedLoadTbl[] = {
7839 {2, MVT::v4i16, 2}, // (load 8i16 and) deinterleave into 2 x 4i16
7840 };
7841
7842 static const CostTblEntry SSE2InterleavedLoadTbl[] = {
7843 {2, MVT::v2i16, 2}, // (load 4i16 and) deinterleave into 2 x 2i16
7844 {2, MVT::v4i16, 7}, // (load 8i16 and) deinterleave into 2 x 4i16
7845
7846 {2, MVT::v2i32, 2}, // (load 4i32 and) deinterleave into 2 x 2i32
7847 {2, MVT::v4i32, 2}, // (load 8i32 and) deinterleave into 2 x 4i32
7848
7849 {2, MVT::v2i64, 2}, // (load 4i64 and) deinterleave into 2 x 2i64
7850 };
7851
7852 static const CostTblEntry AVX2InterleavedStoreTbl[] = {
7853 {2, MVT::v16i8, 3}, // interleave 2 x 16i8 into 32i8 (and store)
7854 {2, MVT::v32i8, 4}, // interleave 2 x 32i8 into 64i8 (and store)
7855
7856 {2, MVT::v8i16, 3}, // interleave 2 x 8i16 into 16i16 (and store)
7857 {2, MVT::v16i16, 4}, // interleave 2 x 16i16 into 32i16 (and store)
7858 {2, MVT::v32i16, 8}, // interleave 2 x 32i16 into 64i16 (and store)
7859
7860 {2, MVT::v4i32, 2}, // interleave 2 x 4i32 into 8i32 (and store)
7861 {2, MVT::v8i32, 4}, // interleave 2 x 8i32 into 16i32 (and store)
7862 {2, MVT::v16i32, 8}, // interleave 2 x 16i32 into 32i32 (and store)
7863 {2, MVT::v32i32, 16}, // interleave 2 x 32i32 into 64i32 (and store)
7864
7865 {2, MVT::v2i64, 2}, // interleave 2 x 2i64 into 4i64 (and store)
7866 {2, MVT::v4i64, 4}, // interleave 2 x 4i64 into 8i64 (and store)
7867 {2, MVT::v8i64, 8}, // interleave 2 x 8i64 into 16i64 (and store)
7868 {2, MVT::v16i64, 16}, // interleave 2 x 16i64 into 32i64 (and store)
7869 {2, MVT::v32i64, 32}, // interleave 2 x 32i64 into 64i64 (and store)
7870
7871 {3, MVT::v2i8, 4}, // interleave 3 x 2i8 into 6i8 (and store)
7872 {3, MVT::v4i8, 4}, // interleave 3 x 4i8 into 12i8 (and store)
7873 {3, MVT::v8i8, 6}, // interleave 3 x 8i8 into 24i8 (and store)
7874 {3, MVT::v16i8, 11}, // interleave 3 x 16i8 into 48i8 (and store)
7875 {3, MVT::v32i8, 13}, // interleave 3 x 32i8 into 96i8 (and store)
7876
7877 {3, MVT::v2i16, 4}, // interleave 3 x 2i16 into 6i16 (and store)
7878 {3, MVT::v4i16, 6}, // interleave 3 x 4i16 into 12i16 (and store)
7879 {3, MVT::v8i16, 12}, // interleave 3 x 8i16 into 24i16 (and store)
7880 {3, MVT::v16i16, 27}, // interleave 3 x 16i16 into 48i16 (and store)
7881 {3, MVT::v32i16, 54}, // interleave 3 x 32i16 into 96i16 (and store)
7882
7883 {3, MVT::v2i32, 4}, // interleave 3 x 2i32 into 6i32 (and store)
7884 {3, MVT::v4i32, 5}, // interleave 3 x 4i32 into 12i32 (and store)
7885 {3, MVT::v8i32, 11}, // interleave 3 x 8i32 into 24i32 (and store)
7886 {3, MVT::v16i32, 22}, // interleave 3 x 16i32 into 48i32 (and store)
7887 {3, MVT::v32i32, 48}, // interleave 3 x 32i32 into 96i32 (and store)
7888
7889 {3, MVT::v2i64, 4}, // interleave 3 x 2i64 into 6i64 (and store)
7890 {3, MVT::v4i64, 6}, // interleave 3 x 4i64 into 12i64 (and store)
7891 {3, MVT::v8i64, 12}, // interleave 3 x 8i64 into 24i64 (and store)
7892 {3, MVT::v16i64, 24}, // interleave 3 x 16i64 into 48i64 (and store)
7893
7894 {4, MVT::v2i8, 4}, // interleave 4 x 2i8 into 8i8 (and store)
7895 {4, MVT::v4i8, 4}, // interleave 4 x 4i8 into 16i8 (and store)
7896 {4, MVT::v8i8, 4}, // interleave 4 x 8i8 into 32i8 (and store)
7897 {4, MVT::v16i8, 8}, // interleave 4 x 16i8 into 64i8 (and store)
7898 {4, MVT::v32i8, 12}, // interleave 4 x 32i8 into 128i8 (and store)
7899
7900 {4, MVT::v2i16, 2}, // interleave 4 x 2i16 into 8i16 (and store)
7901 {4, MVT::v4i16, 6}, // interleave 4 x 4i16 into 16i16 (and store)
7902 {4, MVT::v8i16, 10}, // interleave 4 x 8i16 into 32i16 (and store)
7903 {4, MVT::v16i16, 32}, // interleave 4 x 16i16 into 64i16 (and store)
7904 {4, MVT::v32i16, 64}, // interleave 4 x 32i16 into 128i16 (and store)
7905
7906 {4, MVT::v2i32, 5}, // interleave 4 x 2i32 into 8i32 (and store)
7907 {4, MVT::v4i32, 6}, // interleave 4 x 4i32 into 16i32 (and store)
7908 {4, MVT::v8i32, 16}, // interleave 4 x 8i32 into 32i32 (and store)
7909 {4, MVT::v16i32, 32}, // interleave 4 x 16i32 into 64i32 (and store)
7910 {4, MVT::v32i32, 64}, // interleave 4 x 32i32 into 128i32 (and store)
7911
7912 {4, MVT::v2i64, 6}, // interleave 4 x 2i64 into 8i64 (and store)
7913 {4, MVT::v4i64, 8}, // interleave 4 x 4i64 into 16i64 (and store)
7914 {4, MVT::v8i64, 20}, // interleave 4 x 8i64 into 32i64 (and store)
7915 {4, MVT::v16i64, 40}, // interleave 4 x 16i64 into 64i64 (and store)
7916
7917 {6, MVT::v2i8, 7}, // interleave 6 x 2i8 into 12i8 (and store)
7918 {6, MVT::v4i8, 9}, // interleave 6 x 4i8 into 24i8 (and store)
7919 {6, MVT::v8i8, 16}, // interleave 6 x 8i8 into 48i8 (and store)
7920 {6, MVT::v16i8, 27}, // interleave 6 x 16i8 into 96i8 (and store)
7921 {6, MVT::v32i8, 90}, // interleave 6 x 32i8 into 192i8 (and store)
7922
7923 {6, MVT::v2i16, 10}, // interleave 6 x 2i16 into 12i16 (and store)
7924 {6, MVT::v4i16, 15}, // interleave 6 x 4i16 into 24i16 (and store)
7925 {6, MVT::v8i16, 21}, // interleave 6 x 8i16 into 48i16 (and store)
7926 {6, MVT::v16i16, 58}, // interleave 6 x 16i16 into 96i16 (and store)
7927 {6, MVT::v32i16, 90}, // interleave 6 x 32i16 into 192i16 (and store)
7928
7929 {6, MVT::v2i32, 9}, // interleave 6 x 2i32 into 12i32 (and store)
7930 {6, MVT::v4i32, 12}, // interleave 6 x 4i32 into 24i32 (and store)
7931 {6, MVT::v8i32, 33}, // interleave 6 x 8i32 into 48i32 (and store)
7932 {6, MVT::v16i32, 66}, // interleave 6 x 16i32 into 96i32 (and store)
7933
7934 {6, MVT::v2i64, 8}, // interleave 6 x 2i64 into 12i64 (and store)
7935 {6, MVT::v4i64, 15}, // interleave 6 x 4i64 into 24i64 (and store)
7936 {6, MVT::v8i64, 30}, // interleave 6 x 8i64 into 48i64 (and store)
7937 };
7938
7939 static const CostTblEntry SSE2InterleavedStoreTbl[] = {
7940 {2, MVT::v2i8, 1}, // interleave 2 x 2i8 into 4i8 (and store)
7941 {2, MVT::v4i8, 1}, // interleave 2 x 4i8 into 8i8 (and store)
7942 {2, MVT::v8i8, 1}, // interleave 2 x 8i8 into 16i8 (and store)
7943
7944 {2, MVT::v2i16, 1}, // interleave 2 x 2i16 into 4i16 (and store)
7945 {2, MVT::v4i16, 1}, // interleave 2 x 4i16 into 8i16 (and store)
7946
7947 {2, MVT::v2i32, 1}, // interleave 2 x 2i32 into 4i32 (and store)
7948 };
7949
7950 if (Opcode == Instruction::Load) {
7951 auto GetDiscountedCost = [Factor, NumMembers = Indices.size(),
7952 MemOpCosts](const CostTblEntry *Entry) {
7953 // NOTE: this is just an approximation!
7954 // It can over/under -estimate the cost!
7955 return MemOpCosts + divideCeil(NumMembers * Entry->Cost, Factor);
7956 };
7957
7958 if (ST->hasAVX2())
7959 if (const auto *Entry = CostTableLookup(AVX2InterleavedLoadTbl, Factor,
7960 ETy.getSimpleVT()))
7961 return GetDiscountedCost(Entry);
7962
7963 if (ST->hasSSSE3())
7964 if (const auto *Entry = CostTableLookup(SSSE3InterleavedLoadTbl, Factor,
7965 ETy.getSimpleVT()))
7966 return GetDiscountedCost(Entry);
7967
7968 if (ST->hasSSE2())
7969 if (const auto *Entry = CostTableLookup(SSE2InterleavedLoadTbl, Factor,
7970 ETy.getSimpleVT()))
7971 return GetDiscountedCost(Entry);
7972 } else {
7973 assert(Opcode == Instruction::Store &&
7974 "Expected Store Instruction at this point");
7975 assert((!Indices.size() || Indices.size() == Factor) &&
7976 "Interleaved store only supports fully-interleaved groups.");
7977 if (ST->hasAVX2())
7978 if (const auto *Entry = CostTableLookup(AVX2InterleavedStoreTbl, Factor,
7979 ETy.getSimpleVT()))
7980 return MemOpCosts + Entry->Cost;
7981
7982 if (ST->hasSSE2())
7983 if (const auto *Entry = CostTableLookup(SSE2InterleavedStoreTbl, Factor,
7984 ETy.getSimpleVT()))
7985 return MemOpCosts + Entry->Cost;
7986 }
7987
7988 return BaseT::getInterleavedMemoryOpCost(Opcode, VecTy, Factor, Indices,
7989 Alignment, AddressSpace, CostKind,
7990 UseMaskForCond, UseMaskForGaps);
7991}
7992
7994 StackOffset BaseOffset,
7995 bool HasBaseReg, int64_t Scale,
7996 unsigned AddrSpace) const {
7997 // Scaling factors are not free at all.
7998 // An indexed folded instruction, i.e., inst (reg1, reg2, scale),
7999 // will take 2 allocations in the out of order engine instead of 1
8000 // for plain addressing mode, i.e. inst (reg1).
8001 // E.g.,
8002 // vaddps (%rsi,%rdx), %ymm0, %ymm1
8003 // Requires two allocations (one for the load, one for the computation)
8004 // whereas:
8005 // vaddps (%rsi), %ymm0, %ymm1
8006 // Requires just 1 allocation, i.e., freeing allocations for other operations
8007 // and having less micro operations to execute.
8008 //
8009 // For some X86 architectures, this is even worse because for instance for
8010 // stores, the complex addressing mode forces the instruction to use the
8011 // "load" ports instead of the dedicated "store" port.
8012 // E.g., on Haswell:
8013 // vmovaps %ymm1, (%r8, %rdi) can use port 2 or 3.
8014 // vmovaps %ymm1, (%r8) can use port 2, 3, or 7.
8016 AM.BaseGV = BaseGV;
8017 AM.BaseOffs = BaseOffset.getFixed();
8018 AM.HasBaseReg = HasBaseReg;
8019 AM.Scale = Scale;
8020 AM.ScalableOffset = BaseOffset.getScalable();
8021 if (getTLI()->isLegalAddressingMode(DL, AM, Ty, AddrSpace))
8022 // Scale represents reg2 * scale, thus account for 1
8023 // as soon as we use a second register.
8024 return AM.Scale != 0;
8026}
8027
8029 // TODO: Hook MispredictPenalty of SchedMachineModel into this.
8030 return 14;
8031}
8032
8034 unsigned Bits = Ty->getScalarSizeInBits();
8035
8036 // XOP has v16i8/v8i16/v4i32/v2i64 variable vector shifts.
8037 // Splitting for v32i8/v16i16 on XOP+AVX2 targets is still preferred.
8038 if (ST->hasXOP() && (Bits == 8 || Bits == 16 || Bits == 32 || Bits == 64))
8039 return false;
8040
8041 // AVX2 has vpsllv[dq] instructions (and other shifts) that make variable
8042 // shifts just as cheap as scalar ones.
8043 if (ST->hasAVX2() && (Bits == 32 || Bits == 64))
8044 return false;
8045
8046 // AVX512BW has shifts such as vpsllvw.
8047 if (ST->hasBWI() && Bits == 16)
8048 return false;
8049
8050 // Otherwise, it's significantly cheaper to shift by a scalar amount than by a
8051 // fully general vector.
8052 return true;
8053}
8054
8055unsigned X86TTIImpl::getStoreMinimumVF(unsigned VF, Type *ScalarMemTy,
8056 Type *ScalarValTy, Align Alignment,
8057 unsigned AddrSpace) const {
8058 if (ST->hasF16C() && ScalarMemTy->isHalfTy()) {
8059 return 4;
8060 }
8061 return BaseT::getStoreMinimumVF(VF, ScalarMemTy, ScalarValTy, Alignment,
8062 AddrSpace);
8063}
8064
8066 SmallVectorImpl<Use *> &Ops) const {
8067 using namespace llvm::PatternMatch;
8068
8069 if (I->getOpcode() == Instruction::And &&
8070 (ST->hasBMI() || (I->getType()->isVectorTy() && ST->hasSSE2()))) {
8071 for (auto &Op : I->operands()) {
8072 // (and X, (not Y)) -> (andn X, Y)
8073 if (match(Op.get(), m_Not(m_Value())) && !I->getType()->isIntegerTy(8)) {
8074 Ops.push_back(&Op);
8075 return true;
8076 }
8077 // (and X, (splat (not Y))) -> (andn X, (splat Y))
8078 if (match(Op.get(),
8080 m_Value(), m_ZeroMask()))) {
8081 Use &InsertElt = cast<Instruction>(Op)->getOperandUse(0);
8082 Use &Not = cast<Instruction>(InsertElt)->getOperandUse(1);
8083 Ops.push_back(&Not);
8084 Ops.push_back(&InsertElt);
8085 Ops.push_back(&Op);
8086 return true;
8087 }
8088 }
8089 }
8090
8091 FixedVectorType *VTy = dyn_cast<FixedVectorType>(I->getType());
8092 if (!VTy)
8093 return false;
8094
8095 if (I->getOpcode() == Instruction::Mul &&
8096 VTy->getElementType()->isIntegerTy(64)) {
8097 for (auto &Op : I->operands()) {
8098 // Make sure we are not already sinking this operand
8099 if (any_of(Ops, [&](Use *U) { return U->get() == Op; }))
8100 continue;
8101
8102 // Look for PMULDQ pattern where the input is a sext_inreg from vXi32 or
8103 // the PMULUDQ pattern where the input is a zext_inreg from vXi32.
8104 if (ST->hasSSE41() &&
8105 match(Op.get(), m_AShr(m_Shl(m_Value(), m_SpecificInt(32)),
8106 m_SpecificInt(32)))) {
8107 Ops.push_back(&cast<Instruction>(Op)->getOperandUse(0));
8108 Ops.push_back(&Op);
8109 } else if (ST->hasSSE2() &&
8110 match(Op.get(),
8111 m_And(m_Value(), m_SpecificInt(UINT64_C(0xffffffff))))) {
8112 Ops.push_back(&Op);
8113 }
8114 }
8115
8116 return !Ops.empty();
8117 }
8118
8119 // A uniform shift amount in a vector shift or funnel shift may be much
8120 // cheaper than a generic variable vector shift, so make that pattern visible
8121 // to SDAG by sinking the shuffle instruction next to the shift.
8122 int ShiftAmountOpNum = -1;
8123 if (I->isShift())
8124 ShiftAmountOpNum = 1;
8125 else if (auto *II = dyn_cast<IntrinsicInst>(I)) {
8126 if (II->getIntrinsicID() == Intrinsic::fshl ||
8127 II->getIntrinsicID() == Intrinsic::fshr)
8128 ShiftAmountOpNum = 2;
8129 }
8130
8131 if (ShiftAmountOpNum == -1)
8132 return false;
8133
8134 auto *Shuf = dyn_cast<ShuffleVectorInst>(I->getOperand(ShiftAmountOpNum));
8135 if (Shuf && getSplatIndex(Shuf->getShuffleMask()) >= 0 &&
8136 isVectorShiftByScalarCheap(I->getType())) {
8137 Ops.push_back(&I->getOperandUse(ShiftAmountOpNum));
8138 return true;
8139 }
8140
8141 return false;
8142}
8143
8145 bool HasEGPR = ST->hasEGPR();
8146 const TargetMachine &TM = getTLI()->getTargetMachine();
8147
8148 for (User *U : F.users()) {
8150 if (!CB || CB->getCalledOperand() != &F)
8151 continue;
8152 Function *CallerFunc = CB->getFunction();
8153 if (TM.getSubtarget<X86Subtarget>(*CallerFunc).hasEGPR() != HasEGPR)
8154 return false;
8155 }
8156
8157 return true;
8158}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
unsigned Imm
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
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
uint64_t IntrinsicInst * II
#define P(N)
This file implements the SmallBitVector class.
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
This file describes how to lower LLVM code to machine code.
This pass exposes codegen information to IR-level passes.
static unsigned getBitWidth(Type *Ty, const DataLayout &DL)
Returns the bitwidth of the given scalar or pointer type.
CostTblEntryT< CostKindCosts > CostKindTblEntry
static bool isLegalMaskedLoadStore(Type *ScalarTy, const X86Subtarget *ST)
TypeConversionCostTblEntryT< CostKindCosts > TypeConversionCostKindTblEntry
This file a TargetTransformInfoImplBase conforming object specific to the X86 target machine.
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:329
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 getArithmeticInstrCost(unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind, TTI::OperandValueInfo Opd1Info={TTI::OK_AnyValue, TTI::OP_None}, TTI::OperandValueInfo Opd2Info={TTI::OK_AnyValue, TTI::OP_None}, ArrayRef< const Value * > Args={}, const Instruction *CxtI=nullptr) const override
InstructionCost getMinMaxReductionCost(Intrinsic::ID IID, VectorType *Ty, FastMathFlags FMF, TTI::TargetCostKind CostKind) const override
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 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 getShuffleCost(TTI::ShuffleKind Kind, VectorType *DstTy, VectorType *SrcTy, TTI::TargetCostKind CostKind, ArrayRef< int > Mask, int Index, VectorType *SubTp, ArrayRef< const Value * > Args={}, const Instruction *CxtI=nullptr) 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:730
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.
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:68
Machine Value Type.
bool is128BitVector() const
Return true if this is a 128-bit vector type.
uint64_t getScalarSizeInBits() const
unsigned getVectorNumElements() const
bool isVector() const
Return true if this is a vector value type.
bool isInteger() const
Return true if this is an integer or a vector integer type.
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
bool isScalarInteger() const
Return true if this is an integer, not including vectors.
static MVT getVectorVT(MVT VT, unsigned NumElements)
MVT getVectorElementType() const
MVT getScalarType() const
If this is a vector, return the element type, otherwise return this.
Information for memory intrinsic cost model.
This class represents an analyzed expression in the program.
The main scalar evolution driver.
static LLVM_ABI bool isIdentityMask(ArrayRef< int > Mask, int NumSrcElts)
Return true if this shuffle mask chooses elements from exactly one source vector without lane crossin...
This is a 'bitvector' (really, a variable-sized bit array), optimized for the case when the array is ...
bool test(unsigned Idx) const
Returns true if bit Idx is set.
size_type size() const
Returns the number of bits in this bitvector.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StackOffset holds a fixed and a scalable offset in bytes.
Definition TypeSize.h:30
static StackOffset getScalable(int64_t Scalable)
Definition TypeSize.h:40
static StackOffset getFixed(int64_t Fixed)
Definition TypeSize.h:39
virtual MVT getRegisterTypeForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const
Certain combinations of ABIs, Targets and features require that types are legal for some operations a...
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
Primary interface to the complete machine description for the target machine.
const STC & getSubtarget(const Function &F) const
This method returns a pointer to the specified type of TargetSubtargetInfo.
virtual const TargetSubtargetInfo * getSubtargetImpl(const Function &) const
Virtual method implemented by subclasses that returns a reference to that target's TargetSubtargetInf...
virtual const TargetLowering * getTargetLowering() const
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
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
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
bool isLegalAltInstr(VectorType *VecTy, unsigned Opcode0, unsigned Opcode1, const SmallBitVector &OpcodeMask) const override
TypeSize getRegisterBitWidth(TargetTransformInfo::RegisterKind K) const override
bool isVectorShiftByScalarCheap(Type *Ty) const override
bool isLegalMaskedGather(Type *DataType, Align Alignment) const override
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 *CxtI=nullptr) 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
bool forceScalarizeMaskedGather(VectorType *VTy, Align Alignment) const override
InstructionCost getBranchMispredictPenalty() const override
bool isExpensiveToSpeculativelyExecute(const Instruction *I) const override
bool hasConditionalLoadStoreForType(Type *Ty, bool IsStore) const override
bool isLegalMaskedStore(Type *DataType, Align Alignment, unsigned AddressSpace, TTI::MaskKind MaskKind=TTI::MaskKind::VariableOrConstantMask) const override
std::optional< unsigned > getCacheSize(TargetTransformInfo::CacheLevel Level) const override
InstructionCost getArithmeticInstrCost(unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind, TTI::OperandValueInfo Op1Info={TTI::OK_AnyValue, TTI::OP_None}, TTI::OperandValueInfo Op2Info={TTI::OK_AnyValue, TTI::OP_None}, ArrayRef< const Value * > Args={}, const Instruction *CxtI=nullptr) const override
bool isLegalMaskedGatherScatter(Type *DataType, Align Alignment) const
bool isLegalMaskedLoad(Type *DataType, Align Alignment, unsigned AddressSpace, TTI::MaskKind MaskKind=TTI::MaskKind::VariableOrConstantMask) const override
bool enableInterleavedAccessVectorization() const override
unsigned getLoadStoreVecRegBitWidth(unsigned AS) const override
unsigned getNumberOfRegisters(unsigned ClassID) const override
InstructionCost getVectorInstrCost(unsigned Opcode, Type *Val, TTI::TargetCostKind CostKind, unsigned Index, const Value *Op0, const Value *Op1, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const override
bool isLegalMaskedScatter(Type *DataType, Align Alignment) const override
unsigned getStoreMinimumVF(unsigned VF, Type *ScalarMemTy, Type *ScalarValTy, Align Alignment, unsigned AddrSpace) const override
bool hasDivRemOp(Type *DataType, bool IsSigned) const override
bool isLegalMaskedCompressStore(Type *DataType, Align Alignment) const override
InstructionCost getIntImmCostIntrin(Intrinsic::ID IID, unsigned Idx, const APInt &Imm, Type *Ty, TTI::TargetCostKind CostKind) const override
bool supportsEfficientVectorElementLoadStore() const override
InstructionCost getIntImmCostInst(unsigned Opcode, unsigned Idx, const APInt &Imm, Type *Ty, TTI::TargetCostKind CostKind, Instruction *Inst=nullptr) const override
bool isLegalMaskedExpandLoad(Type *DataType, Align Alignment) const override
TTI::PopcntSupportKind getPopcntSupport(unsigned TyWidth) const override
bool isFCmpOrdCheaperThanFCmpZero(Type *Ty) const override
TTI::MemCmpExpansionOptions enableMemCmpExpansion(bool OptSize, bool IsZeroCmp) const override
InstructionCost 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
InstructionCost getAltInstrCost(VectorType *VecTy, unsigned Opcode0, unsigned Opcode1, const SmallBitVector &OpcodeMask, TTI::TargetCostKind CostKind) const override
bool forceScalarizeMaskedScatter(VectorType *VTy, Align Alignment) const override
InstructionCost getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA, TTI::TargetCostKind CostKind) const override
Get intrinsic cost based on arguments.
bool isProfitableToSinkOperands(Instruction *I, SmallVectorImpl< Use * > &Ops) const override
InstructionCost getScalarizationOverhead(VectorType *Ty, const APInt &DemandedElts, bool Insert, bool Extract, TTI::TargetCostKind CostKind, bool ForPoisonSrc=true, ArrayRef< Value * > VL={}, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const override
Estimate the overhead of scalarizing an instruction.
InstructionCost getArithmeticReductionCost(unsigned Opcode, VectorType *Ty, std::optional< FastMathFlags > FMF, TTI::TargetCostKind CostKind) const override
InstructionCost getGatherScatterOpCost(const MemIntrinsicCostAttributes &MICA, TTI::TargetCostKind CostKind) const
Calculate the cost of Gather / Scatter operation.
InstructionCost getMemoryOpCost(unsigned Opcode, Type *Src, Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind, TTI::OperandValueInfo OpInfo={TTI::OK_AnyValue, TTI::OP_None}, const Instruction *I=nullptr) const override
InstructionCost getAddressComputationCost(Type *PtrTy, ScalarEvolution *SE, const SCEV *Ptr, TTI::TargetCostKind CostKind) const override
InstructionCost getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy, CmpInst::Predicate VecPred, TTI::TargetCostKind CostKind, TTI::OperandValueInfo Op1Info={TTI::OK_AnyValue, TTI::OP_None}, TTI::OperandValueInfo Op2Info={TTI::OK_AnyValue, TTI::OP_None}, const Instruction *I=nullptr) const override
bool isLSRCostLess(const TargetTransformInfo::LSRCost &C1, const TargetTransformInfo::LSRCost &C2) const override
constexpr 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:24
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
Definition ISDOpcodes.h:41
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
Definition ISDOpcodes.h:829
@ DELETED_NODE
DELETED_NODE - This is an illegal value that is used to catch errors.
Definition ISDOpcodes.h:45
@ 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:789
@ ADD
Simple integer binary arithmetic operators.
Definition ISDOpcodes.h:264
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
Definition ISDOpcodes.h:890
@ FADD
Simple binary floating point operators.
Definition ISDOpcodes.h:417
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
Definition ISDOpcodes.h:749
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
Definition ISDOpcodes.h:280
@ CLMUL
Carry-less multiplication operations.
Definition ISDOpcodes.h:780
@ CTLZ_ZERO_POISON
Definition ISDOpcodes.h:798
@ PARTIAL_REDUCE_UMLA
@ SIGN_EXTEND
Conversion operators.
Definition ISDOpcodes.h:854
@ 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:374
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
Definition ISDOpcodes.h:806
@ SADDO
RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
Definition ISDOpcodes.h:348
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
Definition ISDOpcodes.h:706
@ SHL
Shift and rotation operations.
Definition ISDOpcodes.h:771
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
Definition ISDOpcodes.h:578
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
Definition ISDOpcodes.h:860
@ FMINNUM
FMINNUM/FMAXNUM - Perform floating-point minimum maximum on two values, following IEEE-754 definition...
@ SMULO
Same for multiplication.
Definition ISDOpcodes.h:356
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
Definition ISDOpcodes.h:729
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
Definition ISDOpcodes.h:988
@ FMINIMUM
FMINIMUM/FMAXIMUM - NaN-propagating minimum/maximum that also treat -0.0 as less than 0....
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
Definition ISDOpcodes.h:936
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition ISDOpcodes.h:741
@ CTTZ_ZERO_POISON
Bit counting operators with a poisoned result for zero inputs.
Definition ISDOpcodes.h:797
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
Definition ISDOpcodes.h:969
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
Definition ISDOpcodes.h:866
@ PARTIAL_REDUCE_SUMLA
@ SADDSAT
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
Definition ISDOpcodes.h:365
SpecificConstantMatch m_ZeroInt()
Convenience matchers for specific integer values.
BinaryOp_match< SrcTy, SpecificConstantMatch, TargetOpcode::G_XOR, true > m_Not(const SrcTy &&Src)
Matches a register not-ed by a G_XOR.
OneUse_match< SubPat > m_OneUse(const SubPat &SP)
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::AShr > m_AShr(const LHS &L, const RHS &R)
ap_match< APInt > m_APIntAllowPoison(const APInt *&Res)
Match APInt while allowing poison in splat vector constants.
specific_intval< false > m_SpecificInt(const APInt &V)
Match a specific integer value or vector with all elements equal to the value.
bool match(Val *V, const Pattern &P)
auto m_Value()
Match an arbitrary value and ignore it.
TwoOps_match< V1_t, V2_t, Instruction::ShuffleVector > m_Shuffle(const V1_t &v1, const V2_t &v2)
Matches ShuffleVectorInst independently of mask value.
OneOps_match< OpTy, Instruction::Load > m_Load(const OpTy &Op)
Matches LoadInst.
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
ThreeOps_match< Val_t, Elt_t, Idx_t, Instruction::InsertElement > m_InsertElt(const Val_t &Val, const Elt_t &Elt, const Idx_t &Idx)
Matches InsertElementInst.
This is an optimization pass for GlobalISel generic memory operations.
constexpr auto not_equal_to(T &&Arg)
Functor variant of std::not_equal_to that can be used as a UnaryPredicate in functional algorithms li...
Definition STLExtras.h: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:119
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
Definition STLExtras.h:2570
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
constexpr T alignDown(U Value, V Align, W Skew=0)
Returns the largest unsigned integer less than or equal to Value and is Skew mod Align.
Definition MathExtras.h: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
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
LLVM_ABI void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true, unsigned Depth=0)
Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition Alignment.h:144
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
constexpr int PoisonMaskElem
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
Definition MathExtras.h:389
DWARFExpression::Operation Op
LLVM_ABI unsigned ComputeNumSignBits(const Value *Op, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CxtI=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.
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:201
LLVM_ABI void processShuffleMasks(ArrayRef< int > Mask, unsigned NumOfSrcRegs, unsigned NumOfDestRegs, unsigned NumOfUsedRegs, function_ref< void()> NoInputAction, function_ref< void(ArrayRef< int >, unsigned, unsigned)> SingleInputAction, function_ref< void(ArrayRef< int >, unsigned, unsigned, bool)> ManyInputsAction)
Splits and processes shuffle mask depending on the number of input and output registers.
const TypeConversionCostTblEntryT< CostType > * ConvertCostTableLookup(ArrayRef< TypeConversionCostTblEntryT< CostType > > Tbl, int ISD, MVT Dst, MVT Src)
Find in type conversion cost table.
Definition CostTable.h:67
LLVM_ABI int getSplatIndex(ArrayRef< int > Mask)
If all non-negative Mask elements are the same value, return that value.
#define N
std::optional< unsigned > operator[](TargetTransformInfo::TargetCostKind Kind) const
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
Cost Table Entry.
Definition CostTable.h:26
Extended Value Type.
Definition ValueTypes.h:35
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
Definition ValueTypes.h:145
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition ValueTypes.h:396
uint64_t getScalarSizeInBits() const
Definition ValueTypes.h:408
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition ValueTypes.h:339
bool isVector() const
Return true if this is a vector value type.
Definition ValueTypes.h:176
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
Definition ValueTypes.h:346
This represents an addressing mode of: BaseGV + BaseOffs + BaseReg + Scale*ScaleReg + ScalableOffset*...
unsigned Insns
TODO: Some of these could be merged.
Returns options for expansion of memcmp. IsZeroCmp is.
Describe known properties for a set of pointers.
Type Conversion Cost Table.
Definition CostTable.h:56