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 TTI::ShuffleKind Kind, VectorType *DstTy, VectorType *SrcTy,
1951 VectorType *SubTp, ArrayRef<const Value *> Args, const Instruction *CxtI,
1952 TTI::VectorInstrContext VIC) const {
1953 assert((Mask.empty() || DstTy->isScalableTy() ||
1954 Mask.size() == DstTy->getElementCount().getKnownMinValue()) &&
1955 "Expected the Mask to match the return size if given");
1956 assert(SrcTy->getScalarType() == DstTy->getScalarType() &&
1957 "Expected the same scalar types");
1958
1959 // 64-bit packed float vectors (v2f32) are widened to type v4f32.
1960 // 64-bit packed integer vectors (v2i32) are widened to type v4i32.
1961 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(SrcTy);
1962
1963 Kind = improveShuffleKindFromMask(Kind, Mask, SrcTy, Index, SubTp);
1964
1965 // If all args are constant than this will be constant folded away.
1966 if (!Args.empty() &&
1967 all_of(Args, [](const Value *Arg) { return isa<Constant>(Arg); }))
1968 return TTI::TCC_Free;
1969
1970 // Recognize a basic concat_vector shuffle.
1971 if (Kind == TTI::SK_PermuteTwoSrc &&
1972 Mask.size() == (2 * SrcTy->getElementCount().getKnownMinValue()) &&
1973 ShuffleVectorInst::isIdentityMask(Mask, Mask.size()))
1977 CostKind, Mask, Mask.size() / 2, SrcTy);
1978
1979 // Treat Transpose as 2-op shuffles - there's no difference in lowering.
1980 if (Kind == TTI::SK_Transpose)
1981 if (LT.second != MVT::v4f64 && LT.second != MVT::v4i64)
1982 Kind = TTI::SK_PermuteTwoSrc;
1983
1984 if (Kind == TTI::SK_Broadcast) {
1985 // For Broadcasts we are splatting the first element from the first input
1986 // register, so only need to reference that input and all the output
1987 // registers are the same.
1988 LT.first = 1;
1989
1990 // If we're broadcasting a load then AVX/AVX2 can do this for free.
1991 // If many-used-load whose every use is one of a small set of operations
1992 // that SLP can rewrite into a single vector lane, codegen can fold it into
1993 // the free broadcast.
1994 using namespace PatternMatch;
1995 auto IsBroadcastLoadFoldUser = [&](const User *U) {
1996 if (isa<InsertElementInst>(U) && U->getOperand(1) == Args[0])
1997 return true;
1998 if (U->getType()->isVectorTy())
1999 return false;
2000 // Terminators (return/branch/switch/indirectbr/resume/invoke EH)
2001 // and phis carry the value across control flow.
2002 if (const auto *I = dyn_cast<Instruction>(U))
2003 if (I->isTerminator() ||
2005 return false;
2006 // Only pure calls can be folded.
2007 if (const auto *CB = dyn_cast<CallBase>(U))
2008 return CB->doesNotAccessMemory() && !CB->mayHaveSideEffects();
2009 return true;
2010 };
2011 auto IsFoldableSLPBroadcastLoad = [&]() {
2012 if (!match(Args[0], m_Load(m_Value())))
2013 return false;
2014 auto *FVT = dyn_cast<FixedVectorType>(DstTy);
2015 if (!FVT)
2016 return false;
2017 // getNumUses() counts each Use, matching the per-lane broadcast
2018 // accounting (a use like `op %x, %x` consumes two broadcast lanes).
2019 if (Args[0]->getNumUses() != FVT->getNumElements())
2020 return false;
2021 return all_of(Args[0]->users(), IsBroadcastLoadFoldUser);
2022 };
2023 if (!Args.empty() &&
2024 (match(Args[0], m_OneUse(m_Load(m_Value()))) ||
2025 IsFoldableSLPBroadcastLoad()) &&
2026 (ST->hasAVX2() ||
2027 (ST->hasAVX() && LT.second.getScalarSizeInBits() >= 32)))
2028 return TTI::TCC_Free;
2029 }
2030
2031 // Attempt to detect a cheaper inlane shuffle, avoiding 128-bit subvector
2032 // permutation.
2033 // Attempt to detect a shuffle mask with a single defined element.
2034 bool IsInLaneShuffle = false;
2035 bool IsSingleElementMask = false;
2036 if (SrcTy->getPrimitiveSizeInBits() > 0 &&
2037 (SrcTy->getPrimitiveSizeInBits() % 128) == 0 &&
2038 SrcTy->getScalarSizeInBits() == LT.second.getScalarSizeInBits() &&
2039 Mask.size() == SrcTy->getElementCount().getKnownMinValue()) {
2040 unsigned NumLanes = SrcTy->getPrimitiveSizeInBits() / 128;
2041 unsigned NumEltsPerLane = Mask.size() / NumLanes;
2042 if ((Mask.size() % NumLanes) == 0) {
2043 IsInLaneShuffle = all_of(enumerate(Mask), [&](const auto &P) {
2044 return P.value() == PoisonMaskElem ||
2045 ((P.value() % Mask.size()) / NumEltsPerLane) ==
2046 (P.index() / NumEltsPerLane);
2047 });
2048 IsSingleElementMask =
2049 (Mask.size() - 1) == static_cast<unsigned>(count_if(Mask, [](int M) {
2050 return M == PoisonMaskElem;
2051 }));
2052 }
2053 }
2054
2055 // Treat <X x bfloat> shuffles as <X x half>.
2056 if (LT.second.isVectorOf(MVT::bf16))
2057 LT.second = LT.second.changeVectorElementType(MVT::f16);
2058
2059 // Subvector extractions are free if they start at the beginning of a
2060 // vector and cheap if the subvectors are aligned.
2061 if (Kind == TTI::SK_ExtractSubvector && LT.second.isVector()) {
2062 int NumElts = LT.second.getVectorNumElements();
2063 if ((Index % NumElts) == 0)
2064 return TTI::TCC_Free;
2065 std::pair<InstructionCost, MVT> SubLT = getTypeLegalizationCost(SubTp);
2066 if (SubLT.second.isVector()) {
2067 int NumSubElts = SubLT.second.getVectorNumElements();
2068 if ((Index % NumSubElts) == 0 && (NumElts % NumSubElts) == 0)
2069 return SubLT.first;
2070 // Handle some cases for widening legalization. For now we only handle
2071 // cases where the original subvector was naturally aligned and evenly
2072 // fit in its legalized subvector type.
2073 // FIXME: Remove some of the alignment restrictions.
2074 // FIXME: We can use permq for 64-bit or larger extracts from 256-bit
2075 // vectors.
2076 int OrigSubElts = cast<FixedVectorType>(SubTp)->getNumElements();
2077 if (NumSubElts > OrigSubElts && (Index % OrigSubElts) == 0 &&
2078 (NumSubElts % OrigSubElts) == 0 &&
2079 LT.second.getVectorElementType() ==
2080 SubLT.second.getVectorElementType() &&
2081 LT.second.getVectorElementType().getSizeInBits() ==
2082 SrcTy->getElementType()->getPrimitiveSizeInBits()) {
2083 assert(NumElts >= NumSubElts && NumElts > OrigSubElts &&
2084 "Unexpected number of elements!");
2085 auto *VecTy = FixedVectorType::get(SrcTy->getElementType(),
2086 LT.second.getVectorNumElements());
2087 auto *SubTy = FixedVectorType::get(SrcTy->getElementType(),
2088 SubLT.second.getVectorNumElements());
2089 int ExtractIndex = alignDown((Index % NumElts), NumSubElts);
2090 InstructionCost ExtractCost =
2092 ExtractIndex, SubTy);
2093
2094 // If the original size is 32-bits or more, we can use pshufd. Otherwise
2095 // if we have SSSE3 we can use pshufb.
2096 if (SubTp->getPrimitiveSizeInBits() >= 32 || ST->hasSSSE3())
2097 return ExtractCost + 1; // pshufd or pshufb
2098
2099 assert(SubTp->getPrimitiveSizeInBits() == 16 &&
2100 "Unexpected vector size");
2101
2102 return ExtractCost + 2; // worst case pshufhw + pshufd
2103 }
2104 }
2105 // If the extract subvector is not optimal, treat it as single op shuffle.
2107 }
2108
2109 // Subvector insertions are cheap if the subvectors are aligned.
2110 // Note that in general, the insertion starting at the beginning of a vector
2111 // isn't free, because we need to preserve the rest of the wide vector,
2112 // but if the destination vector legalizes to the same width as the subvector
2113 // then the insertion will simplify to a (free) register copy.
2114 if (Kind == TTI::SK_InsertSubvector && LT.second.isVector()) {
2115 std::pair<InstructionCost, MVT> DstLT = getTypeLegalizationCost(DstTy);
2116 int NumElts = DstLT.second.getVectorNumElements();
2117 std::pair<InstructionCost, MVT> SubLT = getTypeLegalizationCost(SubTp);
2118 if (SubLT.second.isVector()) {
2119 int NumSubElts = SubLT.second.getVectorNumElements();
2120 bool MatchingTypes =
2121 NumElts == NumSubElts &&
2122 (SubTp->getElementCount().getKnownMinValue() % NumSubElts) == 0;
2123 if ((Index % NumSubElts) == 0 && (NumElts % NumSubElts) == 0)
2124 return MatchingTypes ? TTI::TCC_Free : SubLT.first;
2125 }
2126
2127 // Attempt to match MOVSS (Idx == 0) or INSERTPS pattern. This will have
2128 // been matched by improveShuffleKindFromMask as a SK_InsertSubvector of
2129 // v1f32 (legalised to f32) into a v4f32.
2130 if (LT.first == 1 && LT.second == MVT::v4f32 && SubLT.first == 1 &&
2131 SubLT.second == MVT::f32 && (Index == 0 || ST->hasSSE41()))
2132 return 1;
2133
2134 // If the insertion is the lowest subvector then it will be blended
2135 // otherwise treat it like a 2-op shuffle.
2136 Kind =
2137 (Index == 0 && LT.first == 1) ? TTI::SK_Select : TTI::SK_PermuteTwoSrc;
2138 }
2139
2140 // Handle some common (illegal) sub-vector types as they are often very cheap
2141 // to shuffle even on targets without PSHUFB.
2142 EVT VT = TLI->getValueType(DL, SrcTy);
2143 if (VT.isSimple() && VT.isVector() && VT.getSizeInBits() < 128 &&
2144 !ST->hasSSSE3()) {
2145 static const CostKindTblEntry SSE2SubVectorShuffleTbl[] = {
2146 {TTI::SK_Broadcast, MVT::v4i16, {1,1,1,1}}, // pshuflw
2147 {TTI::SK_Broadcast, MVT::v2i16, {1,1,1,1}}, // pshuflw
2148 {TTI::SK_Broadcast, MVT::v8i8, {2,2,2,2}}, // punpck/pshuflw
2149 {TTI::SK_Broadcast, MVT::v4i8, {2,2,2,2}}, // punpck/pshuflw
2150 {TTI::SK_Broadcast, MVT::v2i8, {1,1,1,1}}, // punpck
2151
2152 {TTI::SK_Reverse, MVT::v4i16, {1,1,1,1}}, // pshuflw
2153 {TTI::SK_Reverse, MVT::v2i16, {1,1,1,1}}, // pshuflw
2154 {TTI::SK_Reverse, MVT::v4i8, {3,3,3,3}}, // punpck/pshuflw/packus
2155 {TTI::SK_Reverse, MVT::v2i8, {1,1,1,1}}, // punpck
2156
2157 {TTI::SK_Splice, MVT::v4i16, {2,2,2,2}}, // punpck+psrldq
2158 {TTI::SK_Splice, MVT::v2i16, {2,2,2,2}}, // punpck+psrldq
2159 {TTI::SK_Splice, MVT::v4i8, {2,2,2,2}}, // punpck+psrldq
2160 {TTI::SK_Splice, MVT::v2i8, {2,2,2,2}}, // punpck+psrldq
2161
2162 {TTI::SK_PermuteTwoSrc, MVT::v4i16, {2,2,2,2}}, // punpck/pshuflw
2163 {TTI::SK_PermuteTwoSrc, MVT::v2i16, {2,2,2,2}}, // punpck/pshuflw
2164 {TTI::SK_PermuteTwoSrc, MVT::v8i8, {7,7,7,7}}, // punpck/pshuflw
2165 {TTI::SK_PermuteTwoSrc, MVT::v4i8, {4,4,4,4}}, // punpck/pshuflw
2166 {TTI::SK_PermuteTwoSrc, MVT::v2i8, {2,2,2,2}}, // punpck
2167
2168 {TTI::SK_PermuteSingleSrc, MVT::v4i16, {1,1,1,1}}, // pshuflw
2169 {TTI::SK_PermuteSingleSrc, MVT::v2i16, {1,1,1,1}}, // pshuflw
2170 {TTI::SK_PermuteSingleSrc, MVT::v8i8, {5,5,5,5}}, // punpck/pshuflw
2171 {TTI::SK_PermuteSingleSrc, MVT::v4i8, {3,3,3,3}}, // punpck/pshuflw
2172 {TTI::SK_PermuteSingleSrc, MVT::v2i8, {1,1,1,1}}, // punpck
2173 };
2174
2175 if (ST->hasSSE2())
2176 if (const auto *Entry =
2177 CostTableLookup(SSE2SubVectorShuffleTbl, Kind, VT.getSimpleVT()))
2178 if (auto KindCost = Entry->Cost[CostKind])
2179 return LT.first * *KindCost;
2180 }
2181
2182 // We are going to permute multiple sources and the result will be in multiple
2183 // destinations. Providing an accurate cost only for splits where the element
2184 // type remains the same.
2185 if (LT.first != 1) {
2186 MVT LegalVT = LT.second;
2187 if (LegalVT.isVector() &&
2188 LegalVT.getVectorElementType().getSizeInBits() ==
2189 SrcTy->getElementType()->getPrimitiveSizeInBits() &&
2190 LegalVT.getVectorNumElements() <
2191 cast<FixedVectorType>(SrcTy)->getNumElements()) {
2192 unsigned VecTySize = DL.getTypeStoreSize(SrcTy);
2193 unsigned LegalVTSize = LegalVT.getStoreSize();
2194 // Number of source vectors after legalization:
2195 unsigned NumOfSrcs = (VecTySize + LegalVTSize - 1) / LegalVTSize;
2196 // Number of destination vectors after legalization:
2197 InstructionCost NumOfDests = LT.first;
2198
2199 auto *SingleOpTy = FixedVectorType::get(SrcTy->getElementType(),
2200 LegalVT.getVectorNumElements());
2201
2202 if (!Mask.empty() && NumOfDests.isValid()) {
2203 // Try to perform better estimation of the permutation.
2204 // 1. Split the source/destination vectors into real registers.
2205 // 2. Do the mask analysis to identify which real registers are
2206 // permuted. If more than 1 source registers are used for the
2207 // destination register building, the cost for this destination register
2208 // is (Number_of_source_register - 1) * Cost_PermuteTwoSrc. If only one
2209 // source register is used, build mask and calculate the cost as a cost
2210 // of PermuteSingleSrc.
2211 // Also, for the single register permute we try to identify if the
2212 // destination register is just a copy of the source register or the
2213 // copy of the previous destination register (the cost is
2214 // TTI::TCC_Basic). If the source register is just reused, the cost for
2215 // this operation is TTI::TCC_Free.
2216 NumOfDests =
2218 FixedVectorType::get(SrcTy->getElementType(), Mask.size()))
2219 .first;
2220 unsigned E = NumOfDests.getValue();
2221 unsigned NormalizedVF =
2222 LegalVT.getVectorNumElements() * std::max(NumOfSrcs, E);
2223 unsigned NumOfSrcRegs = NormalizedVF / LegalVT.getVectorNumElements();
2224 unsigned NumOfDestRegs = NormalizedVF / LegalVT.getVectorNumElements();
2225 SmallVector<int> NormalizedMask(NormalizedVF, PoisonMaskElem);
2226 copy(Mask, NormalizedMask.begin());
2227 unsigned PrevSrcReg = 0;
2228 ArrayRef<int> PrevRegMask;
2231 NormalizedMask, NumOfSrcRegs, NumOfDestRegs, NumOfDestRegs, []() {},
2232 [this, SingleOpTy, CostKind, &PrevSrcReg, &PrevRegMask,
2233 &Cost](ArrayRef<int> RegMask, unsigned SrcReg, unsigned DestReg) {
2234 if (!ShuffleVectorInst::isIdentityMask(RegMask, RegMask.size())) {
2235 // Check if the previous register can be just copied to the next
2236 // one.
2237 if (PrevRegMask.empty() || PrevSrcReg != SrcReg ||
2238 PrevRegMask != RegMask)
2239 Cost +=
2241 SingleOpTy, CostKind, RegMask, 0, nullptr);
2242 else
2243 // Just a copy of previous destination register.
2245 return;
2246 }
2247 if (SrcReg != DestReg &&
2248 any_of(RegMask, not_equal_to(PoisonMaskElem))) {
2249 // Just a copy of the source register.
2251 }
2252 PrevSrcReg = SrcReg;
2253 PrevRegMask = RegMask;
2254 },
2255 [this, SingleOpTy, CostKind,
2256 &Cost](ArrayRef<int> RegMask, unsigned /*Unused*/,
2257 unsigned /*Unused*/, bool /*Unused*/) {
2259 SingleOpTy, CostKind, RegMask, 0, nullptr);
2260 });
2261 return Cost;
2262 }
2263
2264 InstructionCost NumOfShuffles = (NumOfSrcs - 1) * NumOfDests;
2265 return NumOfShuffles * getShuffleCost(TTI::SK_PermuteTwoSrc, SingleOpTy,
2266 SingleOpTy, CostKind, {}, 0,
2267 nullptr);
2268 }
2269
2270 return BaseT::getShuffleCost(Kind, DstTy, SrcTy, CostKind, Mask, Index,
2271 SubTp);
2272 }
2273
2274 // If we're just moving a single element around (probably as an alternative to
2275 // extracting it), we can assume this is cheap.
2276 if (LT.first == 1 && IsInLaneShuffle && IsSingleElementMask)
2277 return TTI::TCC_Basic;
2278
2279 static const CostKindTblEntry AVX512VBMIShuffleTbl[] = {
2280 { TTI::SK_Reverse, MVT::v64i8, { 1, 1, 1, 1 } }, // vpermb
2281 { TTI::SK_Reverse, MVT::v32i8, { 1, 1, 1, 1 } }, // vpermb
2282 { TTI::SK_PermuteSingleSrc, MVT::v64i8, { 1, 1, 1, 1 } }, // vpermb
2283 { TTI::SK_PermuteSingleSrc, MVT::v32i8, { 1, 1, 1, 1 } }, // vpermb
2284 { TTI::SK_PermuteTwoSrc, MVT::v64i8, { 2, 2, 2, 2 } }, // vpermt2b
2285 { TTI::SK_PermuteTwoSrc, MVT::v32i8, { 2, 2, 2, 2 } }, // vpermt2b
2286 { TTI::SK_PermuteTwoSrc, MVT::v16i8, { 2, 2, 2, 2 } } // vpermt2b
2287 };
2288
2289 if (ST->hasVBMI())
2290 if (const auto *Entry =
2291 CostTableLookup(AVX512VBMIShuffleTbl, Kind, LT.second))
2292 if (auto KindCost = Entry->Cost[CostKind])
2293 return LT.first * *KindCost;
2294
2295 static const CostKindTblEntry AVX512BWShuffleTbl[] = {
2296 { TTI::SK_Broadcast, MVT::v32i16, { 1, 3, 1, 1 } }, // vpbroadcastw
2297 { TTI::SK_Broadcast, MVT::v32f16, { 1, 3, 1, 1 } }, // vpbroadcastw
2298 { TTI::SK_Broadcast, MVT::v64i8, { 1, 3, 1, 1 } }, // vpbroadcastb
2299
2300 { TTI::SK_Reverse, MVT::v32i16, { 2, 6, 2, 4 } }, // vpermw
2301 { TTI::SK_Reverse, MVT::v32f16, { 2, 6, 2, 4 } }, // vpermw
2302 { TTI::SK_Reverse, MVT::v16i16, { 2, 2, 2, 2 } }, // vpermw
2303 { TTI::SK_Reverse, MVT::v16f16, { 2, 2, 2, 2 } }, // vpermw
2304 { TTI::SK_Reverse, MVT::v64i8, { 2, 9, 2, 3 } }, // pshufb + vshufi64x2
2305
2306 { TTI::SK_PermuteSingleSrc, MVT::v32i16, { 2, 2, 2, 2 } }, // vpermw
2307 { TTI::SK_PermuteSingleSrc, MVT::v32f16, { 2, 2, 2, 2 } }, // vpermw
2308 { TTI::SK_PermuteSingleSrc, MVT::v16i16, { 2, 2, 2, 2 } }, // vpermw
2309 { TTI::SK_PermuteSingleSrc, MVT::v16f16, { 2, 2, 2, 2 } }, // vpermw
2310 { TTI::SK_PermuteSingleSrc, MVT::v64i8, { 8, 8, 8, 8 } }, // extend to v32i16
2311
2312 { TTI::SK_PermuteTwoSrc, MVT::v32i16,{ 2, 2, 2, 2 } }, // vpermt2w
2313 { TTI::SK_PermuteTwoSrc, MVT::v32f16,{ 2, 2, 2, 2 } }, // vpermt2w
2314 { TTI::SK_PermuteTwoSrc, MVT::v16i16,{ 2, 2, 2, 2 } }, // vpermt2w
2315 { TTI::SK_PermuteTwoSrc, MVT::v8i16, { 2, 2, 2, 2 } }, // vpermt2w
2316 { TTI::SK_PermuteTwoSrc, MVT::v64i8, { 19, 19, 19, 19 } }, // 6 * v32i8 + 1
2317
2318 { TTI::SK_Select, MVT::v32i16, { 1, 1, 1, 1 } }, // vblendmw
2319 { TTI::SK_Select, MVT::v64i8, { 1, 1, 1, 1 } }, // vblendmb
2320
2321 { TTI::SK_Splice, MVT::v32i16, { 2, 2, 2, 2 } }, // vshufi64x2 + palignr
2322 { TTI::SK_Splice, MVT::v32f16, { 2, 2, 2, 2 } }, // vshufi64x2 + palignr
2323 { TTI::SK_Splice, MVT::v64i8, { 2, 2, 2, 2 } }, // vshufi64x2 + palignr
2324 };
2325
2326 if (ST->hasBWI())
2327 if (const auto *Entry =
2328 CostTableLookup(AVX512BWShuffleTbl, Kind, LT.second))
2329 if (auto KindCost = Entry->Cost[CostKind])
2330 return LT.first * *KindCost;
2331
2332 static const CostKindTblEntry AVX512InLaneShuffleTbl[] = {
2333 {TTI::SK_PermuteTwoSrc, MVT::v8f64, { 1, 3, 1, 1 } },
2334 {TTI::SK_PermuteTwoSrc, MVT::v16f32, { 1, 3, 1, 1 } },
2335 {TTI::SK_PermuteTwoSrc, MVT::v8i64, { 1, 3, 1, 1 } },
2336 {TTI::SK_PermuteTwoSrc, MVT::v16i32, { 1, 3, 1, 1 } },
2337 {TTI::SK_PermuteTwoSrc, MVT::v4f64, { 1, 3, 1, 1 } },
2338 {TTI::SK_PermuteTwoSrc, MVT::v8f32, { 1, 3, 1, 1 } },
2339 {TTI::SK_PermuteTwoSrc, MVT::v4i64, { 1, 3, 1, 1 } },
2340 {TTI::SK_PermuteTwoSrc, MVT::v8i32, { 1, 3, 1, 1 } },
2341 };
2342
2343 if (IsInLaneShuffle && ST->hasAVX512())
2344 if (const auto *Entry =
2345 CostTableLookup(AVX512InLaneShuffleTbl, Kind, LT.second))
2346 if (auto KindCost = Entry->Cost[CostKind])
2347 return LT.first * *KindCost;
2348
2349 static const CostKindTblEntry AVX512ShuffleTbl[] = {
2350 {TTI::SK_Broadcast, MVT::v8f64, { 1, 3, 1, 1 } }, // vbroadcastsd
2351 {TTI::SK_Broadcast, MVT::v4f64, { 1, 3, 1, 1 } }, // vbroadcastsd
2352 {TTI::SK_Broadcast, MVT::v16f32, { 1, 3, 1, 1 } }, // vbroadcastss
2353 {TTI::SK_Broadcast, MVT::v8f32, { 1, 3, 1, 1 } }, // vbroadcastss
2354 {TTI::SK_Broadcast, MVT::v8i64, { 1, 3, 1, 1 } }, // vpbroadcastq
2355 {TTI::SK_Broadcast, MVT::v4i64, { 1, 3, 1, 1 } }, // vpbroadcastq
2356 {TTI::SK_Broadcast, MVT::v16i32, { 1, 3, 1, 1 } }, // vpbroadcastd
2357 {TTI::SK_Broadcast, MVT::v8i32, { 1, 3, 1, 1 } }, // vpbroadcastd
2358 {TTI::SK_Broadcast, MVT::v32i16, { 1, 3, 1, 1 } }, // vpbroadcastw
2359 {TTI::SK_Broadcast, MVT::v16i16, { 1, 3, 1, 1 } }, // vpbroadcastw
2360 {TTI::SK_Broadcast, MVT::v32f16, { 1, 3, 1, 1 } }, // vpbroadcastw
2361 {TTI::SK_Broadcast, MVT::v16f16, { 1, 3, 1, 1 } }, // vpbroadcastw
2362 {TTI::SK_Broadcast, MVT::v64i8, { 1, 3, 1, 1 } }, // vpbroadcastb
2363 {TTI::SK_Broadcast, MVT::v32i8, { 1, 3, 1, 1 }}, // vpbroadcastb
2364
2365 {TTI::SK_Reverse, MVT::v8f64, { 1, 5, 2, 3 } }, // vpermpd
2366 {TTI::SK_Reverse, MVT::v16f32, { 1, 3, 2, 3 } }, // vpermps
2367 {TTI::SK_Reverse, MVT::v8i64, { 1, 5, 2, 3 } }, // vpermq
2368 {TTI::SK_Reverse, MVT::v16i32, { 1, 3, 2, 3 } }, // vpermd
2369 {TTI::SK_Reverse, MVT::v32i16, { 7, 7, 7, 7 } }, // per mca
2370 {TTI::SK_Reverse, MVT::v32f16, { 7, 7, 7, 7 } }, // per mca
2371 {TTI::SK_Reverse, MVT::v64i8, { 7, 7, 7, 7 } }, // per mca
2372
2373 {TTI::SK_Splice, MVT::v8f64, { 1, 1, 1, 1 } }, // vpalignd
2374 {TTI::SK_Splice, MVT::v4f64, { 1, 1, 1, 1 } }, // vpalignd
2375 {TTI::SK_Splice, MVT::v16f32, { 1, 1, 1, 1 } }, // vpalignd
2376 {TTI::SK_Splice, MVT::v8f32, { 1, 1, 1, 1 } }, // vpalignd
2377 {TTI::SK_Splice, MVT::v8i64, { 1, 1, 1, 1 } }, // vpalignd
2378 {TTI::SK_Splice, MVT::v4i64, { 1, 1, 1, 1 } }, // vpalignd
2379 {TTI::SK_Splice, MVT::v16i32, { 1, 1, 1, 1 } }, // vpalignd
2380 {TTI::SK_Splice, MVT::v8i32, { 1, 1, 1, 1 } }, // vpalignd
2381 {TTI::SK_Splice, MVT::v32i16, { 4, 4, 4, 4 } }, // split + palignr
2382 {TTI::SK_Splice, MVT::v32f16, { 4, 4, 4, 4 } }, // split + palignr
2383 {TTI::SK_Splice, MVT::v64i8, { 4, 4, 4, 4 } }, // split + palignr
2384
2385 {TTI::SK_PermuteSingleSrc, MVT::v8f64, { 1, 3, 1, 1 } }, // vpermpd
2386 {TTI::SK_PermuteSingleSrc, MVT::v4f64, { 1, 3, 1, 1 } }, // vpermpd
2387 {TTI::SK_PermuteSingleSrc, MVT::v2f64, { 1, 3, 1, 1 } }, // vpermpd
2388 {TTI::SK_PermuteSingleSrc, MVT::v16f32, { 1, 3, 1, 1 } }, // vpermps
2389 {TTI::SK_PermuteSingleSrc, MVT::v8f32, { 1, 3, 1, 1 } }, // vpermps
2390 {TTI::SK_PermuteSingleSrc, MVT::v4f32, { 1, 3, 1, 1 } }, // vpermps
2391 {TTI::SK_PermuteSingleSrc, MVT::v8i64, { 1, 3, 1, 1 } }, // vpermq
2392 {TTI::SK_PermuteSingleSrc, MVT::v4i64, { 1, 3, 1, 1 } }, // vpermq
2393 {TTI::SK_PermuteSingleSrc, MVT::v2i64, { 1, 3, 1, 1 } }, // vpermq
2394 {TTI::SK_PermuteSingleSrc, MVT::v16i32, { 1, 3, 1, 1 } }, // vpermd
2395 {TTI::SK_PermuteSingleSrc, MVT::v8i32, { 1, 3, 1, 1 } }, // vpermd
2396 {TTI::SK_PermuteSingleSrc, MVT::v4i32, { 1, 3, 1, 1 } }, // vpermd
2397 {TTI::SK_PermuteSingleSrc, MVT::v16i8, { 1, 3, 1, 1 } }, // pshufb
2398
2399 {TTI::SK_PermuteTwoSrc, MVT::v8f64, { 2, 3, 1, 1 } }, // vpermt2pd
2400 {TTI::SK_PermuteTwoSrc, MVT::v16f32, { 2, 3, 1, 1 } }, // vpermt2ps
2401 {TTI::SK_PermuteTwoSrc, MVT::v8i64, { 2, 3, 1, 1 } }, // vpermt2q
2402 {TTI::SK_PermuteTwoSrc, MVT::v16i32, { 2, 3, 1, 1 } }, // vpermt2d
2403 {TTI::SK_PermuteTwoSrc, MVT::v4f64, { 2, 3, 1, 1 } }, // vpermt2pd
2404 {TTI::SK_PermuteTwoSrc, MVT::v8f32, { 2, 3, 1, 1 } }, // vpermt2ps
2405 {TTI::SK_PermuteTwoSrc, MVT::v4i64, { 2, 3, 1, 1 } }, // vpermt2q
2406 {TTI::SK_PermuteTwoSrc, MVT::v8i32, { 2, 3, 1, 1 } }, // vpermt2d
2407 {TTI::SK_PermuteTwoSrc, MVT::v2f64, { 1, 3, 1, 1 } },
2408 {TTI::SK_PermuteTwoSrc, MVT::v4f32, { 1, 3, 1, 1 } },
2409 {TTI::SK_PermuteTwoSrc, MVT::v2i64, { 1, 3, 1, 1 } },
2410 {TTI::SK_PermuteTwoSrc, MVT::v4i32, { 1, 3, 1, 1 } },
2411
2412 // FIXME: This just applies the type legalization cost rules above
2413 // assuming these completely split.
2414 {TTI::SK_PermuteSingleSrc, MVT::v32i16, { 14, 14, 14, 14 } },
2415 {TTI::SK_PermuteSingleSrc, MVT::v32f16, { 14, 14, 14, 14 } },
2416 {TTI::SK_PermuteSingleSrc, MVT::v64i8, { 14, 14, 14, 14 } },
2417 {TTI::SK_PermuteTwoSrc, MVT::v32i16, { 42, 42, 42, 42 } },
2418 {TTI::SK_PermuteTwoSrc, MVT::v32f16, { 42, 42, 42, 42 } },
2419 {TTI::SK_PermuteTwoSrc, MVT::v64i8, { 42, 42, 42, 42 } },
2420
2421 {TTI::SK_Select, MVT::v32i16, { 1, 1, 1, 1 } }, // vpternlogq
2422 {TTI::SK_Select, MVT::v32f16, { 1, 1, 1, 1 } }, // vpternlogq
2423 {TTI::SK_Select, MVT::v64i8, { 1, 1, 1, 1 } }, // vpternlogq
2424 {TTI::SK_Select, MVT::v8f64, { 1, 1, 1, 1 } }, // vblendmpd
2425 {TTI::SK_Select, MVT::v16f32, { 1, 1, 1, 1 } }, // vblendmps
2426 {TTI::SK_Select, MVT::v8i64, { 1, 1, 1, 1 } }, // vblendmq
2427 {TTI::SK_Select, MVT::v16i32, { 1, 1, 1, 1 } }, // vblendmd
2428 };
2429
2430 if (ST->hasAVX512())
2431 if (const auto *Entry = CostTableLookup(AVX512ShuffleTbl, Kind, LT.second))
2432 if (auto KindCost = Entry->Cost[CostKind])
2433 return LT.first * *KindCost;
2434
2435 static const CostKindTblEntry AVX2InLaneShuffleTbl[] = {
2436 { TTI::SK_PermuteSingleSrc, MVT::v16i16, { 1, 1, 1, 1 } }, // vpshufb
2437 { TTI::SK_PermuteSingleSrc, MVT::v16f16, { 1, 1, 1, 1 } }, // vpshufb
2438 { TTI::SK_PermuteSingleSrc, MVT::v32i8, { 1, 1, 1, 1 } }, // vpshufb
2439
2440 { TTI::SK_Transpose, MVT::v4f64, { 1, 1, 1, 1 } }, // vshufpd/vunpck
2441 { TTI::SK_Transpose, MVT::v4i64, { 1, 1, 1, 1 } }, // vshufpd/vunpck
2442
2443 { TTI::SK_PermuteTwoSrc, MVT::v4f64, { 2, 2, 2, 2 } }, // 2*vshufpd + vblendpd
2444 { TTI::SK_PermuteTwoSrc, MVT::v8f32, { 2, 2, 2, 2 } }, // 2*vshufps + vblendps
2445 { TTI::SK_PermuteTwoSrc, MVT::v4i64, { 2, 2, 2, 2 } }, // 2*vpshufd + vpblendd
2446 { TTI::SK_PermuteTwoSrc, MVT::v8i32, { 2, 2, 2, 2 } }, // 2*vpshufd + vpblendd
2447 { TTI::SK_PermuteTwoSrc, MVT::v16i16, { 2, 2, 2, 2 } }, // 2*vpshufb + vpor
2448 { TTI::SK_PermuteTwoSrc, MVT::v16f16, { 2, 2, 2, 2 } }, // 2*vpshufb + vpor
2449 { TTI::SK_PermuteTwoSrc, MVT::v32i8, { 2, 2, 2, 2 } }, // 2*vpshufb + vpor
2450 };
2451
2452 if (IsInLaneShuffle && ST->hasAVX2())
2453 if (const auto *Entry =
2454 CostTableLookup(AVX2InLaneShuffleTbl, Kind, LT.second))
2455 if (auto KindCost = Entry->Cost[CostKind])
2456 return LT.first * *KindCost;
2457
2458 static const CostKindTblEntry AVX2ShuffleTbl[] = {
2459 { TTI::SK_Broadcast, MVT::v4f64, { 1, 3, 1, 2 } }, // vbroadcastpd
2460 { TTI::SK_Broadcast, MVT::v8f32, { 1, 3, 1, 2 } }, // vbroadcastps
2461 { TTI::SK_Broadcast, MVT::v4i64, { 1, 3, 1, 2 } }, // vpbroadcastq
2462 { TTI::SK_Broadcast, MVT::v8i32, { 1, 3, 1, 2 } }, // vpbroadcastd
2463 { TTI::SK_Broadcast, MVT::v16i16, { 1, 3, 1, 2 } }, // vpbroadcastw
2464 { TTI::SK_Broadcast, MVT::v8i16, { 1, 3, 1, 1 } }, // vpbroadcastw
2465 { TTI::SK_Broadcast, MVT::v16f16, { 1, 3, 1, 2 } }, // vpbroadcastw
2466 { TTI::SK_Broadcast, MVT::v8f16, { 1, 3, 1, 1 } }, // vpbroadcastw
2467 { TTI::SK_Broadcast, MVT::v32i8, { 1, 3, 1, 2 } }, // vpbroadcastb
2468 { TTI::SK_Broadcast, MVT::v16i8, { 1, 3, 1, 1 } }, // vpbroadcastb
2469
2470 { TTI::SK_Reverse, MVT::v4f64, { 1, 6, 1, 2 } }, // vpermpd
2471 { TTI::SK_Reverse, MVT::v8f32, { 2, 7, 2, 4 } }, // vpermps
2472 { TTI::SK_Reverse, MVT::v4i64, { 1, 6, 1, 2 } }, // vpermq
2473 { TTI::SK_Reverse, MVT::v8i32, { 2, 7, 2, 4 } }, // vpermd
2474 { TTI::SK_Reverse, MVT::v16i16, { 2, 9, 2, 4 } }, // vperm2i128 + pshufb
2475 { TTI::SK_Reverse, MVT::v16f16, { 2, 9, 2, 4 } }, // vperm2i128 + pshufb
2476 { TTI::SK_Reverse, MVT::v32i8, { 2, 9, 2, 4 } }, // vperm2i128 + pshufb
2477
2478 { TTI::SK_Select, MVT::v16i16, { 1, 1, 1, 1 } }, // vpblendvb
2479 { TTI::SK_Select, MVT::v16f16, { 1, 1, 1, 1 } }, // vpblendvb
2480 { TTI::SK_Select, MVT::v32i8, { 1, 1, 1, 1 } }, // vpblendvb
2481
2482 { TTI::SK_Splice, MVT::v8i32, { 2, 2, 2, 2 } }, // vperm2i128 + vpalignr
2483 { TTI::SK_Splice, MVT::v8f32, { 2, 2, 2, 2 } }, // vperm2i128 + vpalignr
2484 { TTI::SK_Splice, MVT::v16i16, { 2, 2, 2, 2 } }, // vperm2i128 + vpalignr
2485 { TTI::SK_Splice, MVT::v16f16, { 2, 2, 2, 2 } }, // vperm2i128 + vpalignr
2486 { TTI::SK_Splice, MVT::v32i8, { 2, 2, 2, 2 } }, // vperm2i128 + vpalignr
2487
2488 { TTI::SK_PermuteSingleSrc, MVT::v4f64, { 1, 1, 1, 1 } }, // vpermpd
2489 { TTI::SK_PermuteSingleSrc, MVT::v8f32, { 1, 1, 1, 1 } }, // vpermps
2490 { TTI::SK_PermuteSingleSrc, MVT::v4i64, { 1, 1, 1, 1 } }, // vpermq
2491 { TTI::SK_PermuteSingleSrc, MVT::v8i32, { 1, 1, 1, 1 } }, // vpermd
2492 { TTI::SK_PermuteSingleSrc, MVT::v16i16, { 4, 4, 4, 4 } },
2493 { TTI::SK_PermuteSingleSrc, MVT::v16f16, { 4, 4, 4, 4 } },
2494 { TTI::SK_PermuteSingleSrc, MVT::v32i8, { 4, 4, 4, 4 } },
2495
2496 { TTI::SK_PermuteTwoSrc, MVT::v4f64, { 3, 3, 3, 3 } }, // 2*vpermpd + vblendpd
2497 { TTI::SK_PermuteTwoSrc, MVT::v8f32, { 3, 3, 3, 3 } }, // 2*vpermps + vblendps
2498 { TTI::SK_PermuteTwoSrc, MVT::v4i64, { 3, 3, 3, 3 } }, // 2*vpermq + vpblendd
2499 { TTI::SK_PermuteTwoSrc, MVT::v8i32, { 3, 3, 3, 3 } }, // 2*vpermd + vpblendd
2500 { TTI::SK_PermuteTwoSrc, MVT::v16i16, { 7, 7, 7, 7 } },
2501 { TTI::SK_PermuteTwoSrc, MVT::v16f16, { 7, 7, 7, 7 } },
2502 { TTI::SK_PermuteTwoSrc, MVT::v32i8, { 7, 7, 7, 7 } },
2503 };
2504
2505 if (ST->hasAVX2())
2506 if (const auto *Entry = CostTableLookup(AVX2ShuffleTbl, Kind, LT.second))
2507 if (auto KindCost = Entry->Cost[CostKind])
2508 return LT.first * *KindCost;
2509
2510 static const CostKindTblEntry XOPShuffleTbl[] = {
2511 { TTI::SK_PermuteSingleSrc, MVT::v4f64, { 2, 2, 2, 2 } }, // vperm2f128 + vpermil2pd
2512 { TTI::SK_PermuteSingleSrc, MVT::v8f32, { 2, 2, 2, 2 } }, // vperm2f128 + vpermil2ps
2513 { TTI::SK_PermuteSingleSrc, MVT::v4i64, { 2, 2, 2, 2 } }, // vperm2f128 + vpermil2pd
2514 { TTI::SK_PermuteSingleSrc, MVT::v8i32, { 2, 2, 2, 2 } }, // vperm2f128 + vpermil2ps
2515 { TTI::SK_PermuteSingleSrc, MVT::v16i16,{ 4, 4, 4, 4 } }, // vextractf128 + 2*vpperm
2516 // + vinsertf128
2517 { TTI::SK_PermuteSingleSrc, MVT::v32i8, { 4, 4, 4, 4 } }, // vextractf128 + 2*vpperm
2518 // + vinsertf128
2519
2520 { TTI::SK_PermuteTwoSrc, MVT::v16i16, { 9, 9, 9, 9 } }, // 2*vextractf128 + 6*vpperm
2521 // + vinsertf128
2522
2523 { TTI::SK_PermuteTwoSrc, MVT::v8i16, { 1, 1, 1, 1 } }, // vpperm
2524 { TTI::SK_PermuteTwoSrc, MVT::v32i8, { 9, 9, 9, 9 } }, // 2*vextractf128 + 6*vpperm
2525 // + vinsertf128
2526 { TTI::SK_PermuteTwoSrc, MVT::v16i8, { 1, 1, 1, 1 } }, // vpperm
2527 };
2528
2529 if (ST->hasXOP())
2530 if (const auto *Entry = CostTableLookup(XOPShuffleTbl, Kind, LT.second))
2531 if (auto KindCost = Entry->Cost[CostKind])
2532 return LT.first * *KindCost;
2533
2534 static const CostKindTblEntry AVX1InLaneShuffleTbl[] = {
2535 { TTI::SK_PermuteSingleSrc, MVT::v4f64, { 1, 1, 1, 1 } }, // vpermilpd
2536 { TTI::SK_PermuteSingleSrc, MVT::v4i64, { 1, 1, 1, 1 } }, // vpermilpd
2537 { TTI::SK_PermuteSingleSrc, MVT::v8f32, { 1, 1, 1, 1 } }, // vpermilps
2538 { TTI::SK_PermuteSingleSrc, MVT::v8i32, { 1, 1, 1, 1 } }, // vpermilps
2539
2540 { TTI::SK_PermuteSingleSrc, MVT::v16i16, { 4, 4, 4, 4 } }, // vextractf128 + 2*pshufb
2541 // + vpor + vinsertf128
2542 { TTI::SK_PermuteSingleSrc, MVT::v16f16, { 4, 4, 4, 4 } }, // vextractf128 + 2*pshufb
2543 // + vpor + vinsertf128
2544 { TTI::SK_PermuteSingleSrc, MVT::v32i8, { 4, 4, 4, 4 } }, // vextractf128 + 2*pshufb
2545 // + vpor + vinsertf128
2546
2547 { TTI::SK_Transpose, MVT::v4f64, { 1, 1, 1, 1 } }, // vshufpd/vunpck
2548 { TTI::SK_Transpose, MVT::v4i64, { 1, 1, 1, 1 } }, // vshufpd/vunpck
2549
2550 { TTI::SK_PermuteTwoSrc, MVT::v4f64, { 2, 2, 2, 2 } }, // 2*vshufpd + vblendpd
2551 { TTI::SK_PermuteTwoSrc, MVT::v8f32, { 2, 2, 2, 2 } }, // 2*vshufps + vblendps
2552 { TTI::SK_PermuteTwoSrc, MVT::v4i64, { 2, 2, 2, 2 } }, // 2*vpermilpd + vblendpd
2553 { TTI::SK_PermuteTwoSrc, MVT::v8i32, { 2, 2, 2, 2 } }, // 2*vpermilps + vblendps
2554 { TTI::SK_PermuteTwoSrc, MVT::v16i16, { 9, 9, 9, 9 } }, // 2*vextractf128 + 4*pshufb
2555 // + 2*vpor + vinsertf128
2556 { TTI::SK_PermuteTwoSrc, MVT::v16f16, { 9, 9, 9, 9 } }, // 2*vextractf128 + 4*pshufb
2557 // + 2*vpor + vinsertf128
2558 { TTI::SK_PermuteTwoSrc, MVT::v32i8, { 9, 9, 9, 9 } }, // 2*vextractf128 + 4*pshufb
2559 // + 2*vpor + vinsertf128
2560 };
2561
2562 if (IsInLaneShuffle && ST->hasAVX())
2563 if (const auto *Entry =
2564 CostTableLookup(AVX1InLaneShuffleTbl, Kind, LT.second))
2565 if (auto KindCost = Entry->Cost[CostKind])
2566 return LT.first * *KindCost;
2567
2568 static const CostKindTblEntry AVX1ShuffleTbl[] = {
2569 {TTI::SK_Broadcast, MVT::v4f64, {2,3,2,3}}, // vperm2f128 + vpermilpd
2570 {TTI::SK_Broadcast, MVT::v8f32, {2,3,2,3}}, // vperm2f128 + vpermilps
2571 {TTI::SK_Broadcast, MVT::v4i64, {2,3,2,3}}, // vperm2f128 + vpermilpd
2572 {TTI::SK_Broadcast, MVT::v8i32, {2,3,2,3}}, // vperm2f128 + vpermilps
2573 {TTI::SK_Broadcast, MVT::v16i16, {2,3,3,4}}, // vpshuflw + vpshufd + vinsertf128
2574 {TTI::SK_Broadcast, MVT::v16f16, {2,3,3,4}}, // vpshuflw + vpshufd + vinsertf128
2575 {TTI::SK_Broadcast, MVT::v32i8, {3,4,3,6}}, // vpshufb + vinsertf128
2576
2577 {TTI::SK_Reverse, MVT::v4f64, {2,6,2,2}}, // vperm2f128 + vpermilpd
2578 {TTI::SK_Reverse, MVT::v8f32, {2,7,2,4}}, // vperm2f128 + vpermilps
2579 {TTI::SK_Reverse, MVT::v4i64, {2,6,2,2}}, // vperm2f128 + vpermilpd
2580 {TTI::SK_Reverse, MVT::v8i32, {2,7,2,4}}, // vperm2f128 + vpermilps
2581 {TTI::SK_Reverse, MVT::v16i16, {2,9,5,5}}, // vextractf128 + 2*pshufb
2582 // + vinsertf128
2583 {TTI::SK_Reverse, MVT::v16f16, {2,9,5,5}}, // vextractf128 + 2*pshufb
2584 // + vinsertf128
2585 {TTI::SK_Reverse, MVT::v32i8, {2,9,5,5}}, // vextractf128 + 2*pshufb
2586 // + vinsertf128
2587
2588 {TTI::SK_Select, MVT::v4i64, {1,1,1,1}}, // vblendpd
2589 {TTI::SK_Select, MVT::v4f64, {1,1,1,1}}, // vblendpd
2590 {TTI::SK_Select, MVT::v8i32, {1,1,1,1}}, // vblendps
2591 {TTI::SK_Select, MVT::v8f32, {1,1,1,1}}, // vblendps
2592 {TTI::SK_Select, MVT::v16i16, {3,3,3,3}}, // vpand + vpandn + vpor
2593 {TTI::SK_Select, MVT::v16f16, {3,3,3,3}}, // vpand + vpandn + vpor
2594 {TTI::SK_Select, MVT::v32i8, {3,3,3,3}}, // vpand + vpandn + vpor
2595
2596 {TTI::SK_Splice, MVT::v4i64, {2,2,2,2}}, // vperm2f128 + shufpd
2597 {TTI::SK_Splice, MVT::v4f64, {2,2,2,2}}, // vperm2f128 + shufpd
2598 {TTI::SK_Splice, MVT::v8i32, {4,4,4,4}}, // 2*vperm2f128 + 2*vshufps
2599 {TTI::SK_Splice, MVT::v8f32, {4,4,4,4}}, // 2*vperm2f128 + 2*vshufps
2600 {TTI::SK_Splice, MVT::v16i16, {5,5,5,5}}, // 2*vperm2f128 + 2*vpalignr + vinsertf128
2601 {TTI::SK_Splice, MVT::v16f16, {5,5,5,5}}, // 2*vperm2f128 + 2*vpalignr + vinsertf128
2602 {TTI::SK_Splice, MVT::v32i8, {5,5,5,5}}, // 2*vperm2f128 + 2*vpalignr + vinsertf128
2603
2604 {TTI::SK_PermuteSingleSrc, MVT::v4f64, {2,2,2,2}}, // vperm2f128 + vshufpd
2605 {TTI::SK_PermuteSingleSrc, MVT::v4i64, {2,2,2,2}}, // vperm2f128 + vshufpd
2606 {TTI::SK_PermuteSingleSrc, MVT::v8f32, {4,4,4,4}}, // 2*vperm2f128 + 2*vshufps
2607 {TTI::SK_PermuteSingleSrc, MVT::v8i32, {4,4,4,4}}, // 2*vperm2f128 + 2*vshufps
2608 {TTI::SK_PermuteSingleSrc, MVT::v16i16,{8,8,8,8}}, // vextractf128 + 4*pshufb
2609 // + 2*por + vinsertf128
2610 {TTI::SK_PermuteSingleSrc, MVT::v16f16,{8,8,8,8}}, // vextractf128 + 4*pshufb
2611 // + 2*por + vinsertf128
2612 {TTI::SK_PermuteSingleSrc, MVT::v32i8, {8,8,8,8}}, // vextractf128 + 4*pshufb
2613 // + 2*por + vinsertf128
2614
2615 {TTI::SK_PermuteTwoSrc, MVT::v4f64, {3,3,3,3}}, // 2*vperm2f128 + vshufpd
2616 {TTI::SK_PermuteTwoSrc, MVT::v4i64, {3,3,3,3}}, // 2*vperm2f128 + vshufpd
2617 {TTI::SK_PermuteTwoSrc, MVT::v8f32, {4,4,4,4}}, // 2*vperm2f128 + 2*vshufps
2618 {TTI::SK_PermuteTwoSrc, MVT::v8i32, {4,4,4,4}}, // 2*vperm2f128 + 2*vshufps
2619 {TTI::SK_PermuteTwoSrc, MVT::v16i16,{15,15,15,15}}, // 2*vextractf128 + 8*pshufb
2620 // + 4*por + vinsertf128
2621 {TTI::SK_PermuteTwoSrc, MVT::v16f16,{15,15,15,15}}, // 2*vextractf128 + 8*pshufb
2622 // + 4*por + vinsertf128
2623 {TTI::SK_PermuteTwoSrc, MVT::v32i8, {15,15,15,15}}, // 2*vextractf128 + 8*pshufb
2624 // + 4*por + vinsertf128
2625 };
2626
2627 if (ST->hasAVX())
2628 if (const auto *Entry = CostTableLookup(AVX1ShuffleTbl, Kind, LT.second))
2629 if (auto KindCost = Entry->Cost[CostKind])
2630 return LT.first * *KindCost;
2631
2632 static const CostKindTblEntry SSE41ShuffleTbl[] = {
2633 {TTI::SK_Select, MVT::v2i64, {1,1,1,1}}, // pblendw
2634 {TTI::SK_Select, MVT::v2f64, {1,1,1,1}}, // movsd
2635 {TTI::SK_Select, MVT::v4i32, {1,1,1,1}}, // pblendw
2636 {TTI::SK_Select, MVT::v4f32, {1,1,1,1}}, // blendps
2637 {TTI::SK_Select, MVT::v8i16, {1,1,1,1}}, // pblendw
2638 {TTI::SK_Select, MVT::v8f16, {1,1,1,1}}, // pblendw
2639 {TTI::SK_Select, MVT::v16i8, {1,1,1,1}} // pblendvb
2640 };
2641
2642 if (ST->hasSSE41())
2643 if (const auto *Entry = CostTableLookup(SSE41ShuffleTbl, Kind, LT.second))
2644 if (auto KindCost = Entry->Cost[CostKind])
2645 return LT.first * *KindCost;
2646
2647 static const CostKindTblEntry SSSE3ShuffleTbl[] = {
2648 {TTI::SK_Broadcast, MVT::v8i16, {1, 3, 2, 2}}, // pshufb
2649 {TTI::SK_Broadcast, MVT::v8f16, {1, 3, 2, 2}}, // pshufb
2650 {TTI::SK_Broadcast, MVT::v16i8, {1, 3, 2, 2}}, // pshufb
2651
2652 {TTI::SK_Reverse, MVT::v8i16, {1, 2, 1, 2}}, // pshufb
2653 {TTI::SK_Reverse, MVT::v8f16, {1, 2, 1, 2}}, // pshufb
2654 {TTI::SK_Reverse, MVT::v16i8, {1, 2, 1, 2}}, // pshufb
2655
2656 {TTI::SK_Splice, MVT::v4i32, {1, 1, 1, 1}}, // palignr
2657 {TTI::SK_Splice, MVT::v4f32, {1, 1, 1, 1}}, // palignr
2658 {TTI::SK_Splice, MVT::v8i16, {1, 1, 1, 1}}, // palignr
2659 {TTI::SK_Splice, MVT::v8f16, {1, 1, 1, 1}}, // palignr
2660 {TTI::SK_Splice, MVT::v16i8, {1, 1, 1, 1}}, // palignr
2661
2662 {TTI::SK_PermuteSingleSrc, MVT::v8i16, {1, 1, 1, 1}}, // pshufb
2663 {TTI::SK_PermuteSingleSrc, MVT::v8f16, {1, 1, 1, 1}}, // pshufb
2664 {TTI::SK_PermuteSingleSrc, MVT::v16i8, {1, 1, 1, 1}}, // pshufb
2665
2666 {TTI::SK_PermuteTwoSrc, MVT::v8i16, {3, 3, 3, 3}}, // 2*pshufb + por
2667 {TTI::SK_PermuteTwoSrc, MVT::v8f16, {3, 3, 3, 3}}, // 2*pshufb + por
2668 {TTI::SK_PermuteTwoSrc, MVT::v16i8, {3, 3, 3, 3}}, // 2*pshufb + por
2669 };
2670
2671 if (ST->hasSSSE3())
2672 if (const auto *Entry = CostTableLookup(SSSE3ShuffleTbl, Kind, LT.second))
2673 if (auto KindCost = Entry->Cost[CostKind])
2674 return LT.first * *KindCost;
2675
2676 static const CostKindTblEntry SSE2ShuffleTbl[] = {
2677 {TTI::SK_Broadcast, MVT::v2f64, {1, 1, 1, 1}}, // shufpd
2678 {TTI::SK_Broadcast, MVT::v2i64, {1, 1, 1, 1}}, // pshufd
2679 {TTI::SK_Broadcast, MVT::v4i32, {1, 1, 1, 1}}, // pshufd
2680 {TTI::SK_Broadcast, MVT::v8i16, {1, 2, 2, 2}}, // pshuflw + pshufd
2681 {TTI::SK_Broadcast, MVT::v8f16, {1, 2, 2, 2}}, // pshuflw + pshufd
2682 {TTI::SK_Broadcast, MVT::v16i8, {2, 3, 3, 4}}, // unpck + pshuflw + pshufd
2683
2684 {TTI::SK_Reverse, MVT::v2f64, {1, 1, 1, 1}}, // shufpd
2685 {TTI::SK_Reverse, MVT::v2i64, {1, 1, 1, 1}}, // pshufd
2686 {TTI::SK_Reverse, MVT::v4i32, {1, 1, 1, 1}}, // pshufd
2687 {TTI::SK_Reverse, MVT::v8i16, {2, 3, 3, 3}}, // pshuflw + pshufhw + pshufd
2688 {TTI::SK_Reverse, MVT::v8f16, {2, 3, 3, 3}}, // pshuflw + pshufhw + pshufd
2689 {TTI::SK_Reverse, MVT::v16i8, {5, 6,11,11}}, // 2*pshuflw + 2*pshufhw
2690 // + 2*pshufd + 2*unpck + packus
2691
2692 {TTI::SK_Select, MVT::v2i64, {1, 1, 1, 1}}, // movsd
2693 {TTI::SK_Select, MVT::v2f64, {1, 1, 1, 1}}, // movsd
2694 {TTI::SK_Select, MVT::v4i32, {2, 2, 2, 2}}, // 2*shufps
2695 {TTI::SK_Select, MVT::v8i16, {2, 2, 3, 3}}, // pand + pandn + por
2696 {TTI::SK_Select, MVT::v8f16, {2, 2, 3, 3}}, // pand + pandn + por
2697 {TTI::SK_Select, MVT::v16i8, {2, 2, 3, 3}}, // pand + pandn + por
2698
2699 {TTI::SK_Splice, MVT::v2i64, {1, 1, 1, 1}}, // shufpd
2700 {TTI::SK_Splice, MVT::v2f64, {1, 1, 1, 1}}, // shufpd
2701 {TTI::SK_Splice, MVT::v4i32, {2, 2, 2, 2}}, // 2*{unpck,movsd,pshufd}
2702 {TTI::SK_Splice, MVT::v8i16, {3, 3, 3, 3}}, // psrldq + psrlldq + por
2703 {TTI::SK_Splice, MVT::v8f16, {3, 3, 3, 3}}, // psrldq + psrlldq + por
2704 {TTI::SK_Splice, MVT::v16i8, {3, 3, 3, 3}}, // psrldq + psrlldq + por
2705
2706 {TTI::SK_PermuteSingleSrc, MVT::v2f64, {1, 1, 1, 1}}, // shufpd
2707 {TTI::SK_PermuteSingleSrc, MVT::v2i64, {1, 1, 1, 1}}, // pshufd
2708 {TTI::SK_PermuteSingleSrc, MVT::v4i32, {1, 1, 1, 1}}, // pshufd
2709 {TTI::SK_PermuteSingleSrc, MVT::v8i16, {3, 5, 5, 5}}, // 2*pshuflw + 2*pshufhw
2710 // + pshufd/unpck
2711 {TTI::SK_PermuteSingleSrc, MVT::v8f16, {3, 5, 5, 5}}, // 2*pshuflw + 2*pshufhw
2712 // + pshufd/unpck
2713 {TTI::SK_PermuteSingleSrc, MVT::v16i8, {8, 10, 10, 10}}, // 2*pshuflw + 2*pshufhw
2714 // + 2*pshufd + 2*unpck + 2*packus
2715
2716 {TTI::SK_PermuteTwoSrc, MVT::v2f64, {1, 1, 1, 1}}, // shufpd
2717 {TTI::SK_PermuteTwoSrc, MVT::v2i64, {1, 1, 1, 1}}, // shufpd
2718 {TTI::SK_PermuteTwoSrc, MVT::v4i32, {2, 2, 2, 2}}, // 2*{unpck,movsd,pshufd}
2719 {TTI::SK_PermuteTwoSrc, MVT::v8i16, {6, 8, 8, 8}}, // blend+permute
2720 {TTI::SK_PermuteTwoSrc, MVT::v8f16, {6, 8, 8, 8}}, // blend+permute
2721 {TTI::SK_PermuteTwoSrc, MVT::v16i8, {11, 13, 13, 13}}, // blend+permute
2722 };
2723
2724 static const CostTblEntry SSE3BroadcastLoadTbl[] = {
2725 {TTI::SK_Broadcast, MVT::v2f64, 0}, // broadcast handled by movddup
2726 };
2727
2728 if (ST->hasSSE2()) {
2729 bool IsLoad =
2730 llvm::any_of(Args, [](const auto &V) { return isa<LoadInst>(V); });
2731 if (ST->hasSSE3() && IsLoad)
2732 if (const auto *Entry =
2733 CostTableLookup(SSE3BroadcastLoadTbl, Kind, LT.second)) {
2734 assert(isLegalBroadcastLoad(SrcTy->getElementType(),
2735 LT.second.getVectorElementCount()) &&
2736 "Table entry missing from isLegalBroadcastLoad()");
2737 return LT.first * Entry->Cost;
2738 }
2739
2740 if (const auto *Entry = CostTableLookup(SSE2ShuffleTbl, Kind, LT.second))
2741 if (auto KindCost = Entry->Cost[CostKind])
2742 return LT.first * *KindCost;
2743 }
2744
2745 static const CostKindTblEntry SSE1ShuffleTbl[] = {
2746 { TTI::SK_Broadcast, MVT::v4f32, {1,1,1,1} }, // shufps
2747 { TTI::SK_Reverse, MVT::v4f32, {1,1,1,1} }, // shufps
2748 { TTI::SK_Select, MVT::v4f32, {2,2,2,2} }, // 2*shufps
2749 { TTI::SK_Splice, MVT::v4f32, {2,2,2,2} }, // 2*shufps
2750 { TTI::SK_PermuteSingleSrc, MVT::v4f32, {1,1,1,1} }, // shufps
2751 { TTI::SK_PermuteTwoSrc, MVT::v4f32, {2,2,2,2} }, // 2*shufps
2752 };
2753
2754 if (ST->hasSSE1()) {
2755 if (LT.first == 1 && LT.second == MVT::v4f32 && Mask.size() == 4) {
2756 // SHUFPS: both pairs must come from the same source register.
2757 auto MatchSHUFPS = [](int X, int Y) {
2758 return X < 0 || Y < 0 || ((X & 4) == (Y & 4));
2759 };
2760 if (MatchSHUFPS(Mask[0], Mask[1]) && MatchSHUFPS(Mask[2], Mask[3]))
2761 return 1;
2762 }
2763 if (const auto *Entry = CostTableLookup(SSE1ShuffleTbl, Kind, LT.second))
2764 if (auto KindCost = Entry->Cost[CostKind])
2765 return LT.first * *KindCost;
2766 }
2767
2768 return BaseT::getShuffleCost(Kind, DstTy, SrcTy, CostKind, Mask, Index,
2769 SubTp);
2770}
2771
2773 Type *Src,
2776 const Instruction *I) const {
2777 int ISD = TLI->InstructionOpcodeToISD(Opcode);
2778 assert(ISD && "Invalid opcode");
2779
2780 // A narrow (i8/i16) zero-extension used as a GEP *index* can be folded into
2781 // the addressing mode of the consuming memory op, but only if the source is
2782 // already materialised zero-extended in a full register. X86's SIB form
2783 // [base + index*scale + disp] reads the index at full width and does NOT
2784 // zero-extend a narrow index (unlike AArch64's uxtw-extended addressing), so
2785 // a "dirty" narrow source (e.g. an i16 add result used only as an index)
2786 // still needs a dedicated movzx and is not free. Price it as free only with
2787 // positive evidence that no movzx is required.
2788 if (ISD == ISD::ZERO_EXTEND && I && I->hasOneUse() && Src->isIntegerTy() &&
2789 Src->getScalarSizeInBits() < 32) {
2790 const Use &U = *I->use_begin();
2791 if (isa<GetElementPtrInst>(U.getUser()) &&
2792 U.getOperandNo() != GetElementPtrInst::getPointerOperandIndex()) {
2793 const Value *Op = I->getOperand(0);
2794 // Clean sources: an extending load, a zeroext argument, or a value whose
2795 // high bits are provably zero (e.g. from a shift/mask). These mirror the
2796 // proof-based reasoning the middle end uses elsewhere (ValueTracking and
2797 // InstCombine's canEvaluateZExtd); we intentionally do NOT treat a merely
2798 // multiply-used operand as clean, since that is a guess rather than
2799 // proof.
2800 if (isa<LoadInst>(Op))
2801 return TTI::TCC_Free;
2802 if (const auto *A = dyn_cast<Argument>(Op))
2803 if (A->hasAttribute(Attribute::ZExt))
2804 return TTI::TCC_Free;
2805 if (computeKnownBits(Op, I->getDataLayout(), /*AC=*/nullptr, I)
2806 .countMinLeadingZeros() > 0)
2807 return TTI::TCC_Free;
2808 }
2809 }
2810
2811 // The cost tables include both specific, custom (non-legal) src/dst type
2812 // conversions and generic, legalized types. We test for customs first, before
2813 // falling back to legalization.
2814 // FIXME: Need a better design of the cost table to handle non-simple types of
2815 // potential massive combinations (elem_num x src_type x dst_type).
2816 static const TypeConversionCostKindTblEntry AVX512BWConversionTbl[]{
2817 { ISD::SIGN_EXTEND, MVT::v32i16, MVT::v32i8, { 1, 1, 1, 1 } },
2818 { ISD::ZERO_EXTEND, MVT::v32i16, MVT::v32i8, { 1, 1, 1, 1 } },
2819
2820 // Mask sign extend has an instruction.
2821 { ISD::SIGN_EXTEND, MVT::v2i8, MVT::v2i1, { 1, 1, 1, 1 } },
2822 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v2i1, { 1, 1, 1, 1 } },
2823 { ISD::SIGN_EXTEND, MVT::v2i16, MVT::v2i1, { 1, 1, 1, 1 } },
2824 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v2i1, { 1, 1, 1, 1 } },
2825 { ISD::SIGN_EXTEND, MVT::v4i8, MVT::v4i1, { 1, 1, 1, 1 } },
2826 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v4i1, { 1, 1, 1, 1 } },
2827 { ISD::SIGN_EXTEND, MVT::v4i16, MVT::v4i1, { 1, 1, 1, 1 } },
2828 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v4i1, { 1, 1, 1, 1 } },
2829 { ISD::SIGN_EXTEND, MVT::v8i8, MVT::v8i1, { 1, 1, 1, 1 } },
2830 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v8i1, { 1, 1, 1, 1 } },
2831 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v8i1, { 1, 1, 1, 1 } },
2832 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v16i1, { 1, 1, 1, 1 } },
2833 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i1, { 1, 1, 1, 1 } },
2834 { ISD::SIGN_EXTEND, MVT::v32i8, MVT::v32i1, { 1, 1, 1, 1 } },
2835 { ISD::SIGN_EXTEND, MVT::v32i16, MVT::v32i1, { 1, 1, 1, 1 } },
2836 { ISD::SIGN_EXTEND, MVT::v64i8, MVT::v64i1, { 1, 1, 1, 1 } },
2837 { ISD::SIGN_EXTEND, MVT::v32i16, MVT::v64i1, { 1, 1, 1, 1 } },
2838
2839 // Mask zero extend is a sext + shift.
2840 { ISD::ZERO_EXTEND, MVT::v2i8, MVT::v2i1, { 2, 1, 1, 1 } },
2841 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v2i1, { 2, 1, 1, 1 } },
2842 { ISD::ZERO_EXTEND, MVT::v2i16, MVT::v2i1, { 2, 1, 1, 1 } },
2843 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v2i1, { 2, 1, 1, 1 } },
2844 { ISD::ZERO_EXTEND, MVT::v4i8, MVT::v4i1, { 2, 1, 1, 1 } },
2845 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v4i1, { 2, 1, 1, 1 } },
2846 { ISD::ZERO_EXTEND, MVT::v4i16, MVT::v4i1, { 2, 1, 1, 1 } },
2847 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v4i1, { 2, 1, 1, 1 } },
2848 { ISD::ZERO_EXTEND, MVT::v8i8, MVT::v8i1, { 2, 1, 1, 1 } },
2849 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v8i1, { 2, 1, 1, 1 } },
2850 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v8i1, { 2, 1, 1, 1 } },
2851 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v16i1, { 2, 1, 1, 1 } },
2852 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i1, { 2, 1, 1, 1 } },
2853 { ISD::ZERO_EXTEND, MVT::v32i8, MVT::v32i1, { 2, 1, 1, 1 } },
2854 { ISD::ZERO_EXTEND, MVT::v32i16, MVT::v32i1, { 2, 1, 1, 1 } },
2855 { ISD::ZERO_EXTEND, MVT::v64i8, MVT::v64i1, { 2, 1, 1, 1 } },
2856 { ISD::ZERO_EXTEND, MVT::v32i16, MVT::v64i1, { 2, 1, 1, 1 } },
2857
2858 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i8, { 2, 1, 1, 1 } },
2859 { ISD::TRUNCATE, MVT::v2i1, MVT::v16i8, { 2, 1, 1, 1 } },
2860 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i16, { 2, 1, 1, 1 } },
2861 { ISD::TRUNCATE, MVT::v2i1, MVT::v8i16, { 2, 1, 1, 1 } },
2862 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i8, { 2, 1, 1, 1 } },
2863 { ISD::TRUNCATE, MVT::v4i1, MVT::v16i8, { 2, 1, 1, 1 } },
2864 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i16, { 2, 1, 1, 1 } },
2865 { ISD::TRUNCATE, MVT::v4i1, MVT::v8i16, { 2, 1, 1, 1 } },
2866 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i8, { 2, 1, 1, 1 } },
2867 { ISD::TRUNCATE, MVT::v8i1, MVT::v16i8, { 2, 1, 1, 1 } },
2868 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i16, { 2, 1, 1, 1 } },
2869 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i8, { 2, 1, 1, 1 } },
2870 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i16, { 2, 1, 1, 1 } },
2871 { ISD::TRUNCATE, MVT::v32i1, MVT::v32i8, { 2, 1, 1, 1 } },
2872 { ISD::TRUNCATE, MVT::v32i1, MVT::v32i16, { 2, 1, 1, 1 } },
2873 { ISD::TRUNCATE, MVT::v64i1, MVT::v64i8, { 2, 1, 1, 1 } },
2874 { ISD::TRUNCATE, MVT::v64i1, MVT::v32i16, { 2, 1, 1, 1 } },
2875
2876 { ISD::TRUNCATE, MVT::v32i8, MVT::v32i16, { 2, 1, 1, 1 } },
2877 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i16, { 2, 1, 1, 1 } }, // widen to zmm
2878 { ISD::TRUNCATE, MVT::v2i8, MVT::v2i16, { 2, 1, 1, 1 } }, // vpmovwb
2879 { ISD::TRUNCATE, MVT::v4i8, MVT::v4i16, { 2, 1, 1, 1 } }, // vpmovwb
2880 { ISD::TRUNCATE, MVT::v8i8, MVT::v8i16, { 2, 1, 1, 1 } }, // vpmovwb
2881 };
2882
2883 static const TypeConversionCostKindTblEntry AVX512DQConversionTbl[] = {
2884 // Mask sign extend has an instruction.
2885 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v2i1, { 1, 1, 1, 1 } },
2886 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v2i1, { 1, 1, 1, 1 } },
2887 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v4i1, { 1, 1, 1, 1 } },
2888 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i1, { 1, 1, 1, 1 } },
2889 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i1, { 1, 1, 1, 1 } },
2890 { ISD::SIGN_EXTEND, MVT::v8i64, MVT::v16i1, { 1, 1, 1, 1 } },
2891 { ISD::SIGN_EXTEND, MVT::v8i64, MVT::v8i1, { 1, 1, 1, 1 } },
2892 { ISD::SIGN_EXTEND, MVT::v16i32, MVT::v16i1, { 1, 1, 1, 1 } },
2893
2894 // Mask zero extend is a sext + shift.
2895 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v2i1, { 2, 1, 1, 1, } },
2896 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v2i1, { 2, 1, 1, 1, } },
2897 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v4i1, { 2, 1, 1, 1, } },
2898 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i1, { 2, 1, 1, 1, } },
2899 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i1, { 2, 1, 1, 1, } },
2900 { ISD::ZERO_EXTEND, MVT::v8i64, MVT::v16i1, { 2, 1, 1, 1, } },
2901 { ISD::ZERO_EXTEND, MVT::v8i64, MVT::v8i1, { 2, 1, 1, 1, } },
2902 { ISD::ZERO_EXTEND, MVT::v16i32, MVT::v16i1, { 2, 1, 1, 1, } },
2903
2904 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i64, { 2, 1, 1, 1 } },
2905 { ISD::TRUNCATE, MVT::v2i1, MVT::v4i32, { 2, 1, 1, 1 } },
2906 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i32, { 2, 1, 1, 1 } },
2907 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i64, { 2, 1, 1, 1 } },
2908 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i32, { 2, 1, 1, 1 } },
2909 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i64, { 2, 1, 1, 1 } },
2910 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i32, { 2, 1, 1, 1 } },
2911 { ISD::TRUNCATE, MVT::v16i1, MVT::v8i64, { 2, 1, 1, 1 } },
2912
2913 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v8i64, { 1, 1, 1, 1 } },
2914 { ISD::SINT_TO_FP, MVT::v8f64, MVT::v8i64, { 1, 1, 1, 1 } },
2915
2916 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i64, { 1, 1, 1, 1 } },
2917 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i64, { 1, 1, 1, 1 } },
2918
2919 { ISD::FP_TO_SINT, MVT::v8i64, MVT::v8f32, { 1, 1, 1, 1 } },
2920 { ISD::FP_TO_SINT, MVT::v8i64, MVT::v8f64, { 1, 1, 1, 1 } },
2921
2922 { ISD::FP_TO_UINT, MVT::v8i64, MVT::v8f32, { 1, 1, 1, 1 } },
2923 { ISD::FP_TO_UINT, MVT::v8i64, MVT::v8f64, { 1, 1, 1, 1 } },
2924 };
2925
2926 // TODO: For AVX512DQ + AVX512VL, we also have cheap casts for 128-bit and
2927 // 256-bit wide vectors.
2928
2929 static const TypeConversionCostKindTblEntry AVX512FConversionTbl[] = {
2930 { ISD::FP_EXTEND, MVT::v8f64, MVT::v8f32, { 1, 1, 1, 1 } },
2931 { ISD::FP_EXTEND, MVT::v8f64, MVT::v16f32, { 3, 1, 1, 1 } },
2932 { ISD::FP_EXTEND, MVT::v16f64, MVT::v16f32, { 4, 1, 1, 1 } }, // 2*vcvtps2pd+vextractf64x4
2933 { ISD::FP_EXTEND, MVT::v16f32, MVT::v16f16, { 1, 1, 1, 1 } }, // vcvtph2ps
2934 { ISD::FP_EXTEND, MVT::v8f64, MVT::v8f16, { 2, 1, 1, 1 } }, // vcvtph2ps+vcvtps2pd
2935 { ISD::FP_ROUND, MVT::v8f32, MVT::v8f64, { 1, 1, 1, 1 } },
2936 { ISD::FP_ROUND, MVT::v16f16, MVT::v16f32, { 1, 1, 1, 1 } }, // vcvtps2ph
2937
2938 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i8, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
2939 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i8, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
2940 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i8, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
2941 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i8, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
2942 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i16, { 3, 1, 1, 1 } }, // sext+vpsllq+vptestmq
2943 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i16, { 3, 1, 1, 1 } }, // sext+vpsllq+vptestmq
2944 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i16, { 3, 1, 1, 1 } }, // sext+vpsllq+vptestmq
2945 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i16, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
2946 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i32, { 2, 1, 1, 1 } }, // zmm vpslld+vptestmd
2947 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i32, { 2, 1, 1, 1 } }, // zmm vpslld+vptestmd
2948 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i32, { 2, 1, 1, 1 } }, // zmm vpslld+vptestmd
2949 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i32, { 2, 1, 1, 1 } }, // vpslld+vptestmd
2950 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i64, { 2, 1, 1, 1 } }, // zmm vpsllq+vptestmq
2951 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i64, { 2, 1, 1, 1 } }, // zmm vpsllq+vptestmq
2952 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i64, { 2, 1, 1, 1 } }, // vpsllq+vptestmq
2953 { ISD::TRUNCATE, MVT::v2i8, MVT::v2i32, { 2, 1, 1, 1 } }, // vpmovdb
2954 { ISD::TRUNCATE, MVT::v4i8, MVT::v4i32, { 2, 1, 1, 1 } }, // vpmovdb
2955 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i32, { 2, 1, 1, 1 } }, // vpmovdb
2956 { ISD::TRUNCATE, MVT::v32i8, MVT::v16i32, { 2, 1, 1, 1 } }, // vpmovdb
2957 { ISD::TRUNCATE, MVT::v64i8, MVT::v16i32, { 2, 1, 1, 1 } }, // vpmovdb
2958 { ISD::TRUNCATE, MVT::v16i16, MVT::v16i32, { 2, 1, 1, 1 } }, // vpmovdw
2959 { ISD::TRUNCATE, MVT::v32i16, MVT::v16i32, { 2, 1, 1, 1 } }, // vpmovdw
2960 { ISD::TRUNCATE, MVT::v2i8, MVT::v2i64, { 2, 1, 1, 1 } }, // vpmovqb
2961 { ISD::TRUNCATE, MVT::v2i16, MVT::v2i64, { 1, 1, 1, 1 } }, // vpshufb
2962 { ISD::TRUNCATE, MVT::v8i8, MVT::v8i64, { 2, 1, 1, 1 } }, // vpmovqb
2963 { ISD::TRUNCATE, MVT::v16i8, MVT::v8i64, { 2, 1, 1, 1 } }, // vpmovqb
2964 { ISD::TRUNCATE, MVT::v32i8, MVT::v8i64, { 2, 1, 1, 1 } }, // vpmovqb
2965 { ISD::TRUNCATE, MVT::v64i8, MVT::v8i64, { 2, 1, 1, 1 } }, // vpmovqb
2966 { ISD::TRUNCATE, MVT::v8i16, MVT::v8i64, { 2, 1, 1, 1 } }, // vpmovqw
2967 { ISD::TRUNCATE, MVT::v16i16, MVT::v8i64, { 2, 1, 1, 1 } }, // vpmovqw
2968 { ISD::TRUNCATE, MVT::v32i16, MVT::v8i64, { 2, 1, 1, 1 } }, // vpmovqw
2969 { ISD::TRUNCATE, MVT::v8i32, MVT::v8i64, { 1, 1, 1, 1 } }, // vpmovqd
2970 { ISD::TRUNCATE, MVT::v4i32, MVT::v4i64, { 1, 1, 1, 1 } }, // zmm vpmovqd
2971 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i64, { 5, 1, 1, 1 } },// 2*vpmovqd+concat+vpmovdb
2972
2973 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i16, { 3, 1, 1, 1 } }, // extend to v16i32
2974 { ISD::TRUNCATE, MVT::v32i8, MVT::v32i16, { 8, 1, 1, 1 } },
2975 { ISD::TRUNCATE, MVT::v64i8, MVT::v32i16, { 8, 1, 1, 1 } },
2976
2977 // Sign extend is zmm vpternlogd+vptruncdb.
2978 // Zero extend is zmm broadcast load+vptruncdw.
2979 { ISD::SIGN_EXTEND, MVT::v2i8, MVT::v2i1, { 3, 1, 1, 1 } },
2980 { ISD::ZERO_EXTEND, MVT::v2i8, MVT::v2i1, { 4, 1, 1, 1 } },
2981 { ISD::SIGN_EXTEND, MVT::v4i8, MVT::v4i1, { 3, 1, 1, 1 } },
2982 { ISD::ZERO_EXTEND, MVT::v4i8, MVT::v4i1, { 4, 1, 1, 1 } },
2983 { ISD::SIGN_EXTEND, MVT::v8i8, MVT::v8i1, { 3, 1, 1, 1 } },
2984 { ISD::ZERO_EXTEND, MVT::v8i8, MVT::v8i1, { 4, 1, 1, 1 } },
2985 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v16i1, { 3, 1, 1, 1 } },
2986 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v16i1, { 4, 1, 1, 1 } },
2987
2988 // Sign extend is zmm vpternlogd+vptruncdw.
2989 // Zero extend is zmm vpternlogd+vptruncdw+vpsrlw.
2990 { ISD::SIGN_EXTEND, MVT::v2i16, MVT::v2i1, { 3, 1, 1, 1 } },
2991 { ISD::ZERO_EXTEND, MVT::v2i16, MVT::v2i1, { 4, 1, 1, 1 } },
2992 { ISD::SIGN_EXTEND, MVT::v4i16, MVT::v4i1, { 3, 1, 1, 1 } },
2993 { ISD::ZERO_EXTEND, MVT::v4i16, MVT::v4i1, { 4, 1, 1, 1 } },
2994 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v8i1, { 3, 1, 1, 1 } },
2995 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v8i1, { 4, 1, 1, 1 } },
2996 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i1, { 3, 1, 1, 1 } },
2997 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i1, { 4, 1, 1, 1 } },
2998
2999 { ISD::SIGN_EXTEND, MVT::v2i32, MVT::v2i1, { 1, 1, 1, 1 } }, // zmm vpternlogd
3000 { ISD::ZERO_EXTEND, MVT::v2i32, MVT::v2i1, { 2, 1, 1, 1 } }, // zmm vpternlogd+psrld
3001 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v4i1, { 1, 1, 1, 1 } }, // zmm vpternlogd
3002 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v4i1, { 2, 1, 1, 1 } }, // zmm vpternlogd+psrld
3003 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i1, { 1, 1, 1, 1 } }, // zmm vpternlogd
3004 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i1, { 2, 1, 1, 1 } }, // zmm vpternlogd+psrld
3005 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v2i1, { 1, 1, 1, 1 } }, // zmm vpternlogq
3006 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v2i1, { 2, 1, 1, 1 } }, // zmm vpternlogq+psrlq
3007 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i1, { 1, 1, 1, 1 } }, // zmm vpternlogq
3008 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i1, { 2, 1, 1, 1 } }, // zmm vpternlogq+psrlq
3009
3010 { ISD::SIGN_EXTEND, MVT::v16i32, MVT::v16i1, { 1, 1, 1, 1 } }, // vpternlogd
3011 { ISD::ZERO_EXTEND, MVT::v16i32, MVT::v16i1, { 2, 1, 1, 1 } }, // vpternlogd+psrld
3012 { ISD::SIGN_EXTEND, MVT::v8i64, MVT::v8i1, { 1, 1, 1, 1 } }, // vpternlogq
3013 { ISD::ZERO_EXTEND, MVT::v8i64, MVT::v8i1, { 2, 1, 1, 1 } }, // vpternlogq+psrlq
3014
3015 { ISD::SIGN_EXTEND, MVT::v16i32, MVT::v16i8, { 1, 1, 1, 1 } },
3016 { ISD::ZERO_EXTEND, MVT::v16i32, MVT::v16i8, { 1, 1, 1, 1 } },
3017 { ISD::SIGN_EXTEND, MVT::v16i32, MVT::v16i16, { 1, 1, 1, 1 } },
3018 { ISD::ZERO_EXTEND, MVT::v16i32, MVT::v16i16, { 1, 1, 1, 1 } },
3019 { ISD::SIGN_EXTEND, MVT::v8i64, MVT::v8i8, { 1, 1, 1, 1 } },
3020 { ISD::ZERO_EXTEND, MVT::v8i64, MVT::v8i8, { 1, 1, 1, 1 } },
3021 { ISD::SIGN_EXTEND, MVT::v8i64, MVT::v8i16, { 1, 1, 1, 1 } },
3022 { ISD::ZERO_EXTEND, MVT::v8i64, MVT::v8i16, { 1, 1, 1, 1 } },
3023 { ISD::SIGN_EXTEND, MVT::v8i64, MVT::v8i32, { 1, 1, 1, 1 } },
3024 { ISD::ZERO_EXTEND, MVT::v8i64, MVT::v8i32, { 1, 1, 1, 1 } },
3025
3026 { ISD::SIGN_EXTEND, MVT::v32i16, MVT::v32i8, { 3, 1, 1, 1 } }, // FIXME: May not be right
3027 { ISD::ZERO_EXTEND, MVT::v32i16, MVT::v32i8, { 3, 1, 1, 1 } }, // FIXME: May not be right
3028
3029 { ISD::SINT_TO_FP, MVT::v8f64, MVT::v8i1, { 4, 1, 1, 1 } },
3030 { ISD::SINT_TO_FP, MVT::v16f32, MVT::v16i1, { 3, 1, 1, 1 } },
3031 { ISD::SINT_TO_FP, MVT::v8f64, MVT::v16i8, { 2, 1, 1, 1 } },
3032 { ISD::SINT_TO_FP, MVT::v16f32, MVT::v16i8, { 1, 1, 1, 1 } },
3033 { ISD::SINT_TO_FP, MVT::v8f64, MVT::v8i16, { 2, 1, 1, 1 } },
3034 { ISD::SINT_TO_FP, MVT::v16f32, MVT::v16i16, { 1, 1, 1, 1 } },
3035 { ISD::SINT_TO_FP, MVT::v8f64, MVT::v8i32, { 1, 1, 1, 1 } },
3036 { ISD::SINT_TO_FP, MVT::v16f32, MVT::v16i32, { 1, 1, 1, 1 } },
3037
3038 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i1, { 4, 1, 1, 1 } },
3039 { ISD::UINT_TO_FP, MVT::v16f32, MVT::v16i1, { 3, 1, 1, 1 } },
3040 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v16i8, { 2, 1, 1, 1 } },
3041 { ISD::UINT_TO_FP, MVT::v16f32, MVT::v16i8, { 1, 1, 1, 1 } },
3042 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i16, { 2, 1, 1, 1 } },
3043 { ISD::UINT_TO_FP, MVT::v16f32, MVT::v16i16, { 1, 1, 1, 1 } },
3044 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i32, { 1, 1, 1, 1 } },
3045 { ISD::UINT_TO_FP, MVT::v16f32, MVT::v16i32, { 1, 1, 1, 1 } },
3046 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i64, {26, 1, 1, 1 } },
3047 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i64, { 5, 1, 1, 1 } },
3048
3049 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v16f32, { 2, 1, 1, 1 } },
3050 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v16f64, { 7, 1, 1, 1 } },
3051 { ISD::FP_TO_SINT, MVT::v32i8, MVT::v32f64, {15, 1, 1, 1 } },
3052 { ISD::FP_TO_SINT, MVT::v64i8, MVT::v64f32, {11, 1, 1, 1 } },
3053 { ISD::FP_TO_SINT, MVT::v64i8, MVT::v64f64, {31, 1, 1, 1 } },
3054 { ISD::FP_TO_SINT, MVT::v8i16, MVT::v8f64, { 3, 1, 1, 1 } },
3055 { ISD::FP_TO_SINT, MVT::v16i16, MVT::v16f64, { 7, 1, 1, 1 } },
3056 { ISD::FP_TO_SINT, MVT::v32i16, MVT::v32f32, { 5, 1, 1, 1 } },
3057 { ISD::FP_TO_SINT, MVT::v32i16, MVT::v32f64, {15, 1, 1, 1 } },
3058 { ISD::FP_TO_SINT, MVT::v8i32, MVT::v8f64, { 1, 1, 1, 1 } },
3059 { ISD::FP_TO_SINT, MVT::v16i32, MVT::v16f64, { 3, 1, 1, 1 } },
3060
3061 { ISD::FP_TO_UINT, MVT::v8i32, MVT::v8f64, { 1, 1, 1, 1 } },
3062 { ISD::FP_TO_UINT, MVT::v8i16, MVT::v8f64, { 3, 1, 1, 1 } },
3063 { ISD::FP_TO_UINT, MVT::v8i8, MVT::v8f64, { 3, 1, 1, 1 } },
3064 { ISD::FP_TO_UINT, MVT::v16i32, MVT::v16f32, { 1, 1, 1, 1 } },
3065 { ISD::FP_TO_UINT, MVT::v16i16, MVT::v16f32, { 3, 1, 1, 1 } },
3066 { ISD::FP_TO_UINT, MVT::v16i8, MVT::v16f32, { 3, 1, 1, 1 } },
3067 };
3068
3069 static const TypeConversionCostKindTblEntry AVX512BWVLConversionTbl[] {
3070 // Mask sign extend has an instruction.
3071 { ISD::SIGN_EXTEND, MVT::v2i8, MVT::v2i1, { 1, 1, 1, 1 } },
3072 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v2i1, { 1, 1, 1, 1 } },
3073 { ISD::SIGN_EXTEND, MVT::v2i16, MVT::v2i1, { 1, 1, 1, 1 } },
3074 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v2i1, { 1, 1, 1, 1 } },
3075 { ISD::SIGN_EXTEND, MVT::v4i16, MVT::v4i1, { 1, 1, 1, 1 } },
3076 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v4i1, { 1, 1, 1, 1 } },
3077 { ISD::SIGN_EXTEND, MVT::v4i8, MVT::v4i1, { 1, 1, 1, 1 } },
3078 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v4i1, { 1, 1, 1, 1 } },
3079 { ISD::SIGN_EXTEND, MVT::v8i8, MVT::v8i1, { 1, 1, 1, 1 } },
3080 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v8i1, { 1, 1, 1, 1 } },
3081 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v8i1, { 1, 1, 1, 1 } },
3082 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v16i1, { 1, 1, 1, 1 } },
3083 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i1, { 1, 1, 1, 1 } },
3084 { ISD::SIGN_EXTEND, MVT::v32i8, MVT::v32i1, { 1, 1, 1, 1 } },
3085 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v32i1, { 1, 1, 1, 1 } },
3086 { ISD::SIGN_EXTEND, MVT::v32i8, MVT::v64i1, { 1, 1, 1, 1 } },
3087 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v64i1, { 1, 1, 1, 1 } },
3088
3089 // Mask zero extend is a sext + shift.
3090 { ISD::ZERO_EXTEND, MVT::v2i8, MVT::v2i1, { 2, 1, 1, 1 } },
3091 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v2i1, { 2, 1, 1, 1 } },
3092 { ISD::ZERO_EXTEND, MVT::v2i16, MVT::v2i1, { 2, 1, 1, 1 } },
3093 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v2i1, { 2, 1, 1, 1 } },
3094 { ISD::ZERO_EXTEND, MVT::v4i8, MVT::v4i1, { 2, 1, 1, 1 } },
3095 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v4i1, { 2, 1, 1, 1 } },
3096 { ISD::ZERO_EXTEND, MVT::v4i16, MVT::v4i1, { 2, 1, 1, 1 } },
3097 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v4i1, { 2, 1, 1, 1 } },
3098 { ISD::ZERO_EXTEND, MVT::v8i8, MVT::v8i1, { 2, 1, 1, 1 } },
3099 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v8i1, { 2, 1, 1, 1 } },
3100 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v8i1, { 2, 1, 1, 1 } },
3101 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v16i1, { 2, 1, 1, 1 } },
3102 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i1, { 2, 1, 1, 1 } },
3103 { ISD::ZERO_EXTEND, MVT::v32i8, MVT::v32i1, { 2, 1, 1, 1 } },
3104 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v32i1, { 2, 1, 1, 1 } },
3105 { ISD::ZERO_EXTEND, MVT::v32i8, MVT::v64i1, { 2, 1, 1, 1 } },
3106 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v64i1, { 2, 1, 1, 1 } },
3107
3108 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i8, { 2, 1, 1, 1 } },
3109 { ISD::TRUNCATE, MVT::v2i1, MVT::v16i8, { 2, 1, 1, 1 } },
3110 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i16, { 2, 1, 1, 1 } },
3111 { ISD::TRUNCATE, MVT::v2i1, MVT::v8i16, { 2, 1, 1, 1 } },
3112 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i8, { 2, 1, 1, 1 } },
3113 { ISD::TRUNCATE, MVT::v4i1, MVT::v16i8, { 2, 1, 1, 1 } },
3114 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i16, { 2, 1, 1, 1 } },
3115 { ISD::TRUNCATE, MVT::v4i1, MVT::v8i16, { 2, 1, 1, 1 } },
3116 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i8, { 2, 1, 1, 1 } },
3117 { ISD::TRUNCATE, MVT::v8i1, MVT::v16i8, { 2, 1, 1, 1 } },
3118 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i16, { 2, 1, 1, 1 } },
3119 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i8, { 2, 1, 1, 1 } },
3120 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i16, { 2, 1, 1, 1 } },
3121 { ISD::TRUNCATE, MVT::v32i1, MVT::v32i8, { 2, 1, 1, 1 } },
3122 { ISD::TRUNCATE, MVT::v32i1, MVT::v16i16, { 2, 1, 1, 1 } },
3123 { ISD::TRUNCATE, MVT::v64i1, MVT::v32i8, { 2, 1, 1, 1 } },
3124 { ISD::TRUNCATE, MVT::v64i1, MVT::v16i16, { 2, 1, 1, 1 } },
3125
3126 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i16, { 2, 1, 1, 1 } },
3127 };
3128
3129 static const TypeConversionCostKindTblEntry AVX512DQVLConversionTbl[] = {
3130 // Mask sign extend has an instruction.
3131 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v2i1, { 1, 1, 1, 1 } },
3132 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v2i1, { 1, 1, 1, 1 } },
3133 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v4i1, { 1, 1, 1, 1 } },
3134 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v16i1, { 1, 1, 1, 1 } },
3135 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i1, { 1, 1, 1, 1 } },
3136 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v8i1, { 1, 1, 1, 1 } },
3137 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v16i1, { 1, 1, 1, 1 } },
3138 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i1, { 1, 1, 1, 1 } },
3139
3140 // Mask zero extend is a sext + shift.
3141 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v2i1, { 2, 1, 1, 1 } },
3142 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v2i1, { 2, 1, 1, 1 } },
3143 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v4i1, { 2, 1, 1, 1 } },
3144 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v16i1, { 2, 1, 1, 1 } },
3145 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i1, { 2, 1, 1, 1 } },
3146 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v8i1, { 2, 1, 1, 1 } },
3147 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v16i1, { 2, 1, 1, 1 } },
3148 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i1, { 2, 1, 1, 1 } },
3149
3150 { ISD::TRUNCATE, MVT::v16i1, MVT::v4i64, { 2, 1, 1, 1 } },
3151 { ISD::TRUNCATE, MVT::v16i1, MVT::v8i32, { 2, 1, 1, 1 } },
3152 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i64, { 2, 1, 1, 1 } },
3153 { ISD::TRUNCATE, MVT::v2i1, MVT::v4i32, { 2, 1, 1, 1 } },
3154 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i32, { 2, 1, 1, 1 } },
3155 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i64, { 2, 1, 1, 1 } },
3156 { ISD::TRUNCATE, MVT::v8i1, MVT::v4i64, { 2, 1, 1, 1 } },
3157 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i32, { 2, 1, 1, 1 } },
3158
3159 { ISD::SINT_TO_FP, MVT::v2f32, MVT::v2i64, { 1, 1, 1, 1 } },
3160 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v2i64, { 1, 1, 1, 1 } },
3161 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v4i64, { 1, 1, 1, 1 } },
3162 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v4i64, { 1, 1, 1, 1 } },
3163
3164 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i64, { 1, 1, 1, 1 } },
3165 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i64, { 1, 1, 1, 1 } },
3166 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i64, { 1, 1, 1, 1 } },
3167 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i64, { 1, 1, 1, 1 } },
3168
3169 { ISD::FP_TO_SINT, MVT::v2i64, MVT::v4f32, { 1, 1, 1, 1 } },
3170 { ISD::FP_TO_SINT, MVT::v4i64, MVT::v4f32, { 1, 1, 1, 1 } },
3171 { ISD::FP_TO_SINT, MVT::v2i64, MVT::v2f64, { 1, 1, 1, 1 } },
3172 { ISD::FP_TO_SINT, MVT::v4i64, MVT::v4f64, { 1, 1, 1, 1 } },
3173
3174 { ISD::FP_TO_UINT, MVT::v2i64, MVT::v4f32, { 1, 1, 1, 1 } },
3175 { ISD::FP_TO_UINT, MVT::v4i64, MVT::v4f32, { 1, 1, 1, 1 } },
3176 { ISD::FP_TO_UINT, MVT::v2i64, MVT::v2f64, { 1, 1, 1, 1 } },
3177 { ISD::FP_TO_UINT, MVT::v4i64, MVT::v4f64, { 1, 1, 1, 1 } },
3178 };
3179
3180 static const TypeConversionCostKindTblEntry AVX512VLConversionTbl[] = {
3181 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i8, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
3182 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i8, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
3183 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i8, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
3184 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i8, { 8, 1, 1, 1 } }, // split+2*v8i8
3185 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i16, { 3, 1, 1, 1 } }, // sext+vpsllq+vptestmq
3186 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i16, { 3, 1, 1, 1 } }, // sext+vpsllq+vptestmq
3187 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i16, { 3, 1, 1, 1 } }, // sext+vpsllq+vptestmq
3188 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i16, { 8, 1, 1, 1 } }, // split+2*v8i16
3189 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i32, { 2, 1, 1, 1 } }, // vpslld+vptestmd
3190 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i32, { 2, 1, 1, 1 } }, // vpslld+vptestmd
3191 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i32, { 2, 1, 1, 1 } }, // vpslld+vptestmd
3192 { ISD::TRUNCATE, MVT::v16i1, MVT::v8i32, { 2, 1, 1, 1 } }, // vpslld+vptestmd
3193 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i64, { 2, 1, 1, 1 } }, // vpsllq+vptestmq
3194 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i64, { 2, 1, 1, 1 } }, // vpsllq+vptestmq
3195 { ISD::TRUNCATE, MVT::v4i32, MVT::v4i64, { 1, 1, 1, 1 } }, // vpmovqd
3196 { ISD::TRUNCATE, MVT::v4i8, MVT::v4i64, { 2, 1, 1, 1 } }, // vpmovqb
3197 { ISD::TRUNCATE, MVT::v4i16, MVT::v4i64, { 2, 1, 1, 1 } }, // vpmovqw
3198 { ISD::TRUNCATE, MVT::v8i8, MVT::v8i32, { 2, 1, 1, 1 } }, // vpmovwb
3199
3200 // sign extend is vpcmpeq+maskedmove+vpmovdw+vpacksswb
3201 // zero extend is vpcmpeq+maskedmove+vpmovdw+vpsrlw+vpackuswb
3202 { ISD::SIGN_EXTEND, MVT::v2i8, MVT::v2i1, { 5, 1, 1, 1 } },
3203 { ISD::ZERO_EXTEND, MVT::v2i8, MVT::v2i1, { 6, 1, 1, 1 } },
3204 { ISD::SIGN_EXTEND, MVT::v4i8, MVT::v4i1, { 5, 1, 1, 1 } },
3205 { ISD::ZERO_EXTEND, MVT::v4i8, MVT::v4i1, { 6, 1, 1, 1 } },
3206 { ISD::SIGN_EXTEND, MVT::v8i8, MVT::v8i1, { 5, 1, 1, 1 } },
3207 { ISD::ZERO_EXTEND, MVT::v8i8, MVT::v8i1, { 6, 1, 1, 1 } },
3208 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v16i1, {10, 1, 1, 1 } },
3209 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v16i1, {12, 1, 1, 1 } },
3210
3211 // sign extend is vpcmpeq+maskedmove+vpmovdw
3212 // zero extend is vpcmpeq+maskedmove+vpmovdw+vpsrlw
3213 { ISD::SIGN_EXTEND, MVT::v2i16, MVT::v2i1, { 4, 1, 1, 1 } },
3214 { ISD::ZERO_EXTEND, MVT::v2i16, MVT::v2i1, { 5, 1, 1, 1 } },
3215 { ISD::SIGN_EXTEND, MVT::v4i16, MVT::v4i1, { 4, 1, 1, 1 } },
3216 { ISD::ZERO_EXTEND, MVT::v4i16, MVT::v4i1, { 5, 1, 1, 1 } },
3217 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v8i1, { 4, 1, 1, 1 } },
3218 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v8i1, { 5, 1, 1, 1 } },
3219 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i1, {10, 1, 1, 1 } },
3220 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i1, {12, 1, 1, 1 } },
3221
3222 { ISD::SIGN_EXTEND, MVT::v2i32, MVT::v2i1, { 1, 1, 1, 1 } }, // vpternlogd
3223 { ISD::ZERO_EXTEND, MVT::v2i32, MVT::v2i1, { 2, 1, 1, 1 } }, // vpternlogd+psrld
3224 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v4i1, { 1, 1, 1, 1 } }, // vpternlogd
3225 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v4i1, { 2, 1, 1, 1 } }, // vpternlogd+psrld
3226 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i1, { 1, 1, 1, 1 } }, // vpternlogd
3227 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i1, { 2, 1, 1, 1 } }, // vpternlogd+psrld
3228 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v16i1, { 1, 1, 1, 1 } }, // vpternlogd
3229 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v16i1, { 2, 1, 1, 1 } }, // vpternlogd+psrld
3230
3231 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v2i1, { 1, 1, 1, 1 } }, // vpternlogq
3232 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v2i1, { 2, 1, 1, 1 } }, // vpternlogq+psrlq
3233 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i1, { 1, 1, 1, 1 } }, // vpternlogq
3234 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i1, { 2, 1, 1, 1 } }, // vpternlogq+psrlq
3235
3236 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v16i8, { 1, 1, 1, 1 } },
3237 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v16i8, { 1, 1, 1, 1 } },
3238 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v16i8, { 1, 1, 1, 1 } },
3239 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v16i8, { 1, 1, 1, 1 } },
3240 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i8, { 1, 1, 1, 1 } },
3241 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i8, { 1, 1, 1, 1 } },
3242 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v8i16, { 1, 1, 1, 1 } },
3243 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v8i16, { 1, 1, 1, 1 } },
3244 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i16, { 1, 1, 1, 1 } },
3245 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i16, { 1, 1, 1, 1 } },
3246 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i32, { 1, 1, 1, 1 } },
3247 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i32, { 1, 1, 1, 1 } },
3248
3249 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v16i8, { 1, 1, 1, 1 } },
3250 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v16i8, { 1, 1, 1, 1 } },
3251 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v8i16, { 1, 1, 1, 1 } },
3252 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v8i16, { 1, 1, 1, 1 } },
3253
3254 { ISD::UINT_TO_FP, MVT::f32, MVT::i64, { 1, 1, 1, 1 } },
3255 { ISD::UINT_TO_FP, MVT::f64, MVT::i64, { 1, 1, 1, 1 } },
3256 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v16i8, { 1, 1, 1, 1 } },
3257 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v16i8, { 1, 1, 1, 1 } },
3258 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v8i16, { 1, 1, 1, 1 } },
3259 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i16, { 1, 1, 1, 1 } },
3260 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i32, { 1, 1, 1, 1 } },
3261 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i32, { 1, 1, 1, 1 } },
3262 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i32, { 1, 1, 1, 1 } },
3263 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i32, { 1, 1, 1, 1 } },
3264 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i64, { 5, 1, 1, 1 } },
3265 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i64, { 5, 1, 1, 1 } },
3266 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i64, { 5, 1, 1, 1 } },
3267
3268 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v8f32, { 2, 1, 1, 1 } },
3269 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v16f32, { 2, 1, 1, 1 } },
3270 { ISD::FP_TO_SINT, MVT::v32i8, MVT::v32f32, { 5, 1, 1, 1 } },
3271
3272 { ISD::FP_TO_UINT, MVT::i64, MVT::f32, { 1, 1, 1, 1 } },
3273 { ISD::FP_TO_UINT, MVT::i64, MVT::f64, { 1, 1, 1, 1 } },
3274 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f32, { 1, 1, 1, 1 } },
3275 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v2f64, { 1, 1, 1, 1 } },
3276 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f64, { 1, 1, 1, 1 } },
3277 { ISD::FP_TO_UINT, MVT::v8i32, MVT::v8f32, { 1, 1, 1, 1 } },
3278 { ISD::FP_TO_UINT, MVT::v8i32, MVT::v8f64, { 1, 1, 1, 1 } },
3279 };
3280
3281 static const TypeConversionCostKindTblEntry AVX2ConversionTbl[] = {
3282 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i1, { 3, 1, 1, 1 } },
3283 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i1, { 3, 1, 1, 1 } },
3284 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i1, { 3, 1, 1, 1 } },
3285 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i1, { 3, 1, 1, 1 } },
3286 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i1, { 1, 1, 1, 1 } },
3287 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i1, { 1, 1, 1, 1 } },
3288
3289 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v16i8, { 2, 1, 1, 1 } },
3290 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v16i8, { 2, 1, 1, 1 } },
3291 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v16i8, { 2, 1, 1, 1 } },
3292 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v16i8, { 2, 1, 1, 1 } },
3293 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i8, { 2, 1, 1, 1 } },
3294 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i8, { 2, 1, 1, 1 } },
3295 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v8i16, { 2, 1, 1, 1 } },
3296 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v8i16, { 2, 1, 1, 1 } },
3297 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i16, { 2, 1, 1, 1 } },
3298 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i16, { 2, 1, 1, 1 } },
3299 { ISD::ZERO_EXTEND, MVT::v16i32, MVT::v16i16, { 3, 1, 1, 1 } },
3300 { ISD::SIGN_EXTEND, MVT::v16i32, MVT::v16i16, { 3, 1, 1, 1 } },
3301 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i32, { 2, 1, 1, 1 } },
3302 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i32, { 2, 1, 1, 1 } },
3303
3304 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i32, { 2, 1, 1, 1 } },
3305
3306 { ISD::TRUNCATE, MVT::v16i16, MVT::v16i32, { 4, 1, 1, 1 } },
3307 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i32, { 4, 1, 1, 1 } },
3308 { ISD::TRUNCATE, MVT::v16i8, MVT::v8i16, { 1, 1, 1, 1 } },
3309 { ISD::TRUNCATE, MVT::v16i8, MVT::v4i32, { 1, 1, 1, 1 } },
3310 { ISD::TRUNCATE, MVT::v16i8, MVT::v2i64, { 1, 1, 1, 1 } },
3311 { ISD::TRUNCATE, MVT::v16i8, MVT::v8i32, { 4, 1, 1, 1 } },
3312 { ISD::TRUNCATE, MVT::v16i8, MVT::v4i64, { 4, 1, 1, 1 } },
3313 { ISD::TRUNCATE, MVT::v8i16, MVT::v4i32, { 1, 1, 1, 1 } },
3314 { ISD::TRUNCATE, MVT::v8i16, MVT::v2i64, { 1, 1, 1, 1 } },
3315 { ISD::TRUNCATE, MVT::v8i16, MVT::v4i64, { 5, 1, 1, 1 } },
3316 { ISD::TRUNCATE, MVT::v4i32, MVT::v4i64, { 1, 1, 1, 1 } },
3317 { ISD::TRUNCATE, MVT::v8i16, MVT::v8i32, { 2, 1, 1, 1 } },
3318
3319 { ISD::FP_EXTEND, MVT::v8f64, MVT::v8f32, { 3, 1, 1, 1 } },
3320 { ISD::FP_ROUND, MVT::v8f32, MVT::v8f64, { 3, 1, 1, 1 } },
3321
3322 { ISD::FP_TO_SINT, MVT::v16i16, MVT::v8f32, { 1, 1, 1, 1 } },
3323 { ISD::FP_TO_SINT, MVT::v4i32, MVT::v4f64, { 1, 1, 1, 1 } },
3324 { ISD::FP_TO_SINT, MVT::v8i32, MVT::v8f32, { 1, 1, 1, 1 } },
3325 { ISD::FP_TO_SINT, MVT::v8i32, MVT::v8f64, { 3, 1, 1, 1 } },
3326
3327 { ISD::FP_TO_UINT, MVT::i64, MVT::f32, { 3, 1, 1, 1 } },
3328 { ISD::FP_TO_UINT, MVT::i64, MVT::f64, { 3, 1, 1, 1 } },
3329 { ISD::FP_TO_UINT, MVT::v16i16, MVT::v8f32, { 1, 1, 1, 1 } },
3330 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f32, { 3, 1, 1, 1 } },
3331 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v2f64, { 4, 1, 1, 1 } },
3332 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f64, { 4, 1, 1, 1 } },
3333 { ISD::FP_TO_UINT, MVT::v8i32, MVT::v8f32, { 3, 1, 1, 1 } },
3334 { ISD::FP_TO_UINT, MVT::v8i32, MVT::v4f64, { 4, 1, 1, 1 } },
3335
3336 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v16i8, { 2, 1, 1, 1 } },
3337 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v16i8, { 2, 1, 1, 1 } },
3338 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v8i16, { 2, 1, 1, 1 } },
3339 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v8i16, { 2, 1, 1, 1 } },
3340 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v4i32, { 1, 1, 1, 1 } },
3341 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v8i32, { 1, 1, 1, 1 } },
3342 { ISD::SINT_TO_FP, MVT::v8f64, MVT::v8i32, { 3, 1, 1, 1 } },
3343
3344 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v16i8, { 2, 1, 1, 1 } },
3345 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v16i8, { 2, 1, 1, 1 } },
3346 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v8i16, { 2, 1, 1, 1 } },
3347 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i16, { 2, 1, 1, 1 } },
3348 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i32, { 2, 1, 1, 1 } },
3349 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i32, { 1, 1, 1, 1 } },
3350 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i32, { 2, 1, 1, 1 } },
3351 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i32, { 2, 1, 1, 1 } },
3352 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i32, { 2, 1, 1, 1 } },
3353 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i32, { 4, 1, 1, 1 } },
3354 };
3355
3356 static const TypeConversionCostKindTblEntry AVXConversionTbl[] = {
3357 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i1, { 4, 1, 1, 1 } },
3358 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i1, { 4, 1, 1, 1 } },
3359 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i1, { 4, 1, 1, 1 } },
3360 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i1, { 4, 1, 1, 1 } },
3361 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i1, { 4, 1, 1, 1 } },
3362 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i1, { 4, 1, 1, 1 } },
3363
3364 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v16i8, { 3, 1, 1, 1 } },
3365 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v16i8, { 3, 1, 1, 1 } },
3366 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v16i8, { 3, 1, 1, 1 } },
3367 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v16i8, { 3, 1, 1, 1 } },
3368 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i8, { 3, 1, 1, 1 } },
3369 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i8, { 3, 1, 1, 1 } },
3370 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v8i16, { 3, 1, 1, 1 } },
3371 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v8i16, { 3, 1, 1, 1 } },
3372 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i16, { 3, 1, 1, 1 } },
3373 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i16, { 3, 1, 1, 1 } },
3374 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i32, { 3, 1, 1, 1 } },
3375 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i32, { 3, 1, 1, 1 } },
3376
3377 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i64, { 4, 1, 1, 1 } },
3378 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i32, { 5, 1, 1, 1 } },
3379 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i16, { 4, 1, 1, 1 } },
3380 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i64, { 9, 1, 1, 1 } },
3381 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i64, {11, 1, 1, 1 } },
3382
3383 { ISD::TRUNCATE, MVT::v16i16, MVT::v16i32, { 6, 1, 1, 1 } },
3384 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i32, { 6, 1, 1, 1 } },
3385 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i16, { 2, 1, 1, 1 } }, // and+extract+packuswb
3386 { ISD::TRUNCATE, MVT::v16i8, MVT::v8i32, { 5, 1, 1, 1 } },
3387 { ISD::TRUNCATE, MVT::v8i16, MVT::v8i32, { 5, 1, 1, 1 } },
3388 { ISD::TRUNCATE, MVT::v16i8, MVT::v4i64, { 5, 1, 1, 1 } },
3389 { ISD::TRUNCATE, MVT::v8i16, MVT::v4i64, { 3, 1, 1, 1 } }, // and+extract+2*packusdw
3390 { ISD::TRUNCATE, MVT::v4i32, MVT::v4i64, { 2, 1, 1, 1 } },
3391
3392 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v4i1, { 3, 1, 1, 1 } },
3393 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v4i1, { 3, 1, 1, 1 } },
3394 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v8i1, { 8, 1, 1, 1 } },
3395 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v16i8, { 4, 1, 1, 1 } },
3396 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v16i8, { 2, 1, 1, 1 } },
3397 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v8i16, { 4, 1, 1, 1 } },
3398 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v8i16, { 2, 1, 1, 1 } },
3399 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v4i32, { 2, 1, 1, 1 } },
3400 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v8i32, { 2, 1, 1, 1 } },
3401 { ISD::SINT_TO_FP, MVT::v8f64, MVT::v8i32, { 4, 1, 1, 1 } },
3402 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v2i64, { 5, 1, 1, 1 } },
3403 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v4i64, { 8, 1, 1, 1 } },
3404
3405 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i1, { 7, 1, 1, 1 } },
3406 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i1, { 7, 1, 1, 1 } },
3407 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i1, { 6, 1, 1, 1 } },
3408 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v16i8, { 4, 1, 1, 1 } },
3409 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v16i8, { 2, 1, 1, 1 } },
3410 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i16, { 4, 1, 1, 1 } },
3411 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v8i16, { 2, 1, 1, 1 } },
3412 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i32, { 4, 1, 1, 1 } },
3413 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i32, { 4, 1, 1, 1 } },
3414 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i32, { 5, 1, 1, 1 } },
3415 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i32, { 6, 1, 1, 1 } },
3416 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i32, { 8, 1, 1, 1 } },
3417 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i32, {10, 1, 1, 1 } },
3418 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i64, {10, 1, 1, 1 } },
3419 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i64, {18, 1, 1, 1 } },
3420 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i64, { 5, 1, 1, 1 } },
3421 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i64, {10, 1, 1, 1 } },
3422
3423 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v8f32, { 2, 1, 1, 1 } },
3424 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v4f64, { 2, 1, 1, 1 } },
3425 { ISD::FP_TO_SINT, MVT::v32i8, MVT::v8f32, { 2, 1, 1, 1 } },
3426 { ISD::FP_TO_SINT, MVT::v32i8, MVT::v4f64, { 2, 1, 1, 1 } },
3427 { ISD::FP_TO_SINT, MVT::v8i16, MVT::v8f32, { 2, 1, 1, 1 } },
3428 { ISD::FP_TO_SINT, MVT::v8i16, MVT::v4f64, { 2, 1, 1, 1 } },
3429 { ISD::FP_TO_SINT, MVT::v16i16, MVT::v8f32, { 2, 1, 1, 1 } },
3430 { ISD::FP_TO_SINT, MVT::v16i16, MVT::v4f64, { 2, 1, 1, 1 } },
3431 { ISD::FP_TO_SINT, MVT::v4i32, MVT::v4f64, { 2, 1, 1, 1 } },
3432 { ISD::FP_TO_SINT, MVT::v8i32, MVT::v8f32, { 2, 1, 1, 1 } },
3433 { ISD::FP_TO_SINT, MVT::v8i32, MVT::v8f64, { 5, 1, 1, 1 } },
3434
3435 { ISD::FP_TO_UINT, MVT::v16i8, MVT::v8f32, { 2, 1, 1, 1 } },
3436 { ISD::FP_TO_UINT, MVT::v16i8, MVT::v4f64, { 2, 1, 1, 1 } },
3437 { ISD::FP_TO_UINT, MVT::v32i8, MVT::v8f32, { 2, 1, 1, 1 } },
3438 { ISD::FP_TO_UINT, MVT::v32i8, MVT::v4f64, { 2, 1, 1, 1 } },
3439 { ISD::FP_TO_UINT, MVT::v8i16, MVT::v8f32, { 2, 1, 1, 1 } },
3440 { ISD::FP_TO_UINT, MVT::v8i16, MVT::v4f64, { 2, 1, 1, 1 } },
3441 { ISD::FP_TO_UINT, MVT::v16i16, MVT::v8f32, { 2, 1, 1, 1 } },
3442 { ISD::FP_TO_UINT, MVT::v16i16, MVT::v4f64, { 2, 1, 1, 1 } },
3443 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f32, { 3, 1, 1, 1 } },
3444 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v2f64, { 4, 1, 1, 1 } },
3445 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f64, { 6, 1, 1, 1 } },
3446 { ISD::FP_TO_UINT, MVT::v8i32, MVT::v8f32, { 7, 1, 1, 1 } },
3447 { ISD::FP_TO_UINT, MVT::v8i32, MVT::v4f64, { 7, 1, 1, 1 } },
3448
3449 { ISD::FP_EXTEND, MVT::v4f64, MVT::v4f32, { 1, 1, 1, 1 } },
3450 { ISD::FP_ROUND, MVT::v4f32, MVT::v4f64, { 1, 1, 1, 1 } },
3451 };
3452
3453 static const TypeConversionCostKindTblEntry SSE41ConversionTbl[] = {
3454 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v16i8, { 1, 1, 1, 1 } },
3455 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v16i8, { 1, 1, 1, 1 } },
3456 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v16i8, { 1, 1, 1, 1 } },
3457 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v16i8, { 1, 1, 1, 1 } },
3458 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v16i8, { 1, 1, 1, 1 } },
3459 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v16i8, { 1, 1, 1, 1 } },
3460 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v8i16, { 1, 1, 1, 1 } },
3461 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v8i16, { 1, 1, 1, 1 } },
3462 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v8i16, { 1, 1, 1, 1 } },
3463 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v8i16, { 1, 1, 1, 1 } },
3464 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v4i32, { 1, 1, 1, 1 } },
3465 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v4i32, { 1, 1, 1, 1 } },
3466
3467 // These truncates end up widening elements.
3468 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i8, { 1, 1, 1, 1 } }, // PMOVXZBQ
3469 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i16, { 1, 1, 1, 1 } }, // PMOVXZWQ
3470 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i8, { 1, 1, 1, 1 } }, // PMOVXZBD
3471
3472 { ISD::TRUNCATE, MVT::v16i8, MVT::v4i32, { 2, 1, 1, 1 } },
3473 { ISD::TRUNCATE, MVT::v8i16, MVT::v4i32, { 2, 1, 1, 1 } },
3474 { ISD::TRUNCATE, MVT::v16i8, MVT::v2i64, { 2, 1, 1, 1 } },
3475
3476 { ISD::SINT_TO_FP, MVT::f32, MVT::i32, { 1, 1, 1, 1 } },
3477 { ISD::SINT_TO_FP, MVT::f64, MVT::i32, { 1, 1, 1, 1 } },
3478 { ISD::SINT_TO_FP, MVT::f32, MVT::i64, { 1, 1, 1, 1 } },
3479 { ISD::SINT_TO_FP, MVT::f64, MVT::i64, { 1, 1, 1, 1 } },
3480 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v16i8, { 1, 1, 1, 1 } },
3481 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v16i8, { 1, 1, 1, 1 } },
3482 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v8i16, { 1, 1, 1, 1 } },
3483 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v8i16, { 1, 1, 1, 1 } },
3484 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v4i32, { 1, 1, 1, 1 } },
3485 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v4i32, { 1, 1, 1, 1 } },
3486 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v4i32, { 2, 1, 1, 1 } },
3487
3488 { ISD::UINT_TO_FP, MVT::f32, MVT::i32, { 1, 1, 1, 1 } },
3489 { ISD::UINT_TO_FP, MVT::f64, MVT::i32, { 1, 1, 1, 1 } },
3490 { ISD::UINT_TO_FP, MVT::f32, MVT::i64, { 4, 1, 1, 1 } },
3491 { ISD::UINT_TO_FP, MVT::f64, MVT::i64, { 4, 1, 1, 1 } },
3492 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v16i8, { 1, 1, 1, 1 } },
3493 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v16i8, { 1, 1, 1, 1 } },
3494 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v8i16, { 1, 1, 1, 1 } },
3495 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v8i16, { 1, 1, 1, 1 } },
3496 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i32, { 3, 1, 1, 1 } },
3497 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i32, { 3, 1, 1, 1 } },
3498 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v4i32, { 2, 1, 1, 1 } },
3499 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v2i64, {12, 1, 1, 1 } },
3500 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i64, {22, 1, 1, 1 } },
3501 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i64, { 4, 1, 1, 1 } },
3502
3503 { ISD::FP_TO_SINT, MVT::i32, MVT::f32, { 1, 1, 1, 1 } },
3504 { ISD::FP_TO_SINT, MVT::i64, MVT::f32, { 1, 1, 1, 1 } },
3505 { ISD::FP_TO_SINT, MVT::i32, MVT::f64, { 1, 1, 1, 1 } },
3506 { ISD::FP_TO_SINT, MVT::i64, MVT::f64, { 1, 1, 1, 1 } },
3507 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v4f32, { 2, 1, 1, 1 } },
3508 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v2f64, { 2, 1, 1, 1 } },
3509 { ISD::FP_TO_SINT, MVT::v8i16, MVT::v4f32, { 1, 1, 1, 1 } },
3510 { ISD::FP_TO_SINT, MVT::v8i16, MVT::v2f64, { 1, 1, 1, 1 } },
3511 { ISD::FP_TO_SINT, MVT::v4i32, MVT::v4f32, { 1, 1, 1, 1 } },
3512 { ISD::FP_TO_SINT, MVT::v4i32, MVT::v2f64, { 1, 1, 1, 1 } },
3513
3514 { ISD::FP_TO_UINT, MVT::i32, MVT::f32, { 1, 1, 1, 1 } },
3515 { ISD::FP_TO_UINT, MVT::i64, MVT::f32, { 4, 1, 1, 1 } },
3516 { ISD::FP_TO_UINT, MVT::i32, MVT::f64, { 1, 1, 1, 1 } },
3517 { ISD::FP_TO_UINT, MVT::i64, MVT::f64, { 4, 1, 1, 1 } },
3518 { ISD::FP_TO_UINT, MVT::v16i8, MVT::v4f32, { 2, 1, 1, 1 } },
3519 { ISD::FP_TO_UINT, MVT::v16i8, MVT::v2f64, { 2, 1, 1, 1 } },
3520 { ISD::FP_TO_UINT, MVT::v8i16, MVT::v4f32, { 1, 1, 1, 1 } },
3521 { ISD::FP_TO_UINT, MVT::v8i16, MVT::v2f64, { 1, 1, 1, 1 } },
3522 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f32, { 4, 1, 1, 1 } },
3523 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v2f64, { 4, 1, 1, 1 } },
3524 };
3525
3526 static const TypeConversionCostKindTblEntry SSE2ConversionTbl[] = {
3527 // These are somewhat magic numbers justified by comparing the
3528 // output of llvm-mca for our various supported scheduler models
3529 // and basing it off the worst case scenario.
3530 { ISD::SINT_TO_FP, MVT::f32, MVT::i32, { 3, 1, 1, 1 } },
3531 { ISD::SINT_TO_FP, MVT::f64, MVT::i32, { 3, 1, 1, 1 } },
3532 { ISD::SINT_TO_FP, MVT::f32, MVT::i64, { 3, 1, 1, 1 } },
3533 { ISD::SINT_TO_FP, MVT::f64, MVT::i64, { 3, 1, 1, 1 } },
3534 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v16i8, { 3, 1, 1, 1 } },
3535 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v16i8, { 4, 1, 1, 1 } },
3536 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v8i16, { 3, 1, 1, 1 } },
3537 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v8i16, { 4, 1, 1, 1 } },
3538 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v4i32, { 3, 1, 1, 1 } },
3539 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v4i32, { 4, 1, 1, 1 } },
3540 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v2i64, { 8, 1, 1, 1 } },
3541 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v2i64, { 8, 1, 1, 1 } },
3542
3543 { ISD::UINT_TO_FP, MVT::f32, MVT::i32, { 3, 1, 1, 1 } },
3544 { ISD::UINT_TO_FP, MVT::f64, MVT::i32, { 3, 1, 1, 1 } },
3545 { ISD::UINT_TO_FP, MVT::f32, MVT::i64, { 8, 1, 1, 1 } },
3546 { ISD::UINT_TO_FP, MVT::f64, MVT::i64, { 9, 1, 1, 1 } },
3547 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v16i8, { 4, 1, 1, 1 } },
3548 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v16i8, { 4, 1, 1, 1 } },
3549 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v8i16, { 4, 1, 1, 1 } },
3550 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v8i16, { 4, 1, 1, 1 } },
3551 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i32, { 7, 1, 1, 1 } },
3552 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v4i32, { 7, 1, 1, 1 } },
3553 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i32, { 5, 1, 1, 1 } },
3554 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i64, {15, 1, 1, 1 } },
3555 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v2i64, {18, 1, 1, 1 } },
3556
3557 { ISD::FP_TO_SINT, MVT::i32, MVT::f32, { 4, 1, 1, 1 } },
3558 { ISD::FP_TO_SINT, MVT::i64, MVT::f32, { 4, 1, 1, 1 } },
3559 { ISD::FP_TO_SINT, MVT::i32, MVT::f64, { 4, 1, 1, 1 } },
3560 { ISD::FP_TO_SINT, MVT::i64, MVT::f64, { 4, 1, 1, 1 } },
3561 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v4f32, { 6, 1, 1, 1 } },
3562 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v2f64, { 6, 1, 1, 1 } },
3563 { ISD::FP_TO_SINT, MVT::v8i16, MVT::v4f32, { 5, 1, 1, 1 } },
3564 { ISD::FP_TO_SINT, MVT::v8i16, MVT::v2f64, { 5, 1, 1, 1 } },
3565 { ISD::FP_TO_SINT, MVT::v4i32, MVT::v4f32, { 4, 1, 1, 1 } },
3566 { ISD::FP_TO_SINT, MVT::v4i32, MVT::v2f64, { 4, 1, 1, 1 } },
3567
3568 { ISD::FP_TO_UINT, MVT::i32, MVT::f32, { 4, 1, 1, 1 } },
3569 { ISD::FP_TO_UINT, MVT::i64, MVT::f32, { 4, 1, 1, 1 } },
3570 { ISD::FP_TO_UINT, MVT::i32, MVT::f64, { 4, 1, 1, 1 } },
3571 { ISD::FP_TO_UINT, MVT::i64, MVT::f64, {15, 1, 1, 1 } },
3572 { ISD::FP_TO_UINT, MVT::v16i8, MVT::v4f32, { 6, 1, 1, 1 } },
3573 { ISD::FP_TO_UINT, MVT::v16i8, MVT::v2f64, { 6, 1, 1, 1 } },
3574 { ISD::FP_TO_UINT, MVT::v8i16, MVT::v4f32, { 5, 1, 1, 1 } },
3575 { ISD::FP_TO_UINT, MVT::v8i16, MVT::v2f64, { 5, 1, 1, 1 } },
3576 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f32, { 8, 1, 1, 1 } },
3577 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v2f64, { 8, 1, 1, 1 } },
3578
3579 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v16i8, { 4, 1, 1, 1 } },
3580 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v16i8, { 4, 1, 1, 1 } },
3581 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v16i8, { 2, 1, 1, 1 } },
3582 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v16i8, { 3, 1, 1, 1 } },
3583 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v16i8, { 1, 1, 1, 1 } },
3584 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v16i8, { 2, 1, 1, 1 } },
3585 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v8i16, { 2, 1, 1, 1 } },
3586 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v8i16, { 3, 1, 1, 1 } },
3587 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v8i16, { 1, 1, 1, 1 } },
3588 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v8i16, { 2, 1, 1, 1 } },
3589 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v4i32, { 1, 1, 1, 1 } },
3590 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v4i32, { 2, 1, 1, 1 } },
3591
3592 // These truncates are really widening elements.
3593 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i32, { 1, 1, 1, 1 } }, // PSHUFD
3594 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i16, { 2, 1, 1, 1 } }, // PUNPCKLWD+DQ
3595 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i8, { 3, 1, 1, 1 } }, // PUNPCKLBW+WD+PSHUFD
3596 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i16, { 1, 1, 1, 1 } }, // PUNPCKLWD
3597 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i8, { 2, 1, 1, 1 } }, // PUNPCKLBW+WD
3598 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i8, { 1, 1, 1, 1 } }, // PUNPCKLBW
3599
3600 { ISD::TRUNCATE, MVT::v16i8, MVT::v8i16, { 2, 1, 1, 1 } }, // PAND+PACKUSWB
3601 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i16, { 3, 1, 1, 1 } },
3602 { ISD::TRUNCATE, MVT::v16i8, MVT::v4i32, { 3, 1, 1, 1 } }, // PAND+2*PACKUSWB
3603 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i32, { 7, 1, 1, 1 } },
3604 { ISD::TRUNCATE, MVT::v2i16, MVT::v2i32, { 1, 1, 1, 1 } },
3605 { ISD::TRUNCATE, MVT::v8i16, MVT::v4i32, { 3, 1, 1, 1 } },
3606 { ISD::TRUNCATE, MVT::v8i16, MVT::v8i32, { 5, 1, 1, 1 } },
3607 { ISD::TRUNCATE, MVT::v16i16, MVT::v16i32, {10, 1, 1, 1 } },
3608 { ISD::TRUNCATE, MVT::v16i8, MVT::v2i64, { 4, 1, 1, 1 } }, // PAND+3*PACKUSWB
3609 { ISD::TRUNCATE, MVT::v8i16, MVT::v2i64, { 2, 1, 1, 1 } }, // PSHUFD+PSHUFLW
3610 { ISD::TRUNCATE, MVT::v4i32, MVT::v2i64, { 1, 1, 1, 1 } }, // PSHUFD
3611 };
3612
3613 static const TypeConversionCostKindTblEntry F16ConversionTbl[] = {
3614 { ISD::FP_ROUND, MVT::f16, MVT::f32, { 1, 1, 1, 1 } },
3615 { ISD::FP_ROUND, MVT::v8f16, MVT::v8f32, { 1, 1, 1, 1 } },
3616 { ISD::FP_ROUND, MVT::v4f16, MVT::v4f32, { 1, 1, 1, 1 } },
3617 { ISD::FP_EXTEND, MVT::f32, MVT::f16, { 1, 1, 1, 1 } },
3618 { ISD::FP_EXTEND, MVT::f64, MVT::f16, { 2, 1, 1, 1 } }, // vcvtph2ps+vcvtps2pd
3619 { ISD::FP_EXTEND, MVT::v8f32, MVT::v8f16, { 1, 1, 1, 1 } },
3620 { ISD::FP_EXTEND, MVT::v4f32, MVT::v4f16, { 1, 1, 1, 1 } },
3621 { ISD::FP_EXTEND, MVT::v4f64, MVT::v4f16, { 2, 1, 1, 1 } }, // vcvtph2ps+vcvtps2pd
3622 };
3623
3624 // Attempt to map directly to (simple) MVT types to let us match custom entries.
3625 EVT SrcTy = TLI->getValueType(DL, Src);
3626 EVT DstTy = TLI->getValueType(DL, Dst);
3627
3628 // If we're sign-extending a vector comparison result back to the comparison
3629 // width, this will be free without AVX512 (or for 8/16-bit types without
3630 // BWI).
3631 if (!ST->hasAVX512() || (!ST->hasBWI() && DstTy.getScalarSizeInBits() < 32)) {
3632 if (I && Opcode == Instruction::CastOps::SExt &&
3633 SrcTy.isFixedLengthVectorOf(MVT::i1)) {
3634 if (auto *CmpI = dyn_cast<CmpInst>(I->getOperand(0))) {
3635 Type *CmpTy = CmpI->getOperand(0)->getType();
3636 if (CmpTy->getScalarSizeInBits() == DstTy.getScalarSizeInBits())
3637 return TTI::TCC_Free;
3638 }
3639 }
3640 }
3641
3642 // The function getSimpleVT only handles simple value types.
3643 if (SrcTy.isSimple() && DstTy.isSimple()) {
3644 MVT SimpleSrcTy = SrcTy.getSimpleVT();
3645 MVT SimpleDstTy = DstTy.getSimpleVT();
3646
3647 if (ST->useAVX512Regs()) {
3648 if (ST->hasBWI())
3649 if (const auto *Entry = ConvertCostTableLookup(
3650 AVX512BWConversionTbl, ISD, SimpleDstTy, SimpleSrcTy))
3651 if (auto KindCost = Entry->Cost[CostKind])
3652 return *KindCost;
3653
3654 if (ST->hasDQI())
3655 if (const auto *Entry = ConvertCostTableLookup(
3656 AVX512DQConversionTbl, ISD, SimpleDstTy, SimpleSrcTy))
3657 if (auto KindCost = Entry->Cost[CostKind])
3658 return *KindCost;
3659
3660 if (ST->hasAVX512())
3661 if (const auto *Entry = ConvertCostTableLookup(
3662 AVX512FConversionTbl, ISD, SimpleDstTy, SimpleSrcTy))
3663 if (auto KindCost = Entry->Cost[CostKind])
3664 return *KindCost;
3665 }
3666
3667 if (ST->hasBWI())
3668 if (const auto *Entry = ConvertCostTableLookup(
3669 AVX512BWVLConversionTbl, ISD, SimpleDstTy, SimpleSrcTy))
3670 if (auto KindCost = Entry->Cost[CostKind])
3671 return *KindCost;
3672
3673 if (ST->hasDQI())
3674 if (const auto *Entry = ConvertCostTableLookup(
3675 AVX512DQVLConversionTbl, ISD, SimpleDstTy, SimpleSrcTy))
3676 if (auto KindCost = Entry->Cost[CostKind])
3677 return *KindCost;
3678
3679 if (ST->hasAVX512())
3680 if (const auto *Entry = ConvertCostTableLookup(AVX512VLConversionTbl, ISD,
3681 SimpleDstTy, SimpleSrcTy))
3682 if (auto KindCost = Entry->Cost[CostKind])
3683 return *KindCost;
3684
3685 if (ST->hasAVX2()) {
3686 if (const auto *Entry = ConvertCostTableLookup(AVX2ConversionTbl, ISD,
3687 SimpleDstTy, SimpleSrcTy))
3688 if (auto KindCost = Entry->Cost[CostKind])
3689 return *KindCost;
3690 }
3691
3692 if (ST->hasAVX()) {
3693 if (const auto *Entry = ConvertCostTableLookup(AVXConversionTbl, ISD,
3694 SimpleDstTy, SimpleSrcTy))
3695 if (auto KindCost = Entry->Cost[CostKind])
3696 return *KindCost;
3697 }
3698
3699 if (ST->hasF16C()) {
3700 if (const auto *Entry = ConvertCostTableLookup(F16ConversionTbl, ISD,
3701 SimpleDstTy, SimpleSrcTy))
3702 if (auto KindCost = Entry->Cost[CostKind])
3703 return *KindCost;
3704 }
3705
3706 if (ST->hasSSE41()) {
3707 if (const auto *Entry = ConvertCostTableLookup(SSE41ConversionTbl, ISD,
3708 SimpleDstTy, SimpleSrcTy))
3709 if (auto KindCost = Entry->Cost[CostKind])
3710 return *KindCost;
3711 }
3712
3713 if (ST->hasSSE2()) {
3714 if (const auto *Entry = ConvertCostTableLookup(SSE2ConversionTbl, ISD,
3715 SimpleDstTy, SimpleSrcTy))
3716 if (auto KindCost = Entry->Cost[CostKind])
3717 return *KindCost;
3718 }
3719
3720 if ((ISD == ISD::FP_ROUND && SimpleDstTy == MVT::f16) ||
3721 (ISD == ISD::FP_EXTEND && SimpleSrcTy == MVT::f16)) {
3722 // fp16 conversions not covered by any table entries require a libcall.
3723 // Return a large (arbitrary) number to model this.
3724 return InstructionCost(64);
3725 }
3726 }
3727
3728 // Fall back to legalized types.
3729 std::pair<InstructionCost, MVT> LTSrc = getTypeLegalizationCost(Src);
3730 std::pair<InstructionCost, MVT> LTDest = getTypeLegalizationCost(Dst);
3731
3732 // If we're truncating to the same legalized type - just assume its free.
3733 if (ISD == ISD::TRUNCATE && LTSrc.second == LTDest.second)
3734 return TTI::TCC_Free;
3735
3736 if (ST->useAVX512Regs()) {
3737 if (ST->hasBWI())
3738 if (const auto *Entry = ConvertCostTableLookup(
3739 AVX512BWConversionTbl, ISD, LTDest.second, LTSrc.second))
3740 if (auto KindCost = Entry->Cost[CostKind])
3741 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3742
3743 if (ST->hasDQI())
3744 if (const auto *Entry = ConvertCostTableLookup(
3745 AVX512DQConversionTbl, ISD, LTDest.second, LTSrc.second))
3746 if (auto KindCost = Entry->Cost[CostKind])
3747 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3748
3749 if (ST->hasAVX512())
3750 if (const auto *Entry = ConvertCostTableLookup(
3751 AVX512FConversionTbl, ISD, LTDest.second, LTSrc.second))
3752 if (auto KindCost = Entry->Cost[CostKind])
3753 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3754 }
3755
3756 if (ST->hasBWI())
3757 if (const auto *Entry = ConvertCostTableLookup(AVX512BWVLConversionTbl, ISD,
3758 LTDest.second, LTSrc.second))
3759 if (auto KindCost = Entry->Cost[CostKind])
3760 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3761
3762 if (ST->hasDQI())
3763 if (const auto *Entry = ConvertCostTableLookup(AVX512DQVLConversionTbl, ISD,
3764 LTDest.second, LTSrc.second))
3765 if (auto KindCost = Entry->Cost[CostKind])
3766 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3767
3768 if (ST->hasAVX512())
3769 if (const auto *Entry = ConvertCostTableLookup(AVX512VLConversionTbl, ISD,
3770 LTDest.second, LTSrc.second))
3771 if (auto KindCost = Entry->Cost[CostKind])
3772 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3773
3774 if (ST->hasAVX2())
3775 if (const auto *Entry = ConvertCostTableLookup(AVX2ConversionTbl, ISD,
3776 LTDest.second, LTSrc.second))
3777 if (auto KindCost = Entry->Cost[CostKind])
3778 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3779
3780 if (ST->hasAVX())
3781 if (const auto *Entry = ConvertCostTableLookup(AVXConversionTbl, ISD,
3782 LTDest.second, LTSrc.second))
3783 if (auto KindCost = Entry->Cost[CostKind])
3784 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3785
3786 if (ST->hasF16C()) {
3787 if (const auto *Entry = ConvertCostTableLookup(F16ConversionTbl, ISD,
3788 LTDest.second, LTSrc.second))
3789 if (auto KindCost = Entry->Cost[CostKind])
3790 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3791 }
3792
3793 if (ST->hasSSE41())
3794 if (const auto *Entry = ConvertCostTableLookup(SSE41ConversionTbl, ISD,
3795 LTDest.second, LTSrc.second))
3796 if (auto KindCost = Entry->Cost[CostKind])
3797 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3798
3799 if (ST->hasSSE2())
3800 if (const auto *Entry = ConvertCostTableLookup(SSE2ConversionTbl, ISD,
3801 LTDest.second, LTSrc.second))
3802 if (auto KindCost = Entry->Cost[CostKind])
3803 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3804
3805 // Fallback, for i8/i16 sitofp/uitofp cases we need to extend to i32 for
3806 // sitofp.
3807 if ((ISD == ISD::SINT_TO_FP || ISD == ISD::UINT_TO_FP) &&
3808 1 < Src->getScalarSizeInBits() && Src->getScalarSizeInBits() < 32) {
3809 Type *ExtSrc = Src->getWithNewBitWidth(32);
3810 unsigned ExtOpc =
3811 (ISD == ISD::SINT_TO_FP) ? Instruction::SExt : Instruction::ZExt;
3812
3813 // For scalar loads the extend would be free.
3814 InstructionCost ExtCost = 0;
3815 if (!(Src->isIntegerTy() && I && isa<LoadInst>(I->getOperand(0))))
3816 ExtCost = getCastInstrCost(ExtOpc, ExtSrc, Src, CCH, CostKind);
3817
3818 return ExtCost + getCastInstrCost(Instruction::SIToFP, Dst, ExtSrc,
3820 }
3821
3822 // Fallback for fptosi/fptoui i8/i16 cases we need to truncate from fptosi
3823 // i32.
3824 if ((ISD == ISD::FP_TO_SINT || ISD == ISD::FP_TO_UINT) &&
3825 1 < Dst->getScalarSizeInBits() && Dst->getScalarSizeInBits() < 32) {
3826 Type *TruncDst = Dst->getWithNewBitWidth(32);
3827 return getCastInstrCost(Instruction::FPToSI, TruncDst, Src, CCH, CostKind) +
3828 getCastInstrCost(Instruction::Trunc, Dst, TruncDst,
3830 }
3831
3832 // TODO: Allow non-throughput costs that aren't binary.
3833 auto AdjustCost = [&CostKind](InstructionCost Cost,
3836 return Cost == 0 ? 0 : N;
3837 return Cost * N;
3838 };
3839 return AdjustCost(
3840 BaseT::getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I));
3841}
3842
3844 unsigned Opcode, Type *ValTy, Type *CondTy, CmpInst::Predicate VecPred,
3846 TTI::OperandValueInfo Op2Info, const Instruction *I) const {
3847 // Early out if this type isn't scalar/vector integer/float.
3848 if (!(ValTy->isIntOrIntVectorTy() || ValTy->isFPOrFPVectorTy()))
3849 return BaseT::getCmpSelInstrCost(Opcode, ValTy, CondTy, VecPred, CostKind,
3850 Op1Info, Op2Info, I);
3851
3852 // Legalize the type.
3853 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(ValTy);
3854
3855 MVT MTy = LT.second;
3856
3857 int ISD = TLI->InstructionOpcodeToISD(Opcode);
3858 assert(ISD && "Invalid opcode");
3859
3860 InstructionCost ExtraCost = 0;
3861 if (Opcode == Instruction::ICmp || Opcode == Instruction::FCmp) {
3862 // Some vector comparison predicates cost extra instructions.
3863 // TODO: Adjust ExtraCost based on CostKind?
3864 // TODO: Should we invert this and assume worst case cmp costs
3865 // and reduce for particular predicates?
3866 if (MTy.isVector() &&
3867 !((ST->hasXOP() && (!ST->hasAVX2() || MTy.is128BitVector())) ||
3868 (ST->hasAVX512() && 32 <= MTy.getScalarSizeInBits()) ||
3869 ST->hasBWI())) {
3870 // Fallback to I if a specific predicate wasn't specified.
3871 CmpInst::Predicate Pred = VecPred;
3872 if (I && (Pred == CmpInst::BAD_ICMP_PREDICATE ||
3874 Pred = cast<CmpInst>(I)->getPredicate();
3875
3876 bool CmpWithConstant = false;
3877 if (auto *CmpInstr = dyn_cast_or_null<CmpInst>(I))
3878 CmpWithConstant = isa<Constant>(CmpInstr->getOperand(1));
3879
3880 switch (Pred) {
3882 // xor(cmpeq(x,y),-1)
3883 ExtraCost = CmpWithConstant ? 0 : 1;
3884 break;
3887 // xor(cmpgt(x,y),-1)
3888 ExtraCost = CmpWithConstant ? 0 : 1;
3889 break;
3892 // cmpgt(xor(x,signbit),xor(y,signbit))
3893 // xor(cmpeq(pmaxu(x,y),x),-1)
3894 ExtraCost = CmpWithConstant ? 1 : 2;
3895 break;
3898 if ((ST->hasSSE41() && MTy.getScalarSizeInBits() == 32) ||
3899 (ST->hasSSE2() && MTy.getScalarSizeInBits() < 32)) {
3900 // cmpeq(psubus(x,y),0)
3901 // cmpeq(pminu(x,y),x)
3902 ExtraCost = 1;
3903 } else {
3904 // xor(cmpgt(xor(x,signbit),xor(y,signbit)),-1)
3905 ExtraCost = CmpWithConstant ? 2 : 3;
3906 }
3907 break;
3910 // Without AVX we need to expand FCMP_ONE/FCMP_UEQ cases.
3911 // Use FCMP_UEQ expansion - FCMP_ONE should be the same.
3912 if (CondTy && !ST->hasAVX())
3913 return getCmpSelInstrCost(Opcode, ValTy, CondTy,
3915 Op1Info, Op2Info) +
3916 getCmpSelInstrCost(Opcode, ValTy, CondTy,
3918 Op1Info, Op2Info) +
3919 getArithmeticInstrCost(Instruction::Or, CondTy, CostKind);
3920
3921 break;
3924 // Assume worst case scenario and add the maximum extra cost.
3925 ExtraCost = 3;
3926 break;
3927 default:
3928 break;
3929 }
3930 }
3931 }
3932
3933 static const CostKindTblEntry SLMCostTbl[] = {
3934 // slm pcmpeq/pcmpgt throughput is 2
3935 { ISD::SETCC, MVT::v2i64, { 2, 5, 1, 2 } },
3936 // slm pblendvb/blendvpd/blendvps throughput is 4
3937 { ISD::SELECT, MVT::v2f64, { 4, 4, 1, 3 } }, // vblendvpd
3938 { ISD::SELECT, MVT::v4f32, { 4, 4, 1, 3 } }, // vblendvps
3939 { ISD::SELECT, MVT::v2i64, { 4, 4, 1, 3 } }, // pblendvb
3940 { ISD::SELECT, MVT::v8i32, { 4, 4, 1, 3 } }, // pblendvb
3941 { ISD::SELECT, MVT::v8i16, { 4, 4, 1, 3 } }, // pblendvb
3942 { ISD::SELECT, MVT::v16i8, { 4, 4, 1, 3 } }, // pblendvb
3943 };
3944
3945 static const CostKindTblEntry AVX512BWCostTbl[] = {
3946 { ISD::SETCC, MVT::v32i16, { 1, 1, 1, 1 } },
3947 { ISD::SETCC, MVT::v16i16, { 1, 1, 1, 1 } },
3948 { ISD::SETCC, MVT::v64i8, { 1, 1, 1, 1 } },
3949 { ISD::SETCC, MVT::v32i8, { 1, 1, 1, 1 } },
3950
3951 { ISD::SELECT, MVT::v32i16, { 1, 1, 1, 1 } },
3952 { ISD::SELECT, MVT::v64i8, { 1, 1, 1, 1 } },
3953 };
3954
3955 static const CostKindTblEntry AVX512CostTbl[] = {
3956 { ISD::SETCC, MVT::v8f64, { 1, 4, 1, 1 } },
3957 { ISD::SETCC, MVT::v4f64, { 1, 4, 1, 1 } },
3958 { ISD::SETCC, MVT::v16f32, { 1, 4, 1, 1 } },
3959 { ISD::SETCC, MVT::v8f32, { 1, 4, 1, 1 } },
3960
3961 { ISD::SETCC, MVT::v8i64, { 1, 1, 1, 1 } },
3962 { ISD::SETCC, MVT::v4i64, { 1, 1, 1, 1 } },
3963 { ISD::SETCC, MVT::v2i64, { 1, 1, 1, 1 } },
3964 { ISD::SETCC, MVT::v16i32, { 1, 1, 1, 1 } },
3965 { ISD::SETCC, MVT::v8i32, { 1, 1, 1, 1 } },
3966 { ISD::SETCC, MVT::v32i16, { 3, 7, 5, 5 } },
3967 { ISD::SETCC, MVT::v64i8, { 3, 7, 5, 5 } },
3968
3969 { ISD::SELECT, MVT::v8i64, { 1, 1, 1, 1 } },
3970 { ISD::SELECT, MVT::v4i64, { 1, 1, 1, 1 } },
3971 { ISD::SELECT, MVT::v2i64, { 1, 1, 1, 1 } },
3972 { ISD::SELECT, MVT::v16i32, { 1, 1, 1, 1 } },
3973 { ISD::SELECT, MVT::v8i32, { 1, 1, 1, 1 } },
3974 { ISD::SELECT, MVT::v4i32, { 1, 1, 1, 1 } },
3975 { ISD::SELECT, MVT::v8f64, { 1, 1, 1, 1 } },
3976 { ISD::SELECT, MVT::v4f64, { 1, 1, 1, 1 } },
3977 { ISD::SELECT, MVT::v2f64, { 1, 1, 1, 1 } },
3978 { ISD::SELECT, MVT::f64, { 1, 1, 1, 1 } },
3979 { ISD::SELECT, MVT::v16f32, { 1, 1, 1, 1 } },
3980 { ISD::SELECT, MVT::v8f32 , { 1, 1, 1, 1 } },
3981 { ISD::SELECT, MVT::v4f32, { 1, 1, 1, 1 } },
3982 { ISD::SELECT, MVT::f32 , { 1, 1, 1, 1 } },
3983
3984 { ISD::SELECT, MVT::v32i16, { 2, 2, 4, 4 } },
3985 { ISD::SELECT, MVT::v16i16, { 1, 1, 1, 1 } },
3986 { ISD::SELECT, MVT::v8i16, { 1, 1, 1, 1 } },
3987 { ISD::SELECT, MVT::v64i8, { 2, 2, 4, 4 } },
3988 { ISD::SELECT, MVT::v32i8, { 1, 1, 1, 1 } },
3989 { ISD::SELECT, MVT::v16i8, { 1, 1, 1, 1 } },
3990 };
3991
3992 static const CostKindTblEntry AVX2CostTbl[] = {
3993 { ISD::SETCC, MVT::v4f64, { 1, 4, 1, 2 } },
3994 { ISD::SETCC, MVT::v2f64, { 1, 4, 1, 1 } },
3995 { ISD::SETCC, MVT::f64, { 1, 4, 1, 1 } },
3996 { ISD::SETCC, MVT::v8f32, { 1, 4, 1, 2 } },
3997 { ISD::SETCC, MVT::v4f32, { 1, 4, 1, 1 } },
3998 { ISD::SETCC, MVT::f32, { 1, 4, 1, 1 } },
3999
4000 { ISD::SETCC, MVT::v4i64, { 1, 1, 1, 2 } },
4001 { ISD::SETCC, MVT::v8i32, { 1, 1, 1, 2 } },
4002 { ISD::SETCC, MVT::v16i16, { 1, 1, 1, 2 } },
4003 { ISD::SETCC, MVT::v32i8, { 1, 1, 1, 2 } },
4004
4005 { ISD::SELECT, MVT::v4f64, { 2, 2, 1, 2 } }, // vblendvpd
4006 { ISD::SELECT, MVT::v8f32, { 2, 2, 1, 2 } }, // vblendvps
4007 { ISD::SELECT, MVT::v4i64, { 2, 2, 1, 2 } }, // pblendvb
4008 { ISD::SELECT, MVT::v8i32, { 2, 2, 1, 2 } }, // pblendvb
4009 { ISD::SELECT, MVT::v16i16, { 2, 2, 1, 2 } }, // pblendvb
4010 { ISD::SELECT, MVT::v32i8, { 2, 2, 1, 2 } }, // pblendvb
4011 };
4012
4013 static const CostKindTblEntry XOPCostTbl[] = {
4014 { ISD::SETCC, MVT::v4i64, { 4, 2, 5, 6 } },
4015 { ISD::SETCC, MVT::v2i64, { 1, 1, 1, 1 } },
4016 };
4017
4018 static const CostKindTblEntry AVX1CostTbl[] = {
4019 { ISD::SETCC, MVT::v4f64, { 2, 3, 1, 2 } },
4020 { ISD::SETCC, MVT::v2f64, { 1, 3, 1, 1 } },
4021 { ISD::SETCC, MVT::f64, { 1, 3, 1, 1 } },
4022 { ISD::SETCC, MVT::v8f32, { 2, 3, 1, 2 } },
4023 { ISD::SETCC, MVT::v4f32, { 1, 3, 1, 1 } },
4024 { ISD::SETCC, MVT::f32, { 1, 3, 1, 1 } },
4025
4026 // AVX1 does not support 8-wide integer compare.
4027 { ISD::SETCC, MVT::v4i64, { 4, 2, 5, 6 } },
4028 { ISD::SETCC, MVT::v8i32, { 4, 2, 5, 6 } },
4029 { ISD::SETCC, MVT::v16i16, { 4, 2, 5, 6 } },
4030 { ISD::SETCC, MVT::v32i8, { 4, 2, 5, 6 } },
4031
4032 { ISD::SELECT, MVT::v4f64, { 3, 3, 1, 2 } }, // vblendvpd
4033 { ISD::SELECT, MVT::v8f32, { 3, 3, 1, 2 } }, // vblendvps
4034 { ISD::SELECT, MVT::v4i64, { 3, 3, 1, 2 } }, // vblendvpd
4035 { ISD::SELECT, MVT::v8i32, { 3, 3, 1, 2 } }, // vblendvps
4036 { ISD::SELECT, MVT::v16i16, { 3, 3, 3, 3 } }, // vandps + vandnps + vorps
4037 { ISD::SELECT, MVT::v32i8, { 3, 3, 3, 3 } }, // vandps + vandnps + vorps
4038 };
4039
4040 static const CostKindTblEntry SSE42CostTbl[] = {
4041 { ISD::SETCC, MVT::v2i64, { 1, 2, 1, 2 } },
4042 };
4043
4044 static const CostKindTblEntry SSE41CostTbl[] = {
4045 { ISD::SETCC, MVT::v2f64, { 1, 5, 1, 1 } },
4046 { ISD::SETCC, MVT::v4f32, { 1, 5, 1, 1 } },
4047
4048 { ISD::SELECT, MVT::v2f64, { 2, 2, 1, 2 } }, // blendvpd
4049 { ISD::SELECT, MVT::f64, { 2, 2, 1, 2 } }, // blendvpd
4050 { ISD::SELECT, MVT::v4f32, { 2, 2, 1, 2 } }, // blendvps
4051 { ISD::SELECT, MVT::f32 , { 2, 2, 1, 2 } }, // blendvps
4052 { ISD::SELECT, MVT::v2i64, { 2, 2, 1, 2 } }, // pblendvb
4053 { ISD::SELECT, MVT::v4i32, { 2, 2, 1, 2 } }, // pblendvb
4054 { ISD::SELECT, MVT::v8i16, { 2, 2, 1, 2 } }, // pblendvb
4055 { ISD::SELECT, MVT::v16i8, { 2, 2, 1, 2 } }, // pblendvb
4056 };
4057
4058 static const CostKindTblEntry SSE2CostTbl[] = {
4059 { ISD::SETCC, MVT::v2f64, { 2, 5, 1, 1 } },
4060 { ISD::SETCC, MVT::f64, { 1, 5, 1, 1 } },
4061
4062 { ISD::SETCC, MVT::v2i64, { 5, 4, 5, 5 } }, // pcmpeqd/pcmpgtd expansion
4063 { ISD::SETCC, MVT::v4i32, { 1, 1, 1, 1 } },
4064 { ISD::SETCC, MVT::v8i16, { 1, 1, 1, 1 } },
4065 { ISD::SETCC, MVT::v16i8, { 1, 1, 1, 1 } },
4066
4067 { ISD::SELECT, MVT::v2f64, { 2, 2, 3, 3 } }, // andpd + andnpd + orpd
4068 { ISD::SELECT, MVT::f64, { 2, 2, 3, 3 } }, // andpd + andnpd + orpd
4069 { ISD::SELECT, MVT::v2i64, { 2, 2, 3, 3 } }, // pand + pandn + por
4070 { ISD::SELECT, MVT::v4i32, { 2, 2, 3, 3 } }, // pand + pandn + por
4071 { ISD::SELECT, MVT::v8i16, { 2, 2, 3, 3 } }, // pand + pandn + por
4072 { ISD::SELECT, MVT::v16i8, { 2, 2, 3, 3 } }, // pand + pandn + por
4073 };
4074
4075 static const CostKindTblEntry SSE1CostTbl[] = {
4076 { ISD::SETCC, MVT::v4f32, { 2, 5, 1, 1 } },
4077 { ISD::SETCC, MVT::f32, { 1, 5, 1, 1 } },
4078
4079 { ISD::SELECT, MVT::v4f32, { 2, 2, 3, 3 } }, // andps + andnps + orps
4080 { ISD::SELECT, MVT::f32, { 2, 2, 3, 3 } }, // andps + andnps + orps
4081 };
4082
4083 if (ST->useSLMArithCosts())
4084 if (const auto *Entry = CostTableLookup(SLMCostTbl, ISD, MTy))
4085 if (auto KindCost = Entry->Cost[CostKind])
4086 return LT.first * (ExtraCost + *KindCost);
4087
4088 if (ST->hasBWI())
4089 if (const auto *Entry = CostTableLookup(AVX512BWCostTbl, ISD, MTy))
4090 if (auto KindCost = Entry->Cost[CostKind])
4091 return LT.first * (ExtraCost + *KindCost);
4092
4093 if (ST->hasAVX512())
4094 if (const auto *Entry = CostTableLookup(AVX512CostTbl, ISD, MTy))
4095 if (auto KindCost = Entry->Cost[CostKind])
4096 return LT.first * (ExtraCost + *KindCost);
4097
4098 if (ST->hasAVX2())
4099 if (const auto *Entry = CostTableLookup(AVX2CostTbl, ISD, MTy))
4100 if (auto KindCost = Entry->Cost[CostKind])
4101 return LT.first * (ExtraCost + *KindCost);
4102
4103 if (ST->hasXOP())
4104 if (const auto *Entry = CostTableLookup(XOPCostTbl, ISD, MTy))
4105 if (auto KindCost = Entry->Cost[CostKind])
4106 return LT.first * (ExtraCost + *KindCost);
4107
4108 if (ST->hasAVX())
4109 if (const auto *Entry = CostTableLookup(AVX1CostTbl, ISD, MTy))
4110 if (auto KindCost = Entry->Cost[CostKind])
4111 return LT.first * (ExtraCost + *KindCost);
4112
4113 if (ST->hasSSE42())
4114 if (const auto *Entry = CostTableLookup(SSE42CostTbl, ISD, MTy))
4115 if (auto KindCost = Entry->Cost[CostKind])
4116 return LT.first * (ExtraCost + *KindCost);
4117
4118 if (ST->hasSSE41())
4119 if (const auto *Entry = CostTableLookup(SSE41CostTbl, ISD, MTy))
4120 if (auto KindCost = Entry->Cost[CostKind])
4121 return LT.first * (ExtraCost + *KindCost);
4122
4123 if (ST->hasSSE2())
4124 if (const auto *Entry = CostTableLookup(SSE2CostTbl, ISD, MTy))
4125 if (auto KindCost = Entry->Cost[CostKind])
4126 return LT.first * (ExtraCost + *KindCost);
4127
4128 if (ST->hasSSE1())
4129 if (const auto *Entry = CostTableLookup(SSE1CostTbl, ISD, MTy))
4130 if (auto KindCost = Entry->Cost[CostKind])
4131 return LT.first * (ExtraCost + *KindCost);
4132
4133 // Assume a 3cy latency for fp select ops.
4134 if (CostKind == TTI::TCK_Latency && Opcode == Instruction::Select)
4135 if (ValTy->getScalarType()->isFloatingPointTy())
4136 return 3;
4137
4138 return BaseT::getCmpSelInstrCost(Opcode, ValTy, CondTy, VecPred, CostKind,
4139 Op1Info, Op2Info, I);
4140}
4141
4143
4147 // Costs should match the codegen from:
4148 // BITREVERSE: llvm\test\CodeGen\X86\vector-bitreverse.ll
4149 // BSWAP: llvm\test\CodeGen\X86\bswap-vector.ll
4150 // CTLZ: llvm\test\CodeGen\X86\vector-lzcnt-*.ll
4151 // CTPOP: llvm\test\CodeGen\X86\vector-popcnt-*.ll
4152 // CTTZ: llvm\test\CodeGen\X86\vector-tzcnt-*.ll
4153
4154 // TODO: Overflow intrinsics (*ADDO, *SUBO, *MULO) with vector types are not
4155 // specialized in these tables yet.
4156 static const CostKindTblEntry AVX512VBMI2CostTbl[] = {
4157 { ISD::FSHL, MVT::v8i64, { 1, 1, 1, 1 } },
4158 { ISD::FSHL, MVT::v4i64, { 1, 1, 1, 1 } },
4159 { ISD::FSHL, MVT::v2i64, { 1, 1, 1, 1 } },
4160 { ISD::FSHL, MVT::v16i32, { 1, 1, 1, 1 } },
4161 { ISD::FSHL, MVT::v8i32, { 1, 1, 1, 1 } },
4162 { ISD::FSHL, MVT::v4i32, { 1, 1, 1, 1 } },
4163 { ISD::FSHL, MVT::v32i16, { 1, 1, 1, 1 } },
4164 { ISD::FSHL, MVT::v16i16, { 1, 1, 1, 1 } },
4165 { ISD::FSHL, MVT::v8i16, { 1, 1, 1, 1 } },
4166 { ISD::ROTL, MVT::v32i16, { 1, 1, 1, 1 } },
4167 { ISD::ROTL, MVT::v16i16, { 1, 1, 1, 1 } },
4168 { ISD::ROTL, MVT::v8i16, { 1, 1, 1, 1 } },
4169 { ISD::ROTR, MVT::v32i16, { 1, 1, 1, 1 } },
4170 { ISD::ROTR, MVT::v16i16, { 1, 1, 1, 1 } },
4171 { ISD::ROTR, MVT::v8i16, { 1, 1, 1, 1 } },
4172 { X86ISD::VROTLI, MVT::v32i16, { 1, 1, 1, 1 } },
4173 { X86ISD::VROTLI, MVT::v16i16, { 1, 1, 1, 1 } },
4174 { X86ISD::VROTLI, MVT::v8i16, { 1, 1, 1, 1 } },
4175 };
4176 static const CostKindTblEntry AVX512BITALGCostTbl[] = {
4177 { ISD::CTPOP, MVT::v32i16, { 1, 1, 1, 1 } },
4178 { ISD::CTPOP, MVT::v64i8, { 1, 1, 1, 1 } },
4179 { ISD::CTPOP, MVT::v16i16, { 1, 1, 1, 1 } },
4180 { ISD::CTPOP, MVT::v32i8, { 1, 1, 1, 1 } },
4181 { ISD::CTPOP, MVT::v8i16, { 1, 1, 1, 1 } },
4182 { ISD::CTPOP, MVT::v16i8, { 1, 1, 1, 1 } },
4183 };
4184 static const CostKindTblEntry AVX512VPOPCNTDQCostTbl[] = {
4185 { ISD::CTPOP, MVT::v8i64, { 1, 1, 1, 1 } },
4186 { ISD::CTPOP, MVT::v16i32, { 1, 1, 1, 1 } },
4187 { ISD::CTPOP, MVT::v4i64, { 1, 1, 1, 1 } },
4188 { ISD::CTPOP, MVT::v8i32, { 1, 1, 1, 1 } },
4189 { ISD::CTPOP, MVT::v2i64, { 1, 1, 1, 1 } },
4190 { ISD::CTPOP, MVT::v4i32, { 1, 1, 1, 1 } },
4191 };
4192 static const CostKindTblEntry AVX512CDCostTbl[] = {
4193 { ISD::CTLZ, MVT::v8i64, { 1, 5, 1, 1 } },
4194 { ISD::CTLZ, MVT::v16i32, { 1, 5, 1, 1 } },
4195 { ISD::CTLZ, MVT::v32i16, { 18, 27, 23, 27 } },
4196 { ISD::CTLZ, MVT::v64i8, { 3, 16, 9, 11 } },
4197 { ISD::CTLZ, MVT::v4i64, { 1, 5, 1, 1 } },
4198 { ISD::CTLZ, MVT::v8i32, { 1, 5, 1, 1 } },
4199 { ISD::CTLZ, MVT::v16i16, { 8, 19, 11, 13 } },
4200 { ISD::CTLZ, MVT::v32i8, { 2, 11, 9, 10 } },
4201 { ISD::CTLZ, MVT::v2i64, { 1, 5, 1, 1 } },
4202 { ISD::CTLZ, MVT::v4i32, { 1, 5, 1, 1 } },
4203 { ISD::CTLZ, MVT::v8i16, { 3, 15, 4, 6 } },
4204 { ISD::CTLZ, MVT::v16i8, { 2, 10, 9, 10 } },
4205
4206 { ISD::CTTZ, MVT::v8i64, { 2, 8, 6, 7 } },
4207 { ISD::CTTZ, MVT::v16i32, { 2, 8, 6, 7 } },
4208 { ISD::CTTZ, MVT::v4i64, { 1, 8, 6, 6 } },
4209 { ISD::CTTZ, MVT::v8i32, { 1, 8, 6, 6 } },
4210 { ISD::CTTZ, MVT::v2i64, { 1, 8, 6, 6 } },
4211 { ISD::CTTZ, MVT::v4i32, { 1, 8, 6, 6 } },
4212 };
4213 static const CostKindTblEntry AVX512BWCostTbl[] = {
4214 { ISD::ABS, MVT::v32i16, { 1, 1, 1, 1 } },
4215 { ISD::ABS, MVT::v64i8, { 1, 1, 1, 1 } },
4216 { ISD::BITREVERSE, MVT::v2i64, { 3, 10, 10, 11 } },
4217 { ISD::BITREVERSE, MVT::v4i64, { 3, 11, 10, 11 } },
4218 { ISD::BITREVERSE, MVT::v8i64, { 3, 12, 10, 14 } },
4219 { ISD::BITREVERSE, MVT::v4i32, { 3, 10, 10, 11 } },
4220 { ISD::BITREVERSE, MVT::v8i32, { 3, 11, 10, 11 } },
4221 { ISD::BITREVERSE, MVT::v16i32, { 3, 12, 10, 14 } },
4222 { ISD::BITREVERSE, MVT::v8i16, { 3, 10, 10, 11 } },
4223 { ISD::BITREVERSE, MVT::v16i16, { 3, 11, 10, 11 } },
4224 { ISD::BITREVERSE, MVT::v32i16, { 3, 12, 10, 14 } },
4225 { ISD::BITREVERSE, MVT::v16i8, { 2, 5, 9, 9 } },
4226 { ISD::BITREVERSE, MVT::v32i8, { 2, 5, 9, 9 } },
4227 { ISD::BITREVERSE, MVT::v64i8, { 2, 5, 9, 12 } },
4228 { ISD::BSWAP, MVT::v2i64, { 1, 1, 1, 2 } },
4229 { ISD::BSWAP, MVT::v4i64, { 1, 1, 1, 2 } },
4230 { ISD::BSWAP, MVT::v8i64, { 1, 1, 1, 2 } },
4231 { ISD::BSWAP, MVT::v4i32, { 1, 1, 1, 2 } },
4232 { ISD::BSWAP, MVT::v8i32, { 1, 1, 1, 2 } },
4233 { ISD::BSWAP, MVT::v16i32, { 1, 1, 1, 2 } },
4234 { ISD::BSWAP, MVT::v8i16, { 1, 1, 1, 2 } },
4235 { ISD::BSWAP, MVT::v16i16, { 1, 1, 1, 2 } },
4236 { ISD::BSWAP, MVT::v32i16, { 1, 1, 1, 2 } },
4237 { ISD::CTLZ, MVT::v8i64, { 8, 22, 23, 23 } },
4238 { ISD::CTLZ, MVT::v16i32, { 8, 23, 25, 25 } },
4239 { ISD::CTLZ, MVT::v32i16, { 4, 15, 15, 16 } },
4240 { ISD::CTLZ, MVT::v64i8, { 3, 12, 10, 9 } },
4241 { ISD::CTPOP, MVT::v2i64, { 3, 7, 10, 10 } },
4242 { ISD::CTPOP, MVT::v4i64, { 3, 7, 10, 10 } },
4243 { ISD::CTPOP, MVT::v8i64, { 3, 8, 10, 12 } },
4244 { ISD::CTPOP, MVT::v4i32, { 7, 11, 14, 14 } },
4245 { ISD::CTPOP, MVT::v8i32, { 7, 11, 14, 14 } },
4246 { ISD::CTPOP, MVT::v16i32, { 7, 12, 14, 16 } },
4247 { ISD::CTPOP, MVT::v8i16, { 2, 7, 11, 11 } },
4248 { ISD::CTPOP, MVT::v16i16, { 2, 7, 11, 11 } },
4249 { ISD::CTPOP, MVT::v32i16, { 3, 7, 11, 13 } },
4250 { ISD::CTPOP, MVT::v16i8, { 2, 4, 8, 8 } },
4251 { ISD::CTPOP, MVT::v32i8, { 2, 4, 8, 8 } },
4252 { ISD::CTPOP, MVT::v64i8, { 2, 5, 8, 10 } },
4253 { ISD::CTTZ, MVT::v8i16, { 3, 9, 14, 14 } },
4254 { ISD::CTTZ, MVT::v16i16, { 3, 9, 14, 14 } },
4255 { ISD::CTTZ, MVT::v32i16, { 3, 10, 14, 16 } },
4256 { ISD::CTTZ, MVT::v16i8, { 2, 6, 11, 11 } },
4257 { ISD::CTTZ, MVT::v32i8, { 2, 6, 11, 11 } },
4258 { ISD::CTTZ, MVT::v64i8, { 3, 7, 11, 13 } },
4259 { ISD::MULHS, MVT::v32i16, { 1, 5, 1, 1 } },
4260 { ISD::MULHU, MVT::v32i16, { 1, 5, 1, 1 } },
4261 { ISD::ROTL, MVT::v32i16, { 2, 8, 6, 8 } },
4262 { ISD::ROTL, MVT::v16i16, { 2, 8, 6, 7 } },
4263 { ISD::ROTL, MVT::v8i16, { 2, 7, 6, 7 } },
4264 { ISD::ROTL, MVT::v64i8, { 5, 6, 11, 12 } },
4265 { ISD::ROTL, MVT::v32i8, { 5, 15, 7, 10 } },
4266 { ISD::ROTL, MVT::v16i8, { 5, 15, 7, 10 } },
4267 { ISD::ROTR, MVT::v32i16, { 2, 8, 6, 8 } },
4268 { ISD::ROTR, MVT::v16i16, { 2, 8, 6, 7 } },
4269 { ISD::ROTR, MVT::v8i16, { 2, 7, 6, 7 } },
4270 { ISD::ROTR, MVT::v64i8, { 5, 6, 12, 14 } },
4271 { ISD::ROTR, MVT::v32i8, { 5, 14, 6, 9 } },
4272 { ISD::ROTR, MVT::v16i8, { 5, 14, 6, 9 } },
4273 { X86ISD::VROTLI, MVT::v32i16, { 2, 5, 3, 3 } },
4274 { X86ISD::VROTLI, MVT::v16i16, { 1, 5, 3, 3 } },
4275 { X86ISD::VROTLI, MVT::v8i16, { 1, 5, 3, 3 } },
4276 { X86ISD::VROTLI, MVT::v64i8, { 2, 9, 3, 4 } },
4277 { X86ISD::VROTLI, MVT::v32i8, { 1, 9, 3, 4 } },
4278 { X86ISD::VROTLI, MVT::v16i8, { 1, 8, 3, 4 } },
4279 { ISD::SADDSAT, MVT::v32i16, { 1, 1, 1, 1 } },
4280 { ISD::SADDSAT, MVT::v64i8, { 1, 1, 1, 1 } },
4281 { ISD::SMAX, MVT::v32i16, { 1, 1, 1, 1 } },
4282 { ISD::SMAX, MVT::v64i8, { 1, 1, 1, 1 } },
4283 { ISD::SMIN, MVT::v32i16, { 1, 1, 1, 1 } },
4284 { ISD::SMIN, MVT::v64i8, { 1, 1, 1, 1 } },
4285 { ISD::SMULO, MVT::v32i16, { 3, 6, 4, 4 } },
4286 { ISD::SMULO, MVT::v64i8, { 8, 21, 17, 18 } },
4287 { ISD::UMULO, MVT::v32i16, { 2, 5, 3, 3 } },
4288 { ISD::UMULO, MVT::v64i8, { 8, 15, 15, 16 } },
4289 { ISD::SSUBSAT, MVT::v32i16, { 1, 1, 1, 1 } },
4290 { ISD::SSUBSAT, MVT::v64i8, { 1, 1, 1, 1 } },
4291 { ISD::UADDSAT, MVT::v32i16, { 1, 1, 1, 1 } },
4292 { ISD::UADDSAT, MVT::v64i8, { 1, 1, 1, 1 } },
4293 { ISD::UMAX, MVT::v32i16, { 1, 1, 1, 1 } },
4294 { ISD::UMAX, MVT::v64i8, { 1, 1, 1, 1 } },
4295 { ISD::UMIN, MVT::v32i16, { 1, 1, 1, 1 } },
4296 { ISD::UMIN, MVT::v64i8, { 1, 1, 1, 1 } },
4297 { ISD::USUBSAT, MVT::v32i16, { 1, 1, 1, 1 } },
4298 { ISD::USUBSAT, MVT::v64i8, { 1, 1, 1, 1 } },
4299 };
4300 static const CostKindTblEntry AVX512CostTbl[] = {
4301 { ISD::ABS, MVT::v8i64, { 1, 1, 1, 1 } },
4302 { ISD::ABS, MVT::v4i64, { 1, 1, 1, 1 } },
4303 { ISD::ABS, MVT::v2i64, { 1, 1, 1, 1 } },
4304 { ISD::ABS, MVT::v16i32, { 1, 1, 1, 1 } },
4305 { ISD::ABS, MVT::v8i32, { 1, 1, 1, 1 } },
4306 { ISD::ABS, MVT::v32i16, { 2, 7, 4, 4 } },
4307 { ISD::ABS, MVT::v16i16, { 1, 1, 1, 1 } },
4308 { ISD::ABS, MVT::v64i8, { 2, 7, 4, 4 } },
4309 { ISD::ABS, MVT::v32i8, { 1, 1, 1, 1 } },
4310 { ISD::BITREVERSE, MVT::v8i64, { 9, 13, 20, 20 } },
4311 { ISD::BITREVERSE, MVT::v16i32, { 9, 13, 20, 20 } },
4312 { ISD::BITREVERSE, MVT::v32i16, { 9, 13, 20, 20 } },
4313 { ISD::BITREVERSE, MVT::v64i8, { 6, 11, 17, 17 } },
4314 { ISD::BSWAP, MVT::v8i64, { 4, 7, 5, 5 } },
4315 { ISD::BSWAP, MVT::v16i32, { 4, 7, 5, 5 } },
4316 { ISD::BSWAP, MVT::v32i16, { 4, 7, 5, 5 } },
4317 { ISD::CTLZ, MVT::v8i64, { 10, 28, 32, 32 } },
4318 { ISD::CTLZ, MVT::v16i32, { 12, 30, 38, 38 } },
4319 { ISD::CTLZ, MVT::v32i16, { 8, 15, 29, 29 } },
4320 { ISD::CTLZ, MVT::v64i8, { 6, 11, 19, 19 } },
4321 { ISD::CTPOP, MVT::v8i64, { 16, 16, 19, 19 } },
4322 { ISD::CTPOP, MVT::v16i32, { 24, 19, 27, 27 } },
4323 { ISD::CTPOP, MVT::v32i16, { 18, 15, 22, 22 } },
4324 { ISD::CTPOP, MVT::v64i8, { 12, 11, 16, 16 } },
4325 { ISD::CTTZ, MVT::v8i64, { 2, 8, 6, 7 } },
4326 { ISD::CTTZ, MVT::v16i32, { 2, 8, 6, 7 } },
4327 { ISD::CTTZ, MVT::v32i16, { 7, 17, 27, 27 } },
4328 { ISD::CTTZ, MVT::v64i8, { 6, 13, 21, 21 } },
4329 { ISD::MULHS, MVT::v16i32, { 3, 10, 6, 7 } },
4330 { ISD::MULHS, MVT::v8i32, { 3, 9, 6, 6 } },
4331 { ISD::MULHS, MVT::v32i16, { 3, 7, 5, 5 } },
4332 { ISD::MULHS, MVT::v16i16, { 1, 5, 1, 1 } },
4333 { ISD::MULHU, MVT::v16i32, { 3, 10, 6, 7 } },
4334 { ISD::MULHU, MVT::v8i32, { 3, 9, 6, 6 } },
4335 { ISD::MULHU, MVT::v32i16, { 3, 7, 5, 5 } },
4336 { ISD::MULHU, MVT::v16i16, { 1, 5, 1, 1 } },
4337 { ISD::ROTL, MVT::v8i64, { 1, 1, 1, 1 } },
4338 { ISD::ROTL, MVT::v4i64, { 1, 1, 1, 1 } },
4339 { ISD::ROTL, MVT::v2i64, { 1, 1, 1, 1 } },
4340 { ISD::ROTL, MVT::v16i32, { 1, 1, 1, 1 } },
4341 { ISD::ROTL, MVT::v8i32, { 1, 1, 1, 1 } },
4342 { ISD::ROTL, MVT::v4i32, { 1, 1, 1, 1 } },
4343 { ISD::ROTR, MVT::v8i64, { 1, 1, 1, 1 } },
4344 { ISD::ROTR, MVT::v4i64, { 1, 1, 1, 1 } },
4345 { ISD::ROTR, MVT::v2i64, { 1, 1, 1, 1 } },
4346 { ISD::ROTR, MVT::v16i32, { 1, 1, 1, 1 } },
4347 { ISD::ROTR, MVT::v8i32, { 1, 1, 1, 1 } },
4348 { ISD::ROTR, MVT::v4i32, { 1, 1, 1, 1 } },
4349 { X86ISD::VROTLI, MVT::v8i64, { 1, 1, 1, 1 } },
4350 { X86ISD::VROTLI, MVT::v4i64, { 1, 1, 1, 1 } },
4351 { X86ISD::VROTLI, MVT::v2i64, { 1, 1, 1, 1 } },
4352 { X86ISD::VROTLI, MVT::v16i32, { 1, 1, 1, 1 } },
4353 { X86ISD::VROTLI, MVT::v8i32, { 1, 1, 1, 1 } },
4354 { X86ISD::VROTLI, MVT::v4i32, { 1, 1, 1, 1 } },
4355 { ISD::SADDSAT, MVT::v2i64, { 3, 3, 8, 9 } },
4356 { ISD::SADDSAT, MVT::v4i64, { 2, 2, 6, 7 } },
4357 { ISD::SADDSAT, MVT::v8i64, { 3, 3, 6, 7 } },
4358 { ISD::SADDSAT, MVT::v4i32, { 2, 2, 6, 7 } },
4359 { ISD::SADDSAT, MVT::v8i32, { 2, 2, 6, 7 } },
4360 { ISD::SADDSAT, MVT::v16i32, { 3, 3, 6, 7 } },
4361 { ISD::SADDSAT, MVT::v32i16, { 2, 2, 2, 2 } },
4362 { ISD::SADDSAT, MVT::v64i8, { 2, 2, 2, 2 } },
4363 { ISD::SMAX, MVT::v8i64, { 1, 3, 1, 1 } },
4364 { ISD::SMAX, MVT::v16i32, { 1, 1, 1, 1 } },
4365 { ISD::SMAX, MVT::v32i16, { 3, 7, 5, 5 } },
4366 { ISD::SMAX, MVT::v64i8, { 3, 7, 5, 5 } },
4367 { ISD::SMAX, MVT::v4i64, { 1, 3, 1, 1 } },
4368 { ISD::SMAX, MVT::v2i64, { 1, 3, 1, 1 } },
4369 { ISD::SMIN, MVT::v8i64, { 1, 3, 1, 1 } },
4370 { ISD::SMIN, MVT::v16i32, { 1, 1, 1, 1 } },
4371 { ISD::SMIN, MVT::v32i16, { 3, 7, 5, 5 } },
4372 { ISD::SMIN, MVT::v64i8, { 3, 7, 5, 5 } },
4373 { ISD::SMIN, MVT::v4i64, { 1, 3, 1, 1 } },
4374 { ISD::SMIN, MVT::v2i64, { 1, 3, 1, 1 } },
4375 { ISD::SMULO, MVT::v8i64, { 44, 44, 81, 93 } },
4376 { ISD::SMULO, MVT::v16i32, { 5, 12, 9, 11 } },
4377 { ISD::SMULO, MVT::v32i16, { 6, 12, 17, 17 } },
4378 { ISD::SMULO, MVT::v64i8, { 22, 28, 42, 42 } },
4379 { ISD::SSUBSAT, MVT::v2i64, { 2, 13, 9, 10 } },
4380 { ISD::SSUBSAT, MVT::v4i64, { 2, 15, 7, 8 } },
4381 { ISD::SSUBSAT, MVT::v8i64, { 2, 14, 7, 8 } },
4382 { ISD::SSUBSAT, MVT::v4i32, { 2, 14, 7, 8 } },
4383 { ISD::SSUBSAT, MVT::v8i32, { 2, 15, 7, 8 } },
4384 { ISD::SSUBSAT, MVT::v16i32, { 2, 14, 7, 8 } },
4385 { ISD::SSUBSAT, MVT::v32i16, { 2, 2, 2, 2 } },
4386 { ISD::SSUBSAT, MVT::v64i8, { 2, 2, 2, 2 } },
4387 { ISD::UMAX, MVT::v8i64, { 1, 3, 1, 1 } },
4388 { ISD::UMAX, MVT::v16i32, { 1, 1, 1, 1 } },
4389 { ISD::UMAX, MVT::v32i16, { 3, 7, 5, 5 } },
4390 { ISD::UMAX, MVT::v64i8, { 3, 7, 5, 5 } },
4391 { ISD::UMAX, MVT::v4i64, { 1, 3, 1, 1 } },
4392 { ISD::UMAX, MVT::v2i64, { 1, 3, 1, 1 } },
4393 { ISD::UMIN, MVT::v8i64, { 1, 3, 1, 1 } },
4394 { ISD::UMIN, MVT::v16i32, { 1, 1, 1, 1 } },
4395 { ISD::UMIN, MVT::v32i16, { 3, 7, 5, 5 } },
4396 { ISD::UMIN, MVT::v64i8, { 3, 7, 5, 5 } },
4397 { ISD::UMIN, MVT::v4i64, { 1, 3, 1, 1 } },
4398 { ISD::UMIN, MVT::v2i64, { 1, 3, 1, 1 } },
4399 { ISD::UMULO, MVT::v8i64, { 52, 52, 95, 104} },
4400 { ISD::UMULO, MVT::v16i32, { 5, 12, 8, 10 } },
4401 { ISD::UMULO, MVT::v32i16, { 5, 13, 16, 16 } },
4402 { ISD::UMULO, MVT::v64i8, { 18, 24, 30, 30 } },
4403 { ISD::UADDSAT, MVT::v2i64, { 1, 4, 4, 4 } },
4404 { ISD::UADDSAT, MVT::v4i64, { 1, 4, 4, 4 } },
4405 { ISD::UADDSAT, MVT::v8i64, { 1, 4, 4, 4 } },
4406 { ISD::UADDSAT, MVT::v4i32, { 1, 2, 4, 4 } },
4407 { ISD::UADDSAT, MVT::v8i32, { 1, 2, 4, 4 } },
4408 { ISD::UADDSAT, MVT::v16i32, { 2, 2, 4, 4 } },
4409 { ISD::UADDSAT, MVT::v32i16, { 2, 2, 2, 2 } },
4410 { ISD::UADDSAT, MVT::v64i8, { 2, 2, 2, 2 } },
4411 { ISD::USUBSAT, MVT::v2i64, { 1, 4, 2, 2 } },
4412 { ISD::USUBSAT, MVT::v4i64, { 1, 4, 2, 2 } },
4413 { ISD::USUBSAT, MVT::v8i64, { 1, 4, 2, 2 } },
4414 { ISD::USUBSAT, MVT::v8i32, { 1, 2, 2, 2 } },
4415 { ISD::USUBSAT, MVT::v16i32, { 1, 2, 2, 2 } },
4416 { ISD::USUBSAT, MVT::v32i16, { 2, 2, 2, 2 } },
4417 { ISD::USUBSAT, MVT::v64i8, { 2, 2, 2, 2 } },
4418 { ISD::FMAXNUM, MVT::f32, { 2, 2, 3, 3 } },
4419 { ISD::FMAXNUM, MVT::v4f32, { 1, 1, 3, 3 } },
4420 { ISD::FMAXNUM, MVT::v8f32, { 2, 2, 3, 3 } },
4421 { ISD::FMAXNUM, MVT::v16f32, { 4, 4, 3, 3 } },
4422 { ISD::FMAXNUM, MVT::f64, { 2, 2, 3, 3 } },
4423 { ISD::FMAXNUM, MVT::v2f64, { 1, 1, 3, 3 } },
4424 { ISD::FMAXNUM, MVT::v4f64, { 2, 2, 3, 3 } },
4425 { ISD::FMAXNUM, MVT::v8f64, { 3, 3, 3, 3 } },
4426 { ISD::FSQRT, MVT::f32, { 3, 12, 1, 1 } }, // Skylake from http://www.agner.org/
4427 { ISD::FSQRT, MVT::v4f32, { 3, 12, 1, 1 } }, // Skylake from http://www.agner.org/
4428 { ISD::FSQRT, MVT::v8f32, { 6, 12, 1, 1 } }, // Skylake from http://www.agner.org/
4429 { ISD::FSQRT, MVT::v16f32, { 12, 20, 1, 3 } }, // Skylake from http://www.agner.org/
4430 { ISD::FSQRT, MVT::f64, { 6, 18, 1, 1 } }, // Skylake from http://www.agner.org/
4431 { ISD::FSQRT, MVT::v2f64, { 6, 18, 1, 1 } }, // Skylake from http://www.agner.org/
4432 { ISD::FSQRT, MVT::v4f64, { 12, 18, 1, 1 } }, // Skylake from http://www.agner.org/
4433 { ISD::FSQRT, MVT::v8f64, { 24, 32, 1, 3 } }, // Skylake from http://www.agner.org/
4434 };
4435 static const CostKindTblEntry XOPCostTbl[] = {
4436 { ISD::BITREVERSE, MVT::v4i64, { 3, 6, 5, 6 } },
4437 { ISD::BITREVERSE, MVT::v8i32, { 3, 6, 5, 6 } },
4438 { ISD::BITREVERSE, MVT::v16i16, { 3, 6, 5, 6 } },
4439 { ISD::BITREVERSE, MVT::v32i8, { 3, 6, 5, 6 } },
4440 { ISD::BITREVERSE, MVT::v2i64, { 2, 7, 1, 1 } },
4441 { ISD::BITREVERSE, MVT::v4i32, { 2, 7, 1, 1 } },
4442 { ISD::BITREVERSE, MVT::v8i16, { 2, 7, 1, 1 } },
4443 { ISD::BITREVERSE, MVT::v16i8, { 2, 7, 1, 1 } },
4444 { ISD::BITREVERSE, MVT::i64, { 2, 2, 3, 4 } },
4445 { ISD::BITREVERSE, MVT::i32, { 2, 2, 3, 4 } },
4446 { ISD::BITREVERSE, MVT::i16, { 2, 2, 3, 4 } },
4447 { ISD::BITREVERSE, MVT::i8, { 2, 2, 3, 4 } },
4448 // XOP: ROTL = VPROT(X,Y), ROTR = VPROT(X,SUB(0,Y))
4449 { ISD::ROTL, MVT::v4i64, { 4, 7, 5, 6 } },
4450 { ISD::ROTL, MVT::v8i32, { 4, 7, 5, 6 } },
4451 { ISD::ROTL, MVT::v16i16, { 4, 7, 5, 6 } },
4452 { ISD::ROTL, MVT::v32i8, { 4, 7, 5, 6 } },
4453 { ISD::ROTL, MVT::v2i64, { 1, 3, 1, 1 } },
4454 { ISD::ROTL, MVT::v4i32, { 1, 3, 1, 1 } },
4455 { ISD::ROTL, MVT::v8i16, { 1, 3, 1, 1 } },
4456 { ISD::ROTL, MVT::v16i8, { 1, 3, 1, 1 } },
4457 { ISD::ROTR, MVT::v4i64, { 4, 7, 8, 9 } },
4458 { ISD::ROTR, MVT::v8i32, { 4, 7, 8, 9 } },
4459 { ISD::ROTR, MVT::v16i16, { 4, 7, 8, 9 } },
4460 { ISD::ROTR, MVT::v32i8, { 4, 7, 8, 9 } },
4461 { ISD::ROTR, MVT::v2i64, { 1, 3, 3, 3 } },
4462 { ISD::ROTR, MVT::v4i32, { 1, 3, 3, 3 } },
4463 { ISD::ROTR, MVT::v8i16, { 1, 3, 3, 3 } },
4464 { ISD::ROTR, MVT::v16i8, { 1, 3, 3, 3 } },
4465 { X86ISD::VROTLI, MVT::v4i64, { 4, 7, 5, 6 } },
4466 { X86ISD::VROTLI, MVT::v8i32, { 4, 7, 5, 6 } },
4467 { X86ISD::VROTLI, MVT::v16i16, { 4, 7, 5, 6 } },
4468 { X86ISD::VROTLI, MVT::v32i8, { 4, 7, 5, 6 } },
4469 { X86ISD::VROTLI, MVT::v2i64, { 1, 3, 1, 1 } },
4470 { X86ISD::VROTLI, MVT::v4i32, { 1, 3, 1, 1 } },
4471 { X86ISD::VROTLI, MVT::v8i16, { 1, 3, 1, 1 } },
4472 { X86ISD::VROTLI, MVT::v16i8, { 1, 3, 1, 1 } },
4473 };
4474 static const CostKindTblEntry AVX2CostTbl[] = {
4475 { ISD::ABS, MVT::v2i64, { 2, 4, 3, 5 } }, // VBLENDVPD(X,VPSUBQ(0,X),X)
4476 { ISD::ABS, MVT::v4i64, { 2, 4, 3, 5 } }, // VBLENDVPD(X,VPSUBQ(0,X),X)
4477 { ISD::ABS, MVT::v4i32, { 1, 1, 1, 1 } },
4478 { ISD::ABS, MVT::v8i32, { 1, 1, 1, 2 } },
4479 { ISD::ABS, MVT::v8i16, { 1, 1, 1, 1 } },
4480 { ISD::ABS, MVT::v16i16, { 1, 1, 1, 2 } },
4481 { ISD::ABS, MVT::v16i8, { 1, 1, 1, 1 } },
4482 { ISD::ABS, MVT::v32i8, { 1, 1, 1, 2 } },
4483 { ISD::BITREVERSE, MVT::v2i64, { 3, 11, 10, 11 } },
4484 { ISD::BITREVERSE, MVT::v4i64, { 5, 11, 10, 17 } },
4485 { ISD::BITREVERSE, MVT::v4i32, { 3, 11, 10, 11 } },
4486 { ISD::BITREVERSE, MVT::v8i32, { 5, 11, 10, 17 } },
4487 { ISD::BITREVERSE, MVT::v8i16, { 3, 11, 10, 11 } },
4488 { ISD::BITREVERSE, MVT::v16i16, { 5, 11, 10, 17 } },
4489 { ISD::BITREVERSE, MVT::v16i8, { 3, 6, 9, 9 } },
4490 { ISD::BITREVERSE, MVT::v32i8, { 4, 5, 9, 15 } },
4491 { ISD::BSWAP, MVT::v2i64, { 1, 2, 1, 2 } },
4492 { ISD::BSWAP, MVT::v4i64, { 1, 3, 1, 2 } },
4493 { ISD::BSWAP, MVT::v4i32, { 1, 2, 1, 2 } },
4494 { ISD::BSWAP, MVT::v8i32, { 1, 3, 1, 2 } },
4495 { ISD::BSWAP, MVT::v8i16, { 1, 2, 1, 2 } },
4496 { ISD::BSWAP, MVT::v16i16, { 1, 3, 1, 2 } },
4497 { ISD::CTLZ, MVT::v2i64, { 7, 18, 24, 25 } },
4498 { ISD::CTLZ, MVT::v4i64, { 14, 18, 24, 44 } },
4499 { ISD::CTLZ, MVT::v4i32, { 5, 16, 19, 20 } },
4500 { ISD::CTLZ, MVT::v8i32, { 10, 16, 19, 34 } },
4501 { ISD::CTLZ, MVT::v8i16, { 4, 13, 14, 15 } },
4502 { ISD::CTLZ, MVT::v16i16, { 6, 14, 14, 24 } },
4503 { ISD::CTLZ, MVT::v16i8, { 3, 12, 9, 10 } },
4504 { ISD::CTLZ, MVT::v32i8, { 4, 12, 9, 14 } },
4505 { ISD::CTPOP, MVT::v2i64, { 3, 9, 10, 10 } },
4506 { ISD::CTPOP, MVT::v4i64, { 4, 9, 10, 14 } },
4507 { ISD::CTPOP, MVT::v4i32, { 7, 12, 14, 14 } },
4508 { ISD::CTPOP, MVT::v8i32, { 7, 12, 14, 18 } },
4509 { ISD::CTPOP, MVT::v8i16, { 3, 7, 11, 11 } },
4510 { ISD::CTPOP, MVT::v16i16, { 6, 8, 11, 18 } },
4511 { ISD::CTPOP, MVT::v16i8, { 2, 5, 8, 8 } },
4512 { ISD::CTPOP, MVT::v32i8, { 3, 5, 8, 12 } },
4513 { ISD::CTTZ, MVT::v2i64, { 4, 11, 13, 13 } },
4514 { ISD::CTTZ, MVT::v4i64, { 5, 11, 13, 20 } },
4515 { ISD::CTTZ, MVT::v4i32, { 7, 14, 17, 17 } },
4516 { ISD::CTTZ, MVT::v8i32, { 7, 15, 17, 24 } },
4517 { ISD::CTTZ, MVT::v8i16, { 4, 9, 14, 14 } },
4518 { ISD::CTTZ, MVT::v16i16, { 6, 9, 14, 24 } },
4519 { ISD::CTTZ, MVT::v16i8, { 3, 7, 11, 11 } },
4520 { ISD::CTTZ, MVT::v32i8, { 5, 7, 11, 18 } },
4521 { ISD::MULHS, MVT::v8i32, { 4, 9, 6, 12 } },
4522 { ISD::MULHS, MVT::v16i16, { 2, 5, 1, 2 } },
4523 { ISD::MULHU, MVT::v8i32, { 4, 9, 6, 12 } },
4524 { ISD::MULHU, MVT::v16i16, { 2, 5, 1, 2 } },
4525 { ISD::SADDSAT, MVT::v2i64, { 4, 13, 8, 11 } },
4526 { ISD::SADDSAT, MVT::v4i64, { 3, 10, 8, 12 } },
4527 { ISD::SADDSAT, MVT::v4i32, { 2, 6, 7, 9 } },
4528 { ISD::SADDSAT, MVT::v8i32, { 4, 6, 7, 13 } },
4529 { ISD::SADDSAT, MVT::v16i16, { 1, 1, 1, 2 } },
4530 { ISD::SADDSAT, MVT::v32i8, { 1, 1, 1, 2 } },
4531 { ISD::SMAX, MVT::v2i64, { 2, 7, 2, 3 } },
4532 { ISD::SMAX, MVT::v4i64, { 2, 7, 2, 3 } },
4533 { ISD::SMAX, MVT::v8i32, { 1, 1, 1, 2 } },
4534 { ISD::SMAX, MVT::v16i16, { 1, 1, 1, 2 } },
4535 { ISD::SMAX, MVT::v32i8, { 1, 1, 1, 2 } },
4536 { ISD::SMIN, MVT::v2i64, { 2, 7, 2, 3 } },
4537 { ISD::SMIN, MVT::v4i64, { 2, 7, 2, 3 } },
4538 { ISD::SMIN, MVT::v8i32, { 1, 1, 1, 2 } },
4539 { ISD::SMIN, MVT::v16i16, { 1, 1, 1, 2 } },
4540 { ISD::SMIN, MVT::v32i8, { 1, 1, 1, 2 } },
4541 { ISD::SMULO, MVT::v4i64, { 20, 20, 33, 37 } },
4542 { ISD::SMULO, MVT::v2i64, { 8, 8, 13, 15 } },
4543 { ISD::SMULO, MVT::v8i32, { 8, 20, 13, 24 } },
4544 { ISD::SMULO, MVT::v4i32, { 5, 15, 11, 12 } },
4545 { ISD::SMULO, MVT::v16i16, { 4, 14, 8, 14 } },
4546 { ISD::SMULO, MVT::v8i16, { 3, 9, 6, 6 } },
4547 { ISD::SMULO, MVT::v32i8, { 9, 15, 18, 35 } },
4548 { ISD::SMULO, MVT::v16i8, { 6, 22, 14, 21 } },
4549 { ISD::SSUBSAT, MVT::v2i64, { 4, 13, 9, 13 } },
4550 { ISD::SSUBSAT, MVT::v4i64, { 4, 15, 9, 13 } },
4551 { ISD::SSUBSAT, MVT::v4i32, { 3, 14, 9, 11 } },
4552 { ISD::SSUBSAT, MVT::v8i32, { 4, 15, 9, 16 } },
4553 { ISD::SSUBSAT, MVT::v16i16, { 1, 1, 1, 2 } },
4554 { ISD::SSUBSAT, MVT::v32i8, { 1, 1, 1, 2 } },
4555 { ISD::UADDSAT, MVT::v2i64, { 2, 8, 6, 6 } },
4556 { ISD::UADDSAT, MVT::v4i64, { 3, 8, 6, 10 } },
4557 { ISD::UADDSAT, MVT::v8i32, { 2, 2, 4, 8 } },
4558 { ISD::UADDSAT, MVT::v16i16, { 1, 1, 1, 2 } },
4559 { ISD::UADDSAT, MVT::v32i8, { 1, 1, 1, 2 } },
4560 { ISD::UMAX, MVT::v2i64, { 2, 8, 5, 6 } },
4561 { ISD::UMAX, MVT::v4i64, { 2, 8, 5, 8 } },
4562 { ISD::UMAX, MVT::v8i32, { 1, 1, 1, 2 } },
4563 { ISD::UMAX, MVT::v16i16, { 1, 1, 1, 2 } },
4564 { ISD::UMAX, MVT::v32i8, { 1, 1, 1, 2 } },
4565 { ISD::UMIN, MVT::v2i64, { 2, 8, 5, 6 } },
4566 { ISD::UMIN, MVT::v4i64, { 2, 8, 5, 8 } },
4567 { ISD::UMIN, MVT::v8i32, { 1, 1, 1, 2 } },
4568 { ISD::UMIN, MVT::v16i16, { 1, 1, 1, 2 } },
4569 { ISD::UMIN, MVT::v32i8, { 1, 1, 1, 2 } },
4570 { ISD::UMULO, MVT::v4i64, { 24, 24, 39, 43 } },
4571 { ISD::UMULO, MVT::v2i64, { 10, 10, 15, 19 } },
4572 { ISD::UMULO, MVT::v8i32, { 8, 11, 13, 23 } },
4573 { ISD::UMULO, MVT::v4i32, { 5, 12, 11, 12 } },
4574 { ISD::UMULO, MVT::v16i16, { 4, 6, 8, 13 } },
4575 { ISD::UMULO, MVT::v8i16, { 2, 8, 6, 6 } },
4576 { ISD::UMULO, MVT::v32i8, { 9, 13, 17, 33 } },
4577 { ISD::UMULO, MVT::v16i8, { 6, 19, 13, 20 } },
4578 { ISD::USUBSAT, MVT::v2i64, { 2, 7, 6, 6 } },
4579 { ISD::USUBSAT, MVT::v4i64, { 3, 7, 6, 10 } },
4580 { ISD::USUBSAT, MVT::v8i32, { 2, 2, 2, 4 } },
4581 { ISD::USUBSAT, MVT::v16i16, { 1, 1, 1, 2 } },
4582 { ISD::USUBSAT, MVT::v32i8, { 1, 1, 1, 2 } },
4583 { ISD::FMAXNUM, MVT::f32, { 2, 7, 3, 5 } }, // MAXSS + CMPUNORDSS + BLENDVPS
4584 { ISD::FMAXNUM, MVT::v4f32, { 2, 7, 3, 5 } }, // MAXPS + CMPUNORDPS + BLENDVPS
4585 { ISD::FMAXNUM, MVT::v8f32, { 3, 7, 3, 6 } }, // MAXPS + CMPUNORDPS + BLENDVPS
4586 { ISD::FMAXNUM, MVT::f64, { 2, 7, 3, 5 } }, // MAXSD + CMPUNORDSD + BLENDVPD
4587 { ISD::FMAXNUM, MVT::v2f64, { 2, 7, 3, 5 } }, // MAXPD + CMPUNORDPD + BLENDVPD
4588 { ISD::FMAXNUM, MVT::v4f64, { 3, 7, 3, 6 } }, // MAXPD + CMPUNORDPD + BLENDVPD
4589 { ISD::FSQRT, MVT::f32, { 7, 15, 1, 1 } }, // vsqrtss
4590 { ISD::FSQRT, MVT::v4f32, { 7, 15, 1, 1 } }, // vsqrtps
4591 { ISD::FSQRT, MVT::v8f32, { 14, 21, 1, 3 } }, // vsqrtps
4592 { ISD::FSQRT, MVT::f64, { 14, 21, 1, 1 } }, // vsqrtsd
4593 { ISD::FSQRT, MVT::v2f64, { 14, 21, 1, 1 } }, // vsqrtpd
4594 { ISD::FSQRT, MVT::v4f64, { 28, 35, 1, 3 } }, // vsqrtpd
4595 };
4596 static const CostKindTblEntry AVX1CostTbl[] = {
4597 { ISD::ABS, MVT::v4i64, { 6, 8, 6, 12 } }, // VBLENDVPD(X,VPSUBQ(0,X),X)
4598 { ISD::ABS, MVT::v8i32, { 3, 6, 4, 5 } },
4599 { ISD::ABS, MVT::v16i16, { 3, 6, 4, 5 } },
4600 { ISD::ABS, MVT::v32i8, { 3, 6, 4, 5 } },
4601 { ISD::BITREVERSE, MVT::v4i64, { 17, 20, 20, 33 } }, // 2 x 128-bit Op + extract/insert
4602 { ISD::BITREVERSE, MVT::v2i64, { 8, 13, 10, 16 } },
4603 { ISD::BITREVERSE, MVT::v8i32, { 17, 20, 20, 33 } }, // 2 x 128-bit Op + extract/insert
4604 { ISD::BITREVERSE, MVT::v4i32, { 8, 13, 10, 16 } },
4605 { ISD::BITREVERSE, MVT::v16i16, { 17, 20, 20, 33 } }, // 2 x 128-bit Op + extract/insert
4606 { ISD::BITREVERSE, MVT::v8i16, { 8, 13, 10, 16 } },
4607 { ISD::BITREVERSE, MVT::v32i8, { 13, 15, 17, 26 } }, // 2 x 128-bit Op + extract/insert
4608 { ISD::BITREVERSE, MVT::v16i8, { 7, 7, 9, 13 } },
4609 { ISD::BSWAP, MVT::v4i64, { 5, 6, 5, 10 } },
4610 { ISD::BSWAP, MVT::v2i64, { 2, 2, 1, 3 } },
4611 { ISD::BSWAP, MVT::v8i32, { 5, 6, 5, 10 } },
4612 { ISD::BSWAP, MVT::v4i32, { 2, 2, 1, 3 } },
4613 { ISD::BSWAP, MVT::v16i16, { 5, 6, 5, 10 } },
4614 { ISD::BSWAP, MVT::v8i16, { 2, 2, 1, 3 } },
4615 { ISD::CTLZ, MVT::v4i64, { 29, 33, 49, 58 } }, // 2 x 128-bit Op + extract/insert
4616 { ISD::CTLZ, MVT::v2i64, { 14, 24, 24, 28 } },
4617 { ISD::CTLZ, MVT::v8i32, { 24, 28, 39, 48 } }, // 2 x 128-bit Op + extract/insert
4618 { ISD::CTLZ, MVT::v4i32, { 12, 20, 19, 23 } },
4619 { ISD::CTLZ, MVT::v16i16, { 19, 22, 29, 38 } }, // 2 x 128-bit Op + extract/insert
4620 { ISD::CTLZ, MVT::v8i16, { 9, 16, 14, 18 } },
4621 { ISD::CTLZ, MVT::v32i8, { 14, 15, 19, 28 } }, // 2 x 128-bit Op + extract/insert
4622 { ISD::CTLZ, MVT::v16i8, { 7, 12, 9, 13 } },
4623 { ISD::CTPOP, MVT::v4i64, { 14, 18, 19, 28 } }, // 2 x 128-bit Op + extract/insert
4624 { ISD::CTPOP, MVT::v2i64, { 7, 14, 10, 14 } },
4625 { ISD::CTPOP, MVT::v8i32, { 18, 24, 27, 36 } }, // 2 x 128-bit Op + extract/insert
4626 { ISD::CTPOP, MVT::v4i32, { 9, 20, 14, 18 } },
4627 { ISD::CTPOP, MVT::v16i16, { 16, 21, 22, 31 } }, // 2 x 128-bit Op + extract/insert
4628 { ISD::CTPOP, MVT::v8i16, { 8, 18, 11, 15 } },
4629 { ISD::CTPOP, MVT::v32i8, { 13, 15, 16, 25 } }, // 2 x 128-bit Op + extract/insert
4630 { ISD::CTPOP, MVT::v16i8, { 6, 12, 8, 12 } },
4631 { ISD::CTTZ, MVT::v4i64, { 17, 22, 24, 33 } }, // 2 x 128-bit Op + extract/insert
4632 { ISD::CTTZ, MVT::v2i64, { 9, 19, 13, 17 } },
4633 { ISD::CTTZ, MVT::v8i32, { 21, 27, 32, 41 } }, // 2 x 128-bit Op + extract/insert
4634 { ISD::CTTZ, MVT::v4i32, { 11, 24, 17, 21 } },
4635 { ISD::CTTZ, MVT::v16i16, { 18, 24, 27, 36 } }, // 2 x 128-bit Op + extract/insert
4636 { ISD::CTTZ, MVT::v8i16, { 9, 21, 14, 18 } },
4637 { ISD::CTTZ, MVT::v32i8, { 15, 18, 21, 30 } }, // 2 x 128-bit Op + extract/insert
4638 { ISD::CTTZ, MVT::v16i8, { 8, 16, 11, 15 } },
4639 { ISD::MULHS, MVT::v8i32, { 9, 11, 14, 18 } },
4640 { ISD::MULHS, MVT::v16i16, { 3, 7, 5, 6 } },
4641 { ISD::MULHU, MVT::v8i32, { 9, 11, 14, 18 } },
4642 { ISD::MULHU, MVT::v16i16, { 3, 7, 5, 6 } },
4643 { ISD::SADDSAT, MVT::v2i64, { 6, 13, 8, 11 } },
4644 { ISD::SADDSAT, MVT::v4i64, { 13, 20, 15, 25 } }, // 2 x 128-bit Op + extract/insert
4645 { ISD::SADDSAT, MVT::v8i32, { 12, 18, 14, 24 } }, // 2 x 128-bit Op + extract/insert
4646 { ISD::SADDSAT, MVT::v16i16, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4647 { ISD::SADDSAT, MVT::v32i8, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4648 { ISD::SMAX, MVT::v4i64, { 6, 9, 6, 12 } }, // 2 x 128-bit Op + extract/insert
4649 { ISD::SMAX, MVT::v2i64, { 3, 7, 2, 4 } },
4650 { ISD::SMAX, MVT::v8i32, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4651 { ISD::SMAX, MVT::v16i16, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4652 { ISD::SMAX, MVT::v32i8, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4653 { ISD::SMIN, MVT::v4i64, { 6, 9, 6, 12 } }, // 2 x 128-bit Op + extract/insert
4654 { ISD::SMIN, MVT::v2i64, { 3, 7, 2, 3 } },
4655 { ISD::SMIN, MVT::v8i32, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4656 { ISD::SMIN, MVT::v16i16, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4657 { ISD::SMIN, MVT::v32i8, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4658 { ISD::SMULO, MVT::v4i64, { 20, 20, 33, 37 } },
4659 { ISD::SMULO, MVT::v2i64, { 9, 9, 13, 17 } },
4660 { ISD::SMULO, MVT::v8i32, { 15, 20, 24, 29 } },
4661 { ISD::SMULO, MVT::v4i32, { 7, 15, 11, 13 } },
4662 { ISD::SMULO, MVT::v16i16, { 8, 14, 14, 15 } },
4663 { ISD::SMULO, MVT::v8i16, { 3, 9, 6, 6 } },
4664 { ISD::SMULO, MVT::v32i8, { 20, 20, 37, 39 } },
4665 { ISD::SMULO, MVT::v16i8, { 9, 22, 18, 21 } },
4666 { ISD::SSUBSAT, MVT::v2i64, { 7, 13, 9, 13 } },
4667 { ISD::SSUBSAT, MVT::v4i64, { 15, 21, 18, 29 } }, // 2 x 128-bit Op + extract/insert
4668 { ISD::SSUBSAT, MVT::v8i32, { 15, 19, 18, 29 } }, // 2 x 128-bit Op + extract/insert
4669 { ISD::SSUBSAT, MVT::v16i16, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4670 { ISD::SSUBSAT, MVT::v32i8, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4671 { ISD::UADDSAT, MVT::v2i64, { 3, 8, 6, 6 } },
4672 { ISD::UADDSAT, MVT::v4i64, { 8, 11, 14, 15 } }, // 2 x 128-bit Op + extract/insert
4673 { ISD::UADDSAT, MVT::v8i32, { 6, 6, 10, 11 } }, // 2 x 128-bit Op + extract/insert
4674 { ISD::UADDSAT, MVT::v16i16, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4675 { ISD::UADDSAT, MVT::v32i8, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4676 { ISD::UMAX, MVT::v4i64, { 9, 10, 11, 17 } }, // 2 x 128-bit Op + extract/insert
4677 { ISD::UMAX, MVT::v2i64, { 4, 8, 5, 7 } },
4678 { ISD::UMAX, MVT::v8i32, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4679 { ISD::UMAX, MVT::v16i16, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4680 { ISD::UMAX, MVT::v32i8, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4681 { ISD::UMIN, MVT::v4i64, { 9, 10, 11, 17 } }, // 2 x 128-bit Op + extract/insert
4682 { ISD::UMIN, MVT::v2i64, { 4, 8, 5, 7 } },
4683 { ISD::UMIN, MVT::v8i32, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4684 { ISD::UMIN, MVT::v16i16, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4685 { ISD::UMIN, MVT::v32i8, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4686 { ISD::UMULO, MVT::v4i64, { 24, 26, 39, 45 } },
4687 { ISD::UMULO, MVT::v2i64, { 10, 12, 15, 20 } },
4688 { ISD::UMULO, MVT::v8i32, { 14, 15, 23, 28 } },
4689 { ISD::UMULO, MVT::v4i32, { 7, 12, 11, 13 } },
4690 { ISD::UMULO, MVT::v16i16, { 7, 11, 13, 14 } },
4691 { ISD::UMULO, MVT::v8i16, { 3, 8, 6, 6 } },
4692 { ISD::UMULO, MVT::v32i8, { 19, 19, 35, 37 } },
4693 { ISD::UMULO, MVT::v16i8, { 9, 19, 17, 20 } },
4694 { ISD::USUBSAT, MVT::v2i64, { 3, 7, 6, 6 } },
4695 { ISD::USUBSAT, MVT::v4i64, { 8, 10, 14, 15 } }, // 2 x 128-bit Op + extract/insert
4696 { ISD::USUBSAT, MVT::v8i32, { 4, 4, 7, 8 } }, // 2 x 128-bit Op + extract/insert
4697 { ISD::USUBSAT, MVT::v8i32, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4698 { ISD::USUBSAT, MVT::v16i16, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4699 { ISD::USUBSAT, MVT::v32i8, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4700 { ISD::FMAXNUM, MVT::f32, { 3, 6, 3, 5 } }, // MAXSS + CMPUNORDSS + BLENDVPS
4701 { ISD::FMAXNUM, MVT::v4f32, { 3, 6, 3, 5 } }, // MAXPS + CMPUNORDPS + BLENDVPS
4702 { ISD::FMAXNUM, MVT::v8f32, { 5, 7, 3, 10 } }, // MAXPS + CMPUNORDPS + BLENDVPS
4703 { ISD::FMAXNUM, MVT::f64, { 3, 6, 3, 5 } }, // MAXSD + CMPUNORDSD + BLENDVPD
4704 { ISD::FMAXNUM, MVT::v2f64, { 3, 6, 3, 5 } }, // MAXPD + CMPUNORDPD + BLENDVPD
4705 { ISD::FMAXNUM, MVT::v4f64, { 5, 7, 3, 10 } }, // MAXPD + CMPUNORDPD + BLENDVPD
4706 { ISD::FSQRT, MVT::f32, { 21, 21, 1, 1 } }, // vsqrtss
4707 { ISD::FSQRT, MVT::v4f32, { 21, 21, 1, 1 } }, // vsqrtps
4708 { ISD::FSQRT, MVT::v8f32, { 42, 42, 1, 3 } }, // vsqrtps
4709 { ISD::FSQRT, MVT::f64, { 27, 27, 1, 1 } }, // vsqrtsd
4710 { ISD::FSQRT, MVT::v2f64, { 27, 27, 1, 1 } }, // vsqrtpd
4711 { ISD::FSQRT, MVT::v4f64, { 54, 54, 1, 3 } }, // vsqrtpd
4712 };
4713 static const CostKindTblEntry GFNICostTbl[] = {
4714 { ISD::BITREVERSE, MVT::i8, { 3, 3, 3, 4 } }, // gf2p8affineqb
4715 { ISD::BITREVERSE, MVT::i16, { 3, 3, 4, 6 } }, // gf2p8affineqb
4716 { ISD::BITREVERSE, MVT::i32, { 3, 3, 4, 5 } }, // gf2p8affineqb
4717 { ISD::BITREVERSE, MVT::i64, { 3, 3, 4, 6 } }, // gf2p8affineqb
4718 { ISD::BITREVERSE, MVT::v16i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
4719 { ISD::BITREVERSE, MVT::v32i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
4720 { ISD::BITREVERSE, MVT::v64i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
4721 { ISD::BITREVERSE, MVT::v8i16, { 1, 8, 2, 4 } }, // gf2p8affineqb
4722 { ISD::BITREVERSE, MVT::v16i16, { 1, 9, 2, 4 } }, // gf2p8affineqb
4723 { ISD::BITREVERSE, MVT::v32i16, { 1, 9, 2, 4 } }, // gf2p8affineqb
4724 { ISD::BITREVERSE, MVT::v4i32, { 1, 8, 2, 4 } }, // gf2p8affineqb
4725 { ISD::BITREVERSE, MVT::v8i32, { 1, 9, 2, 4 } }, // gf2p8affineqb
4726 { ISD::BITREVERSE, MVT::v16i32, { 1, 9, 2, 4 } }, // gf2p8affineqb
4727 { ISD::BITREVERSE, MVT::v2i64, { 1, 8, 2, 4 } }, // gf2p8affineqb
4728 { ISD::BITREVERSE, MVT::v4i64, { 1, 9, 2, 4 } }, // gf2p8affineqb
4729 { ISD::BITREVERSE, MVT::v8i64, { 1, 9, 2, 4 } }, // gf2p8affineqb
4730 { X86ISD::VROTLI, MVT::v16i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
4731 { X86ISD::VROTLI, MVT::v32i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
4732 { X86ISD::VROTLI, MVT::v64i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
4733 };
4734 static const CostKindTblEntry GLMCostTbl[] = {
4735 { ISD::FSQRT, MVT::f32, { 19, 20, 1, 1 } }, // sqrtss
4736 { ISD::FSQRT, MVT::v4f32, { 37, 41, 1, 5 } }, // sqrtps
4737 { ISD::FSQRT, MVT::f64, { 34, 35, 1, 1 } }, // sqrtsd
4738 { ISD::FSQRT, MVT::v2f64, { 67, 71, 1, 5 } }, // sqrtpd
4739 };
4740 static const CostKindTblEntry SLMCostTbl[] = {
4741 { ISD::BSWAP, MVT::v2i64, { 5, 5, 1, 5 } },
4742 { ISD::BSWAP, MVT::v4i32, { 5, 5, 1, 5 } },
4743 { ISD::BSWAP, MVT::v8i16, { 5, 5, 1, 5 } },
4744 { ISD::FSQRT, MVT::f32, { 20, 20, 1, 1 } }, // sqrtss
4745 { ISD::FSQRT, MVT::v4f32, { 40, 41, 1, 5 } }, // sqrtps
4746 { ISD::FSQRT, MVT::f64, { 35, 35, 1, 1 } }, // sqrtsd
4747 { ISD::FSQRT, MVT::v2f64, { 70, 71, 1, 5 } }, // sqrtpd
4748 };
4749 static const CostKindTblEntry SSE42CostTbl[] = {
4750 { ISD::FMAXNUM, MVT::f32, { 5, 5, 7, 7 } }, // MAXSS + CMPUNORDSS + BLENDVPS
4751 { ISD::FMAXNUM, MVT::v4f32, { 4, 4, 4, 5 } }, // MAXPS + CMPUNORDPS + BLENDVPS
4752 { ISD::FMAXNUM, MVT::f64, { 5, 5, 7, 7 } }, // MAXSD + CMPUNORDSD + BLENDVPD
4753 { ISD::FMAXNUM, MVT::v2f64, { 4, 4, 4, 5 } }, // MAXPD + CMPUNORDPD + BLENDVPD
4754 { ISD::FSQRT, MVT::f32, { 18, 18, 1, 1 } }, // Nehalem from http://www.agner.org/
4755 { ISD::FSQRT, MVT::v4f32, { 18, 18, 1, 1 } }, // Nehalem from http://www.agner.org/
4756 };
4757 static const CostKindTblEntry SSE41CostTbl[] = {
4758 { ISD::ABS, MVT::v2i64, { 3, 4, 3, 5 } }, // BLENDVPD(X,PSUBQ(0,X),X)
4759 { ISD::MULHS, MVT::v4i32, { 3, 9, 6, 7 } },
4760 { ISD::MULHU, MVT::v4i32, { 3, 9, 6, 7 } },
4761 { ISD::SADDSAT, MVT::v2i64, { 10, 14, 17, 21 } },
4762 { ISD::SADDSAT, MVT::v4i32, { 5, 11, 8, 10 } },
4763 { ISD::SSUBSAT, MVT::v2i64, { 12, 19, 25, 29 } },
4764 { ISD::SSUBSAT, MVT::v4i32, { 6, 14, 10, 12 } },
4765 { ISD::SMAX, MVT::v2i64, { 3, 7, 2, 3 } },
4766 { ISD::SMAX, MVT::v4i32, { 1, 1, 1, 1 } },
4767 { ISD::SMAX, MVT::v16i8, { 1, 1, 1, 1 } },
4768 { ISD::SMIN, MVT::v2i64, { 3, 7, 2, 3 } },
4769 { ISD::SMIN, MVT::v4i32, { 1, 1, 1, 1 } },
4770 { ISD::SMIN, MVT::v16i8, { 1, 1, 1, 1 } },
4771 { ISD::SMULO, MVT::v2i64, { 9, 11, 13, 17 } },
4772 { ISD::SMULO, MVT::v4i32, { 20, 24, 13, 19 } },
4773 { ISD::SMULO, MVT::v8i16, { 5, 9, 8, 8 } },
4774 { ISD::SMULO, MVT::v16i8, { 13, 22, 24, 25 } },
4775 { ISD::UADDSAT, MVT::v2i64, { 6, 13, 14, 14 } },
4776 { ISD::UADDSAT, MVT::v4i32, { 2, 2, 4, 4 } },
4777 { ISD::USUBSAT, MVT::v2i64, { 6, 10, 14, 14 } },
4778 { ISD::USUBSAT, MVT::v4i32, { 1, 2, 2, 2 } },
4779 { ISD::UMAX, MVT::v2i64, { 2, 11, 6, 7 } },
4780 { ISD::UMAX, MVT::v4i32, { 1, 1, 1, 1 } },
4781 { ISD::UMAX, MVT::v8i16, { 1, 1, 1, 1 } },
4782 { ISD::UMIN, MVT::v2i64, { 2, 11, 6, 7 } },
4783 { ISD::UMIN, MVT::v4i32, { 1, 1, 1, 1 } },
4784 { ISD::UMIN, MVT::v8i16, { 1, 1, 1, 1 } },
4785 { ISD::UMULO, MVT::v2i64, { 14, 20, 15, 20 } },
4786 { ISD::UMULO, MVT::v4i32, { 19, 22, 12, 18 } },
4787 { ISD::UMULO, MVT::v8i16, { 4, 9, 7, 7 } },
4788 { ISD::UMULO, MVT::v16i8, { 13, 19, 18, 20 } },
4789 };
4790 static const CostKindTblEntry SSSE3CostTbl[] = {
4791 { ISD::ABS, MVT::v4i32, { 1, 2, 1, 1 } },
4792 { ISD::ABS, MVT::v8i16, { 1, 2, 1, 1 } },
4793 { ISD::ABS, MVT::v16i8, { 1, 2, 1, 1 } },
4794 { ISD::BITREVERSE, MVT::v2i64, { 16, 20, 11, 21 } },
4795 { ISD::BITREVERSE, MVT::v4i32, { 16, 20, 11, 21 } },
4796 { ISD::BITREVERSE, MVT::v8i16, { 16, 20, 11, 21 } },
4797 { ISD::BITREVERSE, MVT::v16i8, { 11, 12, 10, 16 } },
4798 { ISD::BSWAP, MVT::v2i64, { 2, 3, 1, 5 } },
4799 { ISD::BSWAP, MVT::v4i32, { 2, 3, 1, 5 } },
4800 { ISD::BSWAP, MVT::v8i16, { 2, 3, 1, 5 } },
4801 { ISD::CTLZ, MVT::v2i64, { 18, 28, 28, 35 } },
4802 { ISD::CTLZ, MVT::v4i32, { 15, 20, 22, 28 } },
4803 { ISD::CTLZ, MVT::v8i16, { 13, 17, 16, 22 } },
4804 { ISD::CTLZ, MVT::v16i8, { 11, 15, 10, 16 } },
4805 { ISD::CTPOP, MVT::v2i64, { 13, 19, 12, 18 } },
4806 { ISD::CTPOP, MVT::v4i32, { 18, 24, 16, 22 } },
4807 { ISD::CTPOP, MVT::v8i16, { 13, 18, 14, 20 } },
4808 { ISD::CTPOP, MVT::v16i8, { 11, 12, 10, 16 } },
4809 { ISD::CTTZ, MVT::v2i64, { 13, 25, 15, 22 } },
4810 { ISD::CTTZ, MVT::v4i32, { 18, 26, 19, 25 } },
4811 { ISD::CTTZ, MVT::v8i16, { 13, 20, 17, 23 } },
4812 { ISD::CTTZ, MVT::v16i8, { 11, 16, 13, 19 } }
4813 };
4814 static const CostKindTblEntry SSE2CostTbl[] = {
4815 { ISD::ABS, MVT::v2i64, { 3, 6, 5, 5 } },
4816 { ISD::ABS, MVT::v4i32, { 1, 4, 4, 4 } },
4817 { ISD::ABS, MVT::v8i16, { 1, 2, 3, 3 } },
4818 { ISD::ABS, MVT::v16i8, { 1, 2, 3, 3 } },
4819 { ISD::BITREVERSE, MVT::v2i64, { 16, 20, 32, 32 } },
4820 { ISD::BITREVERSE, MVT::v4i32, { 16, 20, 30, 30 } },
4821 { ISD::BITREVERSE, MVT::v8i16, { 16, 20, 25, 25 } },
4822 { ISD::BITREVERSE, MVT::v16i8, { 11, 12, 21, 21 } },
4823 { ISD::BSWAP, MVT::v2i64, { 5, 6, 11, 11 } },
4824 { ISD::BSWAP, MVT::v4i32, { 5, 5, 9, 9 } },
4825 { ISD::BSWAP, MVT::v8i16, { 5, 5, 4, 5 } },
4826 { ISD::CTLZ, MVT::v2i64, { 10, 45, 36, 38 } },
4827 { ISD::CTLZ, MVT::v4i32, { 10, 45, 38, 40 } },
4828 { ISD::CTLZ, MVT::v8i16, { 9, 38, 32, 34 } },
4829 { ISD::CTLZ, MVT::v16i8, { 8, 39, 29, 32 } },
4830 { ISD::CTPOP, MVT::v2i64, { 12, 26, 16, 18 } },
4831 { ISD::CTPOP, MVT::v4i32, { 15, 29, 21, 23 } },
4832 { ISD::CTPOP, MVT::v8i16, { 13, 25, 18, 20 } },
4833 { ISD::CTPOP, MVT::v16i8, { 10, 21, 14, 16 } },
4834 { ISD::CTTZ, MVT::v2i64, { 14, 28, 19, 21 } },
4835 { ISD::CTTZ, MVT::v4i32, { 18, 31, 24, 26 } },
4836 { ISD::CTTZ, MVT::v8i16, { 16, 27, 21, 23 } },
4837 { ISD::CTTZ, MVT::v16i8, { 13, 23, 17, 19 } },
4838 { ISD::MULHS, MVT::v4i32, { 5, 11, 15, 15 } },
4839 { ISD::MULHS, MVT::v8i16, { 1, 5, 1, 1 } },
4840 { ISD::MULHU, MVT::v4i32, { 3, 9, 7, 7 } },
4841 { ISD::MULHU, MVT::v8i16, { 1, 5, 1, 1 } },
4842 { ISD::SADDSAT, MVT::v2i64, { 12, 14, 24, 24 } },
4843 { ISD::SADDSAT, MVT::v4i32, { 6, 11, 11, 12 } },
4844 { ISD::SADDSAT, MVT::v8i16, { 1, 2, 1, 1 } },
4845 { ISD::SADDSAT, MVT::v16i8, { 1, 2, 1, 1 } },
4846 { ISD::SMAX, MVT::v2i64, { 4, 8, 15, 15 } },
4847 { ISD::SMAX, MVT::v4i32, { 2, 4, 5, 5 } },
4848 { ISD::SMAX, MVT::v8i16, { 1, 1, 1, 1 } },
4849 { ISD::SMAX, MVT::v16i8, { 2, 4, 5, 5 } },
4850 { ISD::SMIN, MVT::v2i64, { 4, 8, 15, 15 } },
4851 { ISD::SMIN, MVT::v4i32, { 2, 4, 5, 5 } },
4852 { ISD::SMIN, MVT::v8i16, { 1, 1, 1, 1 } },
4853 { ISD::SMIN, MVT::v16i8, { 2, 4, 5, 5 } },
4854 { ISD::SMULO, MVT::v2i64, { 30, 33, 13, 23 } },
4855 { ISD::SMULO, MVT::v4i32, { 20, 24, 23, 23 } },
4856 { ISD::SMULO, MVT::v8i16, { 5, 10, 8, 8 } },
4857 { ISD::SMULO, MVT::v16i8, { 13, 23, 24, 25 } },
4858 { ISD::SSUBSAT, MVT::v2i64, { 16, 19, 31, 31 } },
4859 { ISD::SSUBSAT, MVT::v4i32, { 6, 14, 12, 13 } },
4860 { ISD::SSUBSAT, MVT::v8i16, { 1, 2, 1, 1 } },
4861 { ISD::SSUBSAT, MVT::v16i8, { 1, 2, 1, 1 } },
4862 { ISD::UADDSAT, MVT::v2i64, { 7, 13, 14, 14 } },
4863 { ISD::UADDSAT, MVT::v4i32, { 4, 5, 7, 7 } },
4864 { ISD::UADDSAT, MVT::v8i16, { 1, 2, 1, 1 } },
4865 { ISD::UADDSAT, MVT::v16i8, { 1, 2, 1, 1 } },
4866 { ISD::UMAX, MVT::v2i64, { 4, 8, 15, 15 } },
4867 { ISD::UMAX, MVT::v4i32, { 2, 5, 8, 8 } },
4868 { ISD::UMAX, MVT::v8i16, { 1, 3, 3, 3 } },
4869 { ISD::UMAX, MVT::v16i8, { 1, 1, 1, 1 } },
4870 { ISD::UMIN, MVT::v2i64, { 4, 8, 15, 15 } },
4871 { ISD::UMIN, MVT::v4i32, { 2, 5, 8, 8 } },
4872 { ISD::UMIN, MVT::v8i16, { 1, 3, 3, 3 } },
4873 { ISD::UMIN, MVT::v16i8, { 1, 1, 1, 1 } },
4874 { ISD::UMULO, MVT::v2i64, { 30, 33, 15, 29 } },
4875 { ISD::UMULO, MVT::v4i32, { 19, 22, 14, 18 } },
4876 { ISD::UMULO, MVT::v8i16, { 4, 9, 7, 7 } },
4877 { ISD::UMULO, MVT::v16i8, { 13, 19, 20, 20 } },
4878 { ISD::USUBSAT, MVT::v2i64, { 7, 10, 14, 14 } },
4879 { ISD::USUBSAT, MVT::v4i32, { 4, 4, 7, 7 } },
4880 { ISD::USUBSAT, MVT::v8i16, { 1, 2, 1, 1 } },
4881 { ISD::USUBSAT, MVT::v16i8, { 1, 2, 1, 1 } },
4882 { ISD::FMAXNUM, MVT::f64, { 5, 5, 7, 7 } },
4883 { ISD::FMAXNUM, MVT::v2f64, { 4, 6, 6, 6 } },
4884 { ISD::FSQRT, MVT::f64, { 32, 32, 1, 1 } }, // Nehalem from http://www.agner.org/
4885 { ISD::FSQRT, MVT::v2f64, { 32, 32, 1, 1 } }, // Nehalem from http://www.agner.org/
4886 };
4887 static const CostKindTblEntry SSE1CostTbl[] = {
4888 { ISD::FMAXNUM, MVT::f32, { 5, 5, 7, 7 } },
4889 { ISD::FMAXNUM, MVT::v4f32, { 4, 6, 6, 6 } },
4890 { ISD::FSQRT, MVT::f32, { 28, 30, 1, 2 } }, // Pentium III from http://www.agner.org/
4891 { ISD::FSQRT, MVT::v4f32, { 56, 56, 1, 2 } }, // Pentium III from http://www.agner.org/
4892 };
4893 static const CostKindTblEntry BMI64CostTbl[] = { // 64-bit targets
4894 { ISD::CTTZ, MVT::i64, { 1, 1, 1, 1 } },
4895 };
4896 static const CostKindTblEntry BMI32CostTbl[] = { // 32 or 64-bit targets
4897 { ISD::CTTZ, MVT::i32, { 1, 1, 1, 1 } },
4898 { ISD::CTTZ, MVT::i16, { 2, 1, 1, 1 } },
4899 { ISD::CTTZ, MVT::i8, { 2, 1, 1, 1 } },
4900 };
4901 static const CostKindTblEntry LZCNT64CostTbl[] = { // 64-bit targets
4902 { ISD::CTLZ, MVT::i64, { 1, 1, 1, 1 } },
4903 };
4904 static const CostKindTblEntry LZCNT32CostTbl[] = { // 32 or 64-bit targets
4905 { ISD::CTLZ, MVT::i32, { 1, 1, 1, 1 } },
4906 { ISD::CTLZ, MVT::i16, { 2, 1, 1, 1 } },
4907 { ISD::CTLZ, MVT::i8, { 2, 1, 1, 1 } },
4908 };
4909 static const CostKindTblEntry POPCNT64CostTbl[] = { // 64-bit targets
4910 { ISD::CTPOP, MVT::i64, { 1, 1, 1, 1 } }, // popcnt
4911 };
4912 static const CostKindTblEntry POPCNT32CostTbl[] = { // 32 or 64-bit targets
4913 { ISD::CTPOP, MVT::i32, { 1, 1, 1, 1 } }, // popcnt
4914 { ISD::CTPOP, MVT::i16, { 1, 1, 2, 2 } }, // popcnt(zext())
4915 { ISD::CTPOP, MVT::i8, { 1, 1, 2, 2 } }, // popcnt(zext())
4916 };
4917 static const CostKindTblEntry PCLMULCostTbl[] = {
4918 { ISD::CLMUL, MVT::v2i64, { 3, 12, 4, 8 } }, // MOV+2xPCLMUL+unpack
4919 { ISD::CLMUL, MVT::v4i32, { 8, 18, 12, 16 } }, // MOV+4xPCLMUL+unpack
4920 { ISD::CLMUL, MVT::i64, { 3, 12, 4, 8 } }, // MOV+PCLMUL+MOV
4921 { ISD::CLMUL, MVT::i32, { 3, 12, 4, 8 } }, // MOV+PCLMUL+MOV
4922 { ISD::CLMUL, MVT::i16, { 3, 12, 4, 8 } }, // MOV+PCLMUL+MOV
4923 { ISD::CLMUL, MVT::i8, { 3, 12, 4, 8 } }, // MOV+PCLMUL+MOV
4924 };
4925 static const CostKindTblEntry X64CostTbl[] = { // 64-bit targets
4926 { ISD::ABS, MVT::i64, { 1, 2, 3, 3 } }, // SUB+CMOV
4927 { ISD::BITREVERSE, MVT::i64, { 10, 12, 20, 22 } },
4928 { ISD::BSWAP, MVT::i64, { 1, 2, 1, 2 } },
4929 { ISD::CTLZ, MVT::i64, { 1, 2, 3, 3 } }, // MOV+BSR+XOR
4930 { ISD::CTLZ, MVT::i32, { 1, 2, 3, 3 } }, // MOV+BSR+XOR
4931 { ISD::CTLZ, MVT::i16, { 2, 2, 3, 3 } }, // MOV+BSR+XOR
4932 { ISD::CTLZ, MVT::i8, { 2, 2, 4, 3 } }, // MOV+BSR+XOR
4933 { ISD::CTLZ_ZERO_POISON,MVT::i64,{ 1, 2, 2, 2 } }, // BSR+XOR
4934 { ISD::CTTZ, MVT::i64, { 1, 2, 2, 2 } }, // MOV+BSF
4935 { ISD::CTTZ, MVT::i32, { 1, 2, 2, 2 } }, // MOV+BSF
4936 { ISD::CTTZ, MVT::i16, { 2, 2, 2, 2 } }, // MOV+BSF
4937 { ISD::CTTZ, MVT::i8, { 2, 2, 2, 2 } }, // MOV+BSF
4938 { ISD::CTTZ_ZERO_POISON,MVT::i64,{ 1, 2, 1, 2 } }, // BSF
4939 { ISD::CTPOP, MVT::i64, { 10, 6, 19, 19 } },
4940 { ISD::ROTL, MVT::i64, { 2, 3, 1, 3 } },
4941 { ISD::ROTR, MVT::i64, { 2, 3, 1, 3 } },
4942 { X86ISD::VROTLI, MVT::i64, { 1, 1, 1, 1 } },
4943 { ISD::FSHL, MVT::i64, { 4, 4, 1, 4 } },
4944 { ISD::SADDSAT, MVT::i64, { 4, 4, 7, 10 } },
4945 { ISD::SSUBSAT, MVT::i64, { 4, 5, 8, 11 } },
4946 { ISD::UADDSAT, MVT::i64, { 2, 3, 4, 7 } },
4947 { ISD::USUBSAT, MVT::i64, { 2, 3, 4, 7 } },
4948 { ISD::SMAX, MVT::i64, { 1, 3, 2, 3 } },
4949 { ISD::SMIN, MVT::i64, { 1, 3, 2, 3 } },
4950 { ISD::UMAX, MVT::i64, { 1, 3, 2, 3 } },
4951 { ISD::UMIN, MVT::i64, { 1, 3, 2, 3 } },
4952 { ISD::SADDO, MVT::i64, { 2, 2, 4, 6 } },
4953 { ISD::UADDO, MVT::i64, { 2, 2, 4, 6 } },
4954 { ISD::SMULO, MVT::i64, { 4, 4, 4, 6 } },
4955 { ISD::UMULO, MVT::i64, { 8, 8, 4, 7 } },
4956 };
4957 static const CostKindTblEntry X86CostTbl[] = { // 32 or 64-bit targets
4958 { ISD::ABS, MVT::i32, { 1, 2, 3, 3 } }, // SUB+XOR+SRA or SUB+CMOV
4959 { ISD::ABS, MVT::i16, { 2, 2, 3, 3 } }, // SUB+XOR+SRA or SUB+CMOV
4960 { ISD::ABS, MVT::i8, { 2, 4, 4, 3 } }, // SUB+XOR+SRA
4961 { ISD::BITREVERSE, MVT::i32, { 9, 12, 17, 19 } },
4962 { ISD::BITREVERSE, MVT::i16, { 9, 12, 17, 19 } },
4963 { ISD::BITREVERSE, MVT::i8, { 7, 9, 13, 14 } },
4964 { ISD::BSWAP, MVT::i32, { 1, 1, 1, 1 } },
4965 { ISD::BSWAP, MVT::i16, { 1, 2, 1, 2 } }, // ROL
4966 { ISD::CTLZ, MVT::i32, { 2, 2, 4, 5 } }, // BSR+XOR or BSR+XOR+CMOV
4967 { ISD::CTLZ, MVT::i16, { 2, 2, 4, 5 } }, // BSR+XOR or BSR+XOR+CMOV
4968 { ISD::CTLZ, MVT::i8, { 2, 2, 5, 6 } }, // BSR+XOR or BSR+XOR+CMOV
4969 { ISD::CTLZ_ZERO_POISON,MVT::i32,{ 1, 2, 2, 2 } }, // BSR+XOR
4970 { ISD::CTLZ_ZERO_POISON,MVT::i16,{ 2, 2, 2, 2 } }, // BSR+XOR
4971 { ISD::CTLZ_ZERO_POISON,MVT::i8, { 2, 2, 3, 3 } }, // BSR+XOR
4972 { ISD::CTTZ, MVT::i32, { 2, 2, 3, 3 } }, // TEST+BSF+CMOV/BRANCH
4973 { ISD::CTTZ, MVT::i16, { 2, 2, 2, 3 } }, // TEST+BSF+CMOV/BRANCH
4974 { ISD::CTTZ, MVT::i8, { 2, 2, 2, 3 } }, // TEST+BSF+CMOV/BRANCH
4975 { ISD::CTTZ_ZERO_POISON,MVT::i32,{ 1, 2, 1, 2 } }, // BSF
4976 { ISD::CTTZ_ZERO_POISON,MVT::i16,{ 2, 2, 1, 2 } }, // BSF
4977 { ISD::CTTZ_ZERO_POISON,MVT::i8, { 2, 2, 1, 2 } }, // BSF
4978 { ISD::CTPOP, MVT::i32, { 8, 7, 15, 15 } },
4979 { ISD::CTPOP, MVT::i16, { 9, 8, 17, 17 } },
4980 { ISD::CTPOP, MVT::i8, { 7, 6, 6, 6 } },
4981 { ISD::ROTL, MVT::i32, { 2, 3, 1, 3 } },
4982 { ISD::ROTL, MVT::i16, { 2, 3, 1, 3 } },
4983 { ISD::ROTL, MVT::i8, { 2, 3, 1, 3 } },
4984 { ISD::ROTR, MVT::i32, { 2, 3, 1, 3 } },
4985 { ISD::ROTR, MVT::i16, { 2, 3, 1, 3 } },
4986 { ISD::ROTR, MVT::i8, { 2, 3, 1, 3 } },
4987 { X86ISD::VROTLI, MVT::i32, { 1, 1, 1, 1 } },
4988 { X86ISD::VROTLI, MVT::i16, { 1, 1, 1, 1 } },
4989 { X86ISD::VROTLI, MVT::i8, { 1, 1, 1, 1 } },
4990 { ISD::FSHL, MVT::i32, { 4, 4, 1, 4 } },
4991 { ISD::FSHL, MVT::i16, { 4, 4, 2, 5 } },
4992 { ISD::FSHL, MVT::i8, { 4, 4, 2, 5 } },
4993 { ISD::SADDSAT, MVT::i32, { 3, 4, 6, 9 } },
4994 { ISD::SADDSAT, MVT::i16, { 4, 4, 7, 10 } },
4995 { ISD::SADDSAT, MVT::i8, { 4, 5, 8, 11 } },
4996 { ISD::SSUBSAT, MVT::i32, { 4, 4, 7, 10 } },
4997 { ISD::SSUBSAT, MVT::i16, { 4, 4, 7, 10 } },
4998 { ISD::SSUBSAT, MVT::i8, { 4, 5, 8, 11 } },
4999 { ISD::UADDSAT, MVT::i32, { 2, 3, 4, 7 } },
5000 { ISD::UADDSAT, MVT::i16, { 2, 3, 4, 7 } },
5001 { ISD::UADDSAT, MVT::i8, { 3, 3, 5, 8 } },
5002 { ISD::USUBSAT, MVT::i32, { 2, 3, 4, 7 } },
5003 { ISD::USUBSAT, MVT::i16, { 2, 3, 4, 7 } },
5004 { ISD::USUBSAT, MVT::i8, { 3, 3, 5, 8 } },
5005 { ISD::SMAX, MVT::i32, { 1, 2, 2, 3 } },
5006 { ISD::SMAX, MVT::i16, { 1, 4, 2, 4 } },
5007 { ISD::SMAX, MVT::i8, { 1, 4, 2, 4 } },
5008 { ISD::SMIN, MVT::i32, { 1, 2, 2, 3 } },
5009 { ISD::SMIN, MVT::i16, { 1, 4, 2, 4 } },
5010 { ISD::SMIN, MVT::i8, { 1, 4, 2, 4 } },
5011 { ISD::UMAX, MVT::i32, { 1, 2, 2, 3 } },
5012 { ISD::UMAX, MVT::i16, { 1, 4, 2, 4 } },
5013 { ISD::UMAX, MVT::i8, { 1, 4, 2, 4 } },
5014 { ISD::UMIN, MVT::i32, { 1, 2, 2, 3 } },
5015 { ISD::UMIN, MVT::i16, { 1, 4, 2, 4 } },
5016 { ISD::UMIN, MVT::i8, { 1, 4, 2, 4 } },
5017 { ISD::SADDO, MVT::i32, { 2, 2, 4, 6 } },
5018 { ISD::SADDO, MVT::i16, { 2, 2, 4, 6 } },
5019 { ISD::SADDO, MVT::i8, { 2, 2, 4, 6 } },
5020 { ISD::UADDO, MVT::i32, { 2, 2, 4, 6 } },
5021 { ISD::UADDO, MVT::i16, { 2, 2, 4, 6 } },
5022 { ISD::UADDO, MVT::i8, { 2, 2, 4, 6 } },
5023 { ISD::SMULO, MVT::i32, { 2, 2, 4, 6 } },
5024 { ISD::SMULO, MVT::i16, { 5, 5, 4, 6 } },
5025 { ISD::SMULO, MVT::i8, { 6, 6, 4, 6 } },
5026 { ISD::UMULO, MVT::i32, { 6, 6, 4, 8 } },
5027 { ISD::UMULO, MVT::i16, { 6, 6, 4, 9 } },
5028 { ISD::UMULO, MVT::i8, { 6, 6, 4, 6 } },
5029 };
5030
5031 Type *RetTy = ICA.getReturnType();
5032 Type *OpTy = RetTy;
5033 Intrinsic::ID IID = ICA.getID();
5034 unsigned ISD = ISD::DELETED_NODE;
5035 switch (IID) {
5036 default:
5037 break;
5038 case Intrinsic::abs:
5039 ISD = ISD::ABS;
5040 break;
5041 case Intrinsic::bitreverse:
5043 break;
5044 case Intrinsic::bswap:
5045 ISD = ISD::BSWAP;
5046 break;
5047 case Intrinsic::ctlz:
5048 ISD = ISD::CTLZ;
5049 break;
5050 case Intrinsic::ctpop:
5051 ISD = ISD::CTPOP;
5052 break;
5053 case Intrinsic::cttz:
5054 ISD = ISD::CTTZ;
5055 break;
5056 case Intrinsic::fshl:
5057 ISD = ISD::FSHL;
5058 if (!ICA.isTypeBasedOnly()) {
5059 const SmallVectorImpl<const Value *> &Args = ICA.getArgs();
5060 if (Args[0] == Args[1]) {
5061 ISD = ISD::ROTL;
5062 // Handle uniform constant rotation amounts.
5063 // TODO: Handle funnel-shift cases.
5064 const APInt *Amt;
5065 if (Args[2] &&
5067 ISD = X86ISD::VROTLI;
5068 }
5069 }
5070 break;
5071 case Intrinsic::fshr:
5072 // FSHR has same costs so don't duplicate.
5073 ISD = ISD::FSHL;
5074 if (!ICA.isTypeBasedOnly()) {
5075 const SmallVectorImpl<const Value *> &Args = ICA.getArgs();
5076 if (Args[0] == Args[1]) {
5077 ISD = ISD::ROTR;
5078 // Handle uniform constant rotation amount.
5079 // TODO: Handle funnel-shift cases.
5080 const APInt *Amt;
5081 if (Args[2] &&
5083 ISD = X86ISD::VROTLI;
5084 }
5085 }
5086 break;
5087 case Intrinsic::lrint:
5088 case Intrinsic::llrint: {
5089 // X86 can use the CVTP2SI instructions to lower lrint/llrint calls, which
5090 // have the same costs as the CVTTP2SI (fptosi) instructions
5091 const SmallVectorImpl<Type *> &ArgTys = ICA.getArgTypes();
5092 return getCastInstrCost(Instruction::FPToSI, RetTy, ArgTys[0],
5094 }
5095 case Intrinsic::maxnum:
5096 case Intrinsic::minnum:
5097 // FMINNUM has same costs so don't duplicate.
5098 ISD = ISD::FMAXNUM;
5099 break;
5100 case Intrinsic::sadd_sat:
5101 ISD = ISD::SADDSAT;
5102 break;
5103 case Intrinsic::smax:
5104 ISD = ISD::SMAX;
5105 break;
5106 case Intrinsic::smin:
5107 ISD = ISD::SMIN;
5108 break;
5109 case Intrinsic::smulh:
5110 ISD = ISD::MULHS;
5111 break;
5112 case Intrinsic::ssub_sat:
5113 ISD = ISD::SSUBSAT;
5114 break;
5115 case Intrinsic::uadd_sat:
5116 ISD = ISD::UADDSAT;
5117 break;
5118 case Intrinsic::umax:
5119 ISD = ISD::UMAX;
5120 break;
5121 case Intrinsic::umin:
5122 ISD = ISD::UMIN;
5123 break;
5124 case Intrinsic::usub_sat:
5125 ISD = ISD::USUBSAT;
5126 break;
5127 case Intrinsic::umulh:
5128 ISD = ISD::MULHU;
5129 break;
5130 case Intrinsic::sqrt:
5131 ISD = ISD::FSQRT;
5132 break;
5133 case Intrinsic::sadd_with_overflow:
5134 case Intrinsic::ssub_with_overflow:
5135 // SSUBO has same costs so don't duplicate.
5136 ISD = ISD::SADDO;
5137 OpTy = RetTy->getContainedType(0);
5138 break;
5139 case Intrinsic::uadd_with_overflow:
5140 case Intrinsic::usub_with_overflow:
5141 // USUBO has same costs so don't duplicate.
5142 ISD = ISD::UADDO;
5143 OpTy = RetTy->getContainedType(0);
5144 break;
5145 case Intrinsic::smul_with_overflow:
5146 ISD = ISD::SMULO;
5147 OpTy = RetTy->getContainedType(0);
5148 break;
5149 case Intrinsic::umul_with_overflow:
5150 ISD = ISD::UMULO;
5151 OpTy = RetTy->getContainedType(0);
5152 break;
5153 case Intrinsic::clmul:
5154 ISD = ISD::CLMUL;
5155 break;
5156 }
5157
5158 if (ISD != ISD::DELETED_NODE) {
5159 auto adjustTableCost = [&](int ISD, unsigned Cost,
5160 std::pair<InstructionCost, MVT> LT,
5162 InstructionCost LegalizationCost = LT.first;
5163 MVT MTy = LT.second;
5164
5165 // If there are no NANs to deal with, then these are reduced to a
5166 // single MIN** or MAX** instruction instead of the MIN/CMP/SELECT that we
5167 // assume is used in the non-fast case.
5168 if (ISD == ISD::FMAXNUM || ISD == ISD::FMINNUM) {
5169 if (FMF.noNaNs())
5170 return LegalizationCost * 1;
5171 }
5172
5173 // For cases where some ops can be folded into a load/store, assume free.
5174 if (MTy.isScalarInteger()) {
5175 if (ISD == ISD::BSWAP && ST->hasMOVBE() && ST->hasFastMOVBE()) {
5176 if (const Instruction *II = ICA.getInst()) {
5177 if (II->hasOneUse() && isa<StoreInst>(II->user_back()))
5178 return TTI::TCC_Free;
5179 if (auto *LI = dyn_cast<LoadInst>(II->getOperand(0))) {
5180 if (LI->hasOneUse())
5181 return TTI::TCC_Free;
5182 }
5183 }
5184 }
5185 }
5186
5187 return LegalizationCost * (int)Cost;
5188 };
5189
5190 // Legalize the type.
5191 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(OpTy);
5192 MVT MTy = LT.second;
5193
5194 // Without BMI/LZCNT see if we're only looking for a *_ZERO_POISON cost.
5195 if (((ISD == ISD::CTTZ && !ST->hasBMI()) ||
5196 (ISD == ISD::CTLZ && !ST->hasLZCNT())) &&
5197 !MTy.isVector() && !ICA.isTypeBasedOnly()) {
5198 const SmallVectorImpl<const Value *> &Args = ICA.getArgs();
5199 if (auto *Cst = dyn_cast<ConstantInt>(Args[1]))
5200 if (Cst->isAllOnesValue())
5201 ISD =
5203 }
5204
5205 // FSQRT is a single instruction.
5207 return LT.first;
5208
5209 if (ST->useGLMDivSqrtCosts())
5210 if (const auto *Entry = CostTableLookup(GLMCostTbl, ISD, MTy))
5211 if (auto KindCost = Entry->Cost[CostKind])
5212 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5213
5214 if (ST->useSLMArithCosts())
5215 if (const auto *Entry = CostTableLookup(SLMCostTbl, ISD, MTy))
5216 if (auto KindCost = Entry->Cost[CostKind])
5217 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5218
5219 if (ST->hasVBMI2())
5220 if (const auto *Entry = CostTableLookup(AVX512VBMI2CostTbl, ISD, MTy))
5221 if (auto KindCost = Entry->Cost[CostKind])
5222 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5223
5224 if (ST->hasBITALG())
5225 if (const auto *Entry = CostTableLookup(AVX512BITALGCostTbl, ISD, MTy))
5226 if (auto KindCost = Entry->Cost[CostKind])
5227 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5228
5229 if (ST->hasVPOPCNTDQ())
5230 if (const auto *Entry = CostTableLookup(AVX512VPOPCNTDQCostTbl, ISD, MTy))
5231 if (auto KindCost = Entry->Cost[CostKind])
5232 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5233
5234 if (ST->hasGFNI())
5235 if (const auto *Entry = CostTableLookup(GFNICostTbl, ISD, MTy))
5236 if (auto KindCost = Entry->Cost[CostKind])
5237 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5238
5239 if (ST->hasCDI())
5240 if (const auto *Entry = CostTableLookup(AVX512CDCostTbl, ISD, MTy))
5241 if (auto KindCost = Entry->Cost[CostKind])
5242 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5243
5244 if (ST->hasBWI())
5245 if (const auto *Entry = CostTableLookup(AVX512BWCostTbl, ISD, MTy))
5246 if (auto KindCost = Entry->Cost[CostKind])
5247 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5248
5249 if (ST->hasAVX512())
5250 if (const auto *Entry = CostTableLookup(AVX512CostTbl, ISD, MTy))
5251 if (auto KindCost = Entry->Cost[CostKind])
5252 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5253
5254 if (ST->hasXOP())
5255 if (const auto *Entry = CostTableLookup(XOPCostTbl, ISD, MTy))
5256 if (auto KindCost = Entry->Cost[CostKind])
5257 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5258
5259 if (ST->hasAVX2())
5260 if (const auto *Entry = CostTableLookup(AVX2CostTbl, ISD, MTy))
5261 if (auto KindCost = Entry->Cost[CostKind])
5262 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5263
5264 if (ST->hasAVX())
5265 if (const auto *Entry = CostTableLookup(AVX1CostTbl, ISD, MTy))
5266 if (auto KindCost = Entry->Cost[CostKind])
5267 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5268
5269 if (ST->hasSSE42())
5270 if (const auto *Entry = CostTableLookup(SSE42CostTbl, ISD, MTy))
5271 if (auto KindCost = Entry->Cost[CostKind])
5272 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5273
5274 if (ST->hasSSE41())
5275 if (const auto *Entry = CostTableLookup(SSE41CostTbl, ISD, MTy))
5276 if (auto KindCost = Entry->Cost[CostKind])
5277 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5278
5279 if (ST->hasSSSE3())
5280 if (const auto *Entry = CostTableLookup(SSSE3CostTbl, ISD, MTy))
5281 if (auto KindCost = Entry->Cost[CostKind])
5282 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5283
5284 if (ST->hasSSE2())
5285 if (const auto *Entry = CostTableLookup(SSE2CostTbl, ISD, MTy))
5286 if (auto KindCost = Entry->Cost[CostKind])
5287 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5288
5289 if (ST->hasSSE1())
5290 if (const auto *Entry = CostTableLookup(SSE1CostTbl, ISD, MTy))
5291 if (auto KindCost = Entry->Cost[CostKind])
5292 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5293
5294 if (ST->hasBMI()) {
5295 if (ST->is64Bit())
5296 if (const auto *Entry = CostTableLookup(BMI64CostTbl, ISD, MTy))
5297 if (auto KindCost = Entry->Cost[CostKind])
5298 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5299
5300 if (const auto *Entry = CostTableLookup(BMI32CostTbl, ISD, MTy))
5301 if (auto KindCost = Entry->Cost[CostKind])
5302 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5303 }
5304
5305 if (ST->hasLZCNT()) {
5306 if (ST->is64Bit())
5307 if (const auto *Entry = CostTableLookup(LZCNT64CostTbl, ISD, MTy))
5308 if (auto KindCost = Entry->Cost[CostKind])
5309 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5310
5311 if (const auto *Entry = CostTableLookup(LZCNT32CostTbl, ISD, MTy))
5312 if (auto KindCost = Entry->Cost[CostKind])
5313 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5314 }
5315
5316 if (ST->hasPOPCNT()) {
5317 if (ST->is64Bit())
5318 if (const auto *Entry = CostTableLookup(POPCNT64CostTbl, ISD, MTy))
5319 if (auto KindCost = Entry->Cost[CostKind])
5320 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5321
5322 if (const auto *Entry = CostTableLookup(POPCNT32CostTbl, ISD, MTy))
5323 if (auto KindCost = Entry->Cost[CostKind])
5324 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5325 }
5326
5327 // FIXME: PCLMUL w/ AVX/AVX512 and VPCLMULQDQ are not handled properly.
5328 if (ST->hasPCLMUL())
5329 if (const auto *Entry = CostTableLookup(PCLMULCostTbl, ISD, MTy))
5330 if (auto KindCost = Entry->Cost[CostKind])
5331 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5332
5333 if (ST->is64Bit())
5334 if (const auto *Entry = CostTableLookup(X64CostTbl, ISD, MTy))
5335 if (auto KindCost = Entry->Cost[CostKind])
5336 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5337
5338 if (const auto *Entry = CostTableLookup(X86CostTbl, ISD, MTy))
5339 if (auto KindCost = Entry->Cost[CostKind])
5340 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5341
5342 // Without arg data, we need to compute the expanded costs of custom lowered
5343 // intrinsics to prevent use of the (very low) default costs.
5344 if (ICA.isTypeBasedOnly() &&
5345 (IID == Intrinsic::fshl || IID == Intrinsic::fshr)) {
5346 Type *CondTy = RetTy->getWithNewBitWidth(1);
5348 Cost += getArithmeticInstrCost(BinaryOperator::Or, RetTy, CostKind);
5349 Cost += getArithmeticInstrCost(BinaryOperator::Sub, RetTy, CostKind);
5350 Cost += getArithmeticInstrCost(BinaryOperator::Shl, RetTy, CostKind);
5351 Cost += getArithmeticInstrCost(BinaryOperator::LShr, RetTy, CostKind);
5352 Cost += getArithmeticInstrCost(BinaryOperator::And, RetTy, CostKind);
5353 Cost += getCmpSelInstrCost(BinaryOperator::ICmp, RetTy, CondTy,
5355 Cost += getCmpSelInstrCost(BinaryOperator::Select, RetTy, CondTy,
5357 return Cost;
5358 }
5359 }
5360
5362}
5363
5365 unsigned Opcode, Type *Val, TTI::TargetCostKind CostKind, unsigned Index,
5366 const Value *Op0, const Value *Op1, TTI::VectorInstrContext VIC) const {
5367 static const CostTblEntry SLMCostTbl[] = {
5368 { ISD::EXTRACT_VECTOR_ELT, MVT::i8, 4 },
5369 { ISD::EXTRACT_VECTOR_ELT, MVT::i16, 4 },
5370 { ISD::EXTRACT_VECTOR_ELT, MVT::i32, 4 },
5371 { ISD::EXTRACT_VECTOR_ELT, MVT::i64, 7 }
5372 };
5373
5374 assert(Val->isVectorTy() && "This must be a vector type");
5375 auto *VT = cast<VectorType>(Val);
5376 if (VT->isScalableTy())
5378
5379 Type *ScalarType = Val->getScalarType();
5380 InstructionCost RegisterFileMoveCost = 0;
5381
5382 // Non-immediate extraction/insertion can be handled as a sequence of
5383 // aliased loads+stores via the stack.
5384 if (Index == -1U && (Opcode == Instruction::ExtractElement ||
5385 Opcode == Instruction::InsertElement)) {
5386 // TODO: On some SSE41+ targets, we expand to cmp+splat+select patterns:
5387 // inselt N0, N1, N2 --> select (SplatN2 == {0,1,2...}) ? SplatN1 : N0.
5388
5389 // TODO: Move this to BasicTTIImpl.h? We'd need better gep + index handling.
5390 assert(isa<FixedVectorType>(Val) && "Fixed vector type expected");
5391 Align VecAlign = DL.getPrefTypeAlign(Val);
5392 Align SclAlign = DL.getPrefTypeAlign(ScalarType);
5393
5394 // Extract - store vector to stack, load scalar.
5395 if (Opcode == Instruction::ExtractElement) {
5396 return getMemoryOpCost(Instruction::Store, Val, VecAlign, 0, CostKind) +
5397 getMemoryOpCost(Instruction::Load, ScalarType, SclAlign, 0,
5398 CostKind);
5399 }
5400 // Insert - store vector to stack, store scalar, load vector.
5401 if (Opcode == Instruction::InsertElement) {
5402 return getMemoryOpCost(Instruction::Store, Val, VecAlign, 0, CostKind) +
5403 getMemoryOpCost(Instruction::Store, ScalarType, SclAlign, 0,
5404 CostKind) +
5405 getMemoryOpCost(Instruction::Load, Val, VecAlign, 0, CostKind);
5406 }
5407 }
5408
5409 if (Index != -1U && (Opcode == Instruction::ExtractElement ||
5410 Opcode == Instruction::InsertElement)) {
5411 // Extraction of vXi1 elements are now efficiently handled by MOVMSK.
5412 if (Opcode == Instruction::ExtractElement &&
5413 ScalarType->getScalarSizeInBits() == 1 &&
5414 cast<FixedVectorType>(Val)->getNumElements() > 1)
5415 return 1;
5416
5417 // Legalize the type.
5418 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Val);
5419
5420 // This type is legalized to a scalar type.
5421 if (!LT.second.isVector())
5422 return TTI::TCC_Free;
5423
5424 // The type may be split. Normalize the index to the new type.
5425 unsigned SizeInBits = LT.second.getSizeInBits();
5426 unsigned NumElts = LT.second.getVectorNumElements();
5427 unsigned SubNumElts = NumElts;
5428 Index = Index % NumElts;
5429
5430 // For >128-bit vectors, we need to extract higher 128-bit subvectors.
5431 // For inserts, we also need to insert the subvector back.
5432 if (SizeInBits > 128) {
5433 assert((SizeInBits % 128) == 0 && "Illegal vector");
5434 unsigned NumSubVecs = SizeInBits / 128;
5435 SubNumElts = NumElts / NumSubVecs;
5436 if (SubNumElts <= Index) {
5437 RegisterFileMoveCost += (Opcode == Instruction::InsertElement ? 2 : 1);
5438 Index %= SubNumElts;
5439 }
5440 }
5441
5442 MVT MScalarTy = LT.second.getScalarType();
5443 auto IsCheapPInsrPExtrInsertPS = [&]() {
5444 // Assume pinsr/pextr XMM <-> GPR is relatively cheap on all targets.
5445 // Inserting f32 into index0 is just movss.
5446 // Also, assume insertps is relatively cheap on all >= SSE41 targets.
5447 return (MScalarTy == MVT::i16 && ST->hasSSE2()) ||
5448 (MScalarTy.isInteger() && ST->hasSSE41()) ||
5449 (MScalarTy == MVT::f32 && ST->hasSSE1() && Index == 0 &&
5450 Opcode == Instruction::InsertElement) ||
5451 (MScalarTy == MVT::f32 && ST->hasSSE41() &&
5452 Opcode == Instruction::InsertElement);
5453 };
5454
5455 if (Index == 0) {
5456 // Floating point scalars are already located in index #0.
5457 // Many insertions to #0 can fold away for scalar fp-ops, so let's assume
5458 // true for all.
5459 if (ScalarType->isFloatingPointTy() &&
5460 (Opcode != Instruction::InsertElement || !Op0 ||
5461 isa<UndefValue>(Op0)))
5462 return RegisterFileMoveCost;
5463
5464 if (Opcode == Instruction::InsertElement &&
5466 // Consider the gather cost to be cheap.
5468 return RegisterFileMoveCost;
5469 if (!IsCheapPInsrPExtrInsertPS()) {
5470 // mov constant-to-GPR + movd/movq GPR -> XMM.
5471 if (isa_and_nonnull<Constant>(Op1) && Op1->getType()->isIntegerTy())
5472 return 2 + RegisterFileMoveCost;
5473 // Assume movd/movq GPR -> XMM is relatively cheap on all targets.
5474 return 1 + RegisterFileMoveCost;
5475 }
5476 }
5477
5478 // Assume movd/movq XMM -> GPR is relatively cheap on all targets.
5479 if (ScalarType->isIntegerTy() && Opcode == Instruction::ExtractElement)
5480 return 1 + RegisterFileMoveCost;
5481 }
5482
5483 int ISD = TLI->InstructionOpcodeToISD(Opcode);
5484 assert(ISD && "Unexpected vector opcode");
5485 if (ST->useSLMArithCosts())
5486 if (auto *Entry = CostTableLookup(SLMCostTbl, ISD, MScalarTy))
5487 return Entry->Cost + RegisterFileMoveCost;
5488
5489 // Consider cheap cases.
5490 if (IsCheapPInsrPExtrInsertPS())
5491 return 1 + RegisterFileMoveCost;
5492
5493 // For extractions we just need to shuffle the element to index 0, which
5494 // should be very cheap (assume cost = 1). For insertions we need to shuffle
5495 // the elements to its destination. In both cases we must handle the
5496 // subvector move(s).
5497 // If the vector type is already less than 128-bits then don't reduce it.
5498 // TODO: Under what circumstances should we shuffle using the full width?
5499 InstructionCost ShuffleCost = 1;
5500 if (Opcode == Instruction::InsertElement) {
5501 auto *SubTy = cast<VectorType>(Val);
5502 EVT VT = TLI->getValueType(DL, Val);
5503 if (VT.getScalarType() != MScalarTy || VT.getSizeInBits() >= 128)
5504 SubTy = FixedVectorType::get(ScalarType, SubNumElts);
5505 ShuffleCost = getShuffleCost(TTI::SK_PermuteTwoSrc, SubTy, SubTy,
5506 CostKind, {}, 0, SubTy);
5507 }
5508 int IntOrFpCost = ScalarType->isFloatingPointTy() ? 0 : 1;
5509 return ShuffleCost + IntOrFpCost + RegisterFileMoveCost;
5510 }
5511
5512 return BaseT::getVectorInstrCost(Opcode, Val, CostKind, Index, Op0, Op1,
5513 VIC) +
5514 RegisterFileMoveCost;
5515}
5516
5518 VectorType *Ty, const APInt &DemandedElts, bool Insert, bool Extract,
5519 TTI::TargetCostKind CostKind, bool ForPoisonSrc, ArrayRef<Value *> VL,
5520 TTI::VectorInstrContext VIC) const {
5521 assert(DemandedElts.getBitWidth() ==
5522 cast<FixedVectorType>(Ty)->getNumElements() &&
5523 "Vector size mismatch");
5524
5525 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Ty);
5526 MVT MScalarTy = LT.second.getScalarType();
5527 unsigned LegalVectorBitWidth = LT.second.getSizeInBits();
5529
5530 constexpr unsigned LaneBitWidth = 128;
5531 assert((LegalVectorBitWidth < LaneBitWidth ||
5532 (LegalVectorBitWidth % LaneBitWidth) == 0) &&
5533 "Illegal vector");
5534
5535 const int NumLegalVectors = LT.first.getValue();
5536 assert(NumLegalVectors >= 0 && "Negative cost!");
5537
5538 // For insertions, a ISD::BUILD_VECTOR style vector initialization can be much
5539 // cheaper than an accumulation of ISD::INSERT_VECTOR_ELT. SLPVectorizer has
5540 // a special heuristic regarding poison input which is passed here in
5541 // ForPoisonSrc.
5542 if (Insert && !ForPoisonSrc) {
5543 // This is nearly identical to BaseT::getScalarizationOverhead(), except
5544 // it is passing nullptr to getVectorInstrCost() for Op0 (instead of
5545 // Constant::getNullValue()), which makes the X86TTIImpl
5546 // getVectorInstrCost() return 0 instead of 1.
5547 for (unsigned I : seq(DemandedElts.getBitWidth())) {
5548 if (!DemandedElts[I])
5549 continue;
5550 Cost += getVectorInstrCost(Instruction::InsertElement, Ty, CostKind, I,
5552 VL.empty() ? nullptr : VL[I],
5554 }
5555 return Cost;
5556 }
5557
5558 if (Insert) {
5559 if ((MScalarTy == MVT::i16 && ST->hasSSE2()) ||
5560 (MScalarTy.isInteger() && ST->hasSSE41()) ||
5561 (MScalarTy == MVT::f32 && ST->hasSSE41())) {
5562 // For types we can insert directly, insertion into 128-bit sub vectors is
5563 // cheap, followed by a cheap chain of concatenations.
5564 if (LegalVectorBitWidth <= LaneBitWidth) {
5565 Cost += BaseT::getScalarizationOverhead(Ty, DemandedElts, Insert,
5566 /*Extract*/ false, CostKind);
5567 } else {
5568 // In each 128-lane, if at least one index is demanded but not all
5569 // indices are demanded and this 128-lane is not the first 128-lane of
5570 // the legalized-vector, then this 128-lane needs a extracti128; If in
5571 // each 128-lane, there is at least one demanded index, this 128-lane
5572 // needs a inserti128.
5573
5574 // The following cases will help you build a better understanding:
5575 // Assume we insert several elements into a v8i32 vector in avx2,
5576 // Case#1: inserting into 1th index needs vpinsrd + inserti128.
5577 // Case#2: inserting into 5th index needs extracti128 + vpinsrd +
5578 // inserti128.
5579 // Case#3: inserting into 4,5,6,7 index needs 4*vpinsrd + inserti128.
5580 assert((LegalVectorBitWidth % LaneBitWidth) == 0 && "Illegal vector");
5581 unsigned NumLegalLanes = LegalVectorBitWidth / LaneBitWidth;
5582 unsigned NumLanesTotal = NumLegalLanes * NumLegalVectors;
5583 unsigned NumLegalElts =
5584 LT.second.getVectorNumElements() * NumLegalVectors;
5585 assert(NumLegalElts >= DemandedElts.getBitWidth() &&
5586 "Vector has been legalized to smaller element count");
5587 assert((NumLegalElts % NumLanesTotal) == 0 &&
5588 "Unexpected elts per lane");
5589 unsigned NumEltsPerLane = NumLegalElts / NumLanesTotal;
5590
5591 APInt WidenedDemandedElts = DemandedElts.zext(NumLegalElts);
5592 auto *LaneTy =
5593 FixedVectorType::get(Ty->getElementType(), NumEltsPerLane);
5594
5595 for (unsigned I = 0; I != NumLanesTotal; ++I) {
5596 APInt LaneEltMask = WidenedDemandedElts.extractBits(
5597 NumEltsPerLane, NumEltsPerLane * I);
5598 if (LaneEltMask.isZero())
5599 continue;
5600 // FIXME: we don't need to extract if all non-demanded elements
5601 // are legalization-inserted padding.
5602 if (!LaneEltMask.isAllOnes())
5604 {}, I * NumEltsPerLane, LaneTy);
5605 Cost += BaseT::getScalarizationOverhead(LaneTy, LaneEltMask, Insert,
5606 /*Extract*/ false, CostKind);
5607 }
5608
5609 APInt AffectedLanes =
5610 APIntOps::ScaleBitMask(WidenedDemandedElts, NumLanesTotal);
5611 APInt FullyAffectedLegalVectors = APIntOps::ScaleBitMask(
5612 AffectedLanes, NumLegalVectors, /*MatchAllBits=*/true);
5613 for (int LegalVec = 0; LegalVec != NumLegalVectors; ++LegalVec) {
5614 for (unsigned Lane = 0; Lane != NumLegalLanes; ++Lane) {
5615 unsigned I = NumLegalLanes * LegalVec + Lane;
5616 // No need to insert unaffected lane; or lane 0 of each legal vector
5617 // iff ALL lanes of that vector were affected and will be inserted.
5618 if (!AffectedLanes[I] ||
5619 (Lane == 0 && FullyAffectedLegalVectors[LegalVec]))
5620 continue;
5622 {}, I * NumEltsPerLane, LaneTy);
5623 }
5624 }
5625 }
5626 } else if (LT.second.isVector()) {
5627 // Without fast insertion, we need to use MOVD/MOVQ to pass each demanded
5628 // integer element as a SCALAR_TO_VECTOR, then we build the vector as a
5629 // series of UNPCK followed by CONCAT_VECTORS - all of these can be
5630 // considered cheap.
5631 if (Ty->isIntOrIntVectorTy())
5632 Cost += DemandedElts.popcount();
5633
5634 // Get the smaller of the legalized or original pow2-extended number of
5635 // vector elements, which represents the number of unpacks we'll end up
5636 // performing.
5637 unsigned NumElts = LT.second.getVectorNumElements();
5638 unsigned Pow2Elts =
5639 PowerOf2Ceil(cast<FixedVectorType>(Ty)->getNumElements());
5640 Cost += (std::min<unsigned>(NumElts, Pow2Elts) - 1) * LT.first;
5641 }
5642 }
5643
5644 if (Extract) {
5645 // vXi1 can be efficiently extracted with MOVMSK.
5646 // TODO: AVX512 predicate mask handling.
5647 // NOTE: This doesn't work well for roundtrip scalarization.
5648 if (!Insert && Ty->getScalarSizeInBits() == 1 && !ST->hasAVX512()) {
5649 unsigned NumElts = cast<FixedVectorType>(Ty)->getNumElements();
5650 unsigned MaxElts = ST->hasAVX2() ? 32 : 16;
5651 unsigned MOVMSKCost = (NumElts + MaxElts - 1) / MaxElts;
5652 return MOVMSKCost;
5653 }
5654
5655 if (LT.second.isVector()) {
5656 unsigned NumLegalElts =
5657 LT.second.getVectorNumElements() * NumLegalVectors;
5658 assert(NumLegalElts >= DemandedElts.getBitWidth() &&
5659 "Vector has been legalized to smaller element count");
5660
5661 // If we're extracting elements from a 128-bit subvector lane,
5662 // we only need to extract each lane once, not for every element.
5663 if (LegalVectorBitWidth > LaneBitWidth) {
5664 unsigned NumLegalLanes = LegalVectorBitWidth / LaneBitWidth;
5665 unsigned NumLanesTotal = NumLegalLanes * NumLegalVectors;
5666 assert((NumLegalElts % NumLanesTotal) == 0 &&
5667 "Unexpected elts per lane");
5668 unsigned NumEltsPerLane = NumLegalElts / NumLanesTotal;
5669
5670 // Add cost for each demanded 128-bit subvector extraction.
5671 // Luckily this is a lot easier than for insertion.
5672 APInt WidenedDemandedElts = DemandedElts.zext(NumLegalElts);
5673 auto *LaneTy =
5674 FixedVectorType::get(Ty->getElementType(), NumEltsPerLane);
5675
5676 for (unsigned I = 0; I != NumLanesTotal; ++I) {
5677 APInt LaneEltMask = WidenedDemandedElts.extractBits(
5678 NumEltsPerLane, I * NumEltsPerLane);
5679 if (LaneEltMask.isZero())
5680 continue;
5682 I * NumEltsPerLane, LaneTy);
5684 LaneTy, LaneEltMask, /*Insert*/ false, Extract, CostKind);
5685 }
5686
5687 return Cost;
5688 }
5689 }
5690
5691 // Fallback to default extraction.
5692 Cost += BaseT::getScalarizationOverhead(Ty, DemandedElts, /*Insert*/ false,
5693 Extract, CostKind);
5694 }
5695
5696 return Cost;
5697}
5698
5700X86TTIImpl::getReplicationShuffleCost(Type *EltTy, int ReplicationFactor,
5701 int VF, const APInt &DemandedDstElts,
5703 const unsigned EltTyBits = DL.getTypeSizeInBits(EltTy);
5704 // We don't differentiate element types here, only element bit width.
5705 EltTy = IntegerType::getIntNTy(EltTy->getContext(), EltTyBits);
5706
5707 auto bailout = [&]() {
5708 return BaseT::getReplicationShuffleCost(EltTy, ReplicationFactor, VF,
5709 DemandedDstElts, CostKind);
5710 };
5711
5712 // For now, only deal with AVX512 cases.
5713 if (!ST->hasAVX512())
5714 return bailout();
5715
5716 // Do we have a native shuffle for this element type, or should we promote?
5717 unsigned PromEltTyBits = EltTyBits;
5718 switch (EltTyBits) {
5719 case 32:
5720 case 64:
5721 break; // AVX512F.
5722 case 16:
5723 if (!ST->hasBWI())
5724 PromEltTyBits = 32; // promote to i32, AVX512F.
5725 break; // AVX512BW
5726 case 8:
5727 if (!ST->hasVBMI())
5728 PromEltTyBits = 32; // promote to i32, AVX512F.
5729 break; // AVX512VBMI
5730 case 1:
5731 // There is no support for shuffling i1 elements. We *must* promote.
5732 if (ST->hasBWI()) {
5733 if (ST->hasVBMI())
5734 PromEltTyBits = 8; // promote to i8, AVX512VBMI.
5735 else
5736 PromEltTyBits = 16; // promote to i16, AVX512BW.
5737 break;
5738 }
5739 PromEltTyBits = 32; // promote to i32, AVX512F.
5740 break;
5741 default:
5742 return bailout();
5743 }
5744 auto *PromEltTy = IntegerType::getIntNTy(EltTy->getContext(), PromEltTyBits);
5745
5746 auto *SrcVecTy = FixedVectorType::get(EltTy, VF);
5747 auto *PromSrcVecTy = FixedVectorType::get(PromEltTy, VF);
5748
5749 int NumDstElements = VF * ReplicationFactor;
5750 auto *PromDstVecTy = FixedVectorType::get(PromEltTy, NumDstElements);
5751 auto *DstVecTy = FixedVectorType::get(EltTy, NumDstElements);
5752
5753 // Legalize the types.
5754 MVT LegalSrcVecTy = getTypeLegalizationCost(SrcVecTy).second;
5755 MVT LegalPromSrcVecTy = getTypeLegalizationCost(PromSrcVecTy).second;
5756 MVT LegalPromDstVecTy = getTypeLegalizationCost(PromDstVecTy).second;
5757 MVT LegalDstVecTy = getTypeLegalizationCost(DstVecTy).second;
5758 // They should have legalized into vector types.
5759 if (!LegalSrcVecTy.isVector() || !LegalPromSrcVecTy.isVector() ||
5760 !LegalPromDstVecTy.isVector() || !LegalDstVecTy.isVector())
5761 return bailout();
5762
5763 if (PromEltTyBits != EltTyBits) {
5764 // If we have to perform the shuffle with wider elt type than our data type,
5765 // then we will first need to anyext (we don't care about the new bits)
5766 // the source elements, and then truncate Dst elements.
5767 InstructionCost PromotionCost;
5768 PromotionCost += getCastInstrCost(
5769 Instruction::SExt, /*Dst=*/PromSrcVecTy, /*Src=*/SrcVecTy,
5771 PromotionCost +=
5772 getCastInstrCost(Instruction::Trunc, /*Dst=*/DstVecTy,
5773 /*Src=*/PromDstVecTy,
5775 return PromotionCost + getReplicationShuffleCost(PromEltTy,
5776 ReplicationFactor, VF,
5777 DemandedDstElts, CostKind);
5778 }
5779
5780 assert(LegalSrcVecTy.getScalarSizeInBits() == EltTyBits &&
5781 LegalSrcVecTy.getScalarType() == LegalDstVecTy.getScalarType() &&
5782 "We expect that the legalization doesn't affect the element width, "
5783 "doesn't coalesce/split elements.");
5784
5785 unsigned NumEltsPerDstVec = LegalDstVecTy.getVectorNumElements();
5786 unsigned NumDstVectors =
5787 divideCeil(DstVecTy->getNumElements(), NumEltsPerDstVec);
5788
5789 auto *SingleDstVecTy = FixedVectorType::get(EltTy, NumEltsPerDstVec);
5790
5791 // Not all the produced Dst elements may be demanded. In our case,
5792 // given that a single Dst vector is formed by a single shuffle,
5793 // if all elements that will form a single Dst vector aren't demanded,
5794 // then we won't need to do that shuffle, so adjust the cost accordingly.
5795 APInt DemandedDstVectors = APIntOps::ScaleBitMask(
5796 DemandedDstElts.zext(NumDstVectors * NumEltsPerDstVec), NumDstVectors);
5797 unsigned NumDstVectorsDemanded = DemandedDstVectors.popcount();
5798
5799 InstructionCost SingleShuffleCost =
5800 getShuffleCost(TTI::SK_PermuteSingleSrc, SingleDstVecTy, SingleDstVecTy,
5801 CostKind, /*Mask=*/{},
5802 /*Index=*/0, /*SubTp=*/nullptr);
5803 return NumDstVectorsDemanded * SingleShuffleCost;
5804}
5805
5807 Align Alignment,
5808 unsigned AddressSpace,
5810 TTI::OperandValueInfo OpInfo,
5811 const Instruction *I) const {
5812 // FIXME: Load latency isn't handled here
5813 if (Opcode == Instruction::Load && CostKind == TTI::TCK_Latency)
5814 return BaseT::getMemoryOpCost(Opcode, Src, Alignment, AddressSpace,
5815 CostKind, OpInfo, I);
5816
5817 // TODO: Handle other cost kinds.
5819 if (auto *SI = dyn_cast_or_null<StoreInst>(I)) {
5820 // Store instruction with index and scale costs 2 Uops.
5821 // Check the preceding GEP to identify non-const indices.
5822 if (auto *GEP = dyn_cast<GetElementPtrInst>(SI->getPointerOperand())) {
5823 if (!all_of(GEP->indices(), [](Value *V) { return isa<Constant>(V); }))
5824 return TTI::TCC_Basic * 2;
5825 }
5826 }
5827 return TTI::TCC_Basic;
5828 }
5829
5830 assert((Opcode == Instruction::Load || Opcode == Instruction::Store) &&
5831 "Invalid Opcode");
5832 // Type legalization can't handle structs
5833 if (TLI->getValueType(DL, Src, true) == MVT::Other)
5834 return BaseT::getMemoryOpCost(Opcode, Src, Alignment, AddressSpace,
5835 CostKind, OpInfo, I);
5836
5837 // Legalize the type.
5838 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Src);
5839
5840 auto *VTy = dyn_cast<FixedVectorType>(Src);
5841
5843
5844 // Add a cost for constant load to vector.
5845 if (Opcode == Instruction::Store && OpInfo.isConstant())
5846 Cost += getMemoryOpCost(Instruction::Load, Src, DL.getABITypeAlign(Src),
5847 /*AddressSpace=*/0, CostKind, OpInfo);
5848
5849 // Handle the simple case of non-vectors.
5850 // NOTE: this assumes that legalization never creates vector from scalars!
5851 if (!VTy || !LT.second.isVector()) {
5852 // Each load/store unit costs 1.
5853 return (LT.second.isFloatingPoint() ? Cost : 0) + LT.first * 1;
5854 }
5855
5856 bool IsLoad = Opcode == Instruction::Load;
5857
5858 Type *EltTy = VTy->getElementType();
5859
5860 const int EltTyBits = DL.getTypeSizeInBits(EltTy);
5861
5862 // Source of truth: how many elements were there in the original IR vector?
5863 const unsigned SrcNumElt = VTy->getNumElements();
5864
5865 // How far have we gotten?
5866 int NumEltRemaining = SrcNumElt;
5867 // Note that we intentionally capture by-reference, NumEltRemaining changes.
5868 auto NumEltDone = [&]() { return SrcNumElt - NumEltRemaining; };
5869
5870 const int MaxLegalOpSizeBytes = divideCeil(LT.second.getSizeInBits(), 8);
5871
5872 // Note that even if we can store 64 bits of an XMM, we still operate on XMM.
5873 const unsigned XMMBits = 128;
5874 if (XMMBits % EltTyBits != 0)
5875 // Vector size must be a multiple of the element size. I.e. no padding.
5876 return BaseT::getMemoryOpCost(Opcode, Src, Alignment, AddressSpace,
5877 CostKind, OpInfo, I);
5878 const int NumEltPerXMM = XMMBits / EltTyBits;
5879
5880 auto *XMMVecTy = FixedVectorType::get(EltTy, NumEltPerXMM);
5881
5882 for (int CurrOpSizeBytes = MaxLegalOpSizeBytes, SubVecEltsLeft = 0;
5883 NumEltRemaining > 0; CurrOpSizeBytes /= 2) {
5884 // How many elements would a single op deal with at once?
5885 if ((8 * CurrOpSizeBytes) % EltTyBits != 0)
5886 // Vector size must be a multiple of the element size. I.e. no padding.
5887 return BaseT::getMemoryOpCost(Opcode, Src, Alignment, AddressSpace,
5888 CostKind, OpInfo, I);
5889 int CurrNumEltPerOp = (8 * CurrOpSizeBytes) / EltTyBits;
5890
5891 assert(CurrOpSizeBytes > 0 && CurrNumEltPerOp > 0 && "How'd we get here?");
5892 assert((((NumEltRemaining * EltTyBits) < (2 * 8 * CurrOpSizeBytes)) ||
5893 (CurrOpSizeBytes == MaxLegalOpSizeBytes)) &&
5894 "Unless we haven't halved the op size yet, "
5895 "we have less than two op's sized units of work left.");
5896
5897 auto *CurrVecTy = CurrNumEltPerOp > NumEltPerXMM
5898 ? FixedVectorType::get(EltTy, CurrNumEltPerOp)
5899 : XMMVecTy;
5900
5901 assert(CurrVecTy->getNumElements() % CurrNumEltPerOp == 0 &&
5902 "After halving sizes, the vector elt count is no longer a multiple "
5903 "of number of elements per operation?");
5904 auto *CoalescedVecTy =
5905 CurrNumEltPerOp == 1
5906 ? CurrVecTy
5908 IntegerType::get(Src->getContext(),
5909 EltTyBits * CurrNumEltPerOp),
5910 CurrVecTy->getNumElements() / CurrNumEltPerOp);
5911 assert(DL.getTypeSizeInBits(CoalescedVecTy) ==
5912 DL.getTypeSizeInBits(CurrVecTy) &&
5913 "coalesciing elements doesn't change vector width.");
5914
5915 while (NumEltRemaining > 0) {
5916 assert(SubVecEltsLeft >= 0 && "Subreg element count overconsumtion?");
5917
5918 // Can we use this vector size, as per the remaining element count?
5919 // Iff the vector is naturally aligned, we can do a wide load regardless.
5920 if (NumEltRemaining < CurrNumEltPerOp &&
5921 (!IsLoad || Alignment < CurrOpSizeBytes) && CurrOpSizeBytes != 1)
5922 break; // Try smalled vector size.
5923
5924 // This isn't exactly right. We're using slow unaligned 32-byte accesses
5925 // as a proxy for a double-pumped AVX memory interface such as on
5926 // Sandybridge.
5927 // Sub-32-bit loads/stores will be slower either with PINSR*/PEXTR* or
5928 // will be scalarized.
5929 if (CurrOpSizeBytes == 32 && ST->isUnalignedMem32Slow())
5930 Cost += 2;
5931 else if (CurrOpSizeBytes < 4)
5932 Cost += 2;
5933 else
5934 Cost += 1;
5935
5936 // If we're loading a uniform value, then we don't need to split the load,
5937 // loading just a single (widest) vector can be reused by all splits.
5938 if (IsLoad && OpInfo.isUniform())
5939 return Cost;
5940
5941 bool Is0thSubVec = (NumEltDone() % LT.second.getVectorNumElements()) == 0;
5942
5943 // If we have fully processed the previous reg, we need to replenish it.
5944 if (SubVecEltsLeft == 0) {
5945 SubVecEltsLeft += CurrVecTy->getNumElements();
5946 // And that's free only for the 0'th subvector of a legalized vector.
5947 if (!Is0thSubVec)
5948 Cost +=
5951 VTy, VTy, CostKind, {}, NumEltDone(), CurrVecTy);
5952 }
5953
5954 // While we can directly load/store ZMM, YMM, and 64-bit halves of XMM,
5955 // for smaller widths (32/16/8) we have to insert/extract them separately.
5956 // Again, it's free for the 0'th subreg (if op is 32/64 bit wide,
5957 // but let's pretend that it is also true for 16/8 bit wide ops...)
5958 if (CurrOpSizeBytes <= 32 / 8 && !Is0thSubVec) {
5959 int NumEltDoneInCurrXMM = NumEltDone() % NumEltPerXMM;
5960 assert(NumEltDoneInCurrXMM % CurrNumEltPerOp == 0 && "");
5961 int CoalescedVecEltIdx = NumEltDoneInCurrXMM / CurrNumEltPerOp;
5962 APInt DemandedElts =
5963 APInt::getBitsSet(CoalescedVecTy->getNumElements(),
5964 CoalescedVecEltIdx, CoalescedVecEltIdx + 1);
5965 assert(DemandedElts.popcount() == 1 && "Inserting single value");
5966 Cost += getScalarizationOverhead(CoalescedVecTy, DemandedElts, IsLoad,
5967 !IsLoad, CostKind);
5968 }
5969
5970 SubVecEltsLeft -= CurrNumEltPerOp;
5971 NumEltRemaining -= CurrNumEltPerOp;
5972 Alignment = commonAlignment(Alignment, CurrOpSizeBytes);
5973 }
5974 }
5975
5976 assert(NumEltRemaining <= 0 && "Should have processed all the elements.");
5977
5978 return Cost;
5979}
5980
5984 switch (MICA.getID()) {
5985 case Intrinsic::masked_scatter:
5986 case Intrinsic::masked_gather:
5987 return getGatherScatterOpCost(MICA, CostKind);
5988 case Intrinsic::masked_load:
5989 case Intrinsic::masked_store:
5990 return getMaskedMemoryOpCost(MICA, CostKind);
5991 }
5993}
5994
5998 unsigned Opcode = MICA.getID() == Intrinsic::masked_load ? Instruction::Load
5999 : Instruction::Store;
6000 Type *SrcTy = MICA.getDataType();
6001 Align Alignment = MICA.getAlignment();
6002 unsigned AddressSpace = MICA.getAddressSpace();
6003
6004 bool IsLoad = (Instruction::Load == Opcode);
6005 bool IsStore = (Instruction::Store == Opcode);
6006
6007 auto *SrcVTy = dyn_cast<FixedVectorType>(SrcTy);
6008 if (!SrcVTy)
6009 // To calculate scalar take the regular cost, without mask
6010 return getMemoryOpCost(Opcode, SrcTy, Alignment, AddressSpace, CostKind);
6011
6012 unsigned NumElem = SrcVTy->getNumElements();
6013 auto *MaskTy =
6014 FixedVectorType::get(Type::getInt8Ty(SrcVTy->getContext()), NumElem);
6015 if ((IsLoad && !isLegalMaskedLoad(SrcVTy, Alignment, AddressSpace)) ||
6016 (IsStore && !isLegalMaskedStore(SrcVTy, Alignment, AddressSpace))) {
6017 // Scalarization
6018 APInt DemandedElts = APInt::getAllOnes(NumElem);
6020 MaskTy, DemandedElts, /*Insert*/ false, /*Extract*/ true, CostKind);
6021 InstructionCost ScalarCompareCost = getCmpSelInstrCost(
6022 Instruction::ICmp, Type::getInt8Ty(SrcVTy->getContext()), nullptr,
6024 InstructionCost BranchCost = getCFInstrCost(Instruction::CondBr, CostKind);
6025 InstructionCost MaskCmpCost = NumElem * (BranchCost + ScalarCompareCost);
6027 SrcVTy, DemandedElts, IsLoad, IsStore, CostKind);
6028 InstructionCost MemopCost =
6029 NumElem * BaseT::getMemoryOpCost(Opcode, SrcVTy->getScalarType(),
6030 Alignment, AddressSpace, CostKind);
6031 return MemopCost + ValueSplitCost + MaskSplitCost + MaskCmpCost;
6032 }
6033
6034 // Legalize the type.
6035 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(SrcVTy);
6036 auto VT = TLI->getValueType(DL, SrcVTy);
6038 MVT Ty = LT.second;
6039 if (Ty == MVT::i16 || Ty == MVT::i32 || Ty == MVT::i64)
6040 // APX masked load/store for scalar is cheap.
6041 return Cost + LT.first;
6042
6043 if (VT.isSimple() && Ty != VT.getSimpleVT() &&
6044 LT.second.getVectorNumElements() == NumElem)
6045 // Promotion requires extend/truncate for data and a shuffle for mask.
6046 Cost += getShuffleCost(TTI::SK_PermuteTwoSrc, SrcVTy, SrcVTy, CostKind, {},
6047 0, nullptr) +
6048 getShuffleCost(TTI::SK_PermuteTwoSrc, MaskTy, MaskTy, CostKind, {},
6049 0, nullptr);
6050
6051 else if (LT.first * Ty.getVectorNumElements() > NumElem) {
6052 auto *NewMaskTy = FixedVectorType::get(MaskTy->getElementType(),
6053 (unsigned)LT.first.getValue() *
6054 Ty.getVectorNumElements());
6055 // Expanding requires fill mask with zeroes
6056 Cost += getShuffleCost(TTI::SK_InsertSubvector, NewMaskTy, NewMaskTy,
6057 CostKind, {}, 0, MaskTy);
6058 }
6059
6060 // Pre-AVX512 - each maskmov load costs 2 + store costs ~8.
6061 if (!ST->hasAVX512())
6062 return Cost + LT.first * (IsLoad ? 2 : 8);
6063
6064 // AVX-512 masked load/store is cheaper
6065 return Cost + LT.first;
6066}
6067
6069 ArrayRef<const Value *> Ptrs, const Value *Base,
6070 const TTI::PointersChainInfo &Info, Type *AccessTy,
6071 const TTI::TargetCostKind CostKind) const {
6072 if (Info.isSameBase() && Info.isKnownStride()) {
6073 // If all the pointers have known stride all the differences are translated
6074 // into constants. X86 memory addressing allows encoding it into
6075 // displacement. So we just need to take the base GEP cost.
6076 if (const auto *BaseGEP = dyn_cast<GetElementPtrInst>(Base)) {
6077 SmallVector<const Value *> Indices(BaseGEP->indices());
6078 return getGEPCost(BaseGEP->getSourceElementType(),
6079 BaseGEP->getPointerOperand(), Indices, CostKind,
6080 nullptr);
6081 }
6082 return TTI::TCC_Free;
6083 }
6084 return BaseT::getPointersChainCost(Ptrs, Base, Info, AccessTy, CostKind);
6085}
6086
6089 const SCEV *Ptr,
6091 // Address computations in vectorized code with non-consecutive addresses will
6092 // likely result in more instructions compared to scalar code where the
6093 // computation can more often be merged into the index mode. The resulting
6094 // extra micro-ops can significantly decrease throughput.
6095 const unsigned NumVectorInstToHideOverhead = 10;
6096
6097 // Cost modeling of Strided Access Computation is hidden by the indexing
6098 // modes of X86 regardless of the stride value. We dont believe that there
6099 // is a difference between constant strided access in gerenal and constant
6100 // strided value which is less than or equal to 64.
6101 // Even in the case of (loop invariant) stride whose value is not known at
6102 // compile time, the address computation will not incur more than one extra
6103 // ADD instruction.
6104 if (PtrTy->isVectorTy() && SE) {
6106 return 1;
6107 if (!ST->hasAVX2()) {
6108 // TODO: AVX2 is the current cut-off because we don't have correct
6109 // interleaving costs for prior ISA's.
6110 if (!BaseT::isStridedAccess(Ptr))
6111 return NumVectorInstToHideOverhead;
6112 }
6113 }
6114
6115 return BaseT::getAddressComputationCost(PtrTy, SE, Ptr, CostKind);
6116}
6117
6119 unsigned Opcode, Type *InputTypeA, Type *InputTypeB, Type *AccumType,
6121 TTI::PartialReductionExtendKind OpBExtend, std::optional<unsigned> BinOp,
6122 TTI::TargetCostKind CostKind, std::optional<FastMathFlags> FMF) const {
6123 auto ExpandCost = [&]() {
6124 return BaseT::getPartialReductionCost(Opcode, InputTypeA, InputTypeB,
6125 AccumType, VF, OpAExtend, OpBExtend,
6126 BinOp, CostKind, FMF);
6127 };
6128
6129 // The dot product instructions multiply-accumulate i8 x i8 -> i32,
6130 // i16 x i16 -> i32, bf16 x bf16 -> f32 or f16 x f16 -> f32. Partial
6131 // reductions may also multiply inputs extended from different types, which
6132 // they can't handle.
6133 if (VF.isScalable() || !BinOp || OpAExtend == TTI::PR_None ||
6134 OpBExtend == TTI::PR_None || InputTypeA != InputTypeB)
6135 return ExpandCost();
6136
6137 unsigned Opc;
6138 if (Opcode == Instruction::Add && *BinOp == Instruction::Mul &&
6139 AccumType->isIntegerTy(32) &&
6140 (InputTypeA->isIntegerTy(8) || InputTypeA->isIntegerTy(16))) {
6141 if (OpAExtend != OpBExtend)
6143 else if (OpAExtend == TTI::PR_SignExtend)
6145 else
6147 } else if (Opcode == Instruction::FAdd && *BinOp == Instruction::FMul &&
6148 AccumType->isFloatTy() &&
6149 (InputTypeA->isBFloatTy() || InputTypeA->isHalfTy())) {
6150 // VDPBF16PS and VDPPHPS, like the expansion, reassociate the additions and
6151 // fuse the multiplications.
6152 if (!FMF || !FMF->allowReassoc() || !FMF->allowContract())
6155 } else {
6156 return ExpandCost();
6157 }
6158
6159 unsigned Ratio =
6160 AccumType->getScalarSizeInBits() / InputTypeA->getScalarSizeInBits();
6161 if (!VF.isKnownMultipleOf(Ratio))
6162 return ExpandCost();
6163
6164 // One dot product per legal accumulator vector. Accumulators narrower than
6165 // a legal vector are widened by expanding the partial reduction instead.
6166 auto *AccVecTy = VectorType::get(AccumType, VF.divideCoefficientBy(Ratio));
6167 auto *InputVecTy = VectorType::get(InputTypeA, VF);
6168 std::pair<InstructionCost, MVT> AccLT = getTypeLegalizationCost(AccVecTy);
6169 std::pair<InstructionCost, MVT> InputLT = getTypeLegalizationCost(InputVecTy);
6170 if (AccLT.second.getFixedSizeInBits() >
6171 AccVecTy->getPrimitiveSizeInBits().getFixedValue() ||
6172 !TLI->isPartialReduceMLALegalOrCustom(Opc, AccLT.second, InputLT.second))
6173 return ExpandCost();
6174
6175 return AccLT.first;
6176}
6177
6180 std::optional<FastMathFlags> FMF,
6183 return BaseT::getArithmeticReductionCost(Opcode, ValTy, FMF, CostKind);
6184
6185 // We use llvm-mca across all supported CPUs to measure the logic cost stats.
6186 // We use the Intel Architecture Code Analyzer(IACA) to measure the throughput
6187 // and make it as the cost. TODO: Update old IACA numbers to llvm-mca.
6188
6189 static const CostKindTblEntry SLMCostTbl[] = {
6190 { ISD::FADD, MVT::v2f64, {3, 3, 3, 3} },
6191 { ISD::ADD, MVT::v2i64, {5, 5, 5, 5} },
6192 };
6193
6194 static const CostKindTblEntry SSE2CostTbl[] = {
6195 { ISD::FADD, MVT::v2f64, {2, 2, 2, 2} },
6196 { ISD::FADD, MVT::v2f32, {2, 2, 2, 2} },
6197 { ISD::FADD, MVT::v4f32, {4, 4, 4, 4} },
6198 { ISD::ADD, MVT::v2i64, {2, 2, 2, 2} }, // The data reported by the IACA tool is "1.6".
6199 { ISD::ADD, MVT::v2i32, {2, 2, 2, 2} }, // FIXME: chosen to be less than v4i32
6200 { ISD::ADD, MVT::v4i32, {3, 3, 3, 3} }, // The data reported by the IACA tool is "3.3".
6201 { ISD::ADD, MVT::v2i16, {2, 2, 2, 2} }, // The data reported by the IACA tool is "4.3".
6202 { ISD::ADD, MVT::v4i16, {3, 3, 3, 3} }, // The data reported by the IACA tool is "4.3".
6203 { ISD::ADD, MVT::v8i16, {4, 4, 4, 4} }, // The data reported by the IACA tool is "4.3".
6204 { ISD::ADD, MVT::v2i8, {2, 2, 2, 2} },
6205 { ISD::ADD, MVT::v4i8, {2, 2, 2, 2} },
6206 { ISD::ADD, MVT::v8i8, {2, 2, 2, 2} },
6207 { ISD::ADD, MVT::v16i8, {3, 3, 3, 3} },
6208
6209 { ISD::AND, MVT::v2i64, {2, 2, 3, 3} },
6210 { ISD::AND, MVT::v4i32, {3, 4, 5, 5} },
6211 { ISD::AND, MVT::v8i16, {4, 7, 8, 8} },
6212 { ISD::AND, MVT::v16i8, {6,10,11,11} },
6213 { ISD::OR, MVT::v2i64, {2, 2, 3, 3} },
6214 { ISD::OR, MVT::v4i32, {3, 4, 5, 5} },
6215 { ISD::OR, MVT::v8i16, {4, 7, 8, 8} },
6216 { ISD::OR, MVT::v16i8, {6,10,11,11} },
6217 { ISD::XOR, MVT::v2i64, {2, 2, 3, 3} },
6218 { ISD::XOR, MVT::v4i32, {3, 4, 5, 5} },
6219 { ISD::XOR, MVT::v8i16, {4, 7, 8, 8} },
6220 { ISD::XOR, MVT::v16i8, {6,10,11,11} },
6221 };
6222
6223 static const CostKindTblEntry AVX1CostTbl[] = {
6224 { ISD::FADD, MVT::v4f64, {3, 3, 3, 3} },
6225 { ISD::FADD, MVT::v4f32, {3, 3, 3, 3} },
6226 { ISD::FADD, MVT::v8f32, {4, 4, 4, 4} },
6227 { ISD::ADD, MVT::v2i64, {1, 1, 1, 1} }, // The data reported by the IACA tool is "1.5".
6228 { ISD::ADD, MVT::v4i64, {3, 3, 3, 3} },
6229 { ISD::ADD, MVT::v8i32, {5, 5, 5, 5} },
6230 { ISD::ADD, MVT::v16i16, {5, 5, 5, 5} },
6231 { ISD::ADD, MVT::v32i8, {4, 4, 4, 4} },
6232
6233 { ISD::AND, MVT::v4i64, {3, 7, 5, 5} },
6234 { ISD::AND, MVT::v8i32, {4, 9, 7, 7} },
6235 { ISD::AND, MVT::v16i16, {5,11, 9, 9} },
6236 { ISD::AND, MVT::v8i16, {4, 7, 7, 7} },
6237 { ISD::AND, MVT::v32i8, {6,13,11,11} },
6238 { ISD::AND, MVT::v16i8, {5,10, 9, 9} },
6239 { ISD::OR, MVT::v4i64, {3, 7, 5, 5} },
6240 { ISD::OR, MVT::v8i32, {4, 9, 7, 7} },
6241 { ISD::OR, MVT::v16i16, {5,11, 9, 9} },
6242 { ISD::OR, MVT::v8i16, {4, 7, 7, 7} },
6243 { ISD::OR, MVT::v32i8, {6,13,11,11} },
6244 { ISD::OR, MVT::v16i8, {5,10, 9, 9} },
6245 { ISD::XOR, MVT::v4i64, {3, 7, 5, 5} },
6246 { ISD::XOR, MVT::v8i32, {4, 9, 7, 7} },
6247 { ISD::XOR, MVT::v16i16, {5,11, 9, 9} },
6248 { ISD::XOR, MVT::v8i16, {4, 7, 7, 7} },
6249 { ISD::XOR, MVT::v32i8, {6,13,11,11} },
6250 { ISD::XOR, MVT::v16i8, {5,10, 9, 9} },
6251 };
6252
6253 static const CostKindTblEntry AVX2CostTbl[] = {
6254 { ISD::AND, MVT::v4i64, {2, 7, 5, 5} },
6255 { ISD::AND, MVT::v2i64, {1, 2, 3, 3} },
6256 { ISD::AND, MVT::v8i32, {3, 9, 7, 7} },
6257 { ISD::AND, MVT::v4i32, {2, 4, 5, 5} },
6258 { ISD::AND, MVT::v16i16, {3,11, 9, 9} },
6259 { ISD::AND, MVT::v8i16, {2, 6, 7, 7} },
6260 { ISD::AND, MVT::v32i8, {3,13,11,11} },
6261 { ISD::AND, MVT::v16i8, {3, 8, 9, 9} },
6262 { ISD::OR, MVT::v4i64, {2, 7, 5, 5} },
6263 { ISD::OR, MVT::v2i64, {1, 2, 3, 3} },
6264 { ISD::OR, MVT::v8i32, {3, 9, 7, 7} },
6265 { ISD::OR, MVT::v4i32, {2, 4, 5, 5} },
6266 { ISD::OR, MVT::v16i16, {3,11, 9, 9} },
6267 { ISD::OR, MVT::v8i16, {2, 6, 7, 7} },
6268 { ISD::OR, MVT::v32i8, {3,13,11,11} },
6269 { ISD::OR, MVT::v16i8, {3, 8, 9, 9} },
6270 { ISD::XOR, MVT::v4i64, {2, 7, 5, 5} },
6271 { ISD::XOR, MVT::v2i64, {1, 2, 3, 3} },
6272 { ISD::XOR, MVT::v8i32, {3, 9, 7, 7} },
6273 { ISD::XOR, MVT::v4i32, {2, 4, 5, 5} },
6274 { ISD::XOR, MVT::v16i16, {3,11, 9, 9} },
6275 { ISD::XOR, MVT::v8i16, {2, 6, 7, 7} },
6276 { ISD::XOR, MVT::v32i8, {3,13,11,11} },
6277 { ISD::XOR, MVT::v16i8, {3, 8, 9, 9} },
6278 };
6279
6280 static const CostKindTblEntry AVX512FCostTbl[] = {
6281 { ISD::FADD, MVT::v8f64, {4, 4, 4, 4} },
6282 { ISD::FADD, MVT::v16f32, {5, 5, 5, 5} },
6283 { ISD::ADD, MVT::v8i64, {4, 4, 4, 4} },
6284 { ISD::ADD, MVT::v16i32, {6, 6, 6, 6} },
6285
6286 { ISD::AND, MVT::v8i64, {3,10, 7, 7} },
6287 { ISD::AND, MVT::v16i32, {4,12, 9, 9} },
6288 { ISD::AND, MVT::v32i16, {4,14,11,11} },
6289 { ISD::AND, MVT::v64i8, {4,16,13,13} },
6290 { ISD::AND, MVT::v16i8, {2, 8, 9, 9} },
6291 { ISD::OR, MVT::v8i64, {3,10, 7, 7} },
6292 { ISD::OR, MVT::v16i32, {4,12, 9, 9} },
6293 { ISD::OR, MVT::v32i16, {4,14,11,11} },
6294 { ISD::OR, MVT::v64i8, {4,16,13,13} },
6295 { ISD::OR, MVT::v16i8, {2, 8, 9, 9} },
6296 { ISD::XOR, MVT::v8i64, {3,10, 7, 7} },
6297 { ISD::XOR, MVT::v16i32, {4,12, 9, 9} },
6298 { ISD::XOR, MVT::v32i16, {4,14,11,11} },
6299 { ISD::XOR, MVT::v64i8, {4,16,13,13} },
6300 { ISD::XOR, MVT::v16i8, {2, 8, 9, 9} },
6301 };
6302
6303 static const CostKindTblEntry AVX512BWCostTbl[] = {
6304 { ISD::ADD, MVT::v32i16, {7, 7, 7, 7} },
6305 { ISD::ADD, MVT::v64i8, {4, 4, 4, 4} },
6306 };
6307
6308 int ISD = TLI->InstructionOpcodeToISD(Opcode);
6309 assert(ISD && "Invalid opcode");
6310
6311 // Before legalizing the type, give a chance to look up illegal narrow types
6312 // in the table.
6313 // FIXME: Is there a better way to do this?
6314 EVT VT = TLI->getValueType(DL, ValTy);
6315 if (VT.isSimple()) {
6316 MVT MTy = VT.getSimpleVT();
6317 if (ST->useSLMArithCosts())
6318 if (const auto *Entry = CostTableLookup(SLMCostTbl, ISD, MTy))
6319 if (auto KindCost = Entry->Cost[CostKind])
6320 return *KindCost;
6321
6322 if (ST->hasBWI())
6323 if (const auto *Entry = CostTableLookup(AVX512BWCostTbl, ISD, MTy))
6324 if (auto KindCost = Entry->Cost[CostKind])
6325 return *KindCost;
6326
6327 if (ST->hasAVX512())
6328 if (const auto *Entry = CostTableLookup(AVX512FCostTbl, ISD, MTy))
6329 if (auto KindCost = Entry->Cost[CostKind])
6330 return *KindCost;
6331
6332 if (ST->hasAVX2())
6333 if (const auto *Entry = CostTableLookup(AVX2CostTbl, ISD, MTy))
6334 if (auto KindCost = Entry->Cost[CostKind])
6335 return *KindCost;
6336
6337 if (ST->hasAVX())
6338 if (const auto *Entry = CostTableLookup(AVX1CostTbl, ISD, MTy))
6339 if (auto KindCost = Entry->Cost[CostKind])
6340 return *KindCost;
6341
6342 if (ST->hasSSE2())
6343 if (const auto *Entry = CostTableLookup(SSE2CostTbl, ISD, MTy))
6344 if (auto KindCost = Entry->Cost[CostKind])
6345 return *KindCost;
6346 }
6347
6348 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(ValTy);
6349
6350 MVT MTy = LT.second;
6351
6352 auto *ValVTy = cast<FixedVectorType>(ValTy);
6353
6354 InstructionCost ArithmeticCost = 0;
6355 if (LT.first != 1 && MTy.isVector() &&
6356 MTy.getVectorNumElements() < ValVTy->getNumElements()) {
6357 // Type needs to be split. We need LT.first - 1 arithmetic ops.
6358 auto *SingleOpTy = FixedVectorType::get(ValVTy->getElementType(),
6359 MTy.getVectorNumElements());
6360 ArithmeticCost = getArithmeticInstrCost(Opcode, SingleOpTy, CostKind);
6361 ArithmeticCost *= LT.first - 1;
6362 }
6363
6364 // FIXME: These assume a naive kshift+binop lowering, which is probably
6365 // conservative in most cases.
6366 static const CostKindTblEntry AVX512BoolReduction[] = {
6367 { ISD::AND, MVT::v2i1, { 3, 3, 3, 3} },
6368 { ISD::AND, MVT::v4i1, { 5, 5, 5, 5} },
6369 { ISD::AND, MVT::v8i1, { 7, 7, 7, 7} },
6370 { ISD::AND, MVT::v16i1, { 9, 9, 9, 9} },
6371 { ISD::AND, MVT::v32i1, {11,11,11,11} },
6372 { ISD::AND, MVT::v64i1, {13,13,13,13} },
6373 { ISD::OR, MVT::v2i1, { 3, 3, 3, 3} },
6374 { ISD::OR, MVT::v4i1, { 5, 5, 5, 5} },
6375 { ISD::OR, MVT::v8i1, { 7, 7, 7, 7} },
6376 { ISD::OR, MVT::v16i1, { 9, 9, 9, 9} },
6377 { ISD::OR, MVT::v32i1, {11,11,11,11} },
6378 { ISD::OR, MVT::v64i1, {13,13,13,13} },
6379 };
6380
6381 static const CostKindTblEntry AVX2BoolReduction[] = {
6382 { ISD::AND, MVT::v16i16, { 2, 2, 2, 2} }, // vpmovmskb + cmp
6383 { ISD::AND, MVT::v32i8, { 2, 2, 2, 2} }, // vpmovmskb + cmp
6384 { ISD::OR, MVT::v16i16, { 2, 2, 2, 2} }, // vpmovmskb + cmp
6385 { ISD::OR, MVT::v32i8, { 2, 2, 2, 2} }, // vpmovmskb + cmp
6386 };
6387
6388 static const CostKindTblEntry AVX1BoolReduction[] = {
6389 { ISD::AND, MVT::v4i64, {2, 2, 2, 2} }, // vmovmskpd + cmp
6390 { ISD::AND, MVT::v8i32, {2, 2, 2, 2} }, // vmovmskps + cmp
6391 { ISD::AND, MVT::v16i16, {4, 4, 4, 4} }, // vextractf128 + vpand + vpmovmskb + cmp
6392 { ISD::AND, MVT::v32i8, {4, 4, 4, 4} }, // vextractf128 + vpand + vpmovmskb + cmp
6393 { ISD::OR, MVT::v4i64, {2, 2, 2, 2} }, // vmovmskpd + cmp
6394 { ISD::OR, MVT::v8i32, {2, 2, 2, 2} }, // vmovmskps + cmp
6395 { ISD::OR, MVT::v16i16, {4, 4, 4, 4} }, // vextractf128 + vpor + vpmovmskb + cmp
6396 { ISD::OR, MVT::v32i8, {4, 4, 4, 4} }, // vextractf128 + vpor + vpmovmskb + cmp
6397 };
6398
6399 static const CostKindTblEntry SSE2BoolReduction[] = {
6400 { ISD::AND, MVT::v2i64, {2, 2, 2, 2} }, // movmskpd + cmp
6401 { ISD::AND, MVT::v4i32, {2, 2, 2, 2} }, // movmskps + cmp
6402 { ISD::AND, MVT::v8i16, {2, 2, 2, 2} }, // pmovmskb + cmp
6403 { ISD::AND, MVT::v16i8, {2, 2, 2, 2} }, // pmovmskb + cmp
6404 { ISD::OR, MVT::v2i64, {2, 2, 2, 2} }, // movmskpd + cmp
6405 { ISD::OR, MVT::v4i32, {2, 2, 2, 2} }, // movmskps + cmp
6406 { ISD::OR, MVT::v8i16, {2, 2, 2, 2} }, // pmovmskb + cmp
6407 { ISD::OR, MVT::v16i8, {2, 2, 2, 2} }, // pmovmskb + cmp
6408 };
6409
6410 // Handle bool allof/anyof vXi1 patterns before we check legal types.
6411 if (ValVTy->getElementType()->isIntegerTy(1)) {
6412 if (ISD == ISD::ADD) {
6413 // vXi1 addition reduction will bitcast to scalar and perform a popcount.
6414 auto *IntTy = IntegerType::getIntNTy(ValVTy->getContext(),
6415 ValVTy->getNumElements());
6416 IntrinsicCostAttributes ICA(Intrinsic::ctpop, IntTy, {IntTy});
6417 return getCastInstrCost(Instruction::BitCast, IntTy, ValVTy,
6419 CostKind) +
6421 }
6422
6423 if (ST->hasAVX512())
6424 if (const auto *Entry = CostTableLookup(AVX512BoolReduction, ISD, MTy))
6425 if (auto KindCost = Entry->Cost[CostKind])
6426 return ArithmeticCost + *KindCost;
6427 if (ST->hasAVX2())
6428 if (const auto *Entry = CostTableLookup(AVX2BoolReduction, ISD, MTy))
6429 if (auto KindCost = Entry->Cost[CostKind])
6430 return ArithmeticCost + *KindCost;
6431 if (ST->hasAVX())
6432 if (const auto *Entry = CostTableLookup(AVX1BoolReduction, ISD, MTy))
6433 if (auto KindCost = Entry->Cost[CostKind])
6434 return ArithmeticCost + *KindCost;
6435 if (ST->hasSSE2())
6436 if (const auto *Entry = CostTableLookup(SSE2BoolReduction, ISD, MTy))
6437 if (auto KindCost = Entry->Cost[CostKind])
6438 return ArithmeticCost + *KindCost;
6439
6440 return BaseT::getArithmeticReductionCost(Opcode, ValVTy, FMF, CostKind);
6441 }
6442
6443 // Special case: vXi8 mul reductions are performed as vXi16.
6444 if (ISD == ISD::MUL && MTy.getScalarType() == MVT::i8) {
6445 auto *WideSclTy = IntegerType::get(ValVTy->getContext(), 16);
6446 auto *WideVecTy = FixedVectorType::get(WideSclTy, ValVTy->getNumElements());
6447 return getCastInstrCost(Instruction::ZExt, WideVecTy, ValTy,
6449 CostKind) +
6450 getArithmeticReductionCost(Opcode, WideVecTy, FMF, CostKind);
6451 }
6452
6453 if (ST->useSLMArithCosts())
6454 if (const auto *Entry = CostTableLookup(SLMCostTbl, ISD, MTy))
6455 if (auto KindCost = Entry->Cost[CostKind])
6456 return ArithmeticCost + *KindCost;
6457
6458 if (ST->hasBWI())
6459 if (const auto *Entry = CostTableLookup(AVX512BWCostTbl, ISD, MTy))
6460 if (auto KindCost = Entry->Cost[CostKind])
6461 return ArithmeticCost + *KindCost;
6462
6463 if (ST->hasAVX512())
6464 if (const auto *Entry = CostTableLookup(AVX512FCostTbl, ISD, MTy))
6465 if (auto KindCost = Entry->Cost[CostKind])
6466 return ArithmeticCost + *KindCost;
6467
6468 if (ST->hasAVX2())
6469 if (const auto *Entry = CostTableLookup(AVX2CostTbl, ISD, MTy))
6470 if (auto KindCost = Entry->Cost[CostKind])
6471 return ArithmeticCost + *KindCost;
6472
6473 if (ST->hasAVX())
6474 if (const auto *Entry = CostTableLookup(AVX1CostTbl, ISD, MTy))
6475 if (auto KindCost = Entry->Cost[CostKind])
6476 return ArithmeticCost + *KindCost;
6477
6478 if (ST->hasSSE2())
6479 if (const auto *Entry = CostTableLookup(SSE2CostTbl, ISD, MTy))
6480 if (auto KindCost = Entry->Cost[CostKind])
6481 return ArithmeticCost + *KindCost;
6482
6483 unsigned NumVecElts = ValVTy->getNumElements();
6484 unsigned ScalarSize = ValVTy->getScalarSizeInBits();
6485
6486 // Special case power of 2 reductions where the scalar type isn't changed
6487 // by type legalization.
6488 if (!isPowerOf2_32(NumVecElts) || ScalarSize != MTy.getScalarSizeInBits())
6489 return BaseT::getArithmeticReductionCost(Opcode, ValVTy, FMF, CostKind);
6490
6491 InstructionCost ReductionCost = 0;
6492
6493 auto *Ty = ValVTy;
6494 if (LT.first != 1 && MTy.isVector() &&
6495 MTy.getVectorNumElements() < ValVTy->getNumElements()) {
6496 // Type needs to be split. We need LT.first - 1 arithmetic ops.
6497 Ty = FixedVectorType::get(ValVTy->getElementType(),
6498 MTy.getVectorNumElements());
6499 ReductionCost = getArithmeticInstrCost(Opcode, Ty, CostKind);
6500 ReductionCost *= LT.first - 1;
6501 NumVecElts = MTy.getVectorNumElements();
6502 }
6503
6504 // Now handle reduction with the legal type, taking into account size changes
6505 // at each level.
6506 while (NumVecElts > 1) {
6507 // Determine the size of the remaining vector we need to reduce.
6508 unsigned Size = NumVecElts * ScalarSize;
6509 NumVecElts /= 2;
6510 // If we're reducing from 256/512 bits, use an extract_subvector.
6511 if (Size > 128) {
6512 auto *SubTy = FixedVectorType::get(ValVTy->getElementType(), NumVecElts);
6513 ReductionCost += getShuffleCost(TTI::SK_ExtractSubvector, Ty, Ty,
6514 CostKind, {}, NumVecElts, SubTy);
6515 Ty = SubTy;
6516 } else if (Size == 128) {
6517 // Reducing from 128 bits is a permute of v2f64/v2i64.
6518 FixedVectorType *ShufTy;
6519 if (ValVTy->isFloatingPointTy())
6520 ShufTy =
6521 FixedVectorType::get(Type::getDoubleTy(ValVTy->getContext()), 2);
6522 else
6523 ShufTy =
6524 FixedVectorType::get(Type::getInt64Ty(ValVTy->getContext()), 2);
6525 ReductionCost += getShuffleCost(TTI::SK_PermuteSingleSrc, ShufTy, ShufTy,
6526 CostKind, {}, 0, nullptr);
6527 } else if (Size == 64) {
6528 // Reducing from 64 bits is a shuffle of v4f32/v4i32.
6529 FixedVectorType *ShufTy;
6530 if (ValVTy->isFloatingPointTy())
6531 ShufTy =
6532 FixedVectorType::get(Type::getFloatTy(ValVTy->getContext()), 4);
6533 else
6534 ShufTy =
6535 FixedVectorType::get(Type::getInt32Ty(ValVTy->getContext()), 4);
6536 ReductionCost += getShuffleCost(TTI::SK_PermuteSingleSrc, ShufTy, ShufTy,
6537 CostKind, {}, 0, nullptr);
6538 } else {
6539 // Reducing from smaller size is a shift by immediate.
6540 auto *ShiftTy = FixedVectorType::get(
6541 Type::getIntNTy(ValVTy->getContext(), Size), 128 / Size);
6542 ReductionCost += getArithmeticInstrCost(
6543 Instruction::LShr, ShiftTy, CostKind,
6546 }
6547
6548 // Add the arithmetic op for this level.
6549 ReductionCost += getArithmeticInstrCost(Opcode, Ty, CostKind);
6550 }
6551
6552 // Add the final extract element to the cost.
6553 return ReductionCost + getVectorInstrCost(Instruction::ExtractElement, Ty,
6554 CostKind, 0, nullptr, nullptr,
6556}
6557
6560 FastMathFlags FMF) const {
6561 IntrinsicCostAttributes ICA(IID, Ty, {Ty, Ty}, FMF);
6562 return getIntrinsicInstrCost(ICA, CostKind);
6563}
6564
6567 FastMathFlags FMF,
6569 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(ValTy);
6570
6571 MVT MTy = LT.second;
6572
6574 if (ValTy->isIntOrIntVectorTy()) {
6575 ISD = (IID == Intrinsic::umin || IID == Intrinsic::umax) ? ISD::UMIN
6576 : ISD::SMIN;
6577 } else {
6578 assert(ValTy->isFPOrFPVectorTy() &&
6579 "Expected float point or integer vector type.");
6580 ISD = (IID == Intrinsic::minnum || IID == Intrinsic::maxnum)
6581 ? ISD::FMINNUM
6582 : ISD::FMINIMUM;
6583 }
6584
6585 // We use llvm-mca across all supported CPUs to measure the cost stats.
6586 static const CostKindTblEntry SSE2CostTbl[] = {
6587 {ISD::SMIN, MVT::v2i64, {3, 4, 5, 6}},
6588 {ISD::UMIN, MVT::v2i64, {3, 4, 5, 6}},
6589 {ISD::SMIN, MVT::v2i32, {2, 2, 5, 6}},
6590 {ISD::UMIN, MVT::v2i32, {2, 2, 5, 6}},
6591 {ISD::SMIN, MVT::v4i32, {3, 7,11,12}},
6592 {ISD::UMIN, MVT::v4i32, {4, 7,14,15}},
6593 {ISD::SMIN, MVT::v2i16, {2, 3, 4, 4}},
6594 {ISD::UMIN, MVT::v2i16, {2, 3, 4, 6}},
6595 {ISD::SMIN, MVT::v4i16, {3, 5, 6, 6}},
6596 {ISD::UMIN, MVT::v4i16, {3, 5, 8, 10}},
6597 {ISD::SMIN, MVT::v8i16, {3, 8, 8, 8}},
6598 {ISD::UMIN, MVT::v8i16, {4, 8,12,14}},
6599 {ISD::SMIN, MVT::v2i8, {2, 3, 5, 6}},
6600 {ISD::UMIN, MVT::v2i8, {2, 3, 4, 4}},
6601 {ISD::SMIN, MVT::v4i8, {4, 6,12,13}},
6602 {ISD::UMIN, MVT::v4i8, {3, 6, 7, 7}},
6603 {ISD::SMIN, MVT::v8i8, {5, 9,18,19}},
6604 {ISD::UMIN, MVT::v8i8, {4, 8, 9, 9}},
6605 {ISD::SMIN, MVT::v16i8, {7,13,24,25}},
6606 {ISD::UMIN, MVT::v16i8, {3,10,11,11}},
6607 };
6608
6609 static const CostKindTblEntry SSE41CostTbl[] = {
6610 {ISD::SMIN, MVT::v2i64, {3, 4, 4, 6}},
6611 {ISD::UMIN, MVT::v2i64, {3, 4, 4, 6}},
6612 {ISD::SMIN, MVT::v2i32, {2, 2, 3, 3}},
6613 {ISD::UMIN, MVT::v2i32, {2, 2, 3, 3}},
6614 {ISD::SMIN, MVT::v4i32, {3, 4, 5, 5}},
6615 {ISD::UMIN, MVT::v4i32, {3, 4, 5, 5}},
6616 {ISD::UMIN, MVT::v2i16, {2, 3, 4, 4}},
6617 {ISD::SMIN, MVT::v4i16, {3, 5, 6, 6}},
6618 {ISD::UMIN, MVT::v4i16, {3, 5, 6, 6}},
6619 {ISD::SMIN, MVT::v8i16, {2, 8, 4, 5}},
6620 {ISD::UMIN, MVT::v8i16, {2, 5, 2, 2}},
6621 {ISD::SMIN, MVT::v2i8, {2, 3, 4, 4}},
6622 {ISD::SMIN, MVT::v4i8, {3, 6, 7, 7}},
6623 {ISD::SMIN, MVT::v8i8, {4, 8, 9, 9}},
6624 {ISD::SMIN, MVT::v16i8, {3,10, 7, 8}},
6625 {ISD::UMIN, MVT::v16i8, {3, 8, 5, 5}},
6626 };
6627
6628 static const CostKindTblEntry AVX1CostTbl[] = {
6629 {ISD::SMIN, MVT::v4i64, {5,11, 7,10}},
6630 {ISD::UMIN, MVT::v4i64, {6,12,10,13}},
6631 {ISD::SMIN, MVT::v8i32, {4, 9, 7, 7}},
6632 {ISD::UMIN, MVT::v8i32, {4, 9, 7, 7}},
6633 {ISD::SMIN, MVT::v16i16, {3,15, 6, 7}},
6634 {ISD::UMIN, MVT::v16i16, {2, 9, 4, 4}},
6635 {ISD::SMIN, MVT::v32i8, {4,17, 8, 9}},
6636 {ISD::UMIN, MVT::v32i8, {3,11, 6, 6}},
6637 };
6638
6639 static const CostKindTblEntry AVX2CostTbl[] = {
6640 {ISD::SMIN, MVT::v4i64, {4,11, 7,10}},
6641 {ISD::UMIN, MVT::v4i64, {4,12,10,13}},
6642 {ISD::SMIN, MVT::v2i32, {1, 2, 3, 3}},
6643 {ISD::UMIN, MVT::v2i32, {1, 2, 3, 3}},
6644 {ISD::UMIN, MVT::v4i32, {2, 4, 5, 5}},
6645 {ISD::SMIN, MVT::v4i32, {2, 4, 5, 5}},
6646 {ISD::SMIN, MVT::v8i32, {3, 9, 7, 7}},
6647 {ISD::UMIN, MVT::v8i32, {3, 9, 7, 7}},
6648 {ISD::SMIN, MVT::v4i16, {2, 4, 5, 5}},
6649 {ISD::UMIN, MVT::v4i16, {2, 4, 5, 5}},
6650 {ISD::SMIN, MVT::v16i16, {2,15, 6, 7}},
6651 {ISD::SMIN, MVT::v8i8, {3, 6, 7, 7}},
6652 {ISD::UMIN, MVT::v8i8, {3, 6, 7, 7}},
6653 {ISD::SMIN, MVT::v32i8, {3,17, 8, 9}},
6654 };
6655
6656 static const CostKindTblEntry AVX512FCostTbl[] = {
6657 {ISD::SMIN, MVT::v2i64, {2, 4, 3, 3}},
6658 {ISD::UMIN, MVT::v2i64, {2, 4, 3, 3}},
6659 {ISD::SMIN, MVT::v4i64, {3,10, 5, 5}},
6660 {ISD::UMIN, MVT::v4i64, {3,10, 5, 5}},
6661 {ISD::SMIN, MVT::v8i64, {5,16, 7, 7}},
6662 {ISD::UMIN, MVT::v8i64, {5,16, 7, 7}},
6663 {ISD::SMIN, MVT::v16i32, {4,12, 9, 9}},
6664 {ISD::UMIN, MVT::v16i32, {4,12, 9, 9}},
6665 };
6666
6667 static const CostKindTblEntry AVX512BWCostTbl[] = {
6668 {ISD::SMIN, MVT::v2i16, {1, 2, 3, 3}},
6669 {ISD::UMIN, MVT::v2i16, {1, 2, 3, 3}},
6670 {ISD::SMIN, MVT::v32i16, {2,19, 8, 9}},
6671 {ISD::UMIN, MVT::v32i16, {2,12, 6, 6}},
6672 {ISD::SMIN, MVT::v2i8, {1, 2, 3, 3}},
6673 {ISD::UMIN, MVT::v2i8, {1, 2, 3, 3}},
6674 {ISD::SMIN, MVT::v4i8, {2, 4, 5, 5}},
6675 {ISD::UMIN, MVT::v4i8, {2, 4, 5, 5}},
6676 {ISD::SMIN, MVT::v16i8, {2,10, 6, 7}},
6677 {ISD::UMIN, MVT::v16i8, {2, 6, 4, 4}},
6678 {ISD::SMIN, MVT::v32i8, {2,17, 8, 9}},
6679 {ISD::UMIN, MVT::v32i8, {2,10, 6, 6}},
6680 {ISD::SMIN, MVT::v64i8, {2,21,10,11}},
6681 {ISD::UMIN, MVT::v64i8, {2,14, 8, 8}},
6682 };
6683
6684 // Before legalizing the type, give a chance to look up illegal narrow types
6685 // in the table.
6686 // FIXME: Is there a better way to do this?
6687 EVT VT = TLI->getValueType(DL, ValTy);
6688 if (VT.isSimple()) {
6689 MVT MTy = VT.getSimpleVT();
6690 if (ST->hasBWI())
6691 if (const auto *Entry = CostTableLookup(AVX512BWCostTbl, ISD, MTy))
6692 if (auto KindCost = Entry->Cost[CostKind])
6693 return *KindCost;
6694
6695 if (ST->hasAVX512())
6696 if (const auto *Entry = CostTableLookup(AVX512FCostTbl, ISD, MTy))
6697 if (auto KindCost = Entry->Cost[CostKind])
6698 return *KindCost;
6699
6700 if (ST->hasAVX2())
6701 if (const auto *Entry = CostTableLookup(AVX2CostTbl, ISD, MTy))
6702 if (auto KindCost = Entry->Cost[CostKind])
6703 return *KindCost;
6704
6705 if (ST->hasAVX())
6706 if (const auto *Entry = CostTableLookup(AVX1CostTbl, ISD, MTy))
6707 if (auto KindCost = Entry->Cost[CostKind])
6708 return *KindCost;
6709
6710 if (ST->hasSSE41())
6711 if (const auto *Entry = CostTableLookup(SSE41CostTbl, ISD, MTy))
6712 if (auto KindCost = Entry->Cost[CostKind])
6713 return *KindCost;
6714
6715 if (ST->hasSSE2())
6716 if (const auto *Entry = CostTableLookup(SSE2CostTbl, ISD, MTy))
6717 if (auto KindCost = Entry->Cost[CostKind])
6718 return *KindCost;
6719 }
6720
6721 auto *ValVTy = cast<FixedVectorType>(ValTy);
6722 unsigned NumVecElts = ValVTy->getNumElements();
6723
6724 auto *Ty = ValVTy;
6725 InstructionCost MinMaxCost = 0;
6726 if (LT.first != 1 && MTy.isVector() &&
6727 MTy.getVectorNumElements() < ValVTy->getNumElements()) {
6728 // Type needs to be split. We need LT.first - 1 operations ops.
6729 Ty = FixedVectorType::get(ValVTy->getElementType(),
6730 MTy.getVectorNumElements());
6731 MinMaxCost = getMinMaxCost(IID, Ty, CostKind, FMF);
6732 MinMaxCost *= LT.first - 1;
6733 NumVecElts = MTy.getVectorNumElements();
6734 }
6735
6736 if (ST->hasBWI())
6737 if (const auto *Entry = CostTableLookup(AVX512BWCostTbl, ISD, MTy))
6738 if (auto KindCost = Entry->Cost[CostKind])
6739 return MinMaxCost + *KindCost;
6740
6741 if (ST->hasAVX512())
6742 if (const auto *Entry = CostTableLookup(AVX512FCostTbl, ISD, MTy))
6743 if (auto KindCost = Entry->Cost[CostKind])
6744 return MinMaxCost + *KindCost;
6745
6746 if (ST->hasAVX2())
6747 if (const auto *Entry = CostTableLookup(AVX2CostTbl, ISD, MTy))
6748 if (auto KindCost = Entry->Cost[CostKind])
6749 return MinMaxCost + *KindCost;
6750
6751 if (ST->hasAVX())
6752 if (const auto *Entry = CostTableLookup(AVX1CostTbl, ISD, MTy))
6753 if (auto KindCost = Entry->Cost[CostKind])
6754 return MinMaxCost + *KindCost;
6755
6756 if (ST->hasSSE41())
6757 if (const auto *Entry = CostTableLookup(SSE41CostTbl, ISD, MTy))
6758 if (auto KindCost = Entry->Cost[CostKind])
6759 return MinMaxCost + *KindCost;
6760
6761 if (ST->hasSSE2())
6762 if (const auto *Entry = CostTableLookup(SSE2CostTbl, ISD, MTy))
6763 if (auto KindCost = Entry->Cost[CostKind])
6764 return MinMaxCost + *KindCost;
6765
6766 unsigned ScalarSize = ValTy->getScalarSizeInBits();
6767
6768 // Special case power of 2 reductions where the scalar type isn't changed
6769 // by type legalization.
6770 if (!isPowerOf2_32(ValVTy->getNumElements()) ||
6771 ScalarSize != MTy.getScalarSizeInBits())
6772 return BaseT::getMinMaxReductionCost(IID, ValTy, FMF, CostKind);
6773
6774 // Now handle reduction with the legal type, taking into account size changes
6775 // at each level.
6776 while (NumVecElts > 1) {
6777 // Determine the size of the remaining vector we need to reduce.
6778 unsigned Size = NumVecElts * ScalarSize;
6779 NumVecElts /= 2;
6780 // If we're reducing from 256/512 bits, use an extract_subvector.
6781 if (Size > 128) {
6782 auto *SubTy = FixedVectorType::get(ValVTy->getElementType(), NumVecElts);
6783 MinMaxCost += getShuffleCost(TTI::SK_ExtractSubvector, Ty, Ty, CostKind,
6784 {}, NumVecElts, SubTy);
6785 Ty = SubTy;
6786 } else if (Size == 128) {
6787 // Reducing from 128 bits is a permute of v2f64/v2i64.
6788 VectorType *ShufTy;
6789 if (ValTy->isFloatingPointTy())
6790 ShufTy =
6792 else
6793 ShufTy = FixedVectorType::get(Type::getInt64Ty(ValTy->getContext()), 2);
6794 MinMaxCost += getShuffleCost(TTI::SK_PermuteSingleSrc, ShufTy, ShufTy,
6795 CostKind, {}, 0, nullptr);
6796 } else if (Size == 64) {
6797 // Reducing from 64 bits is a shuffle of v4f32/v4i32.
6798 FixedVectorType *ShufTy;
6799 if (ValTy->isFloatingPointTy())
6800 ShufTy = FixedVectorType::get(Type::getFloatTy(ValTy->getContext()), 4);
6801 else
6802 ShufTy = FixedVectorType::get(Type::getInt32Ty(ValTy->getContext()), 4);
6803 MinMaxCost += getShuffleCost(TTI::SK_PermuteSingleSrc, ShufTy, ShufTy,
6804 CostKind, {}, 0, nullptr);
6805 } else {
6806 // Reducing from smaller size is a shift by immediate.
6807 auto *ShiftTy = FixedVectorType::get(
6808 Type::getIntNTy(ValTy->getContext(), Size), 128 / Size);
6809 MinMaxCost += getArithmeticInstrCost(
6810 Instruction::LShr, ShiftTy, TTI::TCK_RecipThroughput,
6813 }
6814
6815 // Add the arithmetic op for this level.
6816 MinMaxCost += getMinMaxCost(IID, Ty, CostKind, FMF);
6817 }
6818
6819 // Add the final extract element to the cost.
6820 return MinMaxCost + getVectorInstrCost(Instruction::ExtractElement, Ty,
6821 CostKind, 0, nullptr, nullptr,
6823}
6824
6825/// Calculate the cost of materializing a 64-bit value. This helper
6826/// method might only calculate a fraction of a larger immediate. Therefore it
6827/// is valid to return a cost of ZERO.
6829 if (Val == 0)
6830 return TTI::TCC_Free;
6831
6832 if (isInt<32>(Val))
6833 return TTI::TCC_Basic;
6834
6835 return 2 * TTI::TCC_Basic;
6836}
6837
6840 assert(Ty->isIntegerTy());
6841
6842 unsigned BitSize = Ty->getPrimitiveSizeInBits();
6843 if (BitSize == 0)
6844 return ~0U;
6845
6846 // Never hoist constants larger than 128bit, because this might lead to
6847 // incorrect code generation or assertions in codegen.
6848 // Fixme: Create a cost model for types larger than i128 once the codegen
6849 // issues have been fixed.
6850 if (BitSize > 128)
6851 return TTI::TCC_Free;
6852
6853 if (Imm == 0)
6854 return TTI::TCC_Free;
6855
6856 // Sign-extend all constants to a multiple of 64-bit.
6857 APInt ImmVal = Imm;
6858 if (BitSize % 64 != 0)
6859 ImmVal = Imm.sext(alignTo(BitSize, 64));
6860
6861 // Split the constant into 64-bit chunks and calculate the cost for each
6862 // chunk.
6864 for (unsigned ShiftVal = 0; ShiftVal < BitSize; ShiftVal += 64) {
6865 APInt Tmp = ImmVal.ashr(ShiftVal).sextOrTrunc(64);
6866 int64_t Val = Tmp.getSExtValue();
6867 Cost += getIntImmCost(Val);
6868 }
6869 // We need at least one instruction to materialize the constant.
6870 return std::max<InstructionCost>(1, Cost);
6871}
6872
6874 const APInt &Imm, Type *Ty,
6876 Instruction *Inst) const {
6877 assert(Ty->isIntegerTy());
6878
6879 unsigned BitSize = Ty->getPrimitiveSizeInBits();
6880 unsigned ImmBitWidth = Imm.getBitWidth();
6881
6882 // There is no cost model for constants with a bit size of 0. Return TCC_Free
6883 // here, so that constant hoisting will ignore this constant.
6884 if (BitSize == 0)
6885 return TTI::TCC_Free;
6886
6887 unsigned ImmIdx = ~0U;
6888 switch (Opcode) {
6889 default:
6890 return TTI::TCC_Free;
6891 case Instruction::GetElementPtr:
6892 // Always hoist the base address of a GetElementPtr. This prevents the
6893 // creation of new constants for every base constant that gets constant
6894 // folded with the offset.
6895 if (Idx == 0)
6896 return 2 * TTI::TCC_Basic;
6897 return TTI::TCC_Free;
6898 case Instruction::Store:
6899 ImmIdx = 0;
6900 break;
6901 case Instruction::ICmp:
6902 // This is an imperfect hack to prevent constant hoisting of
6903 // compares that might be trying to check if a 64-bit value fits in
6904 // 32-bits. The backend can optimize these cases using a right shift by 32.
6905 // There are other predicates and immediates the backend can use shifts for.
6906 if (Idx == 1 && ImmBitWidth == 64) {
6907 uint64_t ImmVal = Imm.getZExtValue();
6908 if (ImmVal == 0x100000000ULL || ImmVal == 0xffffffff)
6909 return TTI::TCC_Free;
6910
6911 if (auto *Cmp = dyn_cast_or_null<CmpInst>(Inst)) {
6912 if (Cmp->isEquality()) {
6913 KnownBits Known = computeKnownBits(Cmp->getOperand(0), DL);
6914 if (Known.countMinTrailingZeros() >= 32)
6915 return TTI::TCC_Free;
6916 }
6917 }
6918 }
6919 ImmIdx = 1;
6920 break;
6921 case Instruction::And:
6922 // We support 64-bit ANDs with immediates with 32-bits of leading zeroes
6923 // by using a 32-bit operation with implicit zero extension. Detect such
6924 // immediates here as the normal path expects bit 31 to be sign extended.
6925 if (Idx == 1 && ImmBitWidth == 64 && Imm.isIntN(32))
6926 return TTI::TCC_Free;
6927 // If we have BMI then we can use BEXTR/BZHI to mask out upper i64 bits.
6928 if (Idx == 1 && ImmBitWidth == 64 && ST->is64Bit() && ST->hasBMI() &&
6929 Imm.isMask())
6930 return X86TTIImpl::getIntImmCost(ST->hasBMI2() ? 255 : 65535);
6931 ImmIdx = 1;
6932 break;
6933 case Instruction::Add:
6934 case Instruction::Sub:
6935 // For add/sub, we can use the opposite instruction for INT32_MIN.
6936 if (Idx == 1 && ImmBitWidth == 64 && Imm.getZExtValue() == 0x80000000)
6937 return TTI::TCC_Free;
6938 ImmIdx = 1;
6939 break;
6940 case Instruction::UDiv:
6941 case Instruction::SDiv:
6942 case Instruction::URem:
6943 case Instruction::SRem:
6944 // Division by constant is typically expanded later into a different
6945 // instruction sequence. This completely changes the constants.
6946 // Report them as "free" to stop ConstantHoist from marking them as opaque.
6947 return TTI::TCC_Free;
6948 case Instruction::Mul:
6949 case Instruction::Or:
6950 case Instruction::Xor:
6951 ImmIdx = 1;
6952 break;
6953 // Always return TCC_Free for the shift value of a shift instruction.
6954 case Instruction::Shl:
6955 case Instruction::LShr:
6956 case Instruction::AShr:
6957 if (Idx == 1)
6958 return TTI::TCC_Free;
6959 break;
6960 case Instruction::Trunc:
6961 case Instruction::ZExt:
6962 case Instruction::SExt:
6963 case Instruction::IntToPtr:
6964 case Instruction::PtrToInt:
6965 case Instruction::BitCast:
6966 case Instruction::PHI:
6967 case Instruction::Call:
6968 case Instruction::Select:
6969 case Instruction::Ret:
6970 case Instruction::Load:
6971 break;
6972 }
6973
6974 if (Idx == ImmIdx) {
6975 uint64_t NumConstants = divideCeil(BitSize, 64);
6977 return (Cost <= NumConstants * TTI::TCC_Basic)
6978 ? static_cast<int>(TTI::TCC_Free)
6979 : Cost;
6980 }
6981
6983}
6984
6987 const APInt &Imm, Type *Ty,
6989 assert(Ty->isIntegerTy());
6990
6991 unsigned BitSize = Ty->getPrimitiveSizeInBits();
6992 // There is no cost model for constants with a bit size of 0. Return TCC_Free
6993 // here, so that constant hoisting will ignore this constant.
6994 if (BitSize == 0)
6995 return TTI::TCC_Free;
6996
6997 switch (IID) {
6998 default:
6999 return TTI::TCC_Free;
7000 case Intrinsic::sadd_with_overflow:
7001 case Intrinsic::uadd_with_overflow:
7002 case Intrinsic::ssub_with_overflow:
7003 case Intrinsic::usub_with_overflow:
7004 case Intrinsic::smul_with_overflow:
7005 case Intrinsic::umul_with_overflow:
7006 if ((Idx == 1) && Imm.getBitWidth() <= 64 && Imm.isSignedIntN(32))
7007 return TTI::TCC_Free;
7008 break;
7009 case Intrinsic::experimental_stackmap:
7010 if ((Idx < 2) || (Imm.getBitWidth() <= 64 && Imm.isSignedIntN(64)))
7011 return TTI::TCC_Free;
7012 break;
7013 case Intrinsic::experimental_patchpoint_void:
7014 case Intrinsic::experimental_patchpoint:
7015 if ((Idx < 4) || (Imm.getBitWidth() <= 64 && Imm.isSignedIntN(64)))
7016 return TTI::TCC_Free;
7017 break;
7018 }
7020}
7021
7024 const Instruction *I) const {
7026 return Opcode == Instruction::PHI ? TTI::TCC_Free : TTI::TCC_Basic;
7027 // Branches are assumed to be predicted.
7028 return TTI::TCC_Free;
7029}
7030
7031int X86TTIImpl::getGatherOverhead() const {
7032 // Some CPUs have more overhead for gather. The specified overhead is relative
7033 // to the Load operation. "2" is the number provided by Intel architects. This
7034 // parameter is used for cost estimation of Gather Op and comparison with
7035 // other alternatives.
7036 // TODO: Remove the explicit hasAVX512()?, That would mean we would only
7037 // enable gather with a -march.
7038 if (ST->hasAVX512() || (ST->hasAVX2() && ST->hasFastGather()))
7039 return 2;
7040
7041 return 1024;
7042}
7043
7044int X86TTIImpl::getScatterOverhead() const {
7045 if (ST->hasAVX512())
7046 return 2;
7047
7048 return 1024;
7049}
7050
7051// Return an average cost of Gather / Scatter instruction, maybe improved later.
7052InstructionCost X86TTIImpl::getGSVectorCost(unsigned Opcode,
7054 Type *SrcVTy, const Value *Ptr,
7055 Align Alignment,
7056 unsigned AddressSpace) const {
7057
7058 assert(isa<VectorType>(SrcVTy) && "Unexpected type in getGSVectorCost");
7059 unsigned VF = cast<FixedVectorType>(SrcVTy)->getNumElements();
7060
7061 // Try to reduce index size from 64 bit (default for GEP)
7062 // to 32. It is essential for VF 16. If the index can't be reduced to 32, the
7063 // operation will use 16 x 64 indices which do not fit in a zmm and needs
7064 // to split. Also check that the base pointer is the same for all lanes,
7065 // and that there's at most one variable index.
7066 auto getIndexSizeInBits = [](const Value *Ptr, const DataLayout &DL) {
7067 unsigned IndexSize = DL.getPointerSizeInBits();
7068 const GetElementPtrInst *GEP = dyn_cast_or_null<GetElementPtrInst>(Ptr);
7069 if (IndexSize < 64 || !GEP)
7070 return IndexSize;
7071
7072 unsigned NumOfVarIndices = 0;
7073 const Value *Ptrs = GEP->getPointerOperand();
7074 if (Ptrs->getType()->isVectorTy() && !getSplatValue(Ptrs))
7075 return IndexSize;
7076 for (unsigned I = 1, E = GEP->getNumOperands(); I != E; ++I) {
7077 if (isa<Constant>(GEP->getOperand(I)))
7078 continue;
7079 Type *IndxTy = GEP->getOperand(I)->getType();
7080 if (auto *IndexVTy = dyn_cast<VectorType>(IndxTy))
7081 IndxTy = IndexVTy->getElementType();
7082 if ((IndxTy->getPrimitiveSizeInBits() == 64 &&
7083 !isa<SExtInst>(GEP->getOperand(I))) ||
7084 ++NumOfVarIndices > 1)
7085 return IndexSize; // 64
7086 }
7087 return (unsigned)32;
7088 };
7089
7090 // Trying to reduce IndexSize to 32 bits for vector 16.
7091 // By default the IndexSize is equal to pointer size.
7092 unsigned IndexSize = (ST->hasAVX512() && VF >= 16)
7093 ? getIndexSizeInBits(Ptr, DL)
7094 : DL.getPointerSizeInBits();
7095
7096 auto *IndexVTy = FixedVectorType::get(
7097 IntegerType::get(SrcVTy->getContext(), IndexSize), VF);
7098 std::pair<InstructionCost, MVT> IdxsLT = getTypeLegalizationCost(IndexVTy);
7099 std::pair<InstructionCost, MVT> SrcLT = getTypeLegalizationCost(SrcVTy);
7100 InstructionCost::CostType SplitFactor =
7101 std::max(IdxsLT.first, SrcLT.first).getValue();
7102 if (SplitFactor > 1) {
7103 // Handle splitting of vector of pointers
7104 auto *SplitSrcTy =
7105 FixedVectorType::get(SrcVTy->getScalarType(), VF / SplitFactor);
7106 return SplitFactor * getGSVectorCost(Opcode, CostKind, SplitSrcTy, Ptr,
7107 Alignment, AddressSpace);
7108 }
7109
7110 // If we didn't split, this will be a single gather/scatter instruction.
7112 return 1;
7113
7114 // The gather / scatter cost is given by Intel architects. It is a rough
7115 // number since we are looking at one instruction in a time.
7116 const int GSOverhead = (Opcode == Instruction::Load) ? getGatherOverhead()
7117 : getScatterOverhead();
7118 return GSOverhead + VF * getMemoryOpCost(Opcode, SrcVTy->getScalarType(),
7119 Alignment, AddressSpace, CostKind);
7120}
7121
7122/// Calculate the cost of Gather / Scatter operation
7126 bool IsLoad = MICA.getID() == Intrinsic::masked_gather ||
7127 MICA.getID() == Intrinsic::vp_gather;
7128 unsigned Opcode = IsLoad ? Instruction::Load : Instruction::Store;
7129 Type *SrcVTy = MICA.getDataType();
7130 const Value *Ptr = MICA.getPointer();
7131 Align Alignment = MICA.getAlignment();
7132 if ((Opcode == Instruction::Load &&
7133 (!isLegalMaskedGather(SrcVTy, Align(Alignment)) ||
7135 Align(Alignment)))) ||
7136 (Opcode == Instruction::Store &&
7137 (!isLegalMaskedScatter(SrcVTy, Align(Alignment)) ||
7139 Align(Alignment)))))
7141
7142 assert(SrcVTy->isVectorTy() && "Unexpected data type for Gather/Scatter");
7143 unsigned AddressSpace = MICA.getAddressSpace();
7144 return getGSVectorCost(Opcode, CostKind, SrcVTy, Ptr, Alignment,
7145 AddressSpace);
7146}
7147
7149 const TargetTransformInfo::LSRCost &C2) const {
7150 // X86 specific here are "instruction number 1st priority".
7151 return std::tie(C1.Insns, C1.NumRegs, C1.AddRecCost, C1.NumIVMuls,
7152 C1.NumBaseAdds, C1.ScaleCost, C1.ImmCost, C1.SetupCost) <
7153 std::tie(C2.Insns, C2.NumRegs, C2.AddRecCost, C2.NumIVMuls,
7154 C2.NumBaseAdds, C2.ScaleCost, C2.ImmCost, C2.SetupCost);
7155}
7156
7158 return ST->hasMacroFusion() || ST->hasBranchFusion();
7159}
7160
7161static bool isLegalMaskedLoadStore(Type *ScalarTy, const X86Subtarget *ST) {
7162 if (!ST->hasAVX())
7163 return false;
7164
7165 if (ScalarTy->isPointerTy())
7166 return true;
7167
7168 if (ScalarTy->isFloatTy() || ScalarTy->isDoubleTy())
7169 return true;
7170
7171 if (ScalarTy->isHalfTy() && ST->hasBWI())
7172 return true;
7173
7174 if (ScalarTy->isBFloatTy() && ST->hasBF16())
7175 return true;
7176
7177 if (!ScalarTy->isIntegerTy())
7178 return false;
7179
7180 unsigned IntWidth = ScalarTy->getIntegerBitWidth();
7181 return IntWidth == 32 || IntWidth == 64 ||
7182 ((IntWidth == 8 || IntWidth == 16) && ST->hasBWI());
7183}
7184
7186 unsigned AddressSpace,
7187 TTI::MaskKind MaskKind) const {
7188 Type *ScalarTy = DataTy->getScalarType();
7189
7190 // The backend can't handle a single element vector w/o CFCMOV.
7191 if (isa<VectorType>(DataTy) &&
7192 cast<FixedVectorType>(DataTy)->getNumElements() == 1)
7193 return ST->hasCF() &&
7194 hasConditionalLoadStoreForType(ScalarTy, /*IsStore=*/false);
7195
7196 return isLegalMaskedLoadStore(ScalarTy, ST);
7197}
7198
7200 unsigned AddressSpace,
7201 TTI::MaskKind MaskKind) const {
7202 Type *ScalarTy = DataTy->getScalarType();
7203
7204 // The backend can't handle a single element vector w/o CFCMOV.
7205 if (isa<VectorType>(DataTy) &&
7206 cast<FixedVectorType>(DataTy)->getNumElements() == 1)
7207 return ST->hasCF() &&
7208 hasConditionalLoadStoreForType(ScalarTy, /*IsStore=*/true);
7209
7210 return isLegalMaskedLoadStore(ScalarTy, ST);
7211}
7212
7213bool X86TTIImpl::isLegalNTLoad(Type *DataType, Align Alignment) const {
7214 unsigned DataSize = DL.getTypeStoreSize(DataType);
7215 // The only supported nontemporal loads are for aligned vectors of 16 or 32
7216 // bytes. Note that 32-byte nontemporal vector loads are supported by AVX2
7217 // (the equivalent stores only require AVX).
7218 if (Alignment >= DataSize && (DataSize == 16 || DataSize == 32))
7219 return DataSize == 16 ? ST->hasSSE1() : ST->hasAVX2();
7220
7221 return false;
7222}
7223
7224bool X86TTIImpl::isLegalNTStore(Type *DataType, Align Alignment) const {
7225 unsigned DataSize = DL.getTypeStoreSize(DataType);
7226
7227 // SSE4A supports nontemporal stores of float and double at arbitrary
7228 // alignment.
7229 if (ST->hasSSE4A() && (DataType->isFloatTy() || DataType->isDoubleTy()))
7230 return true;
7231
7232 // Besides the SSE4A subtarget exception above, only aligned stores are
7233 // available nontemporaly on any other subtarget. And only stores with a size
7234 // of 4..32 bytes (powers of 2, only) are permitted.
7235 if (Alignment < DataSize || DataSize < 4 || DataSize > 32 ||
7236 !isPowerOf2_32(DataSize))
7237 return false;
7238
7239 // 32-byte vector nontemporal stores are supported by AVX (the equivalent
7240 // loads require AVX2).
7241 if (DataSize == 32)
7242 return ST->hasAVX();
7243 if (DataSize == 16)
7244 return ST->hasSSE1();
7245 return true;
7246}
7247
7249 ElementCount NumElements) const {
7250 // movddup
7251 return ST->hasSSE3() && !NumElements.isScalable() &&
7252 NumElements.getFixedValue() == 2 &&
7253 ElementTy == Type::getDoubleTy(ElementTy->getContext());
7254}
7255
7256bool X86TTIImpl::isLegalMaskedExpandLoad(Type *DataTy, Align Alignment) const {
7257 if (!isa<VectorType>(DataTy))
7258 return false;
7259
7260 if (!ST->hasAVX512())
7261 return false;
7262
7263 // The backend can't handle a single element vector.
7264 if (cast<FixedVectorType>(DataTy)->getNumElements() == 1)
7265 return false;
7266
7267 Type *ScalarTy = cast<VectorType>(DataTy)->getElementType();
7268
7269 if (ScalarTy->isFloatTy() || ScalarTy->isDoubleTy())
7270 return true;
7271
7272 if (!ScalarTy->isIntegerTy())
7273 return false;
7274
7275 unsigned IntWidth = ScalarTy->getIntegerBitWidth();
7276 return IntWidth == 32 || IntWidth == 64 ||
7277 ((IntWidth == 8 || IntWidth == 16) && ST->hasVBMI2());
7278}
7279
7281 Align Alignment) const {
7282 return isLegalMaskedExpandLoad(DataTy, Alignment);
7283}
7284
7285bool X86TTIImpl::supportsGather() const {
7286 // Some CPUs have better gather performance than others.
7287 // TODO: Remove the explicit ST->hasAVX512()?, That would mean we would only
7288 // enable gather with a -march.
7289 return ST->hasAVX512() || (ST->hasFastGather() && ST->hasAVX2());
7290}
7291
7293 Align Alignment) const {
7294 // Gather / Scatter for vector 2 is not profitable on KNL / SKX
7295 // Vector-4 of gather/scatter instruction does not exist on KNL. We can extend
7296 // it to 8 elements, but zeroing upper bits of the mask vector will add more
7297 // instructions. Right now we give the scalar cost of vector-4 for KNL. TODO:
7298 // Check, maybe the gather/scatter instruction is better in the VariableMask
7299 // case.
7300 unsigned NumElts = cast<FixedVectorType>(VTy)->getNumElements();
7301 return NumElts == 1 ||
7302 (ST->hasAVX512() && (NumElts == 2 || (NumElts == 4 && !ST->hasVLX())));
7303}
7304
7306 Align Alignment) const {
7307 Type *ScalarTy = DataTy->getScalarType();
7308 if (ScalarTy->isPointerTy())
7309 return true;
7310
7311 if (ScalarTy->isFloatTy() || ScalarTy->isDoubleTy())
7312 return true;
7313
7314 if (!ScalarTy->isIntegerTy())
7315 return false;
7316
7317 unsigned IntWidth = ScalarTy->getIntegerBitWidth();
7318 return IntWidth == 32 || IntWidth == 64;
7319}
7320
7321bool X86TTIImpl::isLegalMaskedGather(Type *DataTy, Align Alignment) const {
7322 if (!supportsGather() || !ST->preferGather())
7323 return false;
7324 return isLegalMaskedGatherScatter(DataTy, Alignment);
7325}
7326
7327bool X86TTIImpl::isLegalAltInstr(VectorType *VecTy, unsigned Opcode0,
7328 unsigned Opcode1,
7329 const SmallBitVector &OpcodeMask) const {
7330 // ADDSUBPS 4xf32 SSE3
7331 // VADDSUBPS 4xf32 AVX
7332 // VADDSUBPS 8xf32 AVX2
7333 // ADDSUBPD 2xf64 SSE3
7334 // VADDSUBPD 2xf64 AVX
7335 // VADDSUBPD 4xf64 AVX2
7336
7337 unsigned NumElements = cast<FixedVectorType>(VecTy)->getNumElements();
7338 assert(OpcodeMask.size() == NumElements && "Mask and VecTy are incompatible");
7339 if (!isPowerOf2_32(NumElements))
7340 return false;
7341 // Check the opcode pattern. We apply the mask on the opcode arguments and
7342 // then check if it is what we expect.
7343 for (int Lane : seq<int>(0, NumElements)) {
7344 unsigned Opc = OpcodeMask.test(Lane) ? Opcode1 : Opcode0;
7345 // We expect FSub for even lanes and FAdd for odd lanes.
7346 if (Lane % 2 == 0 && Opc != Instruction::FSub)
7347 return false;
7348 if (Lane % 2 == 1 && Opc != Instruction::FAdd)
7349 return false;
7350 }
7351 // Now check that the pattern is supported by the target ISA.
7352 Type *ElemTy = cast<VectorType>(VecTy)->getElementType();
7353 if (ElemTy->isFloatTy())
7354 return ST->hasSSE3() && NumElements % 4 == 0;
7355 if (ElemTy->isDoubleTy())
7356 return ST->hasSSE3() && NumElements % 2 == 0;
7357 return false;
7358}
7359
7360bool X86TTIImpl::isLegalMaskedScatter(Type *DataType, Align Alignment) const {
7361 // AVX2 doesn't support scatter
7362 if (!ST->hasAVX512() || !ST->preferScatter())
7363 return false;
7364 return isLegalMaskedGatherScatter(DataType, Alignment);
7365}
7366
7367bool X86TTIImpl::hasDivRemOp(Type *DataType, bool IsSigned) const {
7368 EVT VT = TLI->getValueType(DL, DataType);
7369 return TLI->isOperationLegal(IsSigned ? ISD::SDIVREM : ISD::UDIVREM, VT);
7370}
7371
7373 // FDIV is always expensive, even if it has a very low uop count.
7374 // TODO: Still necessary for recent CPUs with low latency/throughput fdiv?
7375 if (I->getOpcode() == Instruction::FDiv)
7376 return true;
7377
7379}
7380
7381bool X86TTIImpl::isFCmpOrdCheaperThanFCmpZero(Type *Ty) const { return false; }
7382
7384 const Function *Callee) const {
7385 const TargetMachine &TM = getTLI()->getTargetMachine();
7386
7387 // Work this as a subsetting of subtarget features.
7388 const X86Subtarget &CallerSubtarget = TM.getSubtarget<X86Subtarget>(*Caller);
7389 const X86Subtarget &CalleeSubtarget = TM.getSubtarget<X86Subtarget>(*Callee);
7390 const FeatureBitset &CallerBits = CallerSubtarget.getFeatureBits();
7391 const FeatureBitset &CalleeBits = CalleeSubtarget.getFeatureBits();
7392
7393 // Check whether callee features are a subset of caller features
7394 // (apart from the ignore list).
7395 const FeatureBitset &InlineIgnoreFeatures =
7396 CallerSubtarget.getInlineIgnoreFeatures();
7397 FeatureBitset RealCallerBits = CallerBits & ~InlineIgnoreFeatures;
7398 FeatureBitset RealCalleeBits = CalleeBits & ~InlineIgnoreFeatures;
7399 if ((RealCallerBits & RealCalleeBits) != RealCalleeBits)
7400 return false;
7401
7402 // If the features are not exactly the same (or there is a difference in
7403 // AVX512 register usage), we need to additionally check for calls
7404 // that may become ABI-incompatible as a result of inlining.
7405 if (RealCallerBits == RealCalleeBits &&
7406 CallerSubtarget.useAVX512Regs() == CalleeSubtarget.useAVX512Regs())
7407 return true;
7408
7409 for (const Instruction &I : instructions(Callee)) {
7410 if (const auto *CB = dyn_cast<CallBase>(&I)) {
7411 // Having more target features is fine for inline ASM and intrinsics.
7412 if (CB->isInlineAsm() || CB->getIntrinsicID() != Intrinsic::not_intrinsic)
7413 continue;
7414
7416 for (Value *Arg : CB->args())
7417 Types.push_back(Arg->getType());
7418 if (!CB->getType()->isVoidTy())
7419 Types.push_back(CB->getType());
7420
7421 // Simple types are always ABI compatible.
7422 auto IsSimpleTy = [](Type *Ty) {
7423 return !Ty->isVectorTy() && !Ty->isAggregateType();
7424 };
7425 if (all_of(Types, IsSimpleTy))
7426 continue;
7427
7428 // Do a precise compatibility check.
7429 if (!areTypesABICompatible(Caller, Callee, Types))
7430 return false;
7431 }
7432 }
7433 return true;
7434}
7435
7437 const Function *Callee,
7438 ArrayRef<Type *> Types) const {
7439 const TargetMachine &TM = getTLI()->getTargetMachine();
7440 const TargetLowering *CallerTLI =
7441 TM.getSubtargetImpl(*Caller)->getTargetLowering();
7442 const TargetLowering *CalleeTLI =
7443 TM.getSubtargetImpl(*Callee)->getTargetLowering();
7444
7445 LLVMContext &Ctx = Caller->getContext();
7446 const DataLayout &DL = Caller->getDataLayout();
7447 CallingConv::ID CC = Callee->getCallingConv();
7448 return all_of(Types, [&](Type *Ty) {
7449 SmallVector<EVT> VTs;
7450 ComputeValueVTs(*CallerTLI, DL, Ty, VTs);
7451 return all_of(VTs, [&](EVT VT) {
7452 return CallerTLI->getRegisterTypeForCallingConv(Ctx, CC, VT) ==
7453 CalleeTLI->getRegisterTypeForCallingConv(Ctx, CC, VT);
7454 });
7455 });
7456}
7457
7459X86TTIImpl::enableMemCmpExpansion(bool OptSize, bool IsZeroCmp) const {
7461 Options.MaxNumLoads = TLI->getMaxExpandSizeMemcmp(OptSize);
7462 Options.NumLoadsPerBlock = IsZeroCmp ? 2 : 1;
7463 // All GPR and vector loads can be unaligned.
7464 Options.AllowOverlappingLoads = true;
7465 if (IsZeroCmp) {
7466 // Only enable vector loads for equality comparison. Right now the vector
7467 // version is not as fast for three way compare (see #33329).
7468 const unsigned PreferredWidth = ST->getPreferVectorWidth();
7469 if (PreferredWidth >= 512 && ST->hasAVX512())
7470 Options.LoadSizes.push_back(64);
7471 if (PreferredWidth >= 256 && ST->hasAVX()) Options.LoadSizes.push_back(32);
7472 if (PreferredWidth >= 128 && ST->hasSSE2()) Options.LoadSizes.push_back(16);
7473 }
7474 if (ST->is64Bit()) {
7475 Options.LoadSizes.push_back(8);
7476 }
7477 Options.LoadSizes.push_back(4);
7478 Options.LoadSizes.push_back(2);
7479 Options.LoadSizes.push_back(1);
7480 return Options;
7481}
7482
7484 return supportsGather();
7485}
7486
7488 return false;
7489}
7490
7492 // TODO: We expect this to be beneficial regardless of arch,
7493 // but there are currently some unexplained performance artifacts on Atom.
7494 // As a temporary solution, disable on Atom.
7495 return !(ST->isAtom());
7496}
7497
7499 switch (II->getIntrinsicID()) {
7500 default:
7501 return true;
7502 case Intrinsic::vector_reduce_and:
7503 case Intrinsic::vector_reduce_or:
7504 case Intrinsic::vector_reduce_xor:
7505 case Intrinsic::vector_reduce_mul:
7506 case Intrinsic::vector_reduce_smax:
7507 case Intrinsic::vector_reduce_smin:
7508 case Intrinsic::vector_reduce_umax:
7509 case Intrinsic::vector_reduce_umin:
7510 return false;
7511 }
7512}
7513
7514// Get estimation for interleaved load/store operations and strided load.
7515// \p Indices contains indices for strided load.
7516// \p Factor - the factor of interleaving.
7517// AVX-512 provides 3-src shuffles that significantly reduces the cost.
7519 unsigned Opcode, FixedVectorType *VecTy, unsigned Factor,
7520 ArrayRef<unsigned> Indices, Align Alignment, unsigned AddressSpace,
7521 TTI::TargetCostKind CostKind, bool UseMaskForCond,
7522 bool UseMaskForGaps) const {
7523 // VecTy for interleave memop is <VF*Factor x Elt>.
7524 // So, for VF=4, Interleave Factor = 3, Element type = i32 we have
7525 // VecTy = <12 x i32>.
7526
7527 // Calculate the number of memory operations (NumOfMemOps), required
7528 // for load/store the VecTy.
7529 MVT LegalVT = getTypeLegalizationCost(VecTy).second;
7530 unsigned VecTySize = DL.getTypeStoreSize(VecTy);
7531 unsigned LegalVTSize = LegalVT.getStoreSize();
7532 unsigned NumOfMemOps = (VecTySize + LegalVTSize - 1) / LegalVTSize;
7533
7534 // Get the cost of one memory operation.
7535 auto *SingleMemOpTy = FixedVectorType::get(VecTy->getElementType(),
7536 LegalVT.getVectorNumElements());
7537 InstructionCost MemOpCost;
7538 bool UseMaskedMemOp = UseMaskForCond || UseMaskForGaps;
7539 if (UseMaskedMemOp) {
7540 unsigned IID = Opcode == Instruction::Load ? Intrinsic::masked_load
7541 : Intrinsic::masked_store;
7542 MemOpCost = getMaskedMemoryOpCost(
7543 {IID, SingleMemOpTy, Alignment, AddressSpace}, CostKind);
7544 } else
7545 MemOpCost = getMemoryOpCost(Opcode, SingleMemOpTy, Alignment, AddressSpace,
7546 CostKind);
7547
7548 unsigned VF = VecTy->getNumElements() / Factor;
7549 MVT VT =
7550 MVT::getVectorVT(TLI->getSimpleValueType(DL, VecTy->getScalarType()), VF);
7551
7552 InstructionCost MaskCost;
7553 if (UseMaskedMemOp) {
7554 APInt DemandedLoadStoreElts = APInt::getZero(VecTy->getNumElements());
7555 for (unsigned Index : Indices) {
7556 assert(Index < Factor && "Invalid index for interleaved memory op");
7557 for (unsigned Elm = 0; Elm < VF; Elm++)
7558 DemandedLoadStoreElts.setBit(Index + Elm * Factor);
7559 }
7560
7561 Type *I1Type = Type::getInt1Ty(VecTy->getContext());
7562
7563 MaskCost = getReplicationShuffleCost(
7564 I1Type, Factor, VF,
7565 UseMaskForGaps ? DemandedLoadStoreElts
7567 CostKind);
7568
7569 // The Gaps mask is invariant and created outside the loop, therefore the
7570 // cost of creating it is not accounted for here. However if we have both
7571 // a MaskForGaps and some other mask that guards the execution of the
7572 // memory access, we need to account for the cost of And-ing the two masks
7573 // inside the loop.
7574 if (UseMaskForGaps) {
7575 auto *MaskVT = FixedVectorType::get(I1Type, VecTy->getNumElements());
7576 MaskCost += getArithmeticInstrCost(BinaryOperator::And, MaskVT, CostKind);
7577 }
7578 }
7579
7580 if (Opcode == Instruction::Load) {
7581 // The tables (AVX512InterleavedLoadTbl and AVX512InterleavedStoreTbl)
7582 // contain the cost of the optimized shuffle sequence that the
7583 // X86InterleavedAccess pass will generate.
7584 // The cost of loads and stores are computed separately from the table.
7585
7586 // X86InterleavedAccess support only the following interleaved-access group.
7587 static const CostTblEntry AVX512InterleavedLoadTbl[] = {
7588 {3, MVT::v16i8, 12}, //(load 48i8 and) deinterleave into 3 x 16i8
7589 {3, MVT::v32i8, 14}, //(load 96i8 and) deinterleave into 3 x 32i8
7590 {3, MVT::v64i8, 22}, //(load 96i8 and) deinterleave into 3 x 32i8
7591 };
7592
7593 if (const auto *Entry =
7594 CostTableLookup(AVX512InterleavedLoadTbl, Factor, VT))
7595 return MaskCost + NumOfMemOps * MemOpCost + Entry->Cost;
7596 //If an entry does not exist, fallback to the default implementation.
7597
7598 // Kind of shuffle depends on number of loaded values.
7599 // If we load the entire data in one register, we can use a 1-src shuffle.
7600 // Otherwise, we'll merge 2 sources in each operation.
7601 TTI::ShuffleKind ShuffleKind =
7602 (NumOfMemOps > 1) ? TTI::SK_PermuteTwoSrc : TTI::SK_PermuteSingleSrc;
7603
7604 InstructionCost ShuffleCost = getShuffleCost(
7605 ShuffleKind, SingleMemOpTy, SingleMemOpTy, CostKind, {}, 0, nullptr);
7606
7607 unsigned NumOfLoadsInInterleaveGrp =
7608 Indices.size() ? Indices.size() : Factor;
7609 auto *ResultTy = FixedVectorType::get(VecTy->getElementType(),
7610 VecTy->getNumElements() / Factor);
7611 InstructionCost NumOfResults =
7612 getTypeLegalizationCost(ResultTy).first * NumOfLoadsInInterleaveGrp;
7613
7614 // About a half of the loads may be folded in shuffles when we have only
7615 // one result. If we have more than one result, or the loads are masked,
7616 // we do not fold loads at all.
7617 unsigned NumOfUnfoldedLoads =
7618 UseMaskedMemOp || NumOfResults > 1 ? NumOfMemOps : NumOfMemOps / 2;
7619
7620 // Get a number of shuffle operations per result.
7621 unsigned NumOfShufflesPerResult =
7622 std::max((unsigned)1, (unsigned)(NumOfMemOps - 1));
7623
7624 // The SK_MergeTwoSrc shuffle clobbers one of src operands.
7625 // When we have more than one destination, we need additional instructions
7626 // to keep sources.
7627 InstructionCost NumOfMoves = 0;
7628 if (NumOfResults > 1 && ShuffleKind == TTI::SK_PermuteTwoSrc)
7629 NumOfMoves = NumOfResults * NumOfShufflesPerResult / 2;
7630
7631 InstructionCost Cost = NumOfResults * NumOfShufflesPerResult * ShuffleCost +
7632 MaskCost + NumOfUnfoldedLoads * MemOpCost +
7633 NumOfMoves;
7634
7635 return Cost;
7636 }
7637
7638 // Store.
7639 assert(Opcode == Instruction::Store &&
7640 "Expected Store Instruction at this point");
7641 // X86InterleavedAccess support only the following interleaved-access group.
7642 static const CostTblEntry AVX512InterleavedStoreTbl[] = {
7643 {3, MVT::v16i8, 12}, // interleave 3 x 16i8 into 48i8 (and store)
7644 {3, MVT::v32i8, 14}, // interleave 3 x 32i8 into 96i8 (and store)
7645 {3, MVT::v64i8, 26}, // interleave 3 x 64i8 into 96i8 (and store)
7646
7647 {4, MVT::v8i8, 10}, // interleave 4 x 8i8 into 32i8 (and store)
7648 {4, MVT::v16i8, 11}, // interleave 4 x 16i8 into 64i8 (and store)
7649 {4, MVT::v32i8, 14}, // interleave 4 x 32i8 into 128i8 (and store)
7650 {4, MVT::v64i8, 24} // interleave 4 x 32i8 into 256i8 (and store)
7651 };
7652
7653 if (const auto *Entry =
7654 CostTableLookup(AVX512InterleavedStoreTbl, Factor, VT))
7655 return MaskCost + NumOfMemOps * MemOpCost + Entry->Cost;
7656 //If an entry does not exist, fallback to the default implementation.
7657
7658 // There is no strided stores meanwhile. And store can't be folded in
7659 // shuffle.
7660 unsigned NumOfSources = Factor; // The number of values to be merged.
7661 InstructionCost ShuffleCost =
7662 getShuffleCost(TTI::SK_PermuteTwoSrc, SingleMemOpTy, SingleMemOpTy,
7663 CostKind, {}, 0, nullptr);
7664 unsigned NumOfShufflesPerStore = NumOfSources - 1;
7665
7666 // The SK_MergeTwoSrc shuffle clobbers one of src operands.
7667 // We need additional instructions to keep sources.
7668 unsigned NumOfMoves = NumOfMemOps * NumOfShufflesPerStore / 2;
7670 MaskCost +
7671 NumOfMemOps * (MemOpCost + NumOfShufflesPerStore * ShuffleCost) +
7672 NumOfMoves;
7673 return Cost;
7674}
7675
7677 unsigned Opcode, Type *BaseTy, unsigned Factor, ArrayRef<unsigned> Indices,
7678 Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind,
7679 bool UseMaskForCond, bool UseMaskForGaps) const {
7680 auto *VecTy = cast<FixedVectorType>(BaseTy);
7681
7682 auto isSupportedOnAVX512 = [&](Type *VecTy) {
7683 Type *EltTy = cast<VectorType>(VecTy)->getElementType();
7684 if (EltTy->isFloatTy() || EltTy->isDoubleTy() || EltTy->isIntegerTy(64) ||
7685 EltTy->isIntegerTy(32) || EltTy->isPointerTy())
7686 return true;
7687 if (EltTy->isIntegerTy(16) || EltTy->isIntegerTy(8) || EltTy->isHalfTy())
7688 return ST->hasBWI();
7689 if (EltTy->isBFloatTy())
7690 return ST->hasBF16();
7691 return false;
7692 };
7693 if (ST->hasAVX512() && isSupportedOnAVX512(VecTy))
7695 Opcode, VecTy, Factor, Indices, Alignment,
7696 AddressSpace, CostKind, UseMaskForCond, UseMaskForGaps);
7697
7698 if (UseMaskForCond || UseMaskForGaps)
7699 return BaseT::getInterleavedMemoryOpCost(Opcode, VecTy, Factor, Indices,
7700 Alignment, AddressSpace, CostKind,
7701 UseMaskForCond, UseMaskForGaps);
7702
7703 // Get estimation for interleaved load/store operations for SSE-AVX2.
7704 // As opposed to AVX-512, SSE-AVX2 do not have generic shuffles that allow
7705 // computing the cost using a generic formula as a function of generic
7706 // shuffles. We therefore use a lookup table instead, filled according to
7707 // the instruction sequences that codegen currently generates.
7708
7709 // VecTy for interleave memop is <VF*Factor x Elt>.
7710 // So, for VF=4, Interleave Factor = 3, Element type = i32 we have
7711 // VecTy = <12 x i32>.
7712 MVT LegalVT = getTypeLegalizationCost(VecTy).second;
7713
7714 // This function can be called with VecTy=<6xi128>, Factor=3, in which case
7715 // the VF=2, while v2i128 is an unsupported MVT vector type
7716 // (see MachineValueType.h::getVectorVT()).
7717 if (!LegalVT.isVector())
7718 return BaseT::getInterleavedMemoryOpCost(Opcode, VecTy, Factor, Indices,
7719 Alignment, AddressSpace, CostKind);
7720
7721 unsigned VF = VecTy->getNumElements() / Factor;
7722 Type *ScalarTy = VecTy->getElementType();
7723 // Deduplicate entries, model floats/pointers as appropriately-sized integers.
7724 if (!ScalarTy->isIntegerTy())
7725 ScalarTy =
7726 Type::getIntNTy(ScalarTy->getContext(), DL.getTypeSizeInBits(ScalarTy));
7727
7728 // Get the cost of all the memory operations.
7729 // FIXME: discount dead loads.
7730 InstructionCost MemOpCosts =
7731 getMemoryOpCost(Opcode, VecTy, Alignment, AddressSpace, CostKind);
7732
7733 auto *VT = FixedVectorType::get(ScalarTy, VF);
7734 EVT ETy = TLI->getValueType(DL, VT);
7735 if (!ETy.isSimple())
7736 return BaseT::getInterleavedMemoryOpCost(Opcode, VecTy, Factor, Indices,
7737 Alignment, AddressSpace, CostKind);
7738
7739 // TODO: Complete for other data-types and strides.
7740 // Each combination of Stride, element bit width and VF results in a different
7741 // sequence; The cost tables are therefore accessed with:
7742 // Factor (stride) and VectorType=VFxiN.
7743 // The Cost accounts only for the shuffle sequence;
7744 // The cost of the loads/stores is accounted for separately.
7745 //
7746 static const CostTblEntry AVX2InterleavedLoadTbl[] = {
7747 {2, MVT::v2i8, 2}, // (load 4i8 and) deinterleave into 2 x 2i8
7748 {2, MVT::v4i8, 2}, // (load 8i8 and) deinterleave into 2 x 4i8
7749 {2, MVT::v8i8, 2}, // (load 16i8 and) deinterleave into 2 x 8i8
7750 {2, MVT::v16i8, 4}, // (load 32i8 and) deinterleave into 2 x 16i8
7751 {2, MVT::v32i8, 6}, // (load 64i8 and) deinterleave into 2 x 32i8
7752
7753 {2, MVT::v8i16, 6}, // (load 16i16 and) deinterleave into 2 x 8i16
7754 {2, MVT::v16i16, 9}, // (load 32i16 and) deinterleave into 2 x 16i16
7755 {2, MVT::v32i16, 18}, // (load 64i16 and) deinterleave into 2 x 32i16
7756
7757 {2, MVT::v8i32, 4}, // (load 16i32 and) deinterleave into 2 x 8i32
7758 {2, MVT::v16i32, 8}, // (load 32i32 and) deinterleave into 2 x 16i32
7759 {2, MVT::v32i32, 16}, // (load 64i32 and) deinterleave into 2 x 32i32
7760
7761 {2, MVT::v4i64, 4}, // (load 8i64 and) deinterleave into 2 x 4i64
7762 {2, MVT::v8i64, 8}, // (load 16i64 and) deinterleave into 2 x 8i64
7763 {2, MVT::v16i64, 16}, // (load 32i64 and) deinterleave into 2 x 16i64
7764 {2, MVT::v32i64, 32}, // (load 64i64 and) deinterleave into 2 x 32i64
7765
7766 {3, MVT::v2i8, 3}, // (load 6i8 and) deinterleave into 3 x 2i8
7767 {3, MVT::v4i8, 3}, // (load 12i8 and) deinterleave into 3 x 4i8
7768 {3, MVT::v8i8, 6}, // (load 24i8 and) deinterleave into 3 x 8i8
7769 {3, MVT::v16i8, 11}, // (load 48i8 and) deinterleave into 3 x 16i8
7770 {3, MVT::v32i8, 14}, // (load 96i8 and) deinterleave into 3 x 32i8
7771
7772 {3, MVT::v2i16, 5}, // (load 6i16 and) deinterleave into 3 x 2i16
7773 {3, MVT::v4i16, 7}, // (load 12i16 and) deinterleave into 3 x 4i16
7774 {3, MVT::v8i16, 9}, // (load 24i16 and) deinterleave into 3 x 8i16
7775 {3, MVT::v16i16, 28}, // (load 48i16 and) deinterleave into 3 x 16i16
7776 {3, MVT::v32i16, 56}, // (load 96i16 and) deinterleave into 3 x 32i16
7777
7778 {3, MVT::v2i32, 3}, // (load 6i32 and) deinterleave into 3 x 2i32
7779 {3, MVT::v4i32, 3}, // (load 12i32 and) deinterleave into 3 x 4i32
7780 {3, MVT::v8i32, 7}, // (load 24i32 and) deinterleave into 3 x 8i32
7781 {3, MVT::v16i32, 14}, // (load 48i32 and) deinterleave into 3 x 16i32
7782 {3, MVT::v32i32, 32}, // (load 96i32 and) deinterleave into 3 x 32i32
7783
7784 {3, MVT::v2i64, 1}, // (load 6i64 and) deinterleave into 3 x 2i64
7785 {3, MVT::v4i64, 5}, // (load 12i64 and) deinterleave into 3 x 4i64
7786 {3, MVT::v8i64, 10}, // (load 24i64 and) deinterleave into 3 x 8i64
7787 {3, MVT::v16i64, 20}, // (load 48i64 and) deinterleave into 3 x 16i64
7788
7789 {4, MVT::v2i8, 4}, // (load 8i8 and) deinterleave into 4 x 2i8
7790 {4, MVT::v4i8, 4}, // (load 16i8 and) deinterleave into 4 x 4i8
7791 {4, MVT::v8i8, 12}, // (load 32i8 and) deinterleave into 4 x 8i8
7792 {4, MVT::v16i8, 24}, // (load 64i8 and) deinterleave into 4 x 16i8
7793 {4, MVT::v32i8, 56}, // (load 128i8 and) deinterleave into 4 x 32i8
7794
7795 {4, MVT::v2i16, 6}, // (load 8i16 and) deinterleave into 4 x 2i16
7796 {4, MVT::v4i16, 17}, // (load 16i16 and) deinterleave into 4 x 4i16
7797 {4, MVT::v8i16, 33}, // (load 32i16 and) deinterleave into 4 x 8i16
7798 {4, MVT::v16i16, 75}, // (load 64i16 and) deinterleave into 4 x 16i16
7799 {4, MVT::v32i16, 150}, // (load 128i16 and) deinterleave into 4 x 32i16
7800
7801 {4, MVT::v2i32, 4}, // (load 8i32 and) deinterleave into 4 x 2i32
7802 {4, MVT::v4i32, 8}, // (load 16i32 and) deinterleave into 4 x 4i32
7803 {4, MVT::v8i32, 16}, // (load 32i32 and) deinterleave into 4 x 8i32
7804 {4, MVT::v16i32, 32}, // (load 64i32 and) deinterleave into 4 x 16i32
7805 {4, MVT::v32i32, 68}, // (load 128i32 and) deinterleave into 4 x 32i32
7806
7807 {4, MVT::v2i64, 6}, // (load 8i64 and) deinterleave into 4 x 2i64
7808 {4, MVT::v4i64, 8}, // (load 16i64 and) deinterleave into 4 x 4i64
7809 {4, MVT::v8i64, 20}, // (load 32i64 and) deinterleave into 4 x 8i64
7810 {4, MVT::v16i64, 40}, // (load 64i64 and) deinterleave into 4 x 16i64
7811
7812 {6, MVT::v2i8, 6}, // (load 12i8 and) deinterleave into 6 x 2i8
7813 {6, MVT::v4i8, 14}, // (load 24i8 and) deinterleave into 6 x 4i8
7814 {6, MVT::v8i8, 18}, // (load 48i8 and) deinterleave into 6 x 8i8
7815 {6, MVT::v16i8, 43}, // (load 96i8 and) deinterleave into 6 x 16i8
7816 {6, MVT::v32i8, 82}, // (load 192i8 and) deinterleave into 6 x 32i8
7817
7818 {6, MVT::v2i16, 13}, // (load 12i16 and) deinterleave into 6 x 2i16
7819 {6, MVT::v4i16, 9}, // (load 24i16 and) deinterleave into 6 x 4i16
7820 {6, MVT::v8i16, 39}, // (load 48i16 and) deinterleave into 6 x 8i16
7821 {6, MVT::v16i16, 106}, // (load 96i16 and) deinterleave into 6 x 16i16
7822 {6, MVT::v32i16, 212}, // (load 192i16 and) deinterleave into 6 x 32i16
7823
7824 {6, MVT::v2i32, 6}, // (load 12i32 and) deinterleave into 6 x 2i32
7825 {6, MVT::v4i32, 15}, // (load 24i32 and) deinterleave into 6 x 4i32
7826 {6, MVT::v8i32, 31}, // (load 48i32 and) deinterleave into 6 x 8i32
7827 {6, MVT::v16i32, 64}, // (load 96i32 and) deinterleave into 6 x 16i32
7828
7829 {6, MVT::v2i64, 6}, // (load 12i64 and) deinterleave into 6 x 2i64
7830 {6, MVT::v4i64, 18}, // (load 24i64 and) deinterleave into 6 x 4i64
7831 {6, MVT::v8i64, 36}, // (load 48i64 and) deinterleave into 6 x 8i64
7832
7833 {8, MVT::v8i32, 40} // (load 64i32 and) deinterleave into 8 x 8i32
7834 };
7835
7836 static const CostTblEntry SSSE3InterleavedLoadTbl[] = {
7837 {2, MVT::v4i16, 2}, // (load 8i16 and) deinterleave into 2 x 4i16
7838 };
7839
7840 static const CostTblEntry SSE2InterleavedLoadTbl[] = {
7841 {2, MVT::v2i16, 2}, // (load 4i16 and) deinterleave into 2 x 2i16
7842 {2, MVT::v4i16, 7}, // (load 8i16 and) deinterleave into 2 x 4i16
7843
7844 {2, MVT::v2i32, 2}, // (load 4i32 and) deinterleave into 2 x 2i32
7845 {2, MVT::v4i32, 2}, // (load 8i32 and) deinterleave into 2 x 4i32
7846
7847 {2, MVT::v2i64, 2}, // (load 4i64 and) deinterleave into 2 x 2i64
7848 };
7849
7850 static const CostTblEntry AVX2InterleavedStoreTbl[] = {
7851 {2, MVT::v16i8, 3}, // interleave 2 x 16i8 into 32i8 (and store)
7852 {2, MVT::v32i8, 4}, // interleave 2 x 32i8 into 64i8 (and store)
7853
7854 {2, MVT::v8i16, 3}, // interleave 2 x 8i16 into 16i16 (and store)
7855 {2, MVT::v16i16, 4}, // interleave 2 x 16i16 into 32i16 (and store)
7856 {2, MVT::v32i16, 8}, // interleave 2 x 32i16 into 64i16 (and store)
7857
7858 {2, MVT::v4i32, 2}, // interleave 2 x 4i32 into 8i32 (and store)
7859 {2, MVT::v8i32, 4}, // interleave 2 x 8i32 into 16i32 (and store)
7860 {2, MVT::v16i32, 8}, // interleave 2 x 16i32 into 32i32 (and store)
7861 {2, MVT::v32i32, 16}, // interleave 2 x 32i32 into 64i32 (and store)
7862
7863 {2, MVT::v2i64, 2}, // interleave 2 x 2i64 into 4i64 (and store)
7864 {2, MVT::v4i64, 4}, // interleave 2 x 4i64 into 8i64 (and store)
7865 {2, MVT::v8i64, 8}, // interleave 2 x 8i64 into 16i64 (and store)
7866 {2, MVT::v16i64, 16}, // interleave 2 x 16i64 into 32i64 (and store)
7867 {2, MVT::v32i64, 32}, // interleave 2 x 32i64 into 64i64 (and store)
7868
7869 {3, MVT::v2i8, 4}, // interleave 3 x 2i8 into 6i8 (and store)
7870 {3, MVT::v4i8, 4}, // interleave 3 x 4i8 into 12i8 (and store)
7871 {3, MVT::v8i8, 6}, // interleave 3 x 8i8 into 24i8 (and store)
7872 {3, MVT::v16i8, 11}, // interleave 3 x 16i8 into 48i8 (and store)
7873 {3, MVT::v32i8, 13}, // interleave 3 x 32i8 into 96i8 (and store)
7874
7875 {3, MVT::v2i16, 4}, // interleave 3 x 2i16 into 6i16 (and store)
7876 {3, MVT::v4i16, 6}, // interleave 3 x 4i16 into 12i16 (and store)
7877 {3, MVT::v8i16, 12}, // interleave 3 x 8i16 into 24i16 (and store)
7878 {3, MVT::v16i16, 27}, // interleave 3 x 16i16 into 48i16 (and store)
7879 {3, MVT::v32i16, 54}, // interleave 3 x 32i16 into 96i16 (and store)
7880
7881 {3, MVT::v2i32, 4}, // interleave 3 x 2i32 into 6i32 (and store)
7882 {3, MVT::v4i32, 5}, // interleave 3 x 4i32 into 12i32 (and store)
7883 {3, MVT::v8i32, 11}, // interleave 3 x 8i32 into 24i32 (and store)
7884 {3, MVT::v16i32, 22}, // interleave 3 x 16i32 into 48i32 (and store)
7885 {3, MVT::v32i32, 48}, // interleave 3 x 32i32 into 96i32 (and store)
7886
7887 {3, MVT::v2i64, 4}, // interleave 3 x 2i64 into 6i64 (and store)
7888 {3, MVT::v4i64, 6}, // interleave 3 x 4i64 into 12i64 (and store)
7889 {3, MVT::v8i64, 12}, // interleave 3 x 8i64 into 24i64 (and store)
7890 {3, MVT::v16i64, 24}, // interleave 3 x 16i64 into 48i64 (and store)
7891
7892 {4, MVT::v2i8, 4}, // interleave 4 x 2i8 into 8i8 (and store)
7893 {4, MVT::v4i8, 4}, // interleave 4 x 4i8 into 16i8 (and store)
7894 {4, MVT::v8i8, 4}, // interleave 4 x 8i8 into 32i8 (and store)
7895 {4, MVT::v16i8, 8}, // interleave 4 x 16i8 into 64i8 (and store)
7896 {4, MVT::v32i8, 12}, // interleave 4 x 32i8 into 128i8 (and store)
7897
7898 {4, MVT::v2i16, 2}, // interleave 4 x 2i16 into 8i16 (and store)
7899 {4, MVT::v4i16, 6}, // interleave 4 x 4i16 into 16i16 (and store)
7900 {4, MVT::v8i16, 10}, // interleave 4 x 8i16 into 32i16 (and store)
7901 {4, MVT::v16i16, 32}, // interleave 4 x 16i16 into 64i16 (and store)
7902 {4, MVT::v32i16, 64}, // interleave 4 x 32i16 into 128i16 (and store)
7903
7904 {4, MVT::v2i32, 5}, // interleave 4 x 2i32 into 8i32 (and store)
7905 {4, MVT::v4i32, 6}, // interleave 4 x 4i32 into 16i32 (and store)
7906 {4, MVT::v8i32, 16}, // interleave 4 x 8i32 into 32i32 (and store)
7907 {4, MVT::v16i32, 32}, // interleave 4 x 16i32 into 64i32 (and store)
7908 {4, MVT::v32i32, 64}, // interleave 4 x 32i32 into 128i32 (and store)
7909
7910 {4, MVT::v2i64, 6}, // interleave 4 x 2i64 into 8i64 (and store)
7911 {4, MVT::v4i64, 8}, // interleave 4 x 4i64 into 16i64 (and store)
7912 {4, MVT::v8i64, 20}, // interleave 4 x 8i64 into 32i64 (and store)
7913 {4, MVT::v16i64, 40}, // interleave 4 x 16i64 into 64i64 (and store)
7914
7915 {6, MVT::v2i8, 7}, // interleave 6 x 2i8 into 12i8 (and store)
7916 {6, MVT::v4i8, 9}, // interleave 6 x 4i8 into 24i8 (and store)
7917 {6, MVT::v8i8, 16}, // interleave 6 x 8i8 into 48i8 (and store)
7918 {6, MVT::v16i8, 27}, // interleave 6 x 16i8 into 96i8 (and store)
7919 {6, MVT::v32i8, 90}, // interleave 6 x 32i8 into 192i8 (and store)
7920
7921 {6, MVT::v2i16, 10}, // interleave 6 x 2i16 into 12i16 (and store)
7922 {6, MVT::v4i16, 15}, // interleave 6 x 4i16 into 24i16 (and store)
7923 {6, MVT::v8i16, 21}, // interleave 6 x 8i16 into 48i16 (and store)
7924 {6, MVT::v16i16, 58}, // interleave 6 x 16i16 into 96i16 (and store)
7925 {6, MVT::v32i16, 90}, // interleave 6 x 32i16 into 192i16 (and store)
7926
7927 {6, MVT::v2i32, 9}, // interleave 6 x 2i32 into 12i32 (and store)
7928 {6, MVT::v4i32, 12}, // interleave 6 x 4i32 into 24i32 (and store)
7929 {6, MVT::v8i32, 33}, // interleave 6 x 8i32 into 48i32 (and store)
7930 {6, MVT::v16i32, 66}, // interleave 6 x 16i32 into 96i32 (and store)
7931
7932 {6, MVT::v2i64, 8}, // interleave 6 x 2i64 into 12i64 (and store)
7933 {6, MVT::v4i64, 15}, // interleave 6 x 4i64 into 24i64 (and store)
7934 {6, MVT::v8i64, 30}, // interleave 6 x 8i64 into 48i64 (and store)
7935 };
7936
7937 static const CostTblEntry SSE2InterleavedStoreTbl[] = {
7938 {2, MVT::v2i8, 1}, // interleave 2 x 2i8 into 4i8 (and store)
7939 {2, MVT::v4i8, 1}, // interleave 2 x 4i8 into 8i8 (and store)
7940 {2, MVT::v8i8, 1}, // interleave 2 x 8i8 into 16i8 (and store)
7941
7942 {2, MVT::v2i16, 1}, // interleave 2 x 2i16 into 4i16 (and store)
7943 {2, MVT::v4i16, 1}, // interleave 2 x 4i16 into 8i16 (and store)
7944
7945 {2, MVT::v2i32, 1}, // interleave 2 x 2i32 into 4i32 (and store)
7946 };
7947
7948 if (Opcode == Instruction::Load) {
7949 auto GetDiscountedCost = [Factor, NumMembers = Indices.size(),
7950 MemOpCosts](const CostTblEntry *Entry) {
7951 // NOTE: this is just an approximation!
7952 // It can over/under -estimate the cost!
7953 return MemOpCosts + divideCeil(NumMembers * Entry->Cost, Factor);
7954 };
7955
7956 if (ST->hasAVX2())
7957 if (const auto *Entry = CostTableLookup(AVX2InterleavedLoadTbl, Factor,
7958 ETy.getSimpleVT()))
7959 return GetDiscountedCost(Entry);
7960
7961 if (ST->hasSSSE3())
7962 if (const auto *Entry = CostTableLookup(SSSE3InterleavedLoadTbl, Factor,
7963 ETy.getSimpleVT()))
7964 return GetDiscountedCost(Entry);
7965
7966 if (ST->hasSSE2())
7967 if (const auto *Entry = CostTableLookup(SSE2InterleavedLoadTbl, Factor,
7968 ETy.getSimpleVT()))
7969 return GetDiscountedCost(Entry);
7970 } else {
7971 assert(Opcode == Instruction::Store &&
7972 "Expected Store Instruction at this point");
7973 assert((!Indices.size() || Indices.size() == Factor) &&
7974 "Interleaved store only supports fully-interleaved groups.");
7975 if (ST->hasAVX2())
7976 if (const auto *Entry = CostTableLookup(AVX2InterleavedStoreTbl, Factor,
7977 ETy.getSimpleVT()))
7978 return MemOpCosts + Entry->Cost;
7979
7980 if (ST->hasSSE2())
7981 if (const auto *Entry = CostTableLookup(SSE2InterleavedStoreTbl, Factor,
7982 ETy.getSimpleVT()))
7983 return MemOpCosts + Entry->Cost;
7984 }
7985
7986 return BaseT::getInterleavedMemoryOpCost(Opcode, VecTy, Factor, Indices,
7987 Alignment, AddressSpace, CostKind,
7988 UseMaskForCond, UseMaskForGaps);
7989}
7990
7992 StackOffset BaseOffset,
7993 bool HasBaseReg, int64_t Scale,
7994 unsigned AddrSpace) const {
7995 // Scaling factors are not free at all.
7996 // An indexed folded instruction, i.e., inst (reg1, reg2, scale),
7997 // will take 2 allocations in the out of order engine instead of 1
7998 // for plain addressing mode, i.e. inst (reg1).
7999 // E.g.,
8000 // vaddps (%rsi,%rdx), %ymm0, %ymm1
8001 // Requires two allocations (one for the load, one for the computation)
8002 // whereas:
8003 // vaddps (%rsi), %ymm0, %ymm1
8004 // Requires just 1 allocation, i.e., freeing allocations for other operations
8005 // and having less micro operations to execute.
8006 //
8007 // For some X86 architectures, this is even worse because for instance for
8008 // stores, the complex addressing mode forces the instruction to use the
8009 // "load" ports instead of the dedicated "store" port.
8010 // E.g., on Haswell:
8011 // vmovaps %ymm1, (%r8, %rdi) can use port 2 or 3.
8012 // vmovaps %ymm1, (%r8) can use port 2, 3, or 7.
8014 AM.BaseGV = BaseGV;
8015 AM.BaseOffs = BaseOffset.getFixed();
8016 AM.HasBaseReg = HasBaseReg;
8017 AM.Scale = Scale;
8018 AM.ScalableOffset = BaseOffset.getScalable();
8019 if (getTLI()->isLegalAddressingMode(DL, AM, Ty, AddrSpace))
8020 // Scale represents reg2 * scale, thus account for 1
8021 // as soon as we use a second register.
8022 return AM.Scale != 0;
8024}
8025
8027 // TODO: Hook MispredictPenalty of SchedMachineModel into this.
8028 return 14;
8029}
8030
8032 unsigned Bits = Ty->getScalarSizeInBits();
8033
8034 // XOP has v16i8/v8i16/v4i32/v2i64 variable vector shifts.
8035 // Splitting for v32i8/v16i16 on XOP+AVX2 targets is still preferred.
8036 if (ST->hasXOP() && (Bits == 8 || Bits == 16 || Bits == 32 || Bits == 64))
8037 return false;
8038
8039 // AVX2 has vpsllv[dq] instructions (and other shifts) that make variable
8040 // shifts just as cheap as scalar ones.
8041 if (ST->hasAVX2() && (Bits == 32 || Bits == 64))
8042 return false;
8043
8044 // AVX512BW has shifts such as vpsllvw.
8045 if (ST->hasBWI() && Bits == 16)
8046 return false;
8047
8048 // Otherwise, it's significantly cheaper to shift by a scalar amount than by a
8049 // fully general vector.
8050 return true;
8051}
8052
8053unsigned X86TTIImpl::getStoreMinimumVF(unsigned VF, Type *ScalarMemTy,
8054 Type *ScalarValTy, Align Alignment,
8055 unsigned AddrSpace) const {
8056 if (ST->hasF16C() && ScalarMemTy->isHalfTy()) {
8057 return 4;
8058 }
8059 return BaseT::getStoreMinimumVF(VF, ScalarMemTy, ScalarValTy, Alignment,
8060 AddrSpace);
8061}
8062
8064 SmallVectorImpl<Use *> &Ops) const {
8065 using namespace llvm::PatternMatch;
8066
8067 if (I->getOpcode() == Instruction::And &&
8068 (ST->hasBMI() || (I->getType()->isVectorTy() && ST->hasSSE2()))) {
8069 for (auto &Op : I->operands()) {
8070 // (and X, (not Y)) -> (andn X, Y)
8071 if (match(Op.get(), m_Not(m_Value())) && !I->getType()->isIntegerTy(8)) {
8072 Ops.push_back(&Op);
8073 return true;
8074 }
8075 // (and X, (splat (not Y))) -> (andn X, (splat Y))
8076 if (match(Op.get(),
8078 m_Value(), m_ZeroMask()))) {
8079 Use &InsertElt = cast<Instruction>(Op)->getOperandUse(0);
8080 Use &Not = cast<Instruction>(InsertElt)->getOperandUse(1);
8081 Ops.push_back(&Not);
8082 Ops.push_back(&InsertElt);
8083 Ops.push_back(&Op);
8084 return true;
8085 }
8086 }
8087 }
8088
8089 FixedVectorType *VTy = dyn_cast<FixedVectorType>(I->getType());
8090 if (!VTy)
8091 return false;
8092
8093 if (I->getOpcode() == Instruction::Mul &&
8094 VTy->getElementType()->isIntegerTy(64)) {
8095 for (auto &Op : I->operands()) {
8096 // Make sure we are not already sinking this operand
8097 if (any_of(Ops, [&](Use *U) { return U->get() == Op; }))
8098 continue;
8099
8100 // Look for PMULDQ pattern where the input is a sext_inreg from vXi32 or
8101 // the PMULUDQ pattern where the input is a zext_inreg from vXi32.
8102 if (ST->hasSSE41() &&
8103 match(Op.get(), m_AShr(m_Shl(m_Value(), m_SpecificInt(32)),
8104 m_SpecificInt(32)))) {
8105 Ops.push_back(&cast<Instruction>(Op)->getOperandUse(0));
8106 Ops.push_back(&Op);
8107 } else if (ST->hasSSE2() &&
8108 match(Op.get(),
8109 m_And(m_Value(), m_SpecificInt(UINT64_C(0xffffffff))))) {
8110 Ops.push_back(&Op);
8111 }
8112 }
8113
8114 return !Ops.empty();
8115 }
8116
8117 // A uniform shift amount in a vector shift or funnel shift may be much
8118 // cheaper than a generic variable vector shift, so make that pattern visible
8119 // to SDAG by sinking the shuffle instruction next to the shift.
8120 int ShiftAmountOpNum = -1;
8121 if (I->isShift())
8122 ShiftAmountOpNum = 1;
8123 else if (auto *II = dyn_cast<IntrinsicInst>(I)) {
8124 if (II->getIntrinsicID() == Intrinsic::fshl ||
8125 II->getIntrinsicID() == Intrinsic::fshr)
8126 ShiftAmountOpNum = 2;
8127 }
8128
8129 if (ShiftAmountOpNum == -1)
8130 return false;
8131
8132 auto *Shuf = dyn_cast<ShuffleVectorInst>(I->getOperand(ShiftAmountOpNum));
8133 if (Shuf && getSplatIndex(Shuf->getShuffleMask()) >= 0 &&
8134 isVectorShiftByScalarCheap(I->getType())) {
8135 Ops.push_back(&I->getOperandUse(ShiftAmountOpNum));
8136 return true;
8137 }
8138
8139 return false;
8140}
8141
8143 bool HasEGPR = ST->hasEGPR();
8144 const TargetMachine &TM = getTLI()->getTargetMachine();
8145
8146 for (User *U : F.users()) {
8148 if (!CB || CB->getCalledOperand() != &F)
8149 continue;
8150 Function *CallerFunc = CB->getFunction();
8151 if (TM.getSubtarget<X86Subtarget>(*CallerFunc).hasEGPR() != HasEGPR)
8152 return false;
8153 }
8154
8155 return true;
8156}
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
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, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) 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 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
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
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, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) 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:830
@ 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:790
@ 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:891
@ FADD
Simple binary floating point operators.
Definition ISDOpcodes.h:418
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
Definition ISDOpcodes.h:750
@ 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:781
@ CTLZ_ZERO_POISON
Definition ISDOpcodes.h:799
@ PARTIAL_REDUCE_UMLA
@ SIGN_EXTEND
Conversion operators.
Definition ISDOpcodes.h:855
@ 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:375
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
Definition ISDOpcodes.h:807
@ SADDO
RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
Definition ISDOpcodes.h:349
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
Definition ISDOpcodes.h:707
@ SHL
Shift and rotation operations.
Definition ISDOpcodes.h:772
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
Definition ISDOpcodes.h:579
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
Definition ISDOpcodes.h:861
@ FMINNUM
FMINNUM/FMAXNUM - Perform floating-point minimum maximum on two values, following IEEE-754 definition...
@ SMULO
Same for multiplication.
Definition ISDOpcodes.h:357
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
Definition ISDOpcodes.h:730
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
Definition ISDOpcodes.h:989
@ 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:937
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition ISDOpcodes.h:742
@ CTTZ_ZERO_POISON
Bit counting operators with a poisoned result for zero inputs.
Definition ISDOpcodes.h:798
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
Definition ISDOpcodes.h:970
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
Definition ISDOpcodes.h:867
@ PARTIAL_REDUCE_SUMLA
@ SADDSAT
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
Definition ISDOpcodes.h:366
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