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 static const CostKindTblEntry AVX512BWUniformCostTable[] = {
757 { ISD::SHL, MVT::v16i8, { 3, 5, 5, 7 } }, // psllw + pand.
758 { ISD::SRL, MVT::v16i8, { 3,10, 5, 8 } }, // psrlw + pand.
759 { ISD::SRA, MVT::v16i8, { 4,12, 8,12 } }, // psrlw, pand, pxor, psubb.
760 { ISD::SHL, MVT::v32i8, { 4, 7, 6, 8 } }, // psllw + pand.
761 { ISD::SRL, MVT::v32i8, { 4, 8, 7, 9 } }, // psrlw + pand.
762 { ISD::SRA, MVT::v32i8, { 5,10,10,13 } }, // psrlw, pand, pxor, psubb.
763 { ISD::SHL, MVT::v64i8, { 4, 7, 6, 8 } }, // psllw + pand.
764 { ISD::SRL, MVT::v64i8, { 4, 8, 7,10 } }, // psrlw + pand.
765 { ISD::SRA, MVT::v64i8, { 5,10,10,15 } }, // psrlw, pand, pxor, psubb.
766
767 { ISD::SHL, MVT::v32i16, { 2, 4, 2, 3 } }, // psllw
768 { ISD::SRL, MVT::v32i16, { 2, 4, 2, 3 } }, // psrlw
769 { ISD::SRA, MVT::v32i16, { 2, 4, 2, 3 } }, // psrqw
770 };
771
772 if (ST->hasBWI() && Op2Info.isUniform())
773 if (const auto *Entry =
774 CostTableLookup(AVX512BWUniformCostTable, ISD, LT.second))
775 if (auto KindCost = Entry->Cost[CostKind])
776 return LT.first * *KindCost;
777
778 static const CostKindTblEntry AVX512UniformCostTable[] = {
779 { ISD::SHL, MVT::v32i16, { 5,10, 5, 7 } }, // psllw + split.
780 { ISD::SRL, MVT::v32i16, { 5,10, 5, 7 } }, // psrlw + split.
781 { ISD::SRA, MVT::v32i16, { 5,10, 5, 7 } }, // psraw + split.
782
783 { ISD::SHL, MVT::v16i32, { 2, 4, 2, 3 } }, // pslld
784 { ISD::SRL, MVT::v16i32, { 2, 4, 2, 3 } }, // psrld
785 { ISD::SRA, MVT::v16i32, { 2, 4, 2, 3 } }, // psrad
786
787 { ISD::SRA, MVT::v2i64, { 1, 2, 1, 2 } }, // psraq
788 { ISD::SHL, MVT::v4i64, { 1, 4, 1, 2 } }, // psllq
789 { ISD::SRL, MVT::v4i64, { 1, 4, 1, 2 } }, // psrlq
790 { ISD::SRA, MVT::v4i64, { 1, 4, 1, 2 } }, // psraq
791 { ISD::SHL, MVT::v8i64, { 1, 4, 1, 2 } }, // psllq
792 { ISD::SRL, MVT::v8i64, { 1, 4, 1, 2 } }, // psrlq
793 { ISD::SRA, MVT::v8i64, { 1, 4, 1, 2 } }, // psraq
794 };
795
796 if (ST->hasAVX512() && Op2Info.isUniform())
797 if (const auto *Entry =
798 CostTableLookup(AVX512UniformCostTable, ISD, LT.second))
799 if (auto KindCost = Entry->Cost[CostKind])
800 return LT.first * *KindCost;
801
802 static const CostKindTblEntry AVX2UniformCostTable[] = {
803 // Uniform splats are cheaper for the following instructions.
804 { ISD::SHL, MVT::v16i8, { 3, 5, 5, 7 } }, // psllw + pand.
805 { ISD::SRL, MVT::v16i8, { 3, 9, 5, 8 } }, // psrlw + pand.
806 { ISD::SRA, MVT::v16i8, { 4, 5, 9,13 } }, // psrlw, pand, pxor, psubb.
807 { ISD::SHL, MVT::v32i8, { 4, 7, 6, 8 } }, // psllw + pand.
808 { ISD::SRL, MVT::v32i8, { 4, 8, 7, 9 } }, // psrlw + pand.
809 { ISD::SRA, MVT::v32i8, { 6, 9,11,16 } }, // psrlw, pand, pxor, psubb.
810
811 { ISD::SHL, MVT::v8i16, { 1, 2, 1, 2 } }, // psllw.
812 { ISD::SRL, MVT::v8i16, { 1, 2, 1, 2 } }, // psrlw.
813 { ISD::SRA, MVT::v8i16, { 1, 2, 1, 2 } }, // psraw.
814 { ISD::SHL, MVT::v16i16, { 2, 4, 2, 3 } }, // psllw.
815 { ISD::SRL, MVT::v16i16, { 2, 4, 2, 3 } }, // psrlw.
816 { ISD::SRA, MVT::v16i16, { 2, 4, 2, 3 } }, // psraw.
817
818 { ISD::SHL, MVT::v4i32, { 1, 2, 1, 2 } }, // pslld
819 { ISD::SRL, MVT::v4i32, { 1, 2, 1, 2 } }, // psrld
820 { ISD::SRA, MVT::v4i32, { 1, 2, 1, 2 } }, // psrad
821 { ISD::SHL, MVT::v8i32, { 2, 4, 2, 3 } }, // pslld
822 { ISD::SRL, MVT::v8i32, { 2, 4, 2, 3 } }, // psrld
823 { ISD::SRA, MVT::v8i32, { 2, 4, 2, 3 } }, // psrad
824
825 { ISD::SHL, MVT::v2i64, { 1, 2, 1, 2 } }, // psllq
826 { ISD::SRL, MVT::v2i64, { 1, 2, 1, 2 } }, // psrlq
827 { ISD::SRA, MVT::v2i64, { 2, 4, 5, 7 } }, // 2 x psrad + shuffle.
828 { ISD::SHL, MVT::v4i64, { 2, 4, 1, 2 } }, // psllq
829 { ISD::SRL, MVT::v4i64, { 2, 4, 1, 2 } }, // psrlq
830 { ISD::SRA, MVT::v4i64, { 4, 6, 5, 9 } }, // 2 x psrad + shuffle.
831 };
832
833 if (ST->hasAVX2() && Op2Info.isUniform())
834 if (const auto *Entry =
835 CostTableLookup(AVX2UniformCostTable, ISD, LT.second))
836 if (auto KindCost = Entry->Cost[CostKind])
837 return LT.first * *KindCost;
838
839 static const CostKindTblEntry AVXUniformCostTable[] = {
840 { ISD::SHL, MVT::v16i8, { 4, 4, 6, 8 } }, // psllw + pand.
841 { ISD::SRL, MVT::v16i8, { 4, 8, 5, 8 } }, // psrlw + pand.
842 { ISD::SRA, MVT::v16i8, { 6, 6, 9,13 } }, // psrlw, pand, pxor, psubb.
843 { ISD::SHL, MVT::v32i8, { 7, 8,11,14 } }, // psllw + pand + split.
844 { ISD::SRL, MVT::v32i8, { 7, 9,10,14 } }, // psrlw + pand + split.
845 { ISD::SRA, MVT::v32i8, { 10,11,16,21 } }, // psrlw, pand, pxor, psubb + split.
846
847 { ISD::SHL, MVT::v8i16, { 1, 3, 1, 2 } }, // psllw.
848 { ISD::SRL, MVT::v8i16, { 1, 3, 1, 2 } }, // psrlw.
849 { ISD::SRA, MVT::v8i16, { 1, 3, 1, 2 } }, // psraw.
850 { ISD::SHL, MVT::v16i16, { 3, 7, 5, 7 } }, // psllw + split.
851 { ISD::SRL, MVT::v16i16, { 3, 7, 5, 7 } }, // psrlw + split.
852 { ISD::SRA, MVT::v16i16, { 3, 7, 5, 7 } }, // psraw + split.
853
854 { ISD::SHL, MVT::v4i32, { 1, 3, 1, 2 } }, // pslld.
855 { ISD::SRL, MVT::v4i32, { 1, 3, 1, 2 } }, // psrld.
856 { ISD::SRA, MVT::v4i32, { 1, 3, 1, 2 } }, // psrad.
857 { ISD::SHL, MVT::v8i32, { 3, 7, 5, 7 } }, // pslld + split.
858 { ISD::SRL, MVT::v8i32, { 3, 7, 5, 7 } }, // psrld + split.
859 { ISD::SRA, MVT::v8i32, { 3, 7, 5, 7 } }, // psrad + split.
860
861 { ISD::SHL, MVT::v2i64, { 1, 3, 1, 2 } }, // psllq.
862 { ISD::SRL, MVT::v2i64, { 1, 3, 1, 2 } }, // psrlq.
863 { ISD::SRA, MVT::v2i64, { 3, 4, 5, 7 } }, // 2 x psrad + shuffle.
864 { ISD::SHL, MVT::v4i64, { 3, 7, 4, 6 } }, // psllq + split.
865 { ISD::SRL, MVT::v4i64, { 3, 7, 4, 6 } }, // psrlq + split.
866 { ISD::SRA, MVT::v4i64, { 6, 7,10,13 } }, // 2 x (2 x psrad + shuffle) + split.
867 };
868
869 // XOP has faster vXi8 shifts.
870 if (ST->hasAVX() && Op2Info.isUniform() &&
871 (!ST->hasXOP() || LT.second.getScalarSizeInBits() != 8))
872 if (const auto *Entry =
873 CostTableLookup(AVXUniformCostTable, ISD, LT.second))
874 if (auto KindCost = Entry->Cost[CostKind])
875 return LT.first * *KindCost;
876
877 static const CostKindTblEntry SSE2UniformCostTable[] = {
878 // Uniform splats are cheaper for the following instructions.
879 { ISD::SHL, MVT::v16i8, { 9, 10, 6, 9 } }, // psllw + pand.
880 { ISD::SRL, MVT::v16i8, { 9, 13, 5, 9 } }, // psrlw + pand.
881 { ISD::SRA, MVT::v16i8, { 11, 15, 9,13 } }, // pcmpgtb sequence.
882
883 { ISD::SHL, MVT::v8i16, { 2, 2, 1, 2 } }, // psllw.
884 { ISD::SRL, MVT::v8i16, { 2, 2, 1, 2 } }, // psrlw.
885 { ISD::SRA, MVT::v8i16, { 2, 2, 1, 2 } }, // psraw.
886
887 { ISD::SHL, MVT::v4i32, { 2, 2, 1, 2 } }, // pslld
888 { ISD::SRL, MVT::v4i32, { 2, 2, 1, 2 } }, // psrld.
889 { ISD::SRA, MVT::v4i32, { 2, 2, 1, 2 } }, // psrad.
890
891 { ISD::SHL, MVT::v2i64, { 2, 2, 1, 2 } }, // psllq.
892 { ISD::SRL, MVT::v2i64, { 2, 2, 1, 2 } }, // psrlq.
893 { ISD::SRA, MVT::v2i64, { 5, 9, 5, 7 } }, // 2*psrlq + xor + sub.
894 };
895
896 if (ST->hasSSE2() && Op2Info.isUniform() &&
897 (!ST->hasXOP() || LT.second.getScalarSizeInBits() != 8))
898 if (const auto *Entry =
899 CostTableLookup(SSE2UniformCostTable, ISD, LT.second))
900 if (auto KindCost = Entry->Cost[CostKind])
901 return LT.first * *KindCost;
902
903 static const CostKindTblEntry AVX512DQCostTable[] = {
904 { ISD::MUL, MVT::v2i64, { 2, 15, 1, 3 } }, // pmullq
905 { ISD::MUL, MVT::v4i64, { 2, 15, 1, 3 } }, // pmullq
906 { ISD::MUL, MVT::v8i64, { 3, 15, 1, 3 } } // pmullq
907 };
908
909 // Look for AVX512DQ lowering tricks for custom cases.
910 if (ST->hasDQI())
911 if (const auto *Entry = CostTableLookup(AVX512DQCostTable, ISD, LT.second))
912 if (auto KindCost = Entry->Cost[CostKind])
913 return LT.first * *KindCost;
914
915 static const CostKindTblEntry AVX512BWCostTable[] = {
916 { ISD::SHL, MVT::v16i8, { 4, 8, 4, 5 } }, // extend/vpsllvw/pack sequence.
917 { ISD::SRL, MVT::v16i8, { 4, 8, 4, 5 } }, // extend/vpsrlvw/pack sequence.
918 { ISD::SRA, MVT::v16i8, { 4, 8, 4, 5 } }, // extend/vpsravw/pack sequence.
919 { ISD::SHL, MVT::v32i8, { 4, 23,11,16 } }, // extend/vpsllvw/pack sequence.
920 { ISD::SRL, MVT::v32i8, { 4, 30,12,18 } }, // extend/vpsrlvw/pack sequence.
921 { ISD::SRA, MVT::v32i8, { 6, 13,24,30 } }, // extend/vpsravw/pack sequence.
922 { ISD::SHL, MVT::v64i8, { 6, 19,13,15 } }, // extend/vpsllvw/pack sequence.
923 { ISD::SRL, MVT::v64i8, { 7, 27,15,18 } }, // extend/vpsrlvw/pack sequence.
924 { ISD::SRA, MVT::v64i8, { 15, 15,30,30 } }, // extend/vpsravw/pack sequence.
925
926 { ISD::SHL, MVT::v8i16, { 1, 1, 1, 1 } }, // vpsllvw
927 { ISD::SRL, MVT::v8i16, { 1, 1, 1, 1 } }, // vpsrlvw
928 { ISD::SRA, MVT::v8i16, { 1, 1, 1, 1 } }, // vpsravw
929 { ISD::SHL, MVT::v16i16, { 1, 1, 1, 1 } }, // vpsllvw
930 { ISD::SRL, MVT::v16i16, { 1, 1, 1, 1 } }, // vpsrlvw
931 { ISD::SRA, MVT::v16i16, { 1, 1, 1, 1 } }, // vpsravw
932 { ISD::SHL, MVT::v32i16, { 1, 1, 1, 1 } }, // vpsllvw
933 { ISD::SRL, MVT::v32i16, { 1, 1, 1, 1 } }, // vpsrlvw
934 { ISD::SRA, MVT::v32i16, { 1, 1, 1, 1 } }, // vpsravw
935
936 { ISD::ADD, MVT::v64i8, { 1, 1, 1, 1 } }, // paddb
937 { ISD::ADD, MVT::v32i16, { 1, 1, 1, 1 } }, // paddw
938
939 { ISD::ADD, MVT::v32i8, { 1, 1, 1, 1 } }, // paddb
940 { ISD::ADD, MVT::v16i16, { 1, 1, 1, 1 } }, // paddw
941 { ISD::ADD, MVT::v8i32, { 1, 1, 1, 1 } }, // paddd
942 { ISD::ADD, MVT::v4i64, { 1, 1, 1, 1 } }, // paddq
943
944 { ISD::SUB, MVT::v64i8, { 1, 1, 1, 1 } }, // psubb
945 { ISD::SUB, MVT::v32i16, { 1, 1, 1, 1 } }, // psubw
946
947 { ISD::MUL, MVT::v16i8, { 4, 12, 4, 5 } }, // extend/pmullw/trunc
948 { ISD::MUL, MVT::v32i8, { 3, 10, 7,10 } }, // pmaddubsw
949 { ISD::MUL, MVT::v64i8, { 3, 11, 7,10 } }, // pmaddubsw
950 { ISD::MUL, MVT::v32i16, { 1, 5, 1, 1 } }, // pmullw
951
952 { ISD::SUB, MVT::v32i8, { 1, 1, 1, 1 } }, // psubb
953 { ISD::SUB, MVT::v16i16, { 1, 1, 1, 1 } }, // psubw
954 { ISD::SUB, MVT::v8i32, { 1, 1, 1, 1 } }, // psubd
955 { ISD::SUB, MVT::v4i64, { 1, 1, 1, 1 } }, // psubq
956 };
957
958 // Look for AVX512BW lowering tricks for custom cases.
959 if (ST->hasBWI())
960 if (const auto *Entry = CostTableLookup(AVX512BWCostTable, ISD, LT.second))
961 if (auto KindCost = Entry->Cost[CostKind])
962 return LT.first * *KindCost;
963
964 static const CostKindTblEntry AVX512CostTable[] = {
965 { ISD::SHL, MVT::v64i8, { 15, 19,27,33 } }, // vpblendv+split sequence.
966 { ISD::SRL, MVT::v64i8, { 15, 19,30,36 } }, // vpblendv+split sequence.
967 { ISD::SRA, MVT::v64i8, { 37, 37,51,63 } }, // vpblendv+split sequence.
968
969 { ISD::SHL, MVT::v32i16, { 11, 16,11,15 } }, // 2*extend/vpsrlvd/pack sequence.
970 { ISD::SRL, MVT::v32i16, { 11, 16,11,15 } }, // 2*extend/vpsrlvd/pack sequence.
971 { ISD::SRA, MVT::v32i16, { 11, 16,11,15 } }, // 2*extend/vpsravd/pack sequence.
972
973 { ISD::SHL, MVT::v4i32, { 1, 1, 1, 1 } },
974 { ISD::SRL, MVT::v4i32, { 1, 1, 1, 1 } },
975 { ISD::SRA, MVT::v4i32, { 1, 1, 1, 1 } },
976 { ISD::SHL, MVT::v8i32, { 1, 1, 1, 1 } },
977 { ISD::SRL, MVT::v8i32, { 1, 1, 1, 1 } },
978 { ISD::SRA, MVT::v8i32, { 1, 1, 1, 1 } },
979 { ISD::SHL, MVT::v16i32, { 1, 1, 1, 1 } },
980 { ISD::SRL, MVT::v16i32, { 1, 1, 1, 1 } },
981 { ISD::SRA, MVT::v16i32, { 1, 1, 1, 1 } },
982
983 { ISD::SHL, MVT::v2i64, { 1, 1, 1, 1 } },
984 { ISD::SRL, MVT::v2i64, { 1, 1, 1, 1 } },
985 { ISD::SRA, MVT::v2i64, { 1, 1, 1, 1 } },
986 { ISD::SHL, MVT::v4i64, { 1, 1, 1, 1 } },
987 { ISD::SRL, MVT::v4i64, { 1, 1, 1, 1 } },
988 { ISD::SRA, MVT::v4i64, { 1, 1, 1, 1 } },
989 { ISD::SHL, MVT::v8i64, { 1, 1, 1, 1 } },
990 { ISD::SRL, MVT::v8i64, { 1, 1, 1, 1 } },
991 { ISD::SRA, MVT::v8i64, { 1, 1, 1, 1 } },
992
993 { ISD::ADD, MVT::v64i8, { 3, 7, 5, 5 } }, // 2*paddb + split
994 { ISD::ADD, MVT::v32i16, { 3, 7, 5, 5 } }, // 2*paddw + split
995
996 { ISD::SUB, MVT::v64i8, { 3, 7, 5, 5 } }, // 2*psubb + split
997 { ISD::SUB, MVT::v32i16, { 3, 7, 5, 5 } }, // 2*psubw + split
998
999 { ISD::AND, MVT::v32i8, { 1, 1, 1, 1 } },
1000 { ISD::AND, MVT::v16i16, { 1, 1, 1, 1 } },
1001 { ISD::AND, MVT::v8i32, { 1, 1, 1, 1 } },
1002 { ISD::AND, MVT::v4i64, { 1, 1, 1, 1 } },
1003
1004 { ISD::OR, MVT::v32i8, { 1, 1, 1, 1 } },
1005 { ISD::OR, MVT::v16i16, { 1, 1, 1, 1 } },
1006 { ISD::OR, MVT::v8i32, { 1, 1, 1, 1 } },
1007 { ISD::OR, MVT::v4i64, { 1, 1, 1, 1 } },
1008
1009 { ISD::XOR, MVT::v32i8, { 1, 1, 1, 1 } },
1010 { ISD::XOR, MVT::v16i16, { 1, 1, 1, 1 } },
1011 { ISD::XOR, MVT::v8i32, { 1, 1, 1, 1 } },
1012 { ISD::XOR, MVT::v4i64, { 1, 1, 1, 1 } },
1013
1014 { ISD::MUL, MVT::v16i32, { 1, 10, 1, 2 } }, // pmulld (Skylake from agner.org)
1015 { ISD::MUL, MVT::v8i32, { 1, 10, 1, 2 } }, // pmulld (Skylake from agner.org)
1016 { ISD::MUL, MVT::v4i32, { 1, 10, 1, 2 } }, // pmulld (Skylake from agner.org)
1017 { ISD::MUL, MVT::v8i64, { 6, 9, 8, 8 } }, // 3*pmuludq/3*shift/2*add
1018 { ISD::MUL, MVT::i64, { 1 } }, // Skylake from http://www.agner.org/
1019
1020 { X86ISD::PMULUDQ, MVT::v8i64, { 1, 5, 1, 1 } },
1021
1022 { ISD::FNEG, MVT::v8f64, { 1, 1, 1, 2 } }, // Skylake from http://www.agner.org/
1023 { ISD::FADD, MVT::v8f64, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1024 { ISD::FADD, MVT::v4f64, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1025 { ISD::FSUB, MVT::v8f64, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1026 { ISD::FSUB, MVT::v4f64, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1027 { ISD::FMUL, MVT::v8f64, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1028 { ISD::FMUL, MVT::v4f64, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1029 { ISD::FMUL, MVT::v2f64, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1030 { ISD::FMUL, MVT::f64, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1031
1032 { ISD::FDIV, MVT::f64, { 4, 14, 1, 1 } }, // Skylake from http://www.agner.org/
1033 { ISD::FDIV, MVT::v2f64, { 4, 14, 1, 1 } }, // Skylake from http://www.agner.org/
1034 { ISD::FDIV, MVT::v4f64, { 8, 14, 1, 1 } }, // Skylake from http://www.agner.org/
1035 { ISD::FDIV, MVT::v8f64, { 16, 23, 1, 3 } }, // Skylake from http://www.agner.org/
1036
1037 { ISD::FNEG, MVT::v16f32, { 1, 1, 1, 2 } }, // Skylake from http://www.agner.org/
1038 { ISD::FADD, MVT::v16f32, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1039 { ISD::FADD, MVT::v8f32, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1040 { ISD::FSUB, MVT::v16f32, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1041 { ISD::FSUB, MVT::v8f32, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1042 { ISD::FMUL, MVT::v16f32, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1043 { ISD::FMUL, MVT::v8f32, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1044 { ISD::FMUL, MVT::v4f32, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1045 { ISD::FMUL, MVT::f32, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1046
1047 { ISD::FDIV, MVT::f32, { 3, 11, 1, 1 } }, // Skylake from http://www.agner.org/
1048 { ISD::FDIV, MVT::v4f32, { 3, 11, 1, 1 } }, // Skylake from http://www.agner.org/
1049 { ISD::FDIV, MVT::v8f32, { 5, 11, 1, 1 } }, // Skylake from http://www.agner.org/
1050 { ISD::FDIV, MVT::v16f32, { 10, 18, 1, 3 } }, // Skylake from http://www.agner.org/
1051 };
1052
1053 if (ST->hasAVX512())
1054 if (const auto *Entry = CostTableLookup(AVX512CostTable, ISD, LT.second))
1055 if (auto KindCost = Entry->Cost[CostKind])
1056 return LT.first * *KindCost;
1057
1058 static const CostKindTblEntry AVX2ShiftCostTable[] = {
1059 // Shifts on vXi64/vXi32 on AVX2 is legal even though we declare to
1060 // customize them to detect the cases where shift amount is a scalar one.
1061 { ISD::SHL, MVT::v4i32, { 2, 3, 1, 3 } }, // vpsllvd (Haswell from agner.org)
1062 { ISD::SRL, MVT::v4i32, { 2, 3, 1, 3 } }, // vpsrlvd (Haswell from agner.org)
1063 { ISD::SRA, MVT::v4i32, { 2, 3, 1, 3 } }, // vpsravd (Haswell from agner.org)
1064 { ISD::SHL, MVT::v8i32, { 4, 4, 1, 3 } }, // vpsllvd (Haswell from agner.org)
1065 { ISD::SRL, MVT::v8i32, { 4, 4, 1, 3 } }, // vpsrlvd (Haswell from agner.org)
1066 { ISD::SRA, MVT::v8i32, { 4, 4, 1, 3 } }, // vpsravd (Haswell from agner.org)
1067 { ISD::SHL, MVT::v2i64, { 2, 3, 1, 1 } }, // vpsllvq (Haswell from agner.org)
1068 { ISD::SRL, MVT::v2i64, { 2, 3, 1, 1 } }, // vpsrlvq (Haswell from agner.org)
1069 { ISD::SHL, MVT::v4i64, { 4, 4, 1, 2 } }, // vpsllvq (Haswell from agner.org)
1070 { ISD::SRL, MVT::v4i64, { 4, 4, 1, 2 } }, // vpsrlvq (Haswell from agner.org)
1071 };
1072
1073 if (ST->hasAVX512()) {
1074 if (ISD == ISD::SHL && LT.second == MVT::v32i16 && Op2Info.isConstant())
1075 // On AVX512, a packed v32i16 shift left by a constant build_vector
1076 // is lowered into a vector multiply (vpmullw).
1077 return getArithmeticInstrCost(Instruction::Mul, Ty, CostKind,
1078 Op1Info.getNoProps(), Op2Info.getNoProps());
1079 }
1080
1081 // Look for AVX2 lowering tricks (XOP is always better at v4i32 shifts).
1082 if (ST->hasAVX2() && !(ST->hasXOP() && LT.second == MVT::v4i32)) {
1083 if (ISD == ISD::SHL && LT.second == MVT::v16i16 &&
1084 Op2Info.isConstant())
1085 // On AVX2, a packed v16i16 shift left by a constant build_vector
1086 // is lowered into a vector multiply (vpmullw).
1087 return getArithmeticInstrCost(Instruction::Mul, Ty, CostKind,
1088 Op1Info.getNoProps(), Op2Info.getNoProps());
1089
1090 if (const auto *Entry = CostTableLookup(AVX2ShiftCostTable, ISD, LT.second))
1091 if (auto KindCost = Entry->Cost[CostKind])
1092 return LT.first * *KindCost;
1093 }
1094
1095 static const CostKindTblEntry XOPShiftCostTable[] = {
1096 // 128bit shifts take 1cy, but right shifts require negation beforehand.
1097 { ISD::SHL, MVT::v16i8, { 1, 3, 1, 1 } },
1098 { ISD::SRL, MVT::v16i8, { 2, 3, 1, 1 } },
1099 { ISD::SRA, MVT::v16i8, { 2, 3, 1, 1 } },
1100 { ISD::SHL, MVT::v8i16, { 1, 3, 1, 1 } },
1101 { ISD::SRL, MVT::v8i16, { 2, 3, 1, 1 } },
1102 { ISD::SRA, MVT::v8i16, { 2, 3, 1, 1 } },
1103 { ISD::SHL, MVT::v4i32, { 1, 3, 1, 1 } },
1104 { ISD::SRL, MVT::v4i32, { 2, 3, 1, 1 } },
1105 { ISD::SRA, MVT::v4i32, { 2, 3, 1, 1 } },
1106 { ISD::SHL, MVT::v2i64, { 1, 3, 1, 1 } },
1107 { ISD::SRL, MVT::v2i64, { 2, 3, 1, 1 } },
1108 { ISD::SRA, MVT::v2i64, { 2, 3, 1, 1 } },
1109 // 256bit shifts require splitting if AVX2 didn't catch them above.
1110 { ISD::SHL, MVT::v32i8, { 4, 7, 5, 6 } },
1111 { ISD::SRL, MVT::v32i8, { 6, 7, 5, 6 } },
1112 { ISD::SRA, MVT::v32i8, { 6, 7, 5, 6 } },
1113 { ISD::SHL, MVT::v16i16, { 4, 7, 5, 6 } },
1114 { ISD::SRL, MVT::v16i16, { 6, 7, 5, 6 } },
1115 { ISD::SRA, MVT::v16i16, { 6, 7, 5, 6 } },
1116 { ISD::SHL, MVT::v8i32, { 4, 7, 5, 6 } },
1117 { ISD::SRL, MVT::v8i32, { 6, 7, 5, 6 } },
1118 { ISD::SRA, MVT::v8i32, { 6, 7, 5, 6 } },
1119 { ISD::SHL, MVT::v4i64, { 4, 7, 5, 6 } },
1120 { ISD::SRL, MVT::v4i64, { 6, 7, 5, 6 } },
1121 { ISD::SRA, MVT::v4i64, { 6, 7, 5, 6 } },
1122 };
1123
1124 // Look for XOP lowering tricks.
1125 if (ST->hasXOP()) {
1126 // If the right shift is constant then we'll fold the negation so
1127 // it's as cheap as a left shift.
1128 int ShiftISD = ISD;
1129 if ((ShiftISD == ISD::SRL || ShiftISD == ISD::SRA) && Op2Info.isConstant())
1130 ShiftISD = ISD::SHL;
1131 if (const auto *Entry =
1132 CostTableLookup(XOPShiftCostTable, ShiftISD, LT.second))
1133 if (auto KindCost = Entry->Cost[CostKind])
1134 return LT.first * *KindCost;
1135 }
1136
1137 if (ISD == ISD::SHL && !Op2Info.isUniform() && Op2Info.isConstant()) {
1138 MVT VT = LT.second;
1139 // Vector shift left by non uniform constant can be lowered
1140 // into vector multiply.
1141 if (((VT == MVT::v8i16 || VT == MVT::v4i32) && ST->hasSSE2()) ||
1142 ((VT == MVT::v16i16 || VT == MVT::v8i32) && ST->hasAVX()))
1143 ISD = ISD::MUL;
1144 }
1145
1146 static const CostKindTblEntry GLMCostTable[] = {
1147 { ISD::FDIV, MVT::f32, { 18, 19, 1, 1 } }, // divss
1148 { ISD::FDIV, MVT::v4f32, { 35, 36, 1, 1 } }, // divps
1149 { ISD::FDIV, MVT::f64, { 33, 34, 1, 1 } }, // divsd
1150 { ISD::FDIV, MVT::v2f64, { 65, 66, 1, 1 } }, // divpd
1151 };
1152
1153 if (ST->useGLMDivSqrtCosts())
1154 if (const auto *Entry = CostTableLookup(GLMCostTable, ISD, LT.second))
1155 if (auto KindCost = Entry->Cost[CostKind])
1156 return LT.first * *KindCost;
1157
1158 static const CostKindTblEntry SLMCostTable[] = {
1159 { ISD::MUL, MVT::v4i32, { 11, 11, 1, 7 } }, // pmulld
1160 { ISD::MUL, MVT::v8i16, { 2, 5, 1, 1 } }, // pmullw
1161 { ISD::FMUL, MVT::f64, { 2, 5, 1, 1 } }, // mulsd
1162 { ISD::FMUL, MVT::f32, { 1, 4, 1, 1 } }, // mulss
1163 { ISD::FMUL, MVT::v2f64, { 4, 7, 1, 1 } }, // mulpd
1164 { ISD::FMUL, MVT::v4f32, { 2, 5, 1, 1 } }, // mulps
1165 { ISD::FDIV, MVT::f32, { 17, 19, 1, 1 } }, // divss
1166 { ISD::FDIV, MVT::v4f32, { 39, 39, 1, 6 } }, // divps
1167 { ISD::FDIV, MVT::f64, { 32, 34, 1, 1 } }, // divsd
1168 { ISD::FDIV, MVT::v2f64, { 69, 69, 1, 6 } }, // divpd
1169 { ISD::FADD, MVT::v2f64, { 2, 4, 1, 1 } }, // addpd
1170 { ISD::FSUB, MVT::v2f64, { 2, 4, 1, 1 } }, // subpd
1171 // v2i64/v4i64 mul is custom lowered as a series of long:
1172 // multiplies(3), shifts(3) and adds(2)
1173 // slm muldq version throughput is 2 and addq throughput 4
1174 // thus: 3X2 (muldq throughput) + 3X1 (shift throughput) +
1175 // 3X4 (addq throughput) = 17
1176 { ISD::MUL, MVT::v2i64, { 17, 22, 9, 9 } },
1177 // slm addq\subq throughput is 4
1178 { ISD::ADD, MVT::v2i64, { 4, 2, 1, 2 } },
1179 { ISD::SUB, MVT::v2i64, { 4, 2, 1, 2 } },
1180 };
1181
1182 if (ST->useSLMArithCosts())
1183 if (const auto *Entry = CostTableLookup(SLMCostTable, ISD, LT.second))
1184 if (auto KindCost = Entry->Cost[CostKind])
1185 return LT.first * *KindCost;
1186
1187 static const CostKindTblEntry AVX2CostTable[] = {
1188 { ISD::SHL, MVT::v16i8, { 6, 21,11,16 } }, // vpblendvb sequence.
1189 { ISD::SHL, MVT::v32i8, { 6, 23,11,22 } }, // vpblendvb sequence.
1190 { ISD::SHL, MVT::v8i16, { 5, 18, 5,10 } }, // extend/vpsrlvd/pack sequence.
1191 { ISD::SHL, MVT::v16i16, { 8, 10,10,14 } }, // extend/vpsrlvd/pack sequence.
1192
1193 { ISD::SRL, MVT::v16i8, { 6, 27,12,18 } }, // vpblendvb sequence.
1194 { ISD::SRL, MVT::v32i8, { 8, 30,12,24 } }, // vpblendvb sequence.
1195 { ISD::SRL, MVT::v8i16, { 5, 11, 5,10 } }, // extend/vpsrlvd/pack sequence.
1196 { ISD::SRL, MVT::v16i16, { 8, 10,10,14 } }, // extend/vpsrlvd/pack sequence.
1197
1198 { ISD::SRA, MVT::v16i8, { 17, 17,24,30 } }, // vpblendvb sequence.
1199 { ISD::SRA, MVT::v32i8, { 18, 20,24,43 } }, // vpblendvb sequence.
1200 { ISD::SRA, MVT::v8i16, { 5, 11, 5,10 } }, // extend/vpsravd/pack sequence.
1201 { ISD::SRA, MVT::v16i16, { 8, 10,10,14 } }, // extend/vpsravd/pack sequence.
1202 { ISD::SRA, MVT::v2i64, { 4, 5, 5, 5 } }, // srl/xor/sub sequence.
1203 { ISD::SRA, MVT::v4i64, { 8, 8, 5, 9 } }, // srl/xor/sub sequence.
1204
1205 { ISD::SUB, MVT::v32i8, { 1, 1, 1, 2 } }, // psubb
1206 { ISD::ADD, MVT::v32i8, { 1, 1, 1, 2 } }, // paddb
1207 { ISD::SUB, MVT::v16i16, { 1, 1, 1, 2 } }, // psubw
1208 { ISD::ADD, MVT::v16i16, { 1, 1, 1, 2 } }, // paddw
1209 { ISD::SUB, MVT::v8i32, { 1, 1, 1, 2 } }, // psubd
1210 { ISD::ADD, MVT::v8i32, { 1, 1, 1, 2 } }, // paddd
1211 { ISD::SUB, MVT::v4i64, { 1, 1, 1, 2 } }, // psubq
1212 { ISD::ADD, MVT::v4i64, { 1, 1, 1, 2 } }, // paddq
1213
1214 { ISD::MUL, MVT::v16i8, { 5, 18, 6,12 } }, // extend/pmullw/pack
1215 { ISD::MUL, MVT::v32i8, { 4, 8, 8,16 } }, // pmaddubsw
1216 { ISD::MUL, MVT::v16i16, { 2, 5, 1, 2 } }, // pmullw
1217 { ISD::MUL, MVT::v8i32, { 4, 10, 1, 2 } }, // pmulld
1218 { ISD::MUL, MVT::v4i32, { 2, 10, 1, 2 } }, // pmulld
1219 { ISD::MUL, MVT::v4i64, { 6, 10, 8,13 } }, // 3*pmuludq/3*shift/2*add
1220 { ISD::MUL, MVT::v2i64, { 6, 10, 8, 8 } }, // 3*pmuludq/3*shift/2*add
1221
1222 { X86ISD::PMULUDQ, MVT::v4i64, { 1, 5, 1, 1 } },
1223
1224 { ISD::FNEG, MVT::v4f64, { 1, 1, 1, 2 } }, // vxorpd
1225 { ISD::FNEG, MVT::v8f32, { 1, 1, 1, 2 } }, // vxorps
1226
1227 { ISD::FADD, MVT::f64, { 1, 4, 1, 1 } }, // vaddsd
1228 { ISD::FADD, MVT::f32, { 1, 4, 1, 1 } }, // vaddss
1229 { ISD::FADD, MVT::v2f64, { 1, 4, 1, 1 } }, // vaddpd
1230 { ISD::FADD, MVT::v4f32, { 1, 4, 1, 1 } }, // vaddps
1231 { ISD::FADD, MVT::v4f64, { 1, 4, 1, 2 } }, // vaddpd
1232 { ISD::FADD, MVT::v8f32, { 1, 4, 1, 2 } }, // vaddps
1233
1234 { ISD::FSUB, MVT::f64, { 1, 4, 1, 1 } }, // vsubsd
1235 { ISD::FSUB, MVT::f32, { 1, 4, 1, 1 } }, // vsubss
1236 { ISD::FSUB, MVT::v2f64, { 1, 4, 1, 1 } }, // vsubpd
1237 { ISD::FSUB, MVT::v4f32, { 1, 4, 1, 1 } }, // vsubps
1238 { ISD::FSUB, MVT::v4f64, { 1, 4, 1, 2 } }, // vsubpd
1239 { ISD::FSUB, MVT::v8f32, { 1, 4, 1, 2 } }, // vsubps
1240
1241 { ISD::FMUL, MVT::f64, { 1, 5, 1, 1 } }, // vmulsd
1242 { ISD::FMUL, MVT::f32, { 1, 5, 1, 1 } }, // vmulss
1243 { ISD::FMUL, MVT::v2f64, { 1, 5, 1, 1 } }, // vmulpd
1244 { ISD::FMUL, MVT::v4f32, { 1, 5, 1, 1 } }, // vmulps
1245 { ISD::FMUL, MVT::v4f64, { 1, 5, 1, 2 } }, // vmulpd
1246 { ISD::FMUL, MVT::v8f32, { 1, 5, 1, 2 } }, // vmulps
1247
1248 { ISD::FDIV, MVT::f32, { 7, 13, 1, 1 } }, // vdivss
1249 { ISD::FDIV, MVT::v4f32, { 7, 13, 1, 1 } }, // vdivps
1250 { ISD::FDIV, MVT::v8f32, { 14, 21, 1, 3 } }, // vdivps
1251 { ISD::FDIV, MVT::f64, { 14, 20, 1, 1 } }, // vdivsd
1252 { ISD::FDIV, MVT::v2f64, { 14, 20, 1, 1 } }, // vdivpd
1253 { ISD::FDIV, MVT::v4f64, { 28, 35, 1, 3 } }, // vdivpd
1254 };
1255
1256 // Look for AVX2 lowering tricks for custom cases.
1257 if (ST->hasAVX2())
1258 if (const auto *Entry = CostTableLookup(AVX2CostTable, ISD, LT.second))
1259 if (auto KindCost = Entry->Cost[CostKind])
1260 return LT.first * *KindCost;
1261
1262 static const CostKindTblEntry AVX1CostTable[] = {
1263 // We don't have to scalarize unsupported ops. We can issue two half-sized
1264 // operations and we only need to extract the upper YMM half.
1265 // Two ops + 1 extract + 1 insert = 4.
1266 { ISD::MUL, MVT::v32i8, { 10, 11, 18, 19 } }, // pmaddubsw + split
1267 { ISD::MUL, MVT::v16i8, { 5, 6, 8, 12 } }, // 2*pmaddubsw/3*and/psllw/or
1268 { ISD::MUL, MVT::v16i16, { 4, 8, 5, 6 } }, // pmullw + split
1269 { ISD::MUL, MVT::v8i32, { 5, 8, 5, 10 } }, // pmulld + split
1270 { ISD::MUL, MVT::v4i32, { 2, 5, 1, 3 } }, // pmulld
1271 { ISD::MUL, MVT::v4i64, { 12, 15, 19, 20 } },
1272
1273 { X86ISD::PMULUDQ, MVT::v4i64, { 3, 5, 5, 6 } }, // pmuludq + split
1274
1275 { ISD::AND, MVT::v32i8, { 1, 1, 1, 2 } }, // vandps
1276 { ISD::AND, MVT::v16i16, { 1, 1, 1, 2 } }, // vandps
1277 { ISD::AND, MVT::v8i32, { 1, 1, 1, 2 } }, // vandps
1278 { ISD::AND, MVT::v4i64, { 1, 1, 1, 2 } }, // vandps
1279
1280 { ISD::OR, MVT::v32i8, { 1, 1, 1, 2 } }, // vorps
1281 { ISD::OR, MVT::v16i16, { 1, 1, 1, 2 } }, // vorps
1282 { ISD::OR, MVT::v8i32, { 1, 1, 1, 2 } }, // vorps
1283 { ISD::OR, MVT::v4i64, { 1, 1, 1, 2 } }, // vorps
1284
1285 { ISD::XOR, MVT::v32i8, { 1, 1, 1, 2 } }, // vxorps
1286 { ISD::XOR, MVT::v16i16, { 1, 1, 1, 2 } }, // vxorps
1287 { ISD::XOR, MVT::v8i32, { 1, 1, 1, 2 } }, // vxorps
1288 { ISD::XOR, MVT::v4i64, { 1, 1, 1, 2 } }, // vxorps
1289
1290 { ISD::SUB, MVT::v32i8, { 4, 2, 5, 6 } }, // psubb + split
1291 { ISD::ADD, MVT::v32i8, { 4, 2, 5, 6 } }, // paddb + split
1292 { ISD::SUB, MVT::v16i16, { 4, 2, 5, 6 } }, // psubw + split
1293 { ISD::ADD, MVT::v16i16, { 4, 2, 5, 6 } }, // paddw + split
1294 { ISD::SUB, MVT::v8i32, { 4, 2, 5, 6 } }, // psubd + split
1295 { ISD::ADD, MVT::v8i32, { 4, 2, 5, 6 } }, // paddd + split
1296 { ISD::SUB, MVT::v4i64, { 4, 2, 5, 6 } }, // psubq + split
1297 { ISD::ADD, MVT::v4i64, { 4, 2, 5, 6 } }, // paddq + split
1298 { ISD::SUB, MVT::v2i64, { 1, 1, 1, 1 } }, // psubq
1299 { ISD::ADD, MVT::v2i64, { 1, 1, 1, 1 } }, // paddq
1300
1301 { ISD::SHL, MVT::v16i8, { 10, 21,11,17 } }, // pblendvb sequence.
1302 { ISD::SHL, MVT::v32i8, { 22, 22,27,40 } }, // pblendvb sequence + split.
1303 { ISD::SHL, MVT::v8i16, { 6, 9,11,11 } }, // pblendvb sequence.
1304 { ISD::SHL, MVT::v16i16, { 13, 16,24,25 } }, // pblendvb sequence + split.
1305 { ISD::SHL, MVT::v4i32, { 3, 11, 4, 6 } }, // pslld/paddd/cvttps2dq/pmulld
1306 { ISD::SHL, MVT::v8i32, { 9, 11,12,17 } }, // pslld/paddd/cvttps2dq/pmulld + split
1307 { ISD::SHL, MVT::v2i64, { 2, 4, 4, 6 } }, // Shift each lane + blend.
1308 { ISD::SHL, MVT::v4i64, { 6, 7,11,15 } }, // Shift each lane + blend + split.
1309
1310 { ISD::SRL, MVT::v16i8, { 11, 27,12,18 } }, // pblendvb sequence.
1311 { ISD::SRL, MVT::v32i8, { 23, 23,30,43 } }, // pblendvb sequence + split.
1312 { ISD::SRL, MVT::v8i16, { 13, 16,14,22 } }, // pblendvb sequence.
1313 { ISD::SRL, MVT::v16i16, { 28, 30,31,48 } }, // pblendvb sequence + split.
1314 { ISD::SRL, MVT::v4i32, { 6, 7,12,16 } }, // Shift each lane + blend.
1315 { ISD::SRL, MVT::v8i32, { 14, 14,26,34 } }, // Shift each lane + blend + split.
1316 { ISD::SRL, MVT::v2i64, { 2, 4, 4, 6 } }, // Shift each lane + blend.
1317 { ISD::SRL, MVT::v4i64, { 6, 7,11,15 } }, // Shift each lane + blend + split.
1318
1319 { ISD::SRA, MVT::v16i8, { 21, 22,24,36 } }, // pblendvb sequence.
1320 { ISD::SRA, MVT::v32i8, { 44, 45,51,76 } }, // pblendvb sequence + split.
1321 { ISD::SRA, MVT::v8i16, { 13, 16,14,22 } }, // pblendvb sequence.
1322 { ISD::SRA, MVT::v16i16, { 28, 30,31,48 } }, // pblendvb sequence + split.
1323 { ISD::SRA, MVT::v4i32, { 6, 7,12,16 } }, // Shift each lane + blend.
1324 { ISD::SRA, MVT::v8i32, { 14, 14,26,34 } }, // Shift each lane + blend + split.
1325 { ISD::SRA, MVT::v2i64, { 5, 6,10,14 } }, // Shift each lane + blend.
1326 { ISD::SRA, MVT::v4i64, { 12, 12,22,30 } }, // Shift each lane + blend + split.
1327
1328 { ISD::FNEG, MVT::v4f64, { 2, 2, 1, 2 } }, // BTVER2 from http://www.agner.org/
1329 { ISD::FNEG, MVT::v8f32, { 2, 2, 1, 2 } }, // BTVER2 from http://www.agner.org/
1330
1331 { ISD::FADD, MVT::f64, { 1, 5, 1, 1 } }, // BDVER2 from http://www.agner.org/
1332 { ISD::FADD, MVT::f32, { 1, 5, 1, 1 } }, // BDVER2 from http://www.agner.org/
1333 { ISD::FADD, MVT::v2f64, { 1, 5, 1, 1 } }, // BDVER2 from http://www.agner.org/
1334 { ISD::FADD, MVT::v4f32, { 1, 5, 1, 1 } }, // BDVER2 from http://www.agner.org/
1335 { ISD::FADD, MVT::v4f64, { 2, 5, 1, 2 } }, // BDVER2 from http://www.agner.org/
1336 { ISD::FADD, MVT::v8f32, { 2, 5, 1, 2 } }, // BDVER2 from http://www.agner.org/
1337
1338 { ISD::FSUB, MVT::f64, { 1, 5, 1, 1 } }, // BDVER2 from http://www.agner.org/
1339 { ISD::FSUB, MVT::f32, { 1, 5, 1, 1 } }, // BDVER2 from http://www.agner.org/
1340 { ISD::FSUB, MVT::v2f64, { 1, 5, 1, 1 } }, // BDVER2 from http://www.agner.org/
1341 { ISD::FSUB, MVT::v4f32, { 1, 5, 1, 1 } }, // BDVER2 from http://www.agner.org/
1342 { ISD::FSUB, MVT::v4f64, { 2, 5, 1, 2 } }, // BDVER2 from http://www.agner.org/
1343 { ISD::FSUB, MVT::v8f32, { 2, 5, 1, 2 } }, // BDVER2 from http://www.agner.org/
1344
1345 { ISD::FMUL, MVT::f64, { 2, 5, 1, 1 } }, // BTVER2 from http://www.agner.org/
1346 { ISD::FMUL, MVT::f32, { 1, 5, 1, 1 } }, // BTVER2 from http://www.agner.org/
1347 { ISD::FMUL, MVT::v2f64, { 2, 5, 1, 1 } }, // BTVER2 from http://www.agner.org/
1348 { ISD::FMUL, MVT::v4f32, { 1, 5, 1, 1 } }, // BTVER2 from http://www.agner.org/
1349 { ISD::FMUL, MVT::v4f64, { 4, 5, 1, 2 } }, // BTVER2 from http://www.agner.org/
1350 { ISD::FMUL, MVT::v8f32, { 2, 5, 1, 2 } }, // BTVER2 from http://www.agner.org/
1351
1352 { ISD::FDIV, MVT::f32, { 14, 14, 1, 1 } }, // SNB from http://www.agner.org/
1353 { ISD::FDIV, MVT::v4f32, { 14, 14, 1, 1 } }, // SNB from http://www.agner.org/
1354 { ISD::FDIV, MVT::v8f32, { 28, 29, 1, 3 } }, // SNB from http://www.agner.org/
1355 { ISD::FDIV, MVT::f64, { 22, 22, 1, 1 } }, // SNB from http://www.agner.org/
1356 { ISD::FDIV, MVT::v2f64, { 22, 22, 1, 1 } }, // SNB from http://www.agner.org/
1357 { ISD::FDIV, MVT::v4f64, { 44, 45, 1, 3 } }, // SNB from http://www.agner.org/
1358 };
1359
1360 if (ST->hasAVX())
1361 if (const auto *Entry = CostTableLookup(AVX1CostTable, ISD, LT.second))
1362 if (auto KindCost = Entry->Cost[CostKind])
1363 return LT.first * *KindCost;
1364
1365 static const CostKindTblEntry SSE42CostTable[] = {
1366 { ISD::FADD, MVT::f64, { 1, 3, 1, 1 } }, // Nehalem from http://www.agner.org/
1367 { ISD::FADD, MVT::f32, { 1, 3, 1, 1 } }, // Nehalem from http://www.agner.org/
1368 { ISD::FADD, MVT::v2f64, { 1, 3, 1, 1 } }, // Nehalem from http://www.agner.org/
1369 { ISD::FADD, MVT::v4f32, { 1, 3, 1, 1 } }, // Nehalem from http://www.agner.org/
1370
1371 { ISD::FSUB, MVT::f64, { 1, 3, 1, 1 } }, // Nehalem from http://www.agner.org/
1372 { ISD::FSUB, MVT::f32 , { 1, 3, 1, 1 } }, // Nehalem from http://www.agner.org/
1373 { ISD::FSUB, MVT::v2f64, { 1, 3, 1, 1 } }, // Nehalem from http://www.agner.org/
1374 { ISD::FSUB, MVT::v4f32, { 1, 3, 1, 1 } }, // Nehalem from http://www.agner.org/
1375
1376 { ISD::FMUL, MVT::f64, { 1, 5, 1, 1 } }, // Nehalem from http://www.agner.org/
1377 { ISD::FMUL, MVT::f32, { 1, 5, 1, 1 } }, // Nehalem from http://www.agner.org/
1378 { ISD::FMUL, MVT::v2f64, { 1, 5, 1, 1 } }, // Nehalem from http://www.agner.org/
1379 { ISD::FMUL, MVT::v4f32, { 1, 5, 1, 1 } }, // Nehalem from http://www.agner.org/
1380
1381 { ISD::FDIV, MVT::f32, { 14, 14, 1, 1 } }, // Nehalem from http://www.agner.org/
1382 { ISD::FDIV, MVT::v4f32, { 14, 14, 1, 1 } }, // Nehalem from http://www.agner.org/
1383 { ISD::FDIV, MVT::f64, { 22, 22, 1, 1 } }, // Nehalem from http://www.agner.org/
1384 { ISD::FDIV, MVT::v2f64, { 22, 22, 1, 1 } }, // Nehalem from http://www.agner.org/
1385
1386 { ISD::MUL, MVT::v2i64, { 6, 10,10,10 } } // 3*pmuludq/3*shift/2*add
1387 };
1388
1389 if (ST->hasSSE42())
1390 if (const auto *Entry = CostTableLookup(SSE42CostTable, ISD, LT.second))
1391 if (auto KindCost = Entry->Cost[CostKind])
1392 return LT.first * *KindCost;
1393
1394 static const CostKindTblEntry SSE41CostTable[] = {
1395 { ISD::SHL, MVT::v16i8, { 15, 24,17,22 } }, // pblendvb sequence.
1396 { ISD::SHL, MVT::v8i16, { 11, 14,11,11 } }, // pblendvb sequence.
1397 { ISD::SHL, MVT::v4i32, { 14, 20, 4,10 } }, // pslld/paddd/cvttps2dq/pmulld
1398
1399 { ISD::SRL, MVT::v16i8, { 16, 27,18,24 } }, // pblendvb sequence.
1400 { ISD::SRL, MVT::v8i16, { 22, 26,23,27 } }, // pblendvb sequence.
1401 { ISD::SRL, MVT::v4i32, { 16, 17,15,19 } }, // Shift each lane + blend.
1402 { ISD::SRL, MVT::v2i64, { 4, 6, 5, 7 } }, // splat+shuffle sequence.
1403
1404 { ISD::SRA, MVT::v16i8, { 38, 41,30,36 } }, // pblendvb sequence.
1405 { ISD::SRA, MVT::v8i16, { 22, 26,23,27 } }, // pblendvb sequence.
1406 { ISD::SRA, MVT::v4i32, { 16, 17,15,19 } }, // Shift each lane + blend.
1407 { ISD::SRA, MVT::v2i64, { 8, 17, 5, 7 } }, // splat+shuffle sequence.
1408
1409 { ISD::MUL, MVT::v4i32, { 2, 11, 1, 1 } } // pmulld (Nehalem from agner.org)
1410 };
1411
1412 if (ST->hasSSE41())
1413 if (const auto *Entry = CostTableLookup(SSE41CostTable, ISD, LT.second))
1414 if (auto KindCost = Entry->Cost[CostKind])
1415 return LT.first * *KindCost;
1416
1417 static const CostKindTblEntry SSSE3CostTable[] = {
1418 { ISD::MUL, MVT::v16i8, { 5, 18,10,12 } }, // 2*pmaddubsw/3*and/psllw/or
1419 };
1420
1421 if (ST->hasSSSE3())
1422 if (const auto *Entry = CostTableLookup(SSSE3CostTable, ISD, LT.second))
1423 if (auto KindCost = Entry->Cost[CostKind])
1424 return LT.first * *KindCost;
1425
1426 static const CostKindTblEntry SSE2CostTable[] = {
1427 // We don't correctly identify costs of casts because they are marked as
1428 // custom.
1429 { ISD::SHL, MVT::v16i8, { 13, 21,26,28 } }, // cmpgtb sequence.
1430 { ISD::SHL, MVT::v8i16, { 24, 27,16,20 } }, // cmpgtw sequence.
1431 { ISD::SHL, MVT::v4i32, { 17, 19,10,12 } }, // pslld/paddd/cvttps2dq/pmuludq.
1432 { ISD::SHL, MVT::v2i64, { 4, 6, 5, 7 } }, // splat+shuffle sequence.
1433
1434 { ISD::SRL, MVT::v16i8, { 14, 28,27,30 } }, // cmpgtb sequence.
1435 { ISD::SRL, MVT::v8i16, { 16, 19,31,31 } }, // cmpgtw sequence.
1436 { ISD::SRL, MVT::v4i32, { 12, 12,15,19 } }, // Shift each lane + blend.
1437 { ISD::SRL, MVT::v2i64, { 4, 6, 5, 7 } }, // splat+shuffle sequence.
1438
1439 { ISD::SRA, MVT::v16i8, { 27, 30,54,54 } }, // unpacked cmpgtb sequence.
1440 { ISD::SRA, MVT::v8i16, { 16, 19,31,31 } }, // cmpgtw sequence.
1441 { ISD::SRA, MVT::v4i32, { 12, 12,15,19 } }, // Shift each lane + blend.
1442 { ISD::SRA, MVT::v2i64, { 8, 11,12,16 } }, // srl/xor/sub splat+shuffle sequence.
1443
1444 { ISD::AND, MVT::v16i8, { 1, 1, 1, 1 } }, // pand
1445 { ISD::AND, MVT::v8i16, { 1, 1, 1, 1 } }, // pand
1446 { ISD::AND, MVT::v4i32, { 1, 1, 1, 1 } }, // pand
1447 { ISD::AND, MVT::v2i64, { 1, 1, 1, 1 } }, // pand
1448
1449 { ISD::OR, MVT::v16i8, { 1, 1, 1, 1 } }, // por
1450 { ISD::OR, MVT::v8i16, { 1, 1, 1, 1 } }, // por
1451 { ISD::OR, MVT::v4i32, { 1, 1, 1, 1 } }, // por
1452 { ISD::OR, MVT::v2i64, { 1, 1, 1, 1 } }, // por
1453
1454 { ISD::XOR, MVT::v16i8, { 1, 1, 1, 1 } }, // pxor
1455 { ISD::XOR, MVT::v8i16, { 1, 1, 1, 1 } }, // pxor
1456 { ISD::XOR, MVT::v4i32, { 1, 1, 1, 1 } }, // pxor
1457 { ISD::XOR, MVT::v2i64, { 1, 1, 1, 1 } }, // pxor
1458
1459 { ISD::ADD, MVT::v2i64, { 1, 2, 1, 2 } }, // paddq
1460 { ISD::SUB, MVT::v2i64, { 1, 2, 1, 2 } }, // psubq
1461
1462 { ISD::MUL, MVT::v16i8, { 6, 18,12,12 } }, // 2*unpack/2*pmullw/2*and/pack
1463 { ISD::MUL, MVT::v8i16, { 1, 5, 1, 1 } }, // pmullw
1464 { ISD::MUL, MVT::v4i32, { 6, 8, 7, 7 } }, // 3*pmuludq/4*shuffle
1465 { ISD::MUL, MVT::v2i64, { 7, 10,10,10 } }, // 3*pmuludq/3*shift/2*add
1466
1467 { X86ISD::PMULUDQ, MVT::v2i64, { 1, 5, 1, 1 } },
1468
1469 { ISD::FDIV, MVT::f32, { 23, 23, 1, 1 } }, // Pentium IV from http://www.agner.org/
1470 { ISD::FDIV, MVT::v4f32, { 39, 39, 1, 1 } }, // Pentium IV from http://www.agner.org/
1471 { ISD::FDIV, MVT::f64, { 38, 38, 1, 1 } }, // Pentium IV from http://www.agner.org/
1472 { ISD::FDIV, MVT::v2f64, { 69, 69, 1, 1 } }, // Pentium IV from http://www.agner.org/
1473
1474 { ISD::FNEG, MVT::f32, { 1, 1, 1, 1 } }, // Pentium IV from http://www.agner.org/
1475 { ISD::FNEG, MVT::f64, { 1, 1, 1, 1 } }, // Pentium IV from http://www.agner.org/
1476 { ISD::FNEG, MVT::v4f32, { 1, 1, 1, 1 } }, // Pentium IV from http://www.agner.org/
1477 { ISD::FNEG, MVT::v2f64, { 1, 1, 1, 1 } }, // Pentium IV from http://www.agner.org/
1478
1479 { ISD::FADD, MVT::f32, { 2, 3, 1, 1 } }, // Pentium IV from http://www.agner.org/
1480 { ISD::FADD, MVT::f64, { 2, 3, 1, 1 } }, // Pentium IV from http://www.agner.org/
1481 { ISD::FADD, MVT::v2f64, { 2, 3, 1, 1 } }, // Pentium IV from http://www.agner.org/
1482
1483 { ISD::FSUB, MVT::f32, { 2, 3, 1, 1 } }, // Pentium IV from http://www.agner.org/
1484 { ISD::FSUB, MVT::f64, { 2, 3, 1, 1 } }, // Pentium IV from http://www.agner.org/
1485 { ISD::FSUB, MVT::v2f64, { 2, 3, 1, 1 } }, // Pentium IV from http://www.agner.org/
1486
1487 { ISD::FMUL, MVT::f64, { 2, 5, 1, 1 } }, // Pentium IV from http://www.agner.org/
1488 { ISD::FMUL, MVT::v2f64, { 2, 5, 1, 1 } }, // Pentium IV from http://www.agner.org/
1489 };
1490
1491 if (ST->hasSSE2())
1492 if (const auto *Entry = CostTableLookup(SSE2CostTable, ISD, LT.second))
1493 if (auto KindCost = Entry->Cost[CostKind])
1494 return LT.first * *KindCost;
1495
1496 static const CostKindTblEntry SSE1CostTable[] = {
1497 { ISD::FDIV, MVT::f32, { 17, 18, 1, 1 } }, // Pentium III from http://www.agner.org/
1498 { ISD::FDIV, MVT::v4f32, { 34, 48, 1, 1 } }, // Pentium III from http://www.agner.org/
1499
1500 { ISD::FNEG, MVT::f32, { 2, 2, 1, 2 } }, // Pentium III from http://www.agner.org/
1501 { ISD::FNEG, MVT::v4f32, { 2, 2, 1, 2 } }, // Pentium III from http://www.agner.org/
1502
1503 { ISD::FADD, MVT::f32, { 1, 3, 1, 1 } }, // Pentium III from http://www.agner.org/
1504 { ISD::FADD, MVT::v4f32, { 2, 3, 1, 1 } }, // Pentium III from http://www.agner.org/
1505
1506 { ISD::FSUB, MVT::f32, { 1, 3, 1, 1 } }, // Pentium III from http://www.agner.org/
1507 { ISD::FSUB, MVT::v4f32, { 2, 3, 1, 1 } }, // Pentium III from http://www.agner.org/
1508
1509 { ISD::FMUL, MVT::f32, { 2, 5, 1, 1 } }, // Pentium III from http://www.agner.org/
1510 { ISD::FMUL, MVT::v4f32, { 2, 5, 1, 1 } }, // Pentium III from http://www.agner.org/
1511 };
1512
1513 if (ST->hasSSE1())
1514 if (const auto *Entry = CostTableLookup(SSE1CostTable, ISD, LT.second))
1515 if (auto KindCost = Entry->Cost[CostKind])
1516 return LT.first * *KindCost;
1517
1518 static const CostKindTblEntry X64CostTbl[] = { // 64-bit targets
1519 { ISD::ADD, MVT::i64, { 1 } }, // Core (Merom) from http://www.agner.org/
1520 { ISD::SUB, MVT::i64, { 1 } }, // Core (Merom) from http://www.agner.org/
1521 { ISD::MUL, MVT::i64, { 2, 6, 1, 2 } },
1522 };
1523
1524 if (ST->is64Bit())
1525 if (const auto *Entry = CostTableLookup(X64CostTbl, ISD, LT.second))
1526 if (auto KindCost = Entry->Cost[CostKind])
1527 return LT.first * *KindCost;
1528
1529 static const CostKindTblEntry X86CostTbl[] = { // 32 or 64-bit targets
1530 { ISD::ADD, MVT::i8, { 1 } }, // Pentium III from http://www.agner.org/
1531 { ISD::ADD, MVT::i16, { 1 } }, // Pentium III from http://www.agner.org/
1532 { ISD::ADD, MVT::i32, { 1 } }, // Pentium III from http://www.agner.org/
1533
1534 { ISD::SUB, MVT::i8, { 1 } }, // Pentium III from http://www.agner.org/
1535 { ISD::SUB, MVT::i16, { 1 } }, // Pentium III from http://www.agner.org/
1536 { ISD::SUB, MVT::i32, { 1 } }, // Pentium III from http://www.agner.org/
1537
1538 { ISD::MUL, MVT::i8, { 3, 4, 1, 1 } },
1539 { ISD::MUL, MVT::i16, { 2, 4, 1, 1 } },
1540 { ISD::MUL, MVT::i32, { 1, 4, 1, 1 } },
1541
1542 { ISD::FNEG, MVT::f64, { 2, 2, 1, 3 } }, // (x87)
1543 { ISD::FADD, MVT::f64, { 2, 3, 1, 1 } }, // (x87)
1544 { ISD::FSUB, MVT::f64, { 2, 3, 1, 1 } }, // (x87)
1545 { ISD::FMUL, MVT::f64, { 2, 5, 1, 1 } }, // (x87)
1546 { ISD::FDIV, MVT::f64, { 38, 38, 1, 1 } }, // (x87)
1547 };
1548
1549 if (const auto *Entry = CostTableLookup(X86CostTbl, ISD, LT.second))
1550 if (auto KindCost = Entry->Cost[CostKind])
1551 return LT.first * *KindCost;
1552
1553 // It is not a good idea to vectorize division. We have to scalarize it and
1554 // in the process we will often end up having to spilling regular
1555 // registers. The overhead of division is going to dominate most kernels
1556 // anyways so try hard to prevent vectorization of division - it is
1557 // generally a bad idea. Assume somewhat arbitrarily that we have to be able
1558 // to hide "20 cycles" for each lane.
1559 if (CostKind == TTI::TCK_RecipThroughput && LT.second.isVector() &&
1560 (ISD == ISD::SDIV || ISD == ISD::SREM || ISD == ISD::UDIV ||
1561 ISD == ISD::UREM)) {
1562 InstructionCost ScalarCost =
1563 getArithmeticInstrCost(Opcode, Ty->getScalarType(), CostKind,
1564 Op1Info.getNoProps(), Op2Info.getNoProps());
1565 return 20 * LT.first * LT.second.getVectorNumElements() * ScalarCost;
1566 }
1567
1568 // Handle some basic single instruction code size cases.
1569 if (CostKind == TTI::TCK_CodeSize) {
1570 switch (ISD) {
1571 case ISD::FADD:
1572 case ISD::FSUB:
1573 case ISD::FMUL:
1574 case ISD::FDIV:
1575 case ISD::FNEG:
1576 case ISD::AND:
1577 case ISD::OR:
1578 case ISD::XOR:
1579 return LT.first;
1580 break;
1581 }
1582 }
1583
1584 // Fallback to the default implementation.
1585 return BaseT::getArithmeticInstrCost(Opcode, Ty, CostKind, Op1Info, Op2Info,
1586 Args, CxtI);
1587}
1588
1591 unsigned Opcode1, const SmallBitVector &OpcodeMask,
1593 if (isLegalAltInstr(VecTy, Opcode0, Opcode1, OpcodeMask))
1594 return TTI::TCC_Basic;
1596}
1597
1599 VectorType *DstTy, VectorType *SrcTy,
1600 ArrayRef<int> Mask,
1602 int Index, VectorType *SubTp,
1604 const Instruction *CxtI) const {
1605 assert((Mask.empty() || DstTy->isScalableTy() ||
1606 Mask.size() == DstTy->getElementCount().getKnownMinValue()) &&
1607 "Expected the Mask to match the return size if given");
1608 assert(SrcTy->getScalarType() == DstTy->getScalarType() &&
1609 "Expected the same scalar types");
1610
1611 // 64-bit packed float vectors (v2f32) are widened to type v4f32.
1612 // 64-bit packed integer vectors (v2i32) are widened to type v4i32.
1613 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(SrcTy);
1614
1615 Kind = improveShuffleKindFromMask(Kind, Mask, SrcTy, Index, SubTp);
1616
1617 // If all args are constant than this will be constant folded away.
1618 if (!Args.empty() &&
1619 all_of(Args, [](const Value *Arg) { return isa<Constant>(Arg); }))
1620 return TTI::TCC_Free;
1621
1622 // Recognize a basic concat_vector shuffle.
1623 if (Kind == TTI::SK_PermuteTwoSrc &&
1624 Mask.size() == (2 * SrcTy->getElementCount().getKnownMinValue()) &&
1625 ShuffleVectorInst::isIdentityMask(Mask, Mask.size()))
1629 CostKind, Mask.size() / 2, SrcTy);
1630
1631 // Treat Transpose as 2-op shuffles - there's no difference in lowering.
1632 if (Kind == TTI::SK_Transpose)
1633 if (LT.second != MVT::v4f64 && LT.second != MVT::v4i64)
1634 Kind = TTI::SK_PermuteTwoSrc;
1635
1636 if (Kind == TTI::SK_Broadcast) {
1637 // For Broadcasts we are splatting the first element from the first input
1638 // register, so only need to reference that input and all the output
1639 // registers are the same.
1640 LT.first = 1;
1641
1642 // If we're broadcasting a load then AVX/AVX2 can do this for free.
1643 // If many-used-load whose every use is one of a small set of operations
1644 // that SLP can rewrite into a single vector lane, codegen can fold it into
1645 // the free broadcast.
1646 using namespace PatternMatch;
1647 auto IsBroadcastLoadFoldUser = [&](const User *U) {
1648 if (isa<InsertElementInst>(U) && U->getOperand(1) == Args[0])
1649 return true;
1650 if (U->getType()->isVectorTy())
1651 return false;
1652 // Terminators (return/branch/switch/indirectbr/resume/invoke EH)
1653 // and phis carry the value across control flow.
1654 if (const auto *I = dyn_cast<Instruction>(U))
1655 if (I->isTerminator() ||
1657 return false;
1658 // Only pure calls can be folded.
1659 if (const auto *CB = dyn_cast<CallBase>(U))
1660 return CB->doesNotAccessMemory() && !CB->mayHaveSideEffects();
1661 return true;
1662 };
1663 auto IsFoldableSLPBroadcastLoad = [&]() {
1664 if (!match(Args[0], m_Load(m_Value())))
1665 return false;
1666 auto *FVT = dyn_cast<FixedVectorType>(DstTy);
1667 if (!FVT)
1668 return false;
1669 // getNumUses() counts each Use, matching the per-lane broadcast
1670 // accounting (a use like `op %x, %x` consumes two broadcast lanes).
1671 if (Args[0]->getNumUses() != FVT->getNumElements())
1672 return false;
1673 return all_of(Args[0]->users(), IsBroadcastLoadFoldUser);
1674 };
1675 if (!Args.empty() &&
1676 (match(Args[0], m_OneUse(m_Load(m_Value()))) ||
1677 IsFoldableSLPBroadcastLoad()) &&
1678 (ST->hasAVX2() ||
1679 (ST->hasAVX() && LT.second.getScalarSizeInBits() >= 32)))
1680 return TTI::TCC_Free;
1681 }
1682
1683 // Attempt to detect a cheaper inlane shuffle, avoiding 128-bit subvector
1684 // permutation.
1685 // Attempt to detect a shuffle mask with a single defined element.
1686 bool IsInLaneShuffle = false;
1687 bool IsSingleElementMask = false;
1688 if (SrcTy->getPrimitiveSizeInBits() > 0 &&
1689 (SrcTy->getPrimitiveSizeInBits() % 128) == 0 &&
1690 SrcTy->getScalarSizeInBits() == LT.second.getScalarSizeInBits() &&
1691 Mask.size() == SrcTy->getElementCount().getKnownMinValue()) {
1692 unsigned NumLanes = SrcTy->getPrimitiveSizeInBits() / 128;
1693 unsigned NumEltsPerLane = Mask.size() / NumLanes;
1694 if ((Mask.size() % NumLanes) == 0) {
1695 IsInLaneShuffle = all_of(enumerate(Mask), [&](const auto &P) {
1696 return P.value() == PoisonMaskElem ||
1697 ((P.value() % Mask.size()) / NumEltsPerLane) ==
1698 (P.index() / NumEltsPerLane);
1699 });
1700 IsSingleElementMask =
1701 (Mask.size() - 1) == static_cast<unsigned>(count_if(Mask, [](int M) {
1702 return M == PoisonMaskElem;
1703 }));
1704 }
1705 }
1706
1707 // Treat <X x bfloat> shuffles as <X x half>.
1708 if (LT.second.isVectorOf(MVT::bf16))
1709 LT.second = LT.second.changeVectorElementType(MVT::f16);
1710
1711 // Subvector extractions are free if they start at the beginning of a
1712 // vector and cheap if the subvectors are aligned.
1713 if (Kind == TTI::SK_ExtractSubvector && LT.second.isVector()) {
1714 int NumElts = LT.second.getVectorNumElements();
1715 if ((Index % NumElts) == 0)
1716 return TTI::TCC_Free;
1717 std::pair<InstructionCost, MVT> SubLT = getTypeLegalizationCost(SubTp);
1718 if (SubLT.second.isVector()) {
1719 int NumSubElts = SubLT.second.getVectorNumElements();
1720 if ((Index % NumSubElts) == 0 && (NumElts % NumSubElts) == 0)
1721 return SubLT.first;
1722 // Handle some cases for widening legalization. For now we only handle
1723 // cases where the original subvector was naturally aligned and evenly
1724 // fit in its legalized subvector type.
1725 // FIXME: Remove some of the alignment restrictions.
1726 // FIXME: We can use permq for 64-bit or larger extracts from 256-bit
1727 // vectors.
1728 int OrigSubElts = cast<FixedVectorType>(SubTp)->getNumElements();
1729 if (NumSubElts > OrigSubElts && (Index % OrigSubElts) == 0 &&
1730 (NumSubElts % OrigSubElts) == 0 &&
1731 LT.second.getVectorElementType() ==
1732 SubLT.second.getVectorElementType() &&
1733 LT.second.getVectorElementType().getSizeInBits() ==
1734 SrcTy->getElementType()->getPrimitiveSizeInBits()) {
1735 assert(NumElts >= NumSubElts && NumElts > OrigSubElts &&
1736 "Unexpected number of elements!");
1737 auto *VecTy = FixedVectorType::get(SrcTy->getElementType(),
1738 LT.second.getVectorNumElements());
1739 auto *SubTy = FixedVectorType::get(SrcTy->getElementType(),
1740 SubLT.second.getVectorNumElements());
1741 int ExtractIndex = alignDown((Index % NumElts), NumSubElts);
1742 InstructionCost ExtractCost =
1744 ExtractIndex, SubTy);
1745
1746 // If the original size is 32-bits or more, we can use pshufd. Otherwise
1747 // if we have SSSE3 we can use pshufb.
1748 if (SubTp->getPrimitiveSizeInBits() >= 32 || ST->hasSSSE3())
1749 return ExtractCost + 1; // pshufd or pshufb
1750
1751 assert(SubTp->getPrimitiveSizeInBits() == 16 &&
1752 "Unexpected vector size");
1753
1754 return ExtractCost + 2; // worst case pshufhw + pshufd
1755 }
1756 }
1757 // If the extract subvector is not optimal, treat it as single op shuffle.
1759 }
1760
1761 // Subvector insertions are cheap if the subvectors are aligned.
1762 // Note that in general, the insertion starting at the beginning of a vector
1763 // isn't free, because we need to preserve the rest of the wide vector,
1764 // but if the destination vector legalizes to the same width as the subvector
1765 // then the insertion will simplify to a (free) register copy.
1766 if (Kind == TTI::SK_InsertSubvector && LT.second.isVector()) {
1767 std::pair<InstructionCost, MVT> DstLT = getTypeLegalizationCost(DstTy);
1768 int NumElts = DstLT.second.getVectorNumElements();
1769 std::pair<InstructionCost, MVT> SubLT = getTypeLegalizationCost(SubTp);
1770 if (SubLT.second.isVector()) {
1771 int NumSubElts = SubLT.second.getVectorNumElements();
1772 bool MatchingTypes =
1773 NumElts == NumSubElts &&
1774 (SubTp->getElementCount().getKnownMinValue() % NumSubElts) == 0;
1775 if ((Index % NumSubElts) == 0 && (NumElts % NumSubElts) == 0)
1776 return MatchingTypes ? TTI::TCC_Free : SubLT.first;
1777 }
1778
1779 // Attempt to match MOVSS (Idx == 0) or INSERTPS pattern. This will have
1780 // been matched by improveShuffleKindFromMask as a SK_InsertSubvector of
1781 // v1f32 (legalised to f32) into a v4f32.
1782 if (LT.first == 1 && LT.second == MVT::v4f32 && SubLT.first == 1 &&
1783 SubLT.second == MVT::f32 && (Index == 0 || ST->hasSSE41()))
1784 return 1;
1785
1786 // If the insertion is the lowest subvector then it will be blended
1787 // otherwise treat it like a 2-op shuffle.
1788 Kind =
1789 (Index == 0 && LT.first == 1) ? TTI::SK_Select : TTI::SK_PermuteTwoSrc;
1790 }
1791
1792 // Handle some common (illegal) sub-vector types as they are often very cheap
1793 // to shuffle even on targets without PSHUFB.
1794 EVT VT = TLI->getValueType(DL, SrcTy);
1795 if (VT.isSimple() && VT.isVector() && VT.getSizeInBits() < 128 &&
1796 !ST->hasSSSE3()) {
1797 static const CostKindTblEntry SSE2SubVectorShuffleTbl[] = {
1798 {TTI::SK_Broadcast, MVT::v4i16, {1,1,1,1}}, // pshuflw
1799 {TTI::SK_Broadcast, MVT::v2i16, {1,1,1,1}}, // pshuflw
1800 {TTI::SK_Broadcast, MVT::v8i8, {2,2,2,2}}, // punpck/pshuflw
1801 {TTI::SK_Broadcast, MVT::v4i8, {2,2,2,2}}, // punpck/pshuflw
1802 {TTI::SK_Broadcast, MVT::v2i8, {1,1,1,1}}, // punpck
1803
1804 {TTI::SK_Reverse, MVT::v4i16, {1,1,1,1}}, // pshuflw
1805 {TTI::SK_Reverse, MVT::v2i16, {1,1,1,1}}, // pshuflw
1806 {TTI::SK_Reverse, MVT::v4i8, {3,3,3,3}}, // punpck/pshuflw/packus
1807 {TTI::SK_Reverse, MVT::v2i8, {1,1,1,1}}, // punpck
1808
1809 {TTI::SK_Splice, MVT::v4i16, {2,2,2,2}}, // punpck+psrldq
1810 {TTI::SK_Splice, MVT::v2i16, {2,2,2,2}}, // punpck+psrldq
1811 {TTI::SK_Splice, MVT::v4i8, {2,2,2,2}}, // punpck+psrldq
1812 {TTI::SK_Splice, MVT::v2i8, {2,2,2,2}}, // punpck+psrldq
1813
1814 {TTI::SK_PermuteTwoSrc, MVT::v4i16, {2,2,2,2}}, // punpck/pshuflw
1815 {TTI::SK_PermuteTwoSrc, MVT::v2i16, {2,2,2,2}}, // punpck/pshuflw
1816 {TTI::SK_PermuteTwoSrc, MVT::v8i8, {7,7,7,7}}, // punpck/pshuflw
1817 {TTI::SK_PermuteTwoSrc, MVT::v4i8, {4,4,4,4}}, // punpck/pshuflw
1818 {TTI::SK_PermuteTwoSrc, MVT::v2i8, {2,2,2,2}}, // punpck
1819
1820 {TTI::SK_PermuteSingleSrc, MVT::v4i16, {1,1,1,1}}, // pshuflw
1821 {TTI::SK_PermuteSingleSrc, MVT::v2i16, {1,1,1,1}}, // pshuflw
1822 {TTI::SK_PermuteSingleSrc, MVT::v8i8, {5,5,5,5}}, // punpck/pshuflw
1823 {TTI::SK_PermuteSingleSrc, MVT::v4i8, {3,3,3,3}}, // punpck/pshuflw
1824 {TTI::SK_PermuteSingleSrc, MVT::v2i8, {1,1,1,1}}, // punpck
1825 };
1826
1827 if (ST->hasSSE2())
1828 if (const auto *Entry =
1829 CostTableLookup(SSE2SubVectorShuffleTbl, Kind, VT.getSimpleVT()))
1830 if (auto KindCost = Entry->Cost[CostKind])
1831 return LT.first * *KindCost;
1832 }
1833
1834 // We are going to permute multiple sources and the result will be in multiple
1835 // destinations. Providing an accurate cost only for splits where the element
1836 // type remains the same.
1837 if (LT.first != 1) {
1838 MVT LegalVT = LT.second;
1839 if (LegalVT.isVector() &&
1840 LegalVT.getVectorElementType().getSizeInBits() ==
1841 SrcTy->getElementType()->getPrimitiveSizeInBits() &&
1842 LegalVT.getVectorNumElements() <
1843 cast<FixedVectorType>(SrcTy)->getNumElements()) {
1844 unsigned VecTySize = DL.getTypeStoreSize(SrcTy);
1845 unsigned LegalVTSize = LegalVT.getStoreSize();
1846 // Number of source vectors after legalization:
1847 unsigned NumOfSrcs = (VecTySize + LegalVTSize - 1) / LegalVTSize;
1848 // Number of destination vectors after legalization:
1849 InstructionCost NumOfDests = LT.first;
1850
1851 auto *SingleOpTy = FixedVectorType::get(SrcTy->getElementType(),
1852 LegalVT.getVectorNumElements());
1853
1854 if (!Mask.empty() && NumOfDests.isValid()) {
1855 // Try to perform better estimation of the permutation.
1856 // 1. Split the source/destination vectors into real registers.
1857 // 2. Do the mask analysis to identify which real registers are
1858 // permuted. If more than 1 source registers are used for the
1859 // destination register building, the cost for this destination register
1860 // is (Number_of_source_register - 1) * Cost_PermuteTwoSrc. If only one
1861 // source register is used, build mask and calculate the cost as a cost
1862 // of PermuteSingleSrc.
1863 // Also, for the single register permute we try to identify if the
1864 // destination register is just a copy of the source register or the
1865 // copy of the previous destination register (the cost is
1866 // TTI::TCC_Basic). If the source register is just reused, the cost for
1867 // this operation is TTI::TCC_Free.
1868 NumOfDests =
1870 FixedVectorType::get(SrcTy->getElementType(), Mask.size()))
1871 .first;
1872 unsigned E = NumOfDests.getValue();
1873 unsigned NormalizedVF =
1874 LegalVT.getVectorNumElements() * std::max(NumOfSrcs, E);
1875 unsigned NumOfSrcRegs = NormalizedVF / LegalVT.getVectorNumElements();
1876 unsigned NumOfDestRegs = NormalizedVF / LegalVT.getVectorNumElements();
1877 SmallVector<int> NormalizedMask(NormalizedVF, PoisonMaskElem);
1878 copy(Mask, NormalizedMask.begin());
1879 unsigned PrevSrcReg = 0;
1880 ArrayRef<int> PrevRegMask;
1883 NormalizedMask, NumOfSrcRegs, NumOfDestRegs, NumOfDestRegs, []() {},
1884 [this, SingleOpTy, CostKind, &PrevSrcReg, &PrevRegMask,
1885 &Cost](ArrayRef<int> RegMask, unsigned SrcReg, unsigned DestReg) {
1886 if (!ShuffleVectorInst::isIdentityMask(RegMask, RegMask.size())) {
1887 // Check if the previous register can be just copied to the next
1888 // one.
1889 if (PrevRegMask.empty() || PrevSrcReg != SrcReg ||
1890 PrevRegMask != RegMask)
1891 Cost +=
1893 SingleOpTy, RegMask, CostKind, 0, nullptr);
1894 else
1895 // Just a copy of previous destination register.
1897 return;
1898 }
1899 if (SrcReg != DestReg &&
1900 any_of(RegMask, not_equal_to(PoisonMaskElem))) {
1901 // Just a copy of the source register.
1903 }
1904 PrevSrcReg = SrcReg;
1905 PrevRegMask = RegMask;
1906 },
1907 [this, SingleOpTy, CostKind,
1908 &Cost](ArrayRef<int> RegMask, unsigned /*Unused*/,
1909 unsigned /*Unused*/, bool /*Unused*/) {
1911 SingleOpTy, RegMask, CostKind, 0, nullptr);
1912 });
1913 return Cost;
1914 }
1915
1916 InstructionCost NumOfShuffles = (NumOfSrcs - 1) * NumOfDests;
1917 return NumOfShuffles * getShuffleCost(TTI::SK_PermuteTwoSrc, SingleOpTy,
1918 SingleOpTy, {}, CostKind, 0,
1919 nullptr);
1920 }
1921
1922 return BaseT::getShuffleCost(Kind, DstTy, SrcTy, Mask, CostKind, Index,
1923 SubTp);
1924 }
1925
1926 // If we're just moving a single element around (probably as an alternative to
1927 // extracting it), we can assume this is cheap.
1928 if (LT.first == 1 && IsInLaneShuffle && IsSingleElementMask)
1929 return TTI::TCC_Basic;
1930
1931 static const CostKindTblEntry AVX512VBMIShuffleTbl[] = {
1932 { TTI::SK_Reverse, MVT::v64i8, { 1, 1, 1, 1 } }, // vpermb
1933 { TTI::SK_Reverse, MVT::v32i8, { 1, 1, 1, 1 } }, // vpermb
1934 { TTI::SK_PermuteSingleSrc, MVT::v64i8, { 1, 1, 1, 1 } }, // vpermb
1935 { TTI::SK_PermuteSingleSrc, MVT::v32i8, { 1, 1, 1, 1 } }, // vpermb
1936 { TTI::SK_PermuteTwoSrc, MVT::v64i8, { 2, 2, 2, 2 } }, // vpermt2b
1937 { TTI::SK_PermuteTwoSrc, MVT::v32i8, { 2, 2, 2, 2 } }, // vpermt2b
1938 { TTI::SK_PermuteTwoSrc, MVT::v16i8, { 2, 2, 2, 2 } } // vpermt2b
1939 };
1940
1941 if (ST->hasVBMI())
1942 if (const auto *Entry =
1943 CostTableLookup(AVX512VBMIShuffleTbl, Kind, LT.second))
1944 if (auto KindCost = Entry->Cost[CostKind])
1945 return LT.first * *KindCost;
1946
1947 static const CostKindTblEntry AVX512BWShuffleTbl[] = {
1948 { TTI::SK_Broadcast, MVT::v32i16, { 1, 3, 1, 1 } }, // vpbroadcastw
1949 { TTI::SK_Broadcast, MVT::v32f16, { 1, 3, 1, 1 } }, // vpbroadcastw
1950 { TTI::SK_Broadcast, MVT::v64i8, { 1, 3, 1, 1 } }, // vpbroadcastb
1951
1952 { TTI::SK_Reverse, MVT::v32i16, { 2, 6, 2, 4 } }, // vpermw
1953 { TTI::SK_Reverse, MVT::v32f16, { 2, 6, 2, 4 } }, // vpermw
1954 { TTI::SK_Reverse, MVT::v16i16, { 2, 2, 2, 2 } }, // vpermw
1955 { TTI::SK_Reverse, MVT::v16f16, { 2, 2, 2, 2 } }, // vpermw
1956 { TTI::SK_Reverse, MVT::v64i8, { 2, 9, 2, 3 } }, // pshufb + vshufi64x2
1957
1958 { TTI::SK_PermuteSingleSrc, MVT::v32i16, { 2, 2, 2, 2 } }, // vpermw
1959 { TTI::SK_PermuteSingleSrc, MVT::v32f16, { 2, 2, 2, 2 } }, // vpermw
1960 { TTI::SK_PermuteSingleSrc, MVT::v16i16, { 2, 2, 2, 2 } }, // vpermw
1961 { TTI::SK_PermuteSingleSrc, MVT::v16f16, { 2, 2, 2, 2 } }, // vpermw
1962 { TTI::SK_PermuteSingleSrc, MVT::v64i8, { 8, 8, 8, 8 } }, // extend to v32i16
1963
1964 { TTI::SK_PermuteTwoSrc, MVT::v32i16,{ 2, 2, 2, 2 } }, // vpermt2w
1965 { TTI::SK_PermuteTwoSrc, MVT::v32f16,{ 2, 2, 2, 2 } }, // vpermt2w
1966 { TTI::SK_PermuteTwoSrc, MVT::v16i16,{ 2, 2, 2, 2 } }, // vpermt2w
1967 { TTI::SK_PermuteTwoSrc, MVT::v8i16, { 2, 2, 2, 2 } }, // vpermt2w
1968 { TTI::SK_PermuteTwoSrc, MVT::v64i8, { 19, 19, 19, 19 } }, // 6 * v32i8 + 1
1969
1970 { TTI::SK_Select, MVT::v32i16, { 1, 1, 1, 1 } }, // vblendmw
1971 { TTI::SK_Select, MVT::v64i8, { 1, 1, 1, 1 } }, // vblendmb
1972
1973 { TTI::SK_Splice, MVT::v32i16, { 2, 2, 2, 2 } }, // vshufi64x2 + palignr
1974 { TTI::SK_Splice, MVT::v32f16, { 2, 2, 2, 2 } }, // vshufi64x2 + palignr
1975 { TTI::SK_Splice, MVT::v64i8, { 2, 2, 2, 2 } }, // vshufi64x2 + palignr
1976 };
1977
1978 if (ST->hasBWI())
1979 if (const auto *Entry =
1980 CostTableLookup(AVX512BWShuffleTbl, Kind, LT.second))
1981 if (auto KindCost = Entry->Cost[CostKind])
1982 return LT.first * *KindCost;
1983
1984 static const CostKindTblEntry AVX512InLaneShuffleTbl[] = {
1985 {TTI::SK_PermuteTwoSrc, MVT::v8f64, { 1, 3, 1, 1 } },
1986 {TTI::SK_PermuteTwoSrc, MVT::v16f32, { 1, 3, 1, 1 } },
1987 {TTI::SK_PermuteTwoSrc, MVT::v8i64, { 1, 3, 1, 1 } },
1988 {TTI::SK_PermuteTwoSrc, MVT::v16i32, { 1, 3, 1, 1 } },
1989 {TTI::SK_PermuteTwoSrc, MVT::v4f64, { 1, 3, 1, 1 } },
1990 {TTI::SK_PermuteTwoSrc, MVT::v8f32, { 1, 3, 1, 1 } },
1991 {TTI::SK_PermuteTwoSrc, MVT::v4i64, { 1, 3, 1, 1 } },
1992 {TTI::SK_PermuteTwoSrc, MVT::v8i32, { 1, 3, 1, 1 } },
1993 };
1994
1995 if (IsInLaneShuffle && ST->hasAVX512())
1996 if (const auto *Entry =
1997 CostTableLookup(AVX512InLaneShuffleTbl, Kind, LT.second))
1998 if (auto KindCost = Entry->Cost[CostKind])
1999 return LT.first * *KindCost;
2000
2001 static const CostKindTblEntry AVX512ShuffleTbl[] = {
2002 {TTI::SK_Broadcast, MVT::v8f64, { 1, 3, 1, 1 } }, // vbroadcastsd
2003 {TTI::SK_Broadcast, MVT::v4f64, { 1, 3, 1, 1 } }, // vbroadcastsd
2004 {TTI::SK_Broadcast, MVT::v16f32, { 1, 3, 1, 1 } }, // vbroadcastss
2005 {TTI::SK_Broadcast, MVT::v8f32, { 1, 3, 1, 1 } }, // vbroadcastss
2006 {TTI::SK_Broadcast, MVT::v8i64, { 1, 3, 1, 1 } }, // vpbroadcastq
2007 {TTI::SK_Broadcast, MVT::v4i64, { 1, 3, 1, 1 } }, // vpbroadcastq
2008 {TTI::SK_Broadcast, MVT::v16i32, { 1, 3, 1, 1 } }, // vpbroadcastd
2009 {TTI::SK_Broadcast, MVT::v8i32, { 1, 3, 1, 1 } }, // vpbroadcastd
2010 {TTI::SK_Broadcast, MVT::v32i16, { 1, 3, 1, 1 } }, // vpbroadcastw
2011 {TTI::SK_Broadcast, MVT::v16i16, { 1, 3, 1, 1 } }, // vpbroadcastw
2012 {TTI::SK_Broadcast, MVT::v32f16, { 1, 3, 1, 1 } }, // vpbroadcastw
2013 {TTI::SK_Broadcast, MVT::v16f16, { 1, 3, 1, 1 } }, // vpbroadcastw
2014 {TTI::SK_Broadcast, MVT::v64i8, { 1, 3, 1, 1 } }, // vpbroadcastb
2015 {TTI::SK_Broadcast, MVT::v32i8, { 1, 3, 1, 1 }}, // vpbroadcastb
2016
2017 {TTI::SK_Reverse, MVT::v8f64, { 1, 5, 2, 3 } }, // vpermpd
2018 {TTI::SK_Reverse, MVT::v16f32, { 1, 3, 2, 3 } }, // vpermps
2019 {TTI::SK_Reverse, MVT::v8i64, { 1, 5, 2, 3 } }, // vpermq
2020 {TTI::SK_Reverse, MVT::v16i32, { 1, 3, 2, 3 } }, // vpermd
2021 {TTI::SK_Reverse, MVT::v32i16, { 7, 7, 7, 7 } }, // per mca
2022 {TTI::SK_Reverse, MVT::v32f16, { 7, 7, 7, 7 } }, // per mca
2023 {TTI::SK_Reverse, MVT::v64i8, { 7, 7, 7, 7 } }, // per mca
2024
2025 {TTI::SK_Splice, MVT::v8f64, { 1, 1, 1, 1 } }, // vpalignd
2026 {TTI::SK_Splice, MVT::v4f64, { 1, 1, 1, 1 } }, // vpalignd
2027 {TTI::SK_Splice, MVT::v16f32, { 1, 1, 1, 1 } }, // vpalignd
2028 {TTI::SK_Splice, MVT::v8f32, { 1, 1, 1, 1 } }, // vpalignd
2029 {TTI::SK_Splice, MVT::v8i64, { 1, 1, 1, 1 } }, // vpalignd
2030 {TTI::SK_Splice, MVT::v4i64, { 1, 1, 1, 1 } }, // vpalignd
2031 {TTI::SK_Splice, MVT::v16i32, { 1, 1, 1, 1 } }, // vpalignd
2032 {TTI::SK_Splice, MVT::v8i32, { 1, 1, 1, 1 } }, // vpalignd
2033 {TTI::SK_Splice, MVT::v32i16, { 4, 4, 4, 4 } }, // split + palignr
2034 {TTI::SK_Splice, MVT::v32f16, { 4, 4, 4, 4 } }, // split + palignr
2035 {TTI::SK_Splice, MVT::v64i8, { 4, 4, 4, 4 } }, // split + palignr
2036
2037 {TTI::SK_PermuteSingleSrc, MVT::v8f64, { 1, 3, 1, 1 } }, // vpermpd
2038 {TTI::SK_PermuteSingleSrc, MVT::v4f64, { 1, 3, 1, 1 } }, // vpermpd
2039 {TTI::SK_PermuteSingleSrc, MVT::v2f64, { 1, 3, 1, 1 } }, // vpermpd
2040 {TTI::SK_PermuteSingleSrc, MVT::v16f32, { 1, 3, 1, 1 } }, // vpermps
2041 {TTI::SK_PermuteSingleSrc, MVT::v8f32, { 1, 3, 1, 1 } }, // vpermps
2042 {TTI::SK_PermuteSingleSrc, MVT::v4f32, { 1, 3, 1, 1 } }, // vpermps
2043 {TTI::SK_PermuteSingleSrc, MVT::v8i64, { 1, 3, 1, 1 } }, // vpermq
2044 {TTI::SK_PermuteSingleSrc, MVT::v4i64, { 1, 3, 1, 1 } }, // vpermq
2045 {TTI::SK_PermuteSingleSrc, MVT::v2i64, { 1, 3, 1, 1 } }, // vpermq
2046 {TTI::SK_PermuteSingleSrc, MVT::v16i32, { 1, 3, 1, 1 } }, // vpermd
2047 {TTI::SK_PermuteSingleSrc, MVT::v8i32, { 1, 3, 1, 1 } }, // vpermd
2048 {TTI::SK_PermuteSingleSrc, MVT::v4i32, { 1, 3, 1, 1 } }, // vpermd
2049 {TTI::SK_PermuteSingleSrc, MVT::v16i8, { 1, 3, 1, 1 } }, // pshufb
2050
2051 {TTI::SK_PermuteTwoSrc, MVT::v8f64, { 2, 3, 1, 1 } }, // vpermt2pd
2052 {TTI::SK_PermuteTwoSrc, MVT::v16f32, { 2, 3, 1, 1 } }, // vpermt2ps
2053 {TTI::SK_PermuteTwoSrc, MVT::v8i64, { 2, 3, 1, 1 } }, // vpermt2q
2054 {TTI::SK_PermuteTwoSrc, MVT::v16i32, { 2, 3, 1, 1 } }, // vpermt2d
2055 {TTI::SK_PermuteTwoSrc, MVT::v4f64, { 2, 3, 1, 1 } }, // vpermt2pd
2056 {TTI::SK_PermuteTwoSrc, MVT::v8f32, { 2, 3, 1, 1 } }, // vpermt2ps
2057 {TTI::SK_PermuteTwoSrc, MVT::v4i64, { 2, 3, 1, 1 } }, // vpermt2q
2058 {TTI::SK_PermuteTwoSrc, MVT::v8i32, { 2, 3, 1, 1 } }, // vpermt2d
2059 {TTI::SK_PermuteTwoSrc, MVT::v2f64, { 1, 3, 1, 1 } },
2060 {TTI::SK_PermuteTwoSrc, MVT::v4f32, { 1, 3, 1, 1 } },
2061 {TTI::SK_PermuteTwoSrc, MVT::v2i64, { 1, 3, 1, 1 } },
2062 {TTI::SK_PermuteTwoSrc, MVT::v4i32, { 1, 3, 1, 1 } },
2063
2064 // FIXME: This just applies the type legalization cost rules above
2065 // assuming these completely split.
2066 {TTI::SK_PermuteSingleSrc, MVT::v32i16, { 14, 14, 14, 14 } },
2067 {TTI::SK_PermuteSingleSrc, MVT::v32f16, { 14, 14, 14, 14 } },
2068 {TTI::SK_PermuteSingleSrc, MVT::v64i8, { 14, 14, 14, 14 } },
2069 {TTI::SK_PermuteTwoSrc, MVT::v32i16, { 42, 42, 42, 42 } },
2070 {TTI::SK_PermuteTwoSrc, MVT::v32f16, { 42, 42, 42, 42 } },
2071 {TTI::SK_PermuteTwoSrc, MVT::v64i8, { 42, 42, 42, 42 } },
2072
2073 {TTI::SK_Select, MVT::v32i16, { 1, 1, 1, 1 } }, // vpternlogq
2074 {TTI::SK_Select, MVT::v32f16, { 1, 1, 1, 1 } }, // vpternlogq
2075 {TTI::SK_Select, MVT::v64i8, { 1, 1, 1, 1 } }, // vpternlogq
2076 {TTI::SK_Select, MVT::v8f64, { 1, 1, 1, 1 } }, // vblendmpd
2077 {TTI::SK_Select, MVT::v16f32, { 1, 1, 1, 1 } }, // vblendmps
2078 {TTI::SK_Select, MVT::v8i64, { 1, 1, 1, 1 } }, // vblendmq
2079 {TTI::SK_Select, MVT::v16i32, { 1, 1, 1, 1 } }, // vblendmd
2080 };
2081
2082 if (ST->hasAVX512())
2083 if (const auto *Entry = CostTableLookup(AVX512ShuffleTbl, Kind, LT.second))
2084 if (auto KindCost = Entry->Cost[CostKind])
2085 return LT.first * *KindCost;
2086
2087 static const CostKindTblEntry AVX2InLaneShuffleTbl[] = {
2088 { TTI::SK_PermuteSingleSrc, MVT::v16i16, { 1, 1, 1, 1 } }, // vpshufb
2089 { TTI::SK_PermuteSingleSrc, MVT::v16f16, { 1, 1, 1, 1 } }, // vpshufb
2090 { TTI::SK_PermuteSingleSrc, MVT::v32i8, { 1, 1, 1, 1 } }, // vpshufb
2091
2092 { TTI::SK_Transpose, MVT::v4f64, { 1, 1, 1, 1 } }, // vshufpd/vunpck
2093 { TTI::SK_Transpose, MVT::v4i64, { 1, 1, 1, 1 } }, // vshufpd/vunpck
2094
2095 { TTI::SK_PermuteTwoSrc, MVT::v4f64, { 2, 2, 2, 2 } }, // 2*vshufpd + vblendpd
2096 { TTI::SK_PermuteTwoSrc, MVT::v8f32, { 2, 2, 2, 2 } }, // 2*vshufps + vblendps
2097 { TTI::SK_PermuteTwoSrc, MVT::v4i64, { 2, 2, 2, 2 } }, // 2*vpshufd + vpblendd
2098 { TTI::SK_PermuteTwoSrc, MVT::v8i32, { 2, 2, 2, 2 } }, // 2*vpshufd + vpblendd
2099 { TTI::SK_PermuteTwoSrc, MVT::v16i16, { 2, 2, 2, 2 } }, // 2*vpshufb + vpor
2100 { TTI::SK_PermuteTwoSrc, MVT::v16f16, { 2, 2, 2, 2 } }, // 2*vpshufb + vpor
2101 { TTI::SK_PermuteTwoSrc, MVT::v32i8, { 2, 2, 2, 2 } }, // 2*vpshufb + vpor
2102 };
2103
2104 if (IsInLaneShuffle && ST->hasAVX2())
2105 if (const auto *Entry =
2106 CostTableLookup(AVX2InLaneShuffleTbl, Kind, LT.second))
2107 if (auto KindCost = Entry->Cost[CostKind])
2108 return LT.first * *KindCost;
2109
2110 static const CostKindTblEntry AVX2ShuffleTbl[] = {
2111 { TTI::SK_Broadcast, MVT::v4f64, { 1, 3, 1, 2 } }, // vbroadcastpd
2112 { TTI::SK_Broadcast, MVT::v8f32, { 1, 3, 1, 2 } }, // vbroadcastps
2113 { TTI::SK_Broadcast, MVT::v4i64, { 1, 3, 1, 2 } }, // vpbroadcastq
2114 { TTI::SK_Broadcast, MVT::v8i32, { 1, 3, 1, 2 } }, // vpbroadcastd
2115 { TTI::SK_Broadcast, MVT::v16i16, { 1, 3, 1, 2 } }, // vpbroadcastw
2116 { TTI::SK_Broadcast, MVT::v8i16, { 1, 3, 1, 1 } }, // vpbroadcastw
2117 { TTI::SK_Broadcast, MVT::v16f16, { 1, 3, 1, 2 } }, // vpbroadcastw
2118 { TTI::SK_Broadcast, MVT::v8f16, { 1, 3, 1, 1 } }, // vpbroadcastw
2119 { TTI::SK_Broadcast, MVT::v32i8, { 1, 3, 1, 2 } }, // vpbroadcastb
2120 { TTI::SK_Broadcast, MVT::v16i8, { 1, 3, 1, 1 } }, // vpbroadcastb
2121
2122 { TTI::SK_Reverse, MVT::v4f64, { 1, 6, 1, 2 } }, // vpermpd
2123 { TTI::SK_Reverse, MVT::v8f32, { 2, 7, 2, 4 } }, // vpermps
2124 { TTI::SK_Reverse, MVT::v4i64, { 1, 6, 1, 2 } }, // vpermq
2125 { TTI::SK_Reverse, MVT::v8i32, { 2, 7, 2, 4 } }, // vpermd
2126 { TTI::SK_Reverse, MVT::v16i16, { 2, 9, 2, 4 } }, // vperm2i128 + pshufb
2127 { TTI::SK_Reverse, MVT::v16f16, { 2, 9, 2, 4 } }, // vperm2i128 + pshufb
2128 { TTI::SK_Reverse, MVT::v32i8, { 2, 9, 2, 4 } }, // vperm2i128 + pshufb
2129
2130 { TTI::SK_Select, MVT::v16i16, { 1, 1, 1, 1 } }, // vpblendvb
2131 { TTI::SK_Select, MVT::v16f16, { 1, 1, 1, 1 } }, // vpblendvb
2132 { TTI::SK_Select, MVT::v32i8, { 1, 1, 1, 1 } }, // vpblendvb
2133
2134 { TTI::SK_Splice, MVT::v8i32, { 2, 2, 2, 2 } }, // vperm2i128 + vpalignr
2135 { TTI::SK_Splice, MVT::v8f32, { 2, 2, 2, 2 } }, // vperm2i128 + vpalignr
2136 { TTI::SK_Splice, MVT::v16i16, { 2, 2, 2, 2 } }, // vperm2i128 + vpalignr
2137 { TTI::SK_Splice, MVT::v16f16, { 2, 2, 2, 2 } }, // vperm2i128 + vpalignr
2138 { TTI::SK_Splice, MVT::v32i8, { 2, 2, 2, 2 } }, // vperm2i128 + vpalignr
2139
2140 { TTI::SK_PermuteSingleSrc, MVT::v4f64, { 1, 1, 1, 1 } }, // vpermpd
2141 { TTI::SK_PermuteSingleSrc, MVT::v8f32, { 1, 1, 1, 1 } }, // vpermps
2142 { TTI::SK_PermuteSingleSrc, MVT::v4i64, { 1, 1, 1, 1 } }, // vpermq
2143 { TTI::SK_PermuteSingleSrc, MVT::v8i32, { 1, 1, 1, 1 } }, // vpermd
2144 { TTI::SK_PermuteSingleSrc, MVT::v16i16, { 4, 4, 4, 4 } },
2145 { TTI::SK_PermuteSingleSrc, MVT::v16f16, { 4, 4, 4, 4 } },
2146 { TTI::SK_PermuteSingleSrc, MVT::v32i8, { 4, 4, 4, 4 } },
2147
2148 { TTI::SK_PermuteTwoSrc, MVT::v4f64, { 3, 3, 3, 3 } }, // 2*vpermpd + vblendpd
2149 { TTI::SK_PermuteTwoSrc, MVT::v8f32, { 3, 3, 3, 3 } }, // 2*vpermps + vblendps
2150 { TTI::SK_PermuteTwoSrc, MVT::v4i64, { 3, 3, 3, 3 } }, // 2*vpermq + vpblendd
2151 { TTI::SK_PermuteTwoSrc, MVT::v8i32, { 3, 3, 3, 3 } }, // 2*vpermd + vpblendd
2152 { TTI::SK_PermuteTwoSrc, MVT::v16i16, { 7, 7, 7, 7 } },
2153 { TTI::SK_PermuteTwoSrc, MVT::v16f16, { 7, 7, 7, 7 } },
2154 { TTI::SK_PermuteTwoSrc, MVT::v32i8, { 7, 7, 7, 7 } },
2155 };
2156
2157 if (ST->hasAVX2())
2158 if (const auto *Entry = CostTableLookup(AVX2ShuffleTbl, Kind, LT.second))
2159 if (auto KindCost = Entry->Cost[CostKind])
2160 return LT.first * *KindCost;
2161
2162 static const CostKindTblEntry XOPShuffleTbl[] = {
2163 { TTI::SK_PermuteSingleSrc, MVT::v4f64, { 2, 2, 2, 2 } }, // vperm2f128 + vpermil2pd
2164 { TTI::SK_PermuteSingleSrc, MVT::v8f32, { 2, 2, 2, 2 } }, // vperm2f128 + vpermil2ps
2165 { TTI::SK_PermuteSingleSrc, MVT::v4i64, { 2, 2, 2, 2 } }, // vperm2f128 + vpermil2pd
2166 { TTI::SK_PermuteSingleSrc, MVT::v8i32, { 2, 2, 2, 2 } }, // vperm2f128 + vpermil2ps
2167 { TTI::SK_PermuteSingleSrc, MVT::v16i16,{ 4, 4, 4, 4 } }, // vextractf128 + 2*vpperm
2168 // + vinsertf128
2169 { TTI::SK_PermuteSingleSrc, MVT::v32i8, { 4, 4, 4, 4 } }, // vextractf128 + 2*vpperm
2170 // + vinsertf128
2171
2172 { TTI::SK_PermuteTwoSrc, MVT::v16i16, { 9, 9, 9, 9 } }, // 2*vextractf128 + 6*vpperm
2173 // + vinsertf128
2174
2175 { TTI::SK_PermuteTwoSrc, MVT::v8i16, { 1, 1, 1, 1 } }, // vpperm
2176 { TTI::SK_PermuteTwoSrc, MVT::v32i8, { 9, 9, 9, 9 } }, // 2*vextractf128 + 6*vpperm
2177 // + vinsertf128
2178 { TTI::SK_PermuteTwoSrc, MVT::v16i8, { 1, 1, 1, 1 } }, // vpperm
2179 };
2180
2181 if (ST->hasXOP())
2182 if (const auto *Entry = CostTableLookup(XOPShuffleTbl, Kind, LT.second))
2183 if (auto KindCost = Entry->Cost[CostKind])
2184 return LT.first * *KindCost;
2185
2186 static const CostKindTblEntry AVX1InLaneShuffleTbl[] = {
2187 { TTI::SK_PermuteSingleSrc, MVT::v4f64, { 1, 1, 1, 1 } }, // vpermilpd
2188 { TTI::SK_PermuteSingleSrc, MVT::v4i64, { 1, 1, 1, 1 } }, // vpermilpd
2189 { TTI::SK_PermuteSingleSrc, MVT::v8f32, { 1, 1, 1, 1 } }, // vpermilps
2190 { TTI::SK_PermuteSingleSrc, MVT::v8i32, { 1, 1, 1, 1 } }, // vpermilps
2191
2192 { TTI::SK_PermuteSingleSrc, MVT::v16i16, { 4, 4, 4, 4 } }, // vextractf128 + 2*pshufb
2193 // + vpor + vinsertf128
2194 { TTI::SK_PermuteSingleSrc, MVT::v16f16, { 4, 4, 4, 4 } }, // vextractf128 + 2*pshufb
2195 // + vpor + vinsertf128
2196 { TTI::SK_PermuteSingleSrc, MVT::v32i8, { 4, 4, 4, 4 } }, // vextractf128 + 2*pshufb
2197 // + vpor + vinsertf128
2198
2199 { TTI::SK_Transpose, MVT::v4f64, { 1, 1, 1, 1 } }, // vshufpd/vunpck
2200 { TTI::SK_Transpose, MVT::v4i64, { 1, 1, 1, 1 } }, // vshufpd/vunpck
2201
2202 { TTI::SK_PermuteTwoSrc, MVT::v4f64, { 2, 2, 2, 2 } }, // 2*vshufpd + vblendpd
2203 { TTI::SK_PermuteTwoSrc, MVT::v8f32, { 2, 2, 2, 2 } }, // 2*vshufps + vblendps
2204 { TTI::SK_PermuteTwoSrc, MVT::v4i64, { 2, 2, 2, 2 } }, // 2*vpermilpd + vblendpd
2205 { TTI::SK_PermuteTwoSrc, MVT::v8i32, { 2, 2, 2, 2 } }, // 2*vpermilps + vblendps
2206 { TTI::SK_PermuteTwoSrc, MVT::v16i16, { 9, 9, 9, 9 } }, // 2*vextractf128 + 4*pshufb
2207 // + 2*vpor + vinsertf128
2208 { TTI::SK_PermuteTwoSrc, MVT::v16f16, { 9, 9, 9, 9 } }, // 2*vextractf128 + 4*pshufb
2209 // + 2*vpor + vinsertf128
2210 { TTI::SK_PermuteTwoSrc, MVT::v32i8, { 9, 9, 9, 9 } }, // 2*vextractf128 + 4*pshufb
2211 // + 2*vpor + vinsertf128
2212 };
2213
2214 if (IsInLaneShuffle && ST->hasAVX())
2215 if (const auto *Entry =
2216 CostTableLookup(AVX1InLaneShuffleTbl, Kind, LT.second))
2217 if (auto KindCost = Entry->Cost[CostKind])
2218 return LT.first * *KindCost;
2219
2220 static const CostKindTblEntry AVX1ShuffleTbl[] = {
2221 {TTI::SK_Broadcast, MVT::v4f64, {2,3,2,3}}, // vperm2f128 + vpermilpd
2222 {TTI::SK_Broadcast, MVT::v8f32, {2,3,2,3}}, // vperm2f128 + vpermilps
2223 {TTI::SK_Broadcast, MVT::v4i64, {2,3,2,3}}, // vperm2f128 + vpermilpd
2224 {TTI::SK_Broadcast, MVT::v8i32, {2,3,2,3}}, // vperm2f128 + vpermilps
2225 {TTI::SK_Broadcast, MVT::v16i16, {2,3,3,4}}, // vpshuflw + vpshufd + vinsertf128
2226 {TTI::SK_Broadcast, MVT::v16f16, {2,3,3,4}}, // vpshuflw + vpshufd + vinsertf128
2227 {TTI::SK_Broadcast, MVT::v32i8, {3,4,3,6}}, // vpshufb + vinsertf128
2228
2229 {TTI::SK_Reverse, MVT::v4f64, {2,6,2,2}}, // vperm2f128 + vpermilpd
2230 {TTI::SK_Reverse, MVT::v8f32, {2,7,2,4}}, // vperm2f128 + vpermilps
2231 {TTI::SK_Reverse, MVT::v4i64, {2,6,2,2}}, // vperm2f128 + vpermilpd
2232 {TTI::SK_Reverse, MVT::v8i32, {2,7,2,4}}, // vperm2f128 + vpermilps
2233 {TTI::SK_Reverse, MVT::v16i16, {2,9,5,5}}, // vextractf128 + 2*pshufb
2234 // + vinsertf128
2235 {TTI::SK_Reverse, MVT::v16f16, {2,9,5,5}}, // vextractf128 + 2*pshufb
2236 // + vinsertf128
2237 {TTI::SK_Reverse, MVT::v32i8, {2,9,5,5}}, // vextractf128 + 2*pshufb
2238 // + vinsertf128
2239
2240 {TTI::SK_Select, MVT::v4i64, {1,1,1,1}}, // vblendpd
2241 {TTI::SK_Select, MVT::v4f64, {1,1,1,1}}, // vblendpd
2242 {TTI::SK_Select, MVT::v8i32, {1,1,1,1}}, // vblendps
2243 {TTI::SK_Select, MVT::v8f32, {1,1,1,1}}, // vblendps
2244 {TTI::SK_Select, MVT::v16i16, {3,3,3,3}}, // vpand + vpandn + vpor
2245 {TTI::SK_Select, MVT::v16f16, {3,3,3,3}}, // vpand + vpandn + vpor
2246 {TTI::SK_Select, MVT::v32i8, {3,3,3,3}}, // vpand + vpandn + vpor
2247
2248 {TTI::SK_Splice, MVT::v4i64, {2,2,2,2}}, // vperm2f128 + shufpd
2249 {TTI::SK_Splice, MVT::v4f64, {2,2,2,2}}, // vperm2f128 + shufpd
2250 {TTI::SK_Splice, MVT::v8i32, {4,4,4,4}}, // 2*vperm2f128 + 2*vshufps
2251 {TTI::SK_Splice, MVT::v8f32, {4,4,4,4}}, // 2*vperm2f128 + 2*vshufps
2252 {TTI::SK_Splice, MVT::v16i16, {5,5,5,5}}, // 2*vperm2f128 + 2*vpalignr + vinsertf128
2253 {TTI::SK_Splice, MVT::v16f16, {5,5,5,5}}, // 2*vperm2f128 + 2*vpalignr + vinsertf128
2254 {TTI::SK_Splice, MVT::v32i8, {5,5,5,5}}, // 2*vperm2f128 + 2*vpalignr + vinsertf128
2255
2256 {TTI::SK_PermuteSingleSrc, MVT::v4f64, {2,2,2,2}}, // vperm2f128 + vshufpd
2257 {TTI::SK_PermuteSingleSrc, MVT::v4i64, {2,2,2,2}}, // vperm2f128 + vshufpd
2258 {TTI::SK_PermuteSingleSrc, MVT::v8f32, {4,4,4,4}}, // 2*vperm2f128 + 2*vshufps
2259 {TTI::SK_PermuteSingleSrc, MVT::v8i32, {4,4,4,4}}, // 2*vperm2f128 + 2*vshufps
2260 {TTI::SK_PermuteSingleSrc, MVT::v16i16,{8,8,8,8}}, // vextractf128 + 4*pshufb
2261 // + 2*por + vinsertf128
2262 {TTI::SK_PermuteSingleSrc, MVT::v16f16,{8,8,8,8}}, // vextractf128 + 4*pshufb
2263 // + 2*por + vinsertf128
2264 {TTI::SK_PermuteSingleSrc, MVT::v32i8, {8,8,8,8}}, // vextractf128 + 4*pshufb
2265 // + 2*por + vinsertf128
2266
2267 {TTI::SK_PermuteTwoSrc, MVT::v4f64, {3,3,3,3}}, // 2*vperm2f128 + vshufpd
2268 {TTI::SK_PermuteTwoSrc, MVT::v4i64, {3,3,3,3}}, // 2*vperm2f128 + vshufpd
2269 {TTI::SK_PermuteTwoSrc, MVT::v8f32, {4,4,4,4}}, // 2*vperm2f128 + 2*vshufps
2270 {TTI::SK_PermuteTwoSrc, MVT::v8i32, {4,4,4,4}}, // 2*vperm2f128 + 2*vshufps
2271 {TTI::SK_PermuteTwoSrc, MVT::v16i16,{15,15,15,15}}, // 2*vextractf128 + 8*pshufb
2272 // + 4*por + vinsertf128
2273 {TTI::SK_PermuteTwoSrc, MVT::v16f16,{15,15,15,15}}, // 2*vextractf128 + 8*pshufb
2274 // + 4*por + vinsertf128
2275 {TTI::SK_PermuteTwoSrc, MVT::v32i8, {15,15,15,15}}, // 2*vextractf128 + 8*pshufb
2276 // + 4*por + vinsertf128
2277 };
2278
2279 if (ST->hasAVX())
2280 if (const auto *Entry = CostTableLookup(AVX1ShuffleTbl, Kind, LT.second))
2281 if (auto KindCost = Entry->Cost[CostKind])
2282 return LT.first * *KindCost;
2283
2284 static const CostKindTblEntry SSE41ShuffleTbl[] = {
2285 {TTI::SK_Select, MVT::v2i64, {1,1,1,1}}, // pblendw
2286 {TTI::SK_Select, MVT::v2f64, {1,1,1,1}}, // movsd
2287 {TTI::SK_Select, MVT::v4i32, {1,1,1,1}}, // pblendw
2288 {TTI::SK_Select, MVT::v4f32, {1,1,1,1}}, // blendps
2289 {TTI::SK_Select, MVT::v8i16, {1,1,1,1}}, // pblendw
2290 {TTI::SK_Select, MVT::v8f16, {1,1,1,1}}, // pblendw
2291 {TTI::SK_Select, MVT::v16i8, {1,1,1,1}} // pblendvb
2292 };
2293
2294 if (ST->hasSSE41())
2295 if (const auto *Entry = CostTableLookup(SSE41ShuffleTbl, Kind, LT.second))
2296 if (auto KindCost = Entry->Cost[CostKind])
2297 return LT.first * *KindCost;
2298
2299 static const CostKindTblEntry SSSE3ShuffleTbl[] = {
2300 {TTI::SK_Broadcast, MVT::v8i16, {1, 3, 2, 2}}, // pshufb
2301 {TTI::SK_Broadcast, MVT::v8f16, {1, 3, 2, 2}}, // pshufb
2302 {TTI::SK_Broadcast, MVT::v16i8, {1, 3, 2, 2}}, // pshufb
2303
2304 {TTI::SK_Reverse, MVT::v8i16, {1, 2, 1, 2}}, // pshufb
2305 {TTI::SK_Reverse, MVT::v8f16, {1, 2, 1, 2}}, // pshufb
2306 {TTI::SK_Reverse, MVT::v16i8, {1, 2, 1, 2}}, // pshufb
2307
2308 {TTI::SK_Splice, MVT::v4i32, {1, 1, 1, 1}}, // palignr
2309 {TTI::SK_Splice, MVT::v4f32, {1, 1, 1, 1}}, // palignr
2310 {TTI::SK_Splice, MVT::v8i16, {1, 1, 1, 1}}, // palignr
2311 {TTI::SK_Splice, MVT::v8f16, {1, 1, 1, 1}}, // palignr
2312 {TTI::SK_Splice, MVT::v16i8, {1, 1, 1, 1}}, // palignr
2313
2314 {TTI::SK_PermuteSingleSrc, MVT::v8i16, {1, 1, 1, 1}}, // pshufb
2315 {TTI::SK_PermuteSingleSrc, MVT::v8f16, {1, 1, 1, 1}}, // pshufb
2316 {TTI::SK_PermuteSingleSrc, MVT::v16i8, {1, 1, 1, 1}}, // pshufb
2317
2318 {TTI::SK_PermuteTwoSrc, MVT::v8i16, {3, 3, 3, 3}}, // 2*pshufb + por
2319 {TTI::SK_PermuteTwoSrc, MVT::v8f16, {3, 3, 3, 3}}, // 2*pshufb + por
2320 {TTI::SK_PermuteTwoSrc, MVT::v16i8, {3, 3, 3, 3}}, // 2*pshufb + por
2321 };
2322
2323 if (ST->hasSSSE3())
2324 if (const auto *Entry = CostTableLookup(SSSE3ShuffleTbl, Kind, LT.second))
2325 if (auto KindCost = Entry->Cost[CostKind])
2326 return LT.first * *KindCost;
2327
2328 static const CostKindTblEntry SSE2ShuffleTbl[] = {
2329 {TTI::SK_Broadcast, MVT::v2f64, {1, 1, 1, 1}}, // shufpd
2330 {TTI::SK_Broadcast, MVT::v2i64, {1, 1, 1, 1}}, // pshufd
2331 {TTI::SK_Broadcast, MVT::v4i32, {1, 1, 1, 1}}, // pshufd
2332 {TTI::SK_Broadcast, MVT::v8i16, {1, 2, 2, 2}}, // pshuflw + pshufd
2333 {TTI::SK_Broadcast, MVT::v8f16, {1, 2, 2, 2}}, // pshuflw + pshufd
2334 {TTI::SK_Broadcast, MVT::v16i8, {2, 3, 3, 4}}, // unpck + pshuflw + pshufd
2335
2336 {TTI::SK_Reverse, MVT::v2f64, {1, 1, 1, 1}}, // shufpd
2337 {TTI::SK_Reverse, MVT::v2i64, {1, 1, 1, 1}}, // pshufd
2338 {TTI::SK_Reverse, MVT::v4i32, {1, 1, 1, 1}}, // pshufd
2339 {TTI::SK_Reverse, MVT::v8i16, {2, 3, 3, 3}}, // pshuflw + pshufhw + pshufd
2340 {TTI::SK_Reverse, MVT::v8f16, {2, 3, 3, 3}}, // pshuflw + pshufhw + pshufd
2341 {TTI::SK_Reverse, MVT::v16i8, {5, 6,11,11}}, // 2*pshuflw + 2*pshufhw
2342 // + 2*pshufd + 2*unpck + packus
2343
2344 {TTI::SK_Select, MVT::v2i64, {1, 1, 1, 1}}, // movsd
2345 {TTI::SK_Select, MVT::v2f64, {1, 1, 1, 1}}, // movsd
2346 {TTI::SK_Select, MVT::v4i32, {2, 2, 2, 2}}, // 2*shufps
2347 {TTI::SK_Select, MVT::v8i16, {2, 2, 3, 3}}, // pand + pandn + por
2348 {TTI::SK_Select, MVT::v8f16, {2, 2, 3, 3}}, // pand + pandn + por
2349 {TTI::SK_Select, MVT::v16i8, {2, 2, 3, 3}}, // pand + pandn + por
2350
2351 {TTI::SK_Splice, MVT::v2i64, {1, 1, 1, 1}}, // shufpd
2352 {TTI::SK_Splice, MVT::v2f64, {1, 1, 1, 1}}, // shufpd
2353 {TTI::SK_Splice, MVT::v4i32, {2, 2, 2, 2}}, // 2*{unpck,movsd,pshufd}
2354 {TTI::SK_Splice, MVT::v8i16, {3, 3, 3, 3}}, // psrldq + psrlldq + por
2355 {TTI::SK_Splice, MVT::v8f16, {3, 3, 3, 3}}, // psrldq + psrlldq + por
2356 {TTI::SK_Splice, MVT::v16i8, {3, 3, 3, 3}}, // psrldq + psrlldq + por
2357
2358 {TTI::SK_PermuteSingleSrc, MVT::v2f64, {1, 1, 1, 1}}, // shufpd
2359 {TTI::SK_PermuteSingleSrc, MVT::v2i64, {1, 1, 1, 1}}, // pshufd
2360 {TTI::SK_PermuteSingleSrc, MVT::v4i32, {1, 1, 1, 1}}, // pshufd
2361 {TTI::SK_PermuteSingleSrc, MVT::v8i16, {3, 5, 5, 5}}, // 2*pshuflw + 2*pshufhw
2362 // + pshufd/unpck
2363 {TTI::SK_PermuteSingleSrc, MVT::v8f16, {3, 5, 5, 5}}, // 2*pshuflw + 2*pshufhw
2364 // + pshufd/unpck
2365 {TTI::SK_PermuteSingleSrc, MVT::v16i8, {8, 10, 10, 10}}, // 2*pshuflw + 2*pshufhw
2366 // + 2*pshufd + 2*unpck + 2*packus
2367
2368 {TTI::SK_PermuteTwoSrc, MVT::v2f64, {1, 1, 1, 1}}, // shufpd
2369 {TTI::SK_PermuteTwoSrc, MVT::v2i64, {1, 1, 1, 1}}, // shufpd
2370 {TTI::SK_PermuteTwoSrc, MVT::v4i32, {2, 2, 2, 2}}, // 2*{unpck,movsd,pshufd}
2371 {TTI::SK_PermuteTwoSrc, MVT::v8i16, {6, 8, 8, 8}}, // blend+permute
2372 {TTI::SK_PermuteTwoSrc, MVT::v8f16, {6, 8, 8, 8}}, // blend+permute
2373 {TTI::SK_PermuteTwoSrc, MVT::v16i8, {11, 13, 13, 13}}, // blend+permute
2374 };
2375
2376 static const CostTblEntry SSE3BroadcastLoadTbl[] = {
2377 {TTI::SK_Broadcast, MVT::v2f64, 0}, // broadcast handled by movddup
2378 };
2379
2380 if (ST->hasSSE2()) {
2381 bool IsLoad =
2382 llvm::any_of(Args, [](const auto &V) { return isa<LoadInst>(V); });
2383 if (ST->hasSSE3() && IsLoad)
2384 if (const auto *Entry =
2385 CostTableLookup(SSE3BroadcastLoadTbl, Kind, LT.second)) {
2386 assert(isLegalBroadcastLoad(SrcTy->getElementType(),
2387 LT.second.getVectorElementCount()) &&
2388 "Table entry missing from isLegalBroadcastLoad()");
2389 return LT.first * Entry->Cost;
2390 }
2391
2392 if (const auto *Entry = CostTableLookup(SSE2ShuffleTbl, Kind, LT.second))
2393 if (auto KindCost = Entry->Cost[CostKind])
2394 return LT.first * *KindCost;
2395 }
2396
2397 static const CostKindTblEntry SSE1ShuffleTbl[] = {
2398 { TTI::SK_Broadcast, MVT::v4f32, {1,1,1,1} }, // shufps
2399 { TTI::SK_Reverse, MVT::v4f32, {1,1,1,1} }, // shufps
2400 { TTI::SK_Select, MVT::v4f32, {2,2,2,2} }, // 2*shufps
2401 { TTI::SK_Splice, MVT::v4f32, {2,2,2,2} }, // 2*shufps
2402 { TTI::SK_PermuteSingleSrc, MVT::v4f32, {1,1,1,1} }, // shufps
2403 { TTI::SK_PermuteTwoSrc, MVT::v4f32, {2,2,2,2} }, // 2*shufps
2404 };
2405
2406 if (ST->hasSSE1()) {
2407 if (LT.first == 1 && LT.second == MVT::v4f32 && Mask.size() == 4) {
2408 // SHUFPS: both pairs must come from the same source register.
2409 auto MatchSHUFPS = [](int X, int Y) {
2410 return X < 0 || Y < 0 || ((X & 4) == (Y & 4));
2411 };
2412 if (MatchSHUFPS(Mask[0], Mask[1]) && MatchSHUFPS(Mask[2], Mask[3]))
2413 return 1;
2414 }
2415 if (const auto *Entry = CostTableLookup(SSE1ShuffleTbl, Kind, LT.second))
2416 if (auto KindCost = Entry->Cost[CostKind])
2417 return LT.first * *KindCost;
2418 }
2419
2420 return BaseT::getShuffleCost(Kind, DstTy, SrcTy, Mask, CostKind, Index,
2421 SubTp);
2422}
2423
2425 Type *Src,
2428 const Instruction *I) const {
2429 int ISD = TLI->InstructionOpcodeToISD(Opcode);
2430 assert(ISD && "Invalid opcode");
2431
2432 // A narrow (i8/i16) zero-extension used as a GEP *index* can be folded into
2433 // the addressing mode of the consuming memory op, but only if the source is
2434 // already materialised zero-extended in a full register. X86's SIB form
2435 // [base + index*scale + disp] reads the index at full width and does NOT
2436 // zero-extend a narrow index (unlike AArch64's uxtw-extended addressing), so
2437 // a "dirty" narrow source (e.g. an i16 add result used only as an index)
2438 // still needs a dedicated movzx and is not free. Price it as free only with
2439 // positive evidence that no movzx is required.
2440 if (ISD == ISD::ZERO_EXTEND && I && I->hasOneUse() && Src->isIntegerTy() &&
2441 Src->getScalarSizeInBits() < 32) {
2442 const Use &U = *I->use_begin();
2443 if (isa<GetElementPtrInst>(U.getUser()) &&
2444 U.getOperandNo() != GetElementPtrInst::getPointerOperandIndex()) {
2445 const Value *Op = I->getOperand(0);
2446 // Clean sources: an extending load, a zeroext argument, or a value whose
2447 // high bits are provably zero (e.g. from a shift/mask). These mirror the
2448 // proof-based reasoning the middle end uses elsewhere (ValueTracking and
2449 // InstCombine's canEvaluateZExtd); we intentionally do NOT treat a merely
2450 // multiply-used operand as clean, since that is a guess rather than
2451 // proof.
2452 if (isa<LoadInst>(Op))
2453 return TTI::TCC_Free;
2454 if (const auto *A = dyn_cast<Argument>(Op))
2455 if (A->hasAttribute(Attribute::ZExt))
2456 return TTI::TCC_Free;
2457 if (computeKnownBits(Op, I->getDataLayout(), /*AC=*/nullptr, I)
2458 .countMinLeadingZeros() > 0)
2459 return TTI::TCC_Free;
2460 }
2461 }
2462
2463 // The cost tables include both specific, custom (non-legal) src/dst type
2464 // conversions and generic, legalized types. We test for customs first, before
2465 // falling back to legalization.
2466 // FIXME: Need a better design of the cost table to handle non-simple types of
2467 // potential massive combinations (elem_num x src_type x dst_type).
2468 static const TypeConversionCostKindTblEntry AVX512BWConversionTbl[]{
2469 { ISD::SIGN_EXTEND, MVT::v32i16, MVT::v32i8, { 1, 1, 1, 1 } },
2470 { ISD::ZERO_EXTEND, MVT::v32i16, MVT::v32i8, { 1, 1, 1, 1 } },
2471
2472 // Mask sign extend has an instruction.
2473 { ISD::SIGN_EXTEND, MVT::v2i8, MVT::v2i1, { 1, 1, 1, 1 } },
2474 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v2i1, { 1, 1, 1, 1 } },
2475 { ISD::SIGN_EXTEND, MVT::v2i16, MVT::v2i1, { 1, 1, 1, 1 } },
2476 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v2i1, { 1, 1, 1, 1 } },
2477 { ISD::SIGN_EXTEND, MVT::v4i8, MVT::v4i1, { 1, 1, 1, 1 } },
2478 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v4i1, { 1, 1, 1, 1 } },
2479 { ISD::SIGN_EXTEND, MVT::v4i16, MVT::v4i1, { 1, 1, 1, 1 } },
2480 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v4i1, { 1, 1, 1, 1 } },
2481 { ISD::SIGN_EXTEND, MVT::v8i8, MVT::v8i1, { 1, 1, 1, 1 } },
2482 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v8i1, { 1, 1, 1, 1 } },
2483 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v8i1, { 1, 1, 1, 1 } },
2484 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v16i1, { 1, 1, 1, 1 } },
2485 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i1, { 1, 1, 1, 1 } },
2486 { ISD::SIGN_EXTEND, MVT::v32i8, MVT::v32i1, { 1, 1, 1, 1 } },
2487 { ISD::SIGN_EXTEND, MVT::v32i16, MVT::v32i1, { 1, 1, 1, 1 } },
2488 { ISD::SIGN_EXTEND, MVT::v64i8, MVT::v64i1, { 1, 1, 1, 1 } },
2489 { ISD::SIGN_EXTEND, MVT::v32i16, MVT::v64i1, { 1, 1, 1, 1 } },
2490
2491 // Mask zero extend is a sext + shift.
2492 { ISD::ZERO_EXTEND, MVT::v2i8, MVT::v2i1, { 2, 1, 1, 1 } },
2493 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v2i1, { 2, 1, 1, 1 } },
2494 { ISD::ZERO_EXTEND, MVT::v2i16, MVT::v2i1, { 2, 1, 1, 1 } },
2495 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v2i1, { 2, 1, 1, 1 } },
2496 { ISD::ZERO_EXTEND, MVT::v4i8, MVT::v4i1, { 2, 1, 1, 1 } },
2497 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v4i1, { 2, 1, 1, 1 } },
2498 { ISD::ZERO_EXTEND, MVT::v4i16, MVT::v4i1, { 2, 1, 1, 1 } },
2499 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v4i1, { 2, 1, 1, 1 } },
2500 { ISD::ZERO_EXTEND, MVT::v8i8, MVT::v8i1, { 2, 1, 1, 1 } },
2501 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v8i1, { 2, 1, 1, 1 } },
2502 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v8i1, { 2, 1, 1, 1 } },
2503 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v16i1, { 2, 1, 1, 1 } },
2504 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i1, { 2, 1, 1, 1 } },
2505 { ISD::ZERO_EXTEND, MVT::v32i8, MVT::v32i1, { 2, 1, 1, 1 } },
2506 { ISD::ZERO_EXTEND, MVT::v32i16, MVT::v32i1, { 2, 1, 1, 1 } },
2507 { ISD::ZERO_EXTEND, MVT::v64i8, MVT::v64i1, { 2, 1, 1, 1 } },
2508 { ISD::ZERO_EXTEND, MVT::v32i16, MVT::v64i1, { 2, 1, 1, 1 } },
2509
2510 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i8, { 2, 1, 1, 1 } },
2511 { ISD::TRUNCATE, MVT::v2i1, MVT::v16i8, { 2, 1, 1, 1 } },
2512 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i16, { 2, 1, 1, 1 } },
2513 { ISD::TRUNCATE, MVT::v2i1, MVT::v8i16, { 2, 1, 1, 1 } },
2514 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i8, { 2, 1, 1, 1 } },
2515 { ISD::TRUNCATE, MVT::v4i1, MVT::v16i8, { 2, 1, 1, 1 } },
2516 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i16, { 2, 1, 1, 1 } },
2517 { ISD::TRUNCATE, MVT::v4i1, MVT::v8i16, { 2, 1, 1, 1 } },
2518 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i8, { 2, 1, 1, 1 } },
2519 { ISD::TRUNCATE, MVT::v8i1, MVT::v16i8, { 2, 1, 1, 1 } },
2520 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i16, { 2, 1, 1, 1 } },
2521 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i8, { 2, 1, 1, 1 } },
2522 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i16, { 2, 1, 1, 1 } },
2523 { ISD::TRUNCATE, MVT::v32i1, MVT::v32i8, { 2, 1, 1, 1 } },
2524 { ISD::TRUNCATE, MVT::v32i1, MVT::v32i16, { 2, 1, 1, 1 } },
2525 { ISD::TRUNCATE, MVT::v64i1, MVT::v64i8, { 2, 1, 1, 1 } },
2526 { ISD::TRUNCATE, MVT::v64i1, MVT::v32i16, { 2, 1, 1, 1 } },
2527
2528 { ISD::TRUNCATE, MVT::v32i8, MVT::v32i16, { 2, 1, 1, 1 } },
2529 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i16, { 2, 1, 1, 1 } }, // widen to zmm
2530 { ISD::TRUNCATE, MVT::v2i8, MVT::v2i16, { 2, 1, 1, 1 } }, // vpmovwb
2531 { ISD::TRUNCATE, MVT::v4i8, MVT::v4i16, { 2, 1, 1, 1 } }, // vpmovwb
2532 { ISD::TRUNCATE, MVT::v8i8, MVT::v8i16, { 2, 1, 1, 1 } }, // vpmovwb
2533 };
2534
2535 static const TypeConversionCostKindTblEntry AVX512DQConversionTbl[] = {
2536 // Mask sign extend has an instruction.
2537 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v2i1, { 1, 1, 1, 1 } },
2538 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v2i1, { 1, 1, 1, 1 } },
2539 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v4i1, { 1, 1, 1, 1 } },
2540 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i1, { 1, 1, 1, 1 } },
2541 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i1, { 1, 1, 1, 1 } },
2542 { ISD::SIGN_EXTEND, MVT::v8i64, MVT::v16i1, { 1, 1, 1, 1 } },
2543 { ISD::SIGN_EXTEND, MVT::v8i64, MVT::v8i1, { 1, 1, 1, 1 } },
2544 { ISD::SIGN_EXTEND, MVT::v16i32, MVT::v16i1, { 1, 1, 1, 1 } },
2545
2546 // Mask zero extend is a sext + shift.
2547 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v2i1, { 2, 1, 1, 1, } },
2548 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v2i1, { 2, 1, 1, 1, } },
2549 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v4i1, { 2, 1, 1, 1, } },
2550 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i1, { 2, 1, 1, 1, } },
2551 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i1, { 2, 1, 1, 1, } },
2552 { ISD::ZERO_EXTEND, MVT::v8i64, MVT::v16i1, { 2, 1, 1, 1, } },
2553 { ISD::ZERO_EXTEND, MVT::v8i64, MVT::v8i1, { 2, 1, 1, 1, } },
2554 { ISD::ZERO_EXTEND, MVT::v16i32, MVT::v16i1, { 2, 1, 1, 1, } },
2555
2556 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i64, { 2, 1, 1, 1 } },
2557 { ISD::TRUNCATE, MVT::v2i1, MVT::v4i32, { 2, 1, 1, 1 } },
2558 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i32, { 2, 1, 1, 1 } },
2559 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i64, { 2, 1, 1, 1 } },
2560 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i32, { 2, 1, 1, 1 } },
2561 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i64, { 2, 1, 1, 1 } },
2562 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i32, { 2, 1, 1, 1 } },
2563 { ISD::TRUNCATE, MVT::v16i1, MVT::v8i64, { 2, 1, 1, 1 } },
2564
2565 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v8i64, { 1, 1, 1, 1 } },
2566 { ISD::SINT_TO_FP, MVT::v8f64, MVT::v8i64, { 1, 1, 1, 1 } },
2567
2568 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i64, { 1, 1, 1, 1 } },
2569 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i64, { 1, 1, 1, 1 } },
2570
2571 { ISD::FP_TO_SINT, MVT::v8i64, MVT::v8f32, { 1, 1, 1, 1 } },
2572 { ISD::FP_TO_SINT, MVT::v8i64, MVT::v8f64, { 1, 1, 1, 1 } },
2573
2574 { ISD::FP_TO_UINT, MVT::v8i64, MVT::v8f32, { 1, 1, 1, 1 } },
2575 { ISD::FP_TO_UINT, MVT::v8i64, MVT::v8f64, { 1, 1, 1, 1 } },
2576 };
2577
2578 // TODO: For AVX512DQ + AVX512VL, we also have cheap casts for 128-bit and
2579 // 256-bit wide vectors.
2580
2581 static const TypeConversionCostKindTblEntry AVX512FConversionTbl[] = {
2582 { ISD::FP_EXTEND, MVT::v8f64, MVT::v8f32, { 1, 1, 1, 1 } },
2583 { ISD::FP_EXTEND, MVT::v8f64, MVT::v16f32, { 3, 1, 1, 1 } },
2584 { ISD::FP_EXTEND, MVT::v16f64, MVT::v16f32, { 4, 1, 1, 1 } }, // 2*vcvtps2pd+vextractf64x4
2585 { ISD::FP_EXTEND, MVT::v16f32, MVT::v16f16, { 1, 1, 1, 1 } }, // vcvtph2ps
2586 { ISD::FP_EXTEND, MVT::v8f64, MVT::v8f16, { 2, 1, 1, 1 } }, // vcvtph2ps+vcvtps2pd
2587 { ISD::FP_ROUND, MVT::v8f32, MVT::v8f64, { 1, 1, 1, 1 } },
2588 { ISD::FP_ROUND, MVT::v16f16, MVT::v16f32, { 1, 1, 1, 1 } }, // vcvtps2ph
2589
2590 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i8, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
2591 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i8, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
2592 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i8, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
2593 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i8, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
2594 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i16, { 3, 1, 1, 1 } }, // sext+vpsllq+vptestmq
2595 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i16, { 3, 1, 1, 1 } }, // sext+vpsllq+vptestmq
2596 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i16, { 3, 1, 1, 1 } }, // sext+vpsllq+vptestmq
2597 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i16, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
2598 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i32, { 2, 1, 1, 1 } }, // zmm vpslld+vptestmd
2599 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i32, { 2, 1, 1, 1 } }, // zmm vpslld+vptestmd
2600 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i32, { 2, 1, 1, 1 } }, // zmm vpslld+vptestmd
2601 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i32, { 2, 1, 1, 1 } }, // vpslld+vptestmd
2602 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i64, { 2, 1, 1, 1 } }, // zmm vpsllq+vptestmq
2603 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i64, { 2, 1, 1, 1 } }, // zmm vpsllq+vptestmq
2604 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i64, { 2, 1, 1, 1 } }, // vpsllq+vptestmq
2605 { ISD::TRUNCATE, MVT::v2i8, MVT::v2i32, { 2, 1, 1, 1 } }, // vpmovdb
2606 { ISD::TRUNCATE, MVT::v4i8, MVT::v4i32, { 2, 1, 1, 1 } }, // vpmovdb
2607 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i32, { 2, 1, 1, 1 } }, // vpmovdb
2608 { ISD::TRUNCATE, MVT::v32i8, MVT::v16i32, { 2, 1, 1, 1 } }, // vpmovdb
2609 { ISD::TRUNCATE, MVT::v64i8, MVT::v16i32, { 2, 1, 1, 1 } }, // vpmovdb
2610 { ISD::TRUNCATE, MVT::v16i16, MVT::v16i32, { 2, 1, 1, 1 } }, // vpmovdw
2611 { ISD::TRUNCATE, MVT::v32i16, MVT::v16i32, { 2, 1, 1, 1 } }, // vpmovdw
2612 { ISD::TRUNCATE, MVT::v2i8, MVT::v2i64, { 2, 1, 1, 1 } }, // vpmovqb
2613 { ISD::TRUNCATE, MVT::v2i16, MVT::v2i64, { 1, 1, 1, 1 } }, // vpshufb
2614 { ISD::TRUNCATE, MVT::v8i8, MVT::v8i64, { 2, 1, 1, 1 } }, // vpmovqb
2615 { ISD::TRUNCATE, MVT::v16i8, MVT::v8i64, { 2, 1, 1, 1 } }, // vpmovqb
2616 { ISD::TRUNCATE, MVT::v32i8, MVT::v8i64, { 2, 1, 1, 1 } }, // vpmovqb
2617 { ISD::TRUNCATE, MVT::v64i8, MVT::v8i64, { 2, 1, 1, 1 } }, // vpmovqb
2618 { ISD::TRUNCATE, MVT::v8i16, MVT::v8i64, { 2, 1, 1, 1 } }, // vpmovqw
2619 { ISD::TRUNCATE, MVT::v16i16, MVT::v8i64, { 2, 1, 1, 1 } }, // vpmovqw
2620 { ISD::TRUNCATE, MVT::v32i16, MVT::v8i64, { 2, 1, 1, 1 } }, // vpmovqw
2621 { ISD::TRUNCATE, MVT::v8i32, MVT::v8i64, { 1, 1, 1, 1 } }, // vpmovqd
2622 { ISD::TRUNCATE, MVT::v4i32, MVT::v4i64, { 1, 1, 1, 1 } }, // zmm vpmovqd
2623 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i64, { 5, 1, 1, 1 } },// 2*vpmovqd+concat+vpmovdb
2624
2625 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i16, { 3, 1, 1, 1 } }, // extend to v16i32
2626 { ISD::TRUNCATE, MVT::v32i8, MVT::v32i16, { 8, 1, 1, 1 } },
2627 { ISD::TRUNCATE, MVT::v64i8, MVT::v32i16, { 8, 1, 1, 1 } },
2628
2629 // Sign extend is zmm vpternlogd+vptruncdb.
2630 // Zero extend is zmm broadcast load+vptruncdw.
2631 { ISD::SIGN_EXTEND, MVT::v2i8, MVT::v2i1, { 3, 1, 1, 1 } },
2632 { ISD::ZERO_EXTEND, MVT::v2i8, MVT::v2i1, { 4, 1, 1, 1 } },
2633 { ISD::SIGN_EXTEND, MVT::v4i8, MVT::v4i1, { 3, 1, 1, 1 } },
2634 { ISD::ZERO_EXTEND, MVT::v4i8, MVT::v4i1, { 4, 1, 1, 1 } },
2635 { ISD::SIGN_EXTEND, MVT::v8i8, MVT::v8i1, { 3, 1, 1, 1 } },
2636 { ISD::ZERO_EXTEND, MVT::v8i8, MVT::v8i1, { 4, 1, 1, 1 } },
2637 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v16i1, { 3, 1, 1, 1 } },
2638 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v16i1, { 4, 1, 1, 1 } },
2639
2640 // Sign extend is zmm vpternlogd+vptruncdw.
2641 // Zero extend is zmm vpternlogd+vptruncdw+vpsrlw.
2642 { ISD::SIGN_EXTEND, MVT::v2i16, MVT::v2i1, { 3, 1, 1, 1 } },
2643 { ISD::ZERO_EXTEND, MVT::v2i16, MVT::v2i1, { 4, 1, 1, 1 } },
2644 { ISD::SIGN_EXTEND, MVT::v4i16, MVT::v4i1, { 3, 1, 1, 1 } },
2645 { ISD::ZERO_EXTEND, MVT::v4i16, MVT::v4i1, { 4, 1, 1, 1 } },
2646 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v8i1, { 3, 1, 1, 1 } },
2647 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v8i1, { 4, 1, 1, 1 } },
2648 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i1, { 3, 1, 1, 1 } },
2649 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i1, { 4, 1, 1, 1 } },
2650
2651 { ISD::SIGN_EXTEND, MVT::v2i32, MVT::v2i1, { 1, 1, 1, 1 } }, // zmm vpternlogd
2652 { ISD::ZERO_EXTEND, MVT::v2i32, MVT::v2i1, { 2, 1, 1, 1 } }, // zmm vpternlogd+psrld
2653 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v4i1, { 1, 1, 1, 1 } }, // zmm vpternlogd
2654 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v4i1, { 2, 1, 1, 1 } }, // zmm vpternlogd+psrld
2655 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i1, { 1, 1, 1, 1 } }, // zmm vpternlogd
2656 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i1, { 2, 1, 1, 1 } }, // zmm vpternlogd+psrld
2657 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v2i1, { 1, 1, 1, 1 } }, // zmm vpternlogq
2658 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v2i1, { 2, 1, 1, 1 } }, // zmm vpternlogq+psrlq
2659 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i1, { 1, 1, 1, 1 } }, // zmm vpternlogq
2660 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i1, { 2, 1, 1, 1 } }, // zmm vpternlogq+psrlq
2661
2662 { ISD::SIGN_EXTEND, MVT::v16i32, MVT::v16i1, { 1, 1, 1, 1 } }, // vpternlogd
2663 { ISD::ZERO_EXTEND, MVT::v16i32, MVT::v16i1, { 2, 1, 1, 1 } }, // vpternlogd+psrld
2664 { ISD::SIGN_EXTEND, MVT::v8i64, MVT::v8i1, { 1, 1, 1, 1 } }, // vpternlogq
2665 { ISD::ZERO_EXTEND, MVT::v8i64, MVT::v8i1, { 2, 1, 1, 1 } }, // vpternlogq+psrlq
2666
2667 { ISD::SIGN_EXTEND, MVT::v16i32, MVT::v16i8, { 1, 1, 1, 1 } },
2668 { ISD::ZERO_EXTEND, MVT::v16i32, MVT::v16i8, { 1, 1, 1, 1 } },
2669 { ISD::SIGN_EXTEND, MVT::v16i32, MVT::v16i16, { 1, 1, 1, 1 } },
2670 { ISD::ZERO_EXTEND, MVT::v16i32, MVT::v16i16, { 1, 1, 1, 1 } },
2671 { ISD::SIGN_EXTEND, MVT::v8i64, MVT::v8i8, { 1, 1, 1, 1 } },
2672 { ISD::ZERO_EXTEND, MVT::v8i64, MVT::v8i8, { 1, 1, 1, 1 } },
2673 { ISD::SIGN_EXTEND, MVT::v8i64, MVT::v8i16, { 1, 1, 1, 1 } },
2674 { ISD::ZERO_EXTEND, MVT::v8i64, MVT::v8i16, { 1, 1, 1, 1 } },
2675 { ISD::SIGN_EXTEND, MVT::v8i64, MVT::v8i32, { 1, 1, 1, 1 } },
2676 { ISD::ZERO_EXTEND, MVT::v8i64, MVT::v8i32, { 1, 1, 1, 1 } },
2677
2678 { ISD::SIGN_EXTEND, MVT::v32i16, MVT::v32i8, { 3, 1, 1, 1 } }, // FIXME: May not be right
2679 { ISD::ZERO_EXTEND, MVT::v32i16, MVT::v32i8, { 3, 1, 1, 1 } }, // FIXME: May not be right
2680
2681 { ISD::SINT_TO_FP, MVT::v8f64, MVT::v8i1, { 4, 1, 1, 1 } },
2682 { ISD::SINT_TO_FP, MVT::v16f32, MVT::v16i1, { 3, 1, 1, 1 } },
2683 { ISD::SINT_TO_FP, MVT::v8f64, MVT::v16i8, { 2, 1, 1, 1 } },
2684 { ISD::SINT_TO_FP, MVT::v16f32, MVT::v16i8, { 1, 1, 1, 1 } },
2685 { ISD::SINT_TO_FP, MVT::v8f64, MVT::v8i16, { 2, 1, 1, 1 } },
2686 { ISD::SINT_TO_FP, MVT::v16f32, MVT::v16i16, { 1, 1, 1, 1 } },
2687 { ISD::SINT_TO_FP, MVT::v8f64, MVT::v8i32, { 1, 1, 1, 1 } },
2688 { ISD::SINT_TO_FP, MVT::v16f32, MVT::v16i32, { 1, 1, 1, 1 } },
2689
2690 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i1, { 4, 1, 1, 1 } },
2691 { ISD::UINT_TO_FP, MVT::v16f32, MVT::v16i1, { 3, 1, 1, 1 } },
2692 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v16i8, { 2, 1, 1, 1 } },
2693 { ISD::UINT_TO_FP, MVT::v16f32, MVT::v16i8, { 1, 1, 1, 1 } },
2694 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i16, { 2, 1, 1, 1 } },
2695 { ISD::UINT_TO_FP, MVT::v16f32, MVT::v16i16, { 1, 1, 1, 1 } },
2696 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i32, { 1, 1, 1, 1 } },
2697 { ISD::UINT_TO_FP, MVT::v16f32, MVT::v16i32, { 1, 1, 1, 1 } },
2698 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i64, {26, 1, 1, 1 } },
2699 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i64, { 5, 1, 1, 1 } },
2700
2701 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v16f32, { 2, 1, 1, 1 } },
2702 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v16f64, { 7, 1, 1, 1 } },
2703 { ISD::FP_TO_SINT, MVT::v32i8, MVT::v32f64, {15, 1, 1, 1 } },
2704 { ISD::FP_TO_SINT, MVT::v64i8, MVT::v64f32, {11, 1, 1, 1 } },
2705 { ISD::FP_TO_SINT, MVT::v64i8, MVT::v64f64, {31, 1, 1, 1 } },
2706 { ISD::FP_TO_SINT, MVT::v8i16, MVT::v8f64, { 3, 1, 1, 1 } },
2707 { ISD::FP_TO_SINT, MVT::v16i16, MVT::v16f64, { 7, 1, 1, 1 } },
2708 { ISD::FP_TO_SINT, MVT::v32i16, MVT::v32f32, { 5, 1, 1, 1 } },
2709 { ISD::FP_TO_SINT, MVT::v32i16, MVT::v32f64, {15, 1, 1, 1 } },
2710 { ISD::FP_TO_SINT, MVT::v8i32, MVT::v8f64, { 1, 1, 1, 1 } },
2711 { ISD::FP_TO_SINT, MVT::v16i32, MVT::v16f64, { 3, 1, 1, 1 } },
2712
2713 { ISD::FP_TO_UINT, MVT::v8i32, MVT::v8f64, { 1, 1, 1, 1 } },
2714 { ISD::FP_TO_UINT, MVT::v8i16, MVT::v8f64, { 3, 1, 1, 1 } },
2715 { ISD::FP_TO_UINT, MVT::v8i8, MVT::v8f64, { 3, 1, 1, 1 } },
2716 { ISD::FP_TO_UINT, MVT::v16i32, MVT::v16f32, { 1, 1, 1, 1 } },
2717 { ISD::FP_TO_UINT, MVT::v16i16, MVT::v16f32, { 3, 1, 1, 1 } },
2718 { ISD::FP_TO_UINT, MVT::v16i8, MVT::v16f32, { 3, 1, 1, 1 } },
2719 };
2720
2721 static const TypeConversionCostKindTblEntry AVX512BWVLConversionTbl[] {
2722 // Mask sign extend has an instruction.
2723 { ISD::SIGN_EXTEND, MVT::v2i8, MVT::v2i1, { 1, 1, 1, 1 } },
2724 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v2i1, { 1, 1, 1, 1 } },
2725 { ISD::SIGN_EXTEND, MVT::v2i16, MVT::v2i1, { 1, 1, 1, 1 } },
2726 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v2i1, { 1, 1, 1, 1 } },
2727 { ISD::SIGN_EXTEND, MVT::v4i16, MVT::v4i1, { 1, 1, 1, 1 } },
2728 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v4i1, { 1, 1, 1, 1 } },
2729 { ISD::SIGN_EXTEND, MVT::v4i8, MVT::v4i1, { 1, 1, 1, 1 } },
2730 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v4i1, { 1, 1, 1, 1 } },
2731 { ISD::SIGN_EXTEND, MVT::v8i8, MVT::v8i1, { 1, 1, 1, 1 } },
2732 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v8i1, { 1, 1, 1, 1 } },
2733 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v8i1, { 1, 1, 1, 1 } },
2734 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v16i1, { 1, 1, 1, 1 } },
2735 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i1, { 1, 1, 1, 1 } },
2736 { ISD::SIGN_EXTEND, MVT::v32i8, MVT::v32i1, { 1, 1, 1, 1 } },
2737 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v32i1, { 1, 1, 1, 1 } },
2738 { ISD::SIGN_EXTEND, MVT::v32i8, MVT::v64i1, { 1, 1, 1, 1 } },
2739 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v64i1, { 1, 1, 1, 1 } },
2740
2741 // Mask zero extend is a sext + shift.
2742 { ISD::ZERO_EXTEND, MVT::v2i8, MVT::v2i1, { 2, 1, 1, 1 } },
2743 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v2i1, { 2, 1, 1, 1 } },
2744 { ISD::ZERO_EXTEND, MVT::v2i16, MVT::v2i1, { 2, 1, 1, 1 } },
2745 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v2i1, { 2, 1, 1, 1 } },
2746 { ISD::ZERO_EXTEND, MVT::v4i8, MVT::v4i1, { 2, 1, 1, 1 } },
2747 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v4i1, { 2, 1, 1, 1 } },
2748 { ISD::ZERO_EXTEND, MVT::v4i16, MVT::v4i1, { 2, 1, 1, 1 } },
2749 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v4i1, { 2, 1, 1, 1 } },
2750 { ISD::ZERO_EXTEND, MVT::v8i8, MVT::v8i1, { 2, 1, 1, 1 } },
2751 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v8i1, { 2, 1, 1, 1 } },
2752 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v8i1, { 2, 1, 1, 1 } },
2753 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v16i1, { 2, 1, 1, 1 } },
2754 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i1, { 2, 1, 1, 1 } },
2755 { ISD::ZERO_EXTEND, MVT::v32i8, MVT::v32i1, { 2, 1, 1, 1 } },
2756 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v32i1, { 2, 1, 1, 1 } },
2757 { ISD::ZERO_EXTEND, MVT::v32i8, MVT::v64i1, { 2, 1, 1, 1 } },
2758 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v64i1, { 2, 1, 1, 1 } },
2759
2760 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i8, { 2, 1, 1, 1 } },
2761 { ISD::TRUNCATE, MVT::v2i1, MVT::v16i8, { 2, 1, 1, 1 } },
2762 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i16, { 2, 1, 1, 1 } },
2763 { ISD::TRUNCATE, MVT::v2i1, MVT::v8i16, { 2, 1, 1, 1 } },
2764 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i8, { 2, 1, 1, 1 } },
2765 { ISD::TRUNCATE, MVT::v4i1, MVT::v16i8, { 2, 1, 1, 1 } },
2766 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i16, { 2, 1, 1, 1 } },
2767 { ISD::TRUNCATE, MVT::v4i1, MVT::v8i16, { 2, 1, 1, 1 } },
2768 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i8, { 2, 1, 1, 1 } },
2769 { ISD::TRUNCATE, MVT::v8i1, MVT::v16i8, { 2, 1, 1, 1 } },
2770 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i16, { 2, 1, 1, 1 } },
2771 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i8, { 2, 1, 1, 1 } },
2772 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i16, { 2, 1, 1, 1 } },
2773 { ISD::TRUNCATE, MVT::v32i1, MVT::v32i8, { 2, 1, 1, 1 } },
2774 { ISD::TRUNCATE, MVT::v32i1, MVT::v16i16, { 2, 1, 1, 1 } },
2775 { ISD::TRUNCATE, MVT::v64i1, MVT::v32i8, { 2, 1, 1, 1 } },
2776 { ISD::TRUNCATE, MVT::v64i1, MVT::v16i16, { 2, 1, 1, 1 } },
2777
2778 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i16, { 2, 1, 1, 1 } },
2779 };
2780
2781 static const TypeConversionCostKindTblEntry AVX512DQVLConversionTbl[] = {
2782 // Mask sign extend has an instruction.
2783 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v2i1, { 1, 1, 1, 1 } },
2784 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v2i1, { 1, 1, 1, 1 } },
2785 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v4i1, { 1, 1, 1, 1 } },
2786 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v16i1, { 1, 1, 1, 1 } },
2787 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i1, { 1, 1, 1, 1 } },
2788 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v8i1, { 1, 1, 1, 1 } },
2789 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v16i1, { 1, 1, 1, 1 } },
2790 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i1, { 1, 1, 1, 1 } },
2791
2792 // Mask zero extend is a sext + shift.
2793 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v2i1, { 2, 1, 1, 1 } },
2794 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v2i1, { 2, 1, 1, 1 } },
2795 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v4i1, { 2, 1, 1, 1 } },
2796 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v16i1, { 2, 1, 1, 1 } },
2797 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i1, { 2, 1, 1, 1 } },
2798 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v8i1, { 2, 1, 1, 1 } },
2799 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v16i1, { 2, 1, 1, 1 } },
2800 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i1, { 2, 1, 1, 1 } },
2801
2802 { ISD::TRUNCATE, MVT::v16i1, MVT::v4i64, { 2, 1, 1, 1 } },
2803 { ISD::TRUNCATE, MVT::v16i1, MVT::v8i32, { 2, 1, 1, 1 } },
2804 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i64, { 2, 1, 1, 1 } },
2805 { ISD::TRUNCATE, MVT::v2i1, MVT::v4i32, { 2, 1, 1, 1 } },
2806 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i32, { 2, 1, 1, 1 } },
2807 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i64, { 2, 1, 1, 1 } },
2808 { ISD::TRUNCATE, MVT::v8i1, MVT::v4i64, { 2, 1, 1, 1 } },
2809 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i32, { 2, 1, 1, 1 } },
2810
2811 { ISD::SINT_TO_FP, MVT::v2f32, MVT::v2i64, { 1, 1, 1, 1 } },
2812 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v2i64, { 1, 1, 1, 1 } },
2813 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v4i64, { 1, 1, 1, 1 } },
2814 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v4i64, { 1, 1, 1, 1 } },
2815
2816 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i64, { 1, 1, 1, 1 } },
2817 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i64, { 1, 1, 1, 1 } },
2818 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i64, { 1, 1, 1, 1 } },
2819 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i64, { 1, 1, 1, 1 } },
2820
2821 { ISD::FP_TO_SINT, MVT::v2i64, MVT::v4f32, { 1, 1, 1, 1 } },
2822 { ISD::FP_TO_SINT, MVT::v4i64, MVT::v4f32, { 1, 1, 1, 1 } },
2823 { ISD::FP_TO_SINT, MVT::v2i64, MVT::v2f64, { 1, 1, 1, 1 } },
2824 { ISD::FP_TO_SINT, MVT::v4i64, MVT::v4f64, { 1, 1, 1, 1 } },
2825
2826 { ISD::FP_TO_UINT, MVT::v2i64, MVT::v4f32, { 1, 1, 1, 1 } },
2827 { ISD::FP_TO_UINT, MVT::v4i64, MVT::v4f32, { 1, 1, 1, 1 } },
2828 { ISD::FP_TO_UINT, MVT::v2i64, MVT::v2f64, { 1, 1, 1, 1 } },
2829 { ISD::FP_TO_UINT, MVT::v4i64, MVT::v4f64, { 1, 1, 1, 1 } },
2830 };
2831
2832 static const TypeConversionCostKindTblEntry AVX512VLConversionTbl[] = {
2833 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i8, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
2834 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i8, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
2835 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i8, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
2836 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i8, { 8, 1, 1, 1 } }, // split+2*v8i8
2837 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i16, { 3, 1, 1, 1 } }, // sext+vpsllq+vptestmq
2838 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i16, { 3, 1, 1, 1 } }, // sext+vpsllq+vptestmq
2839 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i16, { 3, 1, 1, 1 } }, // sext+vpsllq+vptestmq
2840 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i16, { 8, 1, 1, 1 } }, // split+2*v8i16
2841 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i32, { 2, 1, 1, 1 } }, // vpslld+vptestmd
2842 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i32, { 2, 1, 1, 1 } }, // vpslld+vptestmd
2843 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i32, { 2, 1, 1, 1 } }, // vpslld+vptestmd
2844 { ISD::TRUNCATE, MVT::v16i1, MVT::v8i32, { 2, 1, 1, 1 } }, // vpslld+vptestmd
2845 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i64, { 2, 1, 1, 1 } }, // vpsllq+vptestmq
2846 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i64, { 2, 1, 1, 1 } }, // vpsllq+vptestmq
2847 { ISD::TRUNCATE, MVT::v4i32, MVT::v4i64, { 1, 1, 1, 1 } }, // vpmovqd
2848 { ISD::TRUNCATE, MVT::v4i8, MVT::v4i64, { 2, 1, 1, 1 } }, // vpmovqb
2849 { ISD::TRUNCATE, MVT::v4i16, MVT::v4i64, { 2, 1, 1, 1 } }, // vpmovqw
2850 { ISD::TRUNCATE, MVT::v8i8, MVT::v8i32, { 2, 1, 1, 1 } }, // vpmovwb
2851
2852 // sign extend is vpcmpeq+maskedmove+vpmovdw+vpacksswb
2853 // zero extend is vpcmpeq+maskedmove+vpmovdw+vpsrlw+vpackuswb
2854 { ISD::SIGN_EXTEND, MVT::v2i8, MVT::v2i1, { 5, 1, 1, 1 } },
2855 { ISD::ZERO_EXTEND, MVT::v2i8, MVT::v2i1, { 6, 1, 1, 1 } },
2856 { ISD::SIGN_EXTEND, MVT::v4i8, MVT::v4i1, { 5, 1, 1, 1 } },
2857 { ISD::ZERO_EXTEND, MVT::v4i8, MVT::v4i1, { 6, 1, 1, 1 } },
2858 { ISD::SIGN_EXTEND, MVT::v8i8, MVT::v8i1, { 5, 1, 1, 1 } },
2859 { ISD::ZERO_EXTEND, MVT::v8i8, MVT::v8i1, { 6, 1, 1, 1 } },
2860 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v16i1, {10, 1, 1, 1 } },
2861 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v16i1, {12, 1, 1, 1 } },
2862
2863 // sign extend is vpcmpeq+maskedmove+vpmovdw
2864 // zero extend is vpcmpeq+maskedmove+vpmovdw+vpsrlw
2865 { ISD::SIGN_EXTEND, MVT::v2i16, MVT::v2i1, { 4, 1, 1, 1 } },
2866 { ISD::ZERO_EXTEND, MVT::v2i16, MVT::v2i1, { 5, 1, 1, 1 } },
2867 { ISD::SIGN_EXTEND, MVT::v4i16, MVT::v4i1, { 4, 1, 1, 1 } },
2868 { ISD::ZERO_EXTEND, MVT::v4i16, MVT::v4i1, { 5, 1, 1, 1 } },
2869 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v8i1, { 4, 1, 1, 1 } },
2870 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v8i1, { 5, 1, 1, 1 } },
2871 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i1, {10, 1, 1, 1 } },
2872 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i1, {12, 1, 1, 1 } },
2873
2874 { ISD::SIGN_EXTEND, MVT::v2i32, MVT::v2i1, { 1, 1, 1, 1 } }, // vpternlogd
2875 { ISD::ZERO_EXTEND, MVT::v2i32, MVT::v2i1, { 2, 1, 1, 1 } }, // vpternlogd+psrld
2876 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v4i1, { 1, 1, 1, 1 } }, // vpternlogd
2877 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v4i1, { 2, 1, 1, 1 } }, // vpternlogd+psrld
2878 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i1, { 1, 1, 1, 1 } }, // vpternlogd
2879 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i1, { 2, 1, 1, 1 } }, // vpternlogd+psrld
2880 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v16i1, { 1, 1, 1, 1 } }, // vpternlogd
2881 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v16i1, { 2, 1, 1, 1 } }, // vpternlogd+psrld
2882
2883 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v2i1, { 1, 1, 1, 1 } }, // vpternlogq
2884 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v2i1, { 2, 1, 1, 1 } }, // vpternlogq+psrlq
2885 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i1, { 1, 1, 1, 1 } }, // vpternlogq
2886 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i1, { 2, 1, 1, 1 } }, // vpternlogq+psrlq
2887
2888 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v16i8, { 1, 1, 1, 1 } },
2889 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v16i8, { 1, 1, 1, 1 } },
2890 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v16i8, { 1, 1, 1, 1 } },
2891 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v16i8, { 1, 1, 1, 1 } },
2892 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i8, { 1, 1, 1, 1 } },
2893 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i8, { 1, 1, 1, 1 } },
2894 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v8i16, { 1, 1, 1, 1 } },
2895 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v8i16, { 1, 1, 1, 1 } },
2896 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i16, { 1, 1, 1, 1 } },
2897 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i16, { 1, 1, 1, 1 } },
2898 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i32, { 1, 1, 1, 1 } },
2899 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i32, { 1, 1, 1, 1 } },
2900
2901 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v16i8, { 1, 1, 1, 1 } },
2902 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v16i8, { 1, 1, 1, 1 } },
2903 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v8i16, { 1, 1, 1, 1 } },
2904 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v8i16, { 1, 1, 1, 1 } },
2905
2906 { ISD::UINT_TO_FP, MVT::f32, MVT::i64, { 1, 1, 1, 1 } },
2907 { ISD::UINT_TO_FP, MVT::f64, MVT::i64, { 1, 1, 1, 1 } },
2908 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v16i8, { 1, 1, 1, 1 } },
2909 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v16i8, { 1, 1, 1, 1 } },
2910 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v8i16, { 1, 1, 1, 1 } },
2911 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i16, { 1, 1, 1, 1 } },
2912 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i32, { 1, 1, 1, 1 } },
2913 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i32, { 1, 1, 1, 1 } },
2914 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i32, { 1, 1, 1, 1 } },
2915 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i32, { 1, 1, 1, 1 } },
2916 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i64, { 5, 1, 1, 1 } },
2917 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i64, { 5, 1, 1, 1 } },
2918 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i64, { 5, 1, 1, 1 } },
2919
2920 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v8f32, { 2, 1, 1, 1 } },
2921 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v16f32, { 2, 1, 1, 1 } },
2922 { ISD::FP_TO_SINT, MVT::v32i8, MVT::v32f32, { 5, 1, 1, 1 } },
2923
2924 { ISD::FP_TO_UINT, MVT::i64, MVT::f32, { 1, 1, 1, 1 } },
2925 { ISD::FP_TO_UINT, MVT::i64, MVT::f64, { 1, 1, 1, 1 } },
2926 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f32, { 1, 1, 1, 1 } },
2927 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v2f64, { 1, 1, 1, 1 } },
2928 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f64, { 1, 1, 1, 1 } },
2929 { ISD::FP_TO_UINT, MVT::v8i32, MVT::v8f32, { 1, 1, 1, 1 } },
2930 { ISD::FP_TO_UINT, MVT::v8i32, MVT::v8f64, { 1, 1, 1, 1 } },
2931 };
2932
2933 static const TypeConversionCostKindTblEntry AVX2ConversionTbl[] = {
2934 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i1, { 3, 1, 1, 1 } },
2935 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i1, { 3, 1, 1, 1 } },
2936 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i1, { 3, 1, 1, 1 } },
2937 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i1, { 3, 1, 1, 1 } },
2938 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i1, { 1, 1, 1, 1 } },
2939 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i1, { 1, 1, 1, 1 } },
2940
2941 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v16i8, { 2, 1, 1, 1 } },
2942 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v16i8, { 2, 1, 1, 1 } },
2943 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v16i8, { 2, 1, 1, 1 } },
2944 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v16i8, { 2, 1, 1, 1 } },
2945 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i8, { 2, 1, 1, 1 } },
2946 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i8, { 2, 1, 1, 1 } },
2947 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v8i16, { 2, 1, 1, 1 } },
2948 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v8i16, { 2, 1, 1, 1 } },
2949 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i16, { 2, 1, 1, 1 } },
2950 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i16, { 2, 1, 1, 1 } },
2951 { ISD::ZERO_EXTEND, MVT::v16i32, MVT::v16i16, { 3, 1, 1, 1 } },
2952 { ISD::SIGN_EXTEND, MVT::v16i32, MVT::v16i16, { 3, 1, 1, 1 } },
2953 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i32, { 2, 1, 1, 1 } },
2954 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i32, { 2, 1, 1, 1 } },
2955
2956 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i32, { 2, 1, 1, 1 } },
2957
2958 { ISD::TRUNCATE, MVT::v16i16, MVT::v16i32, { 4, 1, 1, 1 } },
2959 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i32, { 4, 1, 1, 1 } },
2960 { ISD::TRUNCATE, MVT::v16i8, MVT::v8i16, { 1, 1, 1, 1 } },
2961 { ISD::TRUNCATE, MVT::v16i8, MVT::v4i32, { 1, 1, 1, 1 } },
2962 { ISD::TRUNCATE, MVT::v16i8, MVT::v2i64, { 1, 1, 1, 1 } },
2963 { ISD::TRUNCATE, MVT::v16i8, MVT::v8i32, { 4, 1, 1, 1 } },
2964 { ISD::TRUNCATE, MVT::v16i8, MVT::v4i64, { 4, 1, 1, 1 } },
2965 { ISD::TRUNCATE, MVT::v8i16, MVT::v4i32, { 1, 1, 1, 1 } },
2966 { ISD::TRUNCATE, MVT::v8i16, MVT::v2i64, { 1, 1, 1, 1 } },
2967 { ISD::TRUNCATE, MVT::v8i16, MVT::v4i64, { 5, 1, 1, 1 } },
2968 { ISD::TRUNCATE, MVT::v4i32, MVT::v4i64, { 1, 1, 1, 1 } },
2969 { ISD::TRUNCATE, MVT::v8i16, MVT::v8i32, { 2, 1, 1, 1 } },
2970
2971 { ISD::FP_EXTEND, MVT::v8f64, MVT::v8f32, { 3, 1, 1, 1 } },
2972 { ISD::FP_ROUND, MVT::v8f32, MVT::v8f64, { 3, 1, 1, 1 } },
2973
2974 { ISD::FP_TO_SINT, MVT::v16i16, MVT::v8f32, { 1, 1, 1, 1 } },
2975 { ISD::FP_TO_SINT, MVT::v4i32, MVT::v4f64, { 1, 1, 1, 1 } },
2976 { ISD::FP_TO_SINT, MVT::v8i32, MVT::v8f32, { 1, 1, 1, 1 } },
2977 { ISD::FP_TO_SINT, MVT::v8i32, MVT::v8f64, { 3, 1, 1, 1 } },
2978
2979 { ISD::FP_TO_UINT, MVT::i64, MVT::f32, { 3, 1, 1, 1 } },
2980 { ISD::FP_TO_UINT, MVT::i64, MVT::f64, { 3, 1, 1, 1 } },
2981 { ISD::FP_TO_UINT, MVT::v16i16, MVT::v8f32, { 1, 1, 1, 1 } },
2982 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f32, { 3, 1, 1, 1 } },
2983 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v2f64, { 4, 1, 1, 1 } },
2984 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f64, { 4, 1, 1, 1 } },
2985 { ISD::FP_TO_UINT, MVT::v8i32, MVT::v8f32, { 3, 1, 1, 1 } },
2986 { ISD::FP_TO_UINT, MVT::v8i32, MVT::v4f64, { 4, 1, 1, 1 } },
2987
2988 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v16i8, { 2, 1, 1, 1 } },
2989 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v16i8, { 2, 1, 1, 1 } },
2990 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v8i16, { 2, 1, 1, 1 } },
2991 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v8i16, { 2, 1, 1, 1 } },
2992 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v4i32, { 1, 1, 1, 1 } },
2993 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v8i32, { 1, 1, 1, 1 } },
2994 { ISD::SINT_TO_FP, MVT::v8f64, MVT::v8i32, { 3, 1, 1, 1 } },
2995
2996 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v16i8, { 2, 1, 1, 1 } },
2997 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v16i8, { 2, 1, 1, 1 } },
2998 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v8i16, { 2, 1, 1, 1 } },
2999 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i16, { 2, 1, 1, 1 } },
3000 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i32, { 2, 1, 1, 1 } },
3001 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i32, { 1, 1, 1, 1 } },
3002 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i32, { 2, 1, 1, 1 } },
3003 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i32, { 2, 1, 1, 1 } },
3004 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i32, { 2, 1, 1, 1 } },
3005 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i32, { 4, 1, 1, 1 } },
3006 };
3007
3008 static const TypeConversionCostKindTblEntry AVXConversionTbl[] = {
3009 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i1, { 4, 1, 1, 1 } },
3010 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i1, { 4, 1, 1, 1 } },
3011 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i1, { 4, 1, 1, 1 } },
3012 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i1, { 4, 1, 1, 1 } },
3013 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i1, { 4, 1, 1, 1 } },
3014 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i1, { 4, 1, 1, 1 } },
3015
3016 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v16i8, { 3, 1, 1, 1 } },
3017 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v16i8, { 3, 1, 1, 1 } },
3018 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v16i8, { 3, 1, 1, 1 } },
3019 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v16i8, { 3, 1, 1, 1 } },
3020 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i8, { 3, 1, 1, 1 } },
3021 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i8, { 3, 1, 1, 1 } },
3022 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v8i16, { 3, 1, 1, 1 } },
3023 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v8i16, { 3, 1, 1, 1 } },
3024 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i16, { 3, 1, 1, 1 } },
3025 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i16, { 3, 1, 1, 1 } },
3026 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i32, { 3, 1, 1, 1 } },
3027 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i32, { 3, 1, 1, 1 } },
3028
3029 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i64, { 4, 1, 1, 1 } },
3030 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i32, { 5, 1, 1, 1 } },
3031 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i16, { 4, 1, 1, 1 } },
3032 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i64, { 9, 1, 1, 1 } },
3033 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i64, {11, 1, 1, 1 } },
3034
3035 { ISD::TRUNCATE, MVT::v16i16, MVT::v16i32, { 6, 1, 1, 1 } },
3036 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i32, { 6, 1, 1, 1 } },
3037 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i16, { 2, 1, 1, 1 } }, // and+extract+packuswb
3038 { ISD::TRUNCATE, MVT::v16i8, MVT::v8i32, { 5, 1, 1, 1 } },
3039 { ISD::TRUNCATE, MVT::v8i16, MVT::v8i32, { 5, 1, 1, 1 } },
3040 { ISD::TRUNCATE, MVT::v16i8, MVT::v4i64, { 5, 1, 1, 1 } },
3041 { ISD::TRUNCATE, MVT::v8i16, MVT::v4i64, { 3, 1, 1, 1 } }, // and+extract+2*packusdw
3042 { ISD::TRUNCATE, MVT::v4i32, MVT::v4i64, { 2, 1, 1, 1 } },
3043
3044 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v4i1, { 3, 1, 1, 1 } },
3045 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v4i1, { 3, 1, 1, 1 } },
3046 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v8i1, { 8, 1, 1, 1 } },
3047 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v16i8, { 4, 1, 1, 1 } },
3048 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v16i8, { 2, 1, 1, 1 } },
3049 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v8i16, { 4, 1, 1, 1 } },
3050 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v8i16, { 2, 1, 1, 1 } },
3051 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v4i32, { 2, 1, 1, 1 } },
3052 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v8i32, { 2, 1, 1, 1 } },
3053 { ISD::SINT_TO_FP, MVT::v8f64, MVT::v8i32, { 4, 1, 1, 1 } },
3054 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v2i64, { 5, 1, 1, 1 } },
3055 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v4i64, { 8, 1, 1, 1 } },
3056
3057 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i1, { 7, 1, 1, 1 } },
3058 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i1, { 7, 1, 1, 1 } },
3059 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i1, { 6, 1, 1, 1 } },
3060 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v16i8, { 4, 1, 1, 1 } },
3061 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v16i8, { 2, 1, 1, 1 } },
3062 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i16, { 4, 1, 1, 1 } },
3063 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v8i16, { 2, 1, 1, 1 } },
3064 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i32, { 4, 1, 1, 1 } },
3065 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i32, { 4, 1, 1, 1 } },
3066 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i32, { 5, 1, 1, 1 } },
3067 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i32, { 6, 1, 1, 1 } },
3068 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i32, { 8, 1, 1, 1 } },
3069 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i32, {10, 1, 1, 1 } },
3070 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i64, {10, 1, 1, 1 } },
3071 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i64, {18, 1, 1, 1 } },
3072 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i64, { 5, 1, 1, 1 } },
3073 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i64, {10, 1, 1, 1 } },
3074
3075 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v8f32, { 2, 1, 1, 1 } },
3076 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v4f64, { 2, 1, 1, 1 } },
3077 { ISD::FP_TO_SINT, MVT::v32i8, MVT::v8f32, { 2, 1, 1, 1 } },
3078 { ISD::FP_TO_SINT, MVT::v32i8, MVT::v4f64, { 2, 1, 1, 1 } },
3079 { ISD::FP_TO_SINT, MVT::v8i16, MVT::v8f32, { 2, 1, 1, 1 } },
3080 { ISD::FP_TO_SINT, MVT::v8i16, MVT::v4f64, { 2, 1, 1, 1 } },
3081 { ISD::FP_TO_SINT, MVT::v16i16, MVT::v8f32, { 2, 1, 1, 1 } },
3082 { ISD::FP_TO_SINT, MVT::v16i16, MVT::v4f64, { 2, 1, 1, 1 } },
3083 { ISD::FP_TO_SINT, MVT::v4i32, MVT::v4f64, { 2, 1, 1, 1 } },
3084 { ISD::FP_TO_SINT, MVT::v8i32, MVT::v8f32, { 2, 1, 1, 1 } },
3085 { ISD::FP_TO_SINT, MVT::v8i32, MVT::v8f64, { 5, 1, 1, 1 } },
3086
3087 { ISD::FP_TO_UINT, MVT::v16i8, MVT::v8f32, { 2, 1, 1, 1 } },
3088 { ISD::FP_TO_UINT, MVT::v16i8, MVT::v4f64, { 2, 1, 1, 1 } },
3089 { ISD::FP_TO_UINT, MVT::v32i8, MVT::v8f32, { 2, 1, 1, 1 } },
3090 { ISD::FP_TO_UINT, MVT::v32i8, MVT::v4f64, { 2, 1, 1, 1 } },
3091 { ISD::FP_TO_UINT, MVT::v8i16, MVT::v8f32, { 2, 1, 1, 1 } },
3092 { ISD::FP_TO_UINT, MVT::v8i16, MVT::v4f64, { 2, 1, 1, 1 } },
3093 { ISD::FP_TO_UINT, MVT::v16i16, MVT::v8f32, { 2, 1, 1, 1 } },
3094 { ISD::FP_TO_UINT, MVT::v16i16, MVT::v4f64, { 2, 1, 1, 1 } },
3095 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f32, { 3, 1, 1, 1 } },
3096 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v2f64, { 4, 1, 1, 1 } },
3097 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f64, { 6, 1, 1, 1 } },
3098 { ISD::FP_TO_UINT, MVT::v8i32, MVT::v8f32, { 7, 1, 1, 1 } },
3099 { ISD::FP_TO_UINT, MVT::v8i32, MVT::v4f64, { 7, 1, 1, 1 } },
3100
3101 { ISD::FP_EXTEND, MVT::v4f64, MVT::v4f32, { 1, 1, 1, 1 } },
3102 { ISD::FP_ROUND, MVT::v4f32, MVT::v4f64, { 1, 1, 1, 1 } },
3103 };
3104
3105 static const TypeConversionCostKindTblEntry SSE41ConversionTbl[] = {
3106 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v16i8, { 1, 1, 1, 1 } },
3107 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v16i8, { 1, 1, 1, 1 } },
3108 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v16i8, { 1, 1, 1, 1 } },
3109 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v16i8, { 1, 1, 1, 1 } },
3110 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v16i8, { 1, 1, 1, 1 } },
3111 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v16i8, { 1, 1, 1, 1 } },
3112 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v8i16, { 1, 1, 1, 1 } },
3113 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v8i16, { 1, 1, 1, 1 } },
3114 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v8i16, { 1, 1, 1, 1 } },
3115 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v8i16, { 1, 1, 1, 1 } },
3116 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v4i32, { 1, 1, 1, 1 } },
3117 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v4i32, { 1, 1, 1, 1 } },
3118
3119 // These truncates end up widening elements.
3120 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i8, { 1, 1, 1, 1 } }, // PMOVXZBQ
3121 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i16, { 1, 1, 1, 1 } }, // PMOVXZWQ
3122 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i8, { 1, 1, 1, 1 } }, // PMOVXZBD
3123
3124 { ISD::TRUNCATE, MVT::v16i8, MVT::v4i32, { 2, 1, 1, 1 } },
3125 { ISD::TRUNCATE, MVT::v8i16, MVT::v4i32, { 2, 1, 1, 1 } },
3126 { ISD::TRUNCATE, MVT::v16i8, MVT::v2i64, { 2, 1, 1, 1 } },
3127
3128 { ISD::SINT_TO_FP, MVT::f32, MVT::i32, { 1, 1, 1, 1 } },
3129 { ISD::SINT_TO_FP, MVT::f64, MVT::i32, { 1, 1, 1, 1 } },
3130 { ISD::SINT_TO_FP, MVT::f32, MVT::i64, { 1, 1, 1, 1 } },
3131 { ISD::SINT_TO_FP, MVT::f64, MVT::i64, { 1, 1, 1, 1 } },
3132 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v16i8, { 1, 1, 1, 1 } },
3133 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v16i8, { 1, 1, 1, 1 } },
3134 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v8i16, { 1, 1, 1, 1 } },
3135 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v8i16, { 1, 1, 1, 1 } },
3136 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v4i32, { 1, 1, 1, 1 } },
3137 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v4i32, { 1, 1, 1, 1 } },
3138 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v4i32, { 2, 1, 1, 1 } },
3139
3140 { ISD::UINT_TO_FP, MVT::f32, MVT::i32, { 1, 1, 1, 1 } },
3141 { ISD::UINT_TO_FP, MVT::f64, MVT::i32, { 1, 1, 1, 1 } },
3142 { ISD::UINT_TO_FP, MVT::f32, MVT::i64, { 4, 1, 1, 1 } },
3143 { ISD::UINT_TO_FP, MVT::f64, MVT::i64, { 4, 1, 1, 1 } },
3144 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v16i8, { 1, 1, 1, 1 } },
3145 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v16i8, { 1, 1, 1, 1 } },
3146 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v8i16, { 1, 1, 1, 1 } },
3147 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v8i16, { 1, 1, 1, 1 } },
3148 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i32, { 3, 1, 1, 1 } },
3149 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i32, { 3, 1, 1, 1 } },
3150 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v4i32, { 2, 1, 1, 1 } },
3151 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v2i64, {12, 1, 1, 1 } },
3152 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i64, {22, 1, 1, 1 } },
3153 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i64, { 4, 1, 1, 1 } },
3154
3155 { ISD::FP_TO_SINT, MVT::i32, MVT::f32, { 1, 1, 1, 1 } },
3156 { ISD::FP_TO_SINT, MVT::i64, MVT::f32, { 1, 1, 1, 1 } },
3157 { ISD::FP_TO_SINT, MVT::i32, MVT::f64, { 1, 1, 1, 1 } },
3158 { ISD::FP_TO_SINT, MVT::i64, MVT::f64, { 1, 1, 1, 1 } },
3159 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v4f32, { 2, 1, 1, 1 } },
3160 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v2f64, { 2, 1, 1, 1 } },
3161 { ISD::FP_TO_SINT, MVT::v8i16, MVT::v4f32, { 1, 1, 1, 1 } },
3162 { ISD::FP_TO_SINT, MVT::v8i16, MVT::v2f64, { 1, 1, 1, 1 } },
3163 { ISD::FP_TO_SINT, MVT::v4i32, MVT::v4f32, { 1, 1, 1, 1 } },
3164 { ISD::FP_TO_SINT, MVT::v4i32, MVT::v2f64, { 1, 1, 1, 1 } },
3165
3166 { ISD::FP_TO_UINT, MVT::i32, MVT::f32, { 1, 1, 1, 1 } },
3167 { ISD::FP_TO_UINT, MVT::i64, MVT::f32, { 4, 1, 1, 1 } },
3168 { ISD::FP_TO_UINT, MVT::i32, MVT::f64, { 1, 1, 1, 1 } },
3169 { ISD::FP_TO_UINT, MVT::i64, MVT::f64, { 4, 1, 1, 1 } },
3170 { ISD::FP_TO_UINT, MVT::v16i8, MVT::v4f32, { 2, 1, 1, 1 } },
3171 { ISD::FP_TO_UINT, MVT::v16i8, MVT::v2f64, { 2, 1, 1, 1 } },
3172 { ISD::FP_TO_UINT, MVT::v8i16, MVT::v4f32, { 1, 1, 1, 1 } },
3173 { ISD::FP_TO_UINT, MVT::v8i16, MVT::v2f64, { 1, 1, 1, 1 } },
3174 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f32, { 4, 1, 1, 1 } },
3175 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v2f64, { 4, 1, 1, 1 } },
3176 };
3177
3178 static const TypeConversionCostKindTblEntry SSE2ConversionTbl[] = {
3179 // These are somewhat magic numbers justified by comparing the
3180 // output of llvm-mca for our various supported scheduler models
3181 // and basing it off the worst case scenario.
3182 { ISD::SINT_TO_FP, MVT::f32, MVT::i32, { 3, 1, 1, 1 } },
3183 { ISD::SINT_TO_FP, MVT::f64, MVT::i32, { 3, 1, 1, 1 } },
3184 { ISD::SINT_TO_FP, MVT::f32, MVT::i64, { 3, 1, 1, 1 } },
3185 { ISD::SINT_TO_FP, MVT::f64, MVT::i64, { 3, 1, 1, 1 } },
3186 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v16i8, { 3, 1, 1, 1 } },
3187 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v16i8, { 4, 1, 1, 1 } },
3188 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v8i16, { 3, 1, 1, 1 } },
3189 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v8i16, { 4, 1, 1, 1 } },
3190 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v4i32, { 3, 1, 1, 1 } },
3191 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v4i32, { 4, 1, 1, 1 } },
3192 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v2i64, { 8, 1, 1, 1 } },
3193 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v2i64, { 8, 1, 1, 1 } },
3194
3195 { ISD::UINT_TO_FP, MVT::f32, MVT::i32, { 3, 1, 1, 1 } },
3196 { ISD::UINT_TO_FP, MVT::f64, MVT::i32, { 3, 1, 1, 1 } },
3197 { ISD::UINT_TO_FP, MVT::f32, MVT::i64, { 8, 1, 1, 1 } },
3198 { ISD::UINT_TO_FP, MVT::f64, MVT::i64, { 9, 1, 1, 1 } },
3199 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v16i8, { 4, 1, 1, 1 } },
3200 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v16i8, { 4, 1, 1, 1 } },
3201 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v8i16, { 4, 1, 1, 1 } },
3202 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v8i16, { 4, 1, 1, 1 } },
3203 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i32, { 7, 1, 1, 1 } },
3204 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v4i32, { 7, 1, 1, 1 } },
3205 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i32, { 5, 1, 1, 1 } },
3206 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i64, {15, 1, 1, 1 } },
3207 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v2i64, {18, 1, 1, 1 } },
3208
3209 { ISD::FP_TO_SINT, MVT::i32, MVT::f32, { 4, 1, 1, 1 } },
3210 { ISD::FP_TO_SINT, MVT::i64, MVT::f32, { 4, 1, 1, 1 } },
3211 { ISD::FP_TO_SINT, MVT::i32, MVT::f64, { 4, 1, 1, 1 } },
3212 { ISD::FP_TO_SINT, MVT::i64, MVT::f64, { 4, 1, 1, 1 } },
3213 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v4f32, { 6, 1, 1, 1 } },
3214 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v2f64, { 6, 1, 1, 1 } },
3215 { ISD::FP_TO_SINT, MVT::v8i16, MVT::v4f32, { 5, 1, 1, 1 } },
3216 { ISD::FP_TO_SINT, MVT::v8i16, MVT::v2f64, { 5, 1, 1, 1 } },
3217 { ISD::FP_TO_SINT, MVT::v4i32, MVT::v4f32, { 4, 1, 1, 1 } },
3218 { ISD::FP_TO_SINT, MVT::v4i32, MVT::v2f64, { 4, 1, 1, 1 } },
3219
3220 { ISD::FP_TO_UINT, MVT::i32, MVT::f32, { 4, 1, 1, 1 } },
3221 { ISD::FP_TO_UINT, MVT::i64, MVT::f32, { 4, 1, 1, 1 } },
3222 { ISD::FP_TO_UINT, MVT::i32, MVT::f64, { 4, 1, 1, 1 } },
3223 { ISD::FP_TO_UINT, MVT::i64, MVT::f64, {15, 1, 1, 1 } },
3224 { ISD::FP_TO_UINT, MVT::v16i8, MVT::v4f32, { 6, 1, 1, 1 } },
3225 { ISD::FP_TO_UINT, MVT::v16i8, MVT::v2f64, { 6, 1, 1, 1 } },
3226 { ISD::FP_TO_UINT, MVT::v8i16, MVT::v4f32, { 5, 1, 1, 1 } },
3227 { ISD::FP_TO_UINT, MVT::v8i16, MVT::v2f64, { 5, 1, 1, 1 } },
3228 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f32, { 8, 1, 1, 1 } },
3229 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v2f64, { 8, 1, 1, 1 } },
3230
3231 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v16i8, { 4, 1, 1, 1 } },
3232 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v16i8, { 4, 1, 1, 1 } },
3233 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v16i8, { 2, 1, 1, 1 } },
3234 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v16i8, { 3, 1, 1, 1 } },
3235 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v16i8, { 1, 1, 1, 1 } },
3236 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v16i8, { 2, 1, 1, 1 } },
3237 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v8i16, { 2, 1, 1, 1 } },
3238 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v8i16, { 3, 1, 1, 1 } },
3239 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v8i16, { 1, 1, 1, 1 } },
3240 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v8i16, { 2, 1, 1, 1 } },
3241 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v4i32, { 1, 1, 1, 1 } },
3242 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v4i32, { 2, 1, 1, 1 } },
3243
3244 // These truncates are really widening elements.
3245 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i32, { 1, 1, 1, 1 } }, // PSHUFD
3246 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i16, { 2, 1, 1, 1 } }, // PUNPCKLWD+DQ
3247 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i8, { 3, 1, 1, 1 } }, // PUNPCKLBW+WD+PSHUFD
3248 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i16, { 1, 1, 1, 1 } }, // PUNPCKLWD
3249 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i8, { 2, 1, 1, 1 } }, // PUNPCKLBW+WD
3250 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i8, { 1, 1, 1, 1 } }, // PUNPCKLBW
3251
3252 { ISD::TRUNCATE, MVT::v16i8, MVT::v8i16, { 2, 1, 1, 1 } }, // PAND+PACKUSWB
3253 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i16, { 3, 1, 1, 1 } },
3254 { ISD::TRUNCATE, MVT::v16i8, MVT::v4i32, { 3, 1, 1, 1 } }, // PAND+2*PACKUSWB
3255 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i32, { 7, 1, 1, 1 } },
3256 { ISD::TRUNCATE, MVT::v2i16, MVT::v2i32, { 1, 1, 1, 1 } },
3257 { ISD::TRUNCATE, MVT::v8i16, MVT::v4i32, { 3, 1, 1, 1 } },
3258 { ISD::TRUNCATE, MVT::v8i16, MVT::v8i32, { 5, 1, 1, 1 } },
3259 { ISD::TRUNCATE, MVT::v16i16, MVT::v16i32, {10, 1, 1, 1 } },
3260 { ISD::TRUNCATE, MVT::v16i8, MVT::v2i64, { 4, 1, 1, 1 } }, // PAND+3*PACKUSWB
3261 { ISD::TRUNCATE, MVT::v8i16, MVT::v2i64, { 2, 1, 1, 1 } }, // PSHUFD+PSHUFLW
3262 { ISD::TRUNCATE, MVT::v4i32, MVT::v2i64, { 1, 1, 1, 1 } }, // PSHUFD
3263 };
3264
3265 static const TypeConversionCostKindTblEntry F16ConversionTbl[] = {
3266 { ISD::FP_ROUND, MVT::f16, MVT::f32, { 1, 1, 1, 1 } },
3267 { ISD::FP_ROUND, MVT::v8f16, MVT::v8f32, { 1, 1, 1, 1 } },
3268 { ISD::FP_ROUND, MVT::v4f16, MVT::v4f32, { 1, 1, 1, 1 } },
3269 { ISD::FP_EXTEND, MVT::f32, MVT::f16, { 1, 1, 1, 1 } },
3270 { ISD::FP_EXTEND, MVT::f64, MVT::f16, { 2, 1, 1, 1 } }, // vcvtph2ps+vcvtps2pd
3271 { ISD::FP_EXTEND, MVT::v8f32, MVT::v8f16, { 1, 1, 1, 1 } },
3272 { ISD::FP_EXTEND, MVT::v4f32, MVT::v4f16, { 1, 1, 1, 1 } },
3273 { ISD::FP_EXTEND, MVT::v4f64, MVT::v4f16, { 2, 1, 1, 1 } }, // vcvtph2ps+vcvtps2pd
3274 };
3275
3276 // Attempt to map directly to (simple) MVT types to let us match custom entries.
3277 EVT SrcTy = TLI->getValueType(DL, Src);
3278 EVT DstTy = TLI->getValueType(DL, Dst);
3279
3280 // If we're sign-extending a vector comparison result back to the comparison
3281 // width, this will be free without AVX512 (or for 8/16-bit types without
3282 // BWI).
3283 if (!ST->hasAVX512() || (!ST->hasBWI() && DstTy.getScalarSizeInBits() < 32)) {
3284 if (I && Opcode == Instruction::CastOps::SExt &&
3285 SrcTy.isFixedLengthVectorOf(MVT::i1)) {
3286 if (auto *CmpI = dyn_cast<CmpInst>(I->getOperand(0))) {
3287 Type *CmpTy = CmpI->getOperand(0)->getType();
3288 if (CmpTy->getScalarSizeInBits() == DstTy.getScalarSizeInBits())
3289 return TTI::TCC_Free;
3290 }
3291 }
3292 }
3293
3294 // The function getSimpleVT only handles simple value types.
3295 if (SrcTy.isSimple() && DstTy.isSimple()) {
3296 MVT SimpleSrcTy = SrcTy.getSimpleVT();
3297 MVT SimpleDstTy = DstTy.getSimpleVT();
3298
3299 if (ST->useAVX512Regs()) {
3300 if (ST->hasBWI())
3301 if (const auto *Entry = ConvertCostTableLookup(
3302 AVX512BWConversionTbl, ISD, SimpleDstTy, SimpleSrcTy))
3303 if (auto KindCost = Entry->Cost[CostKind])
3304 return *KindCost;
3305
3306 if (ST->hasDQI())
3307 if (const auto *Entry = ConvertCostTableLookup(
3308 AVX512DQConversionTbl, ISD, SimpleDstTy, SimpleSrcTy))
3309 if (auto KindCost = Entry->Cost[CostKind])
3310 return *KindCost;
3311
3312 if (ST->hasAVX512())
3313 if (const auto *Entry = ConvertCostTableLookup(
3314 AVX512FConversionTbl, ISD, SimpleDstTy, SimpleSrcTy))
3315 if (auto KindCost = Entry->Cost[CostKind])
3316 return *KindCost;
3317 }
3318
3319 if (ST->hasBWI())
3320 if (const auto *Entry = ConvertCostTableLookup(
3321 AVX512BWVLConversionTbl, ISD, SimpleDstTy, SimpleSrcTy))
3322 if (auto KindCost = Entry->Cost[CostKind])
3323 return *KindCost;
3324
3325 if (ST->hasDQI())
3326 if (const auto *Entry = ConvertCostTableLookup(
3327 AVX512DQVLConversionTbl, ISD, SimpleDstTy, SimpleSrcTy))
3328 if (auto KindCost = Entry->Cost[CostKind])
3329 return *KindCost;
3330
3331 if (ST->hasAVX512())
3332 if (const auto *Entry = ConvertCostTableLookup(AVX512VLConversionTbl, ISD,
3333 SimpleDstTy, SimpleSrcTy))
3334 if (auto KindCost = Entry->Cost[CostKind])
3335 return *KindCost;
3336
3337 if (ST->hasAVX2()) {
3338 if (const auto *Entry = ConvertCostTableLookup(AVX2ConversionTbl, ISD,
3339 SimpleDstTy, SimpleSrcTy))
3340 if (auto KindCost = Entry->Cost[CostKind])
3341 return *KindCost;
3342 }
3343
3344 if (ST->hasAVX()) {
3345 if (const auto *Entry = ConvertCostTableLookup(AVXConversionTbl, ISD,
3346 SimpleDstTy, SimpleSrcTy))
3347 if (auto KindCost = Entry->Cost[CostKind])
3348 return *KindCost;
3349 }
3350
3351 if (ST->hasF16C()) {
3352 if (const auto *Entry = ConvertCostTableLookup(F16ConversionTbl, ISD,
3353 SimpleDstTy, SimpleSrcTy))
3354 if (auto KindCost = Entry->Cost[CostKind])
3355 return *KindCost;
3356 }
3357
3358 if (ST->hasSSE41()) {
3359 if (const auto *Entry = ConvertCostTableLookup(SSE41ConversionTbl, ISD,
3360 SimpleDstTy, SimpleSrcTy))
3361 if (auto KindCost = Entry->Cost[CostKind])
3362 return *KindCost;
3363 }
3364
3365 if (ST->hasSSE2()) {
3366 if (const auto *Entry = ConvertCostTableLookup(SSE2ConversionTbl, ISD,
3367 SimpleDstTy, SimpleSrcTy))
3368 if (auto KindCost = Entry->Cost[CostKind])
3369 return *KindCost;
3370 }
3371
3372 if ((ISD == ISD::FP_ROUND && SimpleDstTy == MVT::f16) ||
3373 (ISD == ISD::FP_EXTEND && SimpleSrcTy == MVT::f16)) {
3374 // fp16 conversions not covered by any table entries require a libcall.
3375 // Return a large (arbitrary) number to model this.
3376 return InstructionCost(64);
3377 }
3378 }
3379
3380 // Fall back to legalized types.
3381 std::pair<InstructionCost, MVT> LTSrc = getTypeLegalizationCost(Src);
3382 std::pair<InstructionCost, MVT> LTDest = getTypeLegalizationCost(Dst);
3383
3384 // If we're truncating to the same legalized type - just assume its free.
3385 if (ISD == ISD::TRUNCATE && LTSrc.second == LTDest.second)
3386 return TTI::TCC_Free;
3387
3388 if (ST->useAVX512Regs()) {
3389 if (ST->hasBWI())
3390 if (const auto *Entry = ConvertCostTableLookup(
3391 AVX512BWConversionTbl, ISD, LTDest.second, LTSrc.second))
3392 if (auto KindCost = Entry->Cost[CostKind])
3393 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3394
3395 if (ST->hasDQI())
3396 if (const auto *Entry = ConvertCostTableLookup(
3397 AVX512DQConversionTbl, ISD, LTDest.second, LTSrc.second))
3398 if (auto KindCost = Entry->Cost[CostKind])
3399 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3400
3401 if (ST->hasAVX512())
3402 if (const auto *Entry = ConvertCostTableLookup(
3403 AVX512FConversionTbl, ISD, LTDest.second, LTSrc.second))
3404 if (auto KindCost = Entry->Cost[CostKind])
3405 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3406 }
3407
3408 if (ST->hasBWI())
3409 if (const auto *Entry = ConvertCostTableLookup(AVX512BWVLConversionTbl, ISD,
3410 LTDest.second, LTSrc.second))
3411 if (auto KindCost = Entry->Cost[CostKind])
3412 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3413
3414 if (ST->hasDQI())
3415 if (const auto *Entry = ConvertCostTableLookup(AVX512DQVLConversionTbl, ISD,
3416 LTDest.second, LTSrc.second))
3417 if (auto KindCost = Entry->Cost[CostKind])
3418 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3419
3420 if (ST->hasAVX512())
3421 if (const auto *Entry = ConvertCostTableLookup(AVX512VLConversionTbl, ISD,
3422 LTDest.second, LTSrc.second))
3423 if (auto KindCost = Entry->Cost[CostKind])
3424 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3425
3426 if (ST->hasAVX2())
3427 if (const auto *Entry = ConvertCostTableLookup(AVX2ConversionTbl, ISD,
3428 LTDest.second, LTSrc.second))
3429 if (auto KindCost = Entry->Cost[CostKind])
3430 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3431
3432 if (ST->hasAVX())
3433 if (const auto *Entry = ConvertCostTableLookup(AVXConversionTbl, ISD,
3434 LTDest.second, LTSrc.second))
3435 if (auto KindCost = Entry->Cost[CostKind])
3436 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3437
3438 if (ST->hasF16C()) {
3439 if (const auto *Entry = ConvertCostTableLookup(F16ConversionTbl, ISD,
3440 LTDest.second, LTSrc.second))
3441 if (auto KindCost = Entry->Cost[CostKind])
3442 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3443 }
3444
3445 if (ST->hasSSE41())
3446 if (const auto *Entry = ConvertCostTableLookup(SSE41ConversionTbl, ISD,
3447 LTDest.second, LTSrc.second))
3448 if (auto KindCost = Entry->Cost[CostKind])
3449 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3450
3451 if (ST->hasSSE2())
3452 if (const auto *Entry = ConvertCostTableLookup(SSE2ConversionTbl, ISD,
3453 LTDest.second, LTSrc.second))
3454 if (auto KindCost = Entry->Cost[CostKind])
3455 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3456
3457 // Fallback, for i8/i16 sitofp/uitofp cases we need to extend to i32 for
3458 // sitofp.
3459 if ((ISD == ISD::SINT_TO_FP || ISD == ISD::UINT_TO_FP) &&
3460 1 < Src->getScalarSizeInBits() && Src->getScalarSizeInBits() < 32) {
3461 Type *ExtSrc = Src->getWithNewBitWidth(32);
3462 unsigned ExtOpc =
3463 (ISD == ISD::SINT_TO_FP) ? Instruction::SExt : Instruction::ZExt;
3464
3465 // For scalar loads the extend would be free.
3466 InstructionCost ExtCost = 0;
3467 if (!(Src->isIntegerTy() && I && isa<LoadInst>(I->getOperand(0))))
3468 ExtCost = getCastInstrCost(ExtOpc, ExtSrc, Src, CCH, CostKind);
3469
3470 return ExtCost + getCastInstrCost(Instruction::SIToFP, Dst, ExtSrc,
3472 }
3473
3474 // Fallback for fptosi/fptoui i8/i16 cases we need to truncate from fptosi
3475 // i32.
3476 if ((ISD == ISD::FP_TO_SINT || ISD == ISD::FP_TO_UINT) &&
3477 1 < Dst->getScalarSizeInBits() && Dst->getScalarSizeInBits() < 32) {
3478 Type *TruncDst = Dst->getWithNewBitWidth(32);
3479 return getCastInstrCost(Instruction::FPToSI, TruncDst, Src, CCH, CostKind) +
3480 getCastInstrCost(Instruction::Trunc, Dst, TruncDst,
3482 }
3483
3484 // TODO: Allow non-throughput costs that aren't binary.
3485 auto AdjustCost = [&CostKind](InstructionCost Cost,
3488 return Cost == 0 ? 0 : N;
3489 return Cost * N;
3490 };
3491 return AdjustCost(
3492 BaseT::getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I));
3493}
3494
3496 unsigned Opcode, Type *ValTy, Type *CondTy, CmpInst::Predicate VecPred,
3498 TTI::OperandValueInfo Op2Info, const Instruction *I) const {
3499 // Early out if this type isn't scalar/vector integer/float.
3500 if (!(ValTy->isIntOrIntVectorTy() || ValTy->isFPOrFPVectorTy()))
3501 return BaseT::getCmpSelInstrCost(Opcode, ValTy, CondTy, VecPred, CostKind,
3502 Op1Info, Op2Info, I);
3503
3504 // Legalize the type.
3505 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(ValTy);
3506
3507 MVT MTy = LT.second;
3508
3509 int ISD = TLI->InstructionOpcodeToISD(Opcode);
3510 assert(ISD && "Invalid opcode");
3511
3512 InstructionCost ExtraCost = 0;
3513 if (Opcode == Instruction::ICmp || Opcode == Instruction::FCmp) {
3514 // Some vector comparison predicates cost extra instructions.
3515 // TODO: Adjust ExtraCost based on CostKind?
3516 // TODO: Should we invert this and assume worst case cmp costs
3517 // and reduce for particular predicates?
3518 if (MTy.isVector() &&
3519 !((ST->hasXOP() && (!ST->hasAVX2() || MTy.is128BitVector())) ||
3520 (ST->hasAVX512() && 32 <= MTy.getScalarSizeInBits()) ||
3521 ST->hasBWI())) {
3522 // Fallback to I if a specific predicate wasn't specified.
3523 CmpInst::Predicate Pred = VecPred;
3524 if (I && (Pred == CmpInst::BAD_ICMP_PREDICATE ||
3526 Pred = cast<CmpInst>(I)->getPredicate();
3527
3528 bool CmpWithConstant = false;
3529 if (auto *CmpInstr = dyn_cast_or_null<CmpInst>(I))
3530 CmpWithConstant = isa<Constant>(CmpInstr->getOperand(1));
3531
3532 switch (Pred) {
3534 // xor(cmpeq(x,y),-1)
3535 ExtraCost = CmpWithConstant ? 0 : 1;
3536 break;
3539 // xor(cmpgt(x,y),-1)
3540 ExtraCost = CmpWithConstant ? 0 : 1;
3541 break;
3544 // cmpgt(xor(x,signbit),xor(y,signbit))
3545 // xor(cmpeq(pmaxu(x,y),x),-1)
3546 ExtraCost = CmpWithConstant ? 1 : 2;
3547 break;
3550 if ((ST->hasSSE41() && MTy.getScalarSizeInBits() == 32) ||
3551 (ST->hasSSE2() && MTy.getScalarSizeInBits() < 32)) {
3552 // cmpeq(psubus(x,y),0)
3553 // cmpeq(pminu(x,y),x)
3554 ExtraCost = 1;
3555 } else {
3556 // xor(cmpgt(xor(x,signbit),xor(y,signbit)),-1)
3557 ExtraCost = CmpWithConstant ? 2 : 3;
3558 }
3559 break;
3562 // Without AVX we need to expand FCMP_ONE/FCMP_UEQ cases.
3563 // Use FCMP_UEQ expansion - FCMP_ONE should be the same.
3564 if (CondTy && !ST->hasAVX())
3565 return getCmpSelInstrCost(Opcode, ValTy, CondTy,
3567 Op1Info, Op2Info) +
3568 getCmpSelInstrCost(Opcode, ValTy, CondTy,
3570 Op1Info, Op2Info) +
3571 getArithmeticInstrCost(Instruction::Or, CondTy, CostKind);
3572
3573 break;
3576 // Assume worst case scenario and add the maximum extra cost.
3577 ExtraCost = 3;
3578 break;
3579 default:
3580 break;
3581 }
3582 }
3583 }
3584
3585 static const CostKindTblEntry SLMCostTbl[] = {
3586 // slm pcmpeq/pcmpgt throughput is 2
3587 { ISD::SETCC, MVT::v2i64, { 2, 5, 1, 2 } },
3588 // slm pblendvb/blendvpd/blendvps throughput is 4
3589 { ISD::SELECT, MVT::v2f64, { 4, 4, 1, 3 } }, // vblendvpd
3590 { ISD::SELECT, MVT::v4f32, { 4, 4, 1, 3 } }, // vblendvps
3591 { ISD::SELECT, MVT::v2i64, { 4, 4, 1, 3 } }, // pblendvb
3592 { ISD::SELECT, MVT::v8i32, { 4, 4, 1, 3 } }, // pblendvb
3593 { ISD::SELECT, MVT::v8i16, { 4, 4, 1, 3 } }, // pblendvb
3594 { ISD::SELECT, MVT::v16i8, { 4, 4, 1, 3 } }, // pblendvb
3595 };
3596
3597 static const CostKindTblEntry AVX512BWCostTbl[] = {
3598 { ISD::SETCC, MVT::v32i16, { 1, 1, 1, 1 } },
3599 { ISD::SETCC, MVT::v16i16, { 1, 1, 1, 1 } },
3600 { ISD::SETCC, MVT::v64i8, { 1, 1, 1, 1 } },
3601 { ISD::SETCC, MVT::v32i8, { 1, 1, 1, 1 } },
3602
3603 { ISD::SELECT, MVT::v32i16, { 1, 1, 1, 1 } },
3604 { ISD::SELECT, MVT::v64i8, { 1, 1, 1, 1 } },
3605 };
3606
3607 static const CostKindTblEntry AVX512CostTbl[] = {
3608 { ISD::SETCC, MVT::v8f64, { 1, 4, 1, 1 } },
3609 { ISD::SETCC, MVT::v4f64, { 1, 4, 1, 1 } },
3610 { ISD::SETCC, MVT::v16f32, { 1, 4, 1, 1 } },
3611 { ISD::SETCC, MVT::v8f32, { 1, 4, 1, 1 } },
3612
3613 { ISD::SETCC, MVT::v8i64, { 1, 1, 1, 1 } },
3614 { ISD::SETCC, MVT::v4i64, { 1, 1, 1, 1 } },
3615 { ISD::SETCC, MVT::v2i64, { 1, 1, 1, 1 } },
3616 { ISD::SETCC, MVT::v16i32, { 1, 1, 1, 1 } },
3617 { ISD::SETCC, MVT::v8i32, { 1, 1, 1, 1 } },
3618 { ISD::SETCC, MVT::v32i16, { 3, 7, 5, 5 } },
3619 { ISD::SETCC, MVT::v64i8, { 3, 7, 5, 5 } },
3620
3621 { ISD::SELECT, MVT::v8i64, { 1, 1, 1, 1 } },
3622 { ISD::SELECT, MVT::v4i64, { 1, 1, 1, 1 } },
3623 { ISD::SELECT, MVT::v2i64, { 1, 1, 1, 1 } },
3624 { ISD::SELECT, MVT::v16i32, { 1, 1, 1, 1 } },
3625 { ISD::SELECT, MVT::v8i32, { 1, 1, 1, 1 } },
3626 { ISD::SELECT, MVT::v4i32, { 1, 1, 1, 1 } },
3627 { ISD::SELECT, MVT::v8f64, { 1, 1, 1, 1 } },
3628 { ISD::SELECT, MVT::v4f64, { 1, 1, 1, 1 } },
3629 { ISD::SELECT, MVT::v2f64, { 1, 1, 1, 1 } },
3630 { ISD::SELECT, MVT::f64, { 1, 1, 1, 1 } },
3631 { ISD::SELECT, MVT::v16f32, { 1, 1, 1, 1 } },
3632 { ISD::SELECT, MVT::v8f32 , { 1, 1, 1, 1 } },
3633 { ISD::SELECT, MVT::v4f32, { 1, 1, 1, 1 } },
3634 { ISD::SELECT, MVT::f32 , { 1, 1, 1, 1 } },
3635
3636 { ISD::SELECT, MVT::v32i16, { 2, 2, 4, 4 } },
3637 { ISD::SELECT, MVT::v16i16, { 1, 1, 1, 1 } },
3638 { ISD::SELECT, MVT::v8i16, { 1, 1, 1, 1 } },
3639 { ISD::SELECT, MVT::v64i8, { 2, 2, 4, 4 } },
3640 { ISD::SELECT, MVT::v32i8, { 1, 1, 1, 1 } },
3641 { ISD::SELECT, MVT::v16i8, { 1, 1, 1, 1 } },
3642 };
3643
3644 static const CostKindTblEntry AVX2CostTbl[] = {
3645 { ISD::SETCC, MVT::v4f64, { 1, 4, 1, 2 } },
3646 { ISD::SETCC, MVT::v2f64, { 1, 4, 1, 1 } },
3647 { ISD::SETCC, MVT::f64, { 1, 4, 1, 1 } },
3648 { ISD::SETCC, MVT::v8f32, { 1, 4, 1, 2 } },
3649 { ISD::SETCC, MVT::v4f32, { 1, 4, 1, 1 } },
3650 { ISD::SETCC, MVT::f32, { 1, 4, 1, 1 } },
3651
3652 { ISD::SETCC, MVT::v4i64, { 1, 1, 1, 2 } },
3653 { ISD::SETCC, MVT::v8i32, { 1, 1, 1, 2 } },
3654 { ISD::SETCC, MVT::v16i16, { 1, 1, 1, 2 } },
3655 { ISD::SETCC, MVT::v32i8, { 1, 1, 1, 2 } },
3656
3657 { ISD::SELECT, MVT::v4f64, { 2, 2, 1, 2 } }, // vblendvpd
3658 { ISD::SELECT, MVT::v8f32, { 2, 2, 1, 2 } }, // vblendvps
3659 { ISD::SELECT, MVT::v4i64, { 2, 2, 1, 2 } }, // pblendvb
3660 { ISD::SELECT, MVT::v8i32, { 2, 2, 1, 2 } }, // pblendvb
3661 { ISD::SELECT, MVT::v16i16, { 2, 2, 1, 2 } }, // pblendvb
3662 { ISD::SELECT, MVT::v32i8, { 2, 2, 1, 2 } }, // pblendvb
3663 };
3664
3665 static const CostKindTblEntry XOPCostTbl[] = {
3666 { ISD::SETCC, MVT::v4i64, { 4, 2, 5, 6 } },
3667 { ISD::SETCC, MVT::v2i64, { 1, 1, 1, 1 } },
3668 };
3669
3670 static const CostKindTblEntry AVX1CostTbl[] = {
3671 { ISD::SETCC, MVT::v4f64, { 2, 3, 1, 2 } },
3672 { ISD::SETCC, MVT::v2f64, { 1, 3, 1, 1 } },
3673 { ISD::SETCC, MVT::f64, { 1, 3, 1, 1 } },
3674 { ISD::SETCC, MVT::v8f32, { 2, 3, 1, 2 } },
3675 { ISD::SETCC, MVT::v4f32, { 1, 3, 1, 1 } },
3676 { ISD::SETCC, MVT::f32, { 1, 3, 1, 1 } },
3677
3678 // AVX1 does not support 8-wide integer compare.
3679 { ISD::SETCC, MVT::v4i64, { 4, 2, 5, 6 } },
3680 { ISD::SETCC, MVT::v8i32, { 4, 2, 5, 6 } },
3681 { ISD::SETCC, MVT::v16i16, { 4, 2, 5, 6 } },
3682 { ISD::SETCC, MVT::v32i8, { 4, 2, 5, 6 } },
3683
3684 { ISD::SELECT, MVT::v4f64, { 3, 3, 1, 2 } }, // vblendvpd
3685 { ISD::SELECT, MVT::v8f32, { 3, 3, 1, 2 } }, // vblendvps
3686 { ISD::SELECT, MVT::v4i64, { 3, 3, 1, 2 } }, // vblendvpd
3687 { ISD::SELECT, MVT::v8i32, { 3, 3, 1, 2 } }, // vblendvps
3688 { ISD::SELECT, MVT::v16i16, { 3, 3, 3, 3 } }, // vandps + vandnps + vorps
3689 { ISD::SELECT, MVT::v32i8, { 3, 3, 3, 3 } }, // vandps + vandnps + vorps
3690 };
3691
3692 static const CostKindTblEntry SSE42CostTbl[] = {
3693 { ISD::SETCC, MVT::v2i64, { 1, 2, 1, 2 } },
3694 };
3695
3696 static const CostKindTblEntry SSE41CostTbl[] = {
3697 { ISD::SETCC, MVT::v2f64, { 1, 5, 1, 1 } },
3698 { ISD::SETCC, MVT::v4f32, { 1, 5, 1, 1 } },
3699
3700 { ISD::SELECT, MVT::v2f64, { 2, 2, 1, 2 } }, // blendvpd
3701 { ISD::SELECT, MVT::f64, { 2, 2, 1, 2 } }, // blendvpd
3702 { ISD::SELECT, MVT::v4f32, { 2, 2, 1, 2 } }, // blendvps
3703 { ISD::SELECT, MVT::f32 , { 2, 2, 1, 2 } }, // blendvps
3704 { ISD::SELECT, MVT::v2i64, { 2, 2, 1, 2 } }, // pblendvb
3705 { ISD::SELECT, MVT::v4i32, { 2, 2, 1, 2 } }, // pblendvb
3706 { ISD::SELECT, MVT::v8i16, { 2, 2, 1, 2 } }, // pblendvb
3707 { ISD::SELECT, MVT::v16i8, { 2, 2, 1, 2 } }, // pblendvb
3708 };
3709
3710 static const CostKindTblEntry SSE2CostTbl[] = {
3711 { ISD::SETCC, MVT::v2f64, { 2, 5, 1, 1 } },
3712 { ISD::SETCC, MVT::f64, { 1, 5, 1, 1 } },
3713
3714 { ISD::SETCC, MVT::v2i64, { 5, 4, 5, 5 } }, // pcmpeqd/pcmpgtd expansion
3715 { ISD::SETCC, MVT::v4i32, { 1, 1, 1, 1 } },
3716 { ISD::SETCC, MVT::v8i16, { 1, 1, 1, 1 } },
3717 { ISD::SETCC, MVT::v16i8, { 1, 1, 1, 1 } },
3718
3719 { ISD::SELECT, MVT::v2f64, { 2, 2, 3, 3 } }, // andpd + andnpd + orpd
3720 { ISD::SELECT, MVT::f64, { 2, 2, 3, 3 } }, // andpd + andnpd + orpd
3721 { ISD::SELECT, MVT::v2i64, { 2, 2, 3, 3 } }, // pand + pandn + por
3722 { ISD::SELECT, MVT::v4i32, { 2, 2, 3, 3 } }, // pand + pandn + por
3723 { ISD::SELECT, MVT::v8i16, { 2, 2, 3, 3 } }, // pand + pandn + por
3724 { ISD::SELECT, MVT::v16i8, { 2, 2, 3, 3 } }, // pand + pandn + por
3725 };
3726
3727 static const CostKindTblEntry SSE1CostTbl[] = {
3728 { ISD::SETCC, MVT::v4f32, { 2, 5, 1, 1 } },
3729 { ISD::SETCC, MVT::f32, { 1, 5, 1, 1 } },
3730
3731 { ISD::SELECT, MVT::v4f32, { 2, 2, 3, 3 } }, // andps + andnps + orps
3732 { ISD::SELECT, MVT::f32, { 2, 2, 3, 3 } }, // andps + andnps + orps
3733 };
3734
3735 if (ST->useSLMArithCosts())
3736 if (const auto *Entry = CostTableLookup(SLMCostTbl, ISD, MTy))
3737 if (auto KindCost = Entry->Cost[CostKind])
3738 return LT.first * (ExtraCost + *KindCost);
3739
3740 if (ST->hasBWI())
3741 if (const auto *Entry = CostTableLookup(AVX512BWCostTbl, ISD, MTy))
3742 if (auto KindCost = Entry->Cost[CostKind])
3743 return LT.first * (ExtraCost + *KindCost);
3744
3745 if (ST->hasAVX512())
3746 if (const auto *Entry = CostTableLookup(AVX512CostTbl, ISD, MTy))
3747 if (auto KindCost = Entry->Cost[CostKind])
3748 return LT.first * (ExtraCost + *KindCost);
3749
3750 if (ST->hasAVX2())
3751 if (const auto *Entry = CostTableLookup(AVX2CostTbl, ISD, MTy))
3752 if (auto KindCost = Entry->Cost[CostKind])
3753 return LT.first * (ExtraCost + *KindCost);
3754
3755 if (ST->hasXOP())
3756 if (const auto *Entry = CostTableLookup(XOPCostTbl, ISD, MTy))
3757 if (auto KindCost = Entry->Cost[CostKind])
3758 return LT.first * (ExtraCost + *KindCost);
3759
3760 if (ST->hasAVX())
3761 if (const auto *Entry = CostTableLookup(AVX1CostTbl, ISD, MTy))
3762 if (auto KindCost = Entry->Cost[CostKind])
3763 return LT.first * (ExtraCost + *KindCost);
3764
3765 if (ST->hasSSE42())
3766 if (const auto *Entry = CostTableLookup(SSE42CostTbl, ISD, MTy))
3767 if (auto KindCost = Entry->Cost[CostKind])
3768 return LT.first * (ExtraCost + *KindCost);
3769
3770 if (ST->hasSSE41())
3771 if (const auto *Entry = CostTableLookup(SSE41CostTbl, ISD, MTy))
3772 if (auto KindCost = Entry->Cost[CostKind])
3773 return LT.first * (ExtraCost + *KindCost);
3774
3775 if (ST->hasSSE2())
3776 if (const auto *Entry = CostTableLookup(SSE2CostTbl, ISD, MTy))
3777 if (auto KindCost = Entry->Cost[CostKind])
3778 return LT.first * (ExtraCost + *KindCost);
3779
3780 if (ST->hasSSE1())
3781 if (const auto *Entry = CostTableLookup(SSE1CostTbl, ISD, MTy))
3782 if (auto KindCost = Entry->Cost[CostKind])
3783 return LT.first * (ExtraCost + *KindCost);
3784
3785 // Assume a 3cy latency for fp select ops.
3786 if (CostKind == TTI::TCK_Latency && Opcode == Instruction::Select)
3787 if (ValTy->getScalarType()->isFloatingPointTy())
3788 return 3;
3789
3790 return BaseT::getCmpSelInstrCost(Opcode, ValTy, CondTy, VecPred, CostKind,
3791 Op1Info, Op2Info, I);
3792}
3793
3795
3799 // Costs should match the codegen from:
3800 // BITREVERSE: llvm\test\CodeGen\X86\vector-bitreverse.ll
3801 // BSWAP: llvm\test\CodeGen\X86\bswap-vector.ll
3802 // CTLZ: llvm\test\CodeGen\X86\vector-lzcnt-*.ll
3803 // CTPOP: llvm\test\CodeGen\X86\vector-popcnt-*.ll
3804 // CTTZ: llvm\test\CodeGen\X86\vector-tzcnt-*.ll
3805
3806 // TODO: Overflow intrinsics (*ADDO, *SUBO, *MULO) with vector types are not
3807 // specialized in these tables yet.
3808 static const CostKindTblEntry AVX512VBMI2CostTbl[] = {
3809 { ISD::FSHL, MVT::v8i64, { 1, 1, 1, 1 } },
3810 { ISD::FSHL, MVT::v4i64, { 1, 1, 1, 1 } },
3811 { ISD::FSHL, MVT::v2i64, { 1, 1, 1, 1 } },
3812 { ISD::FSHL, MVT::v16i32, { 1, 1, 1, 1 } },
3813 { ISD::FSHL, MVT::v8i32, { 1, 1, 1, 1 } },
3814 { ISD::FSHL, MVT::v4i32, { 1, 1, 1, 1 } },
3815 { ISD::FSHL, MVT::v32i16, { 1, 1, 1, 1 } },
3816 { ISD::FSHL, MVT::v16i16, { 1, 1, 1, 1 } },
3817 { ISD::FSHL, MVT::v8i16, { 1, 1, 1, 1 } },
3818 { ISD::ROTL, MVT::v32i16, { 1, 1, 1, 1 } },
3819 { ISD::ROTL, MVT::v16i16, { 1, 1, 1, 1 } },
3820 { ISD::ROTL, MVT::v8i16, { 1, 1, 1, 1 } },
3821 { ISD::ROTR, MVT::v32i16, { 1, 1, 1, 1 } },
3822 { ISD::ROTR, MVT::v16i16, { 1, 1, 1, 1 } },
3823 { ISD::ROTR, MVT::v8i16, { 1, 1, 1, 1 } },
3824 { X86ISD::VROTLI, MVT::v32i16, { 1, 1, 1, 1 } },
3825 { X86ISD::VROTLI, MVT::v16i16, { 1, 1, 1, 1 } },
3826 { X86ISD::VROTLI, MVT::v8i16, { 1, 1, 1, 1 } },
3827 };
3828 static const CostKindTblEntry AVX512BITALGCostTbl[] = {
3829 { ISD::CTPOP, MVT::v32i16, { 1, 1, 1, 1 } },
3830 { ISD::CTPOP, MVT::v64i8, { 1, 1, 1, 1 } },
3831 { ISD::CTPOP, MVT::v16i16, { 1, 1, 1, 1 } },
3832 { ISD::CTPOP, MVT::v32i8, { 1, 1, 1, 1 } },
3833 { ISD::CTPOP, MVT::v8i16, { 1, 1, 1, 1 } },
3834 { ISD::CTPOP, MVT::v16i8, { 1, 1, 1, 1 } },
3835 };
3836 static const CostKindTblEntry AVX512VPOPCNTDQCostTbl[] = {
3837 { ISD::CTPOP, MVT::v8i64, { 1, 1, 1, 1 } },
3838 { ISD::CTPOP, MVT::v16i32, { 1, 1, 1, 1 } },
3839 { ISD::CTPOP, MVT::v4i64, { 1, 1, 1, 1 } },
3840 { ISD::CTPOP, MVT::v8i32, { 1, 1, 1, 1 } },
3841 { ISD::CTPOP, MVT::v2i64, { 1, 1, 1, 1 } },
3842 { ISD::CTPOP, MVT::v4i32, { 1, 1, 1, 1 } },
3843 };
3844 static const CostKindTblEntry AVX512CDCostTbl[] = {
3845 { ISD::CTLZ, MVT::v8i64, { 1, 5, 1, 1 } },
3846 { ISD::CTLZ, MVT::v16i32, { 1, 5, 1, 1 } },
3847 { ISD::CTLZ, MVT::v32i16, { 18, 27, 23, 27 } },
3848 { ISD::CTLZ, MVT::v64i8, { 3, 16, 9, 11 } },
3849 { ISD::CTLZ, MVT::v4i64, { 1, 5, 1, 1 } },
3850 { ISD::CTLZ, MVT::v8i32, { 1, 5, 1, 1 } },
3851 { ISD::CTLZ, MVT::v16i16, { 8, 19, 11, 13 } },
3852 { ISD::CTLZ, MVT::v32i8, { 2, 11, 9, 10 } },
3853 { ISD::CTLZ, MVT::v2i64, { 1, 5, 1, 1 } },
3854 { ISD::CTLZ, MVT::v4i32, { 1, 5, 1, 1 } },
3855 { ISD::CTLZ, MVT::v8i16, { 3, 15, 4, 6 } },
3856 { ISD::CTLZ, MVT::v16i8, { 2, 10, 9, 10 } },
3857
3858 { ISD::CTTZ, MVT::v8i64, { 2, 8, 6, 7 } },
3859 { ISD::CTTZ, MVT::v16i32, { 2, 8, 6, 7 } },
3860 { ISD::CTTZ, MVT::v4i64, { 1, 8, 6, 6 } },
3861 { ISD::CTTZ, MVT::v8i32, { 1, 8, 6, 6 } },
3862 { ISD::CTTZ, MVT::v2i64, { 1, 8, 6, 6 } },
3863 { ISD::CTTZ, MVT::v4i32, { 1, 8, 6, 6 } },
3864 };
3865 static const CostKindTblEntry AVX512BWCostTbl[] = {
3866 { ISD::ABS, MVT::v32i16, { 1, 1, 1, 1 } },
3867 { ISD::ABS, MVT::v64i8, { 1, 1, 1, 1 } },
3868 { ISD::BITREVERSE, MVT::v2i64, { 3, 10, 10, 11 } },
3869 { ISD::BITREVERSE, MVT::v4i64, { 3, 11, 10, 11 } },
3870 { ISD::BITREVERSE, MVT::v8i64, { 3, 12, 10, 14 } },
3871 { ISD::BITREVERSE, MVT::v4i32, { 3, 10, 10, 11 } },
3872 { ISD::BITREVERSE, MVT::v8i32, { 3, 11, 10, 11 } },
3873 { ISD::BITREVERSE, MVT::v16i32, { 3, 12, 10, 14 } },
3874 { ISD::BITREVERSE, MVT::v8i16, { 3, 10, 10, 11 } },
3875 { ISD::BITREVERSE, MVT::v16i16, { 3, 11, 10, 11 } },
3876 { ISD::BITREVERSE, MVT::v32i16, { 3, 12, 10, 14 } },
3877 { ISD::BITREVERSE, MVT::v16i8, { 2, 5, 9, 9 } },
3878 { ISD::BITREVERSE, MVT::v32i8, { 2, 5, 9, 9 } },
3879 { ISD::BITREVERSE, MVT::v64i8, { 2, 5, 9, 12 } },
3880 { ISD::BSWAP, MVT::v2i64, { 1, 1, 1, 2 } },
3881 { ISD::BSWAP, MVT::v4i64, { 1, 1, 1, 2 } },
3882 { ISD::BSWAP, MVT::v8i64, { 1, 1, 1, 2 } },
3883 { ISD::BSWAP, MVT::v4i32, { 1, 1, 1, 2 } },
3884 { ISD::BSWAP, MVT::v8i32, { 1, 1, 1, 2 } },
3885 { ISD::BSWAP, MVT::v16i32, { 1, 1, 1, 2 } },
3886 { ISD::BSWAP, MVT::v8i16, { 1, 1, 1, 2 } },
3887 { ISD::BSWAP, MVT::v16i16, { 1, 1, 1, 2 } },
3888 { ISD::BSWAP, MVT::v32i16, { 1, 1, 1, 2 } },
3889 { ISD::CTLZ, MVT::v8i64, { 8, 22, 23, 23 } },
3890 { ISD::CTLZ, MVT::v16i32, { 8, 23, 25, 25 } },
3891 { ISD::CTLZ, MVT::v32i16, { 4, 15, 15, 16 } },
3892 { ISD::CTLZ, MVT::v64i8, { 3, 12, 10, 9 } },
3893 { ISD::CTPOP, MVT::v2i64, { 3, 7, 10, 10 } },
3894 { ISD::CTPOP, MVT::v4i64, { 3, 7, 10, 10 } },
3895 { ISD::CTPOP, MVT::v8i64, { 3, 8, 10, 12 } },
3896 { ISD::CTPOP, MVT::v4i32, { 7, 11, 14, 14 } },
3897 { ISD::CTPOP, MVT::v8i32, { 7, 11, 14, 14 } },
3898 { ISD::CTPOP, MVT::v16i32, { 7, 12, 14, 16 } },
3899 { ISD::CTPOP, MVT::v8i16, { 2, 7, 11, 11 } },
3900 { ISD::CTPOP, MVT::v16i16, { 2, 7, 11, 11 } },
3901 { ISD::CTPOP, MVT::v32i16, { 3, 7, 11, 13 } },
3902 { ISD::CTPOP, MVT::v16i8, { 2, 4, 8, 8 } },
3903 { ISD::CTPOP, MVT::v32i8, { 2, 4, 8, 8 } },
3904 { ISD::CTPOP, MVT::v64i8, { 2, 5, 8, 10 } },
3905 { ISD::CTTZ, MVT::v8i16, { 3, 9, 14, 14 } },
3906 { ISD::CTTZ, MVT::v16i16, { 3, 9, 14, 14 } },
3907 { ISD::CTTZ, MVT::v32i16, { 3, 10, 14, 16 } },
3908 { ISD::CTTZ, MVT::v16i8, { 2, 6, 11, 11 } },
3909 { ISD::CTTZ, MVT::v32i8, { 2, 6, 11, 11 } },
3910 { ISD::CTTZ, MVT::v64i8, { 3, 7, 11, 13 } },
3911 { ISD::ROTL, MVT::v32i16, { 2, 8, 6, 8 } },
3912 { ISD::ROTL, MVT::v16i16, { 2, 8, 6, 7 } },
3913 { ISD::ROTL, MVT::v8i16, { 2, 7, 6, 7 } },
3914 { ISD::ROTL, MVT::v64i8, { 5, 6, 11, 12 } },
3915 { ISD::ROTL, MVT::v32i8, { 5, 15, 7, 10 } },
3916 { ISD::ROTL, MVT::v16i8, { 5, 15, 7, 10 } },
3917 { ISD::ROTR, MVT::v32i16, { 2, 8, 6, 8 } },
3918 { ISD::ROTR, MVT::v16i16, { 2, 8, 6, 7 } },
3919 { ISD::ROTR, MVT::v8i16, { 2, 7, 6, 7 } },
3920 { ISD::ROTR, MVT::v64i8, { 5, 6, 12, 14 } },
3921 { ISD::ROTR, MVT::v32i8, { 5, 14, 6, 9 } },
3922 { ISD::ROTR, MVT::v16i8, { 5, 14, 6, 9 } },
3923 { X86ISD::VROTLI, MVT::v32i16, { 2, 5, 3, 3 } },
3924 { X86ISD::VROTLI, MVT::v16i16, { 1, 5, 3, 3 } },
3925 { X86ISD::VROTLI, MVT::v8i16, { 1, 5, 3, 3 } },
3926 { X86ISD::VROTLI, MVT::v64i8, { 2, 9, 3, 4 } },
3927 { X86ISD::VROTLI, MVT::v32i8, { 1, 9, 3, 4 } },
3928 { X86ISD::VROTLI, MVT::v16i8, { 1, 8, 3, 4 } },
3929 { ISD::SADDSAT, MVT::v32i16, { 1, 1, 1, 1 } },
3930 { ISD::SADDSAT, MVT::v64i8, { 1, 1, 1, 1 } },
3931 { ISD::SMAX, MVT::v32i16, { 1, 1, 1, 1 } },
3932 { ISD::SMAX, MVT::v64i8, { 1, 1, 1, 1 } },
3933 { ISD::SMIN, MVT::v32i16, { 1, 1, 1, 1 } },
3934 { ISD::SMIN, MVT::v64i8, { 1, 1, 1, 1 } },
3935 { ISD::SMULO, MVT::v32i16, { 3, 6, 4, 4 } },
3936 { ISD::SMULO, MVT::v64i8, { 8, 21, 17, 18 } },
3937 { ISD::UMULO, MVT::v32i16, { 2, 5, 3, 3 } },
3938 { ISD::UMULO, MVT::v64i8, { 8, 15, 15, 16 } },
3939 { ISD::SSUBSAT, MVT::v32i16, { 1, 1, 1, 1 } },
3940 { ISD::SSUBSAT, MVT::v64i8, { 1, 1, 1, 1 } },
3941 { ISD::UADDSAT, MVT::v32i16, { 1, 1, 1, 1 } },
3942 { ISD::UADDSAT, MVT::v64i8, { 1, 1, 1, 1 } },
3943 { ISD::UMAX, MVT::v32i16, { 1, 1, 1, 1 } },
3944 { ISD::UMAX, MVT::v64i8, { 1, 1, 1, 1 } },
3945 { ISD::UMIN, MVT::v32i16, { 1, 1, 1, 1 } },
3946 { ISD::UMIN, MVT::v64i8, { 1, 1, 1, 1 } },
3947 { ISD::USUBSAT, MVT::v32i16, { 1, 1, 1, 1 } },
3948 { ISD::USUBSAT, MVT::v64i8, { 1, 1, 1, 1 } },
3949 };
3950 static const CostKindTblEntry AVX512CostTbl[] = {
3951 { ISD::ABS, MVT::v8i64, { 1, 1, 1, 1 } },
3952 { ISD::ABS, MVT::v4i64, { 1, 1, 1, 1 } },
3953 { ISD::ABS, MVT::v2i64, { 1, 1, 1, 1 } },
3954 { ISD::ABS, MVT::v16i32, { 1, 1, 1, 1 } },
3955 { ISD::ABS, MVT::v8i32, { 1, 1, 1, 1 } },
3956 { ISD::ABS, MVT::v32i16, { 2, 7, 4, 4 } },
3957 { ISD::ABS, MVT::v16i16, { 1, 1, 1, 1 } },
3958 { ISD::ABS, MVT::v64i8, { 2, 7, 4, 4 } },
3959 { ISD::ABS, MVT::v32i8, { 1, 1, 1, 1 } },
3960 { ISD::BITREVERSE, MVT::v8i64, { 9, 13, 20, 20 } },
3961 { ISD::BITREVERSE, MVT::v16i32, { 9, 13, 20, 20 } },
3962 { ISD::BITREVERSE, MVT::v32i16, { 9, 13, 20, 20 } },
3963 { ISD::BITREVERSE, MVT::v64i8, { 6, 11, 17, 17 } },
3964 { ISD::BSWAP, MVT::v8i64, { 4, 7, 5, 5 } },
3965 { ISD::BSWAP, MVT::v16i32, { 4, 7, 5, 5 } },
3966 { ISD::BSWAP, MVT::v32i16, { 4, 7, 5, 5 } },
3967 { ISD::CTLZ, MVT::v8i64, { 10, 28, 32, 32 } },
3968 { ISD::CTLZ, MVT::v16i32, { 12, 30, 38, 38 } },
3969 { ISD::CTLZ, MVT::v32i16, { 8, 15, 29, 29 } },
3970 { ISD::CTLZ, MVT::v64i8, { 6, 11, 19, 19 } },
3971 { ISD::CTPOP, MVT::v8i64, { 16, 16, 19, 19 } },
3972 { ISD::CTPOP, MVT::v16i32, { 24, 19, 27, 27 } },
3973 { ISD::CTPOP, MVT::v32i16, { 18, 15, 22, 22 } },
3974 { ISD::CTPOP, MVT::v64i8, { 12, 11, 16, 16 } },
3975 { ISD::CTTZ, MVT::v8i64, { 2, 8, 6, 7 } },
3976 { ISD::CTTZ, MVT::v16i32, { 2, 8, 6, 7 } },
3977 { ISD::CTTZ, MVT::v32i16, { 7, 17, 27, 27 } },
3978 { ISD::CTTZ, MVT::v64i8, { 6, 13, 21, 21 } },
3979 { ISD::ROTL, MVT::v8i64, { 1, 1, 1, 1 } },
3980 { ISD::ROTL, MVT::v4i64, { 1, 1, 1, 1 } },
3981 { ISD::ROTL, MVT::v2i64, { 1, 1, 1, 1 } },
3982 { ISD::ROTL, MVT::v16i32, { 1, 1, 1, 1 } },
3983 { ISD::ROTL, MVT::v8i32, { 1, 1, 1, 1 } },
3984 { ISD::ROTL, MVT::v4i32, { 1, 1, 1, 1 } },
3985 { ISD::ROTR, MVT::v8i64, { 1, 1, 1, 1 } },
3986 { ISD::ROTR, MVT::v4i64, { 1, 1, 1, 1 } },
3987 { ISD::ROTR, MVT::v2i64, { 1, 1, 1, 1 } },
3988 { ISD::ROTR, MVT::v16i32, { 1, 1, 1, 1 } },
3989 { ISD::ROTR, MVT::v8i32, { 1, 1, 1, 1 } },
3990 { ISD::ROTR, MVT::v4i32, { 1, 1, 1, 1 } },
3991 { X86ISD::VROTLI, MVT::v8i64, { 1, 1, 1, 1 } },
3992 { X86ISD::VROTLI, MVT::v4i64, { 1, 1, 1, 1 } },
3993 { X86ISD::VROTLI, MVT::v2i64, { 1, 1, 1, 1 } },
3994 { X86ISD::VROTLI, MVT::v16i32, { 1, 1, 1, 1 } },
3995 { X86ISD::VROTLI, MVT::v8i32, { 1, 1, 1, 1 } },
3996 { X86ISD::VROTLI, MVT::v4i32, { 1, 1, 1, 1 } },
3997 { ISD::SADDSAT, MVT::v2i64, { 3, 3, 8, 9 } },
3998 { ISD::SADDSAT, MVT::v4i64, { 2, 2, 6, 7 } },
3999 { ISD::SADDSAT, MVT::v8i64, { 3, 3, 6, 7 } },
4000 { ISD::SADDSAT, MVT::v4i32, { 2, 2, 6, 7 } },
4001 { ISD::SADDSAT, MVT::v8i32, { 2, 2, 6, 7 } },
4002 { ISD::SADDSAT, MVT::v16i32, { 3, 3, 6, 7 } },
4003 { ISD::SADDSAT, MVT::v32i16, { 2, 2, 2, 2 } },
4004 { ISD::SADDSAT, MVT::v64i8, { 2, 2, 2, 2 } },
4005 { ISD::SMAX, MVT::v8i64, { 1, 3, 1, 1 } },
4006 { ISD::SMAX, MVT::v16i32, { 1, 1, 1, 1 } },
4007 { ISD::SMAX, MVT::v32i16, { 3, 7, 5, 5 } },
4008 { ISD::SMAX, MVT::v64i8, { 3, 7, 5, 5 } },
4009 { ISD::SMAX, MVT::v4i64, { 1, 3, 1, 1 } },
4010 { ISD::SMAX, MVT::v2i64, { 1, 3, 1, 1 } },
4011 { ISD::SMIN, MVT::v8i64, { 1, 3, 1, 1 } },
4012 { ISD::SMIN, MVT::v16i32, { 1, 1, 1, 1 } },
4013 { ISD::SMIN, MVT::v32i16, { 3, 7, 5, 5 } },
4014 { ISD::SMIN, MVT::v64i8, { 3, 7, 5, 5 } },
4015 { ISD::SMIN, MVT::v4i64, { 1, 3, 1, 1 } },
4016 { ISD::SMIN, MVT::v2i64, { 1, 3, 1, 1 } },
4017 { ISD::SMULO, MVT::v8i64, { 44, 44, 81, 93 } },
4018 { ISD::SMULO, MVT::v16i32, { 5, 12, 9, 11 } },
4019 { ISD::SMULO, MVT::v32i16, { 6, 12, 17, 17 } },
4020 { ISD::SMULO, MVT::v64i8, { 22, 28, 42, 42 } },
4021 { ISD::SSUBSAT, MVT::v2i64, { 2, 13, 9, 10 } },
4022 { ISD::SSUBSAT, MVT::v4i64, { 2, 15, 7, 8 } },
4023 { ISD::SSUBSAT, MVT::v8i64, { 2, 14, 7, 8 } },
4024 { ISD::SSUBSAT, MVT::v4i32, { 2, 14, 7, 8 } },
4025 { ISD::SSUBSAT, MVT::v8i32, { 2, 15, 7, 8 } },
4026 { ISD::SSUBSAT, MVT::v16i32, { 2, 14, 7, 8 } },
4027 { ISD::SSUBSAT, MVT::v32i16, { 2, 2, 2, 2 } },
4028 { ISD::SSUBSAT, MVT::v64i8, { 2, 2, 2, 2 } },
4029 { ISD::UMAX, MVT::v8i64, { 1, 3, 1, 1 } },
4030 { ISD::UMAX, MVT::v16i32, { 1, 1, 1, 1 } },
4031 { ISD::UMAX, MVT::v32i16, { 3, 7, 5, 5 } },
4032 { ISD::UMAX, MVT::v64i8, { 3, 7, 5, 5 } },
4033 { ISD::UMAX, MVT::v4i64, { 1, 3, 1, 1 } },
4034 { ISD::UMAX, MVT::v2i64, { 1, 3, 1, 1 } },
4035 { ISD::UMIN, MVT::v8i64, { 1, 3, 1, 1 } },
4036 { ISD::UMIN, MVT::v16i32, { 1, 1, 1, 1 } },
4037 { ISD::UMIN, MVT::v32i16, { 3, 7, 5, 5 } },
4038 { ISD::UMIN, MVT::v64i8, { 3, 7, 5, 5 } },
4039 { ISD::UMIN, MVT::v4i64, { 1, 3, 1, 1 } },
4040 { ISD::UMIN, MVT::v2i64, { 1, 3, 1, 1 } },
4041 { ISD::UMULO, MVT::v8i64, { 52, 52, 95, 104} },
4042 { ISD::UMULO, MVT::v16i32, { 5, 12, 8, 10 } },
4043 { ISD::UMULO, MVT::v32i16, { 5, 13, 16, 16 } },
4044 { ISD::UMULO, MVT::v64i8, { 18, 24, 30, 30 } },
4045 { ISD::UADDSAT, MVT::v2i64, { 1, 4, 4, 4 } },
4046 { ISD::UADDSAT, MVT::v4i64, { 1, 4, 4, 4 } },
4047 { ISD::UADDSAT, MVT::v8i64, { 1, 4, 4, 4 } },
4048 { ISD::UADDSAT, MVT::v4i32, { 1, 2, 4, 4 } },
4049 { ISD::UADDSAT, MVT::v8i32, { 1, 2, 4, 4 } },
4050 { ISD::UADDSAT, MVT::v16i32, { 2, 2, 4, 4 } },
4051 { ISD::UADDSAT, MVT::v32i16, { 2, 2, 2, 2 } },
4052 { ISD::UADDSAT, MVT::v64i8, { 2, 2, 2, 2 } },
4053 { ISD::USUBSAT, MVT::v2i64, { 1, 4, 2, 2 } },
4054 { ISD::USUBSAT, MVT::v4i64, { 1, 4, 2, 2 } },
4055 { ISD::USUBSAT, MVT::v8i64, { 1, 4, 2, 2 } },
4056 { ISD::USUBSAT, MVT::v8i32, { 1, 2, 2, 2 } },
4057 { ISD::USUBSAT, MVT::v16i32, { 1, 2, 2, 2 } },
4058 { ISD::USUBSAT, MVT::v32i16, { 2, 2, 2, 2 } },
4059 { ISD::USUBSAT, MVT::v64i8, { 2, 2, 2, 2 } },
4060 { ISD::FMAXNUM, MVT::f32, { 2, 2, 3, 3 } },
4061 { ISD::FMAXNUM, MVT::v4f32, { 1, 1, 3, 3 } },
4062 { ISD::FMAXNUM, MVT::v8f32, { 2, 2, 3, 3 } },
4063 { ISD::FMAXNUM, MVT::v16f32, { 4, 4, 3, 3 } },
4064 { ISD::FMAXNUM, MVT::f64, { 2, 2, 3, 3 } },
4065 { ISD::FMAXNUM, MVT::v2f64, { 1, 1, 3, 3 } },
4066 { ISD::FMAXNUM, MVT::v4f64, { 2, 2, 3, 3 } },
4067 { ISD::FMAXNUM, MVT::v8f64, { 3, 3, 3, 3 } },
4068 { ISD::FSQRT, MVT::f32, { 3, 12, 1, 1 } }, // Skylake from http://www.agner.org/
4069 { ISD::FSQRT, MVT::v4f32, { 3, 12, 1, 1 } }, // Skylake from http://www.agner.org/
4070 { ISD::FSQRT, MVT::v8f32, { 6, 12, 1, 1 } }, // Skylake from http://www.agner.org/
4071 { ISD::FSQRT, MVT::v16f32, { 12, 20, 1, 3 } }, // Skylake from http://www.agner.org/
4072 { ISD::FSQRT, MVT::f64, { 6, 18, 1, 1 } }, // Skylake from http://www.agner.org/
4073 { ISD::FSQRT, MVT::v2f64, { 6, 18, 1, 1 } }, // Skylake from http://www.agner.org/
4074 { ISD::FSQRT, MVT::v4f64, { 12, 18, 1, 1 } }, // Skylake from http://www.agner.org/
4075 { ISD::FSQRT, MVT::v8f64, { 24, 32, 1, 3 } }, // Skylake from http://www.agner.org/
4076 };
4077 static const CostKindTblEntry XOPCostTbl[] = {
4078 { ISD::BITREVERSE, MVT::v4i64, { 3, 6, 5, 6 } },
4079 { ISD::BITREVERSE, MVT::v8i32, { 3, 6, 5, 6 } },
4080 { ISD::BITREVERSE, MVT::v16i16, { 3, 6, 5, 6 } },
4081 { ISD::BITREVERSE, MVT::v32i8, { 3, 6, 5, 6 } },
4082 { ISD::BITREVERSE, MVT::v2i64, { 2, 7, 1, 1 } },
4083 { ISD::BITREVERSE, MVT::v4i32, { 2, 7, 1, 1 } },
4084 { ISD::BITREVERSE, MVT::v8i16, { 2, 7, 1, 1 } },
4085 { ISD::BITREVERSE, MVT::v16i8, { 2, 7, 1, 1 } },
4086 { ISD::BITREVERSE, MVT::i64, { 2, 2, 3, 4 } },
4087 { ISD::BITREVERSE, MVT::i32, { 2, 2, 3, 4 } },
4088 { ISD::BITREVERSE, MVT::i16, { 2, 2, 3, 4 } },
4089 { ISD::BITREVERSE, MVT::i8, { 2, 2, 3, 4 } },
4090 // XOP: ROTL = VPROT(X,Y), ROTR = VPROT(X,SUB(0,Y))
4091 { ISD::ROTL, MVT::v4i64, { 4, 7, 5, 6 } },
4092 { ISD::ROTL, MVT::v8i32, { 4, 7, 5, 6 } },
4093 { ISD::ROTL, MVT::v16i16, { 4, 7, 5, 6 } },
4094 { ISD::ROTL, MVT::v32i8, { 4, 7, 5, 6 } },
4095 { ISD::ROTL, MVT::v2i64, { 1, 3, 1, 1 } },
4096 { ISD::ROTL, MVT::v4i32, { 1, 3, 1, 1 } },
4097 { ISD::ROTL, MVT::v8i16, { 1, 3, 1, 1 } },
4098 { ISD::ROTL, MVT::v16i8, { 1, 3, 1, 1 } },
4099 { ISD::ROTR, MVT::v4i64, { 4, 7, 8, 9 } },
4100 { ISD::ROTR, MVT::v8i32, { 4, 7, 8, 9 } },
4101 { ISD::ROTR, MVT::v16i16, { 4, 7, 8, 9 } },
4102 { ISD::ROTR, MVT::v32i8, { 4, 7, 8, 9 } },
4103 { ISD::ROTR, MVT::v2i64, { 1, 3, 3, 3 } },
4104 { ISD::ROTR, MVT::v4i32, { 1, 3, 3, 3 } },
4105 { ISD::ROTR, MVT::v8i16, { 1, 3, 3, 3 } },
4106 { ISD::ROTR, MVT::v16i8, { 1, 3, 3, 3 } },
4107 { X86ISD::VROTLI, MVT::v4i64, { 4, 7, 5, 6 } },
4108 { X86ISD::VROTLI, MVT::v8i32, { 4, 7, 5, 6 } },
4109 { X86ISD::VROTLI, MVT::v16i16, { 4, 7, 5, 6 } },
4110 { X86ISD::VROTLI, MVT::v32i8, { 4, 7, 5, 6 } },
4111 { X86ISD::VROTLI, MVT::v2i64, { 1, 3, 1, 1 } },
4112 { X86ISD::VROTLI, MVT::v4i32, { 1, 3, 1, 1 } },
4113 { X86ISD::VROTLI, MVT::v8i16, { 1, 3, 1, 1 } },
4114 { X86ISD::VROTLI, MVT::v16i8, { 1, 3, 1, 1 } },
4115 };
4116 static const CostKindTblEntry AVX2CostTbl[] = {
4117 { ISD::ABS, MVT::v2i64, { 2, 4, 3, 5 } }, // VBLENDVPD(X,VPSUBQ(0,X),X)
4118 { ISD::ABS, MVT::v4i64, { 2, 4, 3, 5 } }, // VBLENDVPD(X,VPSUBQ(0,X),X)
4119 { ISD::ABS, MVT::v4i32, { 1, 1, 1, 1 } },
4120 { ISD::ABS, MVT::v8i32, { 1, 1, 1, 2 } },
4121 { ISD::ABS, MVT::v8i16, { 1, 1, 1, 1 } },
4122 { ISD::ABS, MVT::v16i16, { 1, 1, 1, 2 } },
4123 { ISD::ABS, MVT::v16i8, { 1, 1, 1, 1 } },
4124 { ISD::ABS, MVT::v32i8, { 1, 1, 1, 2 } },
4125 { ISD::BITREVERSE, MVT::v2i64, { 3, 11, 10, 11 } },
4126 { ISD::BITREVERSE, MVT::v4i64, { 5, 11, 10, 17 } },
4127 { ISD::BITREVERSE, MVT::v4i32, { 3, 11, 10, 11 } },
4128 { ISD::BITREVERSE, MVT::v8i32, { 5, 11, 10, 17 } },
4129 { ISD::BITREVERSE, MVT::v8i16, { 3, 11, 10, 11 } },
4130 { ISD::BITREVERSE, MVT::v16i16, { 5, 11, 10, 17 } },
4131 { ISD::BITREVERSE, MVT::v16i8, { 3, 6, 9, 9 } },
4132 { ISD::BITREVERSE, MVT::v32i8, { 4, 5, 9, 15 } },
4133 { ISD::BSWAP, MVT::v2i64, { 1, 2, 1, 2 } },
4134 { ISD::BSWAP, MVT::v4i64, { 1, 3, 1, 2 } },
4135 { ISD::BSWAP, MVT::v4i32, { 1, 2, 1, 2 } },
4136 { ISD::BSWAP, MVT::v8i32, { 1, 3, 1, 2 } },
4137 { ISD::BSWAP, MVT::v8i16, { 1, 2, 1, 2 } },
4138 { ISD::BSWAP, MVT::v16i16, { 1, 3, 1, 2 } },
4139 { ISD::CTLZ, MVT::v2i64, { 7, 18, 24, 25 } },
4140 { ISD::CTLZ, MVT::v4i64, { 14, 18, 24, 44 } },
4141 { ISD::CTLZ, MVT::v4i32, { 5, 16, 19, 20 } },
4142 { ISD::CTLZ, MVT::v8i32, { 10, 16, 19, 34 } },
4143 { ISD::CTLZ, MVT::v8i16, { 4, 13, 14, 15 } },
4144 { ISD::CTLZ, MVT::v16i16, { 6, 14, 14, 24 } },
4145 { ISD::CTLZ, MVT::v16i8, { 3, 12, 9, 10 } },
4146 { ISD::CTLZ, MVT::v32i8, { 4, 12, 9, 14 } },
4147 { ISD::CTPOP, MVT::v2i64, { 3, 9, 10, 10 } },
4148 { ISD::CTPOP, MVT::v4i64, { 4, 9, 10, 14 } },
4149 { ISD::CTPOP, MVT::v4i32, { 7, 12, 14, 14 } },
4150 { ISD::CTPOP, MVT::v8i32, { 7, 12, 14, 18 } },
4151 { ISD::CTPOP, MVT::v8i16, { 3, 7, 11, 11 } },
4152 { ISD::CTPOP, MVT::v16i16, { 6, 8, 11, 18 } },
4153 { ISD::CTPOP, MVT::v16i8, { 2, 5, 8, 8 } },
4154 { ISD::CTPOP, MVT::v32i8, { 3, 5, 8, 12 } },
4155 { ISD::CTTZ, MVT::v2i64, { 4, 11, 13, 13 } },
4156 { ISD::CTTZ, MVT::v4i64, { 5, 11, 13, 20 } },
4157 { ISD::CTTZ, MVT::v4i32, { 7, 14, 17, 17 } },
4158 { ISD::CTTZ, MVT::v8i32, { 7, 15, 17, 24 } },
4159 { ISD::CTTZ, MVT::v8i16, { 4, 9, 14, 14 } },
4160 { ISD::CTTZ, MVT::v16i16, { 6, 9, 14, 24 } },
4161 { ISD::CTTZ, MVT::v16i8, { 3, 7, 11, 11 } },
4162 { ISD::CTTZ, MVT::v32i8, { 5, 7, 11, 18 } },
4163 { ISD::SADDSAT, MVT::v2i64, { 4, 13, 8, 11 } },
4164 { ISD::SADDSAT, MVT::v4i64, { 3, 10, 8, 12 } },
4165 { ISD::SADDSAT, MVT::v4i32, { 2, 6, 7, 9 } },
4166 { ISD::SADDSAT, MVT::v8i32, { 4, 6, 7, 13 } },
4167 { ISD::SADDSAT, MVT::v16i16, { 1, 1, 1, 2 } },
4168 { ISD::SADDSAT, MVT::v32i8, { 1, 1, 1, 2 } },
4169 { ISD::SMAX, MVT::v2i64, { 2, 7, 2, 3 } },
4170 { ISD::SMAX, MVT::v4i64, { 2, 7, 2, 3 } },
4171 { ISD::SMAX, MVT::v8i32, { 1, 1, 1, 2 } },
4172 { ISD::SMAX, MVT::v16i16, { 1, 1, 1, 2 } },
4173 { ISD::SMAX, MVT::v32i8, { 1, 1, 1, 2 } },
4174 { ISD::SMIN, MVT::v2i64, { 2, 7, 2, 3 } },
4175 { ISD::SMIN, MVT::v4i64, { 2, 7, 2, 3 } },
4176 { ISD::SMIN, MVT::v8i32, { 1, 1, 1, 2 } },
4177 { ISD::SMIN, MVT::v16i16, { 1, 1, 1, 2 } },
4178 { ISD::SMIN, MVT::v32i8, { 1, 1, 1, 2 } },
4179 { ISD::SMULO, MVT::v4i64, { 20, 20, 33, 37 } },
4180 { ISD::SMULO, MVT::v2i64, { 8, 8, 13, 15 } },
4181 { ISD::SMULO, MVT::v8i32, { 8, 20, 13, 24 } },
4182 { ISD::SMULO, MVT::v4i32, { 5, 15, 11, 12 } },
4183 { ISD::SMULO, MVT::v16i16, { 4, 14, 8, 14 } },
4184 { ISD::SMULO, MVT::v8i16, { 3, 9, 6, 6 } },
4185 { ISD::SMULO, MVT::v32i8, { 9, 15, 18, 35 } },
4186 { ISD::SMULO, MVT::v16i8, { 6, 22, 14, 21 } },
4187 { ISD::SSUBSAT, MVT::v2i64, { 4, 13, 9, 13 } },
4188 { ISD::SSUBSAT, MVT::v4i64, { 4, 15, 9, 13 } },
4189 { ISD::SSUBSAT, MVT::v4i32, { 3, 14, 9, 11 } },
4190 { ISD::SSUBSAT, MVT::v8i32, { 4, 15, 9, 16 } },
4191 { ISD::SSUBSAT, MVT::v16i16, { 1, 1, 1, 2 } },
4192 { ISD::SSUBSAT, MVT::v32i8, { 1, 1, 1, 2 } },
4193 { ISD::UADDSAT, MVT::v2i64, { 2, 8, 6, 6 } },
4194 { ISD::UADDSAT, MVT::v4i64, { 3, 8, 6, 10 } },
4195 { ISD::UADDSAT, MVT::v8i32, { 2, 2, 4, 8 } },
4196 { ISD::UADDSAT, MVT::v16i16, { 1, 1, 1, 2 } },
4197 { ISD::UADDSAT, MVT::v32i8, { 1, 1, 1, 2 } },
4198 { ISD::UMAX, MVT::v2i64, { 2, 8, 5, 6 } },
4199 { ISD::UMAX, MVT::v4i64, { 2, 8, 5, 8 } },
4200 { ISD::UMAX, MVT::v8i32, { 1, 1, 1, 2 } },
4201 { ISD::UMAX, MVT::v16i16, { 1, 1, 1, 2 } },
4202 { ISD::UMAX, MVT::v32i8, { 1, 1, 1, 2 } },
4203 { ISD::UMIN, MVT::v2i64, { 2, 8, 5, 6 } },
4204 { ISD::UMIN, MVT::v4i64, { 2, 8, 5, 8 } },
4205 { ISD::UMIN, MVT::v8i32, { 1, 1, 1, 2 } },
4206 { ISD::UMIN, MVT::v16i16, { 1, 1, 1, 2 } },
4207 { ISD::UMIN, MVT::v32i8, { 1, 1, 1, 2 } },
4208 { ISD::UMULO, MVT::v4i64, { 24, 24, 39, 43 } },
4209 { ISD::UMULO, MVT::v2i64, { 10, 10, 15, 19 } },
4210 { ISD::UMULO, MVT::v8i32, { 8, 11, 13, 23 } },
4211 { ISD::UMULO, MVT::v4i32, { 5, 12, 11, 12 } },
4212 { ISD::UMULO, MVT::v16i16, { 4, 6, 8, 13 } },
4213 { ISD::UMULO, MVT::v8i16, { 2, 8, 6, 6 } },
4214 { ISD::UMULO, MVT::v32i8, { 9, 13, 17, 33 } },
4215 { ISD::UMULO, MVT::v16i8, { 6, 19, 13, 20 } },
4216 { ISD::USUBSAT, MVT::v2i64, { 2, 7, 6, 6 } },
4217 { ISD::USUBSAT, MVT::v4i64, { 3, 7, 6, 10 } },
4218 { ISD::USUBSAT, MVT::v8i32, { 2, 2, 2, 4 } },
4219 { ISD::USUBSAT, MVT::v16i16, { 1, 1, 1, 2 } },
4220 { ISD::USUBSAT, MVT::v32i8, { 1, 1, 1, 2 } },
4221 { ISD::FMAXNUM, MVT::f32, { 2, 7, 3, 5 } }, // MAXSS + CMPUNORDSS + BLENDVPS
4222 { ISD::FMAXNUM, MVT::v4f32, { 2, 7, 3, 5 } }, // MAXPS + CMPUNORDPS + BLENDVPS
4223 { ISD::FMAXNUM, MVT::v8f32, { 3, 7, 3, 6 } }, // MAXPS + CMPUNORDPS + BLENDVPS
4224 { ISD::FMAXNUM, MVT::f64, { 2, 7, 3, 5 } }, // MAXSD + CMPUNORDSD + BLENDVPD
4225 { ISD::FMAXNUM, MVT::v2f64, { 2, 7, 3, 5 } }, // MAXPD + CMPUNORDPD + BLENDVPD
4226 { ISD::FMAXNUM, MVT::v4f64, { 3, 7, 3, 6 } }, // MAXPD + CMPUNORDPD + BLENDVPD
4227 { ISD::FSQRT, MVT::f32, { 7, 15, 1, 1 } }, // vsqrtss
4228 { ISD::FSQRT, MVT::v4f32, { 7, 15, 1, 1 } }, // vsqrtps
4229 { ISD::FSQRT, MVT::v8f32, { 14, 21, 1, 3 } }, // vsqrtps
4230 { ISD::FSQRT, MVT::f64, { 14, 21, 1, 1 } }, // vsqrtsd
4231 { ISD::FSQRT, MVT::v2f64, { 14, 21, 1, 1 } }, // vsqrtpd
4232 { ISD::FSQRT, MVT::v4f64, { 28, 35, 1, 3 } }, // vsqrtpd
4233 };
4234 static const CostKindTblEntry AVX1CostTbl[] = {
4235 { ISD::ABS, MVT::v4i64, { 6, 8, 6, 12 } }, // VBLENDVPD(X,VPSUBQ(0,X),X)
4236 { ISD::ABS, MVT::v8i32, { 3, 6, 4, 5 } },
4237 { ISD::ABS, MVT::v16i16, { 3, 6, 4, 5 } },
4238 { ISD::ABS, MVT::v32i8, { 3, 6, 4, 5 } },
4239 { ISD::BITREVERSE, MVT::v4i64, { 17, 20, 20, 33 } }, // 2 x 128-bit Op + extract/insert
4240 { ISD::BITREVERSE, MVT::v2i64, { 8, 13, 10, 16 } },
4241 { ISD::BITREVERSE, MVT::v8i32, { 17, 20, 20, 33 } }, // 2 x 128-bit Op + extract/insert
4242 { ISD::BITREVERSE, MVT::v4i32, { 8, 13, 10, 16 } },
4243 { ISD::BITREVERSE, MVT::v16i16, { 17, 20, 20, 33 } }, // 2 x 128-bit Op + extract/insert
4244 { ISD::BITREVERSE, MVT::v8i16, { 8, 13, 10, 16 } },
4245 { ISD::BITREVERSE, MVT::v32i8, { 13, 15, 17, 26 } }, // 2 x 128-bit Op + extract/insert
4246 { ISD::BITREVERSE, MVT::v16i8, { 7, 7, 9, 13 } },
4247 { ISD::BSWAP, MVT::v4i64, { 5, 6, 5, 10 } },
4248 { ISD::BSWAP, MVT::v2i64, { 2, 2, 1, 3 } },
4249 { ISD::BSWAP, MVT::v8i32, { 5, 6, 5, 10 } },
4250 { ISD::BSWAP, MVT::v4i32, { 2, 2, 1, 3 } },
4251 { ISD::BSWAP, MVT::v16i16, { 5, 6, 5, 10 } },
4252 { ISD::BSWAP, MVT::v8i16, { 2, 2, 1, 3 } },
4253 { ISD::CTLZ, MVT::v4i64, { 29, 33, 49, 58 } }, // 2 x 128-bit Op + extract/insert
4254 { ISD::CTLZ, MVT::v2i64, { 14, 24, 24, 28 } },
4255 { ISD::CTLZ, MVT::v8i32, { 24, 28, 39, 48 } }, // 2 x 128-bit Op + extract/insert
4256 { ISD::CTLZ, MVT::v4i32, { 12, 20, 19, 23 } },
4257 { ISD::CTLZ, MVT::v16i16, { 19, 22, 29, 38 } }, // 2 x 128-bit Op + extract/insert
4258 { ISD::CTLZ, MVT::v8i16, { 9, 16, 14, 18 } },
4259 { ISD::CTLZ, MVT::v32i8, { 14, 15, 19, 28 } }, // 2 x 128-bit Op + extract/insert
4260 { ISD::CTLZ, MVT::v16i8, { 7, 12, 9, 13 } },
4261 { ISD::CTPOP, MVT::v4i64, { 14, 18, 19, 28 } }, // 2 x 128-bit Op + extract/insert
4262 { ISD::CTPOP, MVT::v2i64, { 7, 14, 10, 14 } },
4263 { ISD::CTPOP, MVT::v8i32, { 18, 24, 27, 36 } }, // 2 x 128-bit Op + extract/insert
4264 { ISD::CTPOP, MVT::v4i32, { 9, 20, 14, 18 } },
4265 { ISD::CTPOP, MVT::v16i16, { 16, 21, 22, 31 } }, // 2 x 128-bit Op + extract/insert
4266 { ISD::CTPOP, MVT::v8i16, { 8, 18, 11, 15 } },
4267 { ISD::CTPOP, MVT::v32i8, { 13, 15, 16, 25 } }, // 2 x 128-bit Op + extract/insert
4268 { ISD::CTPOP, MVT::v16i8, { 6, 12, 8, 12 } },
4269 { ISD::CTTZ, MVT::v4i64, { 17, 22, 24, 33 } }, // 2 x 128-bit Op + extract/insert
4270 { ISD::CTTZ, MVT::v2i64, { 9, 19, 13, 17 } },
4271 { ISD::CTTZ, MVT::v8i32, { 21, 27, 32, 41 } }, // 2 x 128-bit Op + extract/insert
4272 { ISD::CTTZ, MVT::v4i32, { 11, 24, 17, 21 } },
4273 { ISD::CTTZ, MVT::v16i16, { 18, 24, 27, 36 } }, // 2 x 128-bit Op + extract/insert
4274 { ISD::CTTZ, MVT::v8i16, { 9, 21, 14, 18 } },
4275 { ISD::CTTZ, MVT::v32i8, { 15, 18, 21, 30 } }, // 2 x 128-bit Op + extract/insert
4276 { ISD::CTTZ, MVT::v16i8, { 8, 16, 11, 15 } },
4277 { ISD::SADDSAT, MVT::v2i64, { 6, 13, 8, 11 } },
4278 { ISD::SADDSAT, MVT::v4i64, { 13, 20, 15, 25 } }, // 2 x 128-bit Op + extract/insert
4279 { ISD::SADDSAT, MVT::v8i32, { 12, 18, 14, 24 } }, // 2 x 128-bit Op + extract/insert
4280 { ISD::SADDSAT, MVT::v16i16, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4281 { ISD::SADDSAT, MVT::v32i8, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4282 { ISD::SMAX, MVT::v4i64, { 6, 9, 6, 12 } }, // 2 x 128-bit Op + extract/insert
4283 { ISD::SMAX, MVT::v2i64, { 3, 7, 2, 4 } },
4284 { ISD::SMAX, MVT::v8i32, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4285 { ISD::SMAX, MVT::v16i16, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4286 { ISD::SMAX, MVT::v32i8, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4287 { ISD::SMIN, MVT::v4i64, { 6, 9, 6, 12 } }, // 2 x 128-bit Op + extract/insert
4288 { ISD::SMIN, MVT::v2i64, { 3, 7, 2, 3 } },
4289 { ISD::SMIN, MVT::v8i32, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4290 { ISD::SMIN, MVT::v16i16, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4291 { ISD::SMIN, MVT::v32i8, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4292 { ISD::SMULO, MVT::v4i64, { 20, 20, 33, 37 } },
4293 { ISD::SMULO, MVT::v2i64, { 9, 9, 13, 17 } },
4294 { ISD::SMULO, MVT::v8i32, { 15, 20, 24, 29 } },
4295 { ISD::SMULO, MVT::v4i32, { 7, 15, 11, 13 } },
4296 { ISD::SMULO, MVT::v16i16, { 8, 14, 14, 15 } },
4297 { ISD::SMULO, MVT::v8i16, { 3, 9, 6, 6 } },
4298 { ISD::SMULO, MVT::v32i8, { 20, 20, 37, 39 } },
4299 { ISD::SMULO, MVT::v16i8, { 9, 22, 18, 21 } },
4300 { ISD::SSUBSAT, MVT::v2i64, { 7, 13, 9, 13 } },
4301 { ISD::SSUBSAT, MVT::v4i64, { 15, 21, 18, 29 } }, // 2 x 128-bit Op + extract/insert
4302 { ISD::SSUBSAT, MVT::v8i32, { 15, 19, 18, 29 } }, // 2 x 128-bit Op + extract/insert
4303 { ISD::SSUBSAT, MVT::v16i16, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4304 { ISD::SSUBSAT, MVT::v32i8, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4305 { ISD::UADDSAT, MVT::v2i64, { 3, 8, 6, 6 } },
4306 { ISD::UADDSAT, MVT::v4i64, { 8, 11, 14, 15 } }, // 2 x 128-bit Op + extract/insert
4307 { ISD::UADDSAT, MVT::v8i32, { 6, 6, 10, 11 } }, // 2 x 128-bit Op + extract/insert
4308 { ISD::UADDSAT, MVT::v16i16, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4309 { ISD::UADDSAT, MVT::v32i8, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4310 { ISD::UMAX, MVT::v4i64, { 9, 10, 11, 17 } }, // 2 x 128-bit Op + extract/insert
4311 { ISD::UMAX, MVT::v2i64, { 4, 8, 5, 7 } },
4312 { ISD::UMAX, MVT::v8i32, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4313 { ISD::UMAX, MVT::v16i16, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4314 { ISD::UMAX, MVT::v32i8, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4315 { ISD::UMIN, MVT::v4i64, { 9, 10, 11, 17 } }, // 2 x 128-bit Op + extract/insert
4316 { ISD::UMIN, MVT::v2i64, { 4, 8, 5, 7 } },
4317 { ISD::UMIN, MVT::v8i32, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4318 { ISD::UMIN, MVT::v16i16, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4319 { ISD::UMIN, MVT::v32i8, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4320 { ISD::UMULO, MVT::v4i64, { 24, 26, 39, 45 } },
4321 { ISD::UMULO, MVT::v2i64, { 10, 12, 15, 20 } },
4322 { ISD::UMULO, MVT::v8i32, { 14, 15, 23, 28 } },
4323 { ISD::UMULO, MVT::v4i32, { 7, 12, 11, 13 } },
4324 { ISD::UMULO, MVT::v16i16, { 7, 11, 13, 14 } },
4325 { ISD::UMULO, MVT::v8i16, { 3, 8, 6, 6 } },
4326 { ISD::UMULO, MVT::v32i8, { 19, 19, 35, 37 } },
4327 { ISD::UMULO, MVT::v16i8, { 9, 19, 17, 20 } },
4328 { ISD::USUBSAT, MVT::v2i64, { 3, 7, 6, 6 } },
4329 { ISD::USUBSAT, MVT::v4i64, { 8, 10, 14, 15 } }, // 2 x 128-bit Op + extract/insert
4330 { ISD::USUBSAT, MVT::v8i32, { 4, 4, 7, 8 } }, // 2 x 128-bit Op + extract/insert
4331 { ISD::USUBSAT, MVT::v8i32, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4332 { ISD::USUBSAT, MVT::v16i16, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4333 { ISD::USUBSAT, MVT::v32i8, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4334 { ISD::FMAXNUM, MVT::f32, { 3, 6, 3, 5 } }, // MAXSS + CMPUNORDSS + BLENDVPS
4335 { ISD::FMAXNUM, MVT::v4f32, { 3, 6, 3, 5 } }, // MAXPS + CMPUNORDPS + BLENDVPS
4336 { ISD::FMAXNUM, MVT::v8f32, { 5, 7, 3, 10 } }, // MAXPS + CMPUNORDPS + BLENDVPS
4337 { ISD::FMAXNUM, MVT::f64, { 3, 6, 3, 5 } }, // MAXSD + CMPUNORDSD + BLENDVPD
4338 { ISD::FMAXNUM, MVT::v2f64, { 3, 6, 3, 5 } }, // MAXPD + CMPUNORDPD + BLENDVPD
4339 { ISD::FMAXNUM, MVT::v4f64, { 5, 7, 3, 10 } }, // MAXPD + CMPUNORDPD + BLENDVPD
4340 { ISD::FSQRT, MVT::f32, { 21, 21, 1, 1 } }, // vsqrtss
4341 { ISD::FSQRT, MVT::v4f32, { 21, 21, 1, 1 } }, // vsqrtps
4342 { ISD::FSQRT, MVT::v8f32, { 42, 42, 1, 3 } }, // vsqrtps
4343 { ISD::FSQRT, MVT::f64, { 27, 27, 1, 1 } }, // vsqrtsd
4344 { ISD::FSQRT, MVT::v2f64, { 27, 27, 1, 1 } }, // vsqrtpd
4345 { ISD::FSQRT, MVT::v4f64, { 54, 54, 1, 3 } }, // vsqrtpd
4346 };
4347 static const CostKindTblEntry GFNICostTbl[] = {
4348 { ISD::BITREVERSE, MVT::i8, { 3, 3, 3, 4 } }, // gf2p8affineqb
4349 { ISD::BITREVERSE, MVT::i16, { 3, 3, 4, 6 } }, // gf2p8affineqb
4350 { ISD::BITREVERSE, MVT::i32, { 3, 3, 4, 5 } }, // gf2p8affineqb
4351 { ISD::BITREVERSE, MVT::i64, { 3, 3, 4, 6 } }, // gf2p8affineqb
4352 { ISD::BITREVERSE, MVT::v16i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
4353 { ISD::BITREVERSE, MVT::v32i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
4354 { ISD::BITREVERSE, MVT::v64i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
4355 { ISD::BITREVERSE, MVT::v8i16, { 1, 8, 2, 4 } }, // gf2p8affineqb
4356 { ISD::BITREVERSE, MVT::v16i16, { 1, 9, 2, 4 } }, // gf2p8affineqb
4357 { ISD::BITREVERSE, MVT::v32i16, { 1, 9, 2, 4 } }, // gf2p8affineqb
4358 { ISD::BITREVERSE, MVT::v4i32, { 1, 8, 2, 4 } }, // gf2p8affineqb
4359 { ISD::BITREVERSE, MVT::v8i32, { 1, 9, 2, 4 } }, // gf2p8affineqb
4360 { ISD::BITREVERSE, MVT::v16i32, { 1, 9, 2, 4 } }, // gf2p8affineqb
4361 { ISD::BITREVERSE, MVT::v2i64, { 1, 8, 2, 4 } }, // gf2p8affineqb
4362 { ISD::BITREVERSE, MVT::v4i64, { 1, 9, 2, 4 } }, // gf2p8affineqb
4363 { ISD::BITREVERSE, MVT::v8i64, { 1, 9, 2, 4 } }, // gf2p8affineqb
4364 { X86ISD::VROTLI, MVT::v16i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
4365 { X86ISD::VROTLI, MVT::v32i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
4366 { X86ISD::VROTLI, MVT::v64i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
4367 };
4368 static const CostKindTblEntry GLMCostTbl[] = {
4369 { ISD::FSQRT, MVT::f32, { 19, 20, 1, 1 } }, // sqrtss
4370 { ISD::FSQRT, MVT::v4f32, { 37, 41, 1, 5 } }, // sqrtps
4371 { ISD::FSQRT, MVT::f64, { 34, 35, 1, 1 } }, // sqrtsd
4372 { ISD::FSQRT, MVT::v2f64, { 67, 71, 1, 5 } }, // sqrtpd
4373 };
4374 static const CostKindTblEntry SLMCostTbl[] = {
4375 { ISD::BSWAP, MVT::v2i64, { 5, 5, 1, 5 } },
4376 { ISD::BSWAP, MVT::v4i32, { 5, 5, 1, 5 } },
4377 { ISD::BSWAP, MVT::v8i16, { 5, 5, 1, 5 } },
4378 { ISD::FSQRT, MVT::f32, { 20, 20, 1, 1 } }, // sqrtss
4379 { ISD::FSQRT, MVT::v4f32, { 40, 41, 1, 5 } }, // sqrtps
4380 { ISD::FSQRT, MVT::f64, { 35, 35, 1, 1 } }, // sqrtsd
4381 { ISD::FSQRT, MVT::v2f64, { 70, 71, 1, 5 } }, // sqrtpd
4382 };
4383 static const CostKindTblEntry SSE42CostTbl[] = {
4384 { ISD::FMAXNUM, MVT::f32, { 5, 5, 7, 7 } }, // MAXSS + CMPUNORDSS + BLENDVPS
4385 { ISD::FMAXNUM, MVT::v4f32, { 4, 4, 4, 5 } }, // MAXPS + CMPUNORDPS + BLENDVPS
4386 { ISD::FMAXNUM, MVT::f64, { 5, 5, 7, 7 } }, // MAXSD + CMPUNORDSD + BLENDVPD
4387 { ISD::FMAXNUM, MVT::v2f64, { 4, 4, 4, 5 } }, // MAXPD + CMPUNORDPD + BLENDVPD
4388 { ISD::FSQRT, MVT::f32, { 18, 18, 1, 1 } }, // Nehalem from http://www.agner.org/
4389 { ISD::FSQRT, MVT::v4f32, { 18, 18, 1, 1 } }, // Nehalem from http://www.agner.org/
4390 };
4391 static const CostKindTblEntry SSE41CostTbl[] = {
4392 { ISD::ABS, MVT::v2i64, { 3, 4, 3, 5 } }, // BLENDVPD(X,PSUBQ(0,X),X)
4393 { ISD::SADDSAT, MVT::v2i64, { 10, 14, 17, 21 } },
4394 { ISD::SADDSAT, MVT::v4i32, { 5, 11, 8, 10 } },
4395 { ISD::SSUBSAT, MVT::v2i64, { 12, 19, 25, 29 } },
4396 { ISD::SSUBSAT, MVT::v4i32, { 6, 14, 10, 12 } },
4397 { ISD::SMAX, MVT::v2i64, { 3, 7, 2, 3 } },
4398 { ISD::SMAX, MVT::v4i32, { 1, 1, 1, 1 } },
4399 { ISD::SMAX, MVT::v16i8, { 1, 1, 1, 1 } },
4400 { ISD::SMIN, MVT::v2i64, { 3, 7, 2, 3 } },
4401 { ISD::SMIN, MVT::v4i32, { 1, 1, 1, 1 } },
4402 { ISD::SMIN, MVT::v16i8, { 1, 1, 1, 1 } },
4403 { ISD::SMULO, MVT::v2i64, { 9, 11, 13, 17 } },
4404 { ISD::SMULO, MVT::v4i32, { 20, 24, 13, 19 } },
4405 { ISD::SMULO, MVT::v8i16, { 5, 9, 8, 8 } },
4406 { ISD::SMULO, MVT::v16i8, { 13, 22, 24, 25 } },
4407 { ISD::UADDSAT, MVT::v2i64, { 6, 13, 14, 14 } },
4408 { ISD::UADDSAT, MVT::v4i32, { 2, 2, 4, 4 } },
4409 { ISD::USUBSAT, MVT::v2i64, { 6, 10, 14, 14 } },
4410 { ISD::USUBSAT, MVT::v4i32, { 1, 2, 2, 2 } },
4411 { ISD::UMAX, MVT::v2i64, { 2, 11, 6, 7 } },
4412 { ISD::UMAX, MVT::v4i32, { 1, 1, 1, 1 } },
4413 { ISD::UMAX, MVT::v8i16, { 1, 1, 1, 1 } },
4414 { ISD::UMIN, MVT::v2i64, { 2, 11, 6, 7 } },
4415 { ISD::UMIN, MVT::v4i32, { 1, 1, 1, 1 } },
4416 { ISD::UMIN, MVT::v8i16, { 1, 1, 1, 1 } },
4417 { ISD::UMULO, MVT::v2i64, { 14, 20, 15, 20 } },
4418 { ISD::UMULO, MVT::v4i32, { 19, 22, 12, 18 } },
4419 { ISD::UMULO, MVT::v8i16, { 4, 9, 7, 7 } },
4420 { ISD::UMULO, MVT::v16i8, { 13, 19, 18, 20 } },
4421 };
4422 static const CostKindTblEntry SSSE3CostTbl[] = {
4423 { ISD::ABS, MVT::v4i32, { 1, 2, 1, 1 } },
4424 { ISD::ABS, MVT::v8i16, { 1, 2, 1, 1 } },
4425 { ISD::ABS, MVT::v16i8, { 1, 2, 1, 1 } },
4426 { ISD::BITREVERSE, MVT::v2i64, { 16, 20, 11, 21 } },
4427 { ISD::BITREVERSE, MVT::v4i32, { 16, 20, 11, 21 } },
4428 { ISD::BITREVERSE, MVT::v8i16, { 16, 20, 11, 21 } },
4429 { ISD::BITREVERSE, MVT::v16i8, { 11, 12, 10, 16 } },
4430 { ISD::BSWAP, MVT::v2i64, { 2, 3, 1, 5 } },
4431 { ISD::BSWAP, MVT::v4i32, { 2, 3, 1, 5 } },
4432 { ISD::BSWAP, MVT::v8i16, { 2, 3, 1, 5 } },
4433 { ISD::CTLZ, MVT::v2i64, { 18, 28, 28, 35 } },
4434 { ISD::CTLZ, MVT::v4i32, { 15, 20, 22, 28 } },
4435 { ISD::CTLZ, MVT::v8i16, { 13, 17, 16, 22 } },
4436 { ISD::CTLZ, MVT::v16i8, { 11, 15, 10, 16 } },
4437 { ISD::CTPOP, MVT::v2i64, { 13, 19, 12, 18 } },
4438 { ISD::CTPOP, MVT::v4i32, { 18, 24, 16, 22 } },
4439 { ISD::CTPOP, MVT::v8i16, { 13, 18, 14, 20 } },
4440 { ISD::CTPOP, MVT::v16i8, { 11, 12, 10, 16 } },
4441 { ISD::CTTZ, MVT::v2i64, { 13, 25, 15, 22 } },
4442 { ISD::CTTZ, MVT::v4i32, { 18, 26, 19, 25 } },
4443 { ISD::CTTZ, MVT::v8i16, { 13, 20, 17, 23 } },
4444 { ISD::CTTZ, MVT::v16i8, { 11, 16, 13, 19 } }
4445 };
4446 static const CostKindTblEntry SSE2CostTbl[] = {
4447 { ISD::ABS, MVT::v2i64, { 3, 6, 5, 5 } },
4448 { ISD::ABS, MVT::v4i32, { 1, 4, 4, 4 } },
4449 { ISD::ABS, MVT::v8i16, { 1, 2, 3, 3 } },
4450 { ISD::ABS, MVT::v16i8, { 1, 2, 3, 3 } },
4451 { ISD::BITREVERSE, MVT::v2i64, { 16, 20, 32, 32 } },
4452 { ISD::BITREVERSE, MVT::v4i32, { 16, 20, 30, 30 } },
4453 { ISD::BITREVERSE, MVT::v8i16, { 16, 20, 25, 25 } },
4454 { ISD::BITREVERSE, MVT::v16i8, { 11, 12, 21, 21 } },
4455 { ISD::BSWAP, MVT::v2i64, { 5, 6, 11, 11 } },
4456 { ISD::BSWAP, MVT::v4i32, { 5, 5, 9, 9 } },
4457 { ISD::BSWAP, MVT::v8i16, { 5, 5, 4, 5 } },
4458 { ISD::CTLZ, MVT::v2i64, { 10, 45, 36, 38 } },
4459 { ISD::CTLZ, MVT::v4i32, { 10, 45, 38, 40 } },
4460 { ISD::CTLZ, MVT::v8i16, { 9, 38, 32, 34 } },
4461 { ISD::CTLZ, MVT::v16i8, { 8, 39, 29, 32 } },
4462 { ISD::CTPOP, MVT::v2i64, { 12, 26, 16, 18 } },
4463 { ISD::CTPOP, MVT::v4i32, { 15, 29, 21, 23 } },
4464 { ISD::CTPOP, MVT::v8i16, { 13, 25, 18, 20 } },
4465 { ISD::CTPOP, MVT::v16i8, { 10, 21, 14, 16 } },
4466 { ISD::CTTZ, MVT::v2i64, { 14, 28, 19, 21 } },
4467 { ISD::CTTZ, MVT::v4i32, { 18, 31, 24, 26 } },
4468 { ISD::CTTZ, MVT::v8i16, { 16, 27, 21, 23 } },
4469 { ISD::CTTZ, MVT::v16i8, { 13, 23, 17, 19 } },
4470 { ISD::SADDSAT, MVT::v2i64, { 12, 14, 24, 24 } },
4471 { ISD::SADDSAT, MVT::v4i32, { 6, 11, 11, 12 } },
4472 { ISD::SADDSAT, MVT::v8i16, { 1, 2, 1, 1 } },
4473 { ISD::SADDSAT, MVT::v16i8, { 1, 2, 1, 1 } },
4474 { ISD::SMAX, MVT::v2i64, { 4, 8, 15, 15 } },
4475 { ISD::SMAX, MVT::v4i32, { 2, 4, 5, 5 } },
4476 { ISD::SMAX, MVT::v8i16, { 1, 1, 1, 1 } },
4477 { ISD::SMAX, MVT::v16i8, { 2, 4, 5, 5 } },
4478 { ISD::SMIN, MVT::v2i64, { 4, 8, 15, 15 } },
4479 { ISD::SMIN, MVT::v4i32, { 2, 4, 5, 5 } },
4480 { ISD::SMIN, MVT::v8i16, { 1, 1, 1, 1 } },
4481 { ISD::SMIN, MVT::v16i8, { 2, 4, 5, 5 } },
4482 { ISD::SMULO, MVT::v2i64, { 30, 33, 13, 23 } },
4483 { ISD::SMULO, MVT::v4i32, { 20, 24, 23, 23 } },
4484 { ISD::SMULO, MVT::v8i16, { 5, 10, 8, 8 } },
4485 { ISD::SMULO, MVT::v16i8, { 13, 23, 24, 25 } },
4486 { ISD::SSUBSAT, MVT::v2i64, { 16, 19, 31, 31 } },
4487 { ISD::SSUBSAT, MVT::v4i32, { 6, 14, 12, 13 } },
4488 { ISD::SSUBSAT, MVT::v8i16, { 1, 2, 1, 1 } },
4489 { ISD::SSUBSAT, MVT::v16i8, { 1, 2, 1, 1 } },
4490 { ISD::UADDSAT, MVT::v2i64, { 7, 13, 14, 14 } },
4491 { ISD::UADDSAT, MVT::v4i32, { 4, 5, 7, 7 } },
4492 { ISD::UADDSAT, MVT::v8i16, { 1, 2, 1, 1 } },
4493 { ISD::UADDSAT, MVT::v16i8, { 1, 2, 1, 1 } },
4494 { ISD::UMAX, MVT::v2i64, { 4, 8, 15, 15 } },
4495 { ISD::UMAX, MVT::v4i32, { 2, 5, 8, 8 } },
4496 { ISD::UMAX, MVT::v8i16, { 1, 3, 3, 3 } },
4497 { ISD::UMAX, MVT::v16i8, { 1, 1, 1, 1 } },
4498 { ISD::UMIN, MVT::v2i64, { 4, 8, 15, 15 } },
4499 { ISD::UMIN, MVT::v4i32, { 2, 5, 8, 8 } },
4500 { ISD::UMIN, MVT::v8i16, { 1, 3, 3, 3 } },
4501 { ISD::UMIN, MVT::v16i8, { 1, 1, 1, 1 } },
4502 { ISD::UMULO, MVT::v2i64, { 30, 33, 15, 29 } },
4503 { ISD::UMULO, MVT::v4i32, { 19, 22, 14, 18 } },
4504 { ISD::UMULO, MVT::v8i16, { 4, 9, 7, 7 } },
4505 { ISD::UMULO, MVT::v16i8, { 13, 19, 20, 20 } },
4506 { ISD::USUBSAT, MVT::v2i64, { 7, 10, 14, 14 } },
4507 { ISD::USUBSAT, MVT::v4i32, { 4, 4, 7, 7 } },
4508 { ISD::USUBSAT, MVT::v8i16, { 1, 2, 1, 1 } },
4509 { ISD::USUBSAT, MVT::v16i8, { 1, 2, 1, 1 } },
4510 { ISD::FMAXNUM, MVT::f64, { 5, 5, 7, 7 } },
4511 { ISD::FMAXNUM, MVT::v2f64, { 4, 6, 6, 6 } },
4512 { ISD::FSQRT, MVT::f64, { 32, 32, 1, 1 } }, // Nehalem from http://www.agner.org/
4513 { ISD::FSQRT, MVT::v2f64, { 32, 32, 1, 1 } }, // Nehalem from http://www.agner.org/
4514 };
4515 static const CostKindTblEntry SSE1CostTbl[] = {
4516 { ISD::FMAXNUM, MVT::f32, { 5, 5, 7, 7 } },
4517 { ISD::FMAXNUM, MVT::v4f32, { 4, 6, 6, 6 } },
4518 { ISD::FSQRT, MVT::f32, { 28, 30, 1, 2 } }, // Pentium III from http://www.agner.org/
4519 { ISD::FSQRT, MVT::v4f32, { 56, 56, 1, 2 } }, // Pentium III from http://www.agner.org/
4520 };
4521 static const CostKindTblEntry BMI64CostTbl[] = { // 64-bit targets
4522 { ISD::CTTZ, MVT::i64, { 1, 1, 1, 1 } },
4523 };
4524 static const CostKindTblEntry BMI32CostTbl[] = { // 32 or 64-bit targets
4525 { ISD::CTTZ, MVT::i32, { 1, 1, 1, 1 } },
4526 { ISD::CTTZ, MVT::i16, { 2, 1, 1, 1 } },
4527 { ISD::CTTZ, MVT::i8, { 2, 1, 1, 1 } },
4528 };
4529 static const CostKindTblEntry LZCNT64CostTbl[] = { // 64-bit targets
4530 { ISD::CTLZ, MVT::i64, { 1, 1, 1, 1 } },
4531 };
4532 static const CostKindTblEntry LZCNT32CostTbl[] = { // 32 or 64-bit targets
4533 { ISD::CTLZ, MVT::i32, { 1, 1, 1, 1 } },
4534 { ISD::CTLZ, MVT::i16, { 2, 1, 1, 1 } },
4535 { ISD::CTLZ, MVT::i8, { 2, 1, 1, 1 } },
4536 };
4537 static const CostKindTblEntry POPCNT64CostTbl[] = { // 64-bit targets
4538 { ISD::CTPOP, MVT::i64, { 1, 1, 1, 1 } }, // popcnt
4539 };
4540 static const CostKindTblEntry POPCNT32CostTbl[] = { // 32 or 64-bit targets
4541 { ISD::CTPOP, MVT::i32, { 1, 1, 1, 1 } }, // popcnt
4542 { ISD::CTPOP, MVT::i16, { 1, 1, 2, 2 } }, // popcnt(zext())
4543 { ISD::CTPOP, MVT::i8, { 1, 1, 2, 2 } }, // popcnt(zext())
4544 };
4545 static const CostKindTblEntry PCLMULCostTbl[] = {
4546 { ISD::CLMUL, MVT::v2i64, { 3, 12, 4, 8 } }, // MOV+2xPCLMUL+unpack
4547 { ISD::CLMUL, MVT::v4i32, { 8, 18, 12, 16 } }, // MOV+4xPCLMUL+unpack
4548 { ISD::CLMUL, MVT::i64, { 3, 12, 4, 8 } }, // MOV+PCLMUL+MOV
4549 { ISD::CLMUL, MVT::i32, { 3, 12, 4, 8 } }, // MOV+PCLMUL+MOV
4550 { ISD::CLMUL, MVT::i16, { 3, 12, 4, 8 } }, // MOV+PCLMUL+MOV
4551 { ISD::CLMUL, MVT::i8, { 3, 12, 4, 8 } }, // MOV+PCLMUL+MOV
4552 };
4553 static const CostKindTblEntry X64CostTbl[] = { // 64-bit targets
4554 { ISD::ABS, MVT::i64, { 1, 2, 3, 3 } }, // SUB+CMOV
4555 { ISD::BITREVERSE, MVT::i64, { 10, 12, 20, 22 } },
4556 { ISD::BSWAP, MVT::i64, { 1, 2, 1, 2 } },
4557 { ISD::CTLZ, MVT::i64, { 1, 2, 3, 3 } }, // MOV+BSR+XOR
4558 { ISD::CTLZ, MVT::i32, { 1, 2, 3, 3 } }, // MOV+BSR+XOR
4559 { ISD::CTLZ, MVT::i16, { 2, 2, 3, 3 } }, // MOV+BSR+XOR
4560 { ISD::CTLZ, MVT::i8, { 2, 2, 4, 3 } }, // MOV+BSR+XOR
4561 { ISD::CTLZ_ZERO_POISON,MVT::i64,{ 1, 2, 2, 2 } }, // BSR+XOR
4562 { ISD::CTTZ, MVT::i64, { 1, 2, 2, 2 } }, // MOV+BSF
4563 { ISD::CTTZ, MVT::i32, { 1, 2, 2, 2 } }, // MOV+BSF
4564 { ISD::CTTZ, MVT::i16, { 2, 2, 2, 2 } }, // MOV+BSF
4565 { ISD::CTTZ, MVT::i8, { 2, 2, 2, 2 } }, // MOV+BSF
4566 { ISD::CTTZ_ZERO_POISON,MVT::i64,{ 1, 2, 1, 2 } }, // BSF
4567 { ISD::CTPOP, MVT::i64, { 10, 6, 19, 19 } },
4568 { ISD::ROTL, MVT::i64, { 2, 3, 1, 3 } },
4569 { ISD::ROTR, MVT::i64, { 2, 3, 1, 3 } },
4570 { X86ISD::VROTLI, MVT::i64, { 1, 1, 1, 1 } },
4571 { ISD::FSHL, MVT::i64, { 4, 4, 1, 4 } },
4572 { ISD::SADDSAT, MVT::i64, { 4, 4, 7, 10 } },
4573 { ISD::SSUBSAT, MVT::i64, { 4, 5, 8, 11 } },
4574 { ISD::UADDSAT, MVT::i64, { 2, 3, 4, 7 } },
4575 { ISD::USUBSAT, MVT::i64, { 2, 3, 4, 7 } },
4576 { ISD::SMAX, MVT::i64, { 1, 3, 2, 3 } },
4577 { ISD::SMIN, MVT::i64, { 1, 3, 2, 3 } },
4578 { ISD::UMAX, MVT::i64, { 1, 3, 2, 3 } },
4579 { ISD::UMIN, MVT::i64, { 1, 3, 2, 3 } },
4580 { ISD::SADDO, MVT::i64, { 2, 2, 4, 6 } },
4581 { ISD::UADDO, MVT::i64, { 2, 2, 4, 6 } },
4582 { ISD::SMULO, MVT::i64, { 4, 4, 4, 6 } },
4583 { ISD::UMULO, MVT::i64, { 8, 8, 4, 7 } },
4584 };
4585 static const CostKindTblEntry X86CostTbl[] = { // 32 or 64-bit targets
4586 { ISD::ABS, MVT::i32, { 1, 2, 3, 3 } }, // SUB+XOR+SRA or SUB+CMOV
4587 { ISD::ABS, MVT::i16, { 2, 2, 3, 3 } }, // SUB+XOR+SRA or SUB+CMOV
4588 { ISD::ABS, MVT::i8, { 2, 4, 4, 3 } }, // SUB+XOR+SRA
4589 { ISD::BITREVERSE, MVT::i32, { 9, 12, 17, 19 } },
4590 { ISD::BITREVERSE, MVT::i16, { 9, 12, 17, 19 } },
4591 { ISD::BITREVERSE, MVT::i8, { 7, 9, 13, 14 } },
4592 { ISD::BSWAP, MVT::i32, { 1, 1, 1, 1 } },
4593 { ISD::BSWAP, MVT::i16, { 1, 2, 1, 2 } }, // ROL
4594 { ISD::CTLZ, MVT::i32, { 2, 2, 4, 5 } }, // BSR+XOR or BSR+XOR+CMOV
4595 { ISD::CTLZ, MVT::i16, { 2, 2, 4, 5 } }, // BSR+XOR or BSR+XOR+CMOV
4596 { ISD::CTLZ, MVT::i8, { 2, 2, 5, 6 } }, // BSR+XOR or BSR+XOR+CMOV
4597 { ISD::CTLZ_ZERO_POISON,MVT::i32,{ 1, 2, 2, 2 } }, // BSR+XOR
4598 { ISD::CTLZ_ZERO_POISON,MVT::i16,{ 2, 2, 2, 2 } }, // BSR+XOR
4599 { ISD::CTLZ_ZERO_POISON,MVT::i8, { 2, 2, 3, 3 } }, // BSR+XOR
4600 { ISD::CTTZ, MVT::i32, { 2, 2, 3, 3 } }, // TEST+BSF+CMOV/BRANCH
4601 { ISD::CTTZ, MVT::i16, { 2, 2, 2, 3 } }, // TEST+BSF+CMOV/BRANCH
4602 { ISD::CTTZ, MVT::i8, { 2, 2, 2, 3 } }, // TEST+BSF+CMOV/BRANCH
4603 { ISD::CTTZ_ZERO_POISON,MVT::i32,{ 1, 2, 1, 2 } }, // BSF
4604 { ISD::CTTZ_ZERO_POISON,MVT::i16,{ 2, 2, 1, 2 } }, // BSF
4605 { ISD::CTTZ_ZERO_POISON,MVT::i8, { 2, 2, 1, 2 } }, // BSF
4606 { ISD::CTPOP, MVT::i32, { 8, 7, 15, 15 } },
4607 { ISD::CTPOP, MVT::i16, { 9, 8, 17, 17 } },
4608 { ISD::CTPOP, MVT::i8, { 7, 6, 6, 6 } },
4609 { ISD::ROTL, MVT::i32, { 2, 3, 1, 3 } },
4610 { ISD::ROTL, MVT::i16, { 2, 3, 1, 3 } },
4611 { ISD::ROTL, MVT::i8, { 2, 3, 1, 3 } },
4612 { ISD::ROTR, MVT::i32, { 2, 3, 1, 3 } },
4613 { ISD::ROTR, MVT::i16, { 2, 3, 1, 3 } },
4614 { ISD::ROTR, MVT::i8, { 2, 3, 1, 3 } },
4615 { X86ISD::VROTLI, MVT::i32, { 1, 1, 1, 1 } },
4616 { X86ISD::VROTLI, MVT::i16, { 1, 1, 1, 1 } },
4617 { X86ISD::VROTLI, MVT::i8, { 1, 1, 1, 1 } },
4618 { ISD::FSHL, MVT::i32, { 4, 4, 1, 4 } },
4619 { ISD::FSHL, MVT::i16, { 4, 4, 2, 5 } },
4620 { ISD::FSHL, MVT::i8, { 4, 4, 2, 5 } },
4621 { ISD::SADDSAT, MVT::i32, { 3, 4, 6, 9 } },
4622 { ISD::SADDSAT, MVT::i16, { 4, 4, 7, 10 } },
4623 { ISD::SADDSAT, MVT::i8, { 4, 5, 8, 11 } },
4624 { ISD::SSUBSAT, MVT::i32, { 4, 4, 7, 10 } },
4625 { ISD::SSUBSAT, MVT::i16, { 4, 4, 7, 10 } },
4626 { ISD::SSUBSAT, MVT::i8, { 4, 5, 8, 11 } },
4627 { ISD::UADDSAT, MVT::i32, { 2, 3, 4, 7 } },
4628 { ISD::UADDSAT, MVT::i16, { 2, 3, 4, 7 } },
4629 { ISD::UADDSAT, MVT::i8, { 3, 3, 5, 8 } },
4630 { ISD::USUBSAT, MVT::i32, { 2, 3, 4, 7 } },
4631 { ISD::USUBSAT, MVT::i16, { 2, 3, 4, 7 } },
4632 { ISD::USUBSAT, MVT::i8, { 3, 3, 5, 8 } },
4633 { ISD::SMAX, MVT::i32, { 1, 2, 2, 3 } },
4634 { ISD::SMAX, MVT::i16, { 1, 4, 2, 4 } },
4635 { ISD::SMAX, MVT::i8, { 1, 4, 2, 4 } },
4636 { ISD::SMIN, MVT::i32, { 1, 2, 2, 3 } },
4637 { ISD::SMIN, MVT::i16, { 1, 4, 2, 4 } },
4638 { ISD::SMIN, MVT::i8, { 1, 4, 2, 4 } },
4639 { ISD::UMAX, MVT::i32, { 1, 2, 2, 3 } },
4640 { ISD::UMAX, MVT::i16, { 1, 4, 2, 4 } },
4641 { ISD::UMAX, MVT::i8, { 1, 4, 2, 4 } },
4642 { ISD::UMIN, MVT::i32, { 1, 2, 2, 3 } },
4643 { ISD::UMIN, MVT::i16, { 1, 4, 2, 4 } },
4644 { ISD::UMIN, MVT::i8, { 1, 4, 2, 4 } },
4645 { ISD::SADDO, MVT::i32, { 2, 2, 4, 6 } },
4646 { ISD::SADDO, MVT::i16, { 2, 2, 4, 6 } },
4647 { ISD::SADDO, MVT::i8, { 2, 2, 4, 6 } },
4648 { ISD::UADDO, MVT::i32, { 2, 2, 4, 6 } },
4649 { ISD::UADDO, MVT::i16, { 2, 2, 4, 6 } },
4650 { ISD::UADDO, MVT::i8, { 2, 2, 4, 6 } },
4651 { ISD::SMULO, MVT::i32, { 2, 2, 4, 6 } },
4652 { ISD::SMULO, MVT::i16, { 5, 5, 4, 6 } },
4653 { ISD::SMULO, MVT::i8, { 6, 6, 4, 6 } },
4654 { ISD::UMULO, MVT::i32, { 6, 6, 4, 8 } },
4655 { ISD::UMULO, MVT::i16, { 6, 6, 4, 9 } },
4656 { ISD::UMULO, MVT::i8, { 6, 6, 4, 6 } },
4657 };
4658
4659 Type *RetTy = ICA.getReturnType();
4660 Type *OpTy = RetTy;
4661 Intrinsic::ID IID = ICA.getID();
4662 unsigned ISD = ISD::DELETED_NODE;
4663 switch (IID) {
4664 default:
4665 break;
4666 case Intrinsic::abs:
4667 ISD = ISD::ABS;
4668 break;
4669 case Intrinsic::bitreverse:
4671 break;
4672 case Intrinsic::bswap:
4673 ISD = ISD::BSWAP;
4674 break;
4675 case Intrinsic::ctlz:
4676 ISD = ISD::CTLZ;
4677 break;
4678 case Intrinsic::ctpop:
4679 ISD = ISD::CTPOP;
4680 break;
4681 case Intrinsic::cttz:
4682 ISD = ISD::CTTZ;
4683 break;
4684 case Intrinsic::fshl:
4685 ISD = ISD::FSHL;
4686 if (!ICA.isTypeBasedOnly()) {
4687 const SmallVectorImpl<const Value *> &Args = ICA.getArgs();
4688 if (Args[0] == Args[1]) {
4689 ISD = ISD::ROTL;
4690 // Handle uniform constant rotation amounts.
4691 // TODO: Handle funnel-shift cases.
4692 const APInt *Amt;
4693 if (Args[2] &&
4695 ISD = X86ISD::VROTLI;
4696 }
4697 }
4698 break;
4699 case Intrinsic::fshr:
4700 // FSHR has same costs so don't duplicate.
4701 ISD = ISD::FSHL;
4702 if (!ICA.isTypeBasedOnly()) {
4703 const SmallVectorImpl<const Value *> &Args = ICA.getArgs();
4704 if (Args[0] == Args[1]) {
4705 ISD = ISD::ROTR;
4706 // Handle uniform constant rotation amount.
4707 // TODO: Handle funnel-shift cases.
4708 const APInt *Amt;
4709 if (Args[2] &&
4711 ISD = X86ISD::VROTLI;
4712 }
4713 }
4714 break;
4715 case Intrinsic::lrint:
4716 case Intrinsic::llrint: {
4717 // X86 can use the CVTP2SI instructions to lower lrint/llrint calls, which
4718 // have the same costs as the CVTTP2SI (fptosi) instructions
4719 const SmallVectorImpl<Type *> &ArgTys = ICA.getArgTypes();
4720 return getCastInstrCost(Instruction::FPToSI, RetTy, ArgTys[0],
4722 }
4723 case Intrinsic::maxnum:
4724 case Intrinsic::minnum:
4725 // FMINNUM has same costs so don't duplicate.
4726 ISD = ISD::FMAXNUM;
4727 break;
4728 case Intrinsic::sadd_sat:
4729 ISD = ISD::SADDSAT;
4730 break;
4731 case Intrinsic::smax:
4732 ISD = ISD::SMAX;
4733 break;
4734 case Intrinsic::smin:
4735 ISD = ISD::SMIN;
4736 break;
4737 case Intrinsic::ssub_sat:
4738 ISD = ISD::SSUBSAT;
4739 break;
4740 case Intrinsic::uadd_sat:
4741 ISD = ISD::UADDSAT;
4742 break;
4743 case Intrinsic::umax:
4744 ISD = ISD::UMAX;
4745 break;
4746 case Intrinsic::umin:
4747 ISD = ISD::UMIN;
4748 break;
4749 case Intrinsic::usub_sat:
4750 ISD = ISD::USUBSAT;
4751 break;
4752 case Intrinsic::sqrt:
4753 ISD = ISD::FSQRT;
4754 break;
4755 case Intrinsic::sadd_with_overflow:
4756 case Intrinsic::ssub_with_overflow:
4757 // SSUBO has same costs so don't duplicate.
4758 ISD = ISD::SADDO;
4759 OpTy = RetTy->getContainedType(0);
4760 break;
4761 case Intrinsic::uadd_with_overflow:
4762 case Intrinsic::usub_with_overflow:
4763 // USUBO has same costs so don't duplicate.
4764 ISD = ISD::UADDO;
4765 OpTy = RetTy->getContainedType(0);
4766 break;
4767 case Intrinsic::smul_with_overflow:
4768 ISD = ISD::SMULO;
4769 OpTy = RetTy->getContainedType(0);
4770 break;
4771 case Intrinsic::umul_with_overflow:
4772 ISD = ISD::UMULO;
4773 OpTy = RetTy->getContainedType(0);
4774 break;
4775 case Intrinsic::clmul:
4776 ISD = ISD::CLMUL;
4777 break;
4778 }
4779
4780 if (ISD != ISD::DELETED_NODE) {
4781 auto adjustTableCost = [&](int ISD, unsigned Cost,
4782 std::pair<InstructionCost, MVT> LT,
4784 InstructionCost LegalizationCost = LT.first;
4785 MVT MTy = LT.second;
4786
4787 // If there are no NANs to deal with, then these are reduced to a
4788 // single MIN** or MAX** instruction instead of the MIN/CMP/SELECT that we
4789 // assume is used in the non-fast case.
4790 if (ISD == ISD::FMAXNUM || ISD == ISD::FMINNUM) {
4791 if (FMF.noNaNs())
4792 return LegalizationCost * 1;
4793 }
4794
4795 // For cases where some ops can be folded into a load/store, assume free.
4796 if (MTy.isScalarInteger()) {
4797 if (ISD == ISD::BSWAP && ST->hasMOVBE() && ST->hasFastMOVBE()) {
4798 if (const Instruction *II = ICA.getInst()) {
4799 if (II->hasOneUse() && isa<StoreInst>(II->user_back()))
4800 return TTI::TCC_Free;
4801 if (auto *LI = dyn_cast<LoadInst>(II->getOperand(0))) {
4802 if (LI->hasOneUse())
4803 return TTI::TCC_Free;
4804 }
4805 }
4806 }
4807 }
4808
4809 return LegalizationCost * (int)Cost;
4810 };
4811
4812 // Legalize the type.
4813 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(OpTy);
4814 MVT MTy = LT.second;
4815
4816 // Without BMI/LZCNT see if we're only looking for a *_ZERO_POISON cost.
4817 if (((ISD == ISD::CTTZ && !ST->hasBMI()) ||
4818 (ISD == ISD::CTLZ && !ST->hasLZCNT())) &&
4819 !MTy.isVector() && !ICA.isTypeBasedOnly()) {
4820 const SmallVectorImpl<const Value *> &Args = ICA.getArgs();
4821 if (auto *Cst = dyn_cast<ConstantInt>(Args[1]))
4822 if (Cst->isAllOnesValue())
4823 ISD =
4825 }
4826
4827 // FSQRT is a single instruction.
4829 return LT.first;
4830
4831 if (ST->useGLMDivSqrtCosts())
4832 if (const auto *Entry = CostTableLookup(GLMCostTbl, ISD, MTy))
4833 if (auto KindCost = Entry->Cost[CostKind])
4834 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4835
4836 if (ST->useSLMArithCosts())
4837 if (const auto *Entry = CostTableLookup(SLMCostTbl, ISD, MTy))
4838 if (auto KindCost = Entry->Cost[CostKind])
4839 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4840
4841 if (ST->hasVBMI2())
4842 if (const auto *Entry = CostTableLookup(AVX512VBMI2CostTbl, ISD, MTy))
4843 if (auto KindCost = Entry->Cost[CostKind])
4844 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4845
4846 if (ST->hasBITALG())
4847 if (const auto *Entry = CostTableLookup(AVX512BITALGCostTbl, ISD, MTy))
4848 if (auto KindCost = Entry->Cost[CostKind])
4849 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4850
4851 if (ST->hasVPOPCNTDQ())
4852 if (const auto *Entry = CostTableLookup(AVX512VPOPCNTDQCostTbl, ISD, MTy))
4853 if (auto KindCost = Entry->Cost[CostKind])
4854 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4855
4856 if (ST->hasGFNI())
4857 if (const auto *Entry = CostTableLookup(GFNICostTbl, ISD, MTy))
4858 if (auto KindCost = Entry->Cost[CostKind])
4859 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4860
4861 if (ST->hasCDI())
4862 if (const auto *Entry = CostTableLookup(AVX512CDCostTbl, ISD, MTy))
4863 if (auto KindCost = Entry->Cost[CostKind])
4864 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4865
4866 if (ST->hasBWI())
4867 if (const auto *Entry = CostTableLookup(AVX512BWCostTbl, ISD, MTy))
4868 if (auto KindCost = Entry->Cost[CostKind])
4869 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4870
4871 if (ST->hasAVX512())
4872 if (const auto *Entry = CostTableLookup(AVX512CostTbl, ISD, MTy))
4873 if (auto KindCost = Entry->Cost[CostKind])
4874 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4875
4876 if (ST->hasXOP())
4877 if (const auto *Entry = CostTableLookup(XOPCostTbl, ISD, MTy))
4878 if (auto KindCost = Entry->Cost[CostKind])
4879 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4880
4881 if (ST->hasAVX2())
4882 if (const auto *Entry = CostTableLookup(AVX2CostTbl, ISD, MTy))
4883 if (auto KindCost = Entry->Cost[CostKind])
4884 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4885
4886 if (ST->hasAVX())
4887 if (const auto *Entry = CostTableLookup(AVX1CostTbl, ISD, MTy))
4888 if (auto KindCost = Entry->Cost[CostKind])
4889 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4890
4891 if (ST->hasSSE42())
4892 if (const auto *Entry = CostTableLookup(SSE42CostTbl, ISD, MTy))
4893 if (auto KindCost = Entry->Cost[CostKind])
4894 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4895
4896 if (ST->hasSSE41())
4897 if (const auto *Entry = CostTableLookup(SSE41CostTbl, ISD, MTy))
4898 if (auto KindCost = Entry->Cost[CostKind])
4899 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4900
4901 if (ST->hasSSSE3())
4902 if (const auto *Entry = CostTableLookup(SSSE3CostTbl, ISD, MTy))
4903 if (auto KindCost = Entry->Cost[CostKind])
4904 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4905
4906 if (ST->hasSSE2())
4907 if (const auto *Entry = CostTableLookup(SSE2CostTbl, ISD, MTy))
4908 if (auto KindCost = Entry->Cost[CostKind])
4909 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4910
4911 if (ST->hasSSE1())
4912 if (const auto *Entry = CostTableLookup(SSE1CostTbl, ISD, MTy))
4913 if (auto KindCost = Entry->Cost[CostKind])
4914 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4915
4916 if (ST->hasBMI()) {
4917 if (ST->is64Bit())
4918 if (const auto *Entry = CostTableLookup(BMI64CostTbl, ISD, MTy))
4919 if (auto KindCost = Entry->Cost[CostKind])
4920 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4921
4922 if (const auto *Entry = CostTableLookup(BMI32CostTbl, ISD, MTy))
4923 if (auto KindCost = Entry->Cost[CostKind])
4924 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4925 }
4926
4927 if (ST->hasLZCNT()) {
4928 if (ST->is64Bit())
4929 if (const auto *Entry = CostTableLookup(LZCNT64CostTbl, ISD, MTy))
4930 if (auto KindCost = Entry->Cost[CostKind])
4931 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4932
4933 if (const auto *Entry = CostTableLookup(LZCNT32CostTbl, ISD, MTy))
4934 if (auto KindCost = Entry->Cost[CostKind])
4935 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4936 }
4937
4938 if (ST->hasPOPCNT()) {
4939 if (ST->is64Bit())
4940 if (const auto *Entry = CostTableLookup(POPCNT64CostTbl, ISD, MTy))
4941 if (auto KindCost = Entry->Cost[CostKind])
4942 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4943
4944 if (const auto *Entry = CostTableLookup(POPCNT32CostTbl, ISD, MTy))
4945 if (auto KindCost = Entry->Cost[CostKind])
4946 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4947 }
4948
4949 // FIXME: PCLMUL w/ AVX/AVX512 and VPCLMULQDQ are not handled properly.
4950 if (ST->hasPCLMUL())
4951 if (const auto *Entry = CostTableLookup(PCLMULCostTbl, ISD, MTy))
4952 if (auto KindCost = Entry->Cost[CostKind])
4953 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4954
4955 if (ST->is64Bit())
4956 if (const auto *Entry = CostTableLookup(X64CostTbl, ISD, MTy))
4957 if (auto KindCost = Entry->Cost[CostKind])
4958 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4959
4960 if (const auto *Entry = CostTableLookup(X86CostTbl, ISD, MTy))
4961 if (auto KindCost = Entry->Cost[CostKind])
4962 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
4963
4964 // Without arg data, we need to compute the expanded costs of custom lowered
4965 // intrinsics to prevent use of the (very low) default costs.
4966 if (ICA.isTypeBasedOnly() &&
4967 (IID == Intrinsic::fshl || IID == Intrinsic::fshr)) {
4968 Type *CondTy = RetTy->getWithNewBitWidth(1);
4970 Cost += getArithmeticInstrCost(BinaryOperator::Or, RetTy, CostKind);
4971 Cost += getArithmeticInstrCost(BinaryOperator::Sub, RetTy, CostKind);
4972 Cost += getArithmeticInstrCost(BinaryOperator::Shl, RetTy, CostKind);
4973 Cost += getArithmeticInstrCost(BinaryOperator::LShr, RetTy, CostKind);
4974 Cost += getArithmeticInstrCost(BinaryOperator::And, RetTy, CostKind);
4975 Cost += getCmpSelInstrCost(BinaryOperator::ICmp, RetTy, CondTy,
4977 Cost += getCmpSelInstrCost(BinaryOperator::Select, RetTy, CondTy,
4979 return Cost;
4980 }
4981 }
4982
4984}
4985
4987 unsigned Opcode, Type *Val, TTI::TargetCostKind CostKind, unsigned Index,
4988 const Value *Op0, const Value *Op1, TTI::VectorInstrContext VIC) const {
4989 static const CostTblEntry SLMCostTbl[] = {
4990 { ISD::EXTRACT_VECTOR_ELT, MVT::i8, 4 },
4991 { ISD::EXTRACT_VECTOR_ELT, MVT::i16, 4 },
4992 { ISD::EXTRACT_VECTOR_ELT, MVT::i32, 4 },
4993 { ISD::EXTRACT_VECTOR_ELT, MVT::i64, 7 }
4994 };
4995
4996 assert(Val->isVectorTy() && "This must be a vector type");
4997 auto *VT = cast<VectorType>(Val);
4998 if (VT->isScalableTy())
5000
5001 Type *ScalarType = Val->getScalarType();
5002 InstructionCost RegisterFileMoveCost = 0;
5003
5004 // Non-immediate extraction/insertion can be handled as a sequence of
5005 // aliased loads+stores via the stack.
5006 if (Index == -1U && (Opcode == Instruction::ExtractElement ||
5007 Opcode == Instruction::InsertElement)) {
5008 // TODO: On some SSE41+ targets, we expand to cmp+splat+select patterns:
5009 // inselt N0, N1, N2 --> select (SplatN2 == {0,1,2...}) ? SplatN1 : N0.
5010
5011 // TODO: Move this to BasicTTIImpl.h? We'd need better gep + index handling.
5012 assert(isa<FixedVectorType>(Val) && "Fixed vector type expected");
5013 Align VecAlign = DL.getPrefTypeAlign(Val);
5014 Align SclAlign = DL.getPrefTypeAlign(ScalarType);
5015
5016 // Extract - store vector to stack, load scalar.
5017 if (Opcode == Instruction::ExtractElement) {
5018 return getMemoryOpCost(Instruction::Store, Val, VecAlign, 0, CostKind) +
5019 getMemoryOpCost(Instruction::Load, ScalarType, SclAlign, 0,
5020 CostKind);
5021 }
5022 // Insert - store vector to stack, store scalar, load vector.
5023 if (Opcode == Instruction::InsertElement) {
5024 return getMemoryOpCost(Instruction::Store, Val, VecAlign, 0, CostKind) +
5025 getMemoryOpCost(Instruction::Store, ScalarType, SclAlign, 0,
5026 CostKind) +
5027 getMemoryOpCost(Instruction::Load, Val, VecAlign, 0, CostKind);
5028 }
5029 }
5030
5031 if (Index != -1U && (Opcode == Instruction::ExtractElement ||
5032 Opcode == Instruction::InsertElement)) {
5033 // Extraction of vXi1 elements are now efficiently handled by MOVMSK.
5034 if (Opcode == Instruction::ExtractElement &&
5035 ScalarType->getScalarSizeInBits() == 1 &&
5036 cast<FixedVectorType>(Val)->getNumElements() > 1)
5037 return 1;
5038
5039 // Legalize the type.
5040 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Val);
5041
5042 // This type is legalized to a scalar type.
5043 if (!LT.second.isVector())
5044 return TTI::TCC_Free;
5045
5046 // The type may be split. Normalize the index to the new type.
5047 unsigned SizeInBits = LT.second.getSizeInBits();
5048 unsigned NumElts = LT.second.getVectorNumElements();
5049 unsigned SubNumElts = NumElts;
5050 Index = Index % NumElts;
5051
5052 // For >128-bit vectors, we need to extract higher 128-bit subvectors.
5053 // For inserts, we also need to insert the subvector back.
5054 if (SizeInBits > 128) {
5055 assert((SizeInBits % 128) == 0 && "Illegal vector");
5056 unsigned NumSubVecs = SizeInBits / 128;
5057 SubNumElts = NumElts / NumSubVecs;
5058 if (SubNumElts <= Index) {
5059 RegisterFileMoveCost += (Opcode == Instruction::InsertElement ? 2 : 1);
5060 Index %= SubNumElts;
5061 }
5062 }
5063
5064 MVT MScalarTy = LT.second.getScalarType();
5065 auto IsCheapPInsrPExtrInsertPS = [&]() {
5066 // Assume pinsr/pextr XMM <-> GPR is relatively cheap on all targets.
5067 // Inserting f32 into index0 is just movss.
5068 // Also, assume insertps is relatively cheap on all >= SSE41 targets.
5069 return (MScalarTy == MVT::i16 && ST->hasSSE2()) ||
5070 (MScalarTy.isInteger() && ST->hasSSE41()) ||
5071 (MScalarTy == MVT::f32 && ST->hasSSE1() && Index == 0 &&
5072 Opcode == Instruction::InsertElement) ||
5073 (MScalarTy == MVT::f32 && ST->hasSSE41() &&
5074 Opcode == Instruction::InsertElement);
5075 };
5076
5077 if (Index == 0) {
5078 // Floating point scalars are already located in index #0.
5079 // Many insertions to #0 can fold away for scalar fp-ops, so let's assume
5080 // true for all.
5081 if (ScalarType->isFloatingPointTy() &&
5082 (Opcode != Instruction::InsertElement || !Op0 ||
5083 isa<UndefValue>(Op0)))
5084 return RegisterFileMoveCost;
5085
5086 if (Opcode == Instruction::InsertElement &&
5088 // Consider the gather cost to be cheap.
5090 return RegisterFileMoveCost;
5091 if (!IsCheapPInsrPExtrInsertPS()) {
5092 // mov constant-to-GPR + movd/movq GPR -> XMM.
5093 if (isa_and_nonnull<Constant>(Op1) && Op1->getType()->isIntegerTy())
5094 return 2 + RegisterFileMoveCost;
5095 // Assume movd/movq GPR -> XMM is relatively cheap on all targets.
5096 return 1 + RegisterFileMoveCost;
5097 }
5098 }
5099
5100 // Assume movd/movq XMM -> GPR is relatively cheap on all targets.
5101 if (ScalarType->isIntegerTy() && Opcode == Instruction::ExtractElement)
5102 return 1 + RegisterFileMoveCost;
5103 }
5104
5105 int ISD = TLI->InstructionOpcodeToISD(Opcode);
5106 assert(ISD && "Unexpected vector opcode");
5107 if (ST->useSLMArithCosts())
5108 if (auto *Entry = CostTableLookup(SLMCostTbl, ISD, MScalarTy))
5109 return Entry->Cost + RegisterFileMoveCost;
5110
5111 // Consider cheap cases.
5112 if (IsCheapPInsrPExtrInsertPS())
5113 return 1 + RegisterFileMoveCost;
5114
5115 // For extractions we just need to shuffle the element to index 0, which
5116 // should be very cheap (assume cost = 1). For insertions we need to shuffle
5117 // the elements to its destination. In both cases we must handle the
5118 // subvector move(s).
5119 // If the vector type is already less than 128-bits then don't reduce it.
5120 // TODO: Under what circumstances should we shuffle using the full width?
5121 InstructionCost ShuffleCost = 1;
5122 if (Opcode == Instruction::InsertElement) {
5123 auto *SubTy = cast<VectorType>(Val);
5124 EVT VT = TLI->getValueType(DL, Val);
5125 if (VT.getScalarType() != MScalarTy || VT.getSizeInBits() >= 128)
5126 SubTy = FixedVectorType::get(ScalarType, SubNumElts);
5127 ShuffleCost = getShuffleCost(TTI::SK_PermuteTwoSrc, SubTy, SubTy, {},
5128 CostKind, 0, SubTy);
5129 }
5130 int IntOrFpCost = ScalarType->isFloatingPointTy() ? 0 : 1;
5131 return ShuffleCost + IntOrFpCost + RegisterFileMoveCost;
5132 }
5133
5134 return BaseT::getVectorInstrCost(Opcode, Val, CostKind, Index, Op0, Op1,
5135 VIC) +
5136 RegisterFileMoveCost;
5137}
5138
5140 VectorType *Ty, const APInt &DemandedElts, bool Insert, bool Extract,
5141 TTI::TargetCostKind CostKind, bool ForPoisonSrc, ArrayRef<Value *> VL,
5142 TTI::VectorInstrContext VIC) const {
5143 assert(DemandedElts.getBitWidth() ==
5144 cast<FixedVectorType>(Ty)->getNumElements() &&
5145 "Vector size mismatch");
5146
5147 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Ty);
5148 MVT MScalarTy = LT.second.getScalarType();
5149 unsigned LegalVectorBitWidth = LT.second.getSizeInBits();
5151
5152 constexpr unsigned LaneBitWidth = 128;
5153 assert((LegalVectorBitWidth < LaneBitWidth ||
5154 (LegalVectorBitWidth % LaneBitWidth) == 0) &&
5155 "Illegal vector");
5156
5157 const int NumLegalVectors = LT.first.getValue();
5158 assert(NumLegalVectors >= 0 && "Negative cost!");
5159
5160 // For insertions, a ISD::BUILD_VECTOR style vector initialization can be much
5161 // cheaper than an accumulation of ISD::INSERT_VECTOR_ELT. SLPVectorizer has
5162 // a special heuristic regarding poison input which is passed here in
5163 // ForPoisonSrc.
5164 if (Insert && !ForPoisonSrc) {
5165 // This is nearly identical to BaseT::getScalarizationOverhead(), except
5166 // it is passing nullptr to getVectorInstrCost() for Op0 (instead of
5167 // Constant::getNullValue()), which makes the X86TTIImpl
5168 // getVectorInstrCost() return 0 instead of 1.
5169 for (unsigned I : seq(DemandedElts.getBitWidth())) {
5170 if (!DemandedElts[I])
5171 continue;
5172 Cost += getVectorInstrCost(Instruction::InsertElement, Ty, CostKind, I,
5174 VL.empty() ? nullptr : VL[I],
5176 }
5177 return Cost;
5178 }
5179
5180 if (Insert) {
5181 if ((MScalarTy == MVT::i16 && ST->hasSSE2()) ||
5182 (MScalarTy.isInteger() && ST->hasSSE41()) ||
5183 (MScalarTy == MVT::f32 && ST->hasSSE41())) {
5184 // For types we can insert directly, insertion into 128-bit sub vectors is
5185 // cheap, followed by a cheap chain of concatenations.
5186 if (LegalVectorBitWidth <= LaneBitWidth) {
5187 Cost += BaseT::getScalarizationOverhead(Ty, DemandedElts, Insert,
5188 /*Extract*/ false, CostKind);
5189 } else {
5190 // In each 128-lane, if at least one index is demanded but not all
5191 // indices are demanded and this 128-lane is not the first 128-lane of
5192 // the legalized-vector, then this 128-lane needs a extracti128; If in
5193 // each 128-lane, there is at least one demanded index, this 128-lane
5194 // needs a inserti128.
5195
5196 // The following cases will help you build a better understanding:
5197 // Assume we insert several elements into a v8i32 vector in avx2,
5198 // Case#1: inserting into 1th index needs vpinsrd + inserti128.
5199 // Case#2: inserting into 5th index needs extracti128 + vpinsrd +
5200 // inserti128.
5201 // Case#3: inserting into 4,5,6,7 index needs 4*vpinsrd + inserti128.
5202 assert((LegalVectorBitWidth % LaneBitWidth) == 0 && "Illegal vector");
5203 unsigned NumLegalLanes = LegalVectorBitWidth / LaneBitWidth;
5204 unsigned NumLanesTotal = NumLegalLanes * NumLegalVectors;
5205 unsigned NumLegalElts =
5206 LT.second.getVectorNumElements() * NumLegalVectors;
5207 assert(NumLegalElts >= DemandedElts.getBitWidth() &&
5208 "Vector has been legalized to smaller element count");
5209 assert((NumLegalElts % NumLanesTotal) == 0 &&
5210 "Unexpected elts per lane");
5211 unsigned NumEltsPerLane = NumLegalElts / NumLanesTotal;
5212
5213 APInt WidenedDemandedElts = DemandedElts.zext(NumLegalElts);
5214 auto *LaneTy =
5215 FixedVectorType::get(Ty->getElementType(), NumEltsPerLane);
5216
5217 for (unsigned I = 0; I != NumLanesTotal; ++I) {
5218 APInt LaneEltMask = WidenedDemandedElts.extractBits(
5219 NumEltsPerLane, NumEltsPerLane * I);
5220 if (LaneEltMask.isZero())
5221 continue;
5222 // FIXME: we don't need to extract if all non-demanded elements
5223 // are legalization-inserted padding.
5224 if (!LaneEltMask.isAllOnes())
5226 CostKind, I * NumEltsPerLane, LaneTy);
5227 Cost += BaseT::getScalarizationOverhead(LaneTy, LaneEltMask, Insert,
5228 /*Extract*/ false, CostKind);
5229 }
5230
5231 APInt AffectedLanes =
5232 APIntOps::ScaleBitMask(WidenedDemandedElts, NumLanesTotal);
5233 APInt FullyAffectedLegalVectors = APIntOps::ScaleBitMask(
5234 AffectedLanes, NumLegalVectors, /*MatchAllBits=*/true);
5235 for (int LegalVec = 0; LegalVec != NumLegalVectors; ++LegalVec) {
5236 for (unsigned Lane = 0; Lane != NumLegalLanes; ++Lane) {
5237 unsigned I = NumLegalLanes * LegalVec + Lane;
5238 // No need to insert unaffected lane; or lane 0 of each legal vector
5239 // iff ALL lanes of that vector were affected and will be inserted.
5240 if (!AffectedLanes[I] ||
5241 (Lane == 0 && FullyAffectedLegalVectors[LegalVec]))
5242 continue;
5244 CostKind, I * NumEltsPerLane, LaneTy);
5245 }
5246 }
5247 }
5248 } else if (LT.second.isVector()) {
5249 // Without fast insertion, we need to use MOVD/MOVQ to pass each demanded
5250 // integer element as a SCALAR_TO_VECTOR, then we build the vector as a
5251 // series of UNPCK followed by CONCAT_VECTORS - all of these can be
5252 // considered cheap.
5253 if (Ty->isIntOrIntVectorTy())
5254 Cost += DemandedElts.popcount();
5255
5256 // Get the smaller of the legalized or original pow2-extended number of
5257 // vector elements, which represents the number of unpacks we'll end up
5258 // performing.
5259 unsigned NumElts = LT.second.getVectorNumElements();
5260 unsigned Pow2Elts =
5261 PowerOf2Ceil(cast<FixedVectorType>(Ty)->getNumElements());
5262 Cost += (std::min<unsigned>(NumElts, Pow2Elts) - 1) * LT.first;
5263 }
5264 }
5265
5266 if (Extract) {
5267 // vXi1 can be efficiently extracted with MOVMSK.
5268 // TODO: AVX512 predicate mask handling.
5269 // NOTE: This doesn't work well for roundtrip scalarization.
5270 if (!Insert && Ty->getScalarSizeInBits() == 1 && !ST->hasAVX512()) {
5271 unsigned NumElts = cast<FixedVectorType>(Ty)->getNumElements();
5272 unsigned MaxElts = ST->hasAVX2() ? 32 : 16;
5273 unsigned MOVMSKCost = (NumElts + MaxElts - 1) / MaxElts;
5274 return MOVMSKCost;
5275 }
5276
5277 if (LT.second.isVector()) {
5278 unsigned NumLegalElts =
5279 LT.second.getVectorNumElements() * NumLegalVectors;
5280 assert(NumLegalElts >= DemandedElts.getBitWidth() &&
5281 "Vector has been legalized to smaller element count");
5282
5283 // If we're extracting elements from a 128-bit subvector lane,
5284 // we only need to extract each lane once, not for every element.
5285 if (LegalVectorBitWidth > LaneBitWidth) {
5286 unsigned NumLegalLanes = LegalVectorBitWidth / LaneBitWidth;
5287 unsigned NumLanesTotal = NumLegalLanes * NumLegalVectors;
5288 assert((NumLegalElts % NumLanesTotal) == 0 &&
5289 "Unexpected elts per lane");
5290 unsigned NumEltsPerLane = NumLegalElts / NumLanesTotal;
5291
5292 // Add cost for each demanded 128-bit subvector extraction.
5293 // Luckily this is a lot easier than for insertion.
5294 APInt WidenedDemandedElts = DemandedElts.zext(NumLegalElts);
5295 auto *LaneTy =
5296 FixedVectorType::get(Ty->getElementType(), NumEltsPerLane);
5297
5298 for (unsigned I = 0; I != NumLanesTotal; ++I) {
5299 APInt LaneEltMask = WidenedDemandedElts.extractBits(
5300 NumEltsPerLane, I * NumEltsPerLane);
5301 if (LaneEltMask.isZero())
5302 continue;
5304 I * NumEltsPerLane, LaneTy);
5306 LaneTy, LaneEltMask, /*Insert*/ false, Extract, CostKind);
5307 }
5308
5309 return Cost;
5310 }
5311 }
5312
5313 // Fallback to default extraction.
5314 Cost += BaseT::getScalarizationOverhead(Ty, DemandedElts, /*Insert*/ false,
5315 Extract, CostKind);
5316 }
5317
5318 return Cost;
5319}
5320
5322X86TTIImpl::getReplicationShuffleCost(Type *EltTy, int ReplicationFactor,
5323 int VF, const APInt &DemandedDstElts,
5325 const unsigned EltTyBits = DL.getTypeSizeInBits(EltTy);
5326 // We don't differentiate element types here, only element bit width.
5327 EltTy = IntegerType::getIntNTy(EltTy->getContext(), EltTyBits);
5328
5329 auto bailout = [&]() {
5330 return BaseT::getReplicationShuffleCost(EltTy, ReplicationFactor, VF,
5331 DemandedDstElts, CostKind);
5332 };
5333
5334 // For now, only deal with AVX512 cases.
5335 if (!ST->hasAVX512())
5336 return bailout();
5337
5338 // Do we have a native shuffle for this element type, or should we promote?
5339 unsigned PromEltTyBits = EltTyBits;
5340 switch (EltTyBits) {
5341 case 32:
5342 case 64:
5343 break; // AVX512F.
5344 case 16:
5345 if (!ST->hasBWI())
5346 PromEltTyBits = 32; // promote to i32, AVX512F.
5347 break; // AVX512BW
5348 case 8:
5349 if (!ST->hasVBMI())
5350 PromEltTyBits = 32; // promote to i32, AVX512F.
5351 break; // AVX512VBMI
5352 case 1:
5353 // There is no support for shuffling i1 elements. We *must* promote.
5354 if (ST->hasBWI()) {
5355 if (ST->hasVBMI())
5356 PromEltTyBits = 8; // promote to i8, AVX512VBMI.
5357 else
5358 PromEltTyBits = 16; // promote to i16, AVX512BW.
5359 break;
5360 }
5361 PromEltTyBits = 32; // promote to i32, AVX512F.
5362 break;
5363 default:
5364 return bailout();
5365 }
5366 auto *PromEltTy = IntegerType::getIntNTy(EltTy->getContext(), PromEltTyBits);
5367
5368 auto *SrcVecTy = FixedVectorType::get(EltTy, VF);
5369 auto *PromSrcVecTy = FixedVectorType::get(PromEltTy, VF);
5370
5371 int NumDstElements = VF * ReplicationFactor;
5372 auto *PromDstVecTy = FixedVectorType::get(PromEltTy, NumDstElements);
5373 auto *DstVecTy = FixedVectorType::get(EltTy, NumDstElements);
5374
5375 // Legalize the types.
5376 MVT LegalSrcVecTy = getTypeLegalizationCost(SrcVecTy).second;
5377 MVT LegalPromSrcVecTy = getTypeLegalizationCost(PromSrcVecTy).second;
5378 MVT LegalPromDstVecTy = getTypeLegalizationCost(PromDstVecTy).second;
5379 MVT LegalDstVecTy = getTypeLegalizationCost(DstVecTy).second;
5380 // They should have legalized into vector types.
5381 if (!LegalSrcVecTy.isVector() || !LegalPromSrcVecTy.isVector() ||
5382 !LegalPromDstVecTy.isVector() || !LegalDstVecTy.isVector())
5383 return bailout();
5384
5385 if (PromEltTyBits != EltTyBits) {
5386 // If we have to perform the shuffle with wider elt type than our data type,
5387 // then we will first need to anyext (we don't care about the new bits)
5388 // the source elements, and then truncate Dst elements.
5389 InstructionCost PromotionCost;
5390 PromotionCost += getCastInstrCost(
5391 Instruction::SExt, /*Dst=*/PromSrcVecTy, /*Src=*/SrcVecTy,
5393 PromotionCost +=
5394 getCastInstrCost(Instruction::Trunc, /*Dst=*/DstVecTy,
5395 /*Src=*/PromDstVecTy,
5397 return PromotionCost + getReplicationShuffleCost(PromEltTy,
5398 ReplicationFactor, VF,
5399 DemandedDstElts, CostKind);
5400 }
5401
5402 assert(LegalSrcVecTy.getScalarSizeInBits() == EltTyBits &&
5403 LegalSrcVecTy.getScalarType() == LegalDstVecTy.getScalarType() &&
5404 "We expect that the legalization doesn't affect the element width, "
5405 "doesn't coalesce/split elements.");
5406
5407 unsigned NumEltsPerDstVec = LegalDstVecTy.getVectorNumElements();
5408 unsigned NumDstVectors =
5409 divideCeil(DstVecTy->getNumElements(), NumEltsPerDstVec);
5410
5411 auto *SingleDstVecTy = FixedVectorType::get(EltTy, NumEltsPerDstVec);
5412
5413 // Not all the produced Dst elements may be demanded. In our case,
5414 // given that a single Dst vector is formed by a single shuffle,
5415 // if all elements that will form a single Dst vector aren't demanded,
5416 // then we won't need to do that shuffle, so adjust the cost accordingly.
5417 APInt DemandedDstVectors = APIntOps::ScaleBitMask(
5418 DemandedDstElts.zext(NumDstVectors * NumEltsPerDstVec), NumDstVectors);
5419 unsigned NumDstVectorsDemanded = DemandedDstVectors.popcount();
5420
5421 InstructionCost SingleShuffleCost =
5422 getShuffleCost(TTI::SK_PermuteSingleSrc, SingleDstVecTy, SingleDstVecTy,
5423 /*Mask=*/{}, CostKind,
5424 /*Index=*/0, /*SubTp=*/nullptr);
5425 return NumDstVectorsDemanded * SingleShuffleCost;
5426}
5427
5429 Align Alignment,
5430 unsigned AddressSpace,
5432 TTI::OperandValueInfo OpInfo,
5433 const Instruction *I) const {
5434 // FIXME: Load latency isn't handled here
5435 if (Opcode == Instruction::Load && CostKind == TTI::TCK_Latency)
5436 return BaseT::getMemoryOpCost(Opcode, Src, Alignment, AddressSpace,
5437 CostKind, OpInfo, I);
5438
5439 // TODO: Handle other cost kinds.
5441 if (auto *SI = dyn_cast_or_null<StoreInst>(I)) {
5442 // Store instruction with index and scale costs 2 Uops.
5443 // Check the preceding GEP to identify non-const indices.
5444 if (auto *GEP = dyn_cast<GetElementPtrInst>(SI->getPointerOperand())) {
5445 if (!all_of(GEP->indices(), [](Value *V) { return isa<Constant>(V); }))
5446 return TTI::TCC_Basic * 2;
5447 }
5448 }
5449 return TTI::TCC_Basic;
5450 }
5451
5452 assert((Opcode == Instruction::Load || Opcode == Instruction::Store) &&
5453 "Invalid Opcode");
5454 // Type legalization can't handle structs
5455 if (TLI->getValueType(DL, Src, true) == MVT::Other)
5456 return BaseT::getMemoryOpCost(Opcode, Src, Alignment, AddressSpace,
5457 CostKind, OpInfo, I);
5458
5459 // Legalize the type.
5460 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Src);
5461
5462 auto *VTy = dyn_cast<FixedVectorType>(Src);
5463
5465
5466 // Add a cost for constant load to vector.
5467 if (Opcode == Instruction::Store && OpInfo.isConstant())
5468 Cost += getMemoryOpCost(Instruction::Load, Src, DL.getABITypeAlign(Src),
5469 /*AddressSpace=*/0, CostKind, OpInfo);
5470
5471 // Handle the simple case of non-vectors.
5472 // NOTE: this assumes that legalization never creates vector from scalars!
5473 if (!VTy || !LT.second.isVector()) {
5474 // Each load/store unit costs 1.
5475 return (LT.second.isFloatingPoint() ? Cost : 0) + LT.first * 1;
5476 }
5477
5478 bool IsLoad = Opcode == Instruction::Load;
5479
5480 Type *EltTy = VTy->getElementType();
5481
5482 const int EltTyBits = DL.getTypeSizeInBits(EltTy);
5483
5484 // Source of truth: how many elements were there in the original IR vector?
5485 const unsigned SrcNumElt = VTy->getNumElements();
5486
5487 // How far have we gotten?
5488 int NumEltRemaining = SrcNumElt;
5489 // Note that we intentionally capture by-reference, NumEltRemaining changes.
5490 auto NumEltDone = [&]() { return SrcNumElt - NumEltRemaining; };
5491
5492 const int MaxLegalOpSizeBytes = divideCeil(LT.second.getSizeInBits(), 8);
5493
5494 // Note that even if we can store 64 bits of an XMM, we still operate on XMM.
5495 const unsigned XMMBits = 128;
5496 if (XMMBits % EltTyBits != 0)
5497 // Vector size must be a multiple of the element size. I.e. no padding.
5498 return BaseT::getMemoryOpCost(Opcode, Src, Alignment, AddressSpace,
5499 CostKind, OpInfo, I);
5500 const int NumEltPerXMM = XMMBits / EltTyBits;
5501
5502 auto *XMMVecTy = FixedVectorType::get(EltTy, NumEltPerXMM);
5503
5504 for (int CurrOpSizeBytes = MaxLegalOpSizeBytes, SubVecEltsLeft = 0;
5505 NumEltRemaining > 0; CurrOpSizeBytes /= 2) {
5506 // How many elements would a single op deal with at once?
5507 if ((8 * CurrOpSizeBytes) % EltTyBits != 0)
5508 // Vector size must be a multiple of the element size. I.e. no padding.
5509 return BaseT::getMemoryOpCost(Opcode, Src, Alignment, AddressSpace,
5510 CostKind, OpInfo, I);
5511 int CurrNumEltPerOp = (8 * CurrOpSizeBytes) / EltTyBits;
5512
5513 assert(CurrOpSizeBytes > 0 && CurrNumEltPerOp > 0 && "How'd we get here?");
5514 assert((((NumEltRemaining * EltTyBits) < (2 * 8 * CurrOpSizeBytes)) ||
5515 (CurrOpSizeBytes == MaxLegalOpSizeBytes)) &&
5516 "Unless we haven't halved the op size yet, "
5517 "we have less than two op's sized units of work left.");
5518
5519 auto *CurrVecTy = CurrNumEltPerOp > NumEltPerXMM
5520 ? FixedVectorType::get(EltTy, CurrNumEltPerOp)
5521 : XMMVecTy;
5522
5523 assert(CurrVecTy->getNumElements() % CurrNumEltPerOp == 0 &&
5524 "After halving sizes, the vector elt count is no longer a multiple "
5525 "of number of elements per operation?");
5526 auto *CoalescedVecTy =
5527 CurrNumEltPerOp == 1
5528 ? CurrVecTy
5530 IntegerType::get(Src->getContext(),
5531 EltTyBits * CurrNumEltPerOp),
5532 CurrVecTy->getNumElements() / CurrNumEltPerOp);
5533 assert(DL.getTypeSizeInBits(CoalescedVecTy) ==
5534 DL.getTypeSizeInBits(CurrVecTy) &&
5535 "coalesciing elements doesn't change vector width.");
5536
5537 while (NumEltRemaining > 0) {
5538 assert(SubVecEltsLeft >= 0 && "Subreg element count overconsumtion?");
5539
5540 // Can we use this vector size, as per the remaining element count?
5541 // Iff the vector is naturally aligned, we can do a wide load regardless.
5542 if (NumEltRemaining < CurrNumEltPerOp &&
5543 (!IsLoad || Alignment < CurrOpSizeBytes) && CurrOpSizeBytes != 1)
5544 break; // Try smalled vector size.
5545
5546 // This isn't exactly right. We're using slow unaligned 32-byte accesses
5547 // as a proxy for a double-pumped AVX memory interface such as on
5548 // Sandybridge.
5549 // Sub-32-bit loads/stores will be slower either with PINSR*/PEXTR* or
5550 // will be scalarized.
5551 if (CurrOpSizeBytes == 32 && ST->isUnalignedMem32Slow())
5552 Cost += 2;
5553 else if (CurrOpSizeBytes < 4)
5554 Cost += 2;
5555 else
5556 Cost += 1;
5557
5558 // If we're loading a uniform value, then we don't need to split the load,
5559 // loading just a single (widest) vector can be reused by all splits.
5560 if (IsLoad && OpInfo.isUniform())
5561 return Cost;
5562
5563 bool Is0thSubVec = (NumEltDone() % LT.second.getVectorNumElements()) == 0;
5564
5565 // If we have fully processed the previous reg, we need to replenish it.
5566 if (SubVecEltsLeft == 0) {
5567 SubVecEltsLeft += CurrVecTy->getNumElements();
5568 // And that's free only for the 0'th subvector of a legalized vector.
5569 if (!Is0thSubVec)
5570 Cost +=
5573 VTy, VTy, {}, CostKind, NumEltDone(), CurrVecTy);
5574 }
5575
5576 // While we can directly load/store ZMM, YMM, and 64-bit halves of XMM,
5577 // for smaller widths (32/16/8) we have to insert/extract them separately.
5578 // Again, it's free for the 0'th subreg (if op is 32/64 bit wide,
5579 // but let's pretend that it is also true for 16/8 bit wide ops...)
5580 if (CurrOpSizeBytes <= 32 / 8 && !Is0thSubVec) {
5581 int NumEltDoneInCurrXMM = NumEltDone() % NumEltPerXMM;
5582 assert(NumEltDoneInCurrXMM % CurrNumEltPerOp == 0 && "");
5583 int CoalescedVecEltIdx = NumEltDoneInCurrXMM / CurrNumEltPerOp;
5584 APInt DemandedElts =
5585 APInt::getBitsSet(CoalescedVecTy->getNumElements(),
5586 CoalescedVecEltIdx, CoalescedVecEltIdx + 1);
5587 assert(DemandedElts.popcount() == 1 && "Inserting single value");
5588 Cost += getScalarizationOverhead(CoalescedVecTy, DemandedElts, IsLoad,
5589 !IsLoad, CostKind);
5590 }
5591
5592 SubVecEltsLeft -= CurrNumEltPerOp;
5593 NumEltRemaining -= CurrNumEltPerOp;
5594 Alignment = commonAlignment(Alignment, CurrOpSizeBytes);
5595 }
5596 }
5597
5598 assert(NumEltRemaining <= 0 && "Should have processed all the elements.");
5599
5600 return Cost;
5601}
5602
5606 switch (MICA.getID()) {
5607 case Intrinsic::masked_scatter:
5608 case Intrinsic::masked_gather:
5609 return getGatherScatterOpCost(MICA, CostKind);
5610 case Intrinsic::masked_load:
5611 case Intrinsic::masked_store:
5612 return getMaskedMemoryOpCost(MICA, CostKind);
5613 }
5615}
5616
5620 unsigned Opcode = MICA.getID() == Intrinsic::masked_load ? Instruction::Load
5621 : Instruction::Store;
5622 Type *SrcTy = MICA.getDataType();
5623 Align Alignment = MICA.getAlignment();
5624 unsigned AddressSpace = MICA.getAddressSpace();
5625
5626 bool IsLoad = (Instruction::Load == Opcode);
5627 bool IsStore = (Instruction::Store == Opcode);
5628
5629 auto *SrcVTy = dyn_cast<FixedVectorType>(SrcTy);
5630 if (!SrcVTy)
5631 // To calculate scalar take the regular cost, without mask
5632 return getMemoryOpCost(Opcode, SrcTy, Alignment, AddressSpace, CostKind);
5633
5634 unsigned NumElem = SrcVTy->getNumElements();
5635 auto *MaskTy =
5636 FixedVectorType::get(Type::getInt8Ty(SrcVTy->getContext()), NumElem);
5637 if ((IsLoad && !isLegalMaskedLoad(SrcVTy, Alignment, AddressSpace)) ||
5638 (IsStore && !isLegalMaskedStore(SrcVTy, Alignment, AddressSpace))) {
5639 // Scalarization
5640 APInt DemandedElts = APInt::getAllOnes(NumElem);
5642 MaskTy, DemandedElts, /*Insert*/ false, /*Extract*/ true, CostKind);
5643 InstructionCost ScalarCompareCost = getCmpSelInstrCost(
5644 Instruction::ICmp, Type::getInt8Ty(SrcVTy->getContext()), nullptr,
5646 InstructionCost BranchCost = getCFInstrCost(Instruction::CondBr, CostKind);
5647 InstructionCost MaskCmpCost = NumElem * (BranchCost + ScalarCompareCost);
5649 SrcVTy, DemandedElts, IsLoad, IsStore, CostKind);
5650 InstructionCost MemopCost =
5651 NumElem * BaseT::getMemoryOpCost(Opcode, SrcVTy->getScalarType(),
5652 Alignment, AddressSpace, CostKind);
5653 return MemopCost + ValueSplitCost + MaskSplitCost + MaskCmpCost;
5654 }
5655
5656 // Legalize the type.
5657 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(SrcVTy);
5658 auto VT = TLI->getValueType(DL, SrcVTy);
5660 MVT Ty = LT.second;
5661 if (Ty == MVT::i16 || Ty == MVT::i32 || Ty == MVT::i64)
5662 // APX masked load/store for scalar is cheap.
5663 return Cost + LT.first;
5664
5665 if (VT.isSimple() && Ty != VT.getSimpleVT() &&
5666 LT.second.getVectorNumElements() == NumElem)
5667 // Promotion requires extend/truncate for data and a shuffle for mask.
5668 Cost += getShuffleCost(TTI::SK_PermuteTwoSrc, SrcVTy, SrcVTy, {}, CostKind,
5669 0, nullptr) +
5670 getShuffleCost(TTI::SK_PermuteTwoSrc, MaskTy, MaskTy, {}, CostKind,
5671 0, nullptr);
5672
5673 else if (LT.first * Ty.getVectorNumElements() > NumElem) {
5674 auto *NewMaskTy = FixedVectorType::get(MaskTy->getElementType(),
5675 (unsigned)LT.first.getValue() *
5676 Ty.getVectorNumElements());
5677 // Expanding requires fill mask with zeroes
5678 Cost += getShuffleCost(TTI::SK_InsertSubvector, NewMaskTy, NewMaskTy, {},
5679 CostKind, 0, MaskTy);
5680 }
5681
5682 // Pre-AVX512 - each maskmov load costs 2 + store costs ~8.
5683 if (!ST->hasAVX512())
5684 return Cost + LT.first * (IsLoad ? 2 : 8);
5685
5686 // AVX-512 masked load/store is cheaper
5687 return Cost + LT.first;
5688}
5689
5691 ArrayRef<const Value *> Ptrs, const Value *Base,
5692 const TTI::PointersChainInfo &Info, Type *AccessTy,
5693 const TTI::TargetCostKind CostKind) const {
5694 if (Info.isSameBase() && Info.isKnownStride()) {
5695 // If all the pointers have known stride all the differences are translated
5696 // into constants. X86 memory addressing allows encoding it into
5697 // displacement. So we just need to take the base GEP cost.
5698 if (const auto *BaseGEP = dyn_cast<GetElementPtrInst>(Base)) {
5699 SmallVector<const Value *> Indices(BaseGEP->indices());
5700 return getGEPCost(BaseGEP->getSourceElementType(),
5701 BaseGEP->getPointerOperand(), Indices, nullptr,
5702 CostKind);
5703 }
5704 return TTI::TCC_Free;
5705 }
5706 return BaseT::getPointersChainCost(Ptrs, Base, Info, AccessTy, CostKind);
5707}
5708
5711 const SCEV *Ptr,
5713 // Address computations in vectorized code with non-consecutive addresses will
5714 // likely result in more instructions compared to scalar code where the
5715 // computation can more often be merged into the index mode. The resulting
5716 // extra micro-ops can significantly decrease throughput.
5717 const unsigned NumVectorInstToHideOverhead = 10;
5718
5719 // Cost modeling of Strided Access Computation is hidden by the indexing
5720 // modes of X86 regardless of the stride value. We dont believe that there
5721 // is a difference between constant strided access in gerenal and constant
5722 // strided value which is less than or equal to 64.
5723 // Even in the case of (loop invariant) stride whose value is not known at
5724 // compile time, the address computation will not incur more than one extra
5725 // ADD instruction.
5726 if (PtrTy->isVectorTy() && SE && !ST->hasAVX2()) {
5727 // TODO: AVX2 is the current cut-off because we don't have correct
5728 // interleaving costs for prior ISA's.
5729 if (!BaseT::isStridedAccess(Ptr))
5730 return NumVectorInstToHideOverhead;
5731 if (!BaseT::getConstantStrideStep(SE, Ptr))
5732 return 1;
5733 }
5734
5735 return BaseT::getAddressComputationCost(PtrTy, SE, Ptr, CostKind);
5736}
5737
5740 std::optional<FastMathFlags> FMF,
5743 return BaseT::getArithmeticReductionCost(Opcode, ValTy, FMF, CostKind);
5744
5745 // We use llvm-mca across all supported CPUs to measure the logic cost stats.
5746 // We use the Intel Architecture Code Analyzer(IACA) to measure the throughput
5747 // and make it as the cost. TODO: Update old IACA numbers to llvm-mca.
5748
5749 static const CostKindTblEntry SLMCostTbl[] = {
5750 { ISD::FADD, MVT::v2f64, {3, 3, 3, 3} },
5751 { ISD::ADD, MVT::v2i64, {5, 5, 5, 5} },
5752 };
5753
5754 static const CostKindTblEntry SSE2CostTbl[] = {
5755 { ISD::FADD, MVT::v2f64, {2, 2, 2, 2} },
5756 { ISD::FADD, MVT::v2f32, {2, 2, 2, 2} },
5757 { ISD::FADD, MVT::v4f32, {4, 4, 4, 4} },
5758 { ISD::ADD, MVT::v2i64, {2, 2, 2, 2} }, // The data reported by the IACA tool is "1.6".
5759 { ISD::ADD, MVT::v2i32, {2, 2, 2, 2} }, // FIXME: chosen to be less than v4i32
5760 { ISD::ADD, MVT::v4i32, {3, 3, 3, 3} }, // The data reported by the IACA tool is "3.3".
5761 { ISD::ADD, MVT::v2i16, {2, 2, 2, 2} }, // The data reported by the IACA tool is "4.3".
5762 { ISD::ADD, MVT::v4i16, {3, 3, 3, 3} }, // The data reported by the IACA tool is "4.3".
5763 { ISD::ADD, MVT::v8i16, {4, 4, 4, 4} }, // The data reported by the IACA tool is "4.3".
5764 { ISD::ADD, MVT::v2i8, {2, 2, 2, 2} },
5765 { ISD::ADD, MVT::v4i8, {2, 2, 2, 2} },
5766 { ISD::ADD, MVT::v8i8, {2, 2, 2, 2} },
5767 { ISD::ADD, MVT::v16i8, {3, 3, 3, 3} },
5768
5769 { ISD::AND, MVT::v2i64, {2, 2, 3, 3} },
5770 { ISD::AND, MVT::v4i32, {3, 4, 5, 5} },
5771 { ISD::AND, MVT::v8i16, {4, 7, 8, 8} },
5772 { ISD::AND, MVT::v16i8, {6,10,11,11} },
5773 { ISD::OR, MVT::v2i64, {2, 2, 3, 3} },
5774 { ISD::OR, MVT::v4i32, {3, 4, 5, 5} },
5775 { ISD::OR, MVT::v8i16, {4, 7, 8, 8} },
5776 { ISD::OR, MVT::v16i8, {6,10,11,11} },
5777 { ISD::XOR, MVT::v2i64, {2, 2, 3, 3} },
5778 { ISD::XOR, MVT::v4i32, {3, 4, 5, 5} },
5779 { ISD::XOR, MVT::v8i16, {4, 7, 8, 8} },
5780 { ISD::XOR, MVT::v16i8, {6,10,11,11} },
5781 };
5782
5783 static const CostKindTblEntry AVX1CostTbl[] = {
5784 { ISD::FADD, MVT::v4f64, {3, 3, 3, 3} },
5785 { ISD::FADD, MVT::v4f32, {3, 3, 3, 3} },
5786 { ISD::FADD, MVT::v8f32, {4, 4, 4, 4} },
5787 { ISD::ADD, MVT::v2i64, {1, 1, 1, 1} }, // The data reported by the IACA tool is "1.5".
5788 { ISD::ADD, MVT::v4i64, {3, 3, 3, 3} },
5789 { ISD::ADD, MVT::v8i32, {5, 5, 5, 5} },
5790 { ISD::ADD, MVT::v16i16, {5, 5, 5, 5} },
5791 { ISD::ADD, MVT::v32i8, {4, 4, 4, 4} },
5792
5793 { ISD::AND, MVT::v4i64, {3, 7, 5, 5} },
5794 { ISD::AND, MVT::v8i32, {4, 9, 7, 7} },
5795 { ISD::AND, MVT::v16i16, {5,11, 9, 9} },
5796 { ISD::AND, MVT::v8i16, {4, 7, 7, 7} },
5797 { ISD::AND, MVT::v32i8, {6,13,11,11} },
5798 { ISD::AND, MVT::v16i8, {5,10, 9, 9} },
5799 { ISD::OR, MVT::v4i64, {3, 7, 5, 5} },
5800 { ISD::OR, MVT::v8i32, {4, 9, 7, 7} },
5801 { ISD::OR, MVT::v16i16, {5,11, 9, 9} },
5802 { ISD::OR, MVT::v8i16, {4, 7, 7, 7} },
5803 { ISD::OR, MVT::v32i8, {6,13,11,11} },
5804 { ISD::OR, MVT::v16i8, {5,10, 9, 9} },
5805 { ISD::XOR, MVT::v4i64, {3, 7, 5, 5} },
5806 { ISD::XOR, MVT::v8i32, {4, 9, 7, 7} },
5807 { ISD::XOR, MVT::v16i16, {5,11, 9, 9} },
5808 { ISD::XOR, MVT::v8i16, {4, 7, 7, 7} },
5809 { ISD::XOR, MVT::v32i8, {6,13,11,11} },
5810 { ISD::XOR, MVT::v16i8, {5,10, 9, 9} },
5811 };
5812
5813 static const CostKindTblEntry AVX2CostTbl[] = {
5814 { ISD::AND, MVT::v4i64, {2, 7, 5, 5} },
5815 { ISD::AND, MVT::v2i64, {1, 2, 3, 3} },
5816 { ISD::AND, MVT::v8i32, {3, 9, 7, 7} },
5817 { ISD::AND, MVT::v4i32, {2, 4, 5, 5} },
5818 { ISD::AND, MVT::v16i16, {3,11, 9, 9} },
5819 { ISD::AND, MVT::v8i16, {2, 6, 7, 7} },
5820 { ISD::AND, MVT::v32i8, {3,13,11,11} },
5821 { ISD::AND, MVT::v16i8, {3, 8, 9, 9} },
5822 { ISD::OR, MVT::v4i64, {2, 7, 5, 5} },
5823 { ISD::OR, MVT::v2i64, {1, 2, 3, 3} },
5824 { ISD::OR, MVT::v8i32, {3, 9, 7, 7} },
5825 { ISD::OR, MVT::v4i32, {2, 4, 5, 5} },
5826 { ISD::OR, MVT::v16i16, {3,11, 9, 9} },
5827 { ISD::OR, MVT::v8i16, {2, 6, 7, 7} },
5828 { ISD::OR, MVT::v32i8, {3,13,11,11} },
5829 { ISD::OR, MVT::v16i8, {3, 8, 9, 9} },
5830 { ISD::XOR, MVT::v4i64, {2, 7, 5, 5} },
5831 { ISD::XOR, MVT::v2i64, {1, 2, 3, 3} },
5832 { ISD::XOR, MVT::v8i32, {3, 9, 7, 7} },
5833 { ISD::XOR, MVT::v4i32, {2, 4, 5, 5} },
5834 { ISD::XOR, MVT::v16i16, {3,11, 9, 9} },
5835 { ISD::XOR, MVT::v8i16, {2, 6, 7, 7} },
5836 { ISD::XOR, MVT::v32i8, {3,13,11,11} },
5837 { ISD::XOR, MVT::v16i8, {3, 8, 9, 9} },
5838 };
5839
5840 static const CostKindTblEntry AVX512FCostTbl[] = {
5841 { ISD::FADD, MVT::v8f64, {4, 4, 4, 4} },
5842 { ISD::FADD, MVT::v16f32, {5, 5, 5, 5} },
5843 { ISD::ADD, MVT::v8i64, {4, 4, 4, 4} },
5844 { ISD::ADD, MVT::v16i32, {6, 6, 6, 6} },
5845
5846 { ISD::AND, MVT::v8i64, {3,10, 7, 7} },
5847 { ISD::AND, MVT::v16i32, {4,12, 9, 9} },
5848 { ISD::AND, MVT::v32i16, {4,14,11,11} },
5849 { ISD::AND, MVT::v64i8, {4,16,13,13} },
5850 { ISD::AND, MVT::v16i8, {2, 8, 9, 9} },
5851 { ISD::OR, MVT::v8i64, {3,10, 7, 7} },
5852 { ISD::OR, MVT::v16i32, {4,12, 9, 9} },
5853 { ISD::OR, MVT::v32i16, {4,14,11,11} },
5854 { ISD::OR, MVT::v64i8, {4,16,13,13} },
5855 { ISD::OR, MVT::v16i8, {2, 8, 9, 9} },
5856 { ISD::XOR, MVT::v8i64, {3,10, 7, 7} },
5857 { ISD::XOR, MVT::v16i32, {4,12, 9, 9} },
5858 { ISD::XOR, MVT::v32i16, {4,14,11,11} },
5859 { ISD::XOR, MVT::v64i8, {4,16,13,13} },
5860 { ISD::XOR, MVT::v16i8, {2, 8, 9, 9} },
5861 };
5862
5863 static const CostKindTblEntry AVX512BWCostTbl[] = {
5864 { ISD::ADD, MVT::v32i16, {7, 7, 7, 7} },
5865 { ISD::ADD, MVT::v64i8, {4, 4, 4, 4} },
5866 };
5867
5868 int ISD = TLI->InstructionOpcodeToISD(Opcode);
5869 assert(ISD && "Invalid opcode");
5870
5871 // Before legalizing the type, give a chance to look up illegal narrow types
5872 // in the table.
5873 // FIXME: Is there a better way to do this?
5874 EVT VT = TLI->getValueType(DL, ValTy);
5875 if (VT.isSimple()) {
5876 MVT MTy = VT.getSimpleVT();
5877 if (ST->useSLMArithCosts())
5878 if (const auto *Entry = CostTableLookup(SLMCostTbl, ISD, MTy))
5879 if (auto KindCost = Entry->Cost[CostKind])
5880 return *KindCost;
5881
5882 if (ST->hasBWI())
5883 if (const auto *Entry = CostTableLookup(AVX512BWCostTbl, ISD, MTy))
5884 if (auto KindCost = Entry->Cost[CostKind])
5885 return *KindCost;
5886
5887 if (ST->hasAVX512())
5888 if (const auto *Entry = CostTableLookup(AVX512FCostTbl, ISD, MTy))
5889 if (auto KindCost = Entry->Cost[CostKind])
5890 return *KindCost;
5891
5892 if (ST->hasAVX2())
5893 if (const auto *Entry = CostTableLookup(AVX2CostTbl, ISD, MTy))
5894 if (auto KindCost = Entry->Cost[CostKind])
5895 return *KindCost;
5896
5897 if (ST->hasAVX())
5898 if (const auto *Entry = CostTableLookup(AVX1CostTbl, ISD, MTy))
5899 if (auto KindCost = Entry->Cost[CostKind])
5900 return *KindCost;
5901
5902 if (ST->hasSSE2())
5903 if (const auto *Entry = CostTableLookup(SSE2CostTbl, ISD, MTy))
5904 if (auto KindCost = Entry->Cost[CostKind])
5905 return *KindCost;
5906 }
5907
5908 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(ValTy);
5909
5910 MVT MTy = LT.second;
5911
5912 auto *ValVTy = cast<FixedVectorType>(ValTy);
5913
5914 InstructionCost ArithmeticCost = 0;
5915 if (LT.first != 1 && MTy.isVector() &&
5916 MTy.getVectorNumElements() < ValVTy->getNumElements()) {
5917 // Type needs to be split. We need LT.first - 1 arithmetic ops.
5918 auto *SingleOpTy = FixedVectorType::get(ValVTy->getElementType(),
5919 MTy.getVectorNumElements());
5920 ArithmeticCost = getArithmeticInstrCost(Opcode, SingleOpTy, CostKind);
5921 ArithmeticCost *= LT.first - 1;
5922 }
5923
5924 // FIXME: These assume a naive kshift+binop lowering, which is probably
5925 // conservative in most cases.
5926 static const CostKindTblEntry AVX512BoolReduction[] = {
5927 { ISD::AND, MVT::v2i1, { 3, 3, 3, 3} },
5928 { ISD::AND, MVT::v4i1, { 5, 5, 5, 5} },
5929 { ISD::AND, MVT::v8i1, { 7, 7, 7, 7} },
5930 { ISD::AND, MVT::v16i1, { 9, 9, 9, 9} },
5931 { ISD::AND, MVT::v32i1, {11,11,11,11} },
5932 { ISD::AND, MVT::v64i1, {13,13,13,13} },
5933 { ISD::OR, MVT::v2i1, { 3, 3, 3, 3} },
5934 { ISD::OR, MVT::v4i1, { 5, 5, 5, 5} },
5935 { ISD::OR, MVT::v8i1, { 7, 7, 7, 7} },
5936 { ISD::OR, MVT::v16i1, { 9, 9, 9, 9} },
5937 { ISD::OR, MVT::v32i1, {11,11,11,11} },
5938 { ISD::OR, MVT::v64i1, {13,13,13,13} },
5939 };
5940
5941 static const CostKindTblEntry AVX2BoolReduction[] = {
5942 { ISD::AND, MVT::v16i16, { 2, 2, 2, 2} }, // vpmovmskb + cmp
5943 { ISD::AND, MVT::v32i8, { 2, 2, 2, 2} }, // vpmovmskb + cmp
5944 { ISD::OR, MVT::v16i16, { 2, 2, 2, 2} }, // vpmovmskb + cmp
5945 { ISD::OR, MVT::v32i8, { 2, 2, 2, 2} }, // vpmovmskb + cmp
5946 };
5947
5948 static const CostKindTblEntry AVX1BoolReduction[] = {
5949 { ISD::AND, MVT::v4i64, {2, 2, 2, 2} }, // vmovmskpd + cmp
5950 { ISD::AND, MVT::v8i32, {2, 2, 2, 2} }, // vmovmskps + cmp
5951 { ISD::AND, MVT::v16i16, {4, 4, 4, 4} }, // vextractf128 + vpand + vpmovmskb + cmp
5952 { ISD::AND, MVT::v32i8, {4, 4, 4, 4} }, // vextractf128 + vpand + vpmovmskb + cmp
5953 { ISD::OR, MVT::v4i64, {2, 2, 2, 2} }, // vmovmskpd + cmp
5954 { ISD::OR, MVT::v8i32, {2, 2, 2, 2} }, // vmovmskps + cmp
5955 { ISD::OR, MVT::v16i16, {4, 4, 4, 4} }, // vextractf128 + vpor + vpmovmskb + cmp
5956 { ISD::OR, MVT::v32i8, {4, 4, 4, 4} }, // vextractf128 + vpor + vpmovmskb + cmp
5957 };
5958
5959 static const CostKindTblEntry SSE2BoolReduction[] = {
5960 { ISD::AND, MVT::v2i64, {2, 2, 2, 2} }, // movmskpd + cmp
5961 { ISD::AND, MVT::v4i32, {2, 2, 2, 2} }, // movmskps + cmp
5962 { ISD::AND, MVT::v8i16, {2, 2, 2, 2} }, // pmovmskb + cmp
5963 { ISD::AND, MVT::v16i8, {2, 2, 2, 2} }, // pmovmskb + cmp
5964 { ISD::OR, MVT::v2i64, {2, 2, 2, 2} }, // movmskpd + cmp
5965 { ISD::OR, MVT::v4i32, {2, 2, 2, 2} }, // movmskps + cmp
5966 { ISD::OR, MVT::v8i16, {2, 2, 2, 2} }, // pmovmskb + cmp
5967 { ISD::OR, MVT::v16i8, {2, 2, 2, 2} }, // pmovmskb + cmp
5968 };
5969
5970 // Handle bool allof/anyof vXi1 patterns before we check legal types.
5971 if (ValVTy->getElementType()->isIntegerTy(1)) {
5972 if (ISD == ISD::ADD) {
5973 // vXi1 addition reduction will bitcast to scalar and perform a popcount.
5974 auto *IntTy = IntegerType::getIntNTy(ValVTy->getContext(),
5975 ValVTy->getNumElements());
5976 IntrinsicCostAttributes ICA(Intrinsic::ctpop, IntTy, {IntTy});
5977 return getCastInstrCost(Instruction::BitCast, IntTy, ValVTy,
5979 CostKind) +
5981 }
5982
5983 if (ST->hasAVX512())
5984 if (const auto *Entry = CostTableLookup(AVX512BoolReduction, ISD, MTy))
5985 if (auto KindCost = Entry->Cost[CostKind])
5986 return ArithmeticCost + *KindCost;
5987 if (ST->hasAVX2())
5988 if (const auto *Entry = CostTableLookup(AVX2BoolReduction, ISD, MTy))
5989 if (auto KindCost = Entry->Cost[CostKind])
5990 return ArithmeticCost + *KindCost;
5991 if (ST->hasAVX())
5992 if (const auto *Entry = CostTableLookup(AVX1BoolReduction, ISD, MTy))
5993 if (auto KindCost = Entry->Cost[CostKind])
5994 return ArithmeticCost + *KindCost;
5995 if (ST->hasSSE2())
5996 if (const auto *Entry = CostTableLookup(SSE2BoolReduction, ISD, MTy))
5997 if (auto KindCost = Entry->Cost[CostKind])
5998 return ArithmeticCost + *KindCost;
5999
6000 return BaseT::getArithmeticReductionCost(Opcode, ValVTy, FMF, CostKind);
6001 }
6002
6003 // Special case: vXi8 mul reductions are performed as vXi16.
6004 if (ISD == ISD::MUL && MTy.getScalarType() == MVT::i8) {
6005 auto *WideSclTy = IntegerType::get(ValVTy->getContext(), 16);
6006 auto *WideVecTy = FixedVectorType::get(WideSclTy, ValVTy->getNumElements());
6007 return getCastInstrCost(Instruction::ZExt, WideVecTy, ValTy,
6009 CostKind) +
6010 getArithmeticReductionCost(Opcode, WideVecTy, FMF, CostKind);
6011 }
6012
6013 if (ST->useSLMArithCosts())
6014 if (const auto *Entry = CostTableLookup(SLMCostTbl, ISD, MTy))
6015 if (auto KindCost = Entry->Cost[CostKind])
6016 return ArithmeticCost + *KindCost;
6017
6018 if (ST->hasBWI())
6019 if (const auto *Entry = CostTableLookup(AVX512BWCostTbl, ISD, MTy))
6020 if (auto KindCost = Entry->Cost[CostKind])
6021 return ArithmeticCost + *KindCost;
6022
6023 if (ST->hasAVX512())
6024 if (const auto *Entry = CostTableLookup(AVX512FCostTbl, ISD, MTy))
6025 if (auto KindCost = Entry->Cost[CostKind])
6026 return ArithmeticCost + *KindCost;
6027
6028 if (ST->hasAVX2())
6029 if (const auto *Entry = CostTableLookup(AVX2CostTbl, ISD, MTy))
6030 if (auto KindCost = Entry->Cost[CostKind])
6031 return ArithmeticCost + *KindCost;
6032
6033 if (ST->hasAVX())
6034 if (const auto *Entry = CostTableLookup(AVX1CostTbl, ISD, MTy))
6035 if (auto KindCost = Entry->Cost[CostKind])
6036 return ArithmeticCost + *KindCost;
6037
6038 if (ST->hasSSE2())
6039 if (const auto *Entry = CostTableLookup(SSE2CostTbl, ISD, MTy))
6040 if (auto KindCost = Entry->Cost[CostKind])
6041 return ArithmeticCost + *KindCost;
6042
6043 unsigned NumVecElts = ValVTy->getNumElements();
6044 unsigned ScalarSize = ValVTy->getScalarSizeInBits();
6045
6046 // Special case power of 2 reductions where the scalar type isn't changed
6047 // by type legalization.
6048 if (!isPowerOf2_32(NumVecElts) || ScalarSize != MTy.getScalarSizeInBits())
6049 return BaseT::getArithmeticReductionCost(Opcode, ValVTy, FMF, CostKind);
6050
6051 InstructionCost ReductionCost = 0;
6052
6053 auto *Ty = ValVTy;
6054 if (LT.first != 1 && MTy.isVector() &&
6055 MTy.getVectorNumElements() < ValVTy->getNumElements()) {
6056 // Type needs to be split. We need LT.first - 1 arithmetic ops.
6057 Ty = FixedVectorType::get(ValVTy->getElementType(),
6058 MTy.getVectorNumElements());
6059 ReductionCost = getArithmeticInstrCost(Opcode, Ty, CostKind);
6060 ReductionCost *= LT.first - 1;
6061 NumVecElts = MTy.getVectorNumElements();
6062 }
6063
6064 // Now handle reduction with the legal type, taking into account size changes
6065 // at each level.
6066 while (NumVecElts > 1) {
6067 // Determine the size of the remaining vector we need to reduce.
6068 unsigned Size = NumVecElts * ScalarSize;
6069 NumVecElts /= 2;
6070 // If we're reducing from 256/512 bits, use an extract_subvector.
6071 if (Size > 128) {
6072 auto *SubTy = FixedVectorType::get(ValVTy->getElementType(), NumVecElts);
6073 ReductionCost += getShuffleCost(TTI::SK_ExtractSubvector, Ty, Ty, {},
6074 CostKind, NumVecElts, SubTy);
6075 Ty = SubTy;
6076 } else if (Size == 128) {
6077 // Reducing from 128 bits is a permute of v2f64/v2i64.
6078 FixedVectorType *ShufTy;
6079 if (ValVTy->isFloatingPointTy())
6080 ShufTy =
6081 FixedVectorType::get(Type::getDoubleTy(ValVTy->getContext()), 2);
6082 else
6083 ShufTy =
6084 FixedVectorType::get(Type::getInt64Ty(ValVTy->getContext()), 2);
6085 ReductionCost += getShuffleCost(TTI::SK_PermuteSingleSrc, ShufTy, ShufTy,
6086 {}, CostKind, 0, nullptr);
6087 } else if (Size == 64) {
6088 // Reducing from 64 bits is a shuffle of v4f32/v4i32.
6089 FixedVectorType *ShufTy;
6090 if (ValVTy->isFloatingPointTy())
6091 ShufTy =
6092 FixedVectorType::get(Type::getFloatTy(ValVTy->getContext()), 4);
6093 else
6094 ShufTy =
6095 FixedVectorType::get(Type::getInt32Ty(ValVTy->getContext()), 4);
6096 ReductionCost += getShuffleCost(TTI::SK_PermuteSingleSrc, ShufTy, ShufTy,
6097 {}, CostKind, 0, nullptr);
6098 } else {
6099 // Reducing from smaller size is a shift by immediate.
6100 auto *ShiftTy = FixedVectorType::get(
6101 Type::getIntNTy(ValVTy->getContext(), Size), 128 / Size);
6102 ReductionCost += getArithmeticInstrCost(
6103 Instruction::LShr, ShiftTy, CostKind,
6106 }
6107
6108 // Add the arithmetic op for this level.
6109 ReductionCost += getArithmeticInstrCost(Opcode, Ty, CostKind);
6110 }
6111
6112 // Add the final extract element to the cost.
6113 return ReductionCost + getVectorInstrCost(Instruction::ExtractElement, Ty,
6114 CostKind, 0, nullptr, nullptr,
6116}
6117
6120 FastMathFlags FMF) const {
6121 IntrinsicCostAttributes ICA(IID, Ty, {Ty, Ty}, FMF);
6122 return getIntrinsicInstrCost(ICA, CostKind);
6123}
6124
6127 FastMathFlags FMF,
6129 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(ValTy);
6130
6131 MVT MTy = LT.second;
6132
6134 if (ValTy->isIntOrIntVectorTy()) {
6135 ISD = (IID == Intrinsic::umin || IID == Intrinsic::umax) ? ISD::UMIN
6136 : ISD::SMIN;
6137 } else {
6138 assert(ValTy->isFPOrFPVectorTy() &&
6139 "Expected float point or integer vector type.");
6140 ISD = (IID == Intrinsic::minnum || IID == Intrinsic::maxnum)
6141 ? ISD::FMINNUM
6142 : ISD::FMINIMUM;
6143 }
6144
6145 // We use llvm-mca across all supported CPUs to measure the cost stats.
6146 static const CostKindTblEntry SSE2CostTbl[] = {
6147 {ISD::SMIN, MVT::v2i64, {3, 4, 5, 6}},
6148 {ISD::UMIN, MVT::v2i64, {3, 4, 5, 6}},
6149 {ISD::SMIN, MVT::v2i32, {2, 2, 5, 6}},
6150 {ISD::UMIN, MVT::v2i32, {2, 2, 5, 6}},
6151 {ISD::SMIN, MVT::v4i32, {3, 7,11,12}},
6152 {ISD::UMIN, MVT::v4i32, {4, 7,14,15}},
6153 {ISD::SMIN, MVT::v2i16, {2, 3, 4, 4}},
6154 {ISD::UMIN, MVT::v2i16, {2, 3, 4, 6}},
6155 {ISD::SMIN, MVT::v4i16, {3, 5, 6, 6}},
6156 {ISD::UMIN, MVT::v4i16, {3, 5, 8, 10}},
6157 {ISD::SMIN, MVT::v8i16, {3, 8, 8, 8}},
6158 {ISD::UMIN, MVT::v8i16, {4, 8,12,14}},
6159 {ISD::SMIN, MVT::v2i8, {2, 3, 5, 6}},
6160 {ISD::UMIN, MVT::v2i8, {2, 3, 4, 4}},
6161 {ISD::SMIN, MVT::v4i8, {4, 6,12,13}},
6162 {ISD::UMIN, MVT::v4i8, {3, 6, 7, 7}},
6163 {ISD::SMIN, MVT::v8i8, {5, 9,18,19}},
6164 {ISD::UMIN, MVT::v8i8, {4, 8, 9, 9}},
6165 {ISD::SMIN, MVT::v16i8, {7,13,24,25}},
6166 {ISD::UMIN, MVT::v16i8, {3,10,11,11}},
6167 };
6168
6169 static const CostKindTblEntry SSE41CostTbl[] = {
6170 {ISD::SMIN, MVT::v2i64, {3, 4, 4, 6}},
6171 {ISD::UMIN, MVT::v2i64, {3, 4, 4, 6}},
6172 {ISD::SMIN, MVT::v2i32, {2, 2, 3, 3}},
6173 {ISD::UMIN, MVT::v2i32, {2, 2, 3, 3}},
6174 {ISD::SMIN, MVT::v4i32, {3, 4, 5, 5}},
6175 {ISD::UMIN, MVT::v4i32, {3, 4, 5, 5}},
6176 {ISD::UMIN, MVT::v2i16, {2, 3, 4, 4}},
6177 {ISD::SMIN, MVT::v4i16, {3, 5, 6, 6}},
6178 {ISD::UMIN, MVT::v4i16, {3, 5, 6, 6}},
6179 {ISD::SMIN, MVT::v8i16, {2, 8, 4, 5}},
6180 {ISD::UMIN, MVT::v8i16, {2, 5, 2, 2}},
6181 {ISD::SMIN, MVT::v2i8, {2, 3, 4, 4}},
6182 {ISD::SMIN, MVT::v4i8, {3, 6, 7, 7}},
6183 {ISD::SMIN, MVT::v8i8, {4, 8, 9, 9}},
6184 {ISD::SMIN, MVT::v16i8, {3,10, 7, 8}},
6185 {ISD::UMIN, MVT::v16i8, {3, 8, 5, 5}},
6186 };
6187
6188 static const CostKindTblEntry AVX1CostTbl[] = {
6189 {ISD::SMIN, MVT::v4i64, {5,11, 7,10}},
6190 {ISD::UMIN, MVT::v4i64, {6,12,10,13}},
6191 {ISD::SMIN, MVT::v8i32, {4, 9, 7, 7}},
6192 {ISD::UMIN, MVT::v8i32, {4, 9, 7, 7}},
6193 {ISD::SMIN, MVT::v16i16, {3,15, 6, 7}},
6194 {ISD::UMIN, MVT::v16i16, {2, 9, 4, 4}},
6195 {ISD::SMIN, MVT::v32i8, {4,17, 8, 9}},
6196 {ISD::UMIN, MVT::v32i8, {3,11, 6, 6}},
6197 };
6198
6199 static const CostKindTblEntry AVX2CostTbl[] = {
6200 {ISD::SMIN, MVT::v4i64, {4,11, 7,10}},
6201 {ISD::UMIN, MVT::v4i64, {4,12,10,13}},
6202 {ISD::SMIN, MVT::v2i32, {1, 2, 3, 3}},
6203 {ISD::UMIN, MVT::v2i32, {1, 2, 3, 3}},
6204 {ISD::UMIN, MVT::v4i32, {2, 4, 5, 5}},
6205 {ISD::SMIN, MVT::v4i32, {2, 4, 5, 5}},
6206 {ISD::SMIN, MVT::v8i32, {3, 9, 7, 7}},
6207 {ISD::UMIN, MVT::v8i32, {3, 9, 7, 7}},
6208 {ISD::SMIN, MVT::v4i16, {2, 4, 5, 5}},
6209 {ISD::UMIN, MVT::v4i16, {2, 4, 5, 5}},
6210 {ISD::SMIN, MVT::v16i16, {2,15, 6, 7}},
6211 {ISD::SMIN, MVT::v8i8, {3, 6, 7, 7}},
6212 {ISD::UMIN, MVT::v8i8, {3, 6, 7, 7}},
6213 {ISD::SMIN, MVT::v32i8, {3,17, 8, 9}},
6214 };
6215
6216 static const CostKindTblEntry AVX512FCostTbl[] = {
6217 {ISD::SMIN, MVT::v2i64, {2, 4, 3, 3}},
6218 {ISD::UMIN, MVT::v2i64, {2, 4, 3, 3}},
6219 {ISD::SMIN, MVT::v4i64, {3,10, 5, 5}},
6220 {ISD::UMIN, MVT::v4i64, {3,10, 5, 5}},
6221 {ISD::SMIN, MVT::v8i64, {5,16, 7, 7}},
6222 {ISD::UMIN, MVT::v8i64, {5,16, 7, 7}},
6223 {ISD::SMIN, MVT::v16i32, {4,12, 9, 9}},
6224 {ISD::UMIN, MVT::v16i32, {4,12, 9, 9}},
6225 };
6226
6227 static const CostKindTblEntry AVX512BWCostTbl[] = {
6228 {ISD::SMIN, MVT::v2i16, {1, 2, 3, 3}},
6229 {ISD::UMIN, MVT::v2i16, {1, 2, 3, 3}},
6230 {ISD::SMIN, MVT::v32i16, {2,19, 8, 9}},
6231 {ISD::UMIN, MVT::v32i16, {2,12, 6, 6}},
6232 {ISD::SMIN, MVT::v2i8, {1, 2, 3, 3}},
6233 {ISD::UMIN, MVT::v2i8, {1, 2, 3, 3}},
6234 {ISD::SMIN, MVT::v4i8, {2, 4, 5, 5}},
6235 {ISD::UMIN, MVT::v4i8, {2, 4, 5, 5}},
6236 {ISD::SMIN, MVT::v16i8, {2,10, 6, 7}},
6237 {ISD::UMIN, MVT::v16i8, {2, 6, 4, 4}},
6238 {ISD::SMIN, MVT::v32i8, {2,17, 8, 9}},
6239 {ISD::UMIN, MVT::v32i8, {2,10, 6, 6}},
6240 {ISD::SMIN, MVT::v64i8, {2,21,10,11}},
6241 {ISD::UMIN, MVT::v64i8, {2,14, 8, 8}},
6242 };
6243
6244 // Before legalizing the type, give a chance to look up illegal narrow types
6245 // in the table.
6246 // FIXME: Is there a better way to do this?
6247 EVT VT = TLI->getValueType(DL, ValTy);
6248 if (VT.isSimple()) {
6249 MVT MTy = VT.getSimpleVT();
6250 if (ST->hasBWI())
6251 if (const auto *Entry = CostTableLookup(AVX512BWCostTbl, ISD, MTy))
6252 if (auto KindCost = Entry->Cost[CostKind])
6253 return *KindCost;
6254
6255 if (ST->hasAVX512())
6256 if (const auto *Entry = CostTableLookup(AVX512FCostTbl, ISD, MTy))
6257 if (auto KindCost = Entry->Cost[CostKind])
6258 return *KindCost;
6259
6260 if (ST->hasAVX2())
6261 if (const auto *Entry = CostTableLookup(AVX2CostTbl, ISD, MTy))
6262 if (auto KindCost = Entry->Cost[CostKind])
6263 return *KindCost;
6264
6265 if (ST->hasAVX())
6266 if (const auto *Entry = CostTableLookup(AVX1CostTbl, ISD, MTy))
6267 if (auto KindCost = Entry->Cost[CostKind])
6268 return *KindCost;
6269
6270 if (ST->hasSSE41())
6271 if (const auto *Entry = CostTableLookup(SSE41CostTbl, ISD, MTy))
6272 if (auto KindCost = Entry->Cost[CostKind])
6273 return *KindCost;
6274
6275 if (ST->hasSSE2())
6276 if (const auto *Entry = CostTableLookup(SSE2CostTbl, ISD, MTy))
6277 if (auto KindCost = Entry->Cost[CostKind])
6278 return *KindCost;
6279 }
6280
6281 auto *ValVTy = cast<FixedVectorType>(ValTy);
6282 unsigned NumVecElts = ValVTy->getNumElements();
6283
6284 auto *Ty = ValVTy;
6285 InstructionCost MinMaxCost = 0;
6286 if (LT.first != 1 && MTy.isVector() &&
6287 MTy.getVectorNumElements() < ValVTy->getNumElements()) {
6288 // Type needs to be split. We need LT.first - 1 operations ops.
6289 Ty = FixedVectorType::get(ValVTy->getElementType(),
6290 MTy.getVectorNumElements());
6291 MinMaxCost = getMinMaxCost(IID, Ty, CostKind, FMF);
6292 MinMaxCost *= LT.first - 1;
6293 NumVecElts = MTy.getVectorNumElements();
6294 }
6295
6296 if (ST->hasBWI())
6297 if (const auto *Entry = CostTableLookup(AVX512BWCostTbl, ISD, MTy))
6298 if (auto KindCost = Entry->Cost[CostKind])
6299 return MinMaxCost + *KindCost;
6300
6301 if (ST->hasAVX512())
6302 if (const auto *Entry = CostTableLookup(AVX512FCostTbl, ISD, MTy))
6303 if (auto KindCost = Entry->Cost[CostKind])
6304 return MinMaxCost + *KindCost;
6305
6306 if (ST->hasAVX2())
6307 if (const auto *Entry = CostTableLookup(AVX2CostTbl, ISD, MTy))
6308 if (auto KindCost = Entry->Cost[CostKind])
6309 return MinMaxCost + *KindCost;
6310
6311 if (ST->hasAVX())
6312 if (const auto *Entry = CostTableLookup(AVX1CostTbl, ISD, MTy))
6313 if (auto KindCost = Entry->Cost[CostKind])
6314 return MinMaxCost + *KindCost;
6315
6316 if (ST->hasSSE41())
6317 if (const auto *Entry = CostTableLookup(SSE41CostTbl, ISD, MTy))
6318 if (auto KindCost = Entry->Cost[CostKind])
6319 return MinMaxCost + *KindCost;
6320
6321 if (ST->hasSSE2())
6322 if (const auto *Entry = CostTableLookup(SSE2CostTbl, ISD, MTy))
6323 if (auto KindCost = Entry->Cost[CostKind])
6324 return MinMaxCost + *KindCost;
6325
6326 unsigned ScalarSize = ValTy->getScalarSizeInBits();
6327
6328 // Special case power of 2 reductions where the scalar type isn't changed
6329 // by type legalization.
6330 if (!isPowerOf2_32(ValVTy->getNumElements()) ||
6331 ScalarSize != MTy.getScalarSizeInBits())
6332 return BaseT::getMinMaxReductionCost(IID, ValTy, FMF, CostKind);
6333
6334 // Now handle reduction with the legal type, taking into account size changes
6335 // at each level.
6336 while (NumVecElts > 1) {
6337 // Determine the size of the remaining vector we need to reduce.
6338 unsigned Size = NumVecElts * ScalarSize;
6339 NumVecElts /= 2;
6340 // If we're reducing from 256/512 bits, use an extract_subvector.
6341 if (Size > 128) {
6342 auto *SubTy = FixedVectorType::get(ValVTy->getElementType(), NumVecElts);
6343 MinMaxCost += getShuffleCost(TTI::SK_ExtractSubvector, Ty, Ty, {},
6344 CostKind, NumVecElts, SubTy);
6345 Ty = SubTy;
6346 } else if (Size == 128) {
6347 // Reducing from 128 bits is a permute of v2f64/v2i64.
6348 VectorType *ShufTy;
6349 if (ValTy->isFloatingPointTy())
6350 ShufTy =
6352 else
6353 ShufTy = FixedVectorType::get(Type::getInt64Ty(ValTy->getContext()), 2);
6354 MinMaxCost += getShuffleCost(TTI::SK_PermuteSingleSrc, ShufTy, ShufTy, {},
6355 CostKind, 0, nullptr);
6356 } else if (Size == 64) {
6357 // Reducing from 64 bits is a shuffle of v4f32/v4i32.
6358 FixedVectorType *ShufTy;
6359 if (ValTy->isFloatingPointTy())
6360 ShufTy = FixedVectorType::get(Type::getFloatTy(ValTy->getContext()), 4);
6361 else
6362 ShufTy = FixedVectorType::get(Type::getInt32Ty(ValTy->getContext()), 4);
6363 MinMaxCost += getShuffleCost(TTI::SK_PermuteSingleSrc, ShufTy, ShufTy, {},
6364 CostKind, 0, nullptr);
6365 } else {
6366 // Reducing from smaller size is a shift by immediate.
6367 auto *ShiftTy = FixedVectorType::get(
6368 Type::getIntNTy(ValTy->getContext(), Size), 128 / Size);
6369 MinMaxCost += getArithmeticInstrCost(
6370 Instruction::LShr, ShiftTy, TTI::TCK_RecipThroughput,
6373 }
6374
6375 // Add the arithmetic op for this level.
6376 MinMaxCost += getMinMaxCost(IID, Ty, CostKind, FMF);
6377 }
6378
6379 // Add the final extract element to the cost.
6380 return MinMaxCost + getVectorInstrCost(Instruction::ExtractElement, Ty,
6381 CostKind, 0, nullptr, nullptr,
6383}
6384
6385/// Calculate the cost of materializing a 64-bit value. This helper
6386/// method might only calculate a fraction of a larger immediate. Therefore it
6387/// is valid to return a cost of ZERO.
6389 if (Val == 0)
6390 return TTI::TCC_Free;
6391
6392 if (isInt<32>(Val))
6393 return TTI::TCC_Basic;
6394
6395 return 2 * TTI::TCC_Basic;
6396}
6397
6400 assert(Ty->isIntegerTy());
6401
6402 unsigned BitSize = Ty->getPrimitiveSizeInBits();
6403 if (BitSize == 0)
6404 return ~0U;
6405
6406 // Never hoist constants larger than 128bit, because this might lead to
6407 // incorrect code generation or assertions in codegen.
6408 // Fixme: Create a cost model for types larger than i128 once the codegen
6409 // issues have been fixed.
6410 if (BitSize > 128)
6411 return TTI::TCC_Free;
6412
6413 if (Imm == 0)
6414 return TTI::TCC_Free;
6415
6416 // Sign-extend all constants to a multiple of 64-bit.
6417 APInt ImmVal = Imm;
6418 if (BitSize % 64 != 0)
6419 ImmVal = Imm.sext(alignTo(BitSize, 64));
6420
6421 // Split the constant into 64-bit chunks and calculate the cost for each
6422 // chunk.
6424 for (unsigned ShiftVal = 0; ShiftVal < BitSize; ShiftVal += 64) {
6425 APInt Tmp = ImmVal.ashr(ShiftVal).sextOrTrunc(64);
6426 int64_t Val = Tmp.getSExtValue();
6427 Cost += getIntImmCost(Val);
6428 }
6429 // We need at least one instruction to materialize the constant.
6430 return std::max<InstructionCost>(1, Cost);
6431}
6432
6434 const APInt &Imm, Type *Ty,
6436 Instruction *Inst) const {
6437 assert(Ty->isIntegerTy());
6438
6439 unsigned BitSize = Ty->getPrimitiveSizeInBits();
6440 unsigned ImmBitWidth = Imm.getBitWidth();
6441
6442 // There is no cost model for constants with a bit size of 0. Return TCC_Free
6443 // here, so that constant hoisting will ignore this constant.
6444 if (BitSize == 0)
6445 return TTI::TCC_Free;
6446
6447 unsigned ImmIdx = ~0U;
6448 switch (Opcode) {
6449 default:
6450 return TTI::TCC_Free;
6451 case Instruction::GetElementPtr:
6452 // Always hoist the base address of a GetElementPtr. This prevents the
6453 // creation of new constants for every base constant that gets constant
6454 // folded with the offset.
6455 if (Idx == 0)
6456 return 2 * TTI::TCC_Basic;
6457 return TTI::TCC_Free;
6458 case Instruction::Store:
6459 ImmIdx = 0;
6460 break;
6461 case Instruction::ICmp:
6462 // This is an imperfect hack to prevent constant hoisting of
6463 // compares that might be trying to check if a 64-bit value fits in
6464 // 32-bits. The backend can optimize these cases using a right shift by 32.
6465 // There are other predicates and immediates the backend can use shifts for.
6466 if (Idx == 1 && ImmBitWidth == 64) {
6467 uint64_t ImmVal = Imm.getZExtValue();
6468 if (ImmVal == 0x100000000ULL || ImmVal == 0xffffffff)
6469 return TTI::TCC_Free;
6470
6471 if (auto *Cmp = dyn_cast_or_null<CmpInst>(Inst)) {
6472 if (Cmp->isEquality()) {
6473 KnownBits Known = computeKnownBits(Cmp->getOperand(0), DL);
6474 if (Known.countMinTrailingZeros() >= 32)
6475 return TTI::TCC_Free;
6476 }
6477 }
6478 }
6479 ImmIdx = 1;
6480 break;
6481 case Instruction::And:
6482 // We support 64-bit ANDs with immediates with 32-bits of leading zeroes
6483 // by using a 32-bit operation with implicit zero extension. Detect such
6484 // immediates here as the normal path expects bit 31 to be sign extended.
6485 if (Idx == 1 && ImmBitWidth == 64 && Imm.isIntN(32))
6486 return TTI::TCC_Free;
6487 // If we have BMI then we can use BEXTR/BZHI to mask out upper i64 bits.
6488 if (Idx == 1 && ImmBitWidth == 64 && ST->is64Bit() && ST->hasBMI() &&
6489 Imm.isMask())
6490 return X86TTIImpl::getIntImmCost(ST->hasBMI2() ? 255 : 65535);
6491 ImmIdx = 1;
6492 break;
6493 case Instruction::Add:
6494 case Instruction::Sub:
6495 // For add/sub, we can use the opposite instruction for INT32_MIN.
6496 if (Idx == 1 && ImmBitWidth == 64 && Imm.getZExtValue() == 0x80000000)
6497 return TTI::TCC_Free;
6498 ImmIdx = 1;
6499 break;
6500 case Instruction::UDiv:
6501 case Instruction::SDiv:
6502 case Instruction::URem:
6503 case Instruction::SRem:
6504 // Division by constant is typically expanded later into a different
6505 // instruction sequence. This completely changes the constants.
6506 // Report them as "free" to stop ConstantHoist from marking them as opaque.
6507 return TTI::TCC_Free;
6508 case Instruction::Mul:
6509 case Instruction::Or:
6510 case Instruction::Xor:
6511 ImmIdx = 1;
6512 break;
6513 // Always return TCC_Free for the shift value of a shift instruction.
6514 case Instruction::Shl:
6515 case Instruction::LShr:
6516 case Instruction::AShr:
6517 if (Idx == 1)
6518 return TTI::TCC_Free;
6519 break;
6520 case Instruction::Trunc:
6521 case Instruction::ZExt:
6522 case Instruction::SExt:
6523 case Instruction::IntToPtr:
6524 case Instruction::PtrToInt:
6525 case Instruction::BitCast:
6526 case Instruction::PHI:
6527 case Instruction::Call:
6528 case Instruction::Select:
6529 case Instruction::Ret:
6530 case Instruction::Load:
6531 break;
6532 }
6533
6534 if (Idx == ImmIdx) {
6535 uint64_t NumConstants = divideCeil(BitSize, 64);
6537 return (Cost <= NumConstants * TTI::TCC_Basic)
6538 ? static_cast<int>(TTI::TCC_Free)
6539 : Cost;
6540 }
6541
6543}
6544
6547 const APInt &Imm, Type *Ty,
6549 assert(Ty->isIntegerTy());
6550
6551 unsigned BitSize = Ty->getPrimitiveSizeInBits();
6552 // There is no cost model for constants with a bit size of 0. Return TCC_Free
6553 // here, so that constant hoisting will ignore this constant.
6554 if (BitSize == 0)
6555 return TTI::TCC_Free;
6556
6557 switch (IID) {
6558 default:
6559 return TTI::TCC_Free;
6560 case Intrinsic::sadd_with_overflow:
6561 case Intrinsic::uadd_with_overflow:
6562 case Intrinsic::ssub_with_overflow:
6563 case Intrinsic::usub_with_overflow:
6564 case Intrinsic::smul_with_overflow:
6565 case Intrinsic::umul_with_overflow:
6566 if ((Idx == 1) && Imm.getBitWidth() <= 64 && Imm.isSignedIntN(32))
6567 return TTI::TCC_Free;
6568 break;
6569 case Intrinsic::experimental_stackmap:
6570 if ((Idx < 2) || (Imm.getBitWidth() <= 64 && Imm.isSignedIntN(64)))
6571 return TTI::TCC_Free;
6572 break;
6573 case Intrinsic::experimental_patchpoint_void:
6574 case Intrinsic::experimental_patchpoint:
6575 if ((Idx < 4) || (Imm.getBitWidth() <= 64 && Imm.isSignedIntN(64)))
6576 return TTI::TCC_Free;
6577 break;
6578 }
6580}
6581
6584 const Instruction *I) const {
6586 return Opcode == Instruction::PHI ? TTI::TCC_Free : TTI::TCC_Basic;
6587 // Branches are assumed to be predicted.
6588 return TTI::TCC_Free;
6589}
6590
6591int X86TTIImpl::getGatherOverhead() const {
6592 // Some CPUs have more overhead for gather. The specified overhead is relative
6593 // to the Load operation. "2" is the number provided by Intel architects. This
6594 // parameter is used for cost estimation of Gather Op and comparison with
6595 // other alternatives.
6596 // TODO: Remove the explicit hasAVX512()?, That would mean we would only
6597 // enable gather with a -march.
6598 if (ST->hasAVX512() || (ST->hasAVX2() && ST->hasFastGather()))
6599 return 2;
6600
6601 return 1024;
6602}
6603
6604int X86TTIImpl::getScatterOverhead() const {
6605 if (ST->hasAVX512())
6606 return 2;
6607
6608 return 1024;
6609}
6610
6611// Return an average cost of Gather / Scatter instruction, maybe improved later.
6612InstructionCost X86TTIImpl::getGSVectorCost(unsigned Opcode,
6614 Type *SrcVTy, const Value *Ptr,
6615 Align Alignment,
6616 unsigned AddressSpace) const {
6617
6618 assert(isa<VectorType>(SrcVTy) && "Unexpected type in getGSVectorCost");
6619 unsigned VF = cast<FixedVectorType>(SrcVTy)->getNumElements();
6620
6621 // Try to reduce index size from 64 bit (default for GEP)
6622 // to 32. It is essential for VF 16. If the index can't be reduced to 32, the
6623 // operation will use 16 x 64 indices which do not fit in a zmm and needs
6624 // to split. Also check that the base pointer is the same for all lanes,
6625 // and that there's at most one variable index.
6626 auto getIndexSizeInBits = [](const Value *Ptr, const DataLayout &DL) {
6627 unsigned IndexSize = DL.getPointerSizeInBits();
6628 const GetElementPtrInst *GEP = dyn_cast_or_null<GetElementPtrInst>(Ptr);
6629 if (IndexSize < 64 || !GEP)
6630 return IndexSize;
6631
6632 unsigned NumOfVarIndices = 0;
6633 const Value *Ptrs = GEP->getPointerOperand();
6634 if (Ptrs->getType()->isVectorTy() && !getSplatValue(Ptrs))
6635 return IndexSize;
6636 for (unsigned I = 1, E = GEP->getNumOperands(); I != E; ++I) {
6637 if (isa<Constant>(GEP->getOperand(I)))
6638 continue;
6639 Type *IndxTy = GEP->getOperand(I)->getType();
6640 if (auto *IndexVTy = dyn_cast<VectorType>(IndxTy))
6641 IndxTy = IndexVTy->getElementType();
6642 if ((IndxTy->getPrimitiveSizeInBits() == 64 &&
6643 !isa<SExtInst>(GEP->getOperand(I))) ||
6644 ++NumOfVarIndices > 1)
6645 return IndexSize; // 64
6646 }
6647 return (unsigned)32;
6648 };
6649
6650 // Trying to reduce IndexSize to 32 bits for vector 16.
6651 // By default the IndexSize is equal to pointer size.
6652 unsigned IndexSize = (ST->hasAVX512() && VF >= 16)
6653 ? getIndexSizeInBits(Ptr, DL)
6654 : DL.getPointerSizeInBits();
6655
6656 auto *IndexVTy = FixedVectorType::get(
6657 IntegerType::get(SrcVTy->getContext(), IndexSize), VF);
6658 std::pair<InstructionCost, MVT> IdxsLT = getTypeLegalizationCost(IndexVTy);
6659 std::pair<InstructionCost, MVT> SrcLT = getTypeLegalizationCost(SrcVTy);
6660 InstructionCost::CostType SplitFactor =
6661 std::max(IdxsLT.first, SrcLT.first).getValue();
6662 if (SplitFactor > 1) {
6663 // Handle splitting of vector of pointers
6664 auto *SplitSrcTy =
6665 FixedVectorType::get(SrcVTy->getScalarType(), VF / SplitFactor);
6666 return SplitFactor * getGSVectorCost(Opcode, CostKind, SplitSrcTy, Ptr,
6667 Alignment, AddressSpace);
6668 }
6669
6670 // If we didn't split, this will be a single gather/scatter instruction.
6672 return 1;
6673
6674 // The gather / scatter cost is given by Intel architects. It is a rough
6675 // number since we are looking at one instruction in a time.
6676 const int GSOverhead = (Opcode == Instruction::Load) ? getGatherOverhead()
6677 : getScatterOverhead();
6678 return GSOverhead + VF * getMemoryOpCost(Opcode, SrcVTy->getScalarType(),
6679 Alignment, AddressSpace, CostKind);
6680}
6681
6682/// Calculate the cost of Gather / Scatter operation
6686 bool IsLoad = MICA.getID() == Intrinsic::masked_gather ||
6687 MICA.getID() == Intrinsic::vp_gather;
6688 unsigned Opcode = IsLoad ? Instruction::Load : Instruction::Store;
6689 Type *SrcVTy = MICA.getDataType();
6690 const Value *Ptr = MICA.getPointer();
6691 Align Alignment = MICA.getAlignment();
6692 if ((Opcode == Instruction::Load &&
6693 (!isLegalMaskedGather(SrcVTy, Align(Alignment)) ||
6695 Align(Alignment)))) ||
6696 (Opcode == Instruction::Store &&
6697 (!isLegalMaskedScatter(SrcVTy, Align(Alignment)) ||
6699 Align(Alignment)))))
6701
6702 assert(SrcVTy->isVectorTy() && "Unexpected data type for Gather/Scatter");
6703 unsigned AddressSpace = MICA.getAddressSpace();
6704 return getGSVectorCost(Opcode, CostKind, SrcVTy, Ptr, Alignment,
6705 AddressSpace);
6706}
6707
6709 const TargetTransformInfo::LSRCost &C2) const {
6710 // X86 specific here are "instruction number 1st priority".
6711 return std::tie(C1.Insns, C1.NumRegs, C1.AddRecCost, C1.NumIVMuls,
6712 C1.NumBaseAdds, C1.ScaleCost, C1.ImmCost, C1.SetupCost) <
6713 std::tie(C2.Insns, C2.NumRegs, C2.AddRecCost, C2.NumIVMuls,
6714 C2.NumBaseAdds, C2.ScaleCost, C2.ImmCost, C2.SetupCost);
6715}
6716
6718 return ST->hasMacroFusion() || ST->hasBranchFusion();
6719}
6720
6721static bool isLegalMaskedLoadStore(Type *ScalarTy, const X86Subtarget *ST) {
6722 if (!ST->hasAVX())
6723 return false;
6724
6725 if (ScalarTy->isPointerTy())
6726 return true;
6727
6728 if (ScalarTy->isFloatTy() || ScalarTy->isDoubleTy())
6729 return true;
6730
6731 if (ScalarTy->isHalfTy() && ST->hasBWI())
6732 return true;
6733
6734 if (ScalarTy->isBFloatTy() && ST->hasBF16())
6735 return true;
6736
6737 if (!ScalarTy->isIntegerTy())
6738 return false;
6739
6740 unsigned IntWidth = ScalarTy->getIntegerBitWidth();
6741 return IntWidth == 32 || IntWidth == 64 ||
6742 ((IntWidth == 8 || IntWidth == 16) && ST->hasBWI());
6743}
6744
6746 unsigned AddressSpace,
6747 TTI::MaskKind MaskKind) const {
6748 Type *ScalarTy = DataTy->getScalarType();
6749
6750 // The backend can't handle a single element vector w/o CFCMOV.
6751 if (isa<VectorType>(DataTy) &&
6752 cast<FixedVectorType>(DataTy)->getNumElements() == 1)
6753 return ST->hasCF() &&
6754 hasConditionalLoadStoreForType(ScalarTy, /*IsStore=*/false);
6755
6756 return isLegalMaskedLoadStore(ScalarTy, ST);
6757}
6758
6760 unsigned AddressSpace,
6761 TTI::MaskKind MaskKind) const {
6762 Type *ScalarTy = DataTy->getScalarType();
6763
6764 // The backend can't handle a single element vector w/o CFCMOV.
6765 if (isa<VectorType>(DataTy) &&
6766 cast<FixedVectorType>(DataTy)->getNumElements() == 1)
6767 return ST->hasCF() &&
6768 hasConditionalLoadStoreForType(ScalarTy, /*IsStore=*/true);
6769
6770 return isLegalMaskedLoadStore(ScalarTy, ST);
6771}
6772
6773bool X86TTIImpl::isLegalNTLoad(Type *DataType, Align Alignment) const {
6774 unsigned DataSize = DL.getTypeStoreSize(DataType);
6775 // The only supported nontemporal loads are for aligned vectors of 16 or 32
6776 // bytes. Note that 32-byte nontemporal vector loads are supported by AVX2
6777 // (the equivalent stores only require AVX).
6778 if (Alignment >= DataSize && (DataSize == 16 || DataSize == 32))
6779 return DataSize == 16 ? ST->hasSSE1() : ST->hasAVX2();
6780
6781 return false;
6782}
6783
6784bool X86TTIImpl::isLegalNTStore(Type *DataType, Align Alignment) const {
6785 unsigned DataSize = DL.getTypeStoreSize(DataType);
6786
6787 // SSE4A supports nontemporal stores of float and double at arbitrary
6788 // alignment.
6789 if (ST->hasSSE4A() && (DataType->isFloatTy() || DataType->isDoubleTy()))
6790 return true;
6791
6792 // Besides the SSE4A subtarget exception above, only aligned stores are
6793 // available nontemporaly on any other subtarget. And only stores with a size
6794 // of 4..32 bytes (powers of 2, only) are permitted.
6795 if (Alignment < DataSize || DataSize < 4 || DataSize > 32 ||
6796 !isPowerOf2_32(DataSize))
6797 return false;
6798
6799 // 32-byte vector nontemporal stores are supported by AVX (the equivalent
6800 // loads require AVX2).
6801 if (DataSize == 32)
6802 return ST->hasAVX();
6803 if (DataSize == 16)
6804 return ST->hasSSE1();
6805 return true;
6806}
6807
6809 ElementCount NumElements) const {
6810 // movddup
6811 return ST->hasSSE3() && !NumElements.isScalable() &&
6812 NumElements.getFixedValue() == 2 &&
6813 ElementTy == Type::getDoubleTy(ElementTy->getContext());
6814}
6815
6816bool X86TTIImpl::isLegalMaskedExpandLoad(Type *DataTy, Align Alignment) const {
6817 if (!isa<VectorType>(DataTy))
6818 return false;
6819
6820 if (!ST->hasAVX512())
6821 return false;
6822
6823 // The backend can't handle a single element vector.
6824 if (cast<FixedVectorType>(DataTy)->getNumElements() == 1)
6825 return false;
6826
6827 Type *ScalarTy = cast<VectorType>(DataTy)->getElementType();
6828
6829 if (ScalarTy->isFloatTy() || ScalarTy->isDoubleTy())
6830 return true;
6831
6832 if (!ScalarTy->isIntegerTy())
6833 return false;
6834
6835 unsigned IntWidth = ScalarTy->getIntegerBitWidth();
6836 return IntWidth == 32 || IntWidth == 64 ||
6837 ((IntWidth == 8 || IntWidth == 16) && ST->hasVBMI2());
6838}
6839
6841 Align Alignment) const {
6842 return isLegalMaskedExpandLoad(DataTy, Alignment);
6843}
6844
6845bool X86TTIImpl::supportsGather() const {
6846 // Some CPUs have better gather performance than others.
6847 // TODO: Remove the explicit ST->hasAVX512()?, That would mean we would only
6848 // enable gather with a -march.
6849 return ST->hasAVX512() || (ST->hasFastGather() && ST->hasAVX2());
6850}
6851
6853 Align Alignment) const {
6854 // Gather / Scatter for vector 2 is not profitable on KNL / SKX
6855 // Vector-4 of gather/scatter instruction does not exist on KNL. We can extend
6856 // it to 8 elements, but zeroing upper bits of the mask vector will add more
6857 // instructions. Right now we give the scalar cost of vector-4 for KNL. TODO:
6858 // Check, maybe the gather/scatter instruction is better in the VariableMask
6859 // case.
6860 unsigned NumElts = cast<FixedVectorType>(VTy)->getNumElements();
6861 return NumElts == 1 ||
6862 (ST->hasAVX512() && (NumElts == 2 || (NumElts == 4 && !ST->hasVLX())));
6863}
6864
6866 Align Alignment) const {
6867 Type *ScalarTy = DataTy->getScalarType();
6868 if (ScalarTy->isPointerTy())
6869 return true;
6870
6871 if (ScalarTy->isFloatTy() || ScalarTy->isDoubleTy())
6872 return true;
6873
6874 if (!ScalarTy->isIntegerTy())
6875 return false;
6876
6877 unsigned IntWidth = ScalarTy->getIntegerBitWidth();
6878 return IntWidth == 32 || IntWidth == 64;
6879}
6880
6881bool X86TTIImpl::isLegalMaskedGather(Type *DataTy, Align Alignment) const {
6882 if (!supportsGather() || !ST->preferGather())
6883 return false;
6884 return isLegalMaskedGatherScatter(DataTy, Alignment);
6885}
6886
6887bool X86TTIImpl::isLegalAltInstr(VectorType *VecTy, unsigned Opcode0,
6888 unsigned Opcode1,
6889 const SmallBitVector &OpcodeMask) const {
6890 // ADDSUBPS 4xf32 SSE3
6891 // VADDSUBPS 4xf32 AVX
6892 // VADDSUBPS 8xf32 AVX2
6893 // ADDSUBPD 2xf64 SSE3
6894 // VADDSUBPD 2xf64 AVX
6895 // VADDSUBPD 4xf64 AVX2
6896
6897 unsigned NumElements = cast<FixedVectorType>(VecTy)->getNumElements();
6898 assert(OpcodeMask.size() == NumElements && "Mask and VecTy are incompatible");
6899 if (!isPowerOf2_32(NumElements))
6900 return false;
6901 // Check the opcode pattern. We apply the mask on the opcode arguments and
6902 // then check if it is what we expect.
6903 for (int Lane : seq<int>(0, NumElements)) {
6904 unsigned Opc = OpcodeMask.test(Lane) ? Opcode1 : Opcode0;
6905 // We expect FSub for even lanes and FAdd for odd lanes.
6906 if (Lane % 2 == 0 && Opc != Instruction::FSub)
6907 return false;
6908 if (Lane % 2 == 1 && Opc != Instruction::FAdd)
6909 return false;
6910 }
6911 // Now check that the pattern is supported by the target ISA.
6912 Type *ElemTy = cast<VectorType>(VecTy)->getElementType();
6913 if (ElemTy->isFloatTy())
6914 return ST->hasSSE3() && NumElements % 4 == 0;
6915 if (ElemTy->isDoubleTy())
6916 return ST->hasSSE3() && NumElements % 2 == 0;
6917 return false;
6918}
6919
6920bool X86TTIImpl::isLegalMaskedScatter(Type *DataType, Align Alignment) const {
6921 // AVX2 doesn't support scatter
6922 if (!ST->hasAVX512() || !ST->preferScatter())
6923 return false;
6924 return isLegalMaskedGatherScatter(DataType, Alignment);
6925}
6926
6927bool X86TTIImpl::hasDivRemOp(Type *DataType, bool IsSigned) const {
6928 EVT VT = TLI->getValueType(DL, DataType);
6929 return TLI->isOperationLegal(IsSigned ? ISD::SDIVREM : ISD::UDIVREM, VT);
6930}
6931
6933 // FDIV is always expensive, even if it has a very low uop count.
6934 // TODO: Still necessary for recent CPUs with low latency/throughput fdiv?
6935 if (I->getOpcode() == Instruction::FDiv)
6936 return true;
6937
6939}
6940
6941bool X86TTIImpl::isFCmpOrdCheaperThanFCmpZero(Type *Ty) const { return false; }
6942
6944 const Function *Callee) const {
6945 const TargetMachine &TM = getTLI()->getTargetMachine();
6946
6947 // Work this as a subsetting of subtarget features.
6948 const X86Subtarget &CallerSubtarget = TM.getSubtarget<X86Subtarget>(*Caller);
6949 const X86Subtarget &CalleeSubtarget = TM.getSubtarget<X86Subtarget>(*Callee);
6950 const FeatureBitset &CallerBits = CallerSubtarget.getFeatureBits();
6951 const FeatureBitset &CalleeBits = CalleeSubtarget.getFeatureBits();
6952
6953 // Check whether callee features are a subset of caller features
6954 // (apart from the ignore list).
6955 const FeatureBitset &InlineIgnoreFeatures =
6956 CallerSubtarget.getInlineIgnoreFeatures();
6957 FeatureBitset RealCallerBits = CallerBits & ~InlineIgnoreFeatures;
6958 FeatureBitset RealCalleeBits = CalleeBits & ~InlineIgnoreFeatures;
6959 if ((RealCallerBits & RealCalleeBits) != RealCalleeBits)
6960 return false;
6961
6962 // If the features are not exactly the same (or there is a difference in
6963 // AVX512 register usage), we need to additionally check for calls
6964 // that may become ABI-incompatible as a result of inlining.
6965 if (RealCallerBits == RealCalleeBits &&
6966 CallerSubtarget.useAVX512Regs() == CalleeSubtarget.useAVX512Regs())
6967 return true;
6968
6969 for (const Instruction &I : instructions(Callee)) {
6970 if (const auto *CB = dyn_cast<CallBase>(&I)) {
6971 // Having more target features is fine for inline ASM and intrinsics.
6972 if (CB->isInlineAsm() || CB->getIntrinsicID() != Intrinsic::not_intrinsic)
6973 continue;
6974
6976 for (Value *Arg : CB->args())
6977 Types.push_back(Arg->getType());
6978 if (!CB->getType()->isVoidTy())
6979 Types.push_back(CB->getType());
6980
6981 // Simple types are always ABI compatible.
6982 auto IsSimpleTy = [](Type *Ty) {
6983 return !Ty->isVectorTy() && !Ty->isAggregateType();
6984 };
6985 if (all_of(Types, IsSimpleTy))
6986 continue;
6987
6988 // Do a precise compatibility check.
6989 if (!areTypesABICompatible(Caller, Callee, Types))
6990 return false;
6991 }
6992 }
6993 return true;
6994}
6995
6997 const Function *Callee,
6998 ArrayRef<Type *> Types) const {
6999 const TargetMachine &TM = getTLI()->getTargetMachine();
7000 const TargetLowering *CallerTLI =
7001 TM.getSubtargetImpl(*Caller)->getTargetLowering();
7002 const TargetLowering *CalleeTLI =
7003 TM.getSubtargetImpl(*Callee)->getTargetLowering();
7004
7005 LLVMContext &Ctx = Caller->getContext();
7006 const DataLayout &DL = Caller->getDataLayout();
7007 CallingConv::ID CC = Callee->getCallingConv();
7008 return all_of(Types, [&](Type *Ty) {
7009 SmallVector<EVT> VTs;
7010 ComputeValueVTs(*CallerTLI, DL, Ty, VTs);
7011 return all_of(VTs, [&](EVT VT) {
7012 return CallerTLI->getRegisterTypeForCallingConv(Ctx, CC, VT) ==
7013 CalleeTLI->getRegisterTypeForCallingConv(Ctx, CC, VT);
7014 });
7015 });
7016}
7017
7019X86TTIImpl::enableMemCmpExpansion(bool OptSize, bool IsZeroCmp) const {
7021 Options.MaxNumLoads = TLI->getMaxExpandSizeMemcmp(OptSize);
7022 Options.NumLoadsPerBlock = 2;
7023 // All GPR and vector loads can be unaligned.
7024 Options.AllowOverlappingLoads = true;
7025 if (IsZeroCmp) {
7026 // Only enable vector loads for equality comparison. Right now the vector
7027 // version is not as fast for three way compare (see #33329).
7028 const unsigned PreferredWidth = ST->getPreferVectorWidth();
7029 if (PreferredWidth >= 512 && ST->hasAVX512())
7030 Options.LoadSizes.push_back(64);
7031 if (PreferredWidth >= 256 && ST->hasAVX()) Options.LoadSizes.push_back(32);
7032 if (PreferredWidth >= 128 && ST->hasSSE2()) Options.LoadSizes.push_back(16);
7033 }
7034 if (ST->is64Bit()) {
7035 Options.LoadSizes.push_back(8);
7036 }
7037 Options.LoadSizes.push_back(4);
7038 Options.LoadSizes.push_back(2);
7039 Options.LoadSizes.push_back(1);
7040 return Options;
7041}
7042
7044 return supportsGather();
7045}
7046
7048 return false;
7049}
7050
7052 // TODO: We expect this to be beneficial regardless of arch,
7053 // but there are currently some unexplained performance artifacts on Atom.
7054 // As a temporary solution, disable on Atom.
7055 return !(ST->isAtom());
7056}
7057
7059 switch (II->getIntrinsicID()) {
7060 default:
7061 return true;
7062 case Intrinsic::vector_reduce_and:
7063 case Intrinsic::vector_reduce_or:
7064 case Intrinsic::vector_reduce_xor:
7065 case Intrinsic::vector_reduce_mul:
7066 case Intrinsic::vector_reduce_smax:
7067 case Intrinsic::vector_reduce_smin:
7068 case Intrinsic::vector_reduce_umax:
7069 case Intrinsic::vector_reduce_umin:
7070 return false;
7071 }
7072}
7073
7074// Get estimation for interleaved load/store operations and strided load.
7075// \p Indices contains indices for strided load.
7076// \p Factor - the factor of interleaving.
7077// AVX-512 provides 3-src shuffles that significantly reduces the cost.
7079 unsigned Opcode, FixedVectorType *VecTy, unsigned Factor,
7080 ArrayRef<unsigned> Indices, Align Alignment, unsigned AddressSpace,
7081 TTI::TargetCostKind CostKind, bool UseMaskForCond,
7082 bool UseMaskForGaps) const {
7083 // VecTy for interleave memop is <VF*Factor x Elt>.
7084 // So, for VF=4, Interleave Factor = 3, Element type = i32 we have
7085 // VecTy = <12 x i32>.
7086
7087 // Calculate the number of memory operations (NumOfMemOps), required
7088 // for load/store the VecTy.
7089 MVT LegalVT = getTypeLegalizationCost(VecTy).second;
7090 unsigned VecTySize = DL.getTypeStoreSize(VecTy);
7091 unsigned LegalVTSize = LegalVT.getStoreSize();
7092 unsigned NumOfMemOps = (VecTySize + LegalVTSize - 1) / LegalVTSize;
7093
7094 // Get the cost of one memory operation.
7095 auto *SingleMemOpTy = FixedVectorType::get(VecTy->getElementType(),
7096 LegalVT.getVectorNumElements());
7097 InstructionCost MemOpCost;
7098 bool UseMaskedMemOp = UseMaskForCond || UseMaskForGaps;
7099 if (UseMaskedMemOp) {
7100 unsigned IID = Opcode == Instruction::Load ? Intrinsic::masked_load
7101 : Intrinsic::masked_store;
7102 MemOpCost = getMaskedMemoryOpCost(
7103 {IID, SingleMemOpTy, Alignment, AddressSpace}, CostKind);
7104 } else
7105 MemOpCost = getMemoryOpCost(Opcode, SingleMemOpTy, Alignment, AddressSpace,
7106 CostKind);
7107
7108 unsigned VF = VecTy->getNumElements() / Factor;
7109 MVT VT =
7110 MVT::getVectorVT(TLI->getSimpleValueType(DL, VecTy->getScalarType()), VF);
7111
7112 InstructionCost MaskCost;
7113 if (UseMaskedMemOp) {
7114 APInt DemandedLoadStoreElts = APInt::getZero(VecTy->getNumElements());
7115 for (unsigned Index : Indices) {
7116 assert(Index < Factor && "Invalid index for interleaved memory op");
7117 for (unsigned Elm = 0; Elm < VF; Elm++)
7118 DemandedLoadStoreElts.setBit(Index + Elm * Factor);
7119 }
7120
7121 Type *I1Type = Type::getInt1Ty(VecTy->getContext());
7122
7123 MaskCost = getReplicationShuffleCost(
7124 I1Type, Factor, VF,
7125 UseMaskForGaps ? DemandedLoadStoreElts
7127 CostKind);
7128
7129 // The Gaps mask is invariant and created outside the loop, therefore the
7130 // cost of creating it is not accounted for here. However if we have both
7131 // a MaskForGaps and some other mask that guards the execution of the
7132 // memory access, we need to account for the cost of And-ing the two masks
7133 // inside the loop.
7134 if (UseMaskForGaps) {
7135 auto *MaskVT = FixedVectorType::get(I1Type, VecTy->getNumElements());
7136 MaskCost += getArithmeticInstrCost(BinaryOperator::And, MaskVT, CostKind);
7137 }
7138 }
7139
7140 if (Opcode == Instruction::Load) {
7141 // The tables (AVX512InterleavedLoadTbl and AVX512InterleavedStoreTbl)
7142 // contain the cost of the optimized shuffle sequence that the
7143 // X86InterleavedAccess pass will generate.
7144 // The cost of loads and stores are computed separately from the table.
7145
7146 // X86InterleavedAccess support only the following interleaved-access group.
7147 static const CostTblEntry AVX512InterleavedLoadTbl[] = {
7148 {3, MVT::v16i8, 12}, //(load 48i8 and) deinterleave into 3 x 16i8
7149 {3, MVT::v32i8, 14}, //(load 96i8 and) deinterleave into 3 x 32i8
7150 {3, MVT::v64i8, 22}, //(load 96i8 and) deinterleave into 3 x 32i8
7151 };
7152
7153 if (const auto *Entry =
7154 CostTableLookup(AVX512InterleavedLoadTbl, Factor, VT))
7155 return MaskCost + NumOfMemOps * MemOpCost + Entry->Cost;
7156 //If an entry does not exist, fallback to the default implementation.
7157
7158 // Kind of shuffle depends on number of loaded values.
7159 // If we load the entire data in one register, we can use a 1-src shuffle.
7160 // Otherwise, we'll merge 2 sources in each operation.
7161 TTI::ShuffleKind ShuffleKind =
7162 (NumOfMemOps > 1) ? TTI::SK_PermuteTwoSrc : TTI::SK_PermuteSingleSrc;
7163
7164 InstructionCost ShuffleCost = getShuffleCost(
7165 ShuffleKind, SingleMemOpTy, SingleMemOpTy, {}, CostKind, 0, nullptr);
7166
7167 unsigned NumOfLoadsInInterleaveGrp =
7168 Indices.size() ? Indices.size() : Factor;
7169 auto *ResultTy = FixedVectorType::get(VecTy->getElementType(),
7170 VecTy->getNumElements() / Factor);
7171 InstructionCost NumOfResults =
7172 getTypeLegalizationCost(ResultTy).first * NumOfLoadsInInterleaveGrp;
7173
7174 // About a half of the loads may be folded in shuffles when we have only
7175 // one result. If we have more than one result, or the loads are masked,
7176 // we do not fold loads at all.
7177 unsigned NumOfUnfoldedLoads =
7178 UseMaskedMemOp || NumOfResults > 1 ? NumOfMemOps : NumOfMemOps / 2;
7179
7180 // Get a number of shuffle operations per result.
7181 unsigned NumOfShufflesPerResult =
7182 std::max((unsigned)1, (unsigned)(NumOfMemOps - 1));
7183
7184 // The SK_MergeTwoSrc shuffle clobbers one of src operands.
7185 // When we have more than one destination, we need additional instructions
7186 // to keep sources.
7187 InstructionCost NumOfMoves = 0;
7188 if (NumOfResults > 1 && ShuffleKind == TTI::SK_PermuteTwoSrc)
7189 NumOfMoves = NumOfResults * NumOfShufflesPerResult / 2;
7190
7191 InstructionCost Cost = NumOfResults * NumOfShufflesPerResult * ShuffleCost +
7192 MaskCost + NumOfUnfoldedLoads * MemOpCost +
7193 NumOfMoves;
7194
7195 return Cost;
7196 }
7197
7198 // Store.
7199 assert(Opcode == Instruction::Store &&
7200 "Expected Store Instruction at this point");
7201 // X86InterleavedAccess support only the following interleaved-access group.
7202 static const CostTblEntry AVX512InterleavedStoreTbl[] = {
7203 {3, MVT::v16i8, 12}, // interleave 3 x 16i8 into 48i8 (and store)
7204 {3, MVT::v32i8, 14}, // interleave 3 x 32i8 into 96i8 (and store)
7205 {3, MVT::v64i8, 26}, // interleave 3 x 64i8 into 96i8 (and store)
7206
7207 {4, MVT::v8i8, 10}, // interleave 4 x 8i8 into 32i8 (and store)
7208 {4, MVT::v16i8, 11}, // interleave 4 x 16i8 into 64i8 (and store)
7209 {4, MVT::v32i8, 14}, // interleave 4 x 32i8 into 128i8 (and store)
7210 {4, MVT::v64i8, 24} // interleave 4 x 32i8 into 256i8 (and store)
7211 };
7212
7213 if (const auto *Entry =
7214 CostTableLookup(AVX512InterleavedStoreTbl, Factor, VT))
7215 return MaskCost + NumOfMemOps * MemOpCost + Entry->Cost;
7216 //If an entry does not exist, fallback to the default implementation.
7217
7218 // There is no strided stores meanwhile. And store can't be folded in
7219 // shuffle.
7220 unsigned NumOfSources = Factor; // The number of values to be merged.
7221 InstructionCost ShuffleCost =
7222 getShuffleCost(TTI::SK_PermuteTwoSrc, SingleMemOpTy, SingleMemOpTy, {},
7223 CostKind, 0, nullptr);
7224 unsigned NumOfShufflesPerStore = NumOfSources - 1;
7225
7226 // The SK_MergeTwoSrc shuffle clobbers one of src operands.
7227 // We need additional instructions to keep sources.
7228 unsigned NumOfMoves = NumOfMemOps * NumOfShufflesPerStore / 2;
7230 MaskCost +
7231 NumOfMemOps * (MemOpCost + NumOfShufflesPerStore * ShuffleCost) +
7232 NumOfMoves;
7233 return Cost;
7234}
7235
7237 unsigned Opcode, Type *BaseTy, unsigned Factor, ArrayRef<unsigned> Indices,
7238 Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind,
7239 bool UseMaskForCond, bool UseMaskForGaps) const {
7240 auto *VecTy = cast<FixedVectorType>(BaseTy);
7241
7242 auto isSupportedOnAVX512 = [&](Type *VecTy) {
7243 Type *EltTy = cast<VectorType>(VecTy)->getElementType();
7244 if (EltTy->isFloatTy() || EltTy->isDoubleTy() || EltTy->isIntegerTy(64) ||
7245 EltTy->isIntegerTy(32) || EltTy->isPointerTy())
7246 return true;
7247 if (EltTy->isIntegerTy(16) || EltTy->isIntegerTy(8) || EltTy->isHalfTy())
7248 return ST->hasBWI();
7249 if (EltTy->isBFloatTy())
7250 return ST->hasBF16();
7251 return false;
7252 };
7253 if (ST->hasAVX512() && isSupportedOnAVX512(VecTy))
7255 Opcode, VecTy, Factor, Indices, Alignment,
7256 AddressSpace, CostKind, UseMaskForCond, UseMaskForGaps);
7257
7258 if (UseMaskForCond || UseMaskForGaps)
7259 return BaseT::getInterleavedMemoryOpCost(Opcode, VecTy, Factor, Indices,
7260 Alignment, AddressSpace, CostKind,
7261 UseMaskForCond, UseMaskForGaps);
7262
7263 // Get estimation for interleaved load/store operations for SSE-AVX2.
7264 // As opposed to AVX-512, SSE-AVX2 do not have generic shuffles that allow
7265 // computing the cost using a generic formula as a function of generic
7266 // shuffles. We therefore use a lookup table instead, filled according to
7267 // the instruction sequences that codegen currently generates.
7268
7269 // VecTy for interleave memop is <VF*Factor x Elt>.
7270 // So, for VF=4, Interleave Factor = 3, Element type = i32 we have
7271 // VecTy = <12 x i32>.
7272 MVT LegalVT = getTypeLegalizationCost(VecTy).second;
7273
7274 // This function can be called with VecTy=<6xi128>, Factor=3, in which case
7275 // the VF=2, while v2i128 is an unsupported MVT vector type
7276 // (see MachineValueType.h::getVectorVT()).
7277 if (!LegalVT.isVector())
7278 return BaseT::getInterleavedMemoryOpCost(Opcode, VecTy, Factor, Indices,
7279 Alignment, AddressSpace, CostKind);
7280
7281 unsigned VF = VecTy->getNumElements() / Factor;
7282 Type *ScalarTy = VecTy->getElementType();
7283 // Deduplicate entries, model floats/pointers as appropriately-sized integers.
7284 if (!ScalarTy->isIntegerTy())
7285 ScalarTy =
7286 Type::getIntNTy(ScalarTy->getContext(), DL.getTypeSizeInBits(ScalarTy));
7287
7288 // Get the cost of all the memory operations.
7289 // FIXME: discount dead loads.
7290 InstructionCost MemOpCosts =
7291 getMemoryOpCost(Opcode, VecTy, Alignment, AddressSpace, CostKind);
7292
7293 auto *VT = FixedVectorType::get(ScalarTy, VF);
7294 EVT ETy = TLI->getValueType(DL, VT);
7295 if (!ETy.isSimple())
7296 return BaseT::getInterleavedMemoryOpCost(Opcode, VecTy, Factor, Indices,
7297 Alignment, AddressSpace, CostKind);
7298
7299 // TODO: Complete for other data-types and strides.
7300 // Each combination of Stride, element bit width and VF results in a different
7301 // sequence; The cost tables are therefore accessed with:
7302 // Factor (stride) and VectorType=VFxiN.
7303 // The Cost accounts only for the shuffle sequence;
7304 // The cost of the loads/stores is accounted for separately.
7305 //
7306 static const CostTblEntry AVX2InterleavedLoadTbl[] = {
7307 {2, MVT::v2i8, 2}, // (load 4i8 and) deinterleave into 2 x 2i8
7308 {2, MVT::v4i8, 2}, // (load 8i8 and) deinterleave into 2 x 4i8
7309 {2, MVT::v8i8, 2}, // (load 16i8 and) deinterleave into 2 x 8i8
7310 {2, MVT::v16i8, 4}, // (load 32i8 and) deinterleave into 2 x 16i8
7311 {2, MVT::v32i8, 6}, // (load 64i8 and) deinterleave into 2 x 32i8
7312
7313 {2, MVT::v8i16, 6}, // (load 16i16 and) deinterleave into 2 x 8i16
7314 {2, MVT::v16i16, 9}, // (load 32i16 and) deinterleave into 2 x 16i16
7315 {2, MVT::v32i16, 18}, // (load 64i16 and) deinterleave into 2 x 32i16
7316
7317 {2, MVT::v8i32, 4}, // (load 16i32 and) deinterleave into 2 x 8i32
7318 {2, MVT::v16i32, 8}, // (load 32i32 and) deinterleave into 2 x 16i32
7319 {2, MVT::v32i32, 16}, // (load 64i32 and) deinterleave into 2 x 32i32
7320
7321 {2, MVT::v4i64, 4}, // (load 8i64 and) deinterleave into 2 x 4i64
7322 {2, MVT::v8i64, 8}, // (load 16i64 and) deinterleave into 2 x 8i64
7323 {2, MVT::v16i64, 16}, // (load 32i64 and) deinterleave into 2 x 16i64
7324 {2, MVT::v32i64, 32}, // (load 64i64 and) deinterleave into 2 x 32i64
7325
7326 {3, MVT::v2i8, 3}, // (load 6i8 and) deinterleave into 3 x 2i8
7327 {3, MVT::v4i8, 3}, // (load 12i8 and) deinterleave into 3 x 4i8
7328 {3, MVT::v8i8, 6}, // (load 24i8 and) deinterleave into 3 x 8i8
7329 {3, MVT::v16i8, 11}, // (load 48i8 and) deinterleave into 3 x 16i8
7330 {3, MVT::v32i8, 14}, // (load 96i8 and) deinterleave into 3 x 32i8
7331
7332 {3, MVT::v2i16, 5}, // (load 6i16 and) deinterleave into 3 x 2i16
7333 {3, MVT::v4i16, 7}, // (load 12i16 and) deinterleave into 3 x 4i16
7334 {3, MVT::v8i16, 9}, // (load 24i16 and) deinterleave into 3 x 8i16
7335 {3, MVT::v16i16, 28}, // (load 48i16 and) deinterleave into 3 x 16i16
7336 {3, MVT::v32i16, 56}, // (load 96i16 and) deinterleave into 3 x 32i16
7337
7338 {3, MVT::v2i32, 3}, // (load 6i32 and) deinterleave into 3 x 2i32
7339 {3, MVT::v4i32, 3}, // (load 12i32 and) deinterleave into 3 x 4i32
7340 {3, MVT::v8i32, 7}, // (load 24i32 and) deinterleave into 3 x 8i32
7341 {3, MVT::v16i32, 14}, // (load 48i32 and) deinterleave into 3 x 16i32
7342 {3, MVT::v32i32, 32}, // (load 96i32 and) deinterleave into 3 x 32i32
7343
7344 {3, MVT::v2i64, 1}, // (load 6i64 and) deinterleave into 3 x 2i64
7345 {3, MVT::v4i64, 5}, // (load 12i64 and) deinterleave into 3 x 4i64
7346 {3, MVT::v8i64, 10}, // (load 24i64 and) deinterleave into 3 x 8i64
7347 {3, MVT::v16i64, 20}, // (load 48i64 and) deinterleave into 3 x 16i64
7348
7349 {4, MVT::v2i8, 4}, // (load 8i8 and) deinterleave into 4 x 2i8
7350 {4, MVT::v4i8, 4}, // (load 16i8 and) deinterleave into 4 x 4i8
7351 {4, MVT::v8i8, 12}, // (load 32i8 and) deinterleave into 4 x 8i8
7352 {4, MVT::v16i8, 24}, // (load 64i8 and) deinterleave into 4 x 16i8
7353 {4, MVT::v32i8, 56}, // (load 128i8 and) deinterleave into 4 x 32i8
7354
7355 {4, MVT::v2i16, 6}, // (load 8i16 and) deinterleave into 4 x 2i16
7356 {4, MVT::v4i16, 17}, // (load 16i16 and) deinterleave into 4 x 4i16
7357 {4, MVT::v8i16, 33}, // (load 32i16 and) deinterleave into 4 x 8i16
7358 {4, MVT::v16i16, 75}, // (load 64i16 and) deinterleave into 4 x 16i16
7359 {4, MVT::v32i16, 150}, // (load 128i16 and) deinterleave into 4 x 32i16
7360
7361 {4, MVT::v2i32, 4}, // (load 8i32 and) deinterleave into 4 x 2i32
7362 {4, MVT::v4i32, 8}, // (load 16i32 and) deinterleave into 4 x 4i32
7363 {4, MVT::v8i32, 16}, // (load 32i32 and) deinterleave into 4 x 8i32
7364 {4, MVT::v16i32, 32}, // (load 64i32 and) deinterleave into 4 x 16i32
7365 {4, MVT::v32i32, 68}, // (load 128i32 and) deinterleave into 4 x 32i32
7366
7367 {4, MVT::v2i64, 6}, // (load 8i64 and) deinterleave into 4 x 2i64
7368 {4, MVT::v4i64, 8}, // (load 16i64 and) deinterleave into 4 x 4i64
7369 {4, MVT::v8i64, 20}, // (load 32i64 and) deinterleave into 4 x 8i64
7370 {4, MVT::v16i64, 40}, // (load 64i64 and) deinterleave into 4 x 16i64
7371
7372 {6, MVT::v2i8, 6}, // (load 12i8 and) deinterleave into 6 x 2i8
7373 {6, MVT::v4i8, 14}, // (load 24i8 and) deinterleave into 6 x 4i8
7374 {6, MVT::v8i8, 18}, // (load 48i8 and) deinterleave into 6 x 8i8
7375 {6, MVT::v16i8, 43}, // (load 96i8 and) deinterleave into 6 x 16i8
7376 {6, MVT::v32i8, 82}, // (load 192i8 and) deinterleave into 6 x 32i8
7377
7378 {6, MVT::v2i16, 13}, // (load 12i16 and) deinterleave into 6 x 2i16
7379 {6, MVT::v4i16, 9}, // (load 24i16 and) deinterleave into 6 x 4i16
7380 {6, MVT::v8i16, 39}, // (load 48i16 and) deinterleave into 6 x 8i16
7381 {6, MVT::v16i16, 106}, // (load 96i16 and) deinterleave into 6 x 16i16
7382 {6, MVT::v32i16, 212}, // (load 192i16 and) deinterleave into 6 x 32i16
7383
7384 {6, MVT::v2i32, 6}, // (load 12i32 and) deinterleave into 6 x 2i32
7385 {6, MVT::v4i32, 15}, // (load 24i32 and) deinterleave into 6 x 4i32
7386 {6, MVT::v8i32, 31}, // (load 48i32 and) deinterleave into 6 x 8i32
7387 {6, MVT::v16i32, 64}, // (load 96i32 and) deinterleave into 6 x 16i32
7388
7389 {6, MVT::v2i64, 6}, // (load 12i64 and) deinterleave into 6 x 2i64
7390 {6, MVT::v4i64, 18}, // (load 24i64 and) deinterleave into 6 x 4i64
7391 {6, MVT::v8i64, 36}, // (load 48i64 and) deinterleave into 6 x 8i64
7392
7393 {8, MVT::v8i32, 40} // (load 64i32 and) deinterleave into 8 x 8i32
7394 };
7395
7396 static const CostTblEntry SSSE3InterleavedLoadTbl[] = {
7397 {2, MVT::v4i16, 2}, // (load 8i16 and) deinterleave into 2 x 4i16
7398 };
7399
7400 static const CostTblEntry SSE2InterleavedLoadTbl[] = {
7401 {2, MVT::v2i16, 2}, // (load 4i16 and) deinterleave into 2 x 2i16
7402 {2, MVT::v4i16, 7}, // (load 8i16 and) deinterleave into 2 x 4i16
7403
7404 {2, MVT::v2i32, 2}, // (load 4i32 and) deinterleave into 2 x 2i32
7405 {2, MVT::v4i32, 2}, // (load 8i32 and) deinterleave into 2 x 4i32
7406
7407 {2, MVT::v2i64, 2}, // (load 4i64 and) deinterleave into 2 x 2i64
7408 };
7409
7410 static const CostTblEntry AVX2InterleavedStoreTbl[] = {
7411 {2, MVT::v16i8, 3}, // interleave 2 x 16i8 into 32i8 (and store)
7412 {2, MVT::v32i8, 4}, // interleave 2 x 32i8 into 64i8 (and store)
7413
7414 {2, MVT::v8i16, 3}, // interleave 2 x 8i16 into 16i16 (and store)
7415 {2, MVT::v16i16, 4}, // interleave 2 x 16i16 into 32i16 (and store)
7416 {2, MVT::v32i16, 8}, // interleave 2 x 32i16 into 64i16 (and store)
7417
7418 {2, MVT::v4i32, 2}, // interleave 2 x 4i32 into 8i32 (and store)
7419 {2, MVT::v8i32, 4}, // interleave 2 x 8i32 into 16i32 (and store)
7420 {2, MVT::v16i32, 8}, // interleave 2 x 16i32 into 32i32 (and store)
7421 {2, MVT::v32i32, 16}, // interleave 2 x 32i32 into 64i32 (and store)
7422
7423 {2, MVT::v2i64, 2}, // interleave 2 x 2i64 into 4i64 (and store)
7424 {2, MVT::v4i64, 4}, // interleave 2 x 4i64 into 8i64 (and store)
7425 {2, MVT::v8i64, 8}, // interleave 2 x 8i64 into 16i64 (and store)
7426 {2, MVT::v16i64, 16}, // interleave 2 x 16i64 into 32i64 (and store)
7427 {2, MVT::v32i64, 32}, // interleave 2 x 32i64 into 64i64 (and store)
7428
7429 {3, MVT::v2i8, 4}, // interleave 3 x 2i8 into 6i8 (and store)
7430 {3, MVT::v4i8, 4}, // interleave 3 x 4i8 into 12i8 (and store)
7431 {3, MVT::v8i8, 6}, // interleave 3 x 8i8 into 24i8 (and store)
7432 {3, MVT::v16i8, 11}, // interleave 3 x 16i8 into 48i8 (and store)
7433 {3, MVT::v32i8, 13}, // interleave 3 x 32i8 into 96i8 (and store)
7434
7435 {3, MVT::v2i16, 4}, // interleave 3 x 2i16 into 6i16 (and store)
7436 {3, MVT::v4i16, 6}, // interleave 3 x 4i16 into 12i16 (and store)
7437 {3, MVT::v8i16, 12}, // interleave 3 x 8i16 into 24i16 (and store)
7438 {3, MVT::v16i16, 27}, // interleave 3 x 16i16 into 48i16 (and store)
7439 {3, MVT::v32i16, 54}, // interleave 3 x 32i16 into 96i16 (and store)
7440
7441 {3, MVT::v2i32, 4}, // interleave 3 x 2i32 into 6i32 (and store)
7442 {3, MVT::v4i32, 5}, // interleave 3 x 4i32 into 12i32 (and store)
7443 {3, MVT::v8i32, 11}, // interleave 3 x 8i32 into 24i32 (and store)
7444 {3, MVT::v16i32, 22}, // interleave 3 x 16i32 into 48i32 (and store)
7445 {3, MVT::v32i32, 48}, // interleave 3 x 32i32 into 96i32 (and store)
7446
7447 {3, MVT::v2i64, 4}, // interleave 3 x 2i64 into 6i64 (and store)
7448 {3, MVT::v4i64, 6}, // interleave 3 x 4i64 into 12i64 (and store)
7449 {3, MVT::v8i64, 12}, // interleave 3 x 8i64 into 24i64 (and store)
7450 {3, MVT::v16i64, 24}, // interleave 3 x 16i64 into 48i64 (and store)
7451
7452 {4, MVT::v2i8, 4}, // interleave 4 x 2i8 into 8i8 (and store)
7453 {4, MVT::v4i8, 4}, // interleave 4 x 4i8 into 16i8 (and store)
7454 {4, MVT::v8i8, 4}, // interleave 4 x 8i8 into 32i8 (and store)
7455 {4, MVT::v16i8, 8}, // interleave 4 x 16i8 into 64i8 (and store)
7456 {4, MVT::v32i8, 12}, // interleave 4 x 32i8 into 128i8 (and store)
7457
7458 {4, MVT::v2i16, 2}, // interleave 4 x 2i16 into 8i16 (and store)
7459 {4, MVT::v4i16, 6}, // interleave 4 x 4i16 into 16i16 (and store)
7460 {4, MVT::v8i16, 10}, // interleave 4 x 8i16 into 32i16 (and store)
7461 {4, MVT::v16i16, 32}, // interleave 4 x 16i16 into 64i16 (and store)
7462 {4, MVT::v32i16, 64}, // interleave 4 x 32i16 into 128i16 (and store)
7463
7464 {4, MVT::v2i32, 5}, // interleave 4 x 2i32 into 8i32 (and store)
7465 {4, MVT::v4i32, 6}, // interleave 4 x 4i32 into 16i32 (and store)
7466 {4, MVT::v8i32, 16}, // interleave 4 x 8i32 into 32i32 (and store)
7467 {4, MVT::v16i32, 32}, // interleave 4 x 16i32 into 64i32 (and store)
7468 {4, MVT::v32i32, 64}, // interleave 4 x 32i32 into 128i32 (and store)
7469
7470 {4, MVT::v2i64, 6}, // interleave 4 x 2i64 into 8i64 (and store)
7471 {4, MVT::v4i64, 8}, // interleave 4 x 4i64 into 16i64 (and store)
7472 {4, MVT::v8i64, 20}, // interleave 4 x 8i64 into 32i64 (and store)
7473 {4, MVT::v16i64, 40}, // interleave 4 x 16i64 into 64i64 (and store)
7474
7475 {6, MVT::v2i8, 7}, // interleave 6 x 2i8 into 12i8 (and store)
7476 {6, MVT::v4i8, 9}, // interleave 6 x 4i8 into 24i8 (and store)
7477 {6, MVT::v8i8, 16}, // interleave 6 x 8i8 into 48i8 (and store)
7478 {6, MVT::v16i8, 27}, // interleave 6 x 16i8 into 96i8 (and store)
7479 {6, MVT::v32i8, 90}, // interleave 6 x 32i8 into 192i8 (and store)
7480
7481 {6, MVT::v2i16, 10}, // interleave 6 x 2i16 into 12i16 (and store)
7482 {6, MVT::v4i16, 15}, // interleave 6 x 4i16 into 24i16 (and store)
7483 {6, MVT::v8i16, 21}, // interleave 6 x 8i16 into 48i16 (and store)
7484 {6, MVT::v16i16, 58}, // interleave 6 x 16i16 into 96i16 (and store)
7485 {6, MVT::v32i16, 90}, // interleave 6 x 32i16 into 192i16 (and store)
7486
7487 {6, MVT::v2i32, 9}, // interleave 6 x 2i32 into 12i32 (and store)
7488 {6, MVT::v4i32, 12}, // interleave 6 x 4i32 into 24i32 (and store)
7489 {6, MVT::v8i32, 33}, // interleave 6 x 8i32 into 48i32 (and store)
7490 {6, MVT::v16i32, 66}, // interleave 6 x 16i32 into 96i32 (and store)
7491
7492 {6, MVT::v2i64, 8}, // interleave 6 x 2i64 into 12i64 (and store)
7493 {6, MVT::v4i64, 15}, // interleave 6 x 4i64 into 24i64 (and store)
7494 {6, MVT::v8i64, 30}, // interleave 6 x 8i64 into 48i64 (and store)
7495 };
7496
7497 static const CostTblEntry SSE2InterleavedStoreTbl[] = {
7498 {2, MVT::v2i8, 1}, // interleave 2 x 2i8 into 4i8 (and store)
7499 {2, MVT::v4i8, 1}, // interleave 2 x 4i8 into 8i8 (and store)
7500 {2, MVT::v8i8, 1}, // interleave 2 x 8i8 into 16i8 (and store)
7501
7502 {2, MVT::v2i16, 1}, // interleave 2 x 2i16 into 4i16 (and store)
7503 {2, MVT::v4i16, 1}, // interleave 2 x 4i16 into 8i16 (and store)
7504
7505 {2, MVT::v2i32, 1}, // interleave 2 x 2i32 into 4i32 (and store)
7506 };
7507
7508 if (Opcode == Instruction::Load) {
7509 auto GetDiscountedCost = [Factor, NumMembers = Indices.size(),
7510 MemOpCosts](const CostTblEntry *Entry) {
7511 // NOTE: this is just an approximation!
7512 // It can over/under -estimate the cost!
7513 return MemOpCosts + divideCeil(NumMembers * Entry->Cost, Factor);
7514 };
7515
7516 if (ST->hasAVX2())
7517 if (const auto *Entry = CostTableLookup(AVX2InterleavedLoadTbl, Factor,
7518 ETy.getSimpleVT()))
7519 return GetDiscountedCost(Entry);
7520
7521 if (ST->hasSSSE3())
7522 if (const auto *Entry = CostTableLookup(SSSE3InterleavedLoadTbl, Factor,
7523 ETy.getSimpleVT()))
7524 return GetDiscountedCost(Entry);
7525
7526 if (ST->hasSSE2())
7527 if (const auto *Entry = CostTableLookup(SSE2InterleavedLoadTbl, Factor,
7528 ETy.getSimpleVT()))
7529 return GetDiscountedCost(Entry);
7530 } else {
7531 assert(Opcode == Instruction::Store &&
7532 "Expected Store Instruction at this point");
7533 assert((!Indices.size() || Indices.size() == Factor) &&
7534 "Interleaved store only supports fully-interleaved groups.");
7535 if (ST->hasAVX2())
7536 if (const auto *Entry = CostTableLookup(AVX2InterleavedStoreTbl, Factor,
7537 ETy.getSimpleVT()))
7538 return MemOpCosts + Entry->Cost;
7539
7540 if (ST->hasSSE2())
7541 if (const auto *Entry = CostTableLookup(SSE2InterleavedStoreTbl, Factor,
7542 ETy.getSimpleVT()))
7543 return MemOpCosts + Entry->Cost;
7544 }
7545
7546 return BaseT::getInterleavedMemoryOpCost(Opcode, VecTy, Factor, Indices,
7547 Alignment, AddressSpace, CostKind,
7548 UseMaskForCond, UseMaskForGaps);
7549}
7550
7552 StackOffset BaseOffset,
7553 bool HasBaseReg, int64_t Scale,
7554 unsigned AddrSpace) const {
7555 // Scaling factors are not free at all.
7556 // An indexed folded instruction, i.e., inst (reg1, reg2, scale),
7557 // will take 2 allocations in the out of order engine instead of 1
7558 // for plain addressing mode, i.e. inst (reg1).
7559 // E.g.,
7560 // vaddps (%rsi,%rdx), %ymm0, %ymm1
7561 // Requires two allocations (one for the load, one for the computation)
7562 // whereas:
7563 // vaddps (%rsi), %ymm0, %ymm1
7564 // Requires just 1 allocation, i.e., freeing allocations for other operations
7565 // and having less micro operations to execute.
7566 //
7567 // For some X86 architectures, this is even worse because for instance for
7568 // stores, the complex addressing mode forces the instruction to use the
7569 // "load" ports instead of the dedicated "store" port.
7570 // E.g., on Haswell:
7571 // vmovaps %ymm1, (%r8, %rdi) can use port 2 or 3.
7572 // vmovaps %ymm1, (%r8) can use port 2, 3, or 7.
7574 AM.BaseGV = BaseGV;
7575 AM.BaseOffs = BaseOffset.getFixed();
7576 AM.HasBaseReg = HasBaseReg;
7577 AM.Scale = Scale;
7578 AM.ScalableOffset = BaseOffset.getScalable();
7579 if (getTLI()->isLegalAddressingMode(DL, AM, Ty, AddrSpace))
7580 // Scale represents reg2 * scale, thus account for 1
7581 // as soon as we use a second register.
7582 return AM.Scale != 0;
7584}
7585
7587 // TODO: Hook MispredictPenalty of SchedMachineModel into this.
7588 return 14;
7589}
7590
7592 unsigned Bits = Ty->getScalarSizeInBits();
7593
7594 // XOP has v16i8/v8i16/v4i32/v2i64 variable vector shifts.
7595 // Splitting for v32i8/v16i16 on XOP+AVX2 targets is still preferred.
7596 if (ST->hasXOP() && (Bits == 8 || Bits == 16 || Bits == 32 || Bits == 64))
7597 return false;
7598
7599 // AVX2 has vpsllv[dq] instructions (and other shifts) that make variable
7600 // shifts just as cheap as scalar ones.
7601 if (ST->hasAVX2() && (Bits == 32 || Bits == 64))
7602 return false;
7603
7604 // AVX512BW has shifts such as vpsllvw.
7605 if (ST->hasBWI() && Bits == 16)
7606 return false;
7607
7608 // Otherwise, it's significantly cheaper to shift by a scalar amount than by a
7609 // fully general vector.
7610 return true;
7611}
7612
7613unsigned X86TTIImpl::getStoreMinimumVF(unsigned VF, Type *ScalarMemTy,
7614 Type *ScalarValTy, Align Alignment,
7615 unsigned AddrSpace) const {
7616 if (ST->hasF16C() && ScalarMemTy->isHalfTy()) {
7617 return 4;
7618 }
7619 return BaseT::getStoreMinimumVF(VF, ScalarMemTy, ScalarValTy, Alignment,
7620 AddrSpace);
7621}
7622
7624 SmallVectorImpl<Use *> &Ops) const {
7625 using namespace llvm::PatternMatch;
7626
7627 if (I->getOpcode() == Instruction::And &&
7628 (ST->hasBMI() || (I->getType()->isVectorTy() && ST->hasSSE2()))) {
7629 for (auto &Op : I->operands()) {
7630 // (and X, (not Y)) -> (andn X, Y)
7631 if (match(Op.get(), m_Not(m_Value())) && !I->getType()->isIntegerTy(8)) {
7632 Ops.push_back(&Op);
7633 return true;
7634 }
7635 // (and X, (splat (not Y))) -> (andn X, (splat Y))
7636 if (match(Op.get(),
7638 m_Value(), m_ZeroMask()))) {
7639 Use &InsertElt = cast<Instruction>(Op)->getOperandUse(0);
7640 Use &Not = cast<Instruction>(InsertElt)->getOperandUse(1);
7641 Ops.push_back(&Not);
7642 Ops.push_back(&InsertElt);
7643 Ops.push_back(&Op);
7644 return true;
7645 }
7646 }
7647 }
7648
7649 FixedVectorType *VTy = dyn_cast<FixedVectorType>(I->getType());
7650 if (!VTy)
7651 return false;
7652
7653 if (I->getOpcode() == Instruction::Mul &&
7654 VTy->getElementType()->isIntegerTy(64)) {
7655 for (auto &Op : I->operands()) {
7656 // Make sure we are not already sinking this operand
7657 if (any_of(Ops, [&](Use *U) { return U->get() == Op; }))
7658 continue;
7659
7660 // Look for PMULDQ pattern where the input is a sext_inreg from vXi32 or
7661 // the PMULUDQ pattern where the input is a zext_inreg from vXi32.
7662 if (ST->hasSSE41() &&
7663 match(Op.get(), m_AShr(m_Shl(m_Value(), m_SpecificInt(32)),
7664 m_SpecificInt(32)))) {
7665 Ops.push_back(&cast<Instruction>(Op)->getOperandUse(0));
7666 Ops.push_back(&Op);
7667 } else if (ST->hasSSE2() &&
7668 match(Op.get(),
7669 m_And(m_Value(), m_SpecificInt(UINT64_C(0xffffffff))))) {
7670 Ops.push_back(&Op);
7671 }
7672 }
7673
7674 return !Ops.empty();
7675 }
7676
7677 // A uniform shift amount in a vector shift or funnel shift may be much
7678 // cheaper than a generic variable vector shift, so make that pattern visible
7679 // to SDAG by sinking the shuffle instruction next to the shift.
7680 int ShiftAmountOpNum = -1;
7681 if (I->isShift())
7682 ShiftAmountOpNum = 1;
7683 else if (auto *II = dyn_cast<IntrinsicInst>(I)) {
7684 if (II->getIntrinsicID() == Intrinsic::fshl ||
7685 II->getIntrinsicID() == Intrinsic::fshr)
7686 ShiftAmountOpNum = 2;
7687 }
7688
7689 if (ShiftAmountOpNum == -1)
7690 return false;
7691
7692 auto *Shuf = dyn_cast<ShuffleVectorInst>(I->getOperand(ShiftAmountOpNum));
7693 if (Shuf && getSplatIndex(Shuf->getShuffleMask()) >= 0 &&
7694 isVectorShiftByScalarCheap(I->getType())) {
7695 Ops.push_back(&I->getOperandUse(ShiftAmountOpNum));
7696 return true;
7697 }
7698
7699 return false;
7700}
7701
7703 bool HasEGPR = ST->hasEGPR();
7704 const TargetMachine &TM = getTLI()->getTargetMachine();
7705
7706 for (User *U : F.users()) {
7708 if (!CB || CB->getCalledOperand() != &F)
7709 continue;
7710 Function *CallerFunc = CB->getFunction();
7711 if (TM.getSubtarget<X86Subtarget>(*CallerFunc).hasEGPR() != HasEGPR)
7712 return false;
7713 }
7714
7715 return true;
7716}
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:856
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.
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:231
LLVM_ABI APInt zext(unsigned width) const
Zero extend to a new width.
Definition APInt.cpp:1050
unsigned popcount() const
Count the number of bits set.
Definition APInt.h:1691
void setBit(unsigned BitPosition)
Set the given bit to 1 whose position is given as "bitPosition".
Definition APInt.h:1351
bool isAllOnes() const
Determine if all bits are set. This is true for zero-width values.
Definition APInt.h:368
static APInt getBitsSet(unsigned numBits, unsigned loBit, unsigned hiBit)
Get a value with a block of bits set.
Definition APInt.h:255
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
Definition APInt.h:377
unsigned getBitWidth() const
Return the number of bits in the APInt.
Definition APInt.h:1509
LLVM_ABI APInt sextOrTrunc(unsigned width) const
Sign extend or truncate to width.
Definition APInt.cpp:1079
APInt ashr(unsigned ShiftAmt) const
Arithmetic right-shift function.
Definition APInt.h:830
static APInt getZero(unsigned numBits)
Get the '0' value for the specified bit-width.
Definition APInt.h:197
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:1583
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
size_t size() const
Get the array size.
Definition ArrayRef.h:141
bool empty() const
Check if the array is empty.
Definition ArrayRef.h:136
InstructionCost getInterleavedMemoryOpCost(unsigned Opcode, Type *VecTy, unsigned Factor, ArrayRef< unsigned > Indices, Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind, bool UseMaskForCond=false, bool UseMaskForGaps=false) const override
InstructionCost getArithmeticInstrCost(unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind, TTI::OperandValueInfo Opd1Info={TTI::OK_AnyValue, TTI::OP_None}, TTI::OperandValueInfo Opd2Info={TTI::OK_AnyValue, TTI::OP_None}, ArrayRef< const Value * > Args={}, const Instruction *CxtI=nullptr) const override
InstructionCost getMinMaxReductionCost(Intrinsic::ID IID, VectorType *Ty, FastMathFlags FMF, TTI::TargetCostKind CostKind) const override
InstructionCost getGEPCost(Type *PointeeType, const Value *Ptr, ArrayRef< const Value * > Operands, Type *AccessType, TTI::TargetCostKind CostKind) const override
TTI::ShuffleKind improveShuffleKindFromMask(TTI::ShuffleKind Kind, ArrayRef< int > Mask, VectorType *SrcTy, int &Index, VectorType *&SubTy) const
bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset, bool HasBaseReg, int64_t Scale, unsigned AddrSpace, Instruction *I=nullptr, int64_t ScalableOffset=0) const override
InstructionCost getShuffleCost(TTI::ShuffleKind Kind, VectorType *DstTy, VectorType *SrcTy, ArrayRef< int > Mask, TTI::TargetCostKind CostKind, int Index, VectorType *SubTp, ArrayRef< const Value * > Args={}, const Instruction *CxtI=nullptr) const override
unsigned getStoreMinimumVF(unsigned VF, Type *ScalarMemTy, Type *ScalarValTy, Align Alignment, unsigned AddrSpace) const override
InstructionCost getScalarizationOverhead(VectorType *InTy, const APInt &DemandedElts, bool Insert, bool Extract, TTI::TargetCostKind CostKind, bool ForPoisonSrc=true, ArrayRef< Value * > VL={}, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const override
InstructionCost getArithmeticReductionCost(unsigned Opcode, VectorType *Ty, std::optional< FastMathFlags > FMF, TTI::TargetCostKind CostKind) const override
InstructionCost getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy, CmpInst::Predicate VecPred, TTI::TargetCostKind CostKind, TTI::OperandValueInfo Op1Info={TTI::OK_AnyValue, TTI::OP_None}, TTI::OperandValueInfo Op2Info={TTI::OK_AnyValue, TTI::OP_None}, const Instruction *I=nullptr) const override
InstructionCost getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src, TTI::CastContextHint CCH, TTI::TargetCostKind CostKind, const Instruction *I=nullptr) const override
std::pair< InstructionCost, MVT > getTypeLegalizationCost(Type *Ty) const
InstructionCost getReplicationShuffleCost(Type *EltTy, int ReplicationFactor, int VF, const APInt &DemandedDstElts, TTI::TargetCostKind CostKind) const override
InstructionCost getVectorInstrCost(unsigned Opcode, Type *Val, TTI::TargetCostKind CostKind, unsigned Index, const Value *Op0, const Value *Op1, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const override
InstructionCost getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA, TTI::TargetCostKind CostKind) const override
InstructionCost getAddressComputationCost(Type *PtrTy, ScalarEvolution *, const SCEV *, TTI::TargetCostKind) const override
InstructionCost getMemIntrinsicInstrCost(const MemIntrinsicCostAttributes &MICA, TTI::TargetCostKind CostKind) const override
InstructionCost getMemoryOpCost(unsigned Opcode, Type *Src, Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind, TTI::OperandValueInfo OpInfo={TTI::OK_AnyValue, TTI::OP_None}, const Instruction *I=nullptr) const override
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Value * getCalledOperand() const
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition InstrTypes.h:740
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
Definition InstrTypes.h:743
@ ICMP_SLE
signed less or equal
Definition InstrTypes.h:770
@ ICMP_UGE
unsigned greater or equal
Definition InstrTypes.h:764
@ ICMP_UGT
unsigned greater than
Definition InstrTypes.h:763
@ FCMP_ONE
0 1 1 0 True if ordered and operands are unequal
Definition InstrTypes.h:748
@ FCMP_UEQ
1 0 0 1 True if unordered or equal
Definition InstrTypes.h:751
@ ICMP_ULT
unsigned less than
Definition InstrTypes.h:765
@ ICMP_NE
not equal
Definition InstrTypes.h:762
@ ICMP_SGE
signed greater or equal
Definition InstrTypes.h:768
@ ICMP_ULE
unsigned less or equal
Definition InstrTypes.h:766
@ FCMP_UNO
1 0 0 0 True if unordered: isnan(X) | isnan(Y)
Definition InstrTypes.h:750
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
constexpr bool isScalar() const
Exactly one element.
Definition TypeSize.h:320
Convenience struct for specifying and reasoning about fast-math flags.
Definition FMF.h:23
Container class for subtarget features.
Class to represent fixed width SIMD vectors.
unsigned getNumElements() const
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
Definition Type.cpp:867
static 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.
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
Definition Type.cpp:348
const SmallVectorImpl< Type * > & getArgTypes() const
const SmallVectorImpl< const Value * > & getArgs() const
const IntrinsicInst * getInst() const
A wrapper class for inspecting calls to intrinsic functions.
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
Machine Value Type.
bool is128BitVector() const
Return true if this is a 128-bit vector type.
uint64_t getScalarSizeInBits() const
unsigned getVectorNumElements() const
bool isVector() const
Return true if this is a vector value type.
bool isInteger() const
Return true if this is an integer or a vector integer type.
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
bool isScalarInteger() const
Return true if this is an integer, not including vectors.
static MVT getVectorVT(MVT VT, unsigned NumElements)
MVT getVectorElementType() const
MVT getScalarType() const
If this is a vector, return the element type, otherwise return this.
Information for memory intrinsic cost model.
This class represents an analyzed expression in the program.
The main scalar evolution driver.
static LLVM_ABI bool isIdentityMask(ArrayRef< int > Mask, int NumSrcElts)
Return true if this shuffle mask chooses elements from exactly one source vector without lane crossin...
This is a 'bitvector' (really, a variable-sized bit array), optimized for the case when the array is ...
bool test(unsigned Idx) const
Returns true if bit Idx is set.
size_type size() const
Returns the number of bits in this bitvector.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StackOffset holds a fixed and a scalable offset in bytes.
Definition TypeSize.h:30
static StackOffset getScalable(int64_t Scalable)
Definition TypeSize.h:40
static StackOffset getFixed(int64_t Fixed)
Definition TypeSize.h:39
virtual MVT getRegisterTypeForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const
Certain combinations of ABIs, Targets and features require that types are legal for some operations a...
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
Primary interface to the complete machine description for the target machine.
const STC & getSubtarget(const Function &F) const
This method returns a pointer to the specified type of TargetSubtargetInfo.
virtual const TargetSubtargetInfo * getSubtargetImpl(const Function &) const
Virtual method implemented by subclasses that returns a reference to that target's TargetSubtargetInf...
virtual const TargetLowering * getTargetLowering() const
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:343
static constexpr TypeSize getScalable(ScalarTy MinimumSize)
Definition TypeSize.h:346
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
Definition Type.cpp:310
LLVM_ABI unsigned getIntegerBitWidth() const
bool isVectorTy() const
True if this is an instance of VectorType.
Definition Type.h:288
LLVM_ABI bool isScalableTy(SmallPtrSetImpl< const Type * > &Visited) const
Return true if this is a type whose size is a known multiple of vscale.
Definition Type.cpp:61
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
Definition Type.cpp:309
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
Definition Type.h:263
bool isPointerTy() const
True if this is an instance of PointerType.
Definition Type.h:282
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
Definition Type.h:155
bool isBFloatTy() const
Return true if this is 'bfloat', a 16-bit bfloat type.
Definition Type.h:147
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
Definition Type.cpp:307
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Definition Type.h:368
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
Definition Type.cpp:197
LLVM_ABI Type * getWithNewBitWidth(unsigned NewBitWidth) const
Given an integer or vector type, change the lane bitwidth to NewBitwidth, whilst keeping the old numb...
bool isHalfTy() const
Return true if this is 'half', a 16-bit IEEE fp type.
Definition Type.h:144
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
Definition Type.h:130
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
Definition Type.cpp:232
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
Definition Type.h:158
static LLVM_ABI IntegerType * getInt1Ty(LLVMContext &C)
Definition Type.cpp:306
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
Definition Type.h:186
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:257
static LLVM_ABI IntegerType * getIntNTy(LLVMContext &C, unsigned N)
Definition Type.cpp:313
static LLVM_ABI Type * getDoubleTy(LLVMContext &C)
Definition Type.cpp:287
bool isFPOrFPVectorTy() const
Return true if this is a FP type or a vector of FP.
Definition Type.h:227
Type * getContainedType(unsigned i) const
This method is used to implement the type iterator (defined at the end of the file).
Definition Type.h:397
static LLVM_ABI Type * getFloatTy(LLVMContext &C)
Definition Type.cpp:286
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:255
Base class of all SIMD vector types.
static VectorType * getExtendedElementVectorType(VectorType *VTy)
This static method is like getInteger except that the element types are twice as wide as the elements...
ElementCount getElementCount() const
Return an ElementCount instance to represent the (possibly scalable) number of elements in the vector...
static VectorType * getDoubleElementsVectorType(VectorType *VTy)
This static method returns a VectorType with twice as many elements as the input type and the same el...
Type * getElementType() const
bool useAVX512Regs() const
bool hasAVX512() const
bool hasAVX2() const
bool useFastCCForInternalCall(Function &F) const override
InstructionCost getReplicationShuffleCost(Type *EltTy, int ReplicationFactor, int VF, const APInt &DemandedDstElts, TTI::TargetCostKind CostKind) const override
bool isLegalNTLoad(Type *DataType, Align Alignment) const override
std::optional< unsigned > getCacheAssociativity(TargetTransformInfo::CacheLevel Level) const override
InstructionCost getMinMaxReductionCost(Intrinsic::ID IID, VectorType *Ty, FastMathFlags FMF, TTI::TargetCostKind CostKind) const override
Try to calculate op costs for min/max reduction operations.
bool isLegalBroadcastLoad(Type *ElementTy, ElementCount NumElements) const override
unsigned getRegisterClassForType(bool Vector, Type *Ty) const override
InstructionCost getMemIntrinsicInstrCost(const MemIntrinsicCostAttributes &MICA, TTI::TargetCostKind CostKind) const override
Get memory intrinsic cost based on arguments.
unsigned getMaxInterleaveFactor(ElementCount VF, bool HasUnorderedReductions) const override
InstructionCost getShuffleCost(TTI::ShuffleKind Kind, VectorType *DstTy, VectorType *SrcTy, ArrayRef< int > Mask, TTI::TargetCostKind CostKind, int Index, VectorType *SubTp, ArrayRef< const Value * > Args={}, const Instruction *CxtI=nullptr) const override
bool isLegalNTStore(Type *DataType, Align Alignment) const override
InstructionCost getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src, TTI::CastContextHint CCH, TTI::TargetCostKind CostKind, const Instruction *I=nullptr) const override
InstructionCost getInterleavedMemoryOpCostAVX512(unsigned Opcode, FixedVectorType *VecTy, unsigned Factor, ArrayRef< unsigned > Indices, Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind, bool UseMaskForCond=false, bool UseMaskForGaps=false) const
bool isLegalAltInstr(VectorType *VecTy, unsigned Opcode0, unsigned Opcode1, const SmallBitVector &OpcodeMask) const override
TypeSize getRegisterBitWidth(TargetTransformInfo::RegisterKind K) const override
bool isVectorShiftByScalarCheap(Type *Ty) const override
bool isLegalMaskedGather(Type *DataType, Align Alignment) const override
bool shouldExpandReduction(const IntrinsicInst *II) const override
InstructionCost getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, StackOffset BaseOffset, bool HasBaseReg, int64_t Scale, unsigned AddrSpace) const override
Return the cost of the scaling factor used in the addressing mode represented by AM for this target,...
unsigned getAtomicMemIntrinsicMaxElementSize() const override
bool forceScalarizeMaskedGather(VectorType *VTy, Align Alignment) const override
InstructionCost getBranchMispredictPenalty() const override
bool isExpensiveToSpeculativelyExecute(const Instruction *I) const override
bool hasConditionalLoadStoreForType(Type *Ty, bool IsStore) const override
bool isLegalMaskedStore(Type *DataType, Align Alignment, unsigned AddressSpace, TTI::MaskKind MaskKind=TTI::MaskKind::VariableOrConstantMask) const override
std::optional< unsigned > getCacheSize(TargetTransformInfo::CacheLevel Level) const override
InstructionCost getArithmeticInstrCost(unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind, TTI::OperandValueInfo Op1Info={TTI::OK_AnyValue, TTI::OP_None}, TTI::OperandValueInfo Op2Info={TTI::OK_AnyValue, TTI::OP_None}, ArrayRef< const Value * > Args={}, const Instruction *CxtI=nullptr) const override
bool isLegalMaskedGatherScatter(Type *DataType, Align Alignment) const
bool isLegalMaskedLoad(Type *DataType, Align Alignment, unsigned AddressSpace, TTI::MaskKind MaskKind=TTI::MaskKind::VariableOrConstantMask) const override
bool enableInterleavedAccessVectorization() const override
unsigned getLoadStoreVecRegBitWidth(unsigned AS) const override
unsigned getNumberOfRegisters(unsigned ClassID) const override
InstructionCost getVectorInstrCost(unsigned Opcode, Type *Val, TTI::TargetCostKind CostKind, unsigned Index, const Value *Op0, const Value *Op1, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const override
bool isLegalMaskedScatter(Type *DataType, Align Alignment) const override
unsigned getStoreMinimumVF(unsigned VF, Type *ScalarMemTy, Type *ScalarValTy, Align Alignment, unsigned AddrSpace) const override
bool hasDivRemOp(Type *DataType, bool IsSigned) const override
bool isLegalMaskedCompressStore(Type *DataType, Align Alignment) const override
InstructionCost getIntImmCostIntrin(Intrinsic::ID IID, unsigned Idx, const APInt &Imm, Type *Ty, TTI::TargetCostKind CostKind) const override
bool supportsEfficientVectorElementLoadStore() const override
InstructionCost getIntImmCostInst(unsigned Opcode, unsigned Idx, const APInt &Imm, Type *Ty, TTI::TargetCostKind CostKind, Instruction *Inst=nullptr) const override
bool isLegalMaskedExpandLoad(Type *DataType, Align Alignment) const override
TTI::PopcntSupportKind getPopcntSupport(unsigned TyWidth) const override
bool isFCmpOrdCheaperThanFCmpZero(Type *Ty) const override
TTI::MemCmpExpansionOptions enableMemCmpExpansion(bool OptSize, bool IsZeroCmp) const override
InstructionCost getPointersChainCost(ArrayRef< const Value * > Ptrs, const Value *Base, const TTI::PointersChainInfo &Info, Type *AccessTy, const TTI::TargetCostKind CostKind) const override
InstructionCost getIntImmCost(int64_t) const
Calculate the cost of materializing a 64-bit value.
InstructionCost getMinMaxCost(Intrinsic::ID IID, Type *Ty, TTI::TargetCostKind CostKind, FastMathFlags FMF) const
InstructionCost getCFInstrCost(unsigned Opcode, TTI::TargetCostKind CostKind, const Instruction *I=nullptr) const override
InstructionCost getInterleavedMemoryOpCost(unsigned Opcode, Type *VecTy, unsigned Factor, ArrayRef< unsigned > Indices, Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind, bool UseMaskForCond=false, bool UseMaskForGaps=false) const override
bool canMacroFuseCmp() const override
bool areInlineCompatible(const Function *Caller, const Function *Callee) const override
InstructionCost getMaskedMemoryOpCost(const MemIntrinsicCostAttributes &MICA, TTI::TargetCostKind CostKind) const
bool prefersVectorizedAddressing() const override
bool areTypesABICompatible(const Function *Caller, const Function *Callee, ArrayRef< Type * > Type) const override
InstructionCost getAltInstrCost(VectorType *VecTy, unsigned Opcode0, unsigned Opcode1, const SmallBitVector &OpcodeMask, TTI::TargetCostKind CostKind) const override
bool forceScalarizeMaskedScatter(VectorType *VTy, Align Alignment) const override
InstructionCost getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA, TTI::TargetCostKind CostKind) const override
Get intrinsic cost based on arguments.
bool isProfitableToSinkOperands(Instruction *I, SmallVectorImpl< Use * > &Ops) const override
InstructionCost getScalarizationOverhead(VectorType *Ty, const APInt &DemandedElts, bool Insert, bool Extract, TTI::TargetCostKind CostKind, bool ForPoisonSrc=true, ArrayRef< Value * > VL={}, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const override
Estimate the overhead of scalarizing an instruction.
InstructionCost getArithmeticReductionCost(unsigned Opcode, VectorType *Ty, std::optional< FastMathFlags > FMF, TTI::TargetCostKind CostKind) const override
InstructionCost getGatherScatterOpCost(const MemIntrinsicCostAttributes &MICA, TTI::TargetCostKind CostKind) const
Calculate the cost of Gather / Scatter operation.
InstructionCost getMemoryOpCost(unsigned Opcode, Type *Src, Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind, TTI::OperandValueInfo OpInfo={TTI::OK_AnyValue, TTI::OP_None}, const Instruction *I=nullptr) const override
InstructionCost getAddressComputationCost(Type *PtrTy, ScalarEvolution *SE, const SCEV *Ptr, TTI::TargetCostKind CostKind) const override
InstructionCost getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy, CmpInst::Predicate VecPred, TTI::TargetCostKind CostKind, TTI::OperandValueInfo Op1Info={TTI::OK_AnyValue, TTI::OP_None}, TTI::OperandValueInfo Op2Info={TTI::OK_AnyValue, TTI::OP_None}, const Instruction *I=nullptr) const override
bool isLSRCostLess(const TargetTransformInfo::LSRCost &C1, const TargetTransformInfo::LSRCost &C2) const override
constexpr ScalarTy getFixedValue() const
Definition TypeSize.h:200
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
Definition TypeSize.h:168
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
Definition TypeSize.h:165
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
LLVM_ABI APInt ScaleBitMask(const APInt &A, unsigned NewBitWidth, bool MatchAllBits=false)
Splat/Merge neighboring bits to widen/narrow the bitmask represented by.
Definition APInt.cpp:3035
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
ISD namespace - This namespace contains an enum which represents all of the SelectionDAG node types a...
Definition ISDOpcodes.h:24
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
Definition ISDOpcodes.h:41
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
Definition ISDOpcodes.h:829
@ DELETED_NODE
DELETED_NODE - This is an illegal value that is used to catch errors.
Definition ISDOpcodes.h:45
@ BSWAP
Byte Swap and Counting operators.
Definition ISDOpcodes.h:789
@ ADD
Simple integer binary arithmetic operators.
Definition ISDOpcodes.h:264
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
Definition ISDOpcodes.h:890
@ FADD
Simple binary floating point operators.
Definition ISDOpcodes.h:417
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
Definition ISDOpcodes.h:749
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
Definition ISDOpcodes.h:280
@ CLMUL
Carry-less multiplication operations.
Definition ISDOpcodes.h:780
@ CTLZ_ZERO_POISON
Definition ISDOpcodes.h:798
@ SIGN_EXTEND
Conversion operators.
Definition ISDOpcodes.h:854
@ FNEG
Perform various unary floating-point operations inspired by libm.
@ SSUBSAT
RESULT = [US]SUBSAT(LHS, RHS) - Perform saturation subtraction on 2 integers with the same bit width ...
Definition ISDOpcodes.h:374
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
Definition ISDOpcodes.h:806
@ SADDO
RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
Definition ISDOpcodes.h:348
@ SHL
Shift and rotation operations.
Definition ISDOpcodes.h:771
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
Definition ISDOpcodes.h:578
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
Definition ISDOpcodes.h:860
@ FMINNUM
FMINNUM/FMAXNUM - Perform floating-point minimum maximum on two values, following IEEE-754 definition...
@ SMULO
Same for multiplication.
Definition ISDOpcodes.h:356
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
Definition ISDOpcodes.h:729
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
Definition ISDOpcodes.h:988
@ FMINIMUM
FMINIMUM/FMAXIMUM - NaN-propagating minimum/maximum that also treat -0.0 as less than 0....
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
Definition ISDOpcodes.h:936
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition ISDOpcodes.h:741
@ CTTZ_ZERO_POISON
Bit counting operators with a poisoned result for zero inputs.
Definition ISDOpcodes.h:797
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
Definition ISDOpcodes.h:969
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
Definition ISDOpcodes.h:866
@ SADDSAT
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
Definition ISDOpcodes.h:365
SpecificConstantMatch m_ZeroInt()
Convenience matchers for specific integer values.
BinaryOp_match< SrcTy, SpecificConstantMatch, TargetOpcode::G_XOR, true > m_Not(const SrcTy &&Src)
Matches a register not-ed by a G_XOR.
OneUse_match< SubPat > m_OneUse(const SubPat &SP)
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::AShr > m_AShr(const LHS &L, const RHS &R)
ap_match< APInt > m_APIntAllowPoison(const APInt *&Res)
Match APInt while allowing poison in splat vector constants.
specific_intval< false > m_SpecificInt(const APInt &V)
Match a specific integer value or vector with all elements equal to the value.
bool match(Val *V, const Pattern &P)
auto m_Value()
Match an arbitrary value and ignore it.
TwoOps_match< V1_t, V2_t, Instruction::ShuffleVector > m_Shuffle(const V1_t &v1, const V2_t &v2)
Matches ShuffleVectorInst independently of mask value.
OneOps_match< OpTy, Instruction::Load > m_Load(const OpTy &Op)
Matches LoadInst.
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
ThreeOps_match< Val_t, Elt_t, Idx_t, Instruction::InsertElement > m_InsertElt(const Val_t &Val, const Elt_t &Elt, const Idx_t &Idx)
Matches InsertElementInst.
This is an optimization pass for GlobalISel generic memory operations.
constexpr auto not_equal_to(T &&Arg)
Functor variant of std::not_equal_to that can be used as a UnaryPredicate in functional algorithms li...
Definition STLExtras.h:2180
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1739
const CostTblEntryT< CostType > * CostTableLookup(ArrayRef< CostTblEntryT< CostType > > Tbl, int ISD, MVT Ty)
Find in cost table.
Definition CostTable.h:36
InstructionCost Cost
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Definition MathExtras.h:166
@ Known
Known to have no common set bits.
LLVM_ABI void ComputeValueVTs(const TargetLowering &TLI, const DataLayout &DL, Type *Ty, SmallVectorImpl< EVT > &ValueVTs, SmallVectorImpl< EVT > *MemVTs=nullptr, SmallVectorImpl< TypeSize > *Offsets=nullptr, TypeSize StartingOffset=TypeSize::getZero())
ComputeValueVTs - Given an LLVM IR type, compute a sequence of EVTs that represent all the individual...
Definition Analysis.cpp:119
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
Definition STLExtras.h:2554
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
constexpr T alignDown(U Value, V Align, W Skew=0)
Returns the largest unsigned integer less than or equal to Value and is Skew mod Align.
Definition MathExtras.h:547
LLVM_ABI Value * getSplatValue(const Value *V)
Get splat value if the input is a splat vector or return nullptr.
bool isa_and_nonnull(const Y &Val)
Definition Casting.h:676
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
uint64_t PowerOf2Ceil(uint64_t A)
Returns the power of two which is greater than or equal to the given value.
Definition MathExtras.h:386
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1746
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition MathExtras.h:280
LLVM_ABI void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true, unsigned Depth=0)
Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition Alignment.h:144
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
constexpr int PoisonMaskElem
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
Definition MathExtras.h:395
DWARFExpression::Operation Op
OutputIt copy(R &&Range, OutputIt Out)
Definition STLExtras.h:1885
CostTblEntryT< uint16_t > CostTblEntry
Definition CostTable.h:31
auto count_if(R &&Range, UnaryPredicate P)
Wrapper function around std::count_if to count the number of times an element satisfying a given pred...
Definition STLExtras.h:2019
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
constexpr auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
Definition Sequence.h:341
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
Definition Alignment.h:201
LLVM_ABI void processShuffleMasks(ArrayRef< int > Mask, unsigned NumOfSrcRegs, unsigned NumOfDestRegs, unsigned NumOfUsedRegs, function_ref< void()> NoInputAction, function_ref< void(ArrayRef< int >, unsigned, unsigned)> SingleInputAction, function_ref< void(ArrayRef< int >, unsigned, unsigned, bool)> ManyInputsAction)
Splits and processes shuffle mask depending on the number of input and output registers.
const TypeConversionCostTblEntryT< CostType > * ConvertCostTableLookup(ArrayRef< TypeConversionCostTblEntryT< CostType > > Tbl, int ISD, MVT Dst, MVT Src)
Find in type conversion cost table.
Definition CostTable.h:67
LLVM_ABI int getSplatIndex(ArrayRef< int > Mask)
If all non-negative Mask elements are the same value, return that value.
#define N
std::optional< unsigned > operator[](TargetTransformInfo::TargetCostKind Kind) const
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
Cost Table Entry.
Definition CostTable.h:26
Extended Value Type.
Definition ValueTypes.h:35
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
Definition ValueTypes.h:145
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition ValueTypes.h:396
uint64_t getScalarSizeInBits() const
Definition ValueTypes.h:408
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition ValueTypes.h:339
bool isVector() const
Return true if this is a vector value type.
Definition ValueTypes.h:176
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
Definition ValueTypes.h:346
This represents an addressing mode of: BaseGV + BaseOffs + BaseReg + Scale*ScaleReg + ScalableOffset*...
unsigned Insns
TODO: Some of these could be merged.
Returns options for expansion of memcmp. IsZeroCmp is.
Describe known properties for a set of pointers.
Type Conversion Cost Table.
Definition CostTable.h:56