LLVM 24.0.0git
X86TargetTransformInfo.cpp
Go to the documentation of this file.
1//===-- X86TargetTransformInfo.cpp - X86 specific TTI pass ----------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8/// \file
9/// This file implements a TargetTransformInfo analysis pass specific to the
10/// X86 target machine. It uses the target's detailed information to provide
11/// more precise answers to certain TTI queries, while letting the target
12/// independent and default TTI implementations handle the rest.
13///
14//===----------------------------------------------------------------------===//
15/// About Cost Model numbers used below it's necessary to say the following:
16/// the numbers correspond to some "generic" X86 CPU instead of usage of a
17/// specific CPU model. Usually the numbers correspond to the CPU where the
18/// feature first appeared. For example, if we do Subtarget.hasSSE42() in
19/// the lookups below the cost is based on Nehalem as that was the first CPU
20/// to support that feature level and thus has most likely the worst case cost,
21/// although we may discard an outlying worst cost from one CPU (e.g. Atom).
22///
23/// Some examples of other technologies/CPUs:
24/// SSE 3 - Pentium4 / Athlon64
25/// SSE 4.1 - Penryn
26/// SSE 4.2 - Nehalem / Silvermont
27/// AVX - Sandy Bridge / Jaguar / Bulldozer
28/// AVX2 - Haswell / Ryzen
29/// AVX-512 - Xeon Phi / Skylake
30///
31/// And some examples of instruction target dependent costs (latency)
32/// divss sqrtss rsqrtss
33/// AMD K7 11-16 19 3
34/// Piledriver 9-24 13-15 5
35/// Jaguar 14 16 2
36/// Pentium II,III 18 30 2
37/// Nehalem 7-14 7-18 3
38/// Haswell 10-13 11 5
39///
40/// Interpreting the 4 TargetCostKind types:
41/// TCK_RecipThroughput and TCK_Latency should try to match the worst case
42/// values reported by the CPU scheduler models (and llvm-mca).
43/// TCK_CodeSize should match the instruction count (e.g. divss = 1), NOT the
44/// actual encoding size of the instruction.
45/// TCK_SizeAndLatency should match the worst case micro-op counts reported by
46/// by the CPU scheduler models (and llvm-mca), to ensure that they are
47/// compatible with the MicroOpBufferSize and LoopMicroOpBufferSize values which are
48/// often used as the cost thresholds where TCK_SizeAndLatency is requested.
49//===----------------------------------------------------------------------===//
50
60#include <optional>
61
62using namespace llvm;
63
64#define DEBUG_TYPE "x86tti"
65
66//===----------------------------------------------------------------------===//
67//
68// X86 cost model.
69//
70//===----------------------------------------------------------------------===//
71
72// Helper struct to store/access costs for each cost kind.
73// TODO: Move this to allow other targets to use it?
75 unsigned RecipThroughputCost = ~0U;
76 unsigned LatencyCost = ~0U;
77 unsigned CodeSizeCost = ~0U;
78 unsigned SizeAndLatencyCost = ~0U;
79
80 std::optional<unsigned>
82 unsigned Cost = ~0U;
83 switch (Kind) {
86 break;
89 break;
92 break;
95 break;
96 }
97 if (Cost == ~0U)
98 return std::nullopt;
99 return Cost;
100 }
101};
104
106X86TTIImpl::getPopcntSupport(unsigned TyWidth) const {
107 assert(isPowerOf2_32(TyWidth) && "Ty width must be power of 2");
108 // TODO: Currently the __builtin_popcount() implementation using SSE3
109 // instructions is inefficient. Once the problem is fixed, we should
110 // call ST->hasSSE3() instead of ST->hasPOPCNT().
111 return ST->hasPOPCNT() ? TTI::PSK_FastHardware : TTI::PSK_Software;
112}
113
114std::optional<unsigned> X86TTIImpl::getCacheSize(
116 switch (Level) {
118 // - Penryn
119 // - Nehalem
120 // - Westmere
121 // - Sandy Bridge
122 // - Ivy Bridge
123 // - Haswell
124 // - Broadwell
125 // - Skylake
126 // - Kabylake
127 return 32 * 1024; // 32 KiB
129 // - Penryn
130 // - Nehalem
131 // - Westmere
132 // - Sandy Bridge
133 // - Ivy Bridge
134 // - Haswell
135 // - Broadwell
136 // - Skylake
137 // - Kabylake
138 return 256 * 1024; // 256 KiB
139 }
140
141 llvm_unreachable("Unknown TargetTransformInfo::CacheLevel");
142}
143
144std::optional<unsigned> X86TTIImpl::getCacheAssociativity(
146 // - Penryn
147 // - Nehalem
148 // - Westmere
149 // - Sandy Bridge
150 // - Ivy Bridge
151 // - Haswell
152 // - Broadwell
153 // - Skylake
154 // - Kabylake
155 switch (Level) {
157 [[fallthrough]];
159 return 8;
160 }
161
162 llvm_unreachable("Unknown TargetTransformInfo::CacheLevel");
163}
164
166
168 return Vector ? VectorClass
169 : Ty && Ty->isFloatingPointTy() ? ScalarFPClass
170 : GPRClass;
171}
172
173unsigned X86TTIImpl::getNumberOfRegisters(unsigned ClassID) const {
174 if (ClassID == VectorClass && !ST->hasSSE1())
175 return 0;
176
177 if (!ST->is64Bit())
178 return 8;
179
180 if ((ClassID == GPRClass && ST->hasEGPR()) ||
181 (ClassID != GPRClass && ST->hasAVX512()))
182 return 32;
183
184 return 16;
185}
186
188 if (!ST->hasCF())
189 return false;
190 if (!Ty)
191 return true;
192 // Conditional faulting is supported by CFCMOV, which only accepts
193 // 16/32/64-bit operands.
194 // TODO: Support f32/f64 with VMOVSS/VMOVSD with zero mask when it's
195 // profitable.
196 auto *VTy = dyn_cast<FixedVectorType>(Ty);
197 if (!Ty->isIntegerTy() && (!VTy || VTy->getNumElements() != 1))
198 return false;
199 auto *ScalarTy = Ty->getScalarType();
200 switch (cast<IntegerType>(ScalarTy)->getBitWidth()) {
201 default:
202 return false;
203 case 16:
204 case 32:
205 case 64:
206 return true;
207 }
208}
209
212 unsigned PreferVectorWidth = ST->getPreferVectorWidth();
213 switch (K) {
215 return TypeSize::getFixed(ST->is64Bit() ? 64 : 32);
217 if (ST->hasAVX512() && PreferVectorWidth >= 512)
218 return TypeSize::getFixed(512);
219 if (ST->hasAVX() && PreferVectorWidth >= 256)
220 return TypeSize::getFixed(256);
221 if (ST->hasSSE1() && PreferVectorWidth >= 128)
222 return TypeSize::getFixed(128);
223 return TypeSize::getFixed(0);
225 return TypeSize::getScalable(0);
226 }
227
228 llvm_unreachable("Unsupported register kind");
229}
230
235
237 bool HasUnorderedReductions) const {
238 // If the loop will not be vectorized, don't interleave the loop.
239 // Let regular unroll to unroll the loop, which saves the overflow
240 // check and memory check cost.
241 if (VF.isScalar())
242 return 1;
243
244 if (ST->isAtom())
245 return 1;
246
247 // Sandybridge and Haswell have multiple execution ports and pipelined
248 // vector units.
249 if (ST->hasAVX())
250 return 4;
251
252 return 2;
253}
254
256 unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind,
258 ArrayRef<const Value *> Args, const Instruction *CxtI) const {
259
260 // vXi8 multiplications are always promoted to vXi16.
261 // Sub-128-bit types can be extended/packed more efficiently.
262 if (Opcode == Instruction::Mul && Ty->isVectorTy() &&
263 Ty->getPrimitiveSizeInBits() <= 64 && Ty->getScalarSizeInBits() == 8) {
264 Type *WideVecTy =
266 return getCastInstrCost(Instruction::ZExt, WideVecTy, Ty,
268 CostKind) +
269 getCastInstrCost(Instruction::Trunc, Ty, WideVecTy,
271 CostKind) +
272 getArithmeticInstrCost(Opcode, WideVecTy, CostKind, Op1Info, Op2Info);
273 }
274
275 // Legalize the type.
276 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Ty);
277
278 int ISD = TLI->InstructionOpcodeToISD(Opcode);
279 assert(ISD && "Invalid opcode");
280
281 if (ISD == ISD::MUL && Args.size() == 2 && LT.second.isVector() &&
282 (LT.second.getScalarType() == MVT::i32 ||
283 LT.second.getScalarType() == MVT::i64)) {
284 // Check if the operands can be represented as a smaller datatype.
285 bool Op1Signed = false, Op2Signed = false;
286 unsigned Op1MinSize = BaseT::minRequiredElementSize(Args[0], Op1Signed);
287 unsigned Op2MinSize = BaseT::minRequiredElementSize(Args[1], Op2Signed);
288 unsigned OpMinSize = std::max(Op1MinSize, Op2MinSize);
289 bool SignedMode = Op1Signed || Op2Signed;
290
291 // If both vXi32 are representable as i15 and at least one is constant,
292 // zero-extended, or sign-extended from vXi16 (or less pre-SSE41) then we
293 // can treat this as PMADDWD which has the same costs as a vXi16 multiply.
294 if (OpMinSize <= 15 && !ST->isPMADDWDSlow() &&
295 LT.second.getScalarType() == MVT::i32) {
296 bool Op1Constant =
297 isa<ConstantDataVector>(Args[0]) || isa<ConstantVector>(Args[0]);
298 bool Op2Constant =
299 isa<ConstantDataVector>(Args[1]) || isa<ConstantVector>(Args[1]);
300 bool Op1Sext = isa<SExtInst>(Args[0]) &&
301 (Op1MinSize == 15 || (Op1MinSize < 15 && !ST->hasSSE41()));
302 bool Op2Sext = isa<SExtInst>(Args[1]) &&
303 (Op2MinSize == 15 || (Op2MinSize < 15 && !ST->hasSSE41()));
304
305 bool IsZeroExtended = !Op1Signed || !Op2Signed;
306 bool IsConstant = Op1Constant || Op2Constant;
307 bool IsSext = Op1Sext || Op2Sext;
308 if (IsConstant || IsZeroExtended || IsSext)
309 LT.second =
310 MVT::getVectorVT(MVT::i16, 2 * LT.second.getVectorNumElements());
311 }
312
313 // Check if the vXi32 operands can be shrunk into a smaller datatype.
314 // This should match the codegen from reduceVMULWidth.
315 // TODO: Make this generic (!ST->SSE41 || ST->isPMULLDSlow()).
316 if (ST->useSLMArithCosts() && LT.second == MVT::v4i32) {
317 if (OpMinSize <= 7)
318 return LT.first * 3; // pmullw/sext
319 if (!SignedMode && OpMinSize <= 8)
320 return LT.first * 3; // pmullw/zext
321 if (OpMinSize <= 15)
322 return LT.first * 5; // pmullw/pmulhw/pshuf
323 if (!SignedMode && OpMinSize <= 16)
324 return LT.first * 5; // pmullw/pmulhw/pshuf
325 }
326
327 // If both vXi64 are representable as (unsigned) i32, then we can perform
328 // the multiple with a single PMULUDQ instruction.
329 // TODO: Add (SSE41+) PMULDQ handling for signed extensions.
330 if (!SignedMode && OpMinSize <= 32 && LT.second.getScalarType() == MVT::i64)
331 ISD = X86ISD::PMULUDQ;
332 }
333
334 // Vector multiply by pow2 will be simplified to shifts.
335 // Vector multiply by -pow2 will be simplified to shifts/negates.
336 if (ISD == ISD::MUL && Op2Info.isConstant() &&
337 (Op2Info.isPowerOf2() || Op2Info.isNegatedPowerOf2())) {
339 getArithmeticInstrCost(Instruction::Shl, Ty, CostKind,
340 Op1Info.getNoProps(), Op2Info.getNoProps());
341 if (Op2Info.isNegatedPowerOf2())
342 Cost += getArithmeticInstrCost(Instruction::Sub, Ty, CostKind);
343 return Cost;
344 }
345
346 // On X86, vector signed division by constants power-of-two are
347 // normally expanded to the sequence SRA + SRL + ADD + SRA.
348 // The OperandValue properties may not be the same as that of the previous
349 // operation; conservatively assume OP_None.
350 if ((ISD == ISD::SDIV || ISD == ISD::SREM) &&
351 Op2Info.isConstant() && Op2Info.isPowerOf2()) {
353 2 * getArithmeticInstrCost(Instruction::AShr, Ty, CostKind,
354 Op1Info.getNoProps(), Op2Info.getNoProps());
355 Cost += getArithmeticInstrCost(Instruction::LShr, Ty, CostKind,
356 Op1Info.getNoProps(), Op2Info.getNoProps());
357 Cost += getArithmeticInstrCost(Instruction::Add, Ty, CostKind,
358 Op1Info.getNoProps(), Op2Info.getNoProps());
359
360 if (ISD == ISD::SREM) {
361 // For SREM: (X % C) is the equivalent of (X - (X/C)*C)
362 Cost += getArithmeticInstrCost(Instruction::Mul, Ty, CostKind, Op1Info.getNoProps(),
363 Op2Info.getNoProps());
364 Cost += getArithmeticInstrCost(Instruction::Sub, Ty, CostKind, Op1Info.getNoProps(),
365 Op2Info.getNoProps());
366 }
367
368 return Cost;
369 }
370
371 // Vector unsigned division/remainder will be simplified to shifts/masks.
372 if ((ISD == ISD::UDIV || ISD == ISD::UREM) &&
373 Op2Info.isConstant() && Op2Info.isPowerOf2()) {
374 if (ISD == ISD::UDIV)
375 return getArithmeticInstrCost(Instruction::LShr, Ty, CostKind,
376 Op1Info.getNoProps(), Op2Info.getNoProps());
377 // UREM
378 return getArithmeticInstrCost(Instruction::And, Ty, CostKind,
379 Op1Info.getNoProps(), Op2Info.getNoProps());
380 }
381
382 // A scalar integer divide/remainder by a constant is not a hardware divide;
383 // it lowers to a magic-number multiply-high plus a few fixup ops. Cost it as
384 // that sequence rather than the generic single-instruction divide, so the
385 // vectorizers do not compare against an artificially cheap scalar lane. The
386 // power-of-two cases are handled above; negated powers of two are left to the
387 // generic handling.
388 if (!Ty->isVectorTy() && Op2Info.isConstant() && !Op2Info.isNegatedPowerOf2() &&
389 (ISD == ISD::UDIV || ISD == ISD::SDIV || ISD == ISD::UREM ||
390 ISD == ISD::SREM)) {
391 unsigned Cost = ISD == ISD::UREM || ISD == ISD::SREM ? 6 : 5;
393 Cost += 2;
394 return LT.first * Cost;
395 }
396
397 static const CostKindTblEntry GFNIUniformConstCostTable[] = {
398 { ISD::SHL, MVT::v16i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
399 { ISD::SRL, MVT::v16i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
400 { ISD::SRA, MVT::v16i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
401 { ISD::SHL, MVT::v32i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
402 { ISD::SRL, MVT::v32i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
403 { ISD::SRA, MVT::v32i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
404 { ISD::SHL, MVT::v64i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
405 { ISD::SRL, MVT::v64i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
406 { ISD::SRA, MVT::v64i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
407 };
408
409 if (Op2Info.isUniform() && Op2Info.isConstant() && ST->hasGFNI())
410 if (const auto *Entry =
411 CostTableLookup(GFNIUniformConstCostTable, ISD, LT.second))
412 if (auto KindCost = Entry->Cost[CostKind])
413 return LT.first * *KindCost;
414
415 static const CostKindTblEntry AVX512BWUniformConstCostTable[] = {
416 { ISD::SHL, MVT::v16i8, { 1, 7, 2, 3 } }, // psllw + pand.
417 { ISD::SRL, MVT::v16i8, { 1, 7, 2, 3 } }, // psrlw + pand.
418 { ISD::SRA, MVT::v16i8, { 1, 8, 4, 5 } }, // psrlw, pand, pxor, psubb.
419 { ISD::SHL, MVT::v32i8, { 1, 8, 2, 3 } }, // psllw + pand.
420 { ISD::SRL, MVT::v32i8, { 1, 8, 2, 3 } }, // psrlw + pand.
421 { ISD::SRA, MVT::v32i8, { 1, 9, 4, 5 } }, // psrlw, pand, pxor, psubb.
422 { ISD::SHL, MVT::v64i8, { 1, 8, 2, 3 } }, // psllw + pand.
423 { ISD::SRL, MVT::v64i8, { 1, 8, 2, 3 } }, // psrlw + pand.
424 { ISD::SRA, MVT::v64i8, { 1, 9, 4, 6 } }, // psrlw, pand, pxor, psubb.
425
426 { ISD::SHL, MVT::v16i16, { 1, 1, 1, 1 } }, // psllw
427 { ISD::SRL, MVT::v16i16, { 1, 1, 1, 1 } }, // psrlw
428 { ISD::SRA, MVT::v16i16, { 1, 1, 1, 1 } }, // psrlw
429 { ISD::SHL, MVT::v32i16, { 1, 1, 1, 1 } }, // psllw
430 { ISD::SRL, MVT::v32i16, { 1, 1, 1, 1 } }, // psrlw
431 { ISD::SRA, MVT::v32i16, { 1, 1, 1, 1 } }, // psrlw
432 };
433
434 if (Op2Info.isUniform() && Op2Info.isConstant() && ST->hasBWI())
435 if (const auto *Entry =
436 CostTableLookup(AVX512BWUniformConstCostTable, ISD, LT.second))
437 if (auto KindCost = Entry->Cost[CostKind])
438 return LT.first * *KindCost;
439
440 static const CostKindTblEntry AVX512DQUniformConstCostTable[] = {
441 { ISD::SDIV, MVT::v4i64, { 15 } }, // vpmullq-based MULHS sequence
442 { ISD::SREM, MVT::v4i64, { 17 } }, // vpmullq-based MULHS+mul+sub sequence
443 { ISD::SDIV, MVT::v8i64, { 15 } }, // vpmullq-based MULHS sequence
444 { ISD::SREM, MVT::v8i64, { 17 } }, // vpmullq-based MULHS+mul+sub sequence
445 // The remainder's multiply-back is a single vpmullq with DQ, just like the
446 // pmulld the vXi32 entries above rely on. Without DQ it is another
447 // vpmuludq schoolbook, so the AVX512/AVX2 tables charge more.
448 { ISD::UREM, MVT::v4i64, { 17 } }, // MULHU + vpmullq + sub sequence
449 { ISD::UREM, MVT::v8i64, { 17 } }, // MULHU + vpmullq + sub sequence
450 };
451
452 if (Op2Info.isUniform() && Op2Info.isConstant() && ST->hasDQI())
453 if (const auto *Entry =
454 CostTableLookup(AVX512DQUniformConstCostTable, ISD, LT.second))
455 if (auto KindCost = Entry->Cost[CostKind])
456 return LT.first * *KindCost;
457
458 static const CostKindTblEntry AVX512UniformConstCostTable[] = {
459 { ISD::SHL, MVT::v64i8, { 2, 12, 5, 6 } }, // psllw + pand.
460 { ISD::SRL, MVT::v64i8, { 2, 12, 5, 6 } }, // psrlw + pand.
461 { ISD::SRA, MVT::v64i8, { 3, 10, 12, 12 } }, // psrlw, pand, pxor, psubb.
462
463 { ISD::SHL, MVT::v16i16, { 2, 7, 4, 4 } }, // psllw + split.
464 { ISD::SRL, MVT::v16i16, { 2, 7, 4, 4 } }, // psrlw + split.
465 { ISD::SRA, MVT::v16i16, { 2, 7, 4, 4 } }, // psraw + split.
466
467 { ISD::SHL, MVT::v8i32, { 1, 1, 1, 1 } }, // pslld
468 { ISD::SRL, MVT::v8i32, { 1, 1, 1, 1 } }, // psrld
469 { ISD::SRA, MVT::v8i32, { 1, 1, 1, 1 } }, // psrad
470 { ISD::SHL, MVT::v16i32, { 1, 1, 1, 1 } }, // pslld
471 { ISD::SRL, MVT::v16i32, { 1, 1, 1, 1 } }, // psrld
472 { ISD::SRA, MVT::v16i32, { 1, 1, 1, 1 } }, // psrad
473
474 { ISD::SRA, MVT::v2i64, { 1, 1, 1, 1 } }, // psraq
475 { ISD::SHL, MVT::v4i64, { 1, 1, 1, 1 } }, // psllq
476 { ISD::SRL, MVT::v4i64, { 1, 1, 1, 1 } }, // psrlq
477 { ISD::SRA, MVT::v4i64, { 1, 1, 1, 1 } }, // psraq
478 { ISD::SHL, MVT::v8i64, { 1, 1, 1, 1 } }, // psllq
479 { ISD::SRL, MVT::v8i64, { 1, 1, 1, 1 } }, // psrlq
480 { ISD::SRA, MVT::v8i64, { 1, 1, 1, 1 } }, // psraq
481
482 { ISD::SDIV, MVT::v16i32, { 6 } }, // pmuludq sequence
483 { ISD::SREM, MVT::v16i32, { 8 } }, // pmuludq+mul+sub sequence
484 { ISD::UDIV, MVT::v16i32, { 5 } }, // pmuludq sequence
485 { ISD::UREM, MVT::v16i32, { 7 } }, // pmuludq+mul+sub sequence
486
487 { ISD::UDIV, MVT::v8i64, { 15 } }, // pmuludq-based MULHU sequence
488 { ISD::UREM, MVT::v8i64, { 21 } }, // pmuludq-based MULHU+mul+sub sequence
489 };
490
491 if (Op2Info.isUniform() && Op2Info.isConstant() && ST->hasAVX512())
492 if (const auto *Entry =
493 CostTableLookup(AVX512UniformConstCostTable, ISD, LT.second))
494 if (auto KindCost = Entry->Cost[CostKind])
495 return LT.first * *KindCost;
496
497 static const CostKindTblEntry AVX2UniformConstCostTable[] = {
498 { ISD::SHL, MVT::v16i8, { 1, 8, 2, 3 } }, // psllw + pand.
499 { ISD::SRL, MVT::v16i8, { 1, 8, 2, 3 } }, // psrlw + pand.
500 { ISD::SRA, MVT::v16i8, { 2, 10, 5, 6 } }, // psrlw, pand, pxor, psubb.
501 { ISD::SHL, MVT::v32i8, { 2, 8, 2, 4 } }, // psllw + pand.
502 { ISD::SRL, MVT::v32i8, { 2, 8, 2, 4 } }, // psrlw + pand.
503 { ISD::SRA, MVT::v32i8, { 3, 10, 5, 9 } }, // psrlw, pand, pxor, psubb.
504
505 { ISD::SHL, MVT::v8i16, { 1, 1, 1, 1 } }, // psllw
506 { ISD::SRL, MVT::v8i16, { 1, 1, 1, 1 } }, // psrlw
507 { ISD::SRA, MVT::v8i16, { 1, 1, 1, 1 } }, // psraw
508 { ISD::SHL, MVT::v16i16,{ 2, 2, 1, 2 } }, // psllw
509 { ISD::SRL, MVT::v16i16,{ 2, 2, 1, 2 } }, // psrlw
510 { ISD::SRA, MVT::v16i16,{ 2, 2, 1, 2 } }, // psraw
511
512 { ISD::SHL, MVT::v4i32, { 1, 1, 1, 1 } }, // pslld
513 { ISD::SRL, MVT::v4i32, { 1, 1, 1, 1 } }, // psrld
514 { ISD::SRA, MVT::v4i32, { 1, 1, 1, 1 } }, // psrad
515 { ISD::SHL, MVT::v8i32, { 2, 2, 1, 2 } }, // pslld
516 { ISD::SRL, MVT::v8i32, { 2, 2, 1, 2 } }, // psrld
517 { ISD::SRA, MVT::v8i32, { 2, 2, 1, 2 } }, // psrad
518
519 { ISD::SHL, MVT::v2i64, { 1, 1, 1, 1 } }, // psllq
520 { ISD::SRL, MVT::v2i64, { 1, 1, 1, 1 } }, // psrlq
521 { ISD::SRA, MVT::v2i64, { 2, 3, 3, 3 } }, // psrad + shuffle.
522 { ISD::SHL, MVT::v4i64, { 2, 2, 1, 2 } }, // psllq
523 { ISD::SRL, MVT::v4i64, { 2, 2, 1, 2 } }, // psrlq
524 { ISD::SRA, MVT::v4i64, { 4, 4, 3, 6 } }, // psrad + shuffle + split.
525
526 { ISD::SDIV, MVT::v8i32, { 6 } }, // pmuludq sequence
527 { ISD::SREM, MVT::v8i32, { 8 } }, // pmuludq+mul+sub sequence
528 { ISD::UDIV, MVT::v8i32, { 5 } }, // pmuludq sequence
529 { ISD::UREM, MVT::v8i32, { 7 } }, // pmuludq+mul+sub sequence
530
531 { ISD::UDIV, MVT::v4i64, { 15 } }, // pmuludq-based MULHU sequence
532 { ISD::UREM, MVT::v4i64, { 21 } }, // pmuludq-based MULHU+mul+sub sequence
533 };
534
535 if (Op2Info.isUniform() && Op2Info.isConstant() && ST->hasAVX2())
536 if (const auto *Entry =
537 CostTableLookup(AVX2UniformConstCostTable, ISD, LT.second))
538 if (auto KindCost = Entry->Cost[CostKind])
539 return LT.first * *KindCost;
540
541 static const CostKindTblEntry AVXUniformConstCostTable[] = {
542 { ISD::SHL, MVT::v16i8, { 2, 7, 2, 3 } }, // psllw + pand.
543 { ISD::SRL, MVT::v16i8, { 2, 7, 2, 3 } }, // psrlw + pand.
544 { ISD::SRA, MVT::v16i8, { 3, 9, 5, 6 } }, // psrlw, pand, pxor, psubb.
545 { ISD::SHL, MVT::v32i8, { 4, 7, 7, 8 } }, // 2*(psllw + pand) + split.
546 { ISD::SRL, MVT::v32i8, { 4, 7, 7, 8 } }, // 2*(psrlw + pand) + split.
547 { ISD::SRA, MVT::v32i8, { 7, 7, 12, 13 } }, // 2*(psrlw, pand, pxor, psubb) + split.
548
549 { ISD::SHL, MVT::v8i16, { 1, 2, 1, 1 } }, // psllw.
550 { ISD::SRL, MVT::v8i16, { 1, 2, 1, 1 } }, // psrlw.
551 { ISD::SRA, MVT::v8i16, { 1, 2, 1, 1 } }, // psraw.
552 { ISD::SHL, MVT::v16i16,{ 3, 6, 4, 5 } }, // psllw + split.
553 { ISD::SRL, MVT::v16i16,{ 3, 6, 4, 5 } }, // psrlw + split.
554 { ISD::SRA, MVT::v16i16,{ 3, 6, 4, 5 } }, // psraw + split.
555
556 { ISD::SHL, MVT::v4i32, { 1, 2, 1, 1 } }, // pslld.
557 { ISD::SRL, MVT::v4i32, { 1, 2, 1, 1 } }, // psrld.
558 { ISD::SRA, MVT::v4i32, { 1, 2, 1, 1 } }, // psrad.
559 { ISD::SHL, MVT::v8i32, { 3, 6, 4, 5 } }, // pslld + split.
560 { ISD::SRL, MVT::v8i32, { 3, 6, 4, 5 } }, // psrld + split.
561 { ISD::SRA, MVT::v8i32, { 3, 6, 4, 5 } }, // psrad + split.
562
563 { ISD::SHL, MVT::v2i64, { 1, 2, 1, 1 } }, // psllq.
564 { ISD::SRL, MVT::v2i64, { 1, 2, 1, 1 } }, // psrlq.
565 { ISD::SRA, MVT::v2i64, { 2, 3, 3, 3 } }, // psrad + shuffle.
566 { ISD::SHL, MVT::v4i64, { 3, 6, 4, 5 } }, // 2 x psllq + split.
567 { ISD::SRL, MVT::v4i64, { 3, 6, 4, 5 } }, // 2 x psllq + split.
568 { ISD::SRA, MVT::v4i64, { 5, 7, 8, 9 } }, // 2 x psrad + shuffle + split.
569
570 { ISD::SDIV, MVT::v8i32, { 14 } }, // 2*pmuludq sequence + split.
571 { ISD::SREM, MVT::v8i32, { 18 } }, // 2*pmuludq+mul+sub sequence + split.
572 { ISD::UDIV, MVT::v8i32, { 12 } }, // 2*pmuludq sequence + split.
573 { ISD::UREM, MVT::v8i32, { 16 } }, // 2*pmuludq+mul+sub sequence + split.
574 };
575
576 // XOP has faster vXi8 shifts.
577 if (Op2Info.isUniform() && Op2Info.isConstant() && ST->hasAVX() &&
578 (!ST->hasXOP() || LT.second.getScalarSizeInBits() != 8))
579 if (const auto *Entry =
580 CostTableLookup(AVXUniformConstCostTable, ISD, LT.second))
581 if (auto KindCost = Entry->Cost[CostKind])
582 return LT.first * *KindCost;
583
584 static const CostKindTblEntry SSE2UniformConstCostTable[] = {
585 { ISD::SHL, MVT::v16i8, { 1, 7, 2, 3 } }, // psllw + pand.
586 { ISD::SRL, MVT::v16i8, { 1, 7, 2, 3 } }, // psrlw + pand.
587 { ISD::SRA, MVT::v16i8, { 3, 9, 5, 6 } }, // psrlw, pand, pxor, psubb.
588
589 { ISD::SHL, MVT::v8i16, { 1, 1, 1, 1 } }, // psllw.
590 { ISD::SRL, MVT::v8i16, { 1, 1, 1, 1 } }, // psrlw.
591 { ISD::SRA, MVT::v8i16, { 1, 1, 1, 1 } }, // psraw.
592
593 { ISD::SHL, MVT::v4i32, { 1, 1, 1, 1 } }, // pslld
594 { ISD::SRL, MVT::v4i32, { 1, 1, 1, 1 } }, // psrld.
595 { ISD::SRA, MVT::v4i32, { 1, 1, 1, 1 } }, // psrad.
596
597 { ISD::SHL, MVT::v2i64, { 1, 1, 1, 1 } }, // psllq.
598 { ISD::SRL, MVT::v2i64, { 1, 1, 1, 1 } }, // psrlq.
599 { ISD::SRA, MVT::v2i64, { 3, 5, 6, 6 } }, // 2 x psrad + shuffle.
600
601 { ISD::SDIV, MVT::v4i32, { 6 } }, // pmuludq sequence
602 { ISD::SREM, MVT::v4i32, { 8 } }, // pmuludq+mul+sub sequence
603 { ISD::UDIV, MVT::v4i32, { 5 } }, // pmuludq sequence
604 { ISD::UREM, MVT::v4i32, { 7 } }, // pmuludq+mul+sub sequence
605 };
606
607 // XOP has faster vXi8 shifts.
608 if (Op2Info.isUniform() && Op2Info.isConstant() && ST->hasSSE2() &&
609 (!ST->hasXOP() || LT.second.getScalarSizeInBits() != 8))
610 if (const auto *Entry =
611 CostTableLookup(SSE2UniformConstCostTable, ISD, LT.second))
612 if (auto KindCost = Entry->Cost[CostKind])
613 return LT.first * *KindCost;
614
615 static const CostKindTblEntry AVX512BWConstCostTable[] = {
616 { ISD::SDIV, MVT::v64i8, { 14 } }, // 2*ext+2*pmulhw sequence
617 { ISD::SREM, MVT::v64i8, { 16 } }, // 2*ext+2*pmulhw+mul+sub sequence
618 { ISD::UDIV, MVT::v64i8, { 14 } }, // 2*ext+2*pmulhw sequence
619 { ISD::UREM, MVT::v64i8, { 16 } }, // 2*ext+2*pmulhw+mul+sub sequence
620
621 { ISD::SDIV, MVT::v32i16, { 6 } }, // vpmulhw sequence
622 { ISD::SREM, MVT::v32i16, { 8 } }, // vpmulhw+mul+sub sequence
623 { ISD::UDIV, MVT::v32i16, { 6 } }, // vpmulhuw sequence
624 { ISD::UREM, MVT::v32i16, { 8 } }, // vpmulhuw+mul+sub sequence
625 };
626
627 if (Op2Info.isConstant() && ST->hasBWI())
628 if (const auto *Entry =
629 CostTableLookup(AVX512BWConstCostTable, ISD, LT.second))
630 if (auto KindCost = Entry->Cost[CostKind])
631 return LT.first * *KindCost;
632
633 static const CostKindTblEntry AVX512DQConstCostTable[] = {
634 { ISD::SDIV, MVT::v4i64, { 19 } }, // vpmullq-based MULHS sequence
635 { ISD::SREM, MVT::v4i64, { 21 } }, // vpmullq-based MULHS+mul+sub sequence
636 { ISD::SDIV, MVT::v8i64, { 19 } }, // vpmullq-based MULHS sequence
637 { ISD::SREM, MVT::v8i64, { 21 } }, // vpmullq-based MULHS+mul+sub sequence
638 // The remainder's multiply-back is a single vpmullq with DQ, whereas the
639 // AVX512/AVX2 tables have to charge for another vpmuludq schoolbook.
640 { ISD::UREM, MVT::v4i64, { 24 } }, // MULHU + vpmullq + sub sequence
641 { ISD::UREM, MVT::v8i64, { 24 } }, // MULHU + vpmullq + sub sequence
642 };
643
644 if (Op2Info.isConstant() && ST->hasDQI())
645 if (const auto *Entry =
646 CostTableLookup(AVX512DQConstCostTable, ISD, LT.second))
647 if (auto KindCost = Entry->Cost[CostKind])
648 return LT.first * *KindCost;
649
650 static const CostKindTblEntry AVX512ConstCostTable[] = {
651 { ISD::SDIV, MVT::v64i8, { 28 } }, // 4*ext+4*pmulhw sequence
652 { ISD::SREM, MVT::v64i8, { 32 } }, // 4*ext+4*pmulhw+mul+sub sequence
653 { ISD::UDIV, MVT::v64i8, { 28 } }, // 4*ext+4*pmulhw sequence
654 { ISD::UREM, MVT::v64i8, { 32 } }, // 4*ext+4*pmulhw+mul+sub sequence
655
656 { ISD::SDIV, MVT::v32i16, { 12 } }, // 2*vpmulhw sequence
657 { ISD::SREM, MVT::v32i16, { 16 } }, // 2*vpmulhw+mul+sub sequence
658 { ISD::UDIV, MVT::v32i16, { 12 } }, // 2*vpmulhuw sequence
659 { ISD::UREM, MVT::v32i16, { 16 } }, // 2*vpmulhuw+mul+sub sequence
660
661 { ISD::SDIV, MVT::v16i32, { 15 } }, // vpmuldq sequence
662 { ISD::SREM, MVT::v16i32, { 17 } }, // vpmuldq+mul+sub sequence
663 { ISD::UDIV, MVT::v16i32, { 15 } }, // vpmuludq sequence
664 { ISD::UREM, MVT::v16i32, { 17 } }, // vpmuludq+mul+sub sequence
665
666 { ISD::UDIV, MVT::v8i64, { 22 } }, // vpmuludq-based MULHU sequence
667 { ISD::UREM, MVT::v8i64, { 28 } }, // vpmuludq-based MULHU+mul+sub sequence
668 };
669
670 if (Op2Info.isConstant() && ST->hasAVX512())
671 if (const auto *Entry =
672 CostTableLookup(AVX512ConstCostTable, ISD, LT.second))
673 if (auto KindCost = Entry->Cost[CostKind])
674 return LT.first * *KindCost;
675
676 static const CostKindTblEntry AVX2ConstCostTable[] = {
677 { ISD::SDIV, MVT::v32i8, { 14 } }, // 2*ext+2*pmulhw sequence
678 { ISD::SREM, MVT::v32i8, { 16 } }, // 2*ext+2*pmulhw+mul+sub sequence
679 { ISD::UDIV, MVT::v32i8, { 14 } }, // 2*ext+2*pmulhw sequence
680 { ISD::UREM, MVT::v32i8, { 16 } }, // 2*ext+2*pmulhw+mul+sub sequence
681
682 { ISD::SDIV, MVT::v16i16, { 6 } }, // vpmulhw sequence
683 { ISD::SREM, MVT::v16i16, { 8 } }, // vpmulhw+mul+sub sequence
684 { ISD::UDIV, MVT::v16i16, { 6 } }, // vpmulhuw sequence
685 { ISD::UREM, MVT::v16i16, { 8 } }, // vpmulhuw+mul+sub sequence
686
687 { ISD::SDIV, MVT::v8i32, { 15 } }, // vpmuldq sequence
688 { ISD::SREM, MVT::v8i32, { 19 } }, // vpmuldq+mul+sub sequence
689 { ISD::UDIV, MVT::v8i32, { 15 } }, // vpmuludq sequence
690 { ISD::UREM, MVT::v8i32, { 19 } }, // vpmuludq+mul+sub sequence
691
692 { ISD::UDIV, MVT::v4i64, { 22 } }, // vpmuludq-based MULHU sequence
693 { ISD::UREM, MVT::v4i64, { 28 } }, // vpmuludq-based MULHU+mul+sub sequence
694 };
695
696 if (Op2Info.isConstant() && ST->hasAVX2())
697 if (const auto *Entry = CostTableLookup(AVX2ConstCostTable, ISD, LT.second))
698 if (auto KindCost = Entry->Cost[CostKind])
699 return LT.first * *KindCost;
700
701 static const CostKindTblEntry AVXConstCostTable[] = {
702 { ISD::SDIV, MVT::v32i8, { 30 } }, // 4*ext+4*pmulhw sequence + split.
703 { ISD::SREM, MVT::v32i8, { 34 } }, // 4*ext+4*pmulhw+mul+sub sequence + split.
704 { ISD::UDIV, MVT::v32i8, { 30 } }, // 4*ext+4*pmulhw sequence + split.
705 { ISD::UREM, MVT::v32i8, { 34 } }, // 4*ext+4*pmulhw+mul+sub sequence + split.
706
707 { ISD::SDIV, MVT::v16i16, { 14 } }, // 2*pmulhw sequence + split.
708 { ISD::SREM, MVT::v16i16, { 18 } }, // 2*pmulhw+mul+sub sequence + split.
709 { ISD::UDIV, MVT::v16i16, { 14 } }, // 2*pmulhuw sequence + split.
710 { ISD::UREM, MVT::v16i16, { 18 } }, // 2*pmulhuw+mul+sub sequence + split.
711
712 { ISD::SDIV, MVT::v8i32, { 32 } }, // vpmuludq sequence
713 { ISD::SREM, MVT::v8i32, { 38 } }, // vpmuludq+mul+sub sequence
714 { ISD::UDIV, MVT::v8i32, { 32 } }, // 2*pmuludq sequence + split.
715 { ISD::UREM, MVT::v8i32, { 42 } }, // 2*pmuludq+mul+sub sequence + split.
716 };
717
718 if (Op2Info.isConstant() && ST->hasAVX())
719 if (const auto *Entry = CostTableLookup(AVXConstCostTable, ISD, LT.second))
720 if (auto KindCost = Entry->Cost[CostKind])
721 return LT.first * *KindCost;
722
723 static const CostKindTblEntry SSE41ConstCostTable[] = {
724 { ISD::SDIV, MVT::v4i32, { 15 } }, // vpmuludq sequence
725 { ISD::SREM, MVT::v4i32, { 20 } }, // vpmuludq+mul+sub sequence
726 };
727
728 if (Op2Info.isConstant() && ST->hasSSE41())
729 if (const auto *Entry =
730 CostTableLookup(SSE41ConstCostTable, ISD, LT.second))
731 if (auto KindCost = Entry->Cost[CostKind])
732 return LT.first * *KindCost;
733
734 static const CostKindTblEntry SSE2ConstCostTable[] = {
735 { ISD::SDIV, MVT::v16i8, { 14 } }, // 2*ext+2*pmulhw sequence
736 { ISD::SREM, MVT::v16i8, { 16 } }, // 2*ext+2*pmulhw+mul+sub sequence
737 { ISD::UDIV, MVT::v16i8, { 14 } }, // 2*ext+2*pmulhw sequence
738 { ISD::UREM, MVT::v16i8, { 16 } }, // 2*ext+2*pmulhw+mul+sub sequence
739
740 { ISD::SDIV, MVT::v8i16, { 6 } }, // pmulhw sequence
741 { ISD::SREM, MVT::v8i16, { 8 } }, // pmulhw+mul+sub sequence
742 { ISD::UDIV, MVT::v8i16, { 6 } }, // pmulhuw sequence
743 { ISD::UREM, MVT::v8i16, { 8 } }, // pmulhuw+mul+sub sequence
744
745 { ISD::SDIV, MVT::v4i32, { 19 } }, // pmuludq sequence
746 { ISD::SREM, MVT::v4i32, { 24 } }, // pmuludq+mul+sub sequence
747 { ISD::UDIV, MVT::v4i32, { 15 } }, // pmuludq sequence
748 { ISD::UREM, MVT::v4i32, { 20 } }, // pmuludq+mul+sub sequence
749 };
750
751 if (Op2Info.isConstant() && ST->hasSSE2())
752 if (const auto *Entry = CostTableLookup(SSE2ConstCostTable, ISD, LT.second))
753 if (auto KindCost = Entry->Cost[CostKind])
754 return LT.first * *KindCost;
755
756 // rem matches div because the divider returns the remainder for free.
757 static const CostKindTblEntry ScalarVarDivCostTable[] = {
758 { ISD::SDIV, MVT::i8, { 15, 20, 2, 4 } },
759 { ISD::UDIV, MVT::i8, { 15, 20, 2, 4 } },
760 { ISD::SREM, MVT::i8, { 15, 20, 2, 4 } },
761 { ISD::UREM, MVT::i8, { 15, 20, 2, 4 } },
762 { ISD::SDIV, MVT::i16, { 17, 20, 2, 4 } },
763 { ISD::UDIV, MVT::i16, { 17, 20, 2, 4 } },
764 { ISD::SREM, MVT::i16, { 17, 20, 2, 4 } },
765 { ISD::UREM, MVT::i16, { 17, 20, 2, 4 } },
766 { ISD::SDIV, MVT::i32, { 25, 22, 2, 4 } },
767 { ISD::UDIV, MVT::i32, { 25, 22, 2, 4 } },
768 { ISD::SREM, MVT::i32, { 25, 22, 2, 4 } },
769 { ISD::UREM, MVT::i32, { 25, 22, 2, 4 } },
770 { ISD::SDIV, MVT::i64, { 41, 24, 2, 4 } },
771 { ISD::UDIV, MVT::i64, { 41, 24, 2, 4 } },
772 { ISD::SREM, MVT::i64, { 41, 24, 2, 4 } },
773 { ISD::UREM, MVT::i64, { 41, 24, 2, 4 } },
774 };
775
776 if (!LT.second.isVector() && !Op2Info.isConstant())
777 if (const auto *Entry =
778 CostTableLookup(ScalarVarDivCostTable, ISD, LT.second))
779 if (auto KindCost = Entry->Cost[CostKind])
780 return LT.first * *KindCost;
781
782 // Variable divisors lower through a float divide. strictfp needs SAE
783 // rounding which is 512-bit only.
784 bool IsStrictFP =
785 CxtI && CxtI->getFunction()->hasFnAttribute(Attribute::StrictFP);
786 bool IsDivRem = ISD == ISD::UDIV || ISD == ISD::SDIV || ISD == ISD::UREM ||
787 ISD == ISD::SREM;
788 bool VarDivToFP = IsDivRem && !Op2Info.isConstant() &&
789 (!IsStrictFP || ST->useAVX512Regs());
790
791 // i64 needs the qq converts, which are AVX512DQ only. Two tables because the
792 // lowering picks by operand value and not by type.
793 static const CostKindTblEntry AVX512DQExactVarDivCostTable[] = {
794 { ISD::UDIV, MVT::v2i64, { 5 } }, // cvt+divpd sequence
795 { ISD::SDIV, MVT::v2i64, { 5 } },
796 { ISD::UREM, MVT::v2i64, { 5 } },
797 { ISD::SREM, MVT::v2i64, { 5 } },
798 { ISD::UDIV, MVT::v4i64, { 8 } },
799 { ISD::SDIV, MVT::v4i64, { 8 } },
800 { ISD::UREM, MVT::v4i64, { 8 } },
801 { ISD::SREM, MVT::v4i64, { 8 } },
802 { ISD::UDIV, MVT::v8i64, { 16 } },
803 { ISD::SDIV, MVT::v8i64, { 16 } },
804 { ISD::UREM, MVT::v8i64, { 16 } },
805 { ISD::SREM, MVT::v8i64, { 16 } },
806 };
807
808 static const CostKindTblEntry AVX512DQVarDivCostTable[] = {
809 { ISD::UDIV, MVT::v2i64, { 16 } },
810 { ISD::SDIV, MVT::v2i64, { 16 } },
811 { ISD::UREM, MVT::v2i64, { 16 } },
812 { ISD::SREM, MVT::v2i64, { 16 } },
813 { ISD::UDIV, MVT::v4i64, { 16 } },
814 { ISD::SDIV, MVT::v4i64, { 16 } },
815 { ISD::UREM, MVT::v4i64, { 16 } },
816 { ISD::SREM, MVT::v4i64, { 16 } },
817 { ISD::UDIV, MVT::v8i64, { 16 } },
818 { ISD::SDIV, MVT::v8i64, { 18 } },
819 { ISD::UREM, MVT::v8i64, { 16 } },
820 { ISD::SREM, MVT::v8i64, { 18 } },
821 };
822
823 // The DAG combine picks between the two sequences with these same two
824 // queries, so the cost cannot disagree with what codegen emits.
825 bool IsSignedDiv = ISD == ISD::SDIV || ISD == ISD::SREM;
826 auto OperandsFit = [&](unsigned Mantissa) {
827 if (Args.size() != 2 || !CxtI)
828 return false;
829 unsigned EltBits = LT.second.getScalarSizeInBits();
830 const DataLayout &DL = CxtI->getDataLayout();
831 auto Fits = [&](const Value *V) {
832 if (IsSignedDiv)
833 return ComputeNumSignBits(V, DL, /*AC=*/nullptr, CxtI) + Mantissa >
834 EltBits;
835 return computeKnownBits(V, DL, /*AC=*/nullptr, CxtI)
836 .countMaxActiveBits() <= Mantissa;
837 };
838 return Fits(Args[0]) && Fits(Args[1]);
839 };
840
841 // An i32 divide goes through f32 when both operands fit in 24 bits, and
842 // through f64 at twice the vector width when they do not.
843 bool ExactI32 =
844 VarDivToFP && LT.second.getScalarType() == MVT::i32 &&
846
847 if (VarDivToFP && ST->hasDQI() && ST->useAVX512Regs() &&
848 LT.second.getScalarType() == MVT::i64) {
849 bool ExactFPDiv =
851
852 // Only the reciprocal chain multiplies, so only it is vpmullq gated.
853 bool SlowMultiply =
854 !ExactFPDiv && LT.second == MVT::v2i64 && ST->isPMULLQSlow();
855
856 if (!SlowMultiply) {
858 ExactFPDiv ? AVX512DQExactVarDivCostTable : AVX512DQVarDivCostTable;
859 if (const auto *Entry = CostTableLookup(Tbl, ISD, LT.second))
860 if (auto KindCost = Entry->Cost[CostKind])
861 return LT.first * *KindCost;
862 }
863 }
864
865 static const CostKindTblEntry AVX512BWVarDivCostTable[] = {
866 { ISD::UDIV, MVT::v16i8, { 10 } }, // unpack+cvt+divps sequence
867 { ISD::SDIV, MVT::v16i8, { 10 } },
868 { ISD::UREM, MVT::v16i8, { 10 } },
869 { ISD::SREM, MVT::v16i8, { 10 } },
870 { ISD::UDIV, MVT::v32i8, { 20 } },
871 { ISD::SDIV, MVT::v32i8, { 20 } },
872 { ISD::UREM, MVT::v32i8, { 20 } },
873 { ISD::SREM, MVT::v32i8, { 20 } },
874 { ISD::UDIV, MVT::v64i8, { 40 } },
875 { ISD::SDIV, MVT::v64i8, { 40 } },
876 { ISD::UREM, MVT::v64i8, { 40 } },
877 { ISD::SREM, MVT::v64i8, { 40 } },
878 { ISD::UDIV, MVT::v8i16, { 5 } },
879 { ISD::SDIV, MVT::v8i16, { 5 } },
880 { ISD::UREM, MVT::v8i16, { 5 } },
881 { ISD::SREM, MVT::v8i16, { 5 } },
882 { ISD::UDIV, MVT::v16i16, { 10 } },
883 { ISD::SDIV, MVT::v16i16, { 10 } },
884 { ISD::UREM, MVT::v16i16, { 10 } },
885 { ISD::SREM, MVT::v16i16, { 10 } },
886 { ISD::UDIV, MVT::v32i16, { 20 } },
887 { ISD::SDIV, MVT::v32i16, { 20 } },
888 { ISD::UREM, MVT::v32i16, { 20 } },
889 { ISD::SREM, MVT::v32i16, { 20 } },
890 { ISD::UDIV, MVT::v4i32, { 8 } }, // cvt+divpd sequence
891 { ISD::SDIV, MVT::v4i32, { 8 } },
892 { ISD::UREM, MVT::v4i32, { 8 } },
893 { ISD::SREM, MVT::v4i32, { 8 } },
894 { ISD::UDIV, MVT::v8i32, { 16 } },
895 { ISD::SDIV, MVT::v8i32, { 16 } },
896 { ISD::UREM, MVT::v8i32, { 16 } },
897 { ISD::SREM, MVT::v8i32, { 16 } },
898 { ISD::UDIV, MVT::v16i32, { 32 } },
899 { ISD::SDIV, MVT::v16i32, { 32 } },
900 { ISD::UREM, MVT::v16i32, { 32 } },
901 { ISD::SREM, MVT::v16i32, { 32 } },
902 };
903
904 static const CostKindTblEntry AVX512BWExactVarDivCostTable[] = {
905 { ISD::UDIV, MVT::v4i32, { 3 } }, // cvt+divps sequence
906 { ISD::SDIV, MVT::v4i32, { 3 } },
907 { ISD::UREM, MVT::v4i32, { 3 } },
908 { ISD::SREM, MVT::v4i32, { 3 } },
909 { ISD::UDIV, MVT::v8i32, { 5 } },
910 { ISD::SDIV, MVT::v8i32, { 5 } },
911 { ISD::UREM, MVT::v8i32, { 5 } },
912 { ISD::SREM, MVT::v8i32, { 5 } },
913 { ISD::UDIV, MVT::v16i32, { 10 } },
914 { ISD::SDIV, MVT::v16i32, { 10 } },
915 { ISD::UREM, MVT::v16i32, { 10 } },
916 { ISD::SREM, MVT::v16i32, { 10 } },
917 };
918
919 if (VarDivToFP && ST->hasBWI()) {
920 ArrayRef<CostKindTblEntry> Tbl = AVX512BWVarDivCostTable;
921 if (ExactI32)
922 Tbl = AVX512BWExactVarDivCostTable;
923 if (const auto *Entry = CostTableLookup(Tbl, ISD, LT.second))
924 if (auto KindCost = Entry->Cost[CostKind])
925 return LT.first * *KindCost;
926 }
927
928 static const CostKindTblEntry AVX512VarDivCostTable[] = {
929 { ISD::UDIV, MVT::v16i8, { 14 } }, // unpack+cvt+divps sequence
930 { ISD::SDIV, MVT::v16i8, { 14 } },
931 { ISD::UREM, MVT::v16i8, { 14 } },
932 { ISD::SREM, MVT::v16i8, { 14 } },
933 { ISD::UDIV, MVT::v32i8, { 28 } },
934 { ISD::SDIV, MVT::v32i8, { 28 } },
935 { ISD::UREM, MVT::v32i8, { 28 } },
936 { ISD::SREM, MVT::v32i8, { 28 } },
937 { ISD::UDIV, MVT::v64i8, { 56 } },
938 { ISD::SDIV, MVT::v64i8, { 56 } },
939 { ISD::UREM, MVT::v64i8, { 56 } },
940 { ISD::SREM, MVT::v64i8, { 56 } },
941 { ISD::UDIV, MVT::v8i16, { 14 } },
942 { ISD::SDIV, MVT::v8i16, { 14 } },
943 { ISD::UREM, MVT::v8i16, { 14 } },
944 { ISD::SREM, MVT::v8i16, { 14 } },
945 { ISD::UDIV, MVT::v16i16, { 14 } },
946 { ISD::SDIV, MVT::v16i16, { 14 } },
947 { ISD::UREM, MVT::v16i16, { 14 } },
948 { ISD::SREM, MVT::v16i16, { 14 } },
949 { ISD::UDIV, MVT::v32i16, { 28 } },
950 { ISD::SDIV, MVT::v32i16, { 28 } },
951 { ISD::UREM, MVT::v32i16, { 28 } },
952 { ISD::SREM, MVT::v32i16, { 28 } },
953 { ISD::UDIV, MVT::v4i32, { 28 } }, // cvt+divpd sequence
954 { ISD::SDIV, MVT::v4i32, { 28 } },
955 { ISD::UREM, MVT::v4i32, { 28 } },
956 { ISD::SREM, MVT::v4i32, { 28 } },
957 { ISD::UDIV, MVT::v8i32, { 28 } },
958 { ISD::SDIV, MVT::v8i32, { 28 } },
959 { ISD::UREM, MVT::v8i32, { 28 } },
960 { ISD::SREM, MVT::v8i32, { 28 } },
961 { ISD::UDIV, MVT::v16i32, { 56 } },
962 { ISD::SDIV, MVT::v16i32, { 56 } },
963 { ISD::UREM, MVT::v16i32, { 56 } },
964 { ISD::SREM, MVT::v16i32, { 56 } },
965 };
966
967 static const CostKindTblEntry AVX512ExactVarDivCostTable[] = {
968 { ISD::UDIV, MVT::v4i32, { 7 } }, // cvt+divps sequence
969 { ISD::SDIV, MVT::v4i32, { 7 } },
970 { ISD::UREM, MVT::v4i32, { 7 } },
971 { ISD::SREM, MVT::v4i32, { 7 } },
972 { ISD::UDIV, MVT::v8i32, { 14 } },
973 { ISD::SDIV, MVT::v8i32, { 14 } },
974 { ISD::UREM, MVT::v8i32, { 14 } },
975 { ISD::SREM, MVT::v8i32, { 14 } },
976 { ISD::UDIV, MVT::v16i32, { 14 } },
977 { ISD::SDIV, MVT::v16i32, { 14 } },
978 { ISD::UREM, MVT::v16i32, { 14 } },
979 { ISD::SREM, MVT::v16i32, { 14 } },
980 };
981
982 if (VarDivToFP && ST->hasAVX512()) {
983 ArrayRef<CostKindTblEntry> Tbl = AVX512VarDivCostTable;
984 if (ExactI32)
985 Tbl = AVX512ExactVarDivCostTable;
986 if (const auto *Entry = CostTableLookup(Tbl, ISD, LT.second))
987 if (auto KindCost = Entry->Cost[CostKind])
988 return LT.first * *KindCost;
989 }
990
991 static const CostKindTblEntry AVX2VarDivCostTable[] = {
992 { ISD::UDIV, MVT::v16i8, { 28 } }, // unpack+cvt+divps sequence
993 { ISD::SDIV, MVT::v16i8, { 28 } },
994 { ISD::UREM, MVT::v16i8, { 28 } },
995 { ISD::SREM, MVT::v16i8, { 28 } },
996 { ISD::UDIV, MVT::v32i8, { 56 } },
997 { ISD::SDIV, MVT::v32i8, { 56 } },
998 { ISD::UREM, MVT::v32i8, { 56 } },
999 { ISD::SREM, MVT::v32i8, { 56 } },
1000 { ISD::UDIV, MVT::v8i16, { 14 } },
1001 { ISD::SDIV, MVT::v8i16, { 14 } },
1002 { ISD::UREM, MVT::v8i16, { 14 } },
1003 { ISD::SREM, MVT::v8i16, { 14 } },
1004 { ISD::UDIV, MVT::v16i16, { 28 } },
1005 { ISD::SDIV, MVT::v16i16, { 28 } },
1006 { ISD::UREM, MVT::v16i16, { 28 } },
1007 { ISD::SREM, MVT::v16i16, { 28 } },
1008 { ISD::UDIV, MVT::v4i32, { 28 } }, // cvt+divpd sequence
1009 { ISD::SDIV, MVT::v4i32, { 28 } },
1010 { ISD::UREM, MVT::v4i32, { 28 } },
1011 { ISD::SREM, MVT::v4i32, { 28 } },
1012 { ISD::UDIV, MVT::v8i32, { 56 } },
1013 { ISD::SDIV, MVT::v8i32, { 56 } },
1014 { ISD::UREM, MVT::v8i32, { 56 } },
1015 { ISD::SREM, MVT::v8i32, { 56 } },
1016 };
1017
1018 static const CostKindTblEntry AVX2ExactVarDivCostTable[] = {
1019 { ISD::UDIV, MVT::v4i32, { 9 } }, // cvt+divps sequence
1020 { ISD::SDIV, MVT::v4i32, { 8 } },
1021 { ISD::UREM, MVT::v4i32, { 9 } },
1022 { ISD::SREM, MVT::v4i32, { 8 } },
1023 { ISD::UDIV, MVT::v8i32, { 14 } },
1024 { ISD::SDIV, MVT::v8i32, { 14 } },
1025 { ISD::UREM, MVT::v8i32, { 14 } },
1026 { ISD::SREM, MVT::v8i32, { 14 } },
1027 };
1028
1029 if (VarDivToFP && ST->hasAVX2()) {
1030 ArrayRef<CostKindTblEntry> Tbl = AVX2VarDivCostTable;
1031 if (ExactI32)
1032 Tbl = AVX2ExactVarDivCostTable;
1033 if (const auto *Entry = CostTableLookup(Tbl, ISD, LT.second))
1034 if (auto KindCost = Entry->Cost[CostKind])
1035 return LT.first * *KindCost;
1036 }
1037
1038 // No unsigned i32 entries below AVX2, where the u32 to f64 converts are
1039 // emulated and the fold stays off.
1040 static const CostKindTblEntry AVX1VarDivCostTable[] = {
1041 { ISD::UDIV, MVT::v16i8, { 56 } }, // unpack+cvt+divps sequence
1042 { ISD::SDIV, MVT::v16i8, { 56 } },
1043 { ISD::UREM, MVT::v16i8, { 56 } },
1044 { ISD::SREM, MVT::v16i8, { 56 } },
1045 { ISD::UDIV, MVT::v32i8, { 112 } },
1046 { ISD::SDIV, MVT::v32i8, { 112 } },
1047 { ISD::UREM, MVT::v32i8, { 112 } },
1048 { ISD::SREM, MVT::v32i8, { 112 } },
1049 { ISD::UDIV, MVT::v8i16, { 28 } },
1050 { ISD::SDIV, MVT::v8i16, { 28 } },
1051 { ISD::UREM, MVT::v8i16, { 28 } },
1052 { ISD::SREM, MVT::v8i16, { 28 } },
1053 { ISD::UDIV, MVT::v16i16, { 56 } },
1054 { ISD::SDIV, MVT::v16i16, { 56 } },
1055 { ISD::UREM, MVT::v16i16, { 56 } },
1056 { ISD::SREM, MVT::v16i16, { 56 } },
1057 { ISD::SDIV, MVT::v4i32, { 44 } }, // cvt+divpd sequence
1058 { ISD::SREM, MVT::v4i32, { 44 } },
1059 { ISD::SDIV, MVT::v8i32, { 88 } },
1060 { ISD::SREM, MVT::v8i32, { 88 } },
1061 };
1062
1063 static const CostKindTblEntry AVX1ExactVarDivCostTable[] = {
1064 { ISD::SDIV, MVT::v4i32, { 14 } }, // cvt+divps sequence
1065 { ISD::SREM, MVT::v4i32, { 14 } },
1066 { ISD::SDIV, MVT::v8i32, { 28 } },
1067 { ISD::SREM, MVT::v8i32, { 28 } },
1068 };
1069
1070 if (VarDivToFP && ST->hasAVX()) {
1071 ArrayRef<CostKindTblEntry> Tbl = AVX1VarDivCostTable;
1072 if (ExactI32)
1073 Tbl = AVX1ExactVarDivCostTable;
1074 if (const auto *Entry = CostTableLookup(Tbl, ISD, LT.second))
1075 if (auto KindCost = Entry->Cost[CostKind])
1076 return LT.first * *KindCost;
1077 }
1078
1079 static const CostKindTblEntry SSE2VarDivCostTable[] = {
1080 { ISD::UDIV, MVT::v16i8, { 56 } }, // unpack+cvt+divps sequence
1081 { ISD::SDIV, MVT::v16i8, { 56 } },
1082 { ISD::UREM, MVT::v16i8, { 56 } },
1083 { ISD::SREM, MVT::v16i8, { 56 } },
1084 { ISD::UDIV, MVT::v8i16, { 28 } },
1085 { ISD::SDIV, MVT::v8i16, { 28 } },
1086 { ISD::UREM, MVT::v8i16, { 28 } },
1087 { ISD::SREM, MVT::v8i16, { 28 } },
1088 { ISD::SDIV, MVT::v4i32, { 44 } }, // cvt+divpd sequence
1089 { ISD::SREM, MVT::v4i32, { 44 } },
1090 };
1091
1092 static const CostKindTblEntry SSE2ExactVarDivCostTable[] = {
1093 { ISD::SDIV, MVT::v4i32, { 14 } }, // cvt+divps sequence
1094 { ISD::SREM, MVT::v4i32, { 14 } },
1095 };
1096
1097 if (VarDivToFP && ST->hasSSE2()) {
1098 ArrayRef<CostKindTblEntry> Tbl = SSE2VarDivCostTable;
1099 if (ExactI32)
1100 Tbl = SSE2ExactVarDivCostTable;
1101 if (const auto *Entry = CostTableLookup(Tbl, ISD, LT.second))
1102 if (auto KindCost = Entry->Cost[CostKind])
1103 return LT.first * *KindCost;
1104 }
1105
1106 static const CostKindTblEntry AVX512BWUniformCostTable[] = {
1107 { ISD::SHL, MVT::v16i8, { 3, 5, 5, 7 } }, // psllw + pand.
1108 { ISD::SRL, MVT::v16i8, { 3,10, 5, 8 } }, // psrlw + pand.
1109 { ISD::SRA, MVT::v16i8, { 4,12, 8,12 } }, // psrlw, pand, pxor, psubb.
1110 { ISD::SHL, MVT::v32i8, { 4, 7, 6, 8 } }, // psllw + pand.
1111 { ISD::SRL, MVT::v32i8, { 4, 8, 7, 9 } }, // psrlw + pand.
1112 { ISD::SRA, MVT::v32i8, { 5,10,10,13 } }, // psrlw, pand, pxor, psubb.
1113 { ISD::SHL, MVT::v64i8, { 4, 7, 6, 8 } }, // psllw + pand.
1114 { ISD::SRL, MVT::v64i8, { 4, 8, 7,10 } }, // psrlw + pand.
1115 { ISD::SRA, MVT::v64i8, { 5,10,10,15 } }, // psrlw, pand, pxor, psubb.
1116
1117 { ISD::SHL, MVT::v32i16, { 2, 4, 2, 3 } }, // psllw
1118 { ISD::SRL, MVT::v32i16, { 2, 4, 2, 3 } }, // psrlw
1119 { ISD::SRA, MVT::v32i16, { 2, 4, 2, 3 } }, // psrqw
1120 };
1121
1122 if (ST->hasBWI() && Op2Info.isUniform())
1123 if (const auto *Entry =
1124 CostTableLookup(AVX512BWUniformCostTable, ISD, LT.second))
1125 if (auto KindCost = Entry->Cost[CostKind])
1126 return LT.first * *KindCost;
1127
1128 static const CostKindTblEntry AVX512UniformCostTable[] = {
1129 { ISD::SHL, MVT::v32i16, { 5,10, 5, 7 } }, // psllw + split.
1130 { ISD::SRL, MVT::v32i16, { 5,10, 5, 7 } }, // psrlw + split.
1131 { ISD::SRA, MVT::v32i16, { 5,10, 5, 7 } }, // psraw + split.
1132
1133 { ISD::SHL, MVT::v16i32, { 2, 4, 2, 3 } }, // pslld
1134 { ISD::SRL, MVT::v16i32, { 2, 4, 2, 3 } }, // psrld
1135 { ISD::SRA, MVT::v16i32, { 2, 4, 2, 3 } }, // psrad
1136
1137 { ISD::SRA, MVT::v2i64, { 1, 2, 1, 2 } }, // psraq
1138 { ISD::SHL, MVT::v4i64, { 1, 4, 1, 2 } }, // psllq
1139 { ISD::SRL, MVT::v4i64, { 1, 4, 1, 2 } }, // psrlq
1140 { ISD::SRA, MVT::v4i64, { 1, 4, 1, 2 } }, // psraq
1141 { ISD::SHL, MVT::v8i64, { 1, 4, 1, 2 } }, // psllq
1142 { ISD::SRL, MVT::v8i64, { 1, 4, 1, 2 } }, // psrlq
1143 { ISD::SRA, MVT::v8i64, { 1, 4, 1, 2 } }, // psraq
1144 };
1145
1146 if (ST->hasAVX512() && Op2Info.isUniform())
1147 if (const auto *Entry =
1148 CostTableLookup(AVX512UniformCostTable, ISD, LT.second))
1149 if (auto KindCost = Entry->Cost[CostKind])
1150 return LT.first * *KindCost;
1151
1152 static const CostKindTblEntry AVX2UniformCostTable[] = {
1153 // Uniform splats are cheaper for the following instructions.
1154 { ISD::SHL, MVT::v16i8, { 3, 5, 5, 7 } }, // psllw + pand.
1155 { ISD::SRL, MVT::v16i8, { 3, 9, 5, 8 } }, // psrlw + pand.
1156 { ISD::SRA, MVT::v16i8, { 4, 5, 9,13 } }, // psrlw, pand, pxor, psubb.
1157 { ISD::SHL, MVT::v32i8, { 4, 7, 6, 8 } }, // psllw + pand.
1158 { ISD::SRL, MVT::v32i8, { 4, 8, 7, 9 } }, // psrlw + pand.
1159 { ISD::SRA, MVT::v32i8, { 6, 9,11,16 } }, // psrlw, pand, pxor, psubb.
1160
1161 { ISD::SHL, MVT::v8i16, { 1, 2, 1, 2 } }, // psllw.
1162 { ISD::SRL, MVT::v8i16, { 1, 2, 1, 2 } }, // psrlw.
1163 { ISD::SRA, MVT::v8i16, { 1, 2, 1, 2 } }, // psraw.
1164 { ISD::SHL, MVT::v16i16, { 2, 4, 2, 3 } }, // psllw.
1165 { ISD::SRL, MVT::v16i16, { 2, 4, 2, 3 } }, // psrlw.
1166 { ISD::SRA, MVT::v16i16, { 2, 4, 2, 3 } }, // psraw.
1167
1168 { ISD::SHL, MVT::v4i32, { 1, 2, 1, 2 } }, // pslld
1169 { ISD::SRL, MVT::v4i32, { 1, 2, 1, 2 } }, // psrld
1170 { ISD::SRA, MVT::v4i32, { 1, 2, 1, 2 } }, // psrad
1171 { ISD::SHL, MVT::v8i32, { 2, 4, 2, 3 } }, // pslld
1172 { ISD::SRL, MVT::v8i32, { 2, 4, 2, 3 } }, // psrld
1173 { ISD::SRA, MVT::v8i32, { 2, 4, 2, 3 } }, // psrad
1174
1175 { ISD::SHL, MVT::v2i64, { 1, 2, 1, 2 } }, // psllq
1176 { ISD::SRL, MVT::v2i64, { 1, 2, 1, 2 } }, // psrlq
1177 { ISD::SRA, MVT::v2i64, { 2, 4, 5, 7 } }, // 2 x psrad + shuffle.
1178 { ISD::SHL, MVT::v4i64, { 2, 4, 1, 2 } }, // psllq
1179 { ISD::SRL, MVT::v4i64, { 2, 4, 1, 2 } }, // psrlq
1180 { ISD::SRA, MVT::v4i64, { 4, 6, 5, 9 } }, // 2 x psrad + shuffle.
1181 };
1182
1183 if (ST->hasAVX2() && Op2Info.isUniform())
1184 if (const auto *Entry =
1185 CostTableLookup(AVX2UniformCostTable, ISD, LT.second))
1186 if (auto KindCost = Entry->Cost[CostKind])
1187 return LT.first * *KindCost;
1188
1189 static const CostKindTblEntry AVXUniformCostTable[] = {
1190 { ISD::SHL, MVT::v16i8, { 4, 4, 6, 8 } }, // psllw + pand.
1191 { ISD::SRL, MVT::v16i8, { 4, 8, 5, 8 } }, // psrlw + pand.
1192 { ISD::SRA, MVT::v16i8, { 6, 6, 9,13 } }, // psrlw, pand, pxor, psubb.
1193 { ISD::SHL, MVT::v32i8, { 7, 8,11,14 } }, // psllw + pand + split.
1194 { ISD::SRL, MVT::v32i8, { 7, 9,10,14 } }, // psrlw + pand + split.
1195 { ISD::SRA, MVT::v32i8, { 10,11,16,21 } }, // psrlw, pand, pxor, psubb + split.
1196
1197 { ISD::SHL, MVT::v8i16, { 1, 3, 1, 2 } }, // psllw.
1198 { ISD::SRL, MVT::v8i16, { 1, 3, 1, 2 } }, // psrlw.
1199 { ISD::SRA, MVT::v8i16, { 1, 3, 1, 2 } }, // psraw.
1200 { ISD::SHL, MVT::v16i16, { 3, 7, 5, 7 } }, // psllw + split.
1201 { ISD::SRL, MVT::v16i16, { 3, 7, 5, 7 } }, // psrlw + split.
1202 { ISD::SRA, MVT::v16i16, { 3, 7, 5, 7 } }, // psraw + split.
1203
1204 { ISD::SHL, MVT::v4i32, { 1, 3, 1, 2 } }, // pslld.
1205 { ISD::SRL, MVT::v4i32, { 1, 3, 1, 2 } }, // psrld.
1206 { ISD::SRA, MVT::v4i32, { 1, 3, 1, 2 } }, // psrad.
1207 { ISD::SHL, MVT::v8i32, { 3, 7, 5, 7 } }, // pslld + split.
1208 { ISD::SRL, MVT::v8i32, { 3, 7, 5, 7 } }, // psrld + split.
1209 { ISD::SRA, MVT::v8i32, { 3, 7, 5, 7 } }, // psrad + split.
1210
1211 { ISD::SHL, MVT::v2i64, { 1, 3, 1, 2 } }, // psllq.
1212 { ISD::SRL, MVT::v2i64, { 1, 3, 1, 2 } }, // psrlq.
1213 { ISD::SRA, MVT::v2i64, { 3, 4, 5, 7 } }, // 2 x psrad + shuffle.
1214 { ISD::SHL, MVT::v4i64, { 3, 7, 4, 6 } }, // psllq + split.
1215 { ISD::SRL, MVT::v4i64, { 3, 7, 4, 6 } }, // psrlq + split.
1216 { ISD::SRA, MVT::v4i64, { 6, 7,10,13 } }, // 2 x (2 x psrad + shuffle) + split.
1217 };
1218
1219 // XOP has faster vXi8 shifts.
1220 if (ST->hasAVX() && Op2Info.isUniform() &&
1221 (!ST->hasXOP() || LT.second.getScalarSizeInBits() != 8))
1222 if (const auto *Entry =
1223 CostTableLookup(AVXUniformCostTable, ISD, LT.second))
1224 if (auto KindCost = Entry->Cost[CostKind])
1225 return LT.first * *KindCost;
1226
1227 static const CostKindTblEntry SSE2UniformCostTable[] = {
1228 // Uniform splats are cheaper for the following instructions.
1229 { ISD::SHL, MVT::v16i8, { 9, 10, 6, 9 } }, // psllw + pand.
1230 { ISD::SRL, MVT::v16i8, { 9, 13, 5, 9 } }, // psrlw + pand.
1231 { ISD::SRA, MVT::v16i8, { 11, 15, 9,13 } }, // pcmpgtb sequence.
1232
1233 { ISD::SHL, MVT::v8i16, { 2, 2, 1, 2 } }, // psllw.
1234 { ISD::SRL, MVT::v8i16, { 2, 2, 1, 2 } }, // psrlw.
1235 { ISD::SRA, MVT::v8i16, { 2, 2, 1, 2 } }, // psraw.
1236
1237 { ISD::SHL, MVT::v4i32, { 2, 2, 1, 2 } }, // pslld
1238 { ISD::SRL, MVT::v4i32, { 2, 2, 1, 2 } }, // psrld.
1239 { ISD::SRA, MVT::v4i32, { 2, 2, 1, 2 } }, // psrad.
1240
1241 { ISD::SHL, MVT::v2i64, { 2, 2, 1, 2 } }, // psllq.
1242 { ISD::SRL, MVT::v2i64, { 2, 2, 1, 2 } }, // psrlq.
1243 { ISD::SRA, MVT::v2i64, { 5, 9, 5, 7 } }, // 2*psrlq + xor + sub.
1244 };
1245
1246 if (ST->hasSSE2() && Op2Info.isUniform() &&
1247 (!ST->hasXOP() || LT.second.getScalarSizeInBits() != 8))
1248 if (const auto *Entry =
1249 CostTableLookup(SSE2UniformCostTable, ISD, LT.second))
1250 if (auto KindCost = Entry->Cost[CostKind])
1251 return LT.first * *KindCost;
1252
1253 static const CostKindTblEntry AVX512DQCostTable[] = {
1254 { ISD::MUL, MVT::v2i64, { 2, 15, 1, 3 } }, // pmullq
1255 { ISD::MUL, MVT::v4i64, { 2, 15, 1, 3 } }, // pmullq
1256 { ISD::MUL, MVT::v8i64, { 3, 15, 1, 3 } } // pmullq
1257 };
1258
1259 // Look for AVX512DQ lowering tricks for custom cases.
1260 if (ST->hasDQI())
1261 if (const auto *Entry = CostTableLookup(AVX512DQCostTable, ISD, LT.second))
1262 if (auto KindCost = Entry->Cost[CostKind])
1263 return LT.first * *KindCost;
1264
1265 static const CostKindTblEntry AVX512BWCostTable[] = {
1266 { ISD::SHL, MVT::v16i8, { 4, 8, 4, 5 } }, // extend/vpsllvw/pack sequence.
1267 { ISD::SRL, MVT::v16i8, { 4, 8, 4, 5 } }, // extend/vpsrlvw/pack sequence.
1268 { ISD::SRA, MVT::v16i8, { 4, 8, 4, 5 } }, // extend/vpsravw/pack sequence.
1269 { ISD::SHL, MVT::v32i8, { 4, 23,11,16 } }, // extend/vpsllvw/pack sequence.
1270 { ISD::SRL, MVT::v32i8, { 4, 30,12,18 } }, // extend/vpsrlvw/pack sequence.
1271 { ISD::SRA, MVT::v32i8, { 6, 13,24,30 } }, // extend/vpsravw/pack sequence.
1272 { ISD::SHL, MVT::v64i8, { 6, 19,13,15 } }, // extend/vpsllvw/pack sequence.
1273 { ISD::SRL, MVT::v64i8, { 7, 27,15,18 } }, // extend/vpsrlvw/pack sequence.
1274 { ISD::SRA, MVT::v64i8, { 15, 15,30,30 } }, // extend/vpsravw/pack sequence.
1275
1276 { ISD::SHL, MVT::v8i16, { 1, 1, 1, 1 } }, // vpsllvw
1277 { ISD::SRL, MVT::v8i16, { 1, 1, 1, 1 } }, // vpsrlvw
1278 { ISD::SRA, MVT::v8i16, { 1, 1, 1, 1 } }, // vpsravw
1279 { ISD::SHL, MVT::v16i16, { 1, 1, 1, 1 } }, // vpsllvw
1280 { ISD::SRL, MVT::v16i16, { 1, 1, 1, 1 } }, // vpsrlvw
1281 { ISD::SRA, MVT::v16i16, { 1, 1, 1, 1 } }, // vpsravw
1282 { ISD::SHL, MVT::v32i16, { 1, 1, 1, 1 } }, // vpsllvw
1283 { ISD::SRL, MVT::v32i16, { 1, 1, 1, 1 } }, // vpsrlvw
1284 { ISD::SRA, MVT::v32i16, { 1, 1, 1, 1 } }, // vpsravw
1285
1286 { ISD::ADD, MVT::v64i8, { 1, 1, 1, 1 } }, // paddb
1287 { ISD::ADD, MVT::v32i16, { 1, 1, 1, 1 } }, // paddw
1288
1289 { ISD::ADD, MVT::v32i8, { 1, 1, 1, 1 } }, // paddb
1290 { ISD::ADD, MVT::v16i16, { 1, 1, 1, 1 } }, // paddw
1291 { ISD::ADD, MVT::v8i32, { 1, 1, 1, 1 } }, // paddd
1292 { ISD::ADD, MVT::v4i64, { 1, 1, 1, 1 } }, // paddq
1293
1294 { ISD::SUB, MVT::v64i8, { 1, 1, 1, 1 } }, // psubb
1295 { ISD::SUB, MVT::v32i16, { 1, 1, 1, 1 } }, // psubw
1296
1297 { ISD::MUL, MVT::v16i8, { 4, 12, 4, 5 } }, // extend/pmullw/trunc
1298 { ISD::MUL, MVT::v32i8, { 3, 10, 7,10 } }, // pmaddubsw
1299 { ISD::MUL, MVT::v64i8, { 3, 11, 7,10 } }, // pmaddubsw
1300 { ISD::MUL, MVT::v32i16, { 1, 5, 1, 1 } }, // pmullw
1301
1302 { ISD::SUB, MVT::v32i8, { 1, 1, 1, 1 } }, // psubb
1303 { ISD::SUB, MVT::v16i16, { 1, 1, 1, 1 } }, // psubw
1304 { ISD::SUB, MVT::v8i32, { 1, 1, 1, 1 } }, // psubd
1305 { ISD::SUB, MVT::v4i64, { 1, 1, 1, 1 } }, // psubq
1306 };
1307
1308 // Look for AVX512BW lowering tricks for custom cases.
1309 if (ST->hasBWI())
1310 if (const auto *Entry = CostTableLookup(AVX512BWCostTable, ISD, LT.second))
1311 if (auto KindCost = Entry->Cost[CostKind])
1312 return LT.first * *KindCost;
1313
1314 static const CostKindTblEntry AVX512CostTable[] = {
1315 { ISD::SHL, MVT::v64i8, { 15, 19,27,33 } }, // vpblendv+split sequence.
1316 { ISD::SRL, MVT::v64i8, { 15, 19,30,36 } }, // vpblendv+split sequence.
1317 { ISD::SRA, MVT::v64i8, { 37, 37,51,63 } }, // vpblendv+split sequence.
1318
1319 { ISD::SHL, MVT::v32i16, { 11, 16,11,15 } }, // 2*extend/vpsrlvd/pack sequence.
1320 { ISD::SRL, MVT::v32i16, { 11, 16,11,15 } }, // 2*extend/vpsrlvd/pack sequence.
1321 { ISD::SRA, MVT::v32i16, { 11, 16,11,15 } }, // 2*extend/vpsravd/pack sequence.
1322
1323 { ISD::SHL, MVT::v4i32, { 1, 1, 1, 1 } },
1324 { ISD::SRL, MVT::v4i32, { 1, 1, 1, 1 } },
1325 { ISD::SRA, MVT::v4i32, { 1, 1, 1, 1 } },
1326 { ISD::SHL, MVT::v8i32, { 1, 1, 1, 1 } },
1327 { ISD::SRL, MVT::v8i32, { 1, 1, 1, 1 } },
1328 { ISD::SRA, MVT::v8i32, { 1, 1, 1, 1 } },
1329 { ISD::SHL, MVT::v16i32, { 1, 1, 1, 1 } },
1330 { ISD::SRL, MVT::v16i32, { 1, 1, 1, 1 } },
1331 { ISD::SRA, MVT::v16i32, { 1, 1, 1, 1 } },
1332
1333 { ISD::SHL, MVT::v2i64, { 1, 1, 1, 1 } },
1334 { ISD::SRL, MVT::v2i64, { 1, 1, 1, 1 } },
1335 { ISD::SRA, MVT::v2i64, { 1, 1, 1, 1 } },
1336 { ISD::SHL, MVT::v4i64, { 1, 1, 1, 1 } },
1337 { ISD::SRL, MVT::v4i64, { 1, 1, 1, 1 } },
1338 { ISD::SRA, MVT::v4i64, { 1, 1, 1, 1 } },
1339 { ISD::SHL, MVT::v8i64, { 1, 1, 1, 1 } },
1340 { ISD::SRL, MVT::v8i64, { 1, 1, 1, 1 } },
1341 { ISD::SRA, MVT::v8i64, { 1, 1, 1, 1 } },
1342
1343 { ISD::ADD, MVT::v64i8, { 3, 7, 5, 5 } }, // 2*paddb + split
1344 { ISD::ADD, MVT::v32i16, { 3, 7, 5, 5 } }, // 2*paddw + split
1345
1346 { ISD::SUB, MVT::v64i8, { 3, 7, 5, 5 } }, // 2*psubb + split
1347 { ISD::SUB, MVT::v32i16, { 3, 7, 5, 5 } }, // 2*psubw + split
1348
1349 { ISD::AND, MVT::v32i8, { 1, 1, 1, 1 } },
1350 { ISD::AND, MVT::v16i16, { 1, 1, 1, 1 } },
1351 { ISD::AND, MVT::v8i32, { 1, 1, 1, 1 } },
1352 { ISD::AND, MVT::v4i64, { 1, 1, 1, 1 } },
1353
1354 { ISD::OR, MVT::v32i8, { 1, 1, 1, 1 } },
1355 { ISD::OR, MVT::v16i16, { 1, 1, 1, 1 } },
1356 { ISD::OR, MVT::v8i32, { 1, 1, 1, 1 } },
1357 { ISD::OR, MVT::v4i64, { 1, 1, 1, 1 } },
1358
1359 { ISD::XOR, MVT::v32i8, { 1, 1, 1, 1 } },
1360 { ISD::XOR, MVT::v16i16, { 1, 1, 1, 1 } },
1361 { ISD::XOR, MVT::v8i32, { 1, 1, 1, 1 } },
1362 { ISD::XOR, MVT::v4i64, { 1, 1, 1, 1 } },
1363
1364 { ISD::MUL, MVT::v16i32, { 1, 10, 1, 2 } }, // pmulld (Skylake from agner.org)
1365 { ISD::MUL, MVT::v8i32, { 1, 10, 1, 2 } }, // pmulld (Skylake from agner.org)
1366 { ISD::MUL, MVT::v4i32, { 1, 10, 1, 2 } }, // pmulld (Skylake from agner.org)
1367 { ISD::MUL, MVT::v8i64, { 6, 9, 8, 8 } }, // 3*pmuludq/3*shift/2*add
1368 { ISD::MUL, MVT::i64, { 1 } }, // Skylake from http://www.agner.org/
1369
1370 { X86ISD::PMULUDQ, MVT::v8i64, { 1, 5, 1, 1 } },
1371
1372 { ISD::FNEG, MVT::v8f64, { 1, 1, 1, 2 } }, // Skylake from http://www.agner.org/
1373 { ISD::FADD, MVT::v8f64, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1374 { ISD::FADD, MVT::v4f64, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1375 { ISD::FSUB, MVT::v8f64, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1376 { ISD::FSUB, MVT::v4f64, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1377 { ISD::FMUL, MVT::v8f64, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1378 { ISD::FMUL, MVT::v4f64, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1379 { ISD::FMUL, MVT::v2f64, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1380 { ISD::FMUL, MVT::f64, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1381
1382 { ISD::FDIV, MVT::f64, { 4, 14, 1, 1 } }, // Skylake from http://www.agner.org/
1383 { ISD::FDIV, MVT::v2f64, { 4, 14, 1, 1 } }, // Skylake from http://www.agner.org/
1384 { ISD::FDIV, MVT::v4f64, { 8, 14, 1, 1 } }, // Skylake from http://www.agner.org/
1385 { ISD::FDIV, MVT::v8f64, { 16, 23, 1, 3 } }, // Skylake from http://www.agner.org/
1386
1387 { ISD::FNEG, MVT::v16f32, { 1, 1, 1, 2 } }, // Skylake from http://www.agner.org/
1388 { ISD::FADD, MVT::v16f32, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1389 { ISD::FADD, MVT::v8f32, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1390 { ISD::FSUB, MVT::v16f32, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1391 { ISD::FSUB, MVT::v8f32, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1392 { ISD::FMUL, MVT::v16f32, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1393 { ISD::FMUL, MVT::v8f32, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1394 { ISD::FMUL, MVT::v4f32, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1395 { ISD::FMUL, MVT::f32, { 1, 4, 1, 1 } }, // Skylake from http://www.agner.org/
1396
1397 { ISD::FDIV, MVT::f32, { 3, 11, 1, 1 } }, // Skylake from http://www.agner.org/
1398 { ISD::FDIV, MVT::v4f32, { 3, 11, 1, 1 } }, // Skylake from http://www.agner.org/
1399 { ISD::FDIV, MVT::v8f32, { 5, 11, 1, 1 } }, // Skylake from http://www.agner.org/
1400 { ISD::FDIV, MVT::v16f32, { 10, 18, 1, 3 } }, // Skylake from http://www.agner.org/
1401 };
1402
1403 if (ST->hasAVX512())
1404 if (const auto *Entry = CostTableLookup(AVX512CostTable, ISD, LT.second))
1405 if (auto KindCost = Entry->Cost[CostKind])
1406 return LT.first * *KindCost;
1407
1408 static const CostKindTblEntry AVX2ShiftCostTable[] = {
1409 // Shifts on vXi64/vXi32 on AVX2 is legal even though we declare to
1410 // customize them to detect the cases where shift amount is a scalar one.
1411 { ISD::SHL, MVT::v4i32, { 2, 3, 1, 3 } }, // vpsllvd (Haswell from agner.org)
1412 { ISD::SRL, MVT::v4i32, { 2, 3, 1, 3 } }, // vpsrlvd (Haswell from agner.org)
1413 { ISD::SRA, MVT::v4i32, { 2, 3, 1, 3 } }, // vpsravd (Haswell from agner.org)
1414 { ISD::SHL, MVT::v8i32, { 4, 4, 1, 3 } }, // vpsllvd (Haswell from agner.org)
1415 { ISD::SRL, MVT::v8i32, { 4, 4, 1, 3 } }, // vpsrlvd (Haswell from agner.org)
1416 { ISD::SRA, MVT::v8i32, { 4, 4, 1, 3 } }, // vpsravd (Haswell from agner.org)
1417 { ISD::SHL, MVT::v2i64, { 2, 3, 1, 1 } }, // vpsllvq (Haswell from agner.org)
1418 { ISD::SRL, MVT::v2i64, { 2, 3, 1, 1 } }, // vpsrlvq (Haswell from agner.org)
1419 { ISD::SHL, MVT::v4i64, { 4, 4, 1, 2 } }, // vpsllvq (Haswell from agner.org)
1420 { ISD::SRL, MVT::v4i64, { 4, 4, 1, 2 } }, // vpsrlvq (Haswell from agner.org)
1421 };
1422
1423 if (ST->hasAVX512()) {
1424 if (ISD == ISD::SHL && LT.second == MVT::v32i16 && Op2Info.isConstant())
1425 // On AVX512, a packed v32i16 shift left by a constant build_vector
1426 // is lowered into a vector multiply (vpmullw).
1427 return getArithmeticInstrCost(Instruction::Mul, Ty, CostKind,
1428 Op1Info.getNoProps(), Op2Info.getNoProps());
1429 }
1430
1431 // Look for AVX2 lowering tricks (XOP is always better at v4i32 shifts).
1432 if (ST->hasAVX2() && !(ST->hasXOP() && LT.second == MVT::v4i32)) {
1433 if (ISD == ISD::SHL && LT.second == MVT::v16i16 &&
1434 Op2Info.isConstant())
1435 // On AVX2, a packed v16i16 shift left by a constant build_vector
1436 // is lowered into a vector multiply (vpmullw).
1437 return getArithmeticInstrCost(Instruction::Mul, Ty, CostKind,
1438 Op1Info.getNoProps(), Op2Info.getNoProps());
1439
1440 if (const auto *Entry = CostTableLookup(AVX2ShiftCostTable, ISD, LT.second))
1441 if (auto KindCost = Entry->Cost[CostKind])
1442 return LT.first * *KindCost;
1443 }
1444
1445 static const CostKindTblEntry XOPShiftCostTable[] = {
1446 // 128bit shifts take 1cy, but right shifts require negation beforehand.
1447 { ISD::SHL, MVT::v16i8, { 1, 3, 1, 1 } },
1448 { ISD::SRL, MVT::v16i8, { 2, 3, 1, 1 } },
1449 { ISD::SRA, MVT::v16i8, { 2, 3, 1, 1 } },
1450 { ISD::SHL, MVT::v8i16, { 1, 3, 1, 1 } },
1451 { ISD::SRL, MVT::v8i16, { 2, 3, 1, 1 } },
1452 { ISD::SRA, MVT::v8i16, { 2, 3, 1, 1 } },
1453 { ISD::SHL, MVT::v4i32, { 1, 3, 1, 1 } },
1454 { ISD::SRL, MVT::v4i32, { 2, 3, 1, 1 } },
1455 { ISD::SRA, MVT::v4i32, { 2, 3, 1, 1 } },
1456 { ISD::SHL, MVT::v2i64, { 1, 3, 1, 1 } },
1457 { ISD::SRL, MVT::v2i64, { 2, 3, 1, 1 } },
1458 { ISD::SRA, MVT::v2i64, { 2, 3, 1, 1 } },
1459 // 256bit shifts require splitting if AVX2 didn't catch them above.
1460 { ISD::SHL, MVT::v32i8, { 4, 7, 5, 6 } },
1461 { ISD::SRL, MVT::v32i8, { 6, 7, 5, 6 } },
1462 { ISD::SRA, MVT::v32i8, { 6, 7, 5, 6 } },
1463 { ISD::SHL, MVT::v16i16, { 4, 7, 5, 6 } },
1464 { ISD::SRL, MVT::v16i16, { 6, 7, 5, 6 } },
1465 { ISD::SRA, MVT::v16i16, { 6, 7, 5, 6 } },
1466 { ISD::SHL, MVT::v8i32, { 4, 7, 5, 6 } },
1467 { ISD::SRL, MVT::v8i32, { 6, 7, 5, 6 } },
1468 { ISD::SRA, MVT::v8i32, { 6, 7, 5, 6 } },
1469 { ISD::SHL, MVT::v4i64, { 4, 7, 5, 6 } },
1470 { ISD::SRL, MVT::v4i64, { 6, 7, 5, 6 } },
1471 { ISD::SRA, MVT::v4i64, { 6, 7, 5, 6 } },
1472 };
1473
1474 // Look for XOP lowering tricks.
1475 if (ST->hasXOP()) {
1476 // If the right shift is constant then we'll fold the negation so
1477 // it's as cheap as a left shift.
1478 int ShiftISD = ISD;
1479 if ((ShiftISD == ISD::SRL || ShiftISD == ISD::SRA) && Op2Info.isConstant())
1480 ShiftISD = ISD::SHL;
1481 if (const auto *Entry =
1482 CostTableLookup(XOPShiftCostTable, ShiftISD, LT.second))
1483 if (auto KindCost = Entry->Cost[CostKind])
1484 return LT.first * *KindCost;
1485 }
1486
1487 if (ISD == ISD::SHL && !Op2Info.isUniform() && Op2Info.isConstant()) {
1488 MVT VT = LT.second;
1489 // Vector shift left by non uniform constant can be lowered
1490 // into vector multiply.
1491 if (((VT == MVT::v8i16 || VT == MVT::v4i32) && ST->hasSSE2()) ||
1492 ((VT == MVT::v16i16 || VT == MVT::v8i32) && ST->hasAVX()))
1493 ISD = ISD::MUL;
1494 }
1495
1496 static const CostKindTblEntry GLMCostTable[] = {
1497 { ISD::FDIV, MVT::f32, { 18, 19, 1, 1 } }, // divss
1498 { ISD::FDIV, MVT::v4f32, { 35, 36, 1, 1 } }, // divps
1499 { ISD::FDIV, MVT::f64, { 33, 34, 1, 1 } }, // divsd
1500 { ISD::FDIV, MVT::v2f64, { 65, 66, 1, 1 } }, // divpd
1501 };
1502
1503 if (ST->useGLMDivSqrtCosts())
1504 if (const auto *Entry = CostTableLookup(GLMCostTable, ISD, LT.second))
1505 if (auto KindCost = Entry->Cost[CostKind])
1506 return LT.first * *KindCost;
1507
1508 static const CostKindTblEntry SLMCostTable[] = {
1509 { ISD::MUL, MVT::v4i32, { 11, 11, 1, 7 } }, // pmulld
1510 { ISD::MUL, MVT::v8i16, { 2, 5, 1, 1 } }, // pmullw
1511 { ISD::FMUL, MVT::f64, { 2, 5, 1, 1 } }, // mulsd
1512 { ISD::FMUL, MVT::f32, { 1, 4, 1, 1 } }, // mulss
1513 { ISD::FMUL, MVT::v2f64, { 4, 7, 1, 1 } }, // mulpd
1514 { ISD::FMUL, MVT::v4f32, { 2, 5, 1, 1 } }, // mulps
1515 { ISD::FDIV, MVT::f32, { 17, 19, 1, 1 } }, // divss
1516 { ISD::FDIV, MVT::v4f32, { 39, 39, 1, 6 } }, // divps
1517 { ISD::FDIV, MVT::f64, { 32, 34, 1, 1 } }, // divsd
1518 { ISD::FDIV, MVT::v2f64, { 69, 69, 1, 6 } }, // divpd
1519 { ISD::FADD, MVT::v2f64, { 2, 4, 1, 1 } }, // addpd
1520 { ISD::FSUB, MVT::v2f64, { 2, 4, 1, 1 } }, // subpd
1521 // v2i64/v4i64 mul is custom lowered as a series of long:
1522 // multiplies(3), shifts(3) and adds(2)
1523 // slm muldq version throughput is 2 and addq throughput 4
1524 // thus: 3X2 (muldq throughput) + 3X1 (shift throughput) +
1525 // 3X4 (addq throughput) = 17
1526 { ISD::MUL, MVT::v2i64, { 17, 22, 9, 9 } },
1527 // slm addq\subq throughput is 4
1528 { ISD::ADD, MVT::v2i64, { 4, 2, 1, 2 } },
1529 { ISD::SUB, MVT::v2i64, { 4, 2, 1, 2 } },
1530 };
1531
1532 if (ST->useSLMArithCosts())
1533 if (const auto *Entry = CostTableLookup(SLMCostTable, ISD, LT.second))
1534 if (auto KindCost = Entry->Cost[CostKind])
1535 return LT.first * *KindCost;
1536
1537 static const CostKindTblEntry AVX2CostTable[] = {
1538 { ISD::SHL, MVT::v16i8, { 6, 21,11,16 } }, // vpblendvb sequence.
1539 { ISD::SHL, MVT::v32i8, { 6, 23,11,22 } }, // vpblendvb sequence.
1540 { ISD::SHL, MVT::v8i16, { 5, 18, 5,10 } }, // extend/vpsrlvd/pack sequence.
1541 { ISD::SHL, MVT::v16i16, { 8, 10,10,14 } }, // extend/vpsrlvd/pack sequence.
1542
1543 { ISD::SRL, MVT::v16i8, { 6, 27,12,18 } }, // vpblendvb sequence.
1544 { ISD::SRL, MVT::v32i8, { 8, 30,12,24 } }, // vpblendvb sequence.
1545 { ISD::SRL, MVT::v8i16, { 5, 11, 5,10 } }, // extend/vpsrlvd/pack sequence.
1546 { ISD::SRL, MVT::v16i16, { 8, 10,10,14 } }, // extend/vpsrlvd/pack sequence.
1547
1548 { ISD::SRA, MVT::v16i8, { 17, 17,24,30 } }, // vpblendvb sequence.
1549 { ISD::SRA, MVT::v32i8, { 18, 20,24,43 } }, // vpblendvb sequence.
1550 { ISD::SRA, MVT::v8i16, { 5, 11, 5,10 } }, // extend/vpsravd/pack sequence.
1551 { ISD::SRA, MVT::v16i16, { 8, 10,10,14 } }, // extend/vpsravd/pack sequence.
1552 { ISD::SRA, MVT::v2i64, { 4, 5, 5, 5 } }, // srl/xor/sub sequence.
1553 { ISD::SRA, MVT::v4i64, { 8, 8, 5, 9 } }, // srl/xor/sub sequence.
1554
1555 { ISD::SUB, MVT::v32i8, { 1, 1, 1, 2 } }, // psubb
1556 { ISD::ADD, MVT::v32i8, { 1, 1, 1, 2 } }, // paddb
1557 { ISD::SUB, MVT::v16i16, { 1, 1, 1, 2 } }, // psubw
1558 { ISD::ADD, MVT::v16i16, { 1, 1, 1, 2 } }, // paddw
1559 { ISD::SUB, MVT::v8i32, { 1, 1, 1, 2 } }, // psubd
1560 { ISD::ADD, MVT::v8i32, { 1, 1, 1, 2 } }, // paddd
1561 { ISD::SUB, MVT::v4i64, { 1, 1, 1, 2 } }, // psubq
1562 { ISD::ADD, MVT::v4i64, { 1, 1, 1, 2 } }, // paddq
1563
1564 { ISD::MUL, MVT::v16i8, { 5, 18, 6,12 } }, // extend/pmullw/pack
1565 { ISD::MUL, MVT::v32i8, { 4, 8, 8,16 } }, // pmaddubsw
1566 { ISD::MUL, MVT::v16i16, { 2, 5, 1, 2 } }, // pmullw
1567 { ISD::MUL, MVT::v8i32, { 4, 10, 1, 2 } }, // pmulld
1568 { ISD::MUL, MVT::v4i32, { 2, 10, 1, 2 } }, // pmulld
1569 { ISD::MUL, MVT::v4i64, { 6, 10, 8,13 } }, // 3*pmuludq/3*shift/2*add
1570 { ISD::MUL, MVT::v2i64, { 6, 10, 8, 8 } }, // 3*pmuludq/3*shift/2*add
1571
1572 { X86ISD::PMULUDQ, MVT::v4i64, { 1, 5, 1, 1 } },
1573
1574 { ISD::FNEG, MVT::v4f64, { 1, 1, 1, 2 } }, // vxorpd
1575 { ISD::FNEG, MVT::v8f32, { 1, 1, 1, 2 } }, // vxorps
1576
1577 { ISD::FADD, MVT::f64, { 1, 4, 1, 1 } }, // vaddsd
1578 { ISD::FADD, MVT::f32, { 1, 4, 1, 1 } }, // vaddss
1579 { ISD::FADD, MVT::v2f64, { 1, 4, 1, 1 } }, // vaddpd
1580 { ISD::FADD, MVT::v4f32, { 1, 4, 1, 1 } }, // vaddps
1581 { ISD::FADD, MVT::v4f64, { 1, 4, 1, 2 } }, // vaddpd
1582 { ISD::FADD, MVT::v8f32, { 1, 4, 1, 2 } }, // vaddps
1583
1584 { ISD::FSUB, MVT::f64, { 1, 4, 1, 1 } }, // vsubsd
1585 { ISD::FSUB, MVT::f32, { 1, 4, 1, 1 } }, // vsubss
1586 { ISD::FSUB, MVT::v2f64, { 1, 4, 1, 1 } }, // vsubpd
1587 { ISD::FSUB, MVT::v4f32, { 1, 4, 1, 1 } }, // vsubps
1588 { ISD::FSUB, MVT::v4f64, { 1, 4, 1, 2 } }, // vsubpd
1589 { ISD::FSUB, MVT::v8f32, { 1, 4, 1, 2 } }, // vsubps
1590
1591 { ISD::FMUL, MVT::f64, { 1, 5, 1, 1 } }, // vmulsd
1592 { ISD::FMUL, MVT::f32, { 1, 5, 1, 1 } }, // vmulss
1593 { ISD::FMUL, MVT::v2f64, { 1, 5, 1, 1 } }, // vmulpd
1594 { ISD::FMUL, MVT::v4f32, { 1, 5, 1, 1 } }, // vmulps
1595 { ISD::FMUL, MVT::v4f64, { 1, 5, 1, 2 } }, // vmulpd
1596 { ISD::FMUL, MVT::v8f32, { 1, 5, 1, 2 } }, // vmulps
1597
1598 { ISD::FDIV, MVT::f32, { 7, 13, 1, 1 } }, // vdivss
1599 { ISD::FDIV, MVT::v4f32, { 7, 13, 1, 1 } }, // vdivps
1600 { ISD::FDIV, MVT::v8f32, { 14, 21, 1, 3 } }, // vdivps
1601 { ISD::FDIV, MVT::f64, { 14, 20, 1, 1 } }, // vdivsd
1602 { ISD::FDIV, MVT::v2f64, { 14, 20, 1, 1 } }, // vdivpd
1603 { ISD::FDIV, MVT::v4f64, { 28, 35, 1, 3 } }, // vdivpd
1604 };
1605
1606 // Look for AVX2 lowering tricks for custom cases.
1607 if (ST->hasAVX2())
1608 if (const auto *Entry = CostTableLookup(AVX2CostTable, ISD, LT.second))
1609 if (auto KindCost = Entry->Cost[CostKind])
1610 return LT.first * *KindCost;
1611
1612 static const CostKindTblEntry AVX1CostTable[] = {
1613 // We don't have to scalarize unsupported ops. We can issue two half-sized
1614 // operations and we only need to extract the upper YMM half.
1615 // Two ops + 1 extract + 1 insert = 4.
1616 { ISD::MUL, MVT::v32i8, { 10, 11, 18, 19 } }, // pmaddubsw + split
1617 { ISD::MUL, MVT::v16i8, { 5, 6, 8, 12 } }, // 2*pmaddubsw/3*and/psllw/or
1618 { ISD::MUL, MVT::v16i16, { 4, 8, 5, 6 } }, // pmullw + split
1619 { ISD::MUL, MVT::v8i32, { 5, 8, 5, 10 } }, // pmulld + split
1620 { ISD::MUL, MVT::v4i32, { 2, 5, 1, 3 } }, // pmulld
1621 { ISD::MUL, MVT::v4i64, { 12, 15, 19, 20 } },
1622
1623 { X86ISD::PMULUDQ, MVT::v4i64, { 3, 5, 5, 6 } }, // pmuludq + split
1624
1625 { ISD::AND, MVT::v32i8, { 1, 1, 1, 2 } }, // vandps
1626 { ISD::AND, MVT::v16i16, { 1, 1, 1, 2 } }, // vandps
1627 { ISD::AND, MVT::v8i32, { 1, 1, 1, 2 } }, // vandps
1628 { ISD::AND, MVT::v4i64, { 1, 1, 1, 2 } }, // vandps
1629
1630 { ISD::OR, MVT::v32i8, { 1, 1, 1, 2 } }, // vorps
1631 { ISD::OR, MVT::v16i16, { 1, 1, 1, 2 } }, // vorps
1632 { ISD::OR, MVT::v8i32, { 1, 1, 1, 2 } }, // vorps
1633 { ISD::OR, MVT::v4i64, { 1, 1, 1, 2 } }, // vorps
1634
1635 { ISD::XOR, MVT::v32i8, { 1, 1, 1, 2 } }, // vxorps
1636 { ISD::XOR, MVT::v16i16, { 1, 1, 1, 2 } }, // vxorps
1637 { ISD::XOR, MVT::v8i32, { 1, 1, 1, 2 } }, // vxorps
1638 { ISD::XOR, MVT::v4i64, { 1, 1, 1, 2 } }, // vxorps
1639
1640 { ISD::SUB, MVT::v32i8, { 4, 2, 5, 6 } }, // psubb + split
1641 { ISD::ADD, MVT::v32i8, { 4, 2, 5, 6 } }, // paddb + split
1642 { ISD::SUB, MVT::v16i16, { 4, 2, 5, 6 } }, // psubw + split
1643 { ISD::ADD, MVT::v16i16, { 4, 2, 5, 6 } }, // paddw + split
1644 { ISD::SUB, MVT::v8i32, { 4, 2, 5, 6 } }, // psubd + split
1645 { ISD::ADD, MVT::v8i32, { 4, 2, 5, 6 } }, // paddd + split
1646 { ISD::SUB, MVT::v4i64, { 4, 2, 5, 6 } }, // psubq + split
1647 { ISD::ADD, MVT::v4i64, { 4, 2, 5, 6 } }, // paddq + split
1648 { ISD::SUB, MVT::v2i64, { 1, 1, 1, 1 } }, // psubq
1649 { ISD::ADD, MVT::v2i64, { 1, 1, 1, 1 } }, // paddq
1650
1651 { ISD::SHL, MVT::v16i8, { 10, 21,11,17 } }, // pblendvb sequence.
1652 { ISD::SHL, MVT::v32i8, { 22, 22,27,40 } }, // pblendvb sequence + split.
1653 { ISD::SHL, MVT::v8i16, { 6, 9,11,11 } }, // pblendvb sequence.
1654 { ISD::SHL, MVT::v16i16, { 13, 16,24,25 } }, // pblendvb sequence + split.
1655 { ISD::SHL, MVT::v4i32, { 3, 11, 4, 6 } }, // pslld/paddd/cvttps2dq/pmulld
1656 { ISD::SHL, MVT::v8i32, { 9, 11,12,17 } }, // pslld/paddd/cvttps2dq/pmulld + split
1657 { ISD::SHL, MVT::v2i64, { 2, 4, 4, 6 } }, // Shift each lane + blend.
1658 { ISD::SHL, MVT::v4i64, { 6, 7,11,15 } }, // Shift each lane + blend + split.
1659
1660 { ISD::SRL, MVT::v16i8, { 11, 27,12,18 } }, // pblendvb sequence.
1661 { ISD::SRL, MVT::v32i8, { 23, 23,30,43 } }, // pblendvb sequence + split.
1662 { ISD::SRL, MVT::v8i16, { 13, 16,14,22 } }, // pblendvb sequence.
1663 { ISD::SRL, MVT::v16i16, { 28, 30,31,48 } }, // pblendvb sequence + split.
1664 { ISD::SRL, MVT::v4i32, { 6, 7,12,16 } }, // Shift each lane + blend.
1665 { ISD::SRL, MVT::v8i32, { 14, 14,26,34 } }, // Shift each lane + blend + split.
1666 { ISD::SRL, MVT::v2i64, { 2, 4, 4, 6 } }, // Shift each lane + blend.
1667 { ISD::SRL, MVT::v4i64, { 6, 7,11,15 } }, // Shift each lane + blend + split.
1668
1669 { ISD::SRA, MVT::v16i8, { 21, 22,24,36 } }, // pblendvb sequence.
1670 { ISD::SRA, MVT::v32i8, { 44, 45,51,76 } }, // pblendvb sequence + split.
1671 { ISD::SRA, MVT::v8i16, { 13, 16,14,22 } }, // pblendvb sequence.
1672 { ISD::SRA, MVT::v16i16, { 28, 30,31,48 } }, // pblendvb sequence + split.
1673 { ISD::SRA, MVT::v4i32, { 6, 7,12,16 } }, // Shift each lane + blend.
1674 { ISD::SRA, MVT::v8i32, { 14, 14,26,34 } }, // Shift each lane + blend + split.
1675 { ISD::SRA, MVT::v2i64, { 5, 6,10,14 } }, // Shift each lane + blend.
1676 { ISD::SRA, MVT::v4i64, { 12, 12,22,30 } }, // Shift each lane + blend + split.
1677
1678 { ISD::FNEG, MVT::v4f64, { 2, 2, 1, 2 } }, // BTVER2 from http://www.agner.org/
1679 { ISD::FNEG, MVT::v8f32, { 2, 2, 1, 2 } }, // BTVER2 from http://www.agner.org/
1680
1681 { ISD::FADD, MVT::f64, { 1, 5, 1, 1 } }, // BDVER2 from http://www.agner.org/
1682 { ISD::FADD, MVT::f32, { 1, 5, 1, 1 } }, // BDVER2 from http://www.agner.org/
1683 { ISD::FADD, MVT::v2f64, { 1, 5, 1, 1 } }, // BDVER2 from http://www.agner.org/
1684 { ISD::FADD, MVT::v4f32, { 1, 5, 1, 1 } }, // BDVER2 from http://www.agner.org/
1685 { ISD::FADD, MVT::v4f64, { 2, 5, 1, 2 } }, // BDVER2 from http://www.agner.org/
1686 { ISD::FADD, MVT::v8f32, { 2, 5, 1, 2 } }, // BDVER2 from http://www.agner.org/
1687
1688 { ISD::FSUB, MVT::f64, { 1, 5, 1, 1 } }, // BDVER2 from http://www.agner.org/
1689 { ISD::FSUB, MVT::f32, { 1, 5, 1, 1 } }, // BDVER2 from http://www.agner.org/
1690 { ISD::FSUB, MVT::v2f64, { 1, 5, 1, 1 } }, // BDVER2 from http://www.agner.org/
1691 { ISD::FSUB, MVT::v4f32, { 1, 5, 1, 1 } }, // BDVER2 from http://www.agner.org/
1692 { ISD::FSUB, MVT::v4f64, { 2, 5, 1, 2 } }, // BDVER2 from http://www.agner.org/
1693 { ISD::FSUB, MVT::v8f32, { 2, 5, 1, 2 } }, // BDVER2 from http://www.agner.org/
1694
1695 { ISD::FMUL, MVT::f64, { 2, 5, 1, 1 } }, // BTVER2 from http://www.agner.org/
1696 { ISD::FMUL, MVT::f32, { 1, 5, 1, 1 } }, // BTVER2 from http://www.agner.org/
1697 { ISD::FMUL, MVT::v2f64, { 2, 5, 1, 1 } }, // BTVER2 from http://www.agner.org/
1698 { ISD::FMUL, MVT::v4f32, { 1, 5, 1, 1 } }, // BTVER2 from http://www.agner.org/
1699 { ISD::FMUL, MVT::v4f64, { 4, 5, 1, 2 } }, // BTVER2 from http://www.agner.org/
1700 { ISD::FMUL, MVT::v8f32, { 2, 5, 1, 2 } }, // BTVER2 from http://www.agner.org/
1701
1702 { ISD::FDIV, MVT::f32, { 14, 14, 1, 1 } }, // SNB from http://www.agner.org/
1703 { ISD::FDIV, MVT::v4f32, { 14, 14, 1, 1 } }, // SNB from http://www.agner.org/
1704 { ISD::FDIV, MVT::v8f32, { 28, 29, 1, 3 } }, // SNB from http://www.agner.org/
1705 { ISD::FDIV, MVT::f64, { 22, 22, 1, 1 } }, // SNB from http://www.agner.org/
1706 { ISD::FDIV, MVT::v2f64, { 22, 22, 1, 1 } }, // SNB from http://www.agner.org/
1707 { ISD::FDIV, MVT::v4f64, { 44, 45, 1, 3 } }, // SNB from http://www.agner.org/
1708 };
1709
1710 if (ST->hasAVX())
1711 if (const auto *Entry = CostTableLookup(AVX1CostTable, ISD, LT.second))
1712 if (auto KindCost = Entry->Cost[CostKind])
1713 return LT.first * *KindCost;
1714
1715 static const CostKindTblEntry SSE42CostTable[] = {
1716 { ISD::FADD, MVT::f64, { 1, 3, 1, 1 } }, // Nehalem from http://www.agner.org/
1717 { ISD::FADD, MVT::f32, { 1, 3, 1, 1 } }, // Nehalem from http://www.agner.org/
1718 { ISD::FADD, MVT::v2f64, { 1, 3, 1, 1 } }, // Nehalem from http://www.agner.org/
1719 { ISD::FADD, MVT::v4f32, { 1, 3, 1, 1 } }, // Nehalem from http://www.agner.org/
1720
1721 { ISD::FSUB, MVT::f64, { 1, 3, 1, 1 } }, // Nehalem from http://www.agner.org/
1722 { ISD::FSUB, MVT::f32 , { 1, 3, 1, 1 } }, // Nehalem from http://www.agner.org/
1723 { ISD::FSUB, MVT::v2f64, { 1, 3, 1, 1 } }, // Nehalem from http://www.agner.org/
1724 { ISD::FSUB, MVT::v4f32, { 1, 3, 1, 1 } }, // Nehalem from http://www.agner.org/
1725
1726 { ISD::FMUL, MVT::f64, { 1, 5, 1, 1 } }, // Nehalem from http://www.agner.org/
1727 { ISD::FMUL, MVT::f32, { 1, 5, 1, 1 } }, // Nehalem from http://www.agner.org/
1728 { ISD::FMUL, MVT::v2f64, { 1, 5, 1, 1 } }, // Nehalem from http://www.agner.org/
1729 { ISD::FMUL, MVT::v4f32, { 1, 5, 1, 1 } }, // Nehalem from http://www.agner.org/
1730
1731 { ISD::FDIV, MVT::f32, { 14, 14, 1, 1 } }, // Nehalem from http://www.agner.org/
1732 { ISD::FDIV, MVT::v4f32, { 14, 14, 1, 1 } }, // Nehalem from http://www.agner.org/
1733 { ISD::FDIV, MVT::f64, { 22, 22, 1, 1 } }, // Nehalem from http://www.agner.org/
1734 { ISD::FDIV, MVT::v2f64, { 22, 22, 1, 1 } }, // Nehalem from http://www.agner.org/
1735
1736 { ISD::MUL, MVT::v2i64, { 6, 10,10,10 } } // 3*pmuludq/3*shift/2*add
1737 };
1738
1739 if (ST->hasSSE42())
1740 if (const auto *Entry = CostTableLookup(SSE42CostTable, ISD, LT.second))
1741 if (auto KindCost = Entry->Cost[CostKind])
1742 return LT.first * *KindCost;
1743
1744 static const CostKindTblEntry SSE41CostTable[] = {
1745 { ISD::SHL, MVT::v16i8, { 15, 24,17,22 } }, // pblendvb sequence.
1746 { ISD::SHL, MVT::v8i16, { 11, 14,11,11 } }, // pblendvb sequence.
1747 { ISD::SHL, MVT::v4i32, { 14, 20, 4,10 } }, // pslld/paddd/cvttps2dq/pmulld
1748
1749 { ISD::SRL, MVT::v16i8, { 16, 27,18,24 } }, // pblendvb sequence.
1750 { ISD::SRL, MVT::v8i16, { 22, 26,23,27 } }, // pblendvb sequence.
1751 { ISD::SRL, MVT::v4i32, { 16, 17,15,19 } }, // Shift each lane + blend.
1752 { ISD::SRL, MVT::v2i64, { 4, 6, 5, 7 } }, // splat+shuffle sequence.
1753
1754 { ISD::SRA, MVT::v16i8, { 38, 41,30,36 } }, // pblendvb sequence.
1755 { ISD::SRA, MVT::v8i16, { 22, 26,23,27 } }, // pblendvb sequence.
1756 { ISD::SRA, MVT::v4i32, { 16, 17,15,19 } }, // Shift each lane + blend.
1757 { ISD::SRA, MVT::v2i64, { 8, 17, 5, 7 } }, // splat+shuffle sequence.
1758
1759 { ISD::MUL, MVT::v4i32, { 2, 11, 1, 1 } } // pmulld (Nehalem from agner.org)
1760 };
1761
1762 if (ST->hasSSE41())
1763 if (const auto *Entry = CostTableLookup(SSE41CostTable, ISD, LT.second))
1764 if (auto KindCost = Entry->Cost[CostKind])
1765 return LT.first * *KindCost;
1766
1767 static const CostKindTblEntry SSSE3CostTable[] = {
1768 { ISD::MUL, MVT::v16i8, { 5, 18,10,12 } }, // 2*pmaddubsw/3*and/psllw/or
1769 };
1770
1771 if (ST->hasSSSE3())
1772 if (const auto *Entry = CostTableLookup(SSSE3CostTable, ISD, LT.second))
1773 if (auto KindCost = Entry->Cost[CostKind])
1774 return LT.first * *KindCost;
1775
1776 static const CostKindTblEntry SSE2CostTable[] = {
1777 // We don't correctly identify costs of casts because they are marked as
1778 // custom.
1779 { ISD::SHL, MVT::v16i8, { 13, 21,26,28 } }, // cmpgtb sequence.
1780 { ISD::SHL, MVT::v8i16, { 24, 27,16,20 } }, // cmpgtw sequence.
1781 { ISD::SHL, MVT::v4i32, { 17, 19,10,12 } }, // pslld/paddd/cvttps2dq/pmuludq.
1782 { ISD::SHL, MVT::v2i64, { 4, 6, 5, 7 } }, // splat+shuffle sequence.
1783
1784 { ISD::SRL, MVT::v16i8, { 14, 28,27,30 } }, // cmpgtb sequence.
1785 { ISD::SRL, MVT::v8i16, { 16, 19,31,31 } }, // cmpgtw sequence.
1786 { ISD::SRL, MVT::v4i32, { 12, 12,15,19 } }, // Shift each lane + blend.
1787 { ISD::SRL, MVT::v2i64, { 4, 6, 5, 7 } }, // splat+shuffle sequence.
1788
1789 { ISD::SRA, MVT::v16i8, { 27, 30,54,54 } }, // unpacked cmpgtb sequence.
1790 { ISD::SRA, MVT::v8i16, { 16, 19,31,31 } }, // cmpgtw sequence.
1791 { ISD::SRA, MVT::v4i32, { 12, 12,15,19 } }, // Shift each lane + blend.
1792 { ISD::SRA, MVT::v2i64, { 8, 11,12,16 } }, // srl/xor/sub splat+shuffle sequence.
1793
1794 { ISD::AND, MVT::v16i8, { 1, 1, 1, 1 } }, // pand
1795 { ISD::AND, MVT::v8i16, { 1, 1, 1, 1 } }, // pand
1796 { ISD::AND, MVT::v4i32, { 1, 1, 1, 1 } }, // pand
1797 { ISD::AND, MVT::v2i64, { 1, 1, 1, 1 } }, // pand
1798
1799 { ISD::OR, MVT::v16i8, { 1, 1, 1, 1 } }, // por
1800 { ISD::OR, MVT::v8i16, { 1, 1, 1, 1 } }, // por
1801 { ISD::OR, MVT::v4i32, { 1, 1, 1, 1 } }, // por
1802 { ISD::OR, MVT::v2i64, { 1, 1, 1, 1 } }, // por
1803
1804 { ISD::XOR, MVT::v16i8, { 1, 1, 1, 1 } }, // pxor
1805 { ISD::XOR, MVT::v8i16, { 1, 1, 1, 1 } }, // pxor
1806 { ISD::XOR, MVT::v4i32, { 1, 1, 1, 1 } }, // pxor
1807 { ISD::XOR, MVT::v2i64, { 1, 1, 1, 1 } }, // pxor
1808
1809 { ISD::ADD, MVT::v2i64, { 1, 2, 1, 2 } }, // paddq
1810 { ISD::SUB, MVT::v2i64, { 1, 2, 1, 2 } }, // psubq
1811
1812 { ISD::MUL, MVT::v16i8, { 6, 18,12,12 } }, // 2*unpack/2*pmullw/2*and/pack
1813 { ISD::MUL, MVT::v8i16, { 1, 5, 1, 1 } }, // pmullw
1814 { ISD::MUL, MVT::v4i32, { 6, 8, 7, 7 } }, // 3*pmuludq/4*shuffle
1815 { ISD::MUL, MVT::v2i64, { 7, 10,10,10 } }, // 3*pmuludq/3*shift/2*add
1816
1817 { X86ISD::PMULUDQ, MVT::v2i64, { 1, 5, 1, 1 } },
1818
1819 { ISD::FDIV, MVT::f32, { 23, 23, 1, 1 } }, // Pentium IV from http://www.agner.org/
1820 { ISD::FDIV, MVT::v4f32, { 39, 39, 1, 1 } }, // Pentium IV from http://www.agner.org/
1821 { ISD::FDIV, MVT::f64, { 38, 38, 1, 1 } }, // Pentium IV from http://www.agner.org/
1822 { ISD::FDIV, MVT::v2f64, { 69, 69, 1, 1 } }, // Pentium IV from http://www.agner.org/
1823
1824 { ISD::FNEG, MVT::f32, { 1, 1, 1, 1 } }, // Pentium IV from http://www.agner.org/
1825 { ISD::FNEG, MVT::f64, { 1, 1, 1, 1 } }, // Pentium IV from http://www.agner.org/
1826 { ISD::FNEG, MVT::v4f32, { 1, 1, 1, 1 } }, // Pentium IV from http://www.agner.org/
1827 { ISD::FNEG, MVT::v2f64, { 1, 1, 1, 1 } }, // Pentium IV from http://www.agner.org/
1828
1829 { ISD::FADD, MVT::f32, { 2, 3, 1, 1 } }, // Pentium IV from http://www.agner.org/
1830 { ISD::FADD, MVT::f64, { 2, 3, 1, 1 } }, // Pentium IV from http://www.agner.org/
1831 { ISD::FADD, MVT::v2f64, { 2, 3, 1, 1 } }, // Pentium IV from http://www.agner.org/
1832
1833 { ISD::FSUB, MVT::f32, { 2, 3, 1, 1 } }, // Pentium IV from http://www.agner.org/
1834 { ISD::FSUB, MVT::f64, { 2, 3, 1, 1 } }, // Pentium IV from http://www.agner.org/
1835 { ISD::FSUB, MVT::v2f64, { 2, 3, 1, 1 } }, // Pentium IV from http://www.agner.org/
1836
1837 { ISD::FMUL, MVT::f64, { 2, 5, 1, 1 } }, // Pentium IV from http://www.agner.org/
1838 { ISD::FMUL, MVT::v2f64, { 2, 5, 1, 1 } }, // Pentium IV from http://www.agner.org/
1839 };
1840
1841 if (ST->hasSSE2())
1842 if (const auto *Entry = CostTableLookup(SSE2CostTable, ISD, LT.second))
1843 if (auto KindCost = Entry->Cost[CostKind])
1844 return LT.first * *KindCost;
1845
1846 static const CostKindTblEntry SSE1CostTable[] = {
1847 { ISD::FDIV, MVT::f32, { 17, 18, 1, 1 } }, // Pentium III from http://www.agner.org/
1848 { ISD::FDIV, MVT::v4f32, { 34, 48, 1, 1 } }, // Pentium III from http://www.agner.org/
1849
1850 { ISD::FNEG, MVT::f32, { 2, 2, 1, 2 } }, // Pentium III from http://www.agner.org/
1851 { ISD::FNEG, MVT::v4f32, { 2, 2, 1, 2 } }, // Pentium III from http://www.agner.org/
1852
1853 { ISD::FADD, MVT::f32, { 1, 3, 1, 1 } }, // Pentium III from http://www.agner.org/
1854 { ISD::FADD, MVT::v4f32, { 2, 3, 1, 1 } }, // Pentium III from http://www.agner.org/
1855
1856 { ISD::FSUB, MVT::f32, { 1, 3, 1, 1 } }, // Pentium III from http://www.agner.org/
1857 { ISD::FSUB, MVT::v4f32, { 2, 3, 1, 1 } }, // Pentium III from http://www.agner.org/
1858
1859 { ISD::FMUL, MVT::f32, { 2, 5, 1, 1 } }, // Pentium III from http://www.agner.org/
1860 { ISD::FMUL, MVT::v4f32, { 2, 5, 1, 1 } }, // Pentium III from http://www.agner.org/
1861 };
1862
1863 if (ST->hasSSE1())
1864 if (const auto *Entry = CostTableLookup(SSE1CostTable, ISD, LT.second))
1865 if (auto KindCost = Entry->Cost[CostKind])
1866 return LT.first * *KindCost;
1867
1868 static const CostKindTblEntry X64CostTbl[] = { // 64-bit targets
1869 { ISD::ADD, MVT::i64, { 1 } }, // Core (Merom) from http://www.agner.org/
1870 { ISD::SUB, MVT::i64, { 1 } }, // Core (Merom) from http://www.agner.org/
1871 { ISD::MUL, MVT::i64, { 2, 6, 1, 2 } },
1872 };
1873
1874 if (ST->is64Bit())
1875 if (const auto *Entry = CostTableLookup(X64CostTbl, ISD, LT.second))
1876 if (auto KindCost = Entry->Cost[CostKind])
1877 return LT.first * *KindCost;
1878
1879 static const CostKindTblEntry X86CostTbl[] = { // 32 or 64-bit targets
1880 { ISD::ADD, MVT::i8, { 1 } }, // Pentium III from http://www.agner.org/
1881 { ISD::ADD, MVT::i16, { 1 } }, // Pentium III from http://www.agner.org/
1882 { ISD::ADD, MVT::i32, { 1 } }, // Pentium III from http://www.agner.org/
1883
1884 { ISD::SUB, MVT::i8, { 1 } }, // Pentium III from http://www.agner.org/
1885 { ISD::SUB, MVT::i16, { 1 } }, // Pentium III from http://www.agner.org/
1886 { ISD::SUB, MVT::i32, { 1 } }, // Pentium III from http://www.agner.org/
1887
1888 { ISD::MUL, MVT::i8, { 3, 4, 1, 1 } },
1889 { ISD::MUL, MVT::i16, { 2, 4, 1, 1 } },
1890 { ISD::MUL, MVT::i32, { 1, 4, 1, 1 } },
1891
1892 { ISD::FNEG, MVT::f64, { 2, 2, 1, 3 } }, // (x87)
1893 { ISD::FADD, MVT::f64, { 2, 3, 1, 1 } }, // (x87)
1894 { ISD::FSUB, MVT::f64, { 2, 3, 1, 1 } }, // (x87)
1895 { ISD::FMUL, MVT::f64, { 2, 5, 1, 1 } }, // (x87)
1896 { ISD::FDIV, MVT::f64, { 38, 38, 1, 1 } }, // (x87)
1897 };
1898
1899 if (const auto *Entry = CostTableLookup(X86CostTbl, ISD, LT.second))
1900 if (auto KindCost = Entry->Cost[CostKind])
1901 return LT.first * *KindCost;
1902
1903 // It is not a good idea to vectorize division. We have to scalarize it and
1904 // in the process we will often end up having to spilling regular
1905 // registers. The overhead of division is going to dominate most kernels
1906 // anyways so try hard to prevent vectorization of division - it is
1907 // generally a bad idea. Assume somewhat arbitrarily that we have to be able
1908 // to hide "20 cycles" for each lane.
1909 if (CostKind == TTI::TCK_RecipThroughput && LT.second.isVector() &&
1910 (ISD == ISD::SDIV || ISD == ISD::SREM || ISD == ISD::UDIV ||
1911 ISD == ISD::UREM)) {
1912 InstructionCost ScalarCost =
1913 getArithmeticInstrCost(Opcode, Ty->getScalarType(), CostKind,
1914 Op1Info.getNoProps(), Op2Info.getNoProps());
1915 return 20 * LT.first * LT.second.getVectorNumElements() * ScalarCost;
1916 }
1917
1918 // Handle some basic single instruction code size cases.
1919 if (CostKind == TTI::TCK_CodeSize) {
1920 switch (ISD) {
1921 case ISD::FADD:
1922 case ISD::FSUB:
1923 case ISD::FMUL:
1924 case ISD::FDIV:
1925 case ISD::FNEG:
1926 case ISD::AND:
1927 case ISD::OR:
1928 case ISD::XOR:
1929 return LT.first;
1930 break;
1931 }
1932 }
1933
1934 // Fallback to the default implementation.
1935 return BaseT::getArithmeticInstrCost(Opcode, Ty, CostKind, Op1Info, Op2Info,
1936 Args, CxtI);
1937}
1938
1941 unsigned Opcode1, const SmallBitVector &OpcodeMask,
1943 if (isLegalAltInstr(VecTy, Opcode0, Opcode1, OpcodeMask))
1944 return TTI::TCC_Basic;
1946}
1947
1949 VectorType *DstTy, VectorType *SrcTy,
1951 ArrayRef<int> Mask, int Index,
1952 VectorType *SubTp,
1954 const Instruction *CxtI) const {
1955 assert((Mask.empty() || DstTy->isScalableTy() ||
1956 Mask.size() == DstTy->getElementCount().getKnownMinValue()) &&
1957 "Expected the Mask to match the return size if given");
1958 assert(SrcTy->getScalarType() == DstTy->getScalarType() &&
1959 "Expected the same scalar types");
1960
1961 // 64-bit packed float vectors (v2f32) are widened to type v4f32.
1962 // 64-bit packed integer vectors (v2i32) are widened to type v4i32.
1963 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(SrcTy);
1964
1965 Kind = improveShuffleKindFromMask(Kind, Mask, SrcTy, Index, SubTp);
1966
1967 // If all args are constant than this will be constant folded away.
1968 if (!Args.empty() &&
1969 all_of(Args, [](const Value *Arg) { return isa<Constant>(Arg); }))
1970 return TTI::TCC_Free;
1971
1972 // Recognize a basic concat_vector shuffle.
1973 if (Kind == TTI::SK_PermuteTwoSrc &&
1974 Mask.size() == (2 * SrcTy->getElementCount().getKnownMinValue()) &&
1975 ShuffleVectorInst::isIdentityMask(Mask, Mask.size()))
1979 CostKind, Mask, Mask.size() / 2, SrcTy);
1980
1981 // Treat Transpose as 2-op shuffles - there's no difference in lowering.
1982 if (Kind == TTI::SK_Transpose)
1983 if (LT.second != MVT::v4f64 && LT.second != MVT::v4i64)
1984 Kind = TTI::SK_PermuteTwoSrc;
1985
1986 if (Kind == TTI::SK_Broadcast) {
1987 // For Broadcasts we are splatting the first element from the first input
1988 // register, so only need to reference that input and all the output
1989 // registers are the same.
1990 LT.first = 1;
1991
1992 // If we're broadcasting a load then AVX/AVX2 can do this for free.
1993 // If many-used-load whose every use is one of a small set of operations
1994 // that SLP can rewrite into a single vector lane, codegen can fold it into
1995 // the free broadcast.
1996 using namespace PatternMatch;
1997 auto IsBroadcastLoadFoldUser = [&](const User *U) {
1998 if (isa<InsertElementInst>(U) && U->getOperand(1) == Args[0])
1999 return true;
2000 if (U->getType()->isVectorTy())
2001 return false;
2002 // Terminators (return/branch/switch/indirectbr/resume/invoke EH)
2003 // and phis carry the value across control flow.
2004 if (const auto *I = dyn_cast<Instruction>(U))
2005 if (I->isTerminator() ||
2007 return false;
2008 // Only pure calls can be folded.
2009 if (const auto *CB = dyn_cast<CallBase>(U))
2010 return CB->doesNotAccessMemory() && !CB->mayHaveSideEffects();
2011 return true;
2012 };
2013 auto IsFoldableSLPBroadcastLoad = [&]() {
2014 if (!match(Args[0], m_Load(m_Value())))
2015 return false;
2016 auto *FVT = dyn_cast<FixedVectorType>(DstTy);
2017 if (!FVT)
2018 return false;
2019 // getNumUses() counts each Use, matching the per-lane broadcast
2020 // accounting (a use like `op %x, %x` consumes two broadcast lanes).
2021 if (Args[0]->getNumUses() != FVT->getNumElements())
2022 return false;
2023 return all_of(Args[0]->users(), IsBroadcastLoadFoldUser);
2024 };
2025 if (!Args.empty() &&
2026 (match(Args[0], m_OneUse(m_Load(m_Value()))) ||
2027 IsFoldableSLPBroadcastLoad()) &&
2028 (ST->hasAVX2() ||
2029 (ST->hasAVX() && LT.second.getScalarSizeInBits() >= 32)))
2030 return TTI::TCC_Free;
2031 }
2032
2033 // Attempt to detect a cheaper inlane shuffle, avoiding 128-bit subvector
2034 // permutation.
2035 // Attempt to detect a shuffle mask with a single defined element.
2036 bool IsInLaneShuffle = false;
2037 bool IsSingleElementMask = false;
2038 if (SrcTy->getPrimitiveSizeInBits() > 0 &&
2039 (SrcTy->getPrimitiveSizeInBits() % 128) == 0 &&
2040 SrcTy->getScalarSizeInBits() == LT.second.getScalarSizeInBits() &&
2041 Mask.size() == SrcTy->getElementCount().getKnownMinValue()) {
2042 unsigned NumLanes = SrcTy->getPrimitiveSizeInBits() / 128;
2043 unsigned NumEltsPerLane = Mask.size() / NumLanes;
2044 if ((Mask.size() % NumLanes) == 0) {
2045 IsInLaneShuffle = all_of(enumerate(Mask), [&](const auto &P) {
2046 return P.value() == PoisonMaskElem ||
2047 ((P.value() % Mask.size()) / NumEltsPerLane) ==
2048 (P.index() / NumEltsPerLane);
2049 });
2050 IsSingleElementMask =
2051 (Mask.size() - 1) == static_cast<unsigned>(count_if(Mask, [](int M) {
2052 return M == PoisonMaskElem;
2053 }));
2054 }
2055 }
2056
2057 // Treat <X x bfloat> shuffles as <X x half>.
2058 if (LT.second.isVectorOf(MVT::bf16))
2059 LT.second = LT.second.changeVectorElementType(MVT::f16);
2060
2061 // Subvector extractions are free if they start at the beginning of a
2062 // vector and cheap if the subvectors are aligned.
2063 if (Kind == TTI::SK_ExtractSubvector && LT.second.isVector()) {
2064 int NumElts = LT.second.getVectorNumElements();
2065 if ((Index % NumElts) == 0)
2066 return TTI::TCC_Free;
2067 std::pair<InstructionCost, MVT> SubLT = getTypeLegalizationCost(SubTp);
2068 if (SubLT.second.isVector()) {
2069 int NumSubElts = SubLT.second.getVectorNumElements();
2070 if ((Index % NumSubElts) == 0 && (NumElts % NumSubElts) == 0)
2071 return SubLT.first;
2072 // Handle some cases for widening legalization. For now we only handle
2073 // cases where the original subvector was naturally aligned and evenly
2074 // fit in its legalized subvector type.
2075 // FIXME: Remove some of the alignment restrictions.
2076 // FIXME: We can use permq for 64-bit or larger extracts from 256-bit
2077 // vectors.
2078 int OrigSubElts = cast<FixedVectorType>(SubTp)->getNumElements();
2079 if (NumSubElts > OrigSubElts && (Index % OrigSubElts) == 0 &&
2080 (NumSubElts % OrigSubElts) == 0 &&
2081 LT.second.getVectorElementType() ==
2082 SubLT.second.getVectorElementType() &&
2083 LT.second.getVectorElementType().getSizeInBits() ==
2084 SrcTy->getElementType()->getPrimitiveSizeInBits()) {
2085 assert(NumElts >= NumSubElts && NumElts > OrigSubElts &&
2086 "Unexpected number of elements!");
2087 auto *VecTy = FixedVectorType::get(SrcTy->getElementType(),
2088 LT.second.getVectorNumElements());
2089 auto *SubTy = FixedVectorType::get(SrcTy->getElementType(),
2090 SubLT.second.getVectorNumElements());
2091 int ExtractIndex = alignDown((Index % NumElts), NumSubElts);
2092 InstructionCost ExtractCost =
2094 ExtractIndex, SubTy);
2095
2096 // If the original size is 32-bits or more, we can use pshufd. Otherwise
2097 // if we have SSSE3 we can use pshufb.
2098 if (SubTp->getPrimitiveSizeInBits() >= 32 || ST->hasSSSE3())
2099 return ExtractCost + 1; // pshufd or pshufb
2100
2101 assert(SubTp->getPrimitiveSizeInBits() == 16 &&
2102 "Unexpected vector size");
2103
2104 return ExtractCost + 2; // worst case pshufhw + pshufd
2105 }
2106 }
2107 // If the extract subvector is not optimal, treat it as single op shuffle.
2109 }
2110
2111 // Subvector insertions are cheap if the subvectors are aligned.
2112 // Note that in general, the insertion starting at the beginning of a vector
2113 // isn't free, because we need to preserve the rest of the wide vector,
2114 // but if the destination vector legalizes to the same width as the subvector
2115 // then the insertion will simplify to a (free) register copy.
2116 if (Kind == TTI::SK_InsertSubvector && LT.second.isVector()) {
2117 std::pair<InstructionCost, MVT> DstLT = getTypeLegalizationCost(DstTy);
2118 int NumElts = DstLT.second.getVectorNumElements();
2119 std::pair<InstructionCost, MVT> SubLT = getTypeLegalizationCost(SubTp);
2120 if (SubLT.second.isVector()) {
2121 int NumSubElts = SubLT.second.getVectorNumElements();
2122 bool MatchingTypes =
2123 NumElts == NumSubElts &&
2124 (SubTp->getElementCount().getKnownMinValue() % NumSubElts) == 0;
2125 if ((Index % NumSubElts) == 0 && (NumElts % NumSubElts) == 0)
2126 return MatchingTypes ? TTI::TCC_Free : SubLT.first;
2127 }
2128
2129 // Attempt to match MOVSS (Idx == 0) or INSERTPS pattern. This will have
2130 // been matched by improveShuffleKindFromMask as a SK_InsertSubvector of
2131 // v1f32 (legalised to f32) into a v4f32.
2132 if (LT.first == 1 && LT.second == MVT::v4f32 && SubLT.first == 1 &&
2133 SubLT.second == MVT::f32 && (Index == 0 || ST->hasSSE41()))
2134 return 1;
2135
2136 // If the insertion is the lowest subvector then it will be blended
2137 // otherwise treat it like a 2-op shuffle.
2138 Kind =
2139 (Index == 0 && LT.first == 1) ? TTI::SK_Select : TTI::SK_PermuteTwoSrc;
2140 }
2141
2142 // Handle some common (illegal) sub-vector types as they are often very cheap
2143 // to shuffle even on targets without PSHUFB.
2144 EVT VT = TLI->getValueType(DL, SrcTy);
2145 if (VT.isSimple() && VT.isVector() && VT.getSizeInBits() < 128 &&
2146 !ST->hasSSSE3()) {
2147 static const CostKindTblEntry SSE2SubVectorShuffleTbl[] = {
2148 {TTI::SK_Broadcast, MVT::v4i16, {1,1,1,1}}, // pshuflw
2149 {TTI::SK_Broadcast, MVT::v2i16, {1,1,1,1}}, // pshuflw
2150 {TTI::SK_Broadcast, MVT::v8i8, {2,2,2,2}}, // punpck/pshuflw
2151 {TTI::SK_Broadcast, MVT::v4i8, {2,2,2,2}}, // punpck/pshuflw
2152 {TTI::SK_Broadcast, MVT::v2i8, {1,1,1,1}}, // punpck
2153
2154 {TTI::SK_Reverse, MVT::v4i16, {1,1,1,1}}, // pshuflw
2155 {TTI::SK_Reverse, MVT::v2i16, {1,1,1,1}}, // pshuflw
2156 {TTI::SK_Reverse, MVT::v4i8, {3,3,3,3}}, // punpck/pshuflw/packus
2157 {TTI::SK_Reverse, MVT::v2i8, {1,1,1,1}}, // punpck
2158
2159 {TTI::SK_Splice, MVT::v4i16, {2,2,2,2}}, // punpck+psrldq
2160 {TTI::SK_Splice, MVT::v2i16, {2,2,2,2}}, // punpck+psrldq
2161 {TTI::SK_Splice, MVT::v4i8, {2,2,2,2}}, // punpck+psrldq
2162 {TTI::SK_Splice, MVT::v2i8, {2,2,2,2}}, // punpck+psrldq
2163
2164 {TTI::SK_PermuteTwoSrc, MVT::v4i16, {2,2,2,2}}, // punpck/pshuflw
2165 {TTI::SK_PermuteTwoSrc, MVT::v2i16, {2,2,2,2}}, // punpck/pshuflw
2166 {TTI::SK_PermuteTwoSrc, MVT::v8i8, {7,7,7,7}}, // punpck/pshuflw
2167 {TTI::SK_PermuteTwoSrc, MVT::v4i8, {4,4,4,4}}, // punpck/pshuflw
2168 {TTI::SK_PermuteTwoSrc, MVT::v2i8, {2,2,2,2}}, // punpck
2169
2170 {TTI::SK_PermuteSingleSrc, MVT::v4i16, {1,1,1,1}}, // pshuflw
2171 {TTI::SK_PermuteSingleSrc, MVT::v2i16, {1,1,1,1}}, // pshuflw
2172 {TTI::SK_PermuteSingleSrc, MVT::v8i8, {5,5,5,5}}, // punpck/pshuflw
2173 {TTI::SK_PermuteSingleSrc, MVT::v4i8, {3,3,3,3}}, // punpck/pshuflw
2174 {TTI::SK_PermuteSingleSrc, MVT::v2i8, {1,1,1,1}}, // punpck
2175 };
2176
2177 if (ST->hasSSE2())
2178 if (const auto *Entry =
2179 CostTableLookup(SSE2SubVectorShuffleTbl, Kind, VT.getSimpleVT()))
2180 if (auto KindCost = Entry->Cost[CostKind])
2181 return LT.first * *KindCost;
2182 }
2183
2184 // We are going to permute multiple sources and the result will be in multiple
2185 // destinations. Providing an accurate cost only for splits where the element
2186 // type remains the same.
2187 if (LT.first != 1) {
2188 MVT LegalVT = LT.second;
2189 if (LegalVT.isVector() &&
2190 LegalVT.getVectorElementType().getSizeInBits() ==
2191 SrcTy->getElementType()->getPrimitiveSizeInBits() &&
2192 LegalVT.getVectorNumElements() <
2193 cast<FixedVectorType>(SrcTy)->getNumElements()) {
2194 unsigned VecTySize = DL.getTypeStoreSize(SrcTy);
2195 unsigned LegalVTSize = LegalVT.getStoreSize();
2196 // Number of source vectors after legalization:
2197 unsigned NumOfSrcs = (VecTySize + LegalVTSize - 1) / LegalVTSize;
2198 // Number of destination vectors after legalization:
2199 InstructionCost NumOfDests = LT.first;
2200
2201 auto *SingleOpTy = FixedVectorType::get(SrcTy->getElementType(),
2202 LegalVT.getVectorNumElements());
2203
2204 if (!Mask.empty() && NumOfDests.isValid()) {
2205 // Try to perform better estimation of the permutation.
2206 // 1. Split the source/destination vectors into real registers.
2207 // 2. Do the mask analysis to identify which real registers are
2208 // permuted. If more than 1 source registers are used for the
2209 // destination register building, the cost for this destination register
2210 // is (Number_of_source_register - 1) * Cost_PermuteTwoSrc. If only one
2211 // source register is used, build mask and calculate the cost as a cost
2212 // of PermuteSingleSrc.
2213 // Also, for the single register permute we try to identify if the
2214 // destination register is just a copy of the source register or the
2215 // copy of the previous destination register (the cost is
2216 // TTI::TCC_Basic). If the source register is just reused, the cost for
2217 // this operation is TTI::TCC_Free.
2218 NumOfDests =
2220 FixedVectorType::get(SrcTy->getElementType(), Mask.size()))
2221 .first;
2222 unsigned E = NumOfDests.getValue();
2223 unsigned NormalizedVF =
2224 LegalVT.getVectorNumElements() * std::max(NumOfSrcs, E);
2225 unsigned NumOfSrcRegs = NormalizedVF / LegalVT.getVectorNumElements();
2226 unsigned NumOfDestRegs = NormalizedVF / LegalVT.getVectorNumElements();
2227 SmallVector<int> NormalizedMask(NormalizedVF, PoisonMaskElem);
2228 copy(Mask, NormalizedMask.begin());
2229 unsigned PrevSrcReg = 0;
2230 ArrayRef<int> PrevRegMask;
2233 NormalizedMask, NumOfSrcRegs, NumOfDestRegs, NumOfDestRegs, []() {},
2234 [this, SingleOpTy, CostKind, &PrevSrcReg, &PrevRegMask,
2235 &Cost](ArrayRef<int> RegMask, unsigned SrcReg, unsigned DestReg) {
2236 if (!ShuffleVectorInst::isIdentityMask(RegMask, RegMask.size())) {
2237 // Check if the previous register can be just copied to the next
2238 // one.
2239 if (PrevRegMask.empty() || PrevSrcReg != SrcReg ||
2240 PrevRegMask != RegMask)
2241 Cost +=
2243 SingleOpTy, CostKind, RegMask, 0, nullptr);
2244 else
2245 // Just a copy of previous destination register.
2247 return;
2248 }
2249 if (SrcReg != DestReg &&
2250 any_of(RegMask, not_equal_to(PoisonMaskElem))) {
2251 // Just a copy of the source register.
2253 }
2254 PrevSrcReg = SrcReg;
2255 PrevRegMask = RegMask;
2256 },
2257 [this, SingleOpTy, CostKind,
2258 &Cost](ArrayRef<int> RegMask, unsigned /*Unused*/,
2259 unsigned /*Unused*/, bool /*Unused*/) {
2261 SingleOpTy, CostKind, RegMask, 0, nullptr);
2262 });
2263 return Cost;
2264 }
2265
2266 InstructionCost NumOfShuffles = (NumOfSrcs - 1) * NumOfDests;
2267 return NumOfShuffles * getShuffleCost(TTI::SK_PermuteTwoSrc, SingleOpTy,
2268 SingleOpTy, CostKind, {}, 0,
2269 nullptr);
2270 }
2271
2272 return BaseT::getShuffleCost(Kind, DstTy, SrcTy, CostKind, Mask, Index,
2273 SubTp);
2274 }
2275
2276 // If we're just moving a single element around (probably as an alternative to
2277 // extracting it), we can assume this is cheap.
2278 if (LT.first == 1 && IsInLaneShuffle && IsSingleElementMask)
2279 return TTI::TCC_Basic;
2280
2281 static const CostKindTblEntry AVX512VBMIShuffleTbl[] = {
2282 { TTI::SK_Reverse, MVT::v64i8, { 1, 1, 1, 1 } }, // vpermb
2283 { TTI::SK_Reverse, MVT::v32i8, { 1, 1, 1, 1 } }, // vpermb
2284 { TTI::SK_PermuteSingleSrc, MVT::v64i8, { 1, 1, 1, 1 } }, // vpermb
2285 { TTI::SK_PermuteSingleSrc, MVT::v32i8, { 1, 1, 1, 1 } }, // vpermb
2286 { TTI::SK_PermuteTwoSrc, MVT::v64i8, { 2, 2, 2, 2 } }, // vpermt2b
2287 { TTI::SK_PermuteTwoSrc, MVT::v32i8, { 2, 2, 2, 2 } }, // vpermt2b
2288 { TTI::SK_PermuteTwoSrc, MVT::v16i8, { 2, 2, 2, 2 } } // vpermt2b
2289 };
2290
2291 if (ST->hasVBMI())
2292 if (const auto *Entry =
2293 CostTableLookup(AVX512VBMIShuffleTbl, Kind, LT.second))
2294 if (auto KindCost = Entry->Cost[CostKind])
2295 return LT.first * *KindCost;
2296
2297 static const CostKindTblEntry AVX512BWShuffleTbl[] = {
2298 { TTI::SK_Broadcast, MVT::v32i16, { 1, 3, 1, 1 } }, // vpbroadcastw
2299 { TTI::SK_Broadcast, MVT::v32f16, { 1, 3, 1, 1 } }, // vpbroadcastw
2300 { TTI::SK_Broadcast, MVT::v64i8, { 1, 3, 1, 1 } }, // vpbroadcastb
2301
2302 { TTI::SK_Reverse, MVT::v32i16, { 2, 6, 2, 4 } }, // vpermw
2303 { TTI::SK_Reverse, MVT::v32f16, { 2, 6, 2, 4 } }, // vpermw
2304 { TTI::SK_Reverse, MVT::v16i16, { 2, 2, 2, 2 } }, // vpermw
2305 { TTI::SK_Reverse, MVT::v16f16, { 2, 2, 2, 2 } }, // vpermw
2306 { TTI::SK_Reverse, MVT::v64i8, { 2, 9, 2, 3 } }, // pshufb + vshufi64x2
2307
2308 { TTI::SK_PermuteSingleSrc, MVT::v32i16, { 2, 2, 2, 2 } }, // vpermw
2309 { TTI::SK_PermuteSingleSrc, MVT::v32f16, { 2, 2, 2, 2 } }, // vpermw
2310 { TTI::SK_PermuteSingleSrc, MVT::v16i16, { 2, 2, 2, 2 } }, // vpermw
2311 { TTI::SK_PermuteSingleSrc, MVT::v16f16, { 2, 2, 2, 2 } }, // vpermw
2312 { TTI::SK_PermuteSingleSrc, MVT::v64i8, { 8, 8, 8, 8 } }, // extend to v32i16
2313
2314 { TTI::SK_PermuteTwoSrc, MVT::v32i16,{ 2, 2, 2, 2 } }, // vpermt2w
2315 { TTI::SK_PermuteTwoSrc, MVT::v32f16,{ 2, 2, 2, 2 } }, // vpermt2w
2316 { TTI::SK_PermuteTwoSrc, MVT::v16i16,{ 2, 2, 2, 2 } }, // vpermt2w
2317 { TTI::SK_PermuteTwoSrc, MVT::v8i16, { 2, 2, 2, 2 } }, // vpermt2w
2318 { TTI::SK_PermuteTwoSrc, MVT::v64i8, { 19, 19, 19, 19 } }, // 6 * v32i8 + 1
2319
2320 { TTI::SK_Select, MVT::v32i16, { 1, 1, 1, 1 } }, // vblendmw
2321 { TTI::SK_Select, MVT::v64i8, { 1, 1, 1, 1 } }, // vblendmb
2322
2323 { TTI::SK_Splice, MVT::v32i16, { 2, 2, 2, 2 } }, // vshufi64x2 + palignr
2324 { TTI::SK_Splice, MVT::v32f16, { 2, 2, 2, 2 } }, // vshufi64x2 + palignr
2325 { TTI::SK_Splice, MVT::v64i8, { 2, 2, 2, 2 } }, // vshufi64x2 + palignr
2326 };
2327
2328 if (ST->hasBWI())
2329 if (const auto *Entry =
2330 CostTableLookup(AVX512BWShuffleTbl, Kind, LT.second))
2331 if (auto KindCost = Entry->Cost[CostKind])
2332 return LT.first * *KindCost;
2333
2334 static const CostKindTblEntry AVX512InLaneShuffleTbl[] = {
2335 {TTI::SK_PermuteTwoSrc, MVT::v8f64, { 1, 3, 1, 1 } },
2336 {TTI::SK_PermuteTwoSrc, MVT::v16f32, { 1, 3, 1, 1 } },
2337 {TTI::SK_PermuteTwoSrc, MVT::v8i64, { 1, 3, 1, 1 } },
2338 {TTI::SK_PermuteTwoSrc, MVT::v16i32, { 1, 3, 1, 1 } },
2339 {TTI::SK_PermuteTwoSrc, MVT::v4f64, { 1, 3, 1, 1 } },
2340 {TTI::SK_PermuteTwoSrc, MVT::v8f32, { 1, 3, 1, 1 } },
2341 {TTI::SK_PermuteTwoSrc, MVT::v4i64, { 1, 3, 1, 1 } },
2342 {TTI::SK_PermuteTwoSrc, MVT::v8i32, { 1, 3, 1, 1 } },
2343 };
2344
2345 if (IsInLaneShuffle && ST->hasAVX512())
2346 if (const auto *Entry =
2347 CostTableLookup(AVX512InLaneShuffleTbl, Kind, LT.second))
2348 if (auto KindCost = Entry->Cost[CostKind])
2349 return LT.first * *KindCost;
2350
2351 static const CostKindTblEntry AVX512ShuffleTbl[] = {
2352 {TTI::SK_Broadcast, MVT::v8f64, { 1, 3, 1, 1 } }, // vbroadcastsd
2353 {TTI::SK_Broadcast, MVT::v4f64, { 1, 3, 1, 1 } }, // vbroadcastsd
2354 {TTI::SK_Broadcast, MVT::v16f32, { 1, 3, 1, 1 } }, // vbroadcastss
2355 {TTI::SK_Broadcast, MVT::v8f32, { 1, 3, 1, 1 } }, // vbroadcastss
2356 {TTI::SK_Broadcast, MVT::v8i64, { 1, 3, 1, 1 } }, // vpbroadcastq
2357 {TTI::SK_Broadcast, MVT::v4i64, { 1, 3, 1, 1 } }, // vpbroadcastq
2358 {TTI::SK_Broadcast, MVT::v16i32, { 1, 3, 1, 1 } }, // vpbroadcastd
2359 {TTI::SK_Broadcast, MVT::v8i32, { 1, 3, 1, 1 } }, // vpbroadcastd
2360 {TTI::SK_Broadcast, MVT::v32i16, { 1, 3, 1, 1 } }, // vpbroadcastw
2361 {TTI::SK_Broadcast, MVT::v16i16, { 1, 3, 1, 1 } }, // vpbroadcastw
2362 {TTI::SK_Broadcast, MVT::v32f16, { 1, 3, 1, 1 } }, // vpbroadcastw
2363 {TTI::SK_Broadcast, MVT::v16f16, { 1, 3, 1, 1 } }, // vpbroadcastw
2364 {TTI::SK_Broadcast, MVT::v64i8, { 1, 3, 1, 1 } }, // vpbroadcastb
2365 {TTI::SK_Broadcast, MVT::v32i8, { 1, 3, 1, 1 }}, // vpbroadcastb
2366
2367 {TTI::SK_Reverse, MVT::v8f64, { 1, 5, 2, 3 } }, // vpermpd
2368 {TTI::SK_Reverse, MVT::v16f32, { 1, 3, 2, 3 } }, // vpermps
2369 {TTI::SK_Reverse, MVT::v8i64, { 1, 5, 2, 3 } }, // vpermq
2370 {TTI::SK_Reverse, MVT::v16i32, { 1, 3, 2, 3 } }, // vpermd
2371 {TTI::SK_Reverse, MVT::v32i16, { 7, 7, 7, 7 } }, // per mca
2372 {TTI::SK_Reverse, MVT::v32f16, { 7, 7, 7, 7 } }, // per mca
2373 {TTI::SK_Reverse, MVT::v64i8, { 7, 7, 7, 7 } }, // per mca
2374
2375 {TTI::SK_Splice, MVT::v8f64, { 1, 1, 1, 1 } }, // vpalignd
2376 {TTI::SK_Splice, MVT::v4f64, { 1, 1, 1, 1 } }, // vpalignd
2377 {TTI::SK_Splice, MVT::v16f32, { 1, 1, 1, 1 } }, // vpalignd
2378 {TTI::SK_Splice, MVT::v8f32, { 1, 1, 1, 1 } }, // vpalignd
2379 {TTI::SK_Splice, MVT::v8i64, { 1, 1, 1, 1 } }, // vpalignd
2380 {TTI::SK_Splice, MVT::v4i64, { 1, 1, 1, 1 } }, // vpalignd
2381 {TTI::SK_Splice, MVT::v16i32, { 1, 1, 1, 1 } }, // vpalignd
2382 {TTI::SK_Splice, MVT::v8i32, { 1, 1, 1, 1 } }, // vpalignd
2383 {TTI::SK_Splice, MVT::v32i16, { 4, 4, 4, 4 } }, // split + palignr
2384 {TTI::SK_Splice, MVT::v32f16, { 4, 4, 4, 4 } }, // split + palignr
2385 {TTI::SK_Splice, MVT::v64i8, { 4, 4, 4, 4 } }, // split + palignr
2386
2387 {TTI::SK_PermuteSingleSrc, MVT::v8f64, { 1, 3, 1, 1 } }, // vpermpd
2388 {TTI::SK_PermuteSingleSrc, MVT::v4f64, { 1, 3, 1, 1 } }, // vpermpd
2389 {TTI::SK_PermuteSingleSrc, MVT::v2f64, { 1, 3, 1, 1 } }, // vpermpd
2390 {TTI::SK_PermuteSingleSrc, MVT::v16f32, { 1, 3, 1, 1 } }, // vpermps
2391 {TTI::SK_PermuteSingleSrc, MVT::v8f32, { 1, 3, 1, 1 } }, // vpermps
2392 {TTI::SK_PermuteSingleSrc, MVT::v4f32, { 1, 3, 1, 1 } }, // vpermps
2393 {TTI::SK_PermuteSingleSrc, MVT::v8i64, { 1, 3, 1, 1 } }, // vpermq
2394 {TTI::SK_PermuteSingleSrc, MVT::v4i64, { 1, 3, 1, 1 } }, // vpermq
2395 {TTI::SK_PermuteSingleSrc, MVT::v2i64, { 1, 3, 1, 1 } }, // vpermq
2396 {TTI::SK_PermuteSingleSrc, MVT::v16i32, { 1, 3, 1, 1 } }, // vpermd
2397 {TTI::SK_PermuteSingleSrc, MVT::v8i32, { 1, 3, 1, 1 } }, // vpermd
2398 {TTI::SK_PermuteSingleSrc, MVT::v4i32, { 1, 3, 1, 1 } }, // vpermd
2399 {TTI::SK_PermuteSingleSrc, MVT::v16i8, { 1, 3, 1, 1 } }, // pshufb
2400
2401 {TTI::SK_PermuteTwoSrc, MVT::v8f64, { 2, 3, 1, 1 } }, // vpermt2pd
2402 {TTI::SK_PermuteTwoSrc, MVT::v16f32, { 2, 3, 1, 1 } }, // vpermt2ps
2403 {TTI::SK_PermuteTwoSrc, MVT::v8i64, { 2, 3, 1, 1 } }, // vpermt2q
2404 {TTI::SK_PermuteTwoSrc, MVT::v16i32, { 2, 3, 1, 1 } }, // vpermt2d
2405 {TTI::SK_PermuteTwoSrc, MVT::v4f64, { 2, 3, 1, 1 } }, // vpermt2pd
2406 {TTI::SK_PermuteTwoSrc, MVT::v8f32, { 2, 3, 1, 1 } }, // vpermt2ps
2407 {TTI::SK_PermuteTwoSrc, MVT::v4i64, { 2, 3, 1, 1 } }, // vpermt2q
2408 {TTI::SK_PermuteTwoSrc, MVT::v8i32, { 2, 3, 1, 1 } }, // vpermt2d
2409 {TTI::SK_PermuteTwoSrc, MVT::v2f64, { 1, 3, 1, 1 } },
2410 {TTI::SK_PermuteTwoSrc, MVT::v4f32, { 1, 3, 1, 1 } },
2411 {TTI::SK_PermuteTwoSrc, MVT::v2i64, { 1, 3, 1, 1 } },
2412 {TTI::SK_PermuteTwoSrc, MVT::v4i32, { 1, 3, 1, 1 } },
2413
2414 // FIXME: This just applies the type legalization cost rules above
2415 // assuming these completely split.
2416 {TTI::SK_PermuteSingleSrc, MVT::v32i16, { 14, 14, 14, 14 } },
2417 {TTI::SK_PermuteSingleSrc, MVT::v32f16, { 14, 14, 14, 14 } },
2418 {TTI::SK_PermuteSingleSrc, MVT::v64i8, { 14, 14, 14, 14 } },
2419 {TTI::SK_PermuteTwoSrc, MVT::v32i16, { 42, 42, 42, 42 } },
2420 {TTI::SK_PermuteTwoSrc, MVT::v32f16, { 42, 42, 42, 42 } },
2421 {TTI::SK_PermuteTwoSrc, MVT::v64i8, { 42, 42, 42, 42 } },
2422
2423 {TTI::SK_Select, MVT::v32i16, { 1, 1, 1, 1 } }, // vpternlogq
2424 {TTI::SK_Select, MVT::v32f16, { 1, 1, 1, 1 } }, // vpternlogq
2425 {TTI::SK_Select, MVT::v64i8, { 1, 1, 1, 1 } }, // vpternlogq
2426 {TTI::SK_Select, MVT::v8f64, { 1, 1, 1, 1 } }, // vblendmpd
2427 {TTI::SK_Select, MVT::v16f32, { 1, 1, 1, 1 } }, // vblendmps
2428 {TTI::SK_Select, MVT::v8i64, { 1, 1, 1, 1 } }, // vblendmq
2429 {TTI::SK_Select, MVT::v16i32, { 1, 1, 1, 1 } }, // vblendmd
2430 };
2431
2432 if (ST->hasAVX512())
2433 if (const auto *Entry = CostTableLookup(AVX512ShuffleTbl, Kind, LT.second))
2434 if (auto KindCost = Entry->Cost[CostKind])
2435 return LT.first * *KindCost;
2436
2437 static const CostKindTblEntry AVX2InLaneShuffleTbl[] = {
2438 { TTI::SK_PermuteSingleSrc, MVT::v16i16, { 1, 1, 1, 1 } }, // vpshufb
2439 { TTI::SK_PermuteSingleSrc, MVT::v16f16, { 1, 1, 1, 1 } }, // vpshufb
2440 { TTI::SK_PermuteSingleSrc, MVT::v32i8, { 1, 1, 1, 1 } }, // vpshufb
2441
2442 { TTI::SK_Transpose, MVT::v4f64, { 1, 1, 1, 1 } }, // vshufpd/vunpck
2443 { TTI::SK_Transpose, MVT::v4i64, { 1, 1, 1, 1 } }, // vshufpd/vunpck
2444
2445 { TTI::SK_PermuteTwoSrc, MVT::v4f64, { 2, 2, 2, 2 } }, // 2*vshufpd + vblendpd
2446 { TTI::SK_PermuteTwoSrc, MVT::v8f32, { 2, 2, 2, 2 } }, // 2*vshufps + vblendps
2447 { TTI::SK_PermuteTwoSrc, MVT::v4i64, { 2, 2, 2, 2 } }, // 2*vpshufd + vpblendd
2448 { TTI::SK_PermuteTwoSrc, MVT::v8i32, { 2, 2, 2, 2 } }, // 2*vpshufd + vpblendd
2449 { TTI::SK_PermuteTwoSrc, MVT::v16i16, { 2, 2, 2, 2 } }, // 2*vpshufb + vpor
2450 { TTI::SK_PermuteTwoSrc, MVT::v16f16, { 2, 2, 2, 2 } }, // 2*vpshufb + vpor
2451 { TTI::SK_PermuteTwoSrc, MVT::v32i8, { 2, 2, 2, 2 } }, // 2*vpshufb + vpor
2452 };
2453
2454 if (IsInLaneShuffle && ST->hasAVX2())
2455 if (const auto *Entry =
2456 CostTableLookup(AVX2InLaneShuffleTbl, Kind, LT.second))
2457 if (auto KindCost = Entry->Cost[CostKind])
2458 return LT.first * *KindCost;
2459
2460 static const CostKindTblEntry AVX2ShuffleTbl[] = {
2461 { TTI::SK_Broadcast, MVT::v4f64, { 1, 3, 1, 2 } }, // vbroadcastpd
2462 { TTI::SK_Broadcast, MVT::v8f32, { 1, 3, 1, 2 } }, // vbroadcastps
2463 { TTI::SK_Broadcast, MVT::v4i64, { 1, 3, 1, 2 } }, // vpbroadcastq
2464 { TTI::SK_Broadcast, MVT::v8i32, { 1, 3, 1, 2 } }, // vpbroadcastd
2465 { TTI::SK_Broadcast, MVT::v16i16, { 1, 3, 1, 2 } }, // vpbroadcastw
2466 { TTI::SK_Broadcast, MVT::v8i16, { 1, 3, 1, 1 } }, // vpbroadcastw
2467 { TTI::SK_Broadcast, MVT::v16f16, { 1, 3, 1, 2 } }, // vpbroadcastw
2468 { TTI::SK_Broadcast, MVT::v8f16, { 1, 3, 1, 1 } }, // vpbroadcastw
2469 { TTI::SK_Broadcast, MVT::v32i8, { 1, 3, 1, 2 } }, // vpbroadcastb
2470 { TTI::SK_Broadcast, MVT::v16i8, { 1, 3, 1, 1 } }, // vpbroadcastb
2471
2472 { TTI::SK_Reverse, MVT::v4f64, { 1, 6, 1, 2 } }, // vpermpd
2473 { TTI::SK_Reverse, MVT::v8f32, { 2, 7, 2, 4 } }, // vpermps
2474 { TTI::SK_Reverse, MVT::v4i64, { 1, 6, 1, 2 } }, // vpermq
2475 { TTI::SK_Reverse, MVT::v8i32, { 2, 7, 2, 4 } }, // vpermd
2476 { TTI::SK_Reverse, MVT::v16i16, { 2, 9, 2, 4 } }, // vperm2i128 + pshufb
2477 { TTI::SK_Reverse, MVT::v16f16, { 2, 9, 2, 4 } }, // vperm2i128 + pshufb
2478 { TTI::SK_Reverse, MVT::v32i8, { 2, 9, 2, 4 } }, // vperm2i128 + pshufb
2479
2480 { TTI::SK_Select, MVT::v16i16, { 1, 1, 1, 1 } }, // vpblendvb
2481 { TTI::SK_Select, MVT::v16f16, { 1, 1, 1, 1 } }, // vpblendvb
2482 { TTI::SK_Select, MVT::v32i8, { 1, 1, 1, 1 } }, // vpblendvb
2483
2484 { TTI::SK_Splice, MVT::v8i32, { 2, 2, 2, 2 } }, // vperm2i128 + vpalignr
2485 { TTI::SK_Splice, MVT::v8f32, { 2, 2, 2, 2 } }, // vperm2i128 + vpalignr
2486 { TTI::SK_Splice, MVT::v16i16, { 2, 2, 2, 2 } }, // vperm2i128 + vpalignr
2487 { TTI::SK_Splice, MVT::v16f16, { 2, 2, 2, 2 } }, // vperm2i128 + vpalignr
2488 { TTI::SK_Splice, MVT::v32i8, { 2, 2, 2, 2 } }, // vperm2i128 + vpalignr
2489
2490 { TTI::SK_PermuteSingleSrc, MVT::v4f64, { 1, 1, 1, 1 } }, // vpermpd
2491 { TTI::SK_PermuteSingleSrc, MVT::v8f32, { 1, 1, 1, 1 } }, // vpermps
2492 { TTI::SK_PermuteSingleSrc, MVT::v4i64, { 1, 1, 1, 1 } }, // vpermq
2493 { TTI::SK_PermuteSingleSrc, MVT::v8i32, { 1, 1, 1, 1 } }, // vpermd
2494 { TTI::SK_PermuteSingleSrc, MVT::v16i16, { 4, 4, 4, 4 } },
2495 { TTI::SK_PermuteSingleSrc, MVT::v16f16, { 4, 4, 4, 4 } },
2496 { TTI::SK_PermuteSingleSrc, MVT::v32i8, { 4, 4, 4, 4 } },
2497
2498 { TTI::SK_PermuteTwoSrc, MVT::v4f64, { 3, 3, 3, 3 } }, // 2*vpermpd + vblendpd
2499 { TTI::SK_PermuteTwoSrc, MVT::v8f32, { 3, 3, 3, 3 } }, // 2*vpermps + vblendps
2500 { TTI::SK_PermuteTwoSrc, MVT::v4i64, { 3, 3, 3, 3 } }, // 2*vpermq + vpblendd
2501 { TTI::SK_PermuteTwoSrc, MVT::v8i32, { 3, 3, 3, 3 } }, // 2*vpermd + vpblendd
2502 { TTI::SK_PermuteTwoSrc, MVT::v16i16, { 7, 7, 7, 7 } },
2503 { TTI::SK_PermuteTwoSrc, MVT::v16f16, { 7, 7, 7, 7 } },
2504 { TTI::SK_PermuteTwoSrc, MVT::v32i8, { 7, 7, 7, 7 } },
2505 };
2506
2507 if (ST->hasAVX2())
2508 if (const auto *Entry = CostTableLookup(AVX2ShuffleTbl, Kind, LT.second))
2509 if (auto KindCost = Entry->Cost[CostKind])
2510 return LT.first * *KindCost;
2511
2512 static const CostKindTblEntry XOPShuffleTbl[] = {
2513 { TTI::SK_PermuteSingleSrc, MVT::v4f64, { 2, 2, 2, 2 } }, // vperm2f128 + vpermil2pd
2514 { TTI::SK_PermuteSingleSrc, MVT::v8f32, { 2, 2, 2, 2 } }, // vperm2f128 + vpermil2ps
2515 { TTI::SK_PermuteSingleSrc, MVT::v4i64, { 2, 2, 2, 2 } }, // vperm2f128 + vpermil2pd
2516 { TTI::SK_PermuteSingleSrc, MVT::v8i32, { 2, 2, 2, 2 } }, // vperm2f128 + vpermil2ps
2517 { TTI::SK_PermuteSingleSrc, MVT::v16i16,{ 4, 4, 4, 4 } }, // vextractf128 + 2*vpperm
2518 // + vinsertf128
2519 { TTI::SK_PermuteSingleSrc, MVT::v32i8, { 4, 4, 4, 4 } }, // vextractf128 + 2*vpperm
2520 // + vinsertf128
2521
2522 { TTI::SK_PermuteTwoSrc, MVT::v16i16, { 9, 9, 9, 9 } }, // 2*vextractf128 + 6*vpperm
2523 // + vinsertf128
2524
2525 { TTI::SK_PermuteTwoSrc, MVT::v8i16, { 1, 1, 1, 1 } }, // vpperm
2526 { TTI::SK_PermuteTwoSrc, MVT::v32i8, { 9, 9, 9, 9 } }, // 2*vextractf128 + 6*vpperm
2527 // + vinsertf128
2528 { TTI::SK_PermuteTwoSrc, MVT::v16i8, { 1, 1, 1, 1 } }, // vpperm
2529 };
2530
2531 if (ST->hasXOP())
2532 if (const auto *Entry = CostTableLookup(XOPShuffleTbl, Kind, LT.second))
2533 if (auto KindCost = Entry->Cost[CostKind])
2534 return LT.first * *KindCost;
2535
2536 static const CostKindTblEntry AVX1InLaneShuffleTbl[] = {
2537 { TTI::SK_PermuteSingleSrc, MVT::v4f64, { 1, 1, 1, 1 } }, // vpermilpd
2538 { TTI::SK_PermuteSingleSrc, MVT::v4i64, { 1, 1, 1, 1 } }, // vpermilpd
2539 { TTI::SK_PermuteSingleSrc, MVT::v8f32, { 1, 1, 1, 1 } }, // vpermilps
2540 { TTI::SK_PermuteSingleSrc, MVT::v8i32, { 1, 1, 1, 1 } }, // vpermilps
2541
2542 { TTI::SK_PermuteSingleSrc, MVT::v16i16, { 4, 4, 4, 4 } }, // vextractf128 + 2*pshufb
2543 // + vpor + vinsertf128
2544 { TTI::SK_PermuteSingleSrc, MVT::v16f16, { 4, 4, 4, 4 } }, // vextractf128 + 2*pshufb
2545 // + vpor + vinsertf128
2546 { TTI::SK_PermuteSingleSrc, MVT::v32i8, { 4, 4, 4, 4 } }, // vextractf128 + 2*pshufb
2547 // + vpor + vinsertf128
2548
2549 { TTI::SK_Transpose, MVT::v4f64, { 1, 1, 1, 1 } }, // vshufpd/vunpck
2550 { TTI::SK_Transpose, MVT::v4i64, { 1, 1, 1, 1 } }, // vshufpd/vunpck
2551
2552 { TTI::SK_PermuteTwoSrc, MVT::v4f64, { 2, 2, 2, 2 } }, // 2*vshufpd + vblendpd
2553 { TTI::SK_PermuteTwoSrc, MVT::v8f32, { 2, 2, 2, 2 } }, // 2*vshufps + vblendps
2554 { TTI::SK_PermuteTwoSrc, MVT::v4i64, { 2, 2, 2, 2 } }, // 2*vpermilpd + vblendpd
2555 { TTI::SK_PermuteTwoSrc, MVT::v8i32, { 2, 2, 2, 2 } }, // 2*vpermilps + vblendps
2556 { TTI::SK_PermuteTwoSrc, MVT::v16i16, { 9, 9, 9, 9 } }, // 2*vextractf128 + 4*pshufb
2557 // + 2*vpor + vinsertf128
2558 { TTI::SK_PermuteTwoSrc, MVT::v16f16, { 9, 9, 9, 9 } }, // 2*vextractf128 + 4*pshufb
2559 // + 2*vpor + vinsertf128
2560 { TTI::SK_PermuteTwoSrc, MVT::v32i8, { 9, 9, 9, 9 } }, // 2*vextractf128 + 4*pshufb
2561 // + 2*vpor + vinsertf128
2562 };
2563
2564 if (IsInLaneShuffle && ST->hasAVX())
2565 if (const auto *Entry =
2566 CostTableLookup(AVX1InLaneShuffleTbl, Kind, LT.second))
2567 if (auto KindCost = Entry->Cost[CostKind])
2568 return LT.first * *KindCost;
2569
2570 static const CostKindTblEntry AVX1ShuffleTbl[] = {
2571 {TTI::SK_Broadcast, MVT::v4f64, {2,3,2,3}}, // vperm2f128 + vpermilpd
2572 {TTI::SK_Broadcast, MVT::v8f32, {2,3,2,3}}, // vperm2f128 + vpermilps
2573 {TTI::SK_Broadcast, MVT::v4i64, {2,3,2,3}}, // vperm2f128 + vpermilpd
2574 {TTI::SK_Broadcast, MVT::v8i32, {2,3,2,3}}, // vperm2f128 + vpermilps
2575 {TTI::SK_Broadcast, MVT::v16i16, {2,3,3,4}}, // vpshuflw + vpshufd + vinsertf128
2576 {TTI::SK_Broadcast, MVT::v16f16, {2,3,3,4}}, // vpshuflw + vpshufd + vinsertf128
2577 {TTI::SK_Broadcast, MVT::v32i8, {3,4,3,6}}, // vpshufb + vinsertf128
2578
2579 {TTI::SK_Reverse, MVT::v4f64, {2,6,2,2}}, // vperm2f128 + vpermilpd
2580 {TTI::SK_Reverse, MVT::v8f32, {2,7,2,4}}, // vperm2f128 + vpermilps
2581 {TTI::SK_Reverse, MVT::v4i64, {2,6,2,2}}, // vperm2f128 + vpermilpd
2582 {TTI::SK_Reverse, MVT::v8i32, {2,7,2,4}}, // vperm2f128 + vpermilps
2583 {TTI::SK_Reverse, MVT::v16i16, {2,9,5,5}}, // vextractf128 + 2*pshufb
2584 // + vinsertf128
2585 {TTI::SK_Reverse, MVT::v16f16, {2,9,5,5}}, // vextractf128 + 2*pshufb
2586 // + vinsertf128
2587 {TTI::SK_Reverse, MVT::v32i8, {2,9,5,5}}, // vextractf128 + 2*pshufb
2588 // + vinsertf128
2589
2590 {TTI::SK_Select, MVT::v4i64, {1,1,1,1}}, // vblendpd
2591 {TTI::SK_Select, MVT::v4f64, {1,1,1,1}}, // vblendpd
2592 {TTI::SK_Select, MVT::v8i32, {1,1,1,1}}, // vblendps
2593 {TTI::SK_Select, MVT::v8f32, {1,1,1,1}}, // vblendps
2594 {TTI::SK_Select, MVT::v16i16, {3,3,3,3}}, // vpand + vpandn + vpor
2595 {TTI::SK_Select, MVT::v16f16, {3,3,3,3}}, // vpand + vpandn + vpor
2596 {TTI::SK_Select, MVT::v32i8, {3,3,3,3}}, // vpand + vpandn + vpor
2597
2598 {TTI::SK_Splice, MVT::v4i64, {2,2,2,2}}, // vperm2f128 + shufpd
2599 {TTI::SK_Splice, MVT::v4f64, {2,2,2,2}}, // vperm2f128 + shufpd
2600 {TTI::SK_Splice, MVT::v8i32, {4,4,4,4}}, // 2*vperm2f128 + 2*vshufps
2601 {TTI::SK_Splice, MVT::v8f32, {4,4,4,4}}, // 2*vperm2f128 + 2*vshufps
2602 {TTI::SK_Splice, MVT::v16i16, {5,5,5,5}}, // 2*vperm2f128 + 2*vpalignr + vinsertf128
2603 {TTI::SK_Splice, MVT::v16f16, {5,5,5,5}}, // 2*vperm2f128 + 2*vpalignr + vinsertf128
2604 {TTI::SK_Splice, MVT::v32i8, {5,5,5,5}}, // 2*vperm2f128 + 2*vpalignr + vinsertf128
2605
2606 {TTI::SK_PermuteSingleSrc, MVT::v4f64, {2,2,2,2}}, // vperm2f128 + vshufpd
2607 {TTI::SK_PermuteSingleSrc, MVT::v4i64, {2,2,2,2}}, // vperm2f128 + vshufpd
2608 {TTI::SK_PermuteSingleSrc, MVT::v8f32, {4,4,4,4}}, // 2*vperm2f128 + 2*vshufps
2609 {TTI::SK_PermuteSingleSrc, MVT::v8i32, {4,4,4,4}}, // 2*vperm2f128 + 2*vshufps
2610 {TTI::SK_PermuteSingleSrc, MVT::v16i16,{8,8,8,8}}, // vextractf128 + 4*pshufb
2611 // + 2*por + vinsertf128
2612 {TTI::SK_PermuteSingleSrc, MVT::v16f16,{8,8,8,8}}, // vextractf128 + 4*pshufb
2613 // + 2*por + vinsertf128
2614 {TTI::SK_PermuteSingleSrc, MVT::v32i8, {8,8,8,8}}, // vextractf128 + 4*pshufb
2615 // + 2*por + vinsertf128
2616
2617 {TTI::SK_PermuteTwoSrc, MVT::v4f64, {3,3,3,3}}, // 2*vperm2f128 + vshufpd
2618 {TTI::SK_PermuteTwoSrc, MVT::v4i64, {3,3,3,3}}, // 2*vperm2f128 + vshufpd
2619 {TTI::SK_PermuteTwoSrc, MVT::v8f32, {4,4,4,4}}, // 2*vperm2f128 + 2*vshufps
2620 {TTI::SK_PermuteTwoSrc, MVT::v8i32, {4,4,4,4}}, // 2*vperm2f128 + 2*vshufps
2621 {TTI::SK_PermuteTwoSrc, MVT::v16i16,{15,15,15,15}}, // 2*vextractf128 + 8*pshufb
2622 // + 4*por + vinsertf128
2623 {TTI::SK_PermuteTwoSrc, MVT::v16f16,{15,15,15,15}}, // 2*vextractf128 + 8*pshufb
2624 // + 4*por + vinsertf128
2625 {TTI::SK_PermuteTwoSrc, MVT::v32i8, {15,15,15,15}}, // 2*vextractf128 + 8*pshufb
2626 // + 4*por + vinsertf128
2627 };
2628
2629 if (ST->hasAVX())
2630 if (const auto *Entry = CostTableLookup(AVX1ShuffleTbl, Kind, LT.second))
2631 if (auto KindCost = Entry->Cost[CostKind])
2632 return LT.first * *KindCost;
2633
2634 static const CostKindTblEntry SSE41ShuffleTbl[] = {
2635 {TTI::SK_Select, MVT::v2i64, {1,1,1,1}}, // pblendw
2636 {TTI::SK_Select, MVT::v2f64, {1,1,1,1}}, // movsd
2637 {TTI::SK_Select, MVT::v4i32, {1,1,1,1}}, // pblendw
2638 {TTI::SK_Select, MVT::v4f32, {1,1,1,1}}, // blendps
2639 {TTI::SK_Select, MVT::v8i16, {1,1,1,1}}, // pblendw
2640 {TTI::SK_Select, MVT::v8f16, {1,1,1,1}}, // pblendw
2641 {TTI::SK_Select, MVT::v16i8, {1,1,1,1}} // pblendvb
2642 };
2643
2644 if (ST->hasSSE41())
2645 if (const auto *Entry = CostTableLookup(SSE41ShuffleTbl, Kind, LT.second))
2646 if (auto KindCost = Entry->Cost[CostKind])
2647 return LT.first * *KindCost;
2648
2649 static const CostKindTblEntry SSSE3ShuffleTbl[] = {
2650 {TTI::SK_Broadcast, MVT::v8i16, {1, 3, 2, 2}}, // pshufb
2651 {TTI::SK_Broadcast, MVT::v8f16, {1, 3, 2, 2}}, // pshufb
2652 {TTI::SK_Broadcast, MVT::v16i8, {1, 3, 2, 2}}, // pshufb
2653
2654 {TTI::SK_Reverse, MVT::v8i16, {1, 2, 1, 2}}, // pshufb
2655 {TTI::SK_Reverse, MVT::v8f16, {1, 2, 1, 2}}, // pshufb
2656 {TTI::SK_Reverse, MVT::v16i8, {1, 2, 1, 2}}, // pshufb
2657
2658 {TTI::SK_Splice, MVT::v4i32, {1, 1, 1, 1}}, // palignr
2659 {TTI::SK_Splice, MVT::v4f32, {1, 1, 1, 1}}, // palignr
2660 {TTI::SK_Splice, MVT::v8i16, {1, 1, 1, 1}}, // palignr
2661 {TTI::SK_Splice, MVT::v8f16, {1, 1, 1, 1}}, // palignr
2662 {TTI::SK_Splice, MVT::v16i8, {1, 1, 1, 1}}, // palignr
2663
2664 {TTI::SK_PermuteSingleSrc, MVT::v8i16, {1, 1, 1, 1}}, // pshufb
2665 {TTI::SK_PermuteSingleSrc, MVT::v8f16, {1, 1, 1, 1}}, // pshufb
2666 {TTI::SK_PermuteSingleSrc, MVT::v16i8, {1, 1, 1, 1}}, // pshufb
2667
2668 {TTI::SK_PermuteTwoSrc, MVT::v8i16, {3, 3, 3, 3}}, // 2*pshufb + por
2669 {TTI::SK_PermuteTwoSrc, MVT::v8f16, {3, 3, 3, 3}}, // 2*pshufb + por
2670 {TTI::SK_PermuteTwoSrc, MVT::v16i8, {3, 3, 3, 3}}, // 2*pshufb + por
2671 };
2672
2673 if (ST->hasSSSE3())
2674 if (const auto *Entry = CostTableLookup(SSSE3ShuffleTbl, Kind, LT.second))
2675 if (auto KindCost = Entry->Cost[CostKind])
2676 return LT.first * *KindCost;
2677
2678 static const CostKindTblEntry SSE2ShuffleTbl[] = {
2679 {TTI::SK_Broadcast, MVT::v2f64, {1, 1, 1, 1}}, // shufpd
2680 {TTI::SK_Broadcast, MVT::v2i64, {1, 1, 1, 1}}, // pshufd
2681 {TTI::SK_Broadcast, MVT::v4i32, {1, 1, 1, 1}}, // pshufd
2682 {TTI::SK_Broadcast, MVT::v8i16, {1, 2, 2, 2}}, // pshuflw + pshufd
2683 {TTI::SK_Broadcast, MVT::v8f16, {1, 2, 2, 2}}, // pshuflw + pshufd
2684 {TTI::SK_Broadcast, MVT::v16i8, {2, 3, 3, 4}}, // unpck + pshuflw + pshufd
2685
2686 {TTI::SK_Reverse, MVT::v2f64, {1, 1, 1, 1}}, // shufpd
2687 {TTI::SK_Reverse, MVT::v2i64, {1, 1, 1, 1}}, // pshufd
2688 {TTI::SK_Reverse, MVT::v4i32, {1, 1, 1, 1}}, // pshufd
2689 {TTI::SK_Reverse, MVT::v8i16, {2, 3, 3, 3}}, // pshuflw + pshufhw + pshufd
2690 {TTI::SK_Reverse, MVT::v8f16, {2, 3, 3, 3}}, // pshuflw + pshufhw + pshufd
2691 {TTI::SK_Reverse, MVT::v16i8, {5, 6,11,11}}, // 2*pshuflw + 2*pshufhw
2692 // + 2*pshufd + 2*unpck + packus
2693
2694 {TTI::SK_Select, MVT::v2i64, {1, 1, 1, 1}}, // movsd
2695 {TTI::SK_Select, MVT::v2f64, {1, 1, 1, 1}}, // movsd
2696 {TTI::SK_Select, MVT::v4i32, {2, 2, 2, 2}}, // 2*shufps
2697 {TTI::SK_Select, MVT::v8i16, {2, 2, 3, 3}}, // pand + pandn + por
2698 {TTI::SK_Select, MVT::v8f16, {2, 2, 3, 3}}, // pand + pandn + por
2699 {TTI::SK_Select, MVT::v16i8, {2, 2, 3, 3}}, // pand + pandn + por
2700
2701 {TTI::SK_Splice, MVT::v2i64, {1, 1, 1, 1}}, // shufpd
2702 {TTI::SK_Splice, MVT::v2f64, {1, 1, 1, 1}}, // shufpd
2703 {TTI::SK_Splice, MVT::v4i32, {2, 2, 2, 2}}, // 2*{unpck,movsd,pshufd}
2704 {TTI::SK_Splice, MVT::v8i16, {3, 3, 3, 3}}, // psrldq + psrlldq + por
2705 {TTI::SK_Splice, MVT::v8f16, {3, 3, 3, 3}}, // psrldq + psrlldq + por
2706 {TTI::SK_Splice, MVT::v16i8, {3, 3, 3, 3}}, // psrldq + psrlldq + por
2707
2708 {TTI::SK_PermuteSingleSrc, MVT::v2f64, {1, 1, 1, 1}}, // shufpd
2709 {TTI::SK_PermuteSingleSrc, MVT::v2i64, {1, 1, 1, 1}}, // pshufd
2710 {TTI::SK_PermuteSingleSrc, MVT::v4i32, {1, 1, 1, 1}}, // pshufd
2711 {TTI::SK_PermuteSingleSrc, MVT::v8i16, {3, 5, 5, 5}}, // 2*pshuflw + 2*pshufhw
2712 // + pshufd/unpck
2713 {TTI::SK_PermuteSingleSrc, MVT::v8f16, {3, 5, 5, 5}}, // 2*pshuflw + 2*pshufhw
2714 // + pshufd/unpck
2715 {TTI::SK_PermuteSingleSrc, MVT::v16i8, {8, 10, 10, 10}}, // 2*pshuflw + 2*pshufhw
2716 // + 2*pshufd + 2*unpck + 2*packus
2717
2718 {TTI::SK_PermuteTwoSrc, MVT::v2f64, {1, 1, 1, 1}}, // shufpd
2719 {TTI::SK_PermuteTwoSrc, MVT::v2i64, {1, 1, 1, 1}}, // shufpd
2720 {TTI::SK_PermuteTwoSrc, MVT::v4i32, {2, 2, 2, 2}}, // 2*{unpck,movsd,pshufd}
2721 {TTI::SK_PermuteTwoSrc, MVT::v8i16, {6, 8, 8, 8}}, // blend+permute
2722 {TTI::SK_PermuteTwoSrc, MVT::v8f16, {6, 8, 8, 8}}, // blend+permute
2723 {TTI::SK_PermuteTwoSrc, MVT::v16i8, {11, 13, 13, 13}}, // blend+permute
2724 };
2725
2726 static const CostTblEntry SSE3BroadcastLoadTbl[] = {
2727 {TTI::SK_Broadcast, MVT::v2f64, 0}, // broadcast handled by movddup
2728 };
2729
2730 if (ST->hasSSE2()) {
2731 bool IsLoad =
2732 llvm::any_of(Args, [](const auto &V) { return isa<LoadInst>(V); });
2733 if (ST->hasSSE3() && IsLoad)
2734 if (const auto *Entry =
2735 CostTableLookup(SSE3BroadcastLoadTbl, Kind, LT.second)) {
2736 assert(isLegalBroadcastLoad(SrcTy->getElementType(),
2737 LT.second.getVectorElementCount()) &&
2738 "Table entry missing from isLegalBroadcastLoad()");
2739 return LT.first * Entry->Cost;
2740 }
2741
2742 if (const auto *Entry = CostTableLookup(SSE2ShuffleTbl, Kind, LT.second))
2743 if (auto KindCost = Entry->Cost[CostKind])
2744 return LT.first * *KindCost;
2745 }
2746
2747 static const CostKindTblEntry SSE1ShuffleTbl[] = {
2748 { TTI::SK_Broadcast, MVT::v4f32, {1,1,1,1} }, // shufps
2749 { TTI::SK_Reverse, MVT::v4f32, {1,1,1,1} }, // shufps
2750 { TTI::SK_Select, MVT::v4f32, {2,2,2,2} }, // 2*shufps
2751 { TTI::SK_Splice, MVT::v4f32, {2,2,2,2} }, // 2*shufps
2752 { TTI::SK_PermuteSingleSrc, MVT::v4f32, {1,1,1,1} }, // shufps
2753 { TTI::SK_PermuteTwoSrc, MVT::v4f32, {2,2,2,2} }, // 2*shufps
2754 };
2755
2756 if (ST->hasSSE1()) {
2757 if (LT.first == 1 && LT.second == MVT::v4f32 && Mask.size() == 4) {
2758 // SHUFPS: both pairs must come from the same source register.
2759 auto MatchSHUFPS = [](int X, int Y) {
2760 return X < 0 || Y < 0 || ((X & 4) == (Y & 4));
2761 };
2762 if (MatchSHUFPS(Mask[0], Mask[1]) && MatchSHUFPS(Mask[2], Mask[3]))
2763 return 1;
2764 }
2765 if (const auto *Entry = CostTableLookup(SSE1ShuffleTbl, Kind, LT.second))
2766 if (auto KindCost = Entry->Cost[CostKind])
2767 return LT.first * *KindCost;
2768 }
2769
2770 return BaseT::getShuffleCost(Kind, DstTy, SrcTy, CostKind, Mask, Index,
2771 SubTp);
2772}
2773
2775 Type *Src,
2778 const Instruction *I) const {
2779 int ISD = TLI->InstructionOpcodeToISD(Opcode);
2780 assert(ISD && "Invalid opcode");
2781
2782 // A narrow (i8/i16) zero-extension used as a GEP *index* can be folded into
2783 // the addressing mode of the consuming memory op, but only if the source is
2784 // already materialised zero-extended in a full register. X86's SIB form
2785 // [base + index*scale + disp] reads the index at full width and does NOT
2786 // zero-extend a narrow index (unlike AArch64's uxtw-extended addressing), so
2787 // a "dirty" narrow source (e.g. an i16 add result used only as an index)
2788 // still needs a dedicated movzx and is not free. Price it as free only with
2789 // positive evidence that no movzx is required.
2790 if (ISD == ISD::ZERO_EXTEND && I && I->hasOneUse() && Src->isIntegerTy() &&
2791 Src->getScalarSizeInBits() < 32) {
2792 const Use &U = *I->use_begin();
2793 if (isa<GetElementPtrInst>(U.getUser()) &&
2794 U.getOperandNo() != GetElementPtrInst::getPointerOperandIndex()) {
2795 const Value *Op = I->getOperand(0);
2796 // Clean sources: an extending load, a zeroext argument, or a value whose
2797 // high bits are provably zero (e.g. from a shift/mask). These mirror the
2798 // proof-based reasoning the middle end uses elsewhere (ValueTracking and
2799 // InstCombine's canEvaluateZExtd); we intentionally do NOT treat a merely
2800 // multiply-used operand as clean, since that is a guess rather than
2801 // proof.
2802 if (isa<LoadInst>(Op))
2803 return TTI::TCC_Free;
2804 if (const auto *A = dyn_cast<Argument>(Op))
2805 if (A->hasAttribute(Attribute::ZExt))
2806 return TTI::TCC_Free;
2807 if (computeKnownBits(Op, I->getDataLayout(), /*AC=*/nullptr, I)
2808 .countMinLeadingZeros() > 0)
2809 return TTI::TCC_Free;
2810 }
2811 }
2812
2813 // The cost tables include both specific, custom (non-legal) src/dst type
2814 // conversions and generic, legalized types. We test for customs first, before
2815 // falling back to legalization.
2816 // FIXME: Need a better design of the cost table to handle non-simple types of
2817 // potential massive combinations (elem_num x src_type x dst_type).
2818 static const TypeConversionCostKindTblEntry AVX512BWConversionTbl[]{
2819 { ISD::SIGN_EXTEND, MVT::v32i16, MVT::v32i8, { 1, 1, 1, 1 } },
2820 { ISD::ZERO_EXTEND, MVT::v32i16, MVT::v32i8, { 1, 1, 1, 1 } },
2821
2822 // Mask sign extend has an instruction.
2823 { ISD::SIGN_EXTEND, MVT::v2i8, MVT::v2i1, { 1, 1, 1, 1 } },
2824 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v2i1, { 1, 1, 1, 1 } },
2825 { ISD::SIGN_EXTEND, MVT::v2i16, MVT::v2i1, { 1, 1, 1, 1 } },
2826 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v2i1, { 1, 1, 1, 1 } },
2827 { ISD::SIGN_EXTEND, MVT::v4i8, MVT::v4i1, { 1, 1, 1, 1 } },
2828 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v4i1, { 1, 1, 1, 1 } },
2829 { ISD::SIGN_EXTEND, MVT::v4i16, MVT::v4i1, { 1, 1, 1, 1 } },
2830 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v4i1, { 1, 1, 1, 1 } },
2831 { ISD::SIGN_EXTEND, MVT::v8i8, MVT::v8i1, { 1, 1, 1, 1 } },
2832 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v8i1, { 1, 1, 1, 1 } },
2833 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v8i1, { 1, 1, 1, 1 } },
2834 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v16i1, { 1, 1, 1, 1 } },
2835 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i1, { 1, 1, 1, 1 } },
2836 { ISD::SIGN_EXTEND, MVT::v32i8, MVT::v32i1, { 1, 1, 1, 1 } },
2837 { ISD::SIGN_EXTEND, MVT::v32i16, MVT::v32i1, { 1, 1, 1, 1 } },
2838 { ISD::SIGN_EXTEND, MVT::v64i8, MVT::v64i1, { 1, 1, 1, 1 } },
2839 { ISD::SIGN_EXTEND, MVT::v32i16, MVT::v64i1, { 1, 1, 1, 1 } },
2840
2841 // Mask zero extend is a sext + shift.
2842 { ISD::ZERO_EXTEND, MVT::v2i8, MVT::v2i1, { 2, 1, 1, 1 } },
2843 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v2i1, { 2, 1, 1, 1 } },
2844 { ISD::ZERO_EXTEND, MVT::v2i16, MVT::v2i1, { 2, 1, 1, 1 } },
2845 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v2i1, { 2, 1, 1, 1 } },
2846 { ISD::ZERO_EXTEND, MVT::v4i8, MVT::v4i1, { 2, 1, 1, 1 } },
2847 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v4i1, { 2, 1, 1, 1 } },
2848 { ISD::ZERO_EXTEND, MVT::v4i16, MVT::v4i1, { 2, 1, 1, 1 } },
2849 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v4i1, { 2, 1, 1, 1 } },
2850 { ISD::ZERO_EXTEND, MVT::v8i8, MVT::v8i1, { 2, 1, 1, 1 } },
2851 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v8i1, { 2, 1, 1, 1 } },
2852 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v8i1, { 2, 1, 1, 1 } },
2853 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v16i1, { 2, 1, 1, 1 } },
2854 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i1, { 2, 1, 1, 1 } },
2855 { ISD::ZERO_EXTEND, MVT::v32i8, MVT::v32i1, { 2, 1, 1, 1 } },
2856 { ISD::ZERO_EXTEND, MVT::v32i16, MVT::v32i1, { 2, 1, 1, 1 } },
2857 { ISD::ZERO_EXTEND, MVT::v64i8, MVT::v64i1, { 2, 1, 1, 1 } },
2858 { ISD::ZERO_EXTEND, MVT::v32i16, MVT::v64i1, { 2, 1, 1, 1 } },
2859
2860 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i8, { 2, 1, 1, 1 } },
2861 { ISD::TRUNCATE, MVT::v2i1, MVT::v16i8, { 2, 1, 1, 1 } },
2862 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i16, { 2, 1, 1, 1 } },
2863 { ISD::TRUNCATE, MVT::v2i1, MVT::v8i16, { 2, 1, 1, 1 } },
2864 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i8, { 2, 1, 1, 1 } },
2865 { ISD::TRUNCATE, MVT::v4i1, MVT::v16i8, { 2, 1, 1, 1 } },
2866 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i16, { 2, 1, 1, 1 } },
2867 { ISD::TRUNCATE, MVT::v4i1, MVT::v8i16, { 2, 1, 1, 1 } },
2868 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i8, { 2, 1, 1, 1 } },
2869 { ISD::TRUNCATE, MVT::v8i1, MVT::v16i8, { 2, 1, 1, 1 } },
2870 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i16, { 2, 1, 1, 1 } },
2871 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i8, { 2, 1, 1, 1 } },
2872 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i16, { 2, 1, 1, 1 } },
2873 { ISD::TRUNCATE, MVT::v32i1, MVT::v32i8, { 2, 1, 1, 1 } },
2874 { ISD::TRUNCATE, MVT::v32i1, MVT::v32i16, { 2, 1, 1, 1 } },
2875 { ISD::TRUNCATE, MVT::v64i1, MVT::v64i8, { 2, 1, 1, 1 } },
2876 { ISD::TRUNCATE, MVT::v64i1, MVT::v32i16, { 2, 1, 1, 1 } },
2877
2878 { ISD::TRUNCATE, MVT::v32i8, MVT::v32i16, { 2, 1, 1, 1 } },
2879 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i16, { 2, 1, 1, 1 } }, // widen to zmm
2880 { ISD::TRUNCATE, MVT::v2i8, MVT::v2i16, { 2, 1, 1, 1 } }, // vpmovwb
2881 { ISD::TRUNCATE, MVT::v4i8, MVT::v4i16, { 2, 1, 1, 1 } }, // vpmovwb
2882 { ISD::TRUNCATE, MVT::v8i8, MVT::v8i16, { 2, 1, 1, 1 } }, // vpmovwb
2883 };
2884
2885 static const TypeConversionCostKindTblEntry AVX512DQConversionTbl[] = {
2886 // Mask sign extend has an instruction.
2887 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v2i1, { 1, 1, 1, 1 } },
2888 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v2i1, { 1, 1, 1, 1 } },
2889 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v4i1, { 1, 1, 1, 1 } },
2890 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i1, { 1, 1, 1, 1 } },
2891 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i1, { 1, 1, 1, 1 } },
2892 { ISD::SIGN_EXTEND, MVT::v8i64, MVT::v16i1, { 1, 1, 1, 1 } },
2893 { ISD::SIGN_EXTEND, MVT::v8i64, MVT::v8i1, { 1, 1, 1, 1 } },
2894 { ISD::SIGN_EXTEND, MVT::v16i32, MVT::v16i1, { 1, 1, 1, 1 } },
2895
2896 // Mask zero extend is a sext + shift.
2897 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v2i1, { 2, 1, 1, 1, } },
2898 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v2i1, { 2, 1, 1, 1, } },
2899 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v4i1, { 2, 1, 1, 1, } },
2900 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i1, { 2, 1, 1, 1, } },
2901 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i1, { 2, 1, 1, 1, } },
2902 { ISD::ZERO_EXTEND, MVT::v8i64, MVT::v16i1, { 2, 1, 1, 1, } },
2903 { ISD::ZERO_EXTEND, MVT::v8i64, MVT::v8i1, { 2, 1, 1, 1, } },
2904 { ISD::ZERO_EXTEND, MVT::v16i32, MVT::v16i1, { 2, 1, 1, 1, } },
2905
2906 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i64, { 2, 1, 1, 1 } },
2907 { ISD::TRUNCATE, MVT::v2i1, MVT::v4i32, { 2, 1, 1, 1 } },
2908 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i32, { 2, 1, 1, 1 } },
2909 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i64, { 2, 1, 1, 1 } },
2910 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i32, { 2, 1, 1, 1 } },
2911 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i64, { 2, 1, 1, 1 } },
2912 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i32, { 2, 1, 1, 1 } },
2913 { ISD::TRUNCATE, MVT::v16i1, MVT::v8i64, { 2, 1, 1, 1 } },
2914
2915 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v8i64, { 1, 1, 1, 1 } },
2916 { ISD::SINT_TO_FP, MVT::v8f64, MVT::v8i64, { 1, 1, 1, 1 } },
2917
2918 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i64, { 1, 1, 1, 1 } },
2919 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i64, { 1, 1, 1, 1 } },
2920
2921 { ISD::FP_TO_SINT, MVT::v8i64, MVT::v8f32, { 1, 1, 1, 1 } },
2922 { ISD::FP_TO_SINT, MVT::v8i64, MVT::v8f64, { 1, 1, 1, 1 } },
2923
2924 { ISD::FP_TO_UINT, MVT::v8i64, MVT::v8f32, { 1, 1, 1, 1 } },
2925 { ISD::FP_TO_UINT, MVT::v8i64, MVT::v8f64, { 1, 1, 1, 1 } },
2926 };
2927
2928 // TODO: For AVX512DQ + AVX512VL, we also have cheap casts for 128-bit and
2929 // 256-bit wide vectors.
2930
2931 static const TypeConversionCostKindTblEntry AVX512FConversionTbl[] = {
2932 { ISD::FP_EXTEND, MVT::v8f64, MVT::v8f32, { 1, 1, 1, 1 } },
2933 { ISD::FP_EXTEND, MVT::v8f64, MVT::v16f32, { 3, 1, 1, 1 } },
2934 { ISD::FP_EXTEND, MVT::v16f64, MVT::v16f32, { 4, 1, 1, 1 } }, // 2*vcvtps2pd+vextractf64x4
2935 { ISD::FP_EXTEND, MVT::v16f32, MVT::v16f16, { 1, 1, 1, 1 } }, // vcvtph2ps
2936 { ISD::FP_EXTEND, MVT::v8f64, MVT::v8f16, { 2, 1, 1, 1 } }, // vcvtph2ps+vcvtps2pd
2937 { ISD::FP_ROUND, MVT::v8f32, MVT::v8f64, { 1, 1, 1, 1 } },
2938 { ISD::FP_ROUND, MVT::v16f16, MVT::v16f32, { 1, 1, 1, 1 } }, // vcvtps2ph
2939
2940 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i8, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
2941 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i8, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
2942 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i8, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
2943 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i8, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
2944 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i16, { 3, 1, 1, 1 } }, // sext+vpsllq+vptestmq
2945 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i16, { 3, 1, 1, 1 } }, // sext+vpsllq+vptestmq
2946 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i16, { 3, 1, 1, 1 } }, // sext+vpsllq+vptestmq
2947 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i16, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
2948 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i32, { 2, 1, 1, 1 } }, // zmm vpslld+vptestmd
2949 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i32, { 2, 1, 1, 1 } }, // zmm vpslld+vptestmd
2950 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i32, { 2, 1, 1, 1 } }, // zmm vpslld+vptestmd
2951 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i32, { 2, 1, 1, 1 } }, // vpslld+vptestmd
2952 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i64, { 2, 1, 1, 1 } }, // zmm vpsllq+vptestmq
2953 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i64, { 2, 1, 1, 1 } }, // zmm vpsllq+vptestmq
2954 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i64, { 2, 1, 1, 1 } }, // vpsllq+vptestmq
2955 { ISD::TRUNCATE, MVT::v2i8, MVT::v2i32, { 2, 1, 1, 1 } }, // vpmovdb
2956 { ISD::TRUNCATE, MVT::v4i8, MVT::v4i32, { 2, 1, 1, 1 } }, // vpmovdb
2957 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i32, { 2, 1, 1, 1 } }, // vpmovdb
2958 { ISD::TRUNCATE, MVT::v32i8, MVT::v16i32, { 2, 1, 1, 1 } }, // vpmovdb
2959 { ISD::TRUNCATE, MVT::v64i8, MVT::v16i32, { 2, 1, 1, 1 } }, // vpmovdb
2960 { ISD::TRUNCATE, MVT::v16i16, MVT::v16i32, { 2, 1, 1, 1 } }, // vpmovdw
2961 { ISD::TRUNCATE, MVT::v32i16, MVT::v16i32, { 2, 1, 1, 1 } }, // vpmovdw
2962 { ISD::TRUNCATE, MVT::v2i8, MVT::v2i64, { 2, 1, 1, 1 } }, // vpmovqb
2963 { ISD::TRUNCATE, MVT::v2i16, MVT::v2i64, { 1, 1, 1, 1 } }, // vpshufb
2964 { ISD::TRUNCATE, MVT::v8i8, MVT::v8i64, { 2, 1, 1, 1 } }, // vpmovqb
2965 { ISD::TRUNCATE, MVT::v16i8, MVT::v8i64, { 2, 1, 1, 1 } }, // vpmovqb
2966 { ISD::TRUNCATE, MVT::v32i8, MVT::v8i64, { 2, 1, 1, 1 } }, // vpmovqb
2967 { ISD::TRUNCATE, MVT::v64i8, MVT::v8i64, { 2, 1, 1, 1 } }, // vpmovqb
2968 { ISD::TRUNCATE, MVT::v8i16, MVT::v8i64, { 2, 1, 1, 1 } }, // vpmovqw
2969 { ISD::TRUNCATE, MVT::v16i16, MVT::v8i64, { 2, 1, 1, 1 } }, // vpmovqw
2970 { ISD::TRUNCATE, MVT::v32i16, MVT::v8i64, { 2, 1, 1, 1 } }, // vpmovqw
2971 { ISD::TRUNCATE, MVT::v8i32, MVT::v8i64, { 1, 1, 1, 1 } }, // vpmovqd
2972 { ISD::TRUNCATE, MVT::v4i32, MVT::v4i64, { 1, 1, 1, 1 } }, // zmm vpmovqd
2973 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i64, { 5, 1, 1, 1 } },// 2*vpmovqd+concat+vpmovdb
2974
2975 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i16, { 3, 1, 1, 1 } }, // extend to v16i32
2976 { ISD::TRUNCATE, MVT::v32i8, MVT::v32i16, { 8, 1, 1, 1 } },
2977 { ISD::TRUNCATE, MVT::v64i8, MVT::v32i16, { 8, 1, 1, 1 } },
2978
2979 // Sign extend is zmm vpternlogd+vptruncdb.
2980 // Zero extend is zmm broadcast load+vptruncdw.
2981 { ISD::SIGN_EXTEND, MVT::v2i8, MVT::v2i1, { 3, 1, 1, 1 } },
2982 { ISD::ZERO_EXTEND, MVT::v2i8, MVT::v2i1, { 4, 1, 1, 1 } },
2983 { ISD::SIGN_EXTEND, MVT::v4i8, MVT::v4i1, { 3, 1, 1, 1 } },
2984 { ISD::ZERO_EXTEND, MVT::v4i8, MVT::v4i1, { 4, 1, 1, 1 } },
2985 { ISD::SIGN_EXTEND, MVT::v8i8, MVT::v8i1, { 3, 1, 1, 1 } },
2986 { ISD::ZERO_EXTEND, MVT::v8i8, MVT::v8i1, { 4, 1, 1, 1 } },
2987 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v16i1, { 3, 1, 1, 1 } },
2988 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v16i1, { 4, 1, 1, 1 } },
2989
2990 // Sign extend is zmm vpternlogd+vptruncdw.
2991 // Zero extend is zmm vpternlogd+vptruncdw+vpsrlw.
2992 { ISD::SIGN_EXTEND, MVT::v2i16, MVT::v2i1, { 3, 1, 1, 1 } },
2993 { ISD::ZERO_EXTEND, MVT::v2i16, MVT::v2i1, { 4, 1, 1, 1 } },
2994 { ISD::SIGN_EXTEND, MVT::v4i16, MVT::v4i1, { 3, 1, 1, 1 } },
2995 { ISD::ZERO_EXTEND, MVT::v4i16, MVT::v4i1, { 4, 1, 1, 1 } },
2996 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v8i1, { 3, 1, 1, 1 } },
2997 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v8i1, { 4, 1, 1, 1 } },
2998 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i1, { 3, 1, 1, 1 } },
2999 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i1, { 4, 1, 1, 1 } },
3000
3001 { ISD::SIGN_EXTEND, MVT::v2i32, MVT::v2i1, { 1, 1, 1, 1 } }, // zmm vpternlogd
3002 { ISD::ZERO_EXTEND, MVT::v2i32, MVT::v2i1, { 2, 1, 1, 1 } }, // zmm vpternlogd+psrld
3003 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v4i1, { 1, 1, 1, 1 } }, // zmm vpternlogd
3004 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v4i1, { 2, 1, 1, 1 } }, // zmm vpternlogd+psrld
3005 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i1, { 1, 1, 1, 1 } }, // zmm vpternlogd
3006 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i1, { 2, 1, 1, 1 } }, // zmm vpternlogd+psrld
3007 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v2i1, { 1, 1, 1, 1 } }, // zmm vpternlogq
3008 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v2i1, { 2, 1, 1, 1 } }, // zmm vpternlogq+psrlq
3009 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i1, { 1, 1, 1, 1 } }, // zmm vpternlogq
3010 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i1, { 2, 1, 1, 1 } }, // zmm vpternlogq+psrlq
3011
3012 { ISD::SIGN_EXTEND, MVT::v16i32, MVT::v16i1, { 1, 1, 1, 1 } }, // vpternlogd
3013 { ISD::ZERO_EXTEND, MVT::v16i32, MVT::v16i1, { 2, 1, 1, 1 } }, // vpternlogd+psrld
3014 { ISD::SIGN_EXTEND, MVT::v8i64, MVT::v8i1, { 1, 1, 1, 1 } }, // vpternlogq
3015 { ISD::ZERO_EXTEND, MVT::v8i64, MVT::v8i1, { 2, 1, 1, 1 } }, // vpternlogq+psrlq
3016
3017 { ISD::SIGN_EXTEND, MVT::v16i32, MVT::v16i8, { 1, 1, 1, 1 } },
3018 { ISD::ZERO_EXTEND, MVT::v16i32, MVT::v16i8, { 1, 1, 1, 1 } },
3019 { ISD::SIGN_EXTEND, MVT::v16i32, MVT::v16i16, { 1, 1, 1, 1 } },
3020 { ISD::ZERO_EXTEND, MVT::v16i32, MVT::v16i16, { 1, 1, 1, 1 } },
3021 { ISD::SIGN_EXTEND, MVT::v8i64, MVT::v8i8, { 1, 1, 1, 1 } },
3022 { ISD::ZERO_EXTEND, MVT::v8i64, MVT::v8i8, { 1, 1, 1, 1 } },
3023 { ISD::SIGN_EXTEND, MVT::v8i64, MVT::v8i16, { 1, 1, 1, 1 } },
3024 { ISD::ZERO_EXTEND, MVT::v8i64, MVT::v8i16, { 1, 1, 1, 1 } },
3025 { ISD::SIGN_EXTEND, MVT::v8i64, MVT::v8i32, { 1, 1, 1, 1 } },
3026 { ISD::ZERO_EXTEND, MVT::v8i64, MVT::v8i32, { 1, 1, 1, 1 } },
3027
3028 { ISD::SIGN_EXTEND, MVT::v32i16, MVT::v32i8, { 3, 1, 1, 1 } }, // FIXME: May not be right
3029 { ISD::ZERO_EXTEND, MVT::v32i16, MVT::v32i8, { 3, 1, 1, 1 } }, // FIXME: May not be right
3030
3031 { ISD::SINT_TO_FP, MVT::v8f64, MVT::v8i1, { 4, 1, 1, 1 } },
3032 { ISD::SINT_TO_FP, MVT::v16f32, MVT::v16i1, { 3, 1, 1, 1 } },
3033 { ISD::SINT_TO_FP, MVT::v8f64, MVT::v16i8, { 2, 1, 1, 1 } },
3034 { ISD::SINT_TO_FP, MVT::v16f32, MVT::v16i8, { 1, 1, 1, 1 } },
3035 { ISD::SINT_TO_FP, MVT::v8f64, MVT::v8i16, { 2, 1, 1, 1 } },
3036 { ISD::SINT_TO_FP, MVT::v16f32, MVT::v16i16, { 1, 1, 1, 1 } },
3037 { ISD::SINT_TO_FP, MVT::v8f64, MVT::v8i32, { 1, 1, 1, 1 } },
3038 { ISD::SINT_TO_FP, MVT::v16f32, MVT::v16i32, { 1, 1, 1, 1 } },
3039
3040 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i1, { 4, 1, 1, 1 } },
3041 { ISD::UINT_TO_FP, MVT::v16f32, MVT::v16i1, { 3, 1, 1, 1 } },
3042 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v16i8, { 2, 1, 1, 1 } },
3043 { ISD::UINT_TO_FP, MVT::v16f32, MVT::v16i8, { 1, 1, 1, 1 } },
3044 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i16, { 2, 1, 1, 1 } },
3045 { ISD::UINT_TO_FP, MVT::v16f32, MVT::v16i16, { 1, 1, 1, 1 } },
3046 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i32, { 1, 1, 1, 1 } },
3047 { ISD::UINT_TO_FP, MVT::v16f32, MVT::v16i32, { 1, 1, 1, 1 } },
3048 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i64, {26, 1, 1, 1 } },
3049 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i64, { 5, 1, 1, 1 } },
3050
3051 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v16f32, { 2, 1, 1, 1 } },
3052 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v16f64, { 7, 1, 1, 1 } },
3053 { ISD::FP_TO_SINT, MVT::v32i8, MVT::v32f64, {15, 1, 1, 1 } },
3054 { ISD::FP_TO_SINT, MVT::v64i8, MVT::v64f32, {11, 1, 1, 1 } },
3055 { ISD::FP_TO_SINT, MVT::v64i8, MVT::v64f64, {31, 1, 1, 1 } },
3056 { ISD::FP_TO_SINT, MVT::v8i16, MVT::v8f64, { 3, 1, 1, 1 } },
3057 { ISD::FP_TO_SINT, MVT::v16i16, MVT::v16f64, { 7, 1, 1, 1 } },
3058 { ISD::FP_TO_SINT, MVT::v32i16, MVT::v32f32, { 5, 1, 1, 1 } },
3059 { ISD::FP_TO_SINT, MVT::v32i16, MVT::v32f64, {15, 1, 1, 1 } },
3060 { ISD::FP_TO_SINT, MVT::v8i32, MVT::v8f64, { 1, 1, 1, 1 } },
3061 { ISD::FP_TO_SINT, MVT::v16i32, MVT::v16f64, { 3, 1, 1, 1 } },
3062
3063 { ISD::FP_TO_UINT, MVT::v8i32, MVT::v8f64, { 1, 1, 1, 1 } },
3064 { ISD::FP_TO_UINT, MVT::v8i16, MVT::v8f64, { 3, 1, 1, 1 } },
3065 { ISD::FP_TO_UINT, MVT::v8i8, MVT::v8f64, { 3, 1, 1, 1 } },
3066 { ISD::FP_TO_UINT, MVT::v16i32, MVT::v16f32, { 1, 1, 1, 1 } },
3067 { ISD::FP_TO_UINT, MVT::v16i16, MVT::v16f32, { 3, 1, 1, 1 } },
3068 { ISD::FP_TO_UINT, MVT::v16i8, MVT::v16f32, { 3, 1, 1, 1 } },
3069 };
3070
3071 static const TypeConversionCostKindTblEntry AVX512BWVLConversionTbl[] {
3072 // Mask sign extend has an instruction.
3073 { ISD::SIGN_EXTEND, MVT::v2i8, MVT::v2i1, { 1, 1, 1, 1 } },
3074 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v2i1, { 1, 1, 1, 1 } },
3075 { ISD::SIGN_EXTEND, MVT::v2i16, MVT::v2i1, { 1, 1, 1, 1 } },
3076 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v2i1, { 1, 1, 1, 1 } },
3077 { ISD::SIGN_EXTEND, MVT::v4i16, MVT::v4i1, { 1, 1, 1, 1 } },
3078 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v4i1, { 1, 1, 1, 1 } },
3079 { ISD::SIGN_EXTEND, MVT::v4i8, MVT::v4i1, { 1, 1, 1, 1 } },
3080 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v4i1, { 1, 1, 1, 1 } },
3081 { ISD::SIGN_EXTEND, MVT::v8i8, MVT::v8i1, { 1, 1, 1, 1 } },
3082 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v8i1, { 1, 1, 1, 1 } },
3083 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v8i1, { 1, 1, 1, 1 } },
3084 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v16i1, { 1, 1, 1, 1 } },
3085 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i1, { 1, 1, 1, 1 } },
3086 { ISD::SIGN_EXTEND, MVT::v32i8, MVT::v32i1, { 1, 1, 1, 1 } },
3087 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v32i1, { 1, 1, 1, 1 } },
3088 { ISD::SIGN_EXTEND, MVT::v32i8, MVT::v64i1, { 1, 1, 1, 1 } },
3089 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v64i1, { 1, 1, 1, 1 } },
3090
3091 // Mask zero extend is a sext + shift.
3092 { ISD::ZERO_EXTEND, MVT::v2i8, MVT::v2i1, { 2, 1, 1, 1 } },
3093 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v2i1, { 2, 1, 1, 1 } },
3094 { ISD::ZERO_EXTEND, MVT::v2i16, MVT::v2i1, { 2, 1, 1, 1 } },
3095 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v2i1, { 2, 1, 1, 1 } },
3096 { ISD::ZERO_EXTEND, MVT::v4i8, MVT::v4i1, { 2, 1, 1, 1 } },
3097 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v4i1, { 2, 1, 1, 1 } },
3098 { ISD::ZERO_EXTEND, MVT::v4i16, MVT::v4i1, { 2, 1, 1, 1 } },
3099 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v4i1, { 2, 1, 1, 1 } },
3100 { ISD::ZERO_EXTEND, MVT::v8i8, MVT::v8i1, { 2, 1, 1, 1 } },
3101 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v8i1, { 2, 1, 1, 1 } },
3102 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v8i1, { 2, 1, 1, 1 } },
3103 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v16i1, { 2, 1, 1, 1 } },
3104 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i1, { 2, 1, 1, 1 } },
3105 { ISD::ZERO_EXTEND, MVT::v32i8, MVT::v32i1, { 2, 1, 1, 1 } },
3106 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v32i1, { 2, 1, 1, 1 } },
3107 { ISD::ZERO_EXTEND, MVT::v32i8, MVT::v64i1, { 2, 1, 1, 1 } },
3108 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v64i1, { 2, 1, 1, 1 } },
3109
3110 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i8, { 2, 1, 1, 1 } },
3111 { ISD::TRUNCATE, MVT::v2i1, MVT::v16i8, { 2, 1, 1, 1 } },
3112 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i16, { 2, 1, 1, 1 } },
3113 { ISD::TRUNCATE, MVT::v2i1, MVT::v8i16, { 2, 1, 1, 1 } },
3114 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i8, { 2, 1, 1, 1 } },
3115 { ISD::TRUNCATE, MVT::v4i1, MVT::v16i8, { 2, 1, 1, 1 } },
3116 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i16, { 2, 1, 1, 1 } },
3117 { ISD::TRUNCATE, MVT::v4i1, MVT::v8i16, { 2, 1, 1, 1 } },
3118 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i8, { 2, 1, 1, 1 } },
3119 { ISD::TRUNCATE, MVT::v8i1, MVT::v16i8, { 2, 1, 1, 1 } },
3120 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i16, { 2, 1, 1, 1 } },
3121 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i8, { 2, 1, 1, 1 } },
3122 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i16, { 2, 1, 1, 1 } },
3123 { ISD::TRUNCATE, MVT::v32i1, MVT::v32i8, { 2, 1, 1, 1 } },
3124 { ISD::TRUNCATE, MVT::v32i1, MVT::v16i16, { 2, 1, 1, 1 } },
3125 { ISD::TRUNCATE, MVT::v64i1, MVT::v32i8, { 2, 1, 1, 1 } },
3126 { ISD::TRUNCATE, MVT::v64i1, MVT::v16i16, { 2, 1, 1, 1 } },
3127
3128 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i16, { 2, 1, 1, 1 } },
3129 };
3130
3131 static const TypeConversionCostKindTblEntry AVX512DQVLConversionTbl[] = {
3132 // Mask sign extend has an instruction.
3133 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v2i1, { 1, 1, 1, 1 } },
3134 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v2i1, { 1, 1, 1, 1 } },
3135 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v4i1, { 1, 1, 1, 1 } },
3136 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v16i1, { 1, 1, 1, 1 } },
3137 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i1, { 1, 1, 1, 1 } },
3138 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v8i1, { 1, 1, 1, 1 } },
3139 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v16i1, { 1, 1, 1, 1 } },
3140 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i1, { 1, 1, 1, 1 } },
3141
3142 // Mask zero extend is a sext + shift.
3143 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v2i1, { 2, 1, 1, 1 } },
3144 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v2i1, { 2, 1, 1, 1 } },
3145 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v4i1, { 2, 1, 1, 1 } },
3146 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v16i1, { 2, 1, 1, 1 } },
3147 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i1, { 2, 1, 1, 1 } },
3148 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v8i1, { 2, 1, 1, 1 } },
3149 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v16i1, { 2, 1, 1, 1 } },
3150 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i1, { 2, 1, 1, 1 } },
3151
3152 { ISD::TRUNCATE, MVT::v16i1, MVT::v4i64, { 2, 1, 1, 1 } },
3153 { ISD::TRUNCATE, MVT::v16i1, MVT::v8i32, { 2, 1, 1, 1 } },
3154 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i64, { 2, 1, 1, 1 } },
3155 { ISD::TRUNCATE, MVT::v2i1, MVT::v4i32, { 2, 1, 1, 1 } },
3156 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i32, { 2, 1, 1, 1 } },
3157 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i64, { 2, 1, 1, 1 } },
3158 { ISD::TRUNCATE, MVT::v8i1, MVT::v4i64, { 2, 1, 1, 1 } },
3159 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i32, { 2, 1, 1, 1 } },
3160
3161 { ISD::SINT_TO_FP, MVT::v2f32, MVT::v2i64, { 1, 1, 1, 1 } },
3162 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v2i64, { 1, 1, 1, 1 } },
3163 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v4i64, { 1, 1, 1, 1 } },
3164 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v4i64, { 1, 1, 1, 1 } },
3165
3166 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i64, { 1, 1, 1, 1 } },
3167 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i64, { 1, 1, 1, 1 } },
3168 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i64, { 1, 1, 1, 1 } },
3169 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i64, { 1, 1, 1, 1 } },
3170
3171 { ISD::FP_TO_SINT, MVT::v2i64, MVT::v4f32, { 1, 1, 1, 1 } },
3172 { ISD::FP_TO_SINT, MVT::v4i64, MVT::v4f32, { 1, 1, 1, 1 } },
3173 { ISD::FP_TO_SINT, MVT::v2i64, MVT::v2f64, { 1, 1, 1, 1 } },
3174 { ISD::FP_TO_SINT, MVT::v4i64, MVT::v4f64, { 1, 1, 1, 1 } },
3175
3176 { ISD::FP_TO_UINT, MVT::v2i64, MVT::v4f32, { 1, 1, 1, 1 } },
3177 { ISD::FP_TO_UINT, MVT::v4i64, MVT::v4f32, { 1, 1, 1, 1 } },
3178 { ISD::FP_TO_UINT, MVT::v2i64, MVT::v2f64, { 1, 1, 1, 1 } },
3179 { ISD::FP_TO_UINT, MVT::v4i64, MVT::v4f64, { 1, 1, 1, 1 } },
3180 };
3181
3182 static const TypeConversionCostKindTblEntry AVX512VLConversionTbl[] = {
3183 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i8, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
3184 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i8, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
3185 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i8, { 3, 1, 1, 1 } }, // sext+vpslld+vptestmd
3186 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i8, { 8, 1, 1, 1 } }, // split+2*v8i8
3187 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i16, { 3, 1, 1, 1 } }, // sext+vpsllq+vptestmq
3188 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i16, { 3, 1, 1, 1 } }, // sext+vpsllq+vptestmq
3189 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i16, { 3, 1, 1, 1 } }, // sext+vpsllq+vptestmq
3190 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i16, { 8, 1, 1, 1 } }, // split+2*v8i16
3191 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i32, { 2, 1, 1, 1 } }, // vpslld+vptestmd
3192 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i32, { 2, 1, 1, 1 } }, // vpslld+vptestmd
3193 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i32, { 2, 1, 1, 1 } }, // vpslld+vptestmd
3194 { ISD::TRUNCATE, MVT::v16i1, MVT::v8i32, { 2, 1, 1, 1 } }, // vpslld+vptestmd
3195 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i64, { 2, 1, 1, 1 } }, // vpsllq+vptestmq
3196 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i64, { 2, 1, 1, 1 } }, // vpsllq+vptestmq
3197 { ISD::TRUNCATE, MVT::v4i32, MVT::v4i64, { 1, 1, 1, 1 } }, // vpmovqd
3198 { ISD::TRUNCATE, MVT::v4i8, MVT::v4i64, { 2, 1, 1, 1 } }, // vpmovqb
3199 { ISD::TRUNCATE, MVT::v4i16, MVT::v4i64, { 2, 1, 1, 1 } }, // vpmovqw
3200 { ISD::TRUNCATE, MVT::v8i8, MVT::v8i32, { 2, 1, 1, 1 } }, // vpmovwb
3201
3202 // sign extend is vpcmpeq+maskedmove+vpmovdw+vpacksswb
3203 // zero extend is vpcmpeq+maskedmove+vpmovdw+vpsrlw+vpackuswb
3204 { ISD::SIGN_EXTEND, MVT::v2i8, MVT::v2i1, { 5, 1, 1, 1 } },
3205 { ISD::ZERO_EXTEND, MVT::v2i8, MVT::v2i1, { 6, 1, 1, 1 } },
3206 { ISD::SIGN_EXTEND, MVT::v4i8, MVT::v4i1, { 5, 1, 1, 1 } },
3207 { ISD::ZERO_EXTEND, MVT::v4i8, MVT::v4i1, { 6, 1, 1, 1 } },
3208 { ISD::SIGN_EXTEND, MVT::v8i8, MVT::v8i1, { 5, 1, 1, 1 } },
3209 { ISD::ZERO_EXTEND, MVT::v8i8, MVT::v8i1, { 6, 1, 1, 1 } },
3210 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v16i1, {10, 1, 1, 1 } },
3211 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v16i1, {12, 1, 1, 1 } },
3212
3213 // sign extend is vpcmpeq+maskedmove+vpmovdw
3214 // zero extend is vpcmpeq+maskedmove+vpmovdw+vpsrlw
3215 { ISD::SIGN_EXTEND, MVT::v2i16, MVT::v2i1, { 4, 1, 1, 1 } },
3216 { ISD::ZERO_EXTEND, MVT::v2i16, MVT::v2i1, { 5, 1, 1, 1 } },
3217 { ISD::SIGN_EXTEND, MVT::v4i16, MVT::v4i1, { 4, 1, 1, 1 } },
3218 { ISD::ZERO_EXTEND, MVT::v4i16, MVT::v4i1, { 5, 1, 1, 1 } },
3219 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v8i1, { 4, 1, 1, 1 } },
3220 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v8i1, { 5, 1, 1, 1 } },
3221 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i1, {10, 1, 1, 1 } },
3222 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i1, {12, 1, 1, 1 } },
3223
3224 { ISD::SIGN_EXTEND, MVT::v2i32, MVT::v2i1, { 1, 1, 1, 1 } }, // vpternlogd
3225 { ISD::ZERO_EXTEND, MVT::v2i32, MVT::v2i1, { 2, 1, 1, 1 } }, // vpternlogd+psrld
3226 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v4i1, { 1, 1, 1, 1 } }, // vpternlogd
3227 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v4i1, { 2, 1, 1, 1 } }, // vpternlogd+psrld
3228 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i1, { 1, 1, 1, 1 } }, // vpternlogd
3229 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i1, { 2, 1, 1, 1 } }, // vpternlogd+psrld
3230 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v16i1, { 1, 1, 1, 1 } }, // vpternlogd
3231 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v16i1, { 2, 1, 1, 1 } }, // vpternlogd+psrld
3232
3233 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v2i1, { 1, 1, 1, 1 } }, // vpternlogq
3234 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v2i1, { 2, 1, 1, 1 } }, // vpternlogq+psrlq
3235 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i1, { 1, 1, 1, 1 } }, // vpternlogq
3236 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i1, { 2, 1, 1, 1 } }, // vpternlogq+psrlq
3237
3238 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v16i8, { 1, 1, 1, 1 } },
3239 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v16i8, { 1, 1, 1, 1 } },
3240 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v16i8, { 1, 1, 1, 1 } },
3241 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v16i8, { 1, 1, 1, 1 } },
3242 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i8, { 1, 1, 1, 1 } },
3243 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i8, { 1, 1, 1, 1 } },
3244 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v8i16, { 1, 1, 1, 1 } },
3245 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v8i16, { 1, 1, 1, 1 } },
3246 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i16, { 1, 1, 1, 1 } },
3247 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i16, { 1, 1, 1, 1 } },
3248 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i32, { 1, 1, 1, 1 } },
3249 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i32, { 1, 1, 1, 1 } },
3250
3251 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v16i8, { 1, 1, 1, 1 } },
3252 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v16i8, { 1, 1, 1, 1 } },
3253 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v8i16, { 1, 1, 1, 1 } },
3254 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v8i16, { 1, 1, 1, 1 } },
3255
3256 { ISD::UINT_TO_FP, MVT::f32, MVT::i64, { 1, 1, 1, 1 } },
3257 { ISD::UINT_TO_FP, MVT::f64, MVT::i64, { 1, 1, 1, 1 } },
3258 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v16i8, { 1, 1, 1, 1 } },
3259 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v16i8, { 1, 1, 1, 1 } },
3260 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v8i16, { 1, 1, 1, 1 } },
3261 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i16, { 1, 1, 1, 1 } },
3262 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i32, { 1, 1, 1, 1 } },
3263 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i32, { 1, 1, 1, 1 } },
3264 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i32, { 1, 1, 1, 1 } },
3265 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i32, { 1, 1, 1, 1 } },
3266 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i64, { 5, 1, 1, 1 } },
3267 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i64, { 5, 1, 1, 1 } },
3268 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i64, { 5, 1, 1, 1 } },
3269
3270 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v8f32, { 2, 1, 1, 1 } },
3271 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v16f32, { 2, 1, 1, 1 } },
3272 { ISD::FP_TO_SINT, MVT::v32i8, MVT::v32f32, { 5, 1, 1, 1 } },
3273
3274 { ISD::FP_TO_UINT, MVT::i64, MVT::f32, { 1, 1, 1, 1 } },
3275 { ISD::FP_TO_UINT, MVT::i64, MVT::f64, { 1, 1, 1, 1 } },
3276 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f32, { 1, 1, 1, 1 } },
3277 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v2f64, { 1, 1, 1, 1 } },
3278 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f64, { 1, 1, 1, 1 } },
3279 { ISD::FP_TO_UINT, MVT::v8i32, MVT::v8f32, { 1, 1, 1, 1 } },
3280 { ISD::FP_TO_UINT, MVT::v8i32, MVT::v8f64, { 1, 1, 1, 1 } },
3281 };
3282
3283 static const TypeConversionCostKindTblEntry AVX2ConversionTbl[] = {
3284 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i1, { 3, 1, 1, 1 } },
3285 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i1, { 3, 1, 1, 1 } },
3286 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i1, { 3, 1, 1, 1 } },
3287 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i1, { 3, 1, 1, 1 } },
3288 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i1, { 1, 1, 1, 1 } },
3289 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i1, { 1, 1, 1, 1 } },
3290
3291 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v16i8, { 2, 1, 1, 1 } },
3292 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v16i8, { 2, 1, 1, 1 } },
3293 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v16i8, { 2, 1, 1, 1 } },
3294 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v16i8, { 2, 1, 1, 1 } },
3295 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i8, { 2, 1, 1, 1 } },
3296 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i8, { 2, 1, 1, 1 } },
3297 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v8i16, { 2, 1, 1, 1 } },
3298 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v8i16, { 2, 1, 1, 1 } },
3299 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i16, { 2, 1, 1, 1 } },
3300 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i16, { 2, 1, 1, 1 } },
3301 { ISD::ZERO_EXTEND, MVT::v16i32, MVT::v16i16, { 3, 1, 1, 1 } },
3302 { ISD::SIGN_EXTEND, MVT::v16i32, MVT::v16i16, { 3, 1, 1, 1 } },
3303 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i32, { 2, 1, 1, 1 } },
3304 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i32, { 2, 1, 1, 1 } },
3305
3306 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i32, { 2, 1, 1, 1 } },
3307
3308 { ISD::TRUNCATE, MVT::v16i16, MVT::v16i32, { 4, 1, 1, 1 } },
3309 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i32, { 4, 1, 1, 1 } },
3310 { ISD::TRUNCATE, MVT::v16i8, MVT::v8i16, { 1, 1, 1, 1 } },
3311 { ISD::TRUNCATE, MVT::v16i8, MVT::v4i32, { 1, 1, 1, 1 } },
3312 { ISD::TRUNCATE, MVT::v16i8, MVT::v2i64, { 1, 1, 1, 1 } },
3313 { ISD::TRUNCATE, MVT::v16i8, MVT::v8i32, { 4, 1, 1, 1 } },
3314 { ISD::TRUNCATE, MVT::v16i8, MVT::v4i64, { 4, 1, 1, 1 } },
3315 { ISD::TRUNCATE, MVT::v8i16, MVT::v4i32, { 1, 1, 1, 1 } },
3316 { ISD::TRUNCATE, MVT::v8i16, MVT::v2i64, { 1, 1, 1, 1 } },
3317 { ISD::TRUNCATE, MVT::v8i16, MVT::v4i64, { 5, 1, 1, 1 } },
3318 { ISD::TRUNCATE, MVT::v4i32, MVT::v4i64, { 1, 1, 1, 1 } },
3319 { ISD::TRUNCATE, MVT::v8i16, MVT::v8i32, { 2, 1, 1, 1 } },
3320
3321 { ISD::FP_EXTEND, MVT::v8f64, MVT::v8f32, { 3, 1, 1, 1 } },
3322 { ISD::FP_ROUND, MVT::v8f32, MVT::v8f64, { 3, 1, 1, 1 } },
3323
3324 { ISD::FP_TO_SINT, MVT::v16i16, MVT::v8f32, { 1, 1, 1, 1 } },
3325 { ISD::FP_TO_SINT, MVT::v4i32, MVT::v4f64, { 1, 1, 1, 1 } },
3326 { ISD::FP_TO_SINT, MVT::v8i32, MVT::v8f32, { 1, 1, 1, 1 } },
3327 { ISD::FP_TO_SINT, MVT::v8i32, MVT::v8f64, { 3, 1, 1, 1 } },
3328
3329 { ISD::FP_TO_UINT, MVT::i64, MVT::f32, { 3, 1, 1, 1 } },
3330 { ISD::FP_TO_UINT, MVT::i64, MVT::f64, { 3, 1, 1, 1 } },
3331 { ISD::FP_TO_UINT, MVT::v16i16, MVT::v8f32, { 1, 1, 1, 1 } },
3332 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f32, { 3, 1, 1, 1 } },
3333 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v2f64, { 4, 1, 1, 1 } },
3334 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f64, { 4, 1, 1, 1 } },
3335 { ISD::FP_TO_UINT, MVT::v8i32, MVT::v8f32, { 3, 1, 1, 1 } },
3336 { ISD::FP_TO_UINT, MVT::v8i32, MVT::v4f64, { 4, 1, 1, 1 } },
3337
3338 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v16i8, { 2, 1, 1, 1 } },
3339 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v16i8, { 2, 1, 1, 1 } },
3340 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v8i16, { 2, 1, 1, 1 } },
3341 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v8i16, { 2, 1, 1, 1 } },
3342 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v4i32, { 1, 1, 1, 1 } },
3343 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v8i32, { 1, 1, 1, 1 } },
3344 { ISD::SINT_TO_FP, MVT::v8f64, MVT::v8i32, { 3, 1, 1, 1 } },
3345
3346 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v16i8, { 2, 1, 1, 1 } },
3347 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v16i8, { 2, 1, 1, 1 } },
3348 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v8i16, { 2, 1, 1, 1 } },
3349 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i16, { 2, 1, 1, 1 } },
3350 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i32, { 2, 1, 1, 1 } },
3351 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i32, { 1, 1, 1, 1 } },
3352 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i32, { 2, 1, 1, 1 } },
3353 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i32, { 2, 1, 1, 1 } },
3354 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i32, { 2, 1, 1, 1 } },
3355 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i32, { 4, 1, 1, 1 } },
3356 };
3357
3358 static const TypeConversionCostKindTblEntry AVXConversionTbl[] = {
3359 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i1, { 4, 1, 1, 1 } },
3360 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i1, { 4, 1, 1, 1 } },
3361 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i1, { 4, 1, 1, 1 } },
3362 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i1, { 4, 1, 1, 1 } },
3363 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i1, { 4, 1, 1, 1 } },
3364 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i1, { 4, 1, 1, 1 } },
3365
3366 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v16i8, { 3, 1, 1, 1 } },
3367 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v16i8, { 3, 1, 1, 1 } },
3368 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v16i8, { 3, 1, 1, 1 } },
3369 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v16i8, { 3, 1, 1, 1 } },
3370 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i8, { 3, 1, 1, 1 } },
3371 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i8, { 3, 1, 1, 1 } },
3372 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v8i16, { 3, 1, 1, 1 } },
3373 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v8i16, { 3, 1, 1, 1 } },
3374 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i16, { 3, 1, 1, 1 } },
3375 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i16, { 3, 1, 1, 1 } },
3376 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i32, { 3, 1, 1, 1 } },
3377 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i32, { 3, 1, 1, 1 } },
3378
3379 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i64, { 4, 1, 1, 1 } },
3380 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i32, { 5, 1, 1, 1 } },
3381 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i16, { 4, 1, 1, 1 } },
3382 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i64, { 9, 1, 1, 1 } },
3383 { ISD::TRUNCATE, MVT::v16i1, MVT::v16i64, {11, 1, 1, 1 } },
3384
3385 { ISD::TRUNCATE, MVT::v16i16, MVT::v16i32, { 6, 1, 1, 1 } },
3386 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i32, { 6, 1, 1, 1 } },
3387 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i16, { 2, 1, 1, 1 } }, // and+extract+packuswb
3388 { ISD::TRUNCATE, MVT::v16i8, MVT::v8i32, { 5, 1, 1, 1 } },
3389 { ISD::TRUNCATE, MVT::v8i16, MVT::v8i32, { 5, 1, 1, 1 } },
3390 { ISD::TRUNCATE, MVT::v16i8, MVT::v4i64, { 5, 1, 1, 1 } },
3391 { ISD::TRUNCATE, MVT::v8i16, MVT::v4i64, { 3, 1, 1, 1 } }, // and+extract+2*packusdw
3392 { ISD::TRUNCATE, MVT::v4i32, MVT::v4i64, { 2, 1, 1, 1 } },
3393
3394 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v4i1, { 3, 1, 1, 1 } },
3395 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v4i1, { 3, 1, 1, 1 } },
3396 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v8i1, { 8, 1, 1, 1 } },
3397 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v16i8, { 4, 1, 1, 1 } },
3398 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v16i8, { 2, 1, 1, 1 } },
3399 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v8i16, { 4, 1, 1, 1 } },
3400 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v8i16, { 2, 1, 1, 1 } },
3401 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v4i32, { 2, 1, 1, 1 } },
3402 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v8i32, { 2, 1, 1, 1 } },
3403 { ISD::SINT_TO_FP, MVT::v8f64, MVT::v8i32, { 4, 1, 1, 1 } },
3404 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v2i64, { 5, 1, 1, 1 } },
3405 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v4i64, { 8, 1, 1, 1 } },
3406
3407 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i1, { 7, 1, 1, 1 } },
3408 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i1, { 7, 1, 1, 1 } },
3409 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i1, { 6, 1, 1, 1 } },
3410 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v16i8, { 4, 1, 1, 1 } },
3411 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v16i8, { 2, 1, 1, 1 } },
3412 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i16, { 4, 1, 1, 1 } },
3413 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v8i16, { 2, 1, 1, 1 } },
3414 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i32, { 4, 1, 1, 1 } },
3415 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i32, { 4, 1, 1, 1 } },
3416 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i32, { 5, 1, 1, 1 } },
3417 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i32, { 6, 1, 1, 1 } },
3418 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i32, { 8, 1, 1, 1 } },
3419 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i32, {10, 1, 1, 1 } },
3420 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i64, {10, 1, 1, 1 } },
3421 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i64, {18, 1, 1, 1 } },
3422 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i64, { 5, 1, 1, 1 } },
3423 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i64, {10, 1, 1, 1 } },
3424
3425 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v8f32, { 2, 1, 1, 1 } },
3426 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v4f64, { 2, 1, 1, 1 } },
3427 { ISD::FP_TO_SINT, MVT::v32i8, MVT::v8f32, { 2, 1, 1, 1 } },
3428 { ISD::FP_TO_SINT, MVT::v32i8, MVT::v4f64, { 2, 1, 1, 1 } },
3429 { ISD::FP_TO_SINT, MVT::v8i16, MVT::v8f32, { 2, 1, 1, 1 } },
3430 { ISD::FP_TO_SINT, MVT::v8i16, MVT::v4f64, { 2, 1, 1, 1 } },
3431 { ISD::FP_TO_SINT, MVT::v16i16, MVT::v8f32, { 2, 1, 1, 1 } },
3432 { ISD::FP_TO_SINT, MVT::v16i16, MVT::v4f64, { 2, 1, 1, 1 } },
3433 { ISD::FP_TO_SINT, MVT::v4i32, MVT::v4f64, { 2, 1, 1, 1 } },
3434 { ISD::FP_TO_SINT, MVT::v8i32, MVT::v8f32, { 2, 1, 1, 1 } },
3435 { ISD::FP_TO_SINT, MVT::v8i32, MVT::v8f64, { 5, 1, 1, 1 } },
3436
3437 { ISD::FP_TO_UINT, MVT::v16i8, MVT::v8f32, { 2, 1, 1, 1 } },
3438 { ISD::FP_TO_UINT, MVT::v16i8, MVT::v4f64, { 2, 1, 1, 1 } },
3439 { ISD::FP_TO_UINT, MVT::v32i8, MVT::v8f32, { 2, 1, 1, 1 } },
3440 { ISD::FP_TO_UINT, MVT::v32i8, MVT::v4f64, { 2, 1, 1, 1 } },
3441 { ISD::FP_TO_UINT, MVT::v8i16, MVT::v8f32, { 2, 1, 1, 1 } },
3442 { ISD::FP_TO_UINT, MVT::v8i16, MVT::v4f64, { 2, 1, 1, 1 } },
3443 { ISD::FP_TO_UINT, MVT::v16i16, MVT::v8f32, { 2, 1, 1, 1 } },
3444 { ISD::FP_TO_UINT, MVT::v16i16, MVT::v4f64, { 2, 1, 1, 1 } },
3445 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f32, { 3, 1, 1, 1 } },
3446 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v2f64, { 4, 1, 1, 1 } },
3447 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f64, { 6, 1, 1, 1 } },
3448 { ISD::FP_TO_UINT, MVT::v8i32, MVT::v8f32, { 7, 1, 1, 1 } },
3449 { ISD::FP_TO_UINT, MVT::v8i32, MVT::v4f64, { 7, 1, 1, 1 } },
3450
3451 { ISD::FP_EXTEND, MVT::v4f64, MVT::v4f32, { 1, 1, 1, 1 } },
3452 { ISD::FP_ROUND, MVT::v4f32, MVT::v4f64, { 1, 1, 1, 1 } },
3453 };
3454
3455 static const TypeConversionCostKindTblEntry SSE41ConversionTbl[] = {
3456 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v16i8, { 1, 1, 1, 1 } },
3457 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v16i8, { 1, 1, 1, 1 } },
3458 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v16i8, { 1, 1, 1, 1 } },
3459 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v16i8, { 1, 1, 1, 1 } },
3460 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v16i8, { 1, 1, 1, 1 } },
3461 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v16i8, { 1, 1, 1, 1 } },
3462 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v8i16, { 1, 1, 1, 1 } },
3463 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v8i16, { 1, 1, 1, 1 } },
3464 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v8i16, { 1, 1, 1, 1 } },
3465 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v8i16, { 1, 1, 1, 1 } },
3466 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v4i32, { 1, 1, 1, 1 } },
3467 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v4i32, { 1, 1, 1, 1 } },
3468
3469 // These truncates end up widening elements.
3470 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i8, { 1, 1, 1, 1 } }, // PMOVXZBQ
3471 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i16, { 1, 1, 1, 1 } }, // PMOVXZWQ
3472 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i8, { 1, 1, 1, 1 } }, // PMOVXZBD
3473
3474 { ISD::TRUNCATE, MVT::v16i8, MVT::v4i32, { 2, 1, 1, 1 } },
3475 { ISD::TRUNCATE, MVT::v8i16, MVT::v4i32, { 2, 1, 1, 1 } },
3476 { ISD::TRUNCATE, MVT::v16i8, MVT::v2i64, { 2, 1, 1, 1 } },
3477
3478 { ISD::SINT_TO_FP, MVT::f32, MVT::i32, { 1, 1, 1, 1 } },
3479 { ISD::SINT_TO_FP, MVT::f64, MVT::i32, { 1, 1, 1, 1 } },
3480 { ISD::SINT_TO_FP, MVT::f32, MVT::i64, { 1, 1, 1, 1 } },
3481 { ISD::SINT_TO_FP, MVT::f64, MVT::i64, { 1, 1, 1, 1 } },
3482 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v16i8, { 1, 1, 1, 1 } },
3483 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v16i8, { 1, 1, 1, 1 } },
3484 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v8i16, { 1, 1, 1, 1 } },
3485 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v8i16, { 1, 1, 1, 1 } },
3486 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v4i32, { 1, 1, 1, 1 } },
3487 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v4i32, { 1, 1, 1, 1 } },
3488 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v4i32, { 2, 1, 1, 1 } },
3489
3490 { ISD::UINT_TO_FP, MVT::f32, MVT::i32, { 1, 1, 1, 1 } },
3491 { ISD::UINT_TO_FP, MVT::f64, MVT::i32, { 1, 1, 1, 1 } },
3492 { ISD::UINT_TO_FP, MVT::f32, MVT::i64, { 4, 1, 1, 1 } },
3493 { ISD::UINT_TO_FP, MVT::f64, MVT::i64, { 4, 1, 1, 1 } },
3494 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v16i8, { 1, 1, 1, 1 } },
3495 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v16i8, { 1, 1, 1, 1 } },
3496 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v8i16, { 1, 1, 1, 1 } },
3497 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v8i16, { 1, 1, 1, 1 } },
3498 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i32, { 3, 1, 1, 1 } },
3499 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i32, { 3, 1, 1, 1 } },
3500 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v4i32, { 2, 1, 1, 1 } },
3501 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v2i64, {12, 1, 1, 1 } },
3502 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i64, {22, 1, 1, 1 } },
3503 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i64, { 4, 1, 1, 1 } },
3504
3505 { ISD::FP_TO_SINT, MVT::i32, MVT::f32, { 1, 1, 1, 1 } },
3506 { ISD::FP_TO_SINT, MVT::i64, MVT::f32, { 1, 1, 1, 1 } },
3507 { ISD::FP_TO_SINT, MVT::i32, MVT::f64, { 1, 1, 1, 1 } },
3508 { ISD::FP_TO_SINT, MVT::i64, MVT::f64, { 1, 1, 1, 1 } },
3509 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v4f32, { 2, 1, 1, 1 } },
3510 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v2f64, { 2, 1, 1, 1 } },
3511 { ISD::FP_TO_SINT, MVT::v8i16, MVT::v4f32, { 1, 1, 1, 1 } },
3512 { ISD::FP_TO_SINT, MVT::v8i16, MVT::v2f64, { 1, 1, 1, 1 } },
3513 { ISD::FP_TO_SINT, MVT::v4i32, MVT::v4f32, { 1, 1, 1, 1 } },
3514 { ISD::FP_TO_SINT, MVT::v4i32, MVT::v2f64, { 1, 1, 1, 1 } },
3515
3516 { ISD::FP_TO_UINT, MVT::i32, MVT::f32, { 1, 1, 1, 1 } },
3517 { ISD::FP_TO_UINT, MVT::i64, MVT::f32, { 4, 1, 1, 1 } },
3518 { ISD::FP_TO_UINT, MVT::i32, MVT::f64, { 1, 1, 1, 1 } },
3519 { ISD::FP_TO_UINT, MVT::i64, MVT::f64, { 4, 1, 1, 1 } },
3520 { ISD::FP_TO_UINT, MVT::v16i8, MVT::v4f32, { 2, 1, 1, 1 } },
3521 { ISD::FP_TO_UINT, MVT::v16i8, MVT::v2f64, { 2, 1, 1, 1 } },
3522 { ISD::FP_TO_UINT, MVT::v8i16, MVT::v4f32, { 1, 1, 1, 1 } },
3523 { ISD::FP_TO_UINT, MVT::v8i16, MVT::v2f64, { 1, 1, 1, 1 } },
3524 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f32, { 4, 1, 1, 1 } },
3525 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v2f64, { 4, 1, 1, 1 } },
3526 };
3527
3528 static const TypeConversionCostKindTblEntry SSE2ConversionTbl[] = {
3529 // These are somewhat magic numbers justified by comparing the
3530 // output of llvm-mca for our various supported scheduler models
3531 // and basing it off the worst case scenario.
3532 { ISD::SINT_TO_FP, MVT::f32, MVT::i32, { 3, 1, 1, 1 } },
3533 { ISD::SINT_TO_FP, MVT::f64, MVT::i32, { 3, 1, 1, 1 } },
3534 { ISD::SINT_TO_FP, MVT::f32, MVT::i64, { 3, 1, 1, 1 } },
3535 { ISD::SINT_TO_FP, MVT::f64, MVT::i64, { 3, 1, 1, 1 } },
3536 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v16i8, { 3, 1, 1, 1 } },
3537 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v16i8, { 4, 1, 1, 1 } },
3538 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v8i16, { 3, 1, 1, 1 } },
3539 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v8i16, { 4, 1, 1, 1 } },
3540 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v4i32, { 3, 1, 1, 1 } },
3541 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v4i32, { 4, 1, 1, 1 } },
3542 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v2i64, { 8, 1, 1, 1 } },
3543 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v2i64, { 8, 1, 1, 1 } },
3544
3545 { ISD::UINT_TO_FP, MVT::f32, MVT::i32, { 3, 1, 1, 1 } },
3546 { ISD::UINT_TO_FP, MVT::f64, MVT::i32, { 3, 1, 1, 1 } },
3547 { ISD::UINT_TO_FP, MVT::f32, MVT::i64, { 8, 1, 1, 1 } },
3548 { ISD::UINT_TO_FP, MVT::f64, MVT::i64, { 9, 1, 1, 1 } },
3549 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v16i8, { 4, 1, 1, 1 } },
3550 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v16i8, { 4, 1, 1, 1 } },
3551 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v8i16, { 4, 1, 1, 1 } },
3552 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v8i16, { 4, 1, 1, 1 } },
3553 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i32, { 7, 1, 1, 1 } },
3554 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v4i32, { 7, 1, 1, 1 } },
3555 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i32, { 5, 1, 1, 1 } },
3556 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i64, {15, 1, 1, 1 } },
3557 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v2i64, {18, 1, 1, 1 } },
3558
3559 { ISD::FP_TO_SINT, MVT::i32, MVT::f32, { 4, 1, 1, 1 } },
3560 { ISD::FP_TO_SINT, MVT::i64, MVT::f32, { 4, 1, 1, 1 } },
3561 { ISD::FP_TO_SINT, MVT::i32, MVT::f64, { 4, 1, 1, 1 } },
3562 { ISD::FP_TO_SINT, MVT::i64, MVT::f64, { 4, 1, 1, 1 } },
3563 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v4f32, { 6, 1, 1, 1 } },
3564 { ISD::FP_TO_SINT, MVT::v16i8, MVT::v2f64, { 6, 1, 1, 1 } },
3565 { ISD::FP_TO_SINT, MVT::v8i16, MVT::v4f32, { 5, 1, 1, 1 } },
3566 { ISD::FP_TO_SINT, MVT::v8i16, MVT::v2f64, { 5, 1, 1, 1 } },
3567 { ISD::FP_TO_SINT, MVT::v4i32, MVT::v4f32, { 4, 1, 1, 1 } },
3568 { ISD::FP_TO_SINT, MVT::v4i32, MVT::v2f64, { 4, 1, 1, 1 } },
3569
3570 { ISD::FP_TO_UINT, MVT::i32, MVT::f32, { 4, 1, 1, 1 } },
3571 { ISD::FP_TO_UINT, MVT::i64, MVT::f32, { 4, 1, 1, 1 } },
3572 { ISD::FP_TO_UINT, MVT::i32, MVT::f64, { 4, 1, 1, 1 } },
3573 { ISD::FP_TO_UINT, MVT::i64, MVT::f64, {15, 1, 1, 1 } },
3574 { ISD::FP_TO_UINT, MVT::v16i8, MVT::v4f32, { 6, 1, 1, 1 } },
3575 { ISD::FP_TO_UINT, MVT::v16i8, MVT::v2f64, { 6, 1, 1, 1 } },
3576 { ISD::FP_TO_UINT, MVT::v8i16, MVT::v4f32, { 5, 1, 1, 1 } },
3577 { ISD::FP_TO_UINT, MVT::v8i16, MVT::v2f64, { 5, 1, 1, 1 } },
3578 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f32, { 8, 1, 1, 1 } },
3579 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v2f64, { 8, 1, 1, 1 } },
3580
3581 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v16i8, { 4, 1, 1, 1 } },
3582 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v16i8, { 4, 1, 1, 1 } },
3583 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v16i8, { 2, 1, 1, 1 } },
3584 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v16i8, { 3, 1, 1, 1 } },
3585 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v16i8, { 1, 1, 1, 1 } },
3586 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v16i8, { 2, 1, 1, 1 } },
3587 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v8i16, { 2, 1, 1, 1 } },
3588 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v8i16, { 3, 1, 1, 1 } },
3589 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v8i16, { 1, 1, 1, 1 } },
3590 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v8i16, { 2, 1, 1, 1 } },
3591 { ISD::ZERO_EXTEND, MVT::v2i64, MVT::v4i32, { 1, 1, 1, 1 } },
3592 { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v4i32, { 2, 1, 1, 1 } },
3593
3594 // These truncates are really widening elements.
3595 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i32, { 1, 1, 1, 1 } }, // PSHUFD
3596 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i16, { 2, 1, 1, 1 } }, // PUNPCKLWD+DQ
3597 { ISD::TRUNCATE, MVT::v2i1, MVT::v2i8, { 3, 1, 1, 1 } }, // PUNPCKLBW+WD+PSHUFD
3598 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i16, { 1, 1, 1, 1 } }, // PUNPCKLWD
3599 { ISD::TRUNCATE, MVT::v4i1, MVT::v4i8, { 2, 1, 1, 1 } }, // PUNPCKLBW+WD
3600 { ISD::TRUNCATE, MVT::v8i1, MVT::v8i8, { 1, 1, 1, 1 } }, // PUNPCKLBW
3601
3602 { ISD::TRUNCATE, MVT::v16i8, MVT::v8i16, { 2, 1, 1, 1 } }, // PAND+PACKUSWB
3603 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i16, { 3, 1, 1, 1 } },
3604 { ISD::TRUNCATE, MVT::v16i8, MVT::v4i32, { 3, 1, 1, 1 } }, // PAND+2*PACKUSWB
3605 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i32, { 7, 1, 1, 1 } },
3606 { ISD::TRUNCATE, MVT::v2i16, MVT::v2i32, { 1, 1, 1, 1 } },
3607 { ISD::TRUNCATE, MVT::v8i16, MVT::v4i32, { 3, 1, 1, 1 } },
3608 { ISD::TRUNCATE, MVT::v8i16, MVT::v8i32, { 5, 1, 1, 1 } },
3609 { ISD::TRUNCATE, MVT::v16i16, MVT::v16i32, {10, 1, 1, 1 } },
3610 { ISD::TRUNCATE, MVT::v16i8, MVT::v2i64, { 4, 1, 1, 1 } }, // PAND+3*PACKUSWB
3611 { ISD::TRUNCATE, MVT::v8i16, MVT::v2i64, { 2, 1, 1, 1 } }, // PSHUFD+PSHUFLW
3612 { ISD::TRUNCATE, MVT::v4i32, MVT::v2i64, { 1, 1, 1, 1 } }, // PSHUFD
3613 };
3614
3615 static const TypeConversionCostKindTblEntry F16ConversionTbl[] = {
3616 { ISD::FP_ROUND, MVT::f16, MVT::f32, { 1, 1, 1, 1 } },
3617 { ISD::FP_ROUND, MVT::v8f16, MVT::v8f32, { 1, 1, 1, 1 } },
3618 { ISD::FP_ROUND, MVT::v4f16, MVT::v4f32, { 1, 1, 1, 1 } },
3619 { ISD::FP_EXTEND, MVT::f32, MVT::f16, { 1, 1, 1, 1 } },
3620 { ISD::FP_EXTEND, MVT::f64, MVT::f16, { 2, 1, 1, 1 } }, // vcvtph2ps+vcvtps2pd
3621 { ISD::FP_EXTEND, MVT::v8f32, MVT::v8f16, { 1, 1, 1, 1 } },
3622 { ISD::FP_EXTEND, MVT::v4f32, MVT::v4f16, { 1, 1, 1, 1 } },
3623 { ISD::FP_EXTEND, MVT::v4f64, MVT::v4f16, { 2, 1, 1, 1 } }, // vcvtph2ps+vcvtps2pd
3624 };
3625
3626 // Attempt to map directly to (simple) MVT types to let us match custom entries.
3627 EVT SrcTy = TLI->getValueType(DL, Src);
3628 EVT DstTy = TLI->getValueType(DL, Dst);
3629
3630 // If we're sign-extending a vector comparison result back to the comparison
3631 // width, this will be free without AVX512 (or for 8/16-bit types without
3632 // BWI).
3633 if (!ST->hasAVX512() || (!ST->hasBWI() && DstTy.getScalarSizeInBits() < 32)) {
3634 if (I && Opcode == Instruction::CastOps::SExt &&
3635 SrcTy.isFixedLengthVectorOf(MVT::i1)) {
3636 if (auto *CmpI = dyn_cast<CmpInst>(I->getOperand(0))) {
3637 Type *CmpTy = CmpI->getOperand(0)->getType();
3638 if (CmpTy->getScalarSizeInBits() == DstTy.getScalarSizeInBits())
3639 return TTI::TCC_Free;
3640 }
3641 }
3642 }
3643
3644 // The function getSimpleVT only handles simple value types.
3645 if (SrcTy.isSimple() && DstTy.isSimple()) {
3646 MVT SimpleSrcTy = SrcTy.getSimpleVT();
3647 MVT SimpleDstTy = DstTy.getSimpleVT();
3648
3649 if (ST->useAVX512Regs()) {
3650 if (ST->hasBWI())
3651 if (const auto *Entry = ConvertCostTableLookup(
3652 AVX512BWConversionTbl, ISD, SimpleDstTy, SimpleSrcTy))
3653 if (auto KindCost = Entry->Cost[CostKind])
3654 return *KindCost;
3655
3656 if (ST->hasDQI())
3657 if (const auto *Entry = ConvertCostTableLookup(
3658 AVX512DQConversionTbl, ISD, SimpleDstTy, SimpleSrcTy))
3659 if (auto KindCost = Entry->Cost[CostKind])
3660 return *KindCost;
3661
3662 if (ST->hasAVX512())
3663 if (const auto *Entry = ConvertCostTableLookup(
3664 AVX512FConversionTbl, ISD, SimpleDstTy, SimpleSrcTy))
3665 if (auto KindCost = Entry->Cost[CostKind])
3666 return *KindCost;
3667 }
3668
3669 if (ST->hasBWI())
3670 if (const auto *Entry = ConvertCostTableLookup(
3671 AVX512BWVLConversionTbl, ISD, SimpleDstTy, SimpleSrcTy))
3672 if (auto KindCost = Entry->Cost[CostKind])
3673 return *KindCost;
3674
3675 if (ST->hasDQI())
3676 if (const auto *Entry = ConvertCostTableLookup(
3677 AVX512DQVLConversionTbl, ISD, SimpleDstTy, SimpleSrcTy))
3678 if (auto KindCost = Entry->Cost[CostKind])
3679 return *KindCost;
3680
3681 if (ST->hasAVX512())
3682 if (const auto *Entry = ConvertCostTableLookup(AVX512VLConversionTbl, ISD,
3683 SimpleDstTy, SimpleSrcTy))
3684 if (auto KindCost = Entry->Cost[CostKind])
3685 return *KindCost;
3686
3687 if (ST->hasAVX2()) {
3688 if (const auto *Entry = ConvertCostTableLookup(AVX2ConversionTbl, ISD,
3689 SimpleDstTy, SimpleSrcTy))
3690 if (auto KindCost = Entry->Cost[CostKind])
3691 return *KindCost;
3692 }
3693
3694 if (ST->hasAVX()) {
3695 if (const auto *Entry = ConvertCostTableLookup(AVXConversionTbl, ISD,
3696 SimpleDstTy, SimpleSrcTy))
3697 if (auto KindCost = Entry->Cost[CostKind])
3698 return *KindCost;
3699 }
3700
3701 if (ST->hasF16C()) {
3702 if (const auto *Entry = ConvertCostTableLookup(F16ConversionTbl, ISD,
3703 SimpleDstTy, SimpleSrcTy))
3704 if (auto KindCost = Entry->Cost[CostKind])
3705 return *KindCost;
3706 }
3707
3708 if (ST->hasSSE41()) {
3709 if (const auto *Entry = ConvertCostTableLookup(SSE41ConversionTbl, ISD,
3710 SimpleDstTy, SimpleSrcTy))
3711 if (auto KindCost = Entry->Cost[CostKind])
3712 return *KindCost;
3713 }
3714
3715 if (ST->hasSSE2()) {
3716 if (const auto *Entry = ConvertCostTableLookup(SSE2ConversionTbl, ISD,
3717 SimpleDstTy, SimpleSrcTy))
3718 if (auto KindCost = Entry->Cost[CostKind])
3719 return *KindCost;
3720 }
3721
3722 if ((ISD == ISD::FP_ROUND && SimpleDstTy == MVT::f16) ||
3723 (ISD == ISD::FP_EXTEND && SimpleSrcTy == MVT::f16)) {
3724 // fp16 conversions not covered by any table entries require a libcall.
3725 // Return a large (arbitrary) number to model this.
3726 return InstructionCost(64);
3727 }
3728 }
3729
3730 // Fall back to legalized types.
3731 std::pair<InstructionCost, MVT> LTSrc = getTypeLegalizationCost(Src);
3732 std::pair<InstructionCost, MVT> LTDest = getTypeLegalizationCost(Dst);
3733
3734 // If we're truncating to the same legalized type - just assume its free.
3735 if (ISD == ISD::TRUNCATE && LTSrc.second == LTDest.second)
3736 return TTI::TCC_Free;
3737
3738 if (ST->useAVX512Regs()) {
3739 if (ST->hasBWI())
3740 if (const auto *Entry = ConvertCostTableLookup(
3741 AVX512BWConversionTbl, ISD, LTDest.second, LTSrc.second))
3742 if (auto KindCost = Entry->Cost[CostKind])
3743 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3744
3745 if (ST->hasDQI())
3746 if (const auto *Entry = ConvertCostTableLookup(
3747 AVX512DQConversionTbl, ISD, LTDest.second, LTSrc.second))
3748 if (auto KindCost = Entry->Cost[CostKind])
3749 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3750
3751 if (ST->hasAVX512())
3752 if (const auto *Entry = ConvertCostTableLookup(
3753 AVX512FConversionTbl, ISD, LTDest.second, LTSrc.second))
3754 if (auto KindCost = Entry->Cost[CostKind])
3755 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3756 }
3757
3758 if (ST->hasBWI())
3759 if (const auto *Entry = ConvertCostTableLookup(AVX512BWVLConversionTbl, ISD,
3760 LTDest.second, LTSrc.second))
3761 if (auto KindCost = Entry->Cost[CostKind])
3762 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3763
3764 if (ST->hasDQI())
3765 if (const auto *Entry = ConvertCostTableLookup(AVX512DQVLConversionTbl, ISD,
3766 LTDest.second, LTSrc.second))
3767 if (auto KindCost = Entry->Cost[CostKind])
3768 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3769
3770 if (ST->hasAVX512())
3771 if (const auto *Entry = ConvertCostTableLookup(AVX512VLConversionTbl, ISD,
3772 LTDest.second, LTSrc.second))
3773 if (auto KindCost = Entry->Cost[CostKind])
3774 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3775
3776 if (ST->hasAVX2())
3777 if (const auto *Entry = ConvertCostTableLookup(AVX2ConversionTbl, ISD,
3778 LTDest.second, LTSrc.second))
3779 if (auto KindCost = Entry->Cost[CostKind])
3780 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3781
3782 if (ST->hasAVX())
3783 if (const auto *Entry = ConvertCostTableLookup(AVXConversionTbl, ISD,
3784 LTDest.second, LTSrc.second))
3785 if (auto KindCost = Entry->Cost[CostKind])
3786 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3787
3788 if (ST->hasF16C()) {
3789 if (const auto *Entry = ConvertCostTableLookup(F16ConversionTbl, ISD,
3790 LTDest.second, LTSrc.second))
3791 if (auto KindCost = Entry->Cost[CostKind])
3792 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3793 }
3794
3795 if (ST->hasSSE41())
3796 if (const auto *Entry = ConvertCostTableLookup(SSE41ConversionTbl, ISD,
3797 LTDest.second, LTSrc.second))
3798 if (auto KindCost = Entry->Cost[CostKind])
3799 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3800
3801 if (ST->hasSSE2())
3802 if (const auto *Entry = ConvertCostTableLookup(SSE2ConversionTbl, ISD,
3803 LTDest.second, LTSrc.second))
3804 if (auto KindCost = Entry->Cost[CostKind])
3805 return std::max(LTSrc.first, LTDest.first) * *KindCost;
3806
3807 // Fallback, for i8/i16 sitofp/uitofp cases we need to extend to i32 for
3808 // sitofp.
3809 if ((ISD == ISD::SINT_TO_FP || ISD == ISD::UINT_TO_FP) &&
3810 1 < Src->getScalarSizeInBits() && Src->getScalarSizeInBits() < 32) {
3811 Type *ExtSrc = Src->getWithNewBitWidth(32);
3812 unsigned ExtOpc =
3813 (ISD == ISD::SINT_TO_FP) ? Instruction::SExt : Instruction::ZExt;
3814
3815 // For scalar loads the extend would be free.
3816 InstructionCost ExtCost = 0;
3817 if (!(Src->isIntegerTy() && I && isa<LoadInst>(I->getOperand(0))))
3818 ExtCost = getCastInstrCost(ExtOpc, ExtSrc, Src, CCH, CostKind);
3819
3820 return ExtCost + getCastInstrCost(Instruction::SIToFP, Dst, ExtSrc,
3822 }
3823
3824 // Fallback for fptosi/fptoui i8/i16 cases we need to truncate from fptosi
3825 // i32.
3826 if ((ISD == ISD::FP_TO_SINT || ISD == ISD::FP_TO_UINT) &&
3827 1 < Dst->getScalarSizeInBits() && Dst->getScalarSizeInBits() < 32) {
3828 Type *TruncDst = Dst->getWithNewBitWidth(32);
3829 return getCastInstrCost(Instruction::FPToSI, TruncDst, Src, CCH, CostKind) +
3830 getCastInstrCost(Instruction::Trunc, Dst, TruncDst,
3832 }
3833
3834 // TODO: Allow non-throughput costs that aren't binary.
3835 auto AdjustCost = [&CostKind](InstructionCost Cost,
3838 return Cost == 0 ? 0 : N;
3839 return Cost * N;
3840 };
3841 return AdjustCost(
3842 BaseT::getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I));
3843}
3844
3846 unsigned Opcode, Type *ValTy, Type *CondTy, CmpInst::Predicate VecPred,
3848 TTI::OperandValueInfo Op2Info, const Instruction *I) const {
3849 // Early out if this type isn't scalar/vector integer/float.
3850 if (!(ValTy->isIntOrIntVectorTy() || ValTy->isFPOrFPVectorTy()))
3851 return BaseT::getCmpSelInstrCost(Opcode, ValTy, CondTy, VecPred, CostKind,
3852 Op1Info, Op2Info, I);
3853
3854 // Legalize the type.
3855 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(ValTy);
3856
3857 MVT MTy = LT.second;
3858
3859 int ISD = TLI->InstructionOpcodeToISD(Opcode);
3860 assert(ISD && "Invalid opcode");
3861
3862 InstructionCost ExtraCost = 0;
3863 if (Opcode == Instruction::ICmp || Opcode == Instruction::FCmp) {
3864 // Some vector comparison predicates cost extra instructions.
3865 // TODO: Adjust ExtraCost based on CostKind?
3866 // TODO: Should we invert this and assume worst case cmp costs
3867 // and reduce for particular predicates?
3868 if (MTy.isVector() &&
3869 !((ST->hasXOP() && (!ST->hasAVX2() || MTy.is128BitVector())) ||
3870 (ST->hasAVX512() && 32 <= MTy.getScalarSizeInBits()) ||
3871 ST->hasBWI())) {
3872 // Fallback to I if a specific predicate wasn't specified.
3873 CmpInst::Predicate Pred = VecPred;
3874 if (I && (Pred == CmpInst::BAD_ICMP_PREDICATE ||
3876 Pred = cast<CmpInst>(I)->getPredicate();
3877
3878 bool CmpWithConstant = false;
3879 if (auto *CmpInstr = dyn_cast_or_null<CmpInst>(I))
3880 CmpWithConstant = isa<Constant>(CmpInstr->getOperand(1));
3881
3882 switch (Pred) {
3884 // xor(cmpeq(x,y),-1)
3885 ExtraCost = CmpWithConstant ? 0 : 1;
3886 break;
3889 // xor(cmpgt(x,y),-1)
3890 ExtraCost = CmpWithConstant ? 0 : 1;
3891 break;
3894 // cmpgt(xor(x,signbit),xor(y,signbit))
3895 // xor(cmpeq(pmaxu(x,y),x),-1)
3896 ExtraCost = CmpWithConstant ? 1 : 2;
3897 break;
3900 if ((ST->hasSSE41() && MTy.getScalarSizeInBits() == 32) ||
3901 (ST->hasSSE2() && MTy.getScalarSizeInBits() < 32)) {
3902 // cmpeq(psubus(x,y),0)
3903 // cmpeq(pminu(x,y),x)
3904 ExtraCost = 1;
3905 } else {
3906 // xor(cmpgt(xor(x,signbit),xor(y,signbit)),-1)
3907 ExtraCost = CmpWithConstant ? 2 : 3;
3908 }
3909 break;
3912 // Without AVX we need to expand FCMP_ONE/FCMP_UEQ cases.
3913 // Use FCMP_UEQ expansion - FCMP_ONE should be the same.
3914 if (CondTy && !ST->hasAVX())
3915 return getCmpSelInstrCost(Opcode, ValTy, CondTy,
3917 Op1Info, Op2Info) +
3918 getCmpSelInstrCost(Opcode, ValTy, CondTy,
3920 Op1Info, Op2Info) +
3921 getArithmeticInstrCost(Instruction::Or, CondTy, CostKind);
3922
3923 break;
3926 // Assume worst case scenario and add the maximum extra cost.
3927 ExtraCost = 3;
3928 break;
3929 default:
3930 break;
3931 }
3932 }
3933 }
3934
3935 static const CostKindTblEntry SLMCostTbl[] = {
3936 // slm pcmpeq/pcmpgt throughput is 2
3937 { ISD::SETCC, MVT::v2i64, { 2, 5, 1, 2 } },
3938 // slm pblendvb/blendvpd/blendvps throughput is 4
3939 { ISD::SELECT, MVT::v2f64, { 4, 4, 1, 3 } }, // vblendvpd
3940 { ISD::SELECT, MVT::v4f32, { 4, 4, 1, 3 } }, // vblendvps
3941 { ISD::SELECT, MVT::v2i64, { 4, 4, 1, 3 } }, // pblendvb
3942 { ISD::SELECT, MVT::v8i32, { 4, 4, 1, 3 } }, // pblendvb
3943 { ISD::SELECT, MVT::v8i16, { 4, 4, 1, 3 } }, // pblendvb
3944 { ISD::SELECT, MVT::v16i8, { 4, 4, 1, 3 } }, // pblendvb
3945 };
3946
3947 static const CostKindTblEntry AVX512BWCostTbl[] = {
3948 { ISD::SETCC, MVT::v32i16, { 1, 1, 1, 1 } },
3949 { ISD::SETCC, MVT::v16i16, { 1, 1, 1, 1 } },
3950 { ISD::SETCC, MVT::v64i8, { 1, 1, 1, 1 } },
3951 { ISD::SETCC, MVT::v32i8, { 1, 1, 1, 1 } },
3952
3953 { ISD::SELECT, MVT::v32i16, { 1, 1, 1, 1 } },
3954 { ISD::SELECT, MVT::v64i8, { 1, 1, 1, 1 } },
3955 };
3956
3957 static const CostKindTblEntry AVX512CostTbl[] = {
3958 { ISD::SETCC, MVT::v8f64, { 1, 4, 1, 1 } },
3959 { ISD::SETCC, MVT::v4f64, { 1, 4, 1, 1 } },
3960 { ISD::SETCC, MVT::v16f32, { 1, 4, 1, 1 } },
3961 { ISD::SETCC, MVT::v8f32, { 1, 4, 1, 1 } },
3962
3963 { ISD::SETCC, MVT::v8i64, { 1, 1, 1, 1 } },
3964 { ISD::SETCC, MVT::v4i64, { 1, 1, 1, 1 } },
3965 { ISD::SETCC, MVT::v2i64, { 1, 1, 1, 1 } },
3966 { ISD::SETCC, MVT::v16i32, { 1, 1, 1, 1 } },
3967 { ISD::SETCC, MVT::v8i32, { 1, 1, 1, 1 } },
3968 { ISD::SETCC, MVT::v32i16, { 3, 7, 5, 5 } },
3969 { ISD::SETCC, MVT::v64i8, { 3, 7, 5, 5 } },
3970
3971 { ISD::SELECT, MVT::v8i64, { 1, 1, 1, 1 } },
3972 { ISD::SELECT, MVT::v4i64, { 1, 1, 1, 1 } },
3973 { ISD::SELECT, MVT::v2i64, { 1, 1, 1, 1 } },
3974 { ISD::SELECT, MVT::v16i32, { 1, 1, 1, 1 } },
3975 { ISD::SELECT, MVT::v8i32, { 1, 1, 1, 1 } },
3976 { ISD::SELECT, MVT::v4i32, { 1, 1, 1, 1 } },
3977 { ISD::SELECT, MVT::v8f64, { 1, 1, 1, 1 } },
3978 { ISD::SELECT, MVT::v4f64, { 1, 1, 1, 1 } },
3979 { ISD::SELECT, MVT::v2f64, { 1, 1, 1, 1 } },
3980 { ISD::SELECT, MVT::f64, { 1, 1, 1, 1 } },
3981 { ISD::SELECT, MVT::v16f32, { 1, 1, 1, 1 } },
3982 { ISD::SELECT, MVT::v8f32 , { 1, 1, 1, 1 } },
3983 { ISD::SELECT, MVT::v4f32, { 1, 1, 1, 1 } },
3984 { ISD::SELECT, MVT::f32 , { 1, 1, 1, 1 } },
3985
3986 { ISD::SELECT, MVT::v32i16, { 2, 2, 4, 4 } },
3987 { ISD::SELECT, MVT::v16i16, { 1, 1, 1, 1 } },
3988 { ISD::SELECT, MVT::v8i16, { 1, 1, 1, 1 } },
3989 { ISD::SELECT, MVT::v64i8, { 2, 2, 4, 4 } },
3990 { ISD::SELECT, MVT::v32i8, { 1, 1, 1, 1 } },
3991 { ISD::SELECT, MVT::v16i8, { 1, 1, 1, 1 } },
3992 };
3993
3994 static const CostKindTblEntry AVX2CostTbl[] = {
3995 { ISD::SETCC, MVT::v4f64, { 1, 4, 1, 2 } },
3996 { ISD::SETCC, MVT::v2f64, { 1, 4, 1, 1 } },
3997 { ISD::SETCC, MVT::f64, { 1, 4, 1, 1 } },
3998 { ISD::SETCC, MVT::v8f32, { 1, 4, 1, 2 } },
3999 { ISD::SETCC, MVT::v4f32, { 1, 4, 1, 1 } },
4000 { ISD::SETCC, MVT::f32, { 1, 4, 1, 1 } },
4001
4002 { ISD::SETCC, MVT::v4i64, { 1, 1, 1, 2 } },
4003 { ISD::SETCC, MVT::v8i32, { 1, 1, 1, 2 } },
4004 { ISD::SETCC, MVT::v16i16, { 1, 1, 1, 2 } },
4005 { ISD::SETCC, MVT::v32i8, { 1, 1, 1, 2 } },
4006
4007 { ISD::SELECT, MVT::v4f64, { 2, 2, 1, 2 } }, // vblendvpd
4008 { ISD::SELECT, MVT::v8f32, { 2, 2, 1, 2 } }, // vblendvps
4009 { ISD::SELECT, MVT::v4i64, { 2, 2, 1, 2 } }, // pblendvb
4010 { ISD::SELECT, MVT::v8i32, { 2, 2, 1, 2 } }, // pblendvb
4011 { ISD::SELECT, MVT::v16i16, { 2, 2, 1, 2 } }, // pblendvb
4012 { ISD::SELECT, MVT::v32i8, { 2, 2, 1, 2 } }, // pblendvb
4013 };
4014
4015 static const CostKindTblEntry XOPCostTbl[] = {
4016 { ISD::SETCC, MVT::v4i64, { 4, 2, 5, 6 } },
4017 { ISD::SETCC, MVT::v2i64, { 1, 1, 1, 1 } },
4018 };
4019
4020 static const CostKindTblEntry AVX1CostTbl[] = {
4021 { ISD::SETCC, MVT::v4f64, { 2, 3, 1, 2 } },
4022 { ISD::SETCC, MVT::v2f64, { 1, 3, 1, 1 } },
4023 { ISD::SETCC, MVT::f64, { 1, 3, 1, 1 } },
4024 { ISD::SETCC, MVT::v8f32, { 2, 3, 1, 2 } },
4025 { ISD::SETCC, MVT::v4f32, { 1, 3, 1, 1 } },
4026 { ISD::SETCC, MVT::f32, { 1, 3, 1, 1 } },
4027
4028 // AVX1 does not support 8-wide integer compare.
4029 { ISD::SETCC, MVT::v4i64, { 4, 2, 5, 6 } },
4030 { ISD::SETCC, MVT::v8i32, { 4, 2, 5, 6 } },
4031 { ISD::SETCC, MVT::v16i16, { 4, 2, 5, 6 } },
4032 { ISD::SETCC, MVT::v32i8, { 4, 2, 5, 6 } },
4033
4034 { ISD::SELECT, MVT::v4f64, { 3, 3, 1, 2 } }, // vblendvpd
4035 { ISD::SELECT, MVT::v8f32, { 3, 3, 1, 2 } }, // vblendvps
4036 { ISD::SELECT, MVT::v4i64, { 3, 3, 1, 2 } }, // vblendvpd
4037 { ISD::SELECT, MVT::v8i32, { 3, 3, 1, 2 } }, // vblendvps
4038 { ISD::SELECT, MVT::v16i16, { 3, 3, 3, 3 } }, // vandps + vandnps + vorps
4039 { ISD::SELECT, MVT::v32i8, { 3, 3, 3, 3 } }, // vandps + vandnps + vorps
4040 };
4041
4042 static const CostKindTblEntry SSE42CostTbl[] = {
4043 { ISD::SETCC, MVT::v2i64, { 1, 2, 1, 2 } },
4044 };
4045
4046 static const CostKindTblEntry SSE41CostTbl[] = {
4047 { ISD::SETCC, MVT::v2f64, { 1, 5, 1, 1 } },
4048 { ISD::SETCC, MVT::v4f32, { 1, 5, 1, 1 } },
4049
4050 { ISD::SELECT, MVT::v2f64, { 2, 2, 1, 2 } }, // blendvpd
4051 { ISD::SELECT, MVT::f64, { 2, 2, 1, 2 } }, // blendvpd
4052 { ISD::SELECT, MVT::v4f32, { 2, 2, 1, 2 } }, // blendvps
4053 { ISD::SELECT, MVT::f32 , { 2, 2, 1, 2 } }, // blendvps
4054 { ISD::SELECT, MVT::v2i64, { 2, 2, 1, 2 } }, // pblendvb
4055 { ISD::SELECT, MVT::v4i32, { 2, 2, 1, 2 } }, // pblendvb
4056 { ISD::SELECT, MVT::v8i16, { 2, 2, 1, 2 } }, // pblendvb
4057 { ISD::SELECT, MVT::v16i8, { 2, 2, 1, 2 } }, // pblendvb
4058 };
4059
4060 static const CostKindTblEntry SSE2CostTbl[] = {
4061 { ISD::SETCC, MVT::v2f64, { 2, 5, 1, 1 } },
4062 { ISD::SETCC, MVT::f64, { 1, 5, 1, 1 } },
4063
4064 { ISD::SETCC, MVT::v2i64, { 5, 4, 5, 5 } }, // pcmpeqd/pcmpgtd expansion
4065 { ISD::SETCC, MVT::v4i32, { 1, 1, 1, 1 } },
4066 { ISD::SETCC, MVT::v8i16, { 1, 1, 1, 1 } },
4067 { ISD::SETCC, MVT::v16i8, { 1, 1, 1, 1 } },
4068
4069 { ISD::SELECT, MVT::v2f64, { 2, 2, 3, 3 } }, // andpd + andnpd + orpd
4070 { ISD::SELECT, MVT::f64, { 2, 2, 3, 3 } }, // andpd + andnpd + orpd
4071 { ISD::SELECT, MVT::v2i64, { 2, 2, 3, 3 } }, // pand + pandn + por
4072 { ISD::SELECT, MVT::v4i32, { 2, 2, 3, 3 } }, // pand + pandn + por
4073 { ISD::SELECT, MVT::v8i16, { 2, 2, 3, 3 } }, // pand + pandn + por
4074 { ISD::SELECT, MVT::v16i8, { 2, 2, 3, 3 } }, // pand + pandn + por
4075 };
4076
4077 static const CostKindTblEntry SSE1CostTbl[] = {
4078 { ISD::SETCC, MVT::v4f32, { 2, 5, 1, 1 } },
4079 { ISD::SETCC, MVT::f32, { 1, 5, 1, 1 } },
4080
4081 { ISD::SELECT, MVT::v4f32, { 2, 2, 3, 3 } }, // andps + andnps + orps
4082 { ISD::SELECT, MVT::f32, { 2, 2, 3, 3 } }, // andps + andnps + orps
4083 };
4084
4085 if (ST->useSLMArithCosts())
4086 if (const auto *Entry = CostTableLookup(SLMCostTbl, ISD, MTy))
4087 if (auto KindCost = Entry->Cost[CostKind])
4088 return LT.first * (ExtraCost + *KindCost);
4089
4090 if (ST->hasBWI())
4091 if (const auto *Entry = CostTableLookup(AVX512BWCostTbl, ISD, MTy))
4092 if (auto KindCost = Entry->Cost[CostKind])
4093 return LT.first * (ExtraCost + *KindCost);
4094
4095 if (ST->hasAVX512())
4096 if (const auto *Entry = CostTableLookup(AVX512CostTbl, ISD, MTy))
4097 if (auto KindCost = Entry->Cost[CostKind])
4098 return LT.first * (ExtraCost + *KindCost);
4099
4100 if (ST->hasAVX2())
4101 if (const auto *Entry = CostTableLookup(AVX2CostTbl, ISD, MTy))
4102 if (auto KindCost = Entry->Cost[CostKind])
4103 return LT.first * (ExtraCost + *KindCost);
4104
4105 if (ST->hasXOP())
4106 if (const auto *Entry = CostTableLookup(XOPCostTbl, ISD, MTy))
4107 if (auto KindCost = Entry->Cost[CostKind])
4108 return LT.first * (ExtraCost + *KindCost);
4109
4110 if (ST->hasAVX())
4111 if (const auto *Entry = CostTableLookup(AVX1CostTbl, ISD, MTy))
4112 if (auto KindCost = Entry->Cost[CostKind])
4113 return LT.first * (ExtraCost + *KindCost);
4114
4115 if (ST->hasSSE42())
4116 if (const auto *Entry = CostTableLookup(SSE42CostTbl, ISD, MTy))
4117 if (auto KindCost = Entry->Cost[CostKind])
4118 return LT.first * (ExtraCost + *KindCost);
4119
4120 if (ST->hasSSE41())
4121 if (const auto *Entry = CostTableLookup(SSE41CostTbl, ISD, MTy))
4122 if (auto KindCost = Entry->Cost[CostKind])
4123 return LT.first * (ExtraCost + *KindCost);
4124
4125 if (ST->hasSSE2())
4126 if (const auto *Entry = CostTableLookup(SSE2CostTbl, ISD, MTy))
4127 if (auto KindCost = Entry->Cost[CostKind])
4128 return LT.first * (ExtraCost + *KindCost);
4129
4130 if (ST->hasSSE1())
4131 if (const auto *Entry = CostTableLookup(SSE1CostTbl, ISD, MTy))
4132 if (auto KindCost = Entry->Cost[CostKind])
4133 return LT.first * (ExtraCost + *KindCost);
4134
4135 // Assume a 3cy latency for fp select ops.
4136 if (CostKind == TTI::TCK_Latency && Opcode == Instruction::Select)
4137 if (ValTy->getScalarType()->isFloatingPointTy())
4138 return 3;
4139
4140 return BaseT::getCmpSelInstrCost(Opcode, ValTy, CondTy, VecPred, CostKind,
4141 Op1Info, Op2Info, I);
4142}
4143
4145
4149 // Costs should match the codegen from:
4150 // BITREVERSE: llvm\test\CodeGen\X86\vector-bitreverse.ll
4151 // BSWAP: llvm\test\CodeGen\X86\bswap-vector.ll
4152 // CTLZ: llvm\test\CodeGen\X86\vector-lzcnt-*.ll
4153 // CTPOP: llvm\test\CodeGen\X86\vector-popcnt-*.ll
4154 // CTTZ: llvm\test\CodeGen\X86\vector-tzcnt-*.ll
4155
4156 // TODO: Overflow intrinsics (*ADDO, *SUBO, *MULO) with vector types are not
4157 // specialized in these tables yet.
4158 static const CostKindTblEntry AVX512VBMI2CostTbl[] = {
4159 { ISD::FSHL, MVT::v8i64, { 1, 1, 1, 1 } },
4160 { ISD::FSHL, MVT::v4i64, { 1, 1, 1, 1 } },
4161 { ISD::FSHL, MVT::v2i64, { 1, 1, 1, 1 } },
4162 { ISD::FSHL, MVT::v16i32, { 1, 1, 1, 1 } },
4163 { ISD::FSHL, MVT::v8i32, { 1, 1, 1, 1 } },
4164 { ISD::FSHL, MVT::v4i32, { 1, 1, 1, 1 } },
4165 { ISD::FSHL, MVT::v32i16, { 1, 1, 1, 1 } },
4166 { ISD::FSHL, MVT::v16i16, { 1, 1, 1, 1 } },
4167 { ISD::FSHL, MVT::v8i16, { 1, 1, 1, 1 } },
4168 { ISD::ROTL, MVT::v32i16, { 1, 1, 1, 1 } },
4169 { ISD::ROTL, MVT::v16i16, { 1, 1, 1, 1 } },
4170 { ISD::ROTL, MVT::v8i16, { 1, 1, 1, 1 } },
4171 { ISD::ROTR, MVT::v32i16, { 1, 1, 1, 1 } },
4172 { ISD::ROTR, MVT::v16i16, { 1, 1, 1, 1 } },
4173 { ISD::ROTR, MVT::v8i16, { 1, 1, 1, 1 } },
4174 { X86ISD::VROTLI, MVT::v32i16, { 1, 1, 1, 1 } },
4175 { X86ISD::VROTLI, MVT::v16i16, { 1, 1, 1, 1 } },
4176 { X86ISD::VROTLI, MVT::v8i16, { 1, 1, 1, 1 } },
4177 };
4178 static const CostKindTblEntry AVX512BITALGCostTbl[] = {
4179 { ISD::CTPOP, MVT::v32i16, { 1, 1, 1, 1 } },
4180 { ISD::CTPOP, MVT::v64i8, { 1, 1, 1, 1 } },
4181 { ISD::CTPOP, MVT::v16i16, { 1, 1, 1, 1 } },
4182 { ISD::CTPOP, MVT::v32i8, { 1, 1, 1, 1 } },
4183 { ISD::CTPOP, MVT::v8i16, { 1, 1, 1, 1 } },
4184 { ISD::CTPOP, MVT::v16i8, { 1, 1, 1, 1 } },
4185 };
4186 static const CostKindTblEntry AVX512VPOPCNTDQCostTbl[] = {
4187 { ISD::CTPOP, MVT::v8i64, { 1, 1, 1, 1 } },
4188 { ISD::CTPOP, MVT::v16i32, { 1, 1, 1, 1 } },
4189 { ISD::CTPOP, MVT::v4i64, { 1, 1, 1, 1 } },
4190 { ISD::CTPOP, MVT::v8i32, { 1, 1, 1, 1 } },
4191 { ISD::CTPOP, MVT::v2i64, { 1, 1, 1, 1 } },
4192 { ISD::CTPOP, MVT::v4i32, { 1, 1, 1, 1 } },
4193 };
4194 static const CostKindTblEntry AVX512CDCostTbl[] = {
4195 { ISD::CTLZ, MVT::v8i64, { 1, 5, 1, 1 } },
4196 { ISD::CTLZ, MVT::v16i32, { 1, 5, 1, 1 } },
4197 { ISD::CTLZ, MVT::v32i16, { 18, 27, 23, 27 } },
4198 { ISD::CTLZ, MVT::v64i8, { 3, 16, 9, 11 } },
4199 { ISD::CTLZ, MVT::v4i64, { 1, 5, 1, 1 } },
4200 { ISD::CTLZ, MVT::v8i32, { 1, 5, 1, 1 } },
4201 { ISD::CTLZ, MVT::v16i16, { 8, 19, 11, 13 } },
4202 { ISD::CTLZ, MVT::v32i8, { 2, 11, 9, 10 } },
4203 { ISD::CTLZ, MVT::v2i64, { 1, 5, 1, 1 } },
4204 { ISD::CTLZ, MVT::v4i32, { 1, 5, 1, 1 } },
4205 { ISD::CTLZ, MVT::v8i16, { 3, 15, 4, 6 } },
4206 { ISD::CTLZ, MVT::v16i8, { 2, 10, 9, 10 } },
4207
4208 { ISD::CTTZ, MVT::v8i64, { 2, 8, 6, 7 } },
4209 { ISD::CTTZ, MVT::v16i32, { 2, 8, 6, 7 } },
4210 { ISD::CTTZ, MVT::v4i64, { 1, 8, 6, 6 } },
4211 { ISD::CTTZ, MVT::v8i32, { 1, 8, 6, 6 } },
4212 { ISD::CTTZ, MVT::v2i64, { 1, 8, 6, 6 } },
4213 { ISD::CTTZ, MVT::v4i32, { 1, 8, 6, 6 } },
4214 };
4215 static const CostKindTblEntry AVX512BWCostTbl[] = {
4216 { ISD::ABS, MVT::v32i16, { 1, 1, 1, 1 } },
4217 { ISD::ABS, MVT::v64i8, { 1, 1, 1, 1 } },
4218 { ISD::BITREVERSE, MVT::v2i64, { 3, 10, 10, 11 } },
4219 { ISD::BITREVERSE, MVT::v4i64, { 3, 11, 10, 11 } },
4220 { ISD::BITREVERSE, MVT::v8i64, { 3, 12, 10, 14 } },
4221 { ISD::BITREVERSE, MVT::v4i32, { 3, 10, 10, 11 } },
4222 { ISD::BITREVERSE, MVT::v8i32, { 3, 11, 10, 11 } },
4223 { ISD::BITREVERSE, MVT::v16i32, { 3, 12, 10, 14 } },
4224 { ISD::BITREVERSE, MVT::v8i16, { 3, 10, 10, 11 } },
4225 { ISD::BITREVERSE, MVT::v16i16, { 3, 11, 10, 11 } },
4226 { ISD::BITREVERSE, MVT::v32i16, { 3, 12, 10, 14 } },
4227 { ISD::BITREVERSE, MVT::v16i8, { 2, 5, 9, 9 } },
4228 { ISD::BITREVERSE, MVT::v32i8, { 2, 5, 9, 9 } },
4229 { ISD::BITREVERSE, MVT::v64i8, { 2, 5, 9, 12 } },
4230 { ISD::BSWAP, MVT::v2i64, { 1, 1, 1, 2 } },
4231 { ISD::BSWAP, MVT::v4i64, { 1, 1, 1, 2 } },
4232 { ISD::BSWAP, MVT::v8i64, { 1, 1, 1, 2 } },
4233 { ISD::BSWAP, MVT::v4i32, { 1, 1, 1, 2 } },
4234 { ISD::BSWAP, MVT::v8i32, { 1, 1, 1, 2 } },
4235 { ISD::BSWAP, MVT::v16i32, { 1, 1, 1, 2 } },
4236 { ISD::BSWAP, MVT::v8i16, { 1, 1, 1, 2 } },
4237 { ISD::BSWAP, MVT::v16i16, { 1, 1, 1, 2 } },
4238 { ISD::BSWAP, MVT::v32i16, { 1, 1, 1, 2 } },
4239 { ISD::CTLZ, MVT::v8i64, { 8, 22, 23, 23 } },
4240 { ISD::CTLZ, MVT::v16i32, { 8, 23, 25, 25 } },
4241 { ISD::CTLZ, MVT::v32i16, { 4, 15, 15, 16 } },
4242 { ISD::CTLZ, MVT::v64i8, { 3, 12, 10, 9 } },
4243 { ISD::CTPOP, MVT::v2i64, { 3, 7, 10, 10 } },
4244 { ISD::CTPOP, MVT::v4i64, { 3, 7, 10, 10 } },
4245 { ISD::CTPOP, MVT::v8i64, { 3, 8, 10, 12 } },
4246 { ISD::CTPOP, MVT::v4i32, { 7, 11, 14, 14 } },
4247 { ISD::CTPOP, MVT::v8i32, { 7, 11, 14, 14 } },
4248 { ISD::CTPOP, MVT::v16i32, { 7, 12, 14, 16 } },
4249 { ISD::CTPOP, MVT::v8i16, { 2, 7, 11, 11 } },
4250 { ISD::CTPOP, MVT::v16i16, { 2, 7, 11, 11 } },
4251 { ISD::CTPOP, MVT::v32i16, { 3, 7, 11, 13 } },
4252 { ISD::CTPOP, MVT::v16i8, { 2, 4, 8, 8 } },
4253 { ISD::CTPOP, MVT::v32i8, { 2, 4, 8, 8 } },
4254 { ISD::CTPOP, MVT::v64i8, { 2, 5, 8, 10 } },
4255 { ISD::CTTZ, MVT::v8i16, { 3, 9, 14, 14 } },
4256 { ISD::CTTZ, MVT::v16i16, { 3, 9, 14, 14 } },
4257 { ISD::CTTZ, MVT::v32i16, { 3, 10, 14, 16 } },
4258 { ISD::CTTZ, MVT::v16i8, { 2, 6, 11, 11 } },
4259 { ISD::CTTZ, MVT::v32i8, { 2, 6, 11, 11 } },
4260 { ISD::CTTZ, MVT::v64i8, { 3, 7, 11, 13 } },
4261 { ISD::ROTL, MVT::v32i16, { 2, 8, 6, 8 } },
4262 { ISD::ROTL, MVT::v16i16, { 2, 8, 6, 7 } },
4263 { ISD::ROTL, MVT::v8i16, { 2, 7, 6, 7 } },
4264 { ISD::ROTL, MVT::v64i8, { 5, 6, 11, 12 } },
4265 { ISD::ROTL, MVT::v32i8, { 5, 15, 7, 10 } },
4266 { ISD::ROTL, MVT::v16i8, { 5, 15, 7, 10 } },
4267 { ISD::ROTR, MVT::v32i16, { 2, 8, 6, 8 } },
4268 { ISD::ROTR, MVT::v16i16, { 2, 8, 6, 7 } },
4269 { ISD::ROTR, MVT::v8i16, { 2, 7, 6, 7 } },
4270 { ISD::ROTR, MVT::v64i8, { 5, 6, 12, 14 } },
4271 { ISD::ROTR, MVT::v32i8, { 5, 14, 6, 9 } },
4272 { ISD::ROTR, MVT::v16i8, { 5, 14, 6, 9 } },
4273 { X86ISD::VROTLI, MVT::v32i16, { 2, 5, 3, 3 } },
4274 { X86ISD::VROTLI, MVT::v16i16, { 1, 5, 3, 3 } },
4275 { X86ISD::VROTLI, MVT::v8i16, { 1, 5, 3, 3 } },
4276 { X86ISD::VROTLI, MVT::v64i8, { 2, 9, 3, 4 } },
4277 { X86ISD::VROTLI, MVT::v32i8, { 1, 9, 3, 4 } },
4278 { X86ISD::VROTLI, MVT::v16i8, { 1, 8, 3, 4 } },
4279 { ISD::SADDSAT, MVT::v32i16, { 1, 1, 1, 1 } },
4280 { ISD::SADDSAT, MVT::v64i8, { 1, 1, 1, 1 } },
4281 { ISD::SMAX, MVT::v32i16, { 1, 1, 1, 1 } },
4282 { ISD::SMAX, MVT::v64i8, { 1, 1, 1, 1 } },
4283 { ISD::SMIN, MVT::v32i16, { 1, 1, 1, 1 } },
4284 { ISD::SMIN, MVT::v64i8, { 1, 1, 1, 1 } },
4285 { ISD::SMULO, MVT::v32i16, { 3, 6, 4, 4 } },
4286 { ISD::SMULO, MVT::v64i8, { 8, 21, 17, 18 } },
4287 { ISD::UMULO, MVT::v32i16, { 2, 5, 3, 3 } },
4288 { ISD::UMULO, MVT::v64i8, { 8, 15, 15, 16 } },
4289 { ISD::SSUBSAT, MVT::v32i16, { 1, 1, 1, 1 } },
4290 { ISD::SSUBSAT, MVT::v64i8, { 1, 1, 1, 1 } },
4291 { ISD::UADDSAT, MVT::v32i16, { 1, 1, 1, 1 } },
4292 { ISD::UADDSAT, MVT::v64i8, { 1, 1, 1, 1 } },
4293 { ISD::UMAX, MVT::v32i16, { 1, 1, 1, 1 } },
4294 { ISD::UMAX, MVT::v64i8, { 1, 1, 1, 1 } },
4295 { ISD::UMIN, MVT::v32i16, { 1, 1, 1, 1 } },
4296 { ISD::UMIN, MVT::v64i8, { 1, 1, 1, 1 } },
4297 { ISD::USUBSAT, MVT::v32i16, { 1, 1, 1, 1 } },
4298 { ISD::USUBSAT, MVT::v64i8, { 1, 1, 1, 1 } },
4299 };
4300 static const CostKindTblEntry AVX512CostTbl[] = {
4301 { ISD::ABS, MVT::v8i64, { 1, 1, 1, 1 } },
4302 { ISD::ABS, MVT::v4i64, { 1, 1, 1, 1 } },
4303 { ISD::ABS, MVT::v2i64, { 1, 1, 1, 1 } },
4304 { ISD::ABS, MVT::v16i32, { 1, 1, 1, 1 } },
4305 { ISD::ABS, MVT::v8i32, { 1, 1, 1, 1 } },
4306 { ISD::ABS, MVT::v32i16, { 2, 7, 4, 4 } },
4307 { ISD::ABS, MVT::v16i16, { 1, 1, 1, 1 } },
4308 { ISD::ABS, MVT::v64i8, { 2, 7, 4, 4 } },
4309 { ISD::ABS, MVT::v32i8, { 1, 1, 1, 1 } },
4310 { ISD::BITREVERSE, MVT::v8i64, { 9, 13, 20, 20 } },
4311 { ISD::BITREVERSE, MVT::v16i32, { 9, 13, 20, 20 } },
4312 { ISD::BITREVERSE, MVT::v32i16, { 9, 13, 20, 20 } },
4313 { ISD::BITREVERSE, MVT::v64i8, { 6, 11, 17, 17 } },
4314 { ISD::BSWAP, MVT::v8i64, { 4, 7, 5, 5 } },
4315 { ISD::BSWAP, MVT::v16i32, { 4, 7, 5, 5 } },
4316 { ISD::BSWAP, MVT::v32i16, { 4, 7, 5, 5 } },
4317 { ISD::CTLZ, MVT::v8i64, { 10, 28, 32, 32 } },
4318 { ISD::CTLZ, MVT::v16i32, { 12, 30, 38, 38 } },
4319 { ISD::CTLZ, MVT::v32i16, { 8, 15, 29, 29 } },
4320 { ISD::CTLZ, MVT::v64i8, { 6, 11, 19, 19 } },
4321 { ISD::CTPOP, MVT::v8i64, { 16, 16, 19, 19 } },
4322 { ISD::CTPOP, MVT::v16i32, { 24, 19, 27, 27 } },
4323 { ISD::CTPOP, MVT::v32i16, { 18, 15, 22, 22 } },
4324 { ISD::CTPOP, MVT::v64i8, { 12, 11, 16, 16 } },
4325 { ISD::CTTZ, MVT::v8i64, { 2, 8, 6, 7 } },
4326 { ISD::CTTZ, MVT::v16i32, { 2, 8, 6, 7 } },
4327 { ISD::CTTZ, MVT::v32i16, { 7, 17, 27, 27 } },
4328 { ISD::CTTZ, MVT::v64i8, { 6, 13, 21, 21 } },
4329 { ISD::ROTL, MVT::v8i64, { 1, 1, 1, 1 } },
4330 { ISD::ROTL, MVT::v4i64, { 1, 1, 1, 1 } },
4331 { ISD::ROTL, MVT::v2i64, { 1, 1, 1, 1 } },
4332 { ISD::ROTL, MVT::v16i32, { 1, 1, 1, 1 } },
4333 { ISD::ROTL, MVT::v8i32, { 1, 1, 1, 1 } },
4334 { ISD::ROTL, MVT::v4i32, { 1, 1, 1, 1 } },
4335 { ISD::ROTR, MVT::v8i64, { 1, 1, 1, 1 } },
4336 { ISD::ROTR, MVT::v4i64, { 1, 1, 1, 1 } },
4337 { ISD::ROTR, MVT::v2i64, { 1, 1, 1, 1 } },
4338 { ISD::ROTR, MVT::v16i32, { 1, 1, 1, 1 } },
4339 { ISD::ROTR, MVT::v8i32, { 1, 1, 1, 1 } },
4340 { ISD::ROTR, MVT::v4i32, { 1, 1, 1, 1 } },
4341 { X86ISD::VROTLI, MVT::v8i64, { 1, 1, 1, 1 } },
4342 { X86ISD::VROTLI, MVT::v4i64, { 1, 1, 1, 1 } },
4343 { X86ISD::VROTLI, MVT::v2i64, { 1, 1, 1, 1 } },
4344 { X86ISD::VROTLI, MVT::v16i32, { 1, 1, 1, 1 } },
4345 { X86ISD::VROTLI, MVT::v8i32, { 1, 1, 1, 1 } },
4346 { X86ISD::VROTLI, MVT::v4i32, { 1, 1, 1, 1 } },
4347 { ISD::SADDSAT, MVT::v2i64, { 3, 3, 8, 9 } },
4348 { ISD::SADDSAT, MVT::v4i64, { 2, 2, 6, 7 } },
4349 { ISD::SADDSAT, MVT::v8i64, { 3, 3, 6, 7 } },
4350 { ISD::SADDSAT, MVT::v4i32, { 2, 2, 6, 7 } },
4351 { ISD::SADDSAT, MVT::v8i32, { 2, 2, 6, 7 } },
4352 { ISD::SADDSAT, MVT::v16i32, { 3, 3, 6, 7 } },
4353 { ISD::SADDSAT, MVT::v32i16, { 2, 2, 2, 2 } },
4354 { ISD::SADDSAT, MVT::v64i8, { 2, 2, 2, 2 } },
4355 { ISD::SMAX, MVT::v8i64, { 1, 3, 1, 1 } },
4356 { ISD::SMAX, MVT::v16i32, { 1, 1, 1, 1 } },
4357 { ISD::SMAX, MVT::v32i16, { 3, 7, 5, 5 } },
4358 { ISD::SMAX, MVT::v64i8, { 3, 7, 5, 5 } },
4359 { ISD::SMAX, MVT::v4i64, { 1, 3, 1, 1 } },
4360 { ISD::SMAX, MVT::v2i64, { 1, 3, 1, 1 } },
4361 { ISD::SMIN, MVT::v8i64, { 1, 3, 1, 1 } },
4362 { ISD::SMIN, MVT::v16i32, { 1, 1, 1, 1 } },
4363 { ISD::SMIN, MVT::v32i16, { 3, 7, 5, 5 } },
4364 { ISD::SMIN, MVT::v64i8, { 3, 7, 5, 5 } },
4365 { ISD::SMIN, MVT::v4i64, { 1, 3, 1, 1 } },
4366 { ISD::SMIN, MVT::v2i64, { 1, 3, 1, 1 } },
4367 { ISD::SMULO, MVT::v8i64, { 44, 44, 81, 93 } },
4368 { ISD::SMULO, MVT::v16i32, { 5, 12, 9, 11 } },
4369 { ISD::SMULO, MVT::v32i16, { 6, 12, 17, 17 } },
4370 { ISD::SMULO, MVT::v64i8, { 22, 28, 42, 42 } },
4371 { ISD::SSUBSAT, MVT::v2i64, { 2, 13, 9, 10 } },
4372 { ISD::SSUBSAT, MVT::v4i64, { 2, 15, 7, 8 } },
4373 { ISD::SSUBSAT, MVT::v8i64, { 2, 14, 7, 8 } },
4374 { ISD::SSUBSAT, MVT::v4i32, { 2, 14, 7, 8 } },
4375 { ISD::SSUBSAT, MVT::v8i32, { 2, 15, 7, 8 } },
4376 { ISD::SSUBSAT, MVT::v16i32, { 2, 14, 7, 8 } },
4377 { ISD::SSUBSAT, MVT::v32i16, { 2, 2, 2, 2 } },
4378 { ISD::SSUBSAT, MVT::v64i8, { 2, 2, 2, 2 } },
4379 { ISD::UMAX, MVT::v8i64, { 1, 3, 1, 1 } },
4380 { ISD::UMAX, MVT::v16i32, { 1, 1, 1, 1 } },
4381 { ISD::UMAX, MVT::v32i16, { 3, 7, 5, 5 } },
4382 { ISD::UMAX, MVT::v64i8, { 3, 7, 5, 5 } },
4383 { ISD::UMAX, MVT::v4i64, { 1, 3, 1, 1 } },
4384 { ISD::UMAX, MVT::v2i64, { 1, 3, 1, 1 } },
4385 { ISD::UMIN, MVT::v8i64, { 1, 3, 1, 1 } },
4386 { ISD::UMIN, MVT::v16i32, { 1, 1, 1, 1 } },
4387 { ISD::UMIN, MVT::v32i16, { 3, 7, 5, 5 } },
4388 { ISD::UMIN, MVT::v64i8, { 3, 7, 5, 5 } },
4389 { ISD::UMIN, MVT::v4i64, { 1, 3, 1, 1 } },
4390 { ISD::UMIN, MVT::v2i64, { 1, 3, 1, 1 } },
4391 { ISD::UMULO, MVT::v8i64, { 52, 52, 95, 104} },
4392 { ISD::UMULO, MVT::v16i32, { 5, 12, 8, 10 } },
4393 { ISD::UMULO, MVT::v32i16, { 5, 13, 16, 16 } },
4394 { ISD::UMULO, MVT::v64i8, { 18, 24, 30, 30 } },
4395 { ISD::UADDSAT, MVT::v2i64, { 1, 4, 4, 4 } },
4396 { ISD::UADDSAT, MVT::v4i64, { 1, 4, 4, 4 } },
4397 { ISD::UADDSAT, MVT::v8i64, { 1, 4, 4, 4 } },
4398 { ISD::UADDSAT, MVT::v4i32, { 1, 2, 4, 4 } },
4399 { ISD::UADDSAT, MVT::v8i32, { 1, 2, 4, 4 } },
4400 { ISD::UADDSAT, MVT::v16i32, { 2, 2, 4, 4 } },
4401 { ISD::UADDSAT, MVT::v32i16, { 2, 2, 2, 2 } },
4402 { ISD::UADDSAT, MVT::v64i8, { 2, 2, 2, 2 } },
4403 { ISD::USUBSAT, MVT::v2i64, { 1, 4, 2, 2 } },
4404 { ISD::USUBSAT, MVT::v4i64, { 1, 4, 2, 2 } },
4405 { ISD::USUBSAT, MVT::v8i64, { 1, 4, 2, 2 } },
4406 { ISD::USUBSAT, MVT::v8i32, { 1, 2, 2, 2 } },
4407 { ISD::USUBSAT, MVT::v16i32, { 1, 2, 2, 2 } },
4408 { ISD::USUBSAT, MVT::v32i16, { 2, 2, 2, 2 } },
4409 { ISD::USUBSAT, MVT::v64i8, { 2, 2, 2, 2 } },
4410 { ISD::FMAXNUM, MVT::f32, { 2, 2, 3, 3 } },
4411 { ISD::FMAXNUM, MVT::v4f32, { 1, 1, 3, 3 } },
4412 { ISD::FMAXNUM, MVT::v8f32, { 2, 2, 3, 3 } },
4413 { ISD::FMAXNUM, MVT::v16f32, { 4, 4, 3, 3 } },
4414 { ISD::FMAXNUM, MVT::f64, { 2, 2, 3, 3 } },
4415 { ISD::FMAXNUM, MVT::v2f64, { 1, 1, 3, 3 } },
4416 { ISD::FMAXNUM, MVT::v4f64, { 2, 2, 3, 3 } },
4417 { ISD::FMAXNUM, MVT::v8f64, { 3, 3, 3, 3 } },
4418 { ISD::FSQRT, MVT::f32, { 3, 12, 1, 1 } }, // Skylake from http://www.agner.org/
4419 { ISD::FSQRT, MVT::v4f32, { 3, 12, 1, 1 } }, // Skylake from http://www.agner.org/
4420 { ISD::FSQRT, MVT::v8f32, { 6, 12, 1, 1 } }, // Skylake from http://www.agner.org/
4421 { ISD::FSQRT, MVT::v16f32, { 12, 20, 1, 3 } }, // Skylake from http://www.agner.org/
4422 { ISD::FSQRT, MVT::f64, { 6, 18, 1, 1 } }, // Skylake from http://www.agner.org/
4423 { ISD::FSQRT, MVT::v2f64, { 6, 18, 1, 1 } }, // Skylake from http://www.agner.org/
4424 { ISD::FSQRT, MVT::v4f64, { 12, 18, 1, 1 } }, // Skylake from http://www.agner.org/
4425 { ISD::FSQRT, MVT::v8f64, { 24, 32, 1, 3 } }, // Skylake from http://www.agner.org/
4426 };
4427 static const CostKindTblEntry XOPCostTbl[] = {
4428 { ISD::BITREVERSE, MVT::v4i64, { 3, 6, 5, 6 } },
4429 { ISD::BITREVERSE, MVT::v8i32, { 3, 6, 5, 6 } },
4430 { ISD::BITREVERSE, MVT::v16i16, { 3, 6, 5, 6 } },
4431 { ISD::BITREVERSE, MVT::v32i8, { 3, 6, 5, 6 } },
4432 { ISD::BITREVERSE, MVT::v2i64, { 2, 7, 1, 1 } },
4433 { ISD::BITREVERSE, MVT::v4i32, { 2, 7, 1, 1 } },
4434 { ISD::BITREVERSE, MVT::v8i16, { 2, 7, 1, 1 } },
4435 { ISD::BITREVERSE, MVT::v16i8, { 2, 7, 1, 1 } },
4436 { ISD::BITREVERSE, MVT::i64, { 2, 2, 3, 4 } },
4437 { ISD::BITREVERSE, MVT::i32, { 2, 2, 3, 4 } },
4438 { ISD::BITREVERSE, MVT::i16, { 2, 2, 3, 4 } },
4439 { ISD::BITREVERSE, MVT::i8, { 2, 2, 3, 4 } },
4440 // XOP: ROTL = VPROT(X,Y), ROTR = VPROT(X,SUB(0,Y))
4441 { ISD::ROTL, MVT::v4i64, { 4, 7, 5, 6 } },
4442 { ISD::ROTL, MVT::v8i32, { 4, 7, 5, 6 } },
4443 { ISD::ROTL, MVT::v16i16, { 4, 7, 5, 6 } },
4444 { ISD::ROTL, MVT::v32i8, { 4, 7, 5, 6 } },
4445 { ISD::ROTL, MVT::v2i64, { 1, 3, 1, 1 } },
4446 { ISD::ROTL, MVT::v4i32, { 1, 3, 1, 1 } },
4447 { ISD::ROTL, MVT::v8i16, { 1, 3, 1, 1 } },
4448 { ISD::ROTL, MVT::v16i8, { 1, 3, 1, 1 } },
4449 { ISD::ROTR, MVT::v4i64, { 4, 7, 8, 9 } },
4450 { ISD::ROTR, MVT::v8i32, { 4, 7, 8, 9 } },
4451 { ISD::ROTR, MVT::v16i16, { 4, 7, 8, 9 } },
4452 { ISD::ROTR, MVT::v32i8, { 4, 7, 8, 9 } },
4453 { ISD::ROTR, MVT::v2i64, { 1, 3, 3, 3 } },
4454 { ISD::ROTR, MVT::v4i32, { 1, 3, 3, 3 } },
4455 { ISD::ROTR, MVT::v8i16, { 1, 3, 3, 3 } },
4456 { ISD::ROTR, MVT::v16i8, { 1, 3, 3, 3 } },
4457 { X86ISD::VROTLI, MVT::v4i64, { 4, 7, 5, 6 } },
4458 { X86ISD::VROTLI, MVT::v8i32, { 4, 7, 5, 6 } },
4459 { X86ISD::VROTLI, MVT::v16i16, { 4, 7, 5, 6 } },
4460 { X86ISD::VROTLI, MVT::v32i8, { 4, 7, 5, 6 } },
4461 { X86ISD::VROTLI, MVT::v2i64, { 1, 3, 1, 1 } },
4462 { X86ISD::VROTLI, MVT::v4i32, { 1, 3, 1, 1 } },
4463 { X86ISD::VROTLI, MVT::v8i16, { 1, 3, 1, 1 } },
4464 { X86ISD::VROTLI, MVT::v16i8, { 1, 3, 1, 1 } },
4465 };
4466 static const CostKindTblEntry AVX2CostTbl[] = {
4467 { ISD::ABS, MVT::v2i64, { 2, 4, 3, 5 } }, // VBLENDVPD(X,VPSUBQ(0,X),X)
4468 { ISD::ABS, MVT::v4i64, { 2, 4, 3, 5 } }, // VBLENDVPD(X,VPSUBQ(0,X),X)
4469 { ISD::ABS, MVT::v4i32, { 1, 1, 1, 1 } },
4470 { ISD::ABS, MVT::v8i32, { 1, 1, 1, 2 } },
4471 { ISD::ABS, MVT::v8i16, { 1, 1, 1, 1 } },
4472 { ISD::ABS, MVT::v16i16, { 1, 1, 1, 2 } },
4473 { ISD::ABS, MVT::v16i8, { 1, 1, 1, 1 } },
4474 { ISD::ABS, MVT::v32i8, { 1, 1, 1, 2 } },
4475 { ISD::BITREVERSE, MVT::v2i64, { 3, 11, 10, 11 } },
4476 { ISD::BITREVERSE, MVT::v4i64, { 5, 11, 10, 17 } },
4477 { ISD::BITREVERSE, MVT::v4i32, { 3, 11, 10, 11 } },
4478 { ISD::BITREVERSE, MVT::v8i32, { 5, 11, 10, 17 } },
4479 { ISD::BITREVERSE, MVT::v8i16, { 3, 11, 10, 11 } },
4480 { ISD::BITREVERSE, MVT::v16i16, { 5, 11, 10, 17 } },
4481 { ISD::BITREVERSE, MVT::v16i8, { 3, 6, 9, 9 } },
4482 { ISD::BITREVERSE, MVT::v32i8, { 4, 5, 9, 15 } },
4483 { ISD::BSWAP, MVT::v2i64, { 1, 2, 1, 2 } },
4484 { ISD::BSWAP, MVT::v4i64, { 1, 3, 1, 2 } },
4485 { ISD::BSWAP, MVT::v4i32, { 1, 2, 1, 2 } },
4486 { ISD::BSWAP, MVT::v8i32, { 1, 3, 1, 2 } },
4487 { ISD::BSWAP, MVT::v8i16, { 1, 2, 1, 2 } },
4488 { ISD::BSWAP, MVT::v16i16, { 1, 3, 1, 2 } },
4489 { ISD::CTLZ, MVT::v2i64, { 7, 18, 24, 25 } },
4490 { ISD::CTLZ, MVT::v4i64, { 14, 18, 24, 44 } },
4491 { ISD::CTLZ, MVT::v4i32, { 5, 16, 19, 20 } },
4492 { ISD::CTLZ, MVT::v8i32, { 10, 16, 19, 34 } },
4493 { ISD::CTLZ, MVT::v8i16, { 4, 13, 14, 15 } },
4494 { ISD::CTLZ, MVT::v16i16, { 6, 14, 14, 24 } },
4495 { ISD::CTLZ, MVT::v16i8, { 3, 12, 9, 10 } },
4496 { ISD::CTLZ, MVT::v32i8, { 4, 12, 9, 14 } },
4497 { ISD::CTPOP, MVT::v2i64, { 3, 9, 10, 10 } },
4498 { ISD::CTPOP, MVT::v4i64, { 4, 9, 10, 14 } },
4499 { ISD::CTPOP, MVT::v4i32, { 7, 12, 14, 14 } },
4500 { ISD::CTPOP, MVT::v8i32, { 7, 12, 14, 18 } },
4501 { ISD::CTPOP, MVT::v8i16, { 3, 7, 11, 11 } },
4502 { ISD::CTPOP, MVT::v16i16, { 6, 8, 11, 18 } },
4503 { ISD::CTPOP, MVT::v16i8, { 2, 5, 8, 8 } },
4504 { ISD::CTPOP, MVT::v32i8, { 3, 5, 8, 12 } },
4505 { ISD::CTTZ, MVT::v2i64, { 4, 11, 13, 13 } },
4506 { ISD::CTTZ, MVT::v4i64, { 5, 11, 13, 20 } },
4507 { ISD::CTTZ, MVT::v4i32, { 7, 14, 17, 17 } },
4508 { ISD::CTTZ, MVT::v8i32, { 7, 15, 17, 24 } },
4509 { ISD::CTTZ, MVT::v8i16, { 4, 9, 14, 14 } },
4510 { ISD::CTTZ, MVT::v16i16, { 6, 9, 14, 24 } },
4511 { ISD::CTTZ, MVT::v16i8, { 3, 7, 11, 11 } },
4512 { ISD::CTTZ, MVT::v32i8, { 5, 7, 11, 18 } },
4513 { ISD::SADDSAT, MVT::v2i64, { 4, 13, 8, 11 } },
4514 { ISD::SADDSAT, MVT::v4i64, { 3, 10, 8, 12 } },
4515 { ISD::SADDSAT, MVT::v4i32, { 2, 6, 7, 9 } },
4516 { ISD::SADDSAT, MVT::v8i32, { 4, 6, 7, 13 } },
4517 { ISD::SADDSAT, MVT::v16i16, { 1, 1, 1, 2 } },
4518 { ISD::SADDSAT, MVT::v32i8, { 1, 1, 1, 2 } },
4519 { ISD::SMAX, MVT::v2i64, { 2, 7, 2, 3 } },
4520 { ISD::SMAX, MVT::v4i64, { 2, 7, 2, 3 } },
4521 { ISD::SMAX, MVT::v8i32, { 1, 1, 1, 2 } },
4522 { ISD::SMAX, MVT::v16i16, { 1, 1, 1, 2 } },
4523 { ISD::SMAX, MVT::v32i8, { 1, 1, 1, 2 } },
4524 { ISD::SMIN, MVT::v2i64, { 2, 7, 2, 3 } },
4525 { ISD::SMIN, MVT::v4i64, { 2, 7, 2, 3 } },
4526 { ISD::SMIN, MVT::v8i32, { 1, 1, 1, 2 } },
4527 { ISD::SMIN, MVT::v16i16, { 1, 1, 1, 2 } },
4528 { ISD::SMIN, MVT::v32i8, { 1, 1, 1, 2 } },
4529 { ISD::SMULO, MVT::v4i64, { 20, 20, 33, 37 } },
4530 { ISD::SMULO, MVT::v2i64, { 8, 8, 13, 15 } },
4531 { ISD::SMULO, MVT::v8i32, { 8, 20, 13, 24 } },
4532 { ISD::SMULO, MVT::v4i32, { 5, 15, 11, 12 } },
4533 { ISD::SMULO, MVT::v16i16, { 4, 14, 8, 14 } },
4534 { ISD::SMULO, MVT::v8i16, { 3, 9, 6, 6 } },
4535 { ISD::SMULO, MVT::v32i8, { 9, 15, 18, 35 } },
4536 { ISD::SMULO, MVT::v16i8, { 6, 22, 14, 21 } },
4537 { ISD::SSUBSAT, MVT::v2i64, { 4, 13, 9, 13 } },
4538 { ISD::SSUBSAT, MVT::v4i64, { 4, 15, 9, 13 } },
4539 { ISD::SSUBSAT, MVT::v4i32, { 3, 14, 9, 11 } },
4540 { ISD::SSUBSAT, MVT::v8i32, { 4, 15, 9, 16 } },
4541 { ISD::SSUBSAT, MVT::v16i16, { 1, 1, 1, 2 } },
4542 { ISD::SSUBSAT, MVT::v32i8, { 1, 1, 1, 2 } },
4543 { ISD::UADDSAT, MVT::v2i64, { 2, 8, 6, 6 } },
4544 { ISD::UADDSAT, MVT::v4i64, { 3, 8, 6, 10 } },
4545 { ISD::UADDSAT, MVT::v8i32, { 2, 2, 4, 8 } },
4546 { ISD::UADDSAT, MVT::v16i16, { 1, 1, 1, 2 } },
4547 { ISD::UADDSAT, MVT::v32i8, { 1, 1, 1, 2 } },
4548 { ISD::UMAX, MVT::v2i64, { 2, 8, 5, 6 } },
4549 { ISD::UMAX, MVT::v4i64, { 2, 8, 5, 8 } },
4550 { ISD::UMAX, MVT::v8i32, { 1, 1, 1, 2 } },
4551 { ISD::UMAX, MVT::v16i16, { 1, 1, 1, 2 } },
4552 { ISD::UMAX, MVT::v32i8, { 1, 1, 1, 2 } },
4553 { ISD::UMIN, MVT::v2i64, { 2, 8, 5, 6 } },
4554 { ISD::UMIN, MVT::v4i64, { 2, 8, 5, 8 } },
4555 { ISD::UMIN, MVT::v8i32, { 1, 1, 1, 2 } },
4556 { ISD::UMIN, MVT::v16i16, { 1, 1, 1, 2 } },
4557 { ISD::UMIN, MVT::v32i8, { 1, 1, 1, 2 } },
4558 { ISD::UMULO, MVT::v4i64, { 24, 24, 39, 43 } },
4559 { ISD::UMULO, MVT::v2i64, { 10, 10, 15, 19 } },
4560 { ISD::UMULO, MVT::v8i32, { 8, 11, 13, 23 } },
4561 { ISD::UMULO, MVT::v4i32, { 5, 12, 11, 12 } },
4562 { ISD::UMULO, MVT::v16i16, { 4, 6, 8, 13 } },
4563 { ISD::UMULO, MVT::v8i16, { 2, 8, 6, 6 } },
4564 { ISD::UMULO, MVT::v32i8, { 9, 13, 17, 33 } },
4565 { ISD::UMULO, MVT::v16i8, { 6, 19, 13, 20 } },
4566 { ISD::USUBSAT, MVT::v2i64, { 2, 7, 6, 6 } },
4567 { ISD::USUBSAT, MVT::v4i64, { 3, 7, 6, 10 } },
4568 { ISD::USUBSAT, MVT::v8i32, { 2, 2, 2, 4 } },
4569 { ISD::USUBSAT, MVT::v16i16, { 1, 1, 1, 2 } },
4570 { ISD::USUBSAT, MVT::v32i8, { 1, 1, 1, 2 } },
4571 { ISD::FMAXNUM, MVT::f32, { 2, 7, 3, 5 } }, // MAXSS + CMPUNORDSS + BLENDVPS
4572 { ISD::FMAXNUM, MVT::v4f32, { 2, 7, 3, 5 } }, // MAXPS + CMPUNORDPS + BLENDVPS
4573 { ISD::FMAXNUM, MVT::v8f32, { 3, 7, 3, 6 } }, // MAXPS + CMPUNORDPS + BLENDVPS
4574 { ISD::FMAXNUM, MVT::f64, { 2, 7, 3, 5 } }, // MAXSD + CMPUNORDSD + BLENDVPD
4575 { ISD::FMAXNUM, MVT::v2f64, { 2, 7, 3, 5 } }, // MAXPD + CMPUNORDPD + BLENDVPD
4576 { ISD::FMAXNUM, MVT::v4f64, { 3, 7, 3, 6 } }, // MAXPD + CMPUNORDPD + BLENDVPD
4577 { ISD::FSQRT, MVT::f32, { 7, 15, 1, 1 } }, // vsqrtss
4578 { ISD::FSQRT, MVT::v4f32, { 7, 15, 1, 1 } }, // vsqrtps
4579 { ISD::FSQRT, MVT::v8f32, { 14, 21, 1, 3 } }, // vsqrtps
4580 { ISD::FSQRT, MVT::f64, { 14, 21, 1, 1 } }, // vsqrtsd
4581 { ISD::FSQRT, MVT::v2f64, { 14, 21, 1, 1 } }, // vsqrtpd
4582 { ISD::FSQRT, MVT::v4f64, { 28, 35, 1, 3 } }, // vsqrtpd
4583 };
4584 static const CostKindTblEntry AVX1CostTbl[] = {
4585 { ISD::ABS, MVT::v4i64, { 6, 8, 6, 12 } }, // VBLENDVPD(X,VPSUBQ(0,X),X)
4586 { ISD::ABS, MVT::v8i32, { 3, 6, 4, 5 } },
4587 { ISD::ABS, MVT::v16i16, { 3, 6, 4, 5 } },
4588 { ISD::ABS, MVT::v32i8, { 3, 6, 4, 5 } },
4589 { ISD::BITREVERSE, MVT::v4i64, { 17, 20, 20, 33 } }, // 2 x 128-bit Op + extract/insert
4590 { ISD::BITREVERSE, MVT::v2i64, { 8, 13, 10, 16 } },
4591 { ISD::BITREVERSE, MVT::v8i32, { 17, 20, 20, 33 } }, // 2 x 128-bit Op + extract/insert
4592 { ISD::BITREVERSE, MVT::v4i32, { 8, 13, 10, 16 } },
4593 { ISD::BITREVERSE, MVT::v16i16, { 17, 20, 20, 33 } }, // 2 x 128-bit Op + extract/insert
4594 { ISD::BITREVERSE, MVT::v8i16, { 8, 13, 10, 16 } },
4595 { ISD::BITREVERSE, MVT::v32i8, { 13, 15, 17, 26 } }, // 2 x 128-bit Op + extract/insert
4596 { ISD::BITREVERSE, MVT::v16i8, { 7, 7, 9, 13 } },
4597 { ISD::BSWAP, MVT::v4i64, { 5, 6, 5, 10 } },
4598 { ISD::BSWAP, MVT::v2i64, { 2, 2, 1, 3 } },
4599 { ISD::BSWAP, MVT::v8i32, { 5, 6, 5, 10 } },
4600 { ISD::BSWAP, MVT::v4i32, { 2, 2, 1, 3 } },
4601 { ISD::BSWAP, MVT::v16i16, { 5, 6, 5, 10 } },
4602 { ISD::BSWAP, MVT::v8i16, { 2, 2, 1, 3 } },
4603 { ISD::CTLZ, MVT::v4i64, { 29, 33, 49, 58 } }, // 2 x 128-bit Op + extract/insert
4604 { ISD::CTLZ, MVT::v2i64, { 14, 24, 24, 28 } },
4605 { ISD::CTLZ, MVT::v8i32, { 24, 28, 39, 48 } }, // 2 x 128-bit Op + extract/insert
4606 { ISD::CTLZ, MVT::v4i32, { 12, 20, 19, 23 } },
4607 { ISD::CTLZ, MVT::v16i16, { 19, 22, 29, 38 } }, // 2 x 128-bit Op + extract/insert
4608 { ISD::CTLZ, MVT::v8i16, { 9, 16, 14, 18 } },
4609 { ISD::CTLZ, MVT::v32i8, { 14, 15, 19, 28 } }, // 2 x 128-bit Op + extract/insert
4610 { ISD::CTLZ, MVT::v16i8, { 7, 12, 9, 13 } },
4611 { ISD::CTPOP, MVT::v4i64, { 14, 18, 19, 28 } }, // 2 x 128-bit Op + extract/insert
4612 { ISD::CTPOP, MVT::v2i64, { 7, 14, 10, 14 } },
4613 { ISD::CTPOP, MVT::v8i32, { 18, 24, 27, 36 } }, // 2 x 128-bit Op + extract/insert
4614 { ISD::CTPOP, MVT::v4i32, { 9, 20, 14, 18 } },
4615 { ISD::CTPOP, MVT::v16i16, { 16, 21, 22, 31 } }, // 2 x 128-bit Op + extract/insert
4616 { ISD::CTPOP, MVT::v8i16, { 8, 18, 11, 15 } },
4617 { ISD::CTPOP, MVT::v32i8, { 13, 15, 16, 25 } }, // 2 x 128-bit Op + extract/insert
4618 { ISD::CTPOP, MVT::v16i8, { 6, 12, 8, 12 } },
4619 { ISD::CTTZ, MVT::v4i64, { 17, 22, 24, 33 } }, // 2 x 128-bit Op + extract/insert
4620 { ISD::CTTZ, MVT::v2i64, { 9, 19, 13, 17 } },
4621 { ISD::CTTZ, MVT::v8i32, { 21, 27, 32, 41 } }, // 2 x 128-bit Op + extract/insert
4622 { ISD::CTTZ, MVT::v4i32, { 11, 24, 17, 21 } },
4623 { ISD::CTTZ, MVT::v16i16, { 18, 24, 27, 36 } }, // 2 x 128-bit Op + extract/insert
4624 { ISD::CTTZ, MVT::v8i16, { 9, 21, 14, 18 } },
4625 { ISD::CTTZ, MVT::v32i8, { 15, 18, 21, 30 } }, // 2 x 128-bit Op + extract/insert
4626 { ISD::CTTZ, MVT::v16i8, { 8, 16, 11, 15 } },
4627 { ISD::SADDSAT, MVT::v2i64, { 6, 13, 8, 11 } },
4628 { ISD::SADDSAT, MVT::v4i64, { 13, 20, 15, 25 } }, // 2 x 128-bit Op + extract/insert
4629 { ISD::SADDSAT, MVT::v8i32, { 12, 18, 14, 24 } }, // 2 x 128-bit Op + extract/insert
4630 { ISD::SADDSAT, MVT::v16i16, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4631 { ISD::SADDSAT, MVT::v32i8, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4632 { ISD::SMAX, MVT::v4i64, { 6, 9, 6, 12 } }, // 2 x 128-bit Op + extract/insert
4633 { ISD::SMAX, MVT::v2i64, { 3, 7, 2, 4 } },
4634 { ISD::SMAX, MVT::v8i32, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4635 { ISD::SMAX, MVT::v16i16, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4636 { ISD::SMAX, MVT::v32i8, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4637 { ISD::SMIN, MVT::v4i64, { 6, 9, 6, 12 } }, // 2 x 128-bit Op + extract/insert
4638 { ISD::SMIN, MVT::v2i64, { 3, 7, 2, 3 } },
4639 { ISD::SMIN, MVT::v8i32, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4640 { ISD::SMIN, MVT::v16i16, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4641 { ISD::SMIN, MVT::v32i8, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4642 { ISD::SMULO, MVT::v4i64, { 20, 20, 33, 37 } },
4643 { ISD::SMULO, MVT::v2i64, { 9, 9, 13, 17 } },
4644 { ISD::SMULO, MVT::v8i32, { 15, 20, 24, 29 } },
4645 { ISD::SMULO, MVT::v4i32, { 7, 15, 11, 13 } },
4646 { ISD::SMULO, MVT::v16i16, { 8, 14, 14, 15 } },
4647 { ISD::SMULO, MVT::v8i16, { 3, 9, 6, 6 } },
4648 { ISD::SMULO, MVT::v32i8, { 20, 20, 37, 39 } },
4649 { ISD::SMULO, MVT::v16i8, { 9, 22, 18, 21 } },
4650 { ISD::SSUBSAT, MVT::v2i64, { 7, 13, 9, 13 } },
4651 { ISD::SSUBSAT, MVT::v4i64, { 15, 21, 18, 29 } }, // 2 x 128-bit Op + extract/insert
4652 { ISD::SSUBSAT, MVT::v8i32, { 15, 19, 18, 29 } }, // 2 x 128-bit Op + extract/insert
4653 { ISD::SSUBSAT, MVT::v16i16, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4654 { ISD::SSUBSAT, MVT::v32i8, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4655 { ISD::UADDSAT, MVT::v2i64, { 3, 8, 6, 6 } },
4656 { ISD::UADDSAT, MVT::v4i64, { 8, 11, 14, 15 } }, // 2 x 128-bit Op + extract/insert
4657 { ISD::UADDSAT, MVT::v8i32, { 6, 6, 10, 11 } }, // 2 x 128-bit Op + extract/insert
4658 { ISD::UADDSAT, MVT::v16i16, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4659 { ISD::UADDSAT, MVT::v32i8, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4660 { ISD::UMAX, MVT::v4i64, { 9, 10, 11, 17 } }, // 2 x 128-bit Op + extract/insert
4661 { ISD::UMAX, MVT::v2i64, { 4, 8, 5, 7 } },
4662 { ISD::UMAX, MVT::v8i32, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4663 { ISD::UMAX, MVT::v16i16, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4664 { ISD::UMAX, MVT::v32i8, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4665 { ISD::UMIN, MVT::v4i64, { 9, 10, 11, 17 } }, // 2 x 128-bit Op + extract/insert
4666 { ISD::UMIN, MVT::v2i64, { 4, 8, 5, 7 } },
4667 { ISD::UMIN, MVT::v8i32, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4668 { ISD::UMIN, MVT::v16i16, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4669 { ISD::UMIN, MVT::v32i8, { 4, 6, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4670 { ISD::UMULO, MVT::v4i64, { 24, 26, 39, 45 } },
4671 { ISD::UMULO, MVT::v2i64, { 10, 12, 15, 20 } },
4672 { ISD::UMULO, MVT::v8i32, { 14, 15, 23, 28 } },
4673 { ISD::UMULO, MVT::v4i32, { 7, 12, 11, 13 } },
4674 { ISD::UMULO, MVT::v16i16, { 7, 11, 13, 14 } },
4675 { ISD::UMULO, MVT::v8i16, { 3, 8, 6, 6 } },
4676 { ISD::UMULO, MVT::v32i8, { 19, 19, 35, 37 } },
4677 { ISD::UMULO, MVT::v16i8, { 9, 19, 17, 20 } },
4678 { ISD::USUBSAT, MVT::v2i64, { 3, 7, 6, 6 } },
4679 { ISD::USUBSAT, MVT::v4i64, { 8, 10, 14, 15 } }, // 2 x 128-bit Op + extract/insert
4680 { ISD::USUBSAT, MVT::v8i32, { 4, 4, 7, 8 } }, // 2 x 128-bit Op + extract/insert
4681 { ISD::USUBSAT, MVT::v8i32, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4682 { ISD::USUBSAT, MVT::v16i16, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4683 { ISD::USUBSAT, MVT::v32i8, { 3, 3, 5, 6 } }, // 2 x 128-bit Op + extract/insert
4684 { ISD::FMAXNUM, MVT::f32, { 3, 6, 3, 5 } }, // MAXSS + CMPUNORDSS + BLENDVPS
4685 { ISD::FMAXNUM, MVT::v4f32, { 3, 6, 3, 5 } }, // MAXPS + CMPUNORDPS + BLENDVPS
4686 { ISD::FMAXNUM, MVT::v8f32, { 5, 7, 3, 10 } }, // MAXPS + CMPUNORDPS + BLENDVPS
4687 { ISD::FMAXNUM, MVT::f64, { 3, 6, 3, 5 } }, // MAXSD + CMPUNORDSD + BLENDVPD
4688 { ISD::FMAXNUM, MVT::v2f64, { 3, 6, 3, 5 } }, // MAXPD + CMPUNORDPD + BLENDVPD
4689 { ISD::FMAXNUM, MVT::v4f64, { 5, 7, 3, 10 } }, // MAXPD + CMPUNORDPD + BLENDVPD
4690 { ISD::FSQRT, MVT::f32, { 21, 21, 1, 1 } }, // vsqrtss
4691 { ISD::FSQRT, MVT::v4f32, { 21, 21, 1, 1 } }, // vsqrtps
4692 { ISD::FSQRT, MVT::v8f32, { 42, 42, 1, 3 } }, // vsqrtps
4693 { ISD::FSQRT, MVT::f64, { 27, 27, 1, 1 } }, // vsqrtsd
4694 { ISD::FSQRT, MVT::v2f64, { 27, 27, 1, 1 } }, // vsqrtpd
4695 { ISD::FSQRT, MVT::v4f64, { 54, 54, 1, 3 } }, // vsqrtpd
4696 };
4697 static const CostKindTblEntry GFNICostTbl[] = {
4698 { ISD::BITREVERSE, MVT::i8, { 3, 3, 3, 4 } }, // gf2p8affineqb
4699 { ISD::BITREVERSE, MVT::i16, { 3, 3, 4, 6 } }, // gf2p8affineqb
4700 { ISD::BITREVERSE, MVT::i32, { 3, 3, 4, 5 } }, // gf2p8affineqb
4701 { ISD::BITREVERSE, MVT::i64, { 3, 3, 4, 6 } }, // gf2p8affineqb
4702 { ISD::BITREVERSE, MVT::v16i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
4703 { ISD::BITREVERSE, MVT::v32i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
4704 { ISD::BITREVERSE, MVT::v64i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
4705 { ISD::BITREVERSE, MVT::v8i16, { 1, 8, 2, 4 } }, // gf2p8affineqb
4706 { ISD::BITREVERSE, MVT::v16i16, { 1, 9, 2, 4 } }, // gf2p8affineqb
4707 { ISD::BITREVERSE, MVT::v32i16, { 1, 9, 2, 4 } }, // gf2p8affineqb
4708 { ISD::BITREVERSE, MVT::v4i32, { 1, 8, 2, 4 } }, // gf2p8affineqb
4709 { ISD::BITREVERSE, MVT::v8i32, { 1, 9, 2, 4 } }, // gf2p8affineqb
4710 { ISD::BITREVERSE, MVT::v16i32, { 1, 9, 2, 4 } }, // gf2p8affineqb
4711 { ISD::BITREVERSE, MVT::v2i64, { 1, 8, 2, 4 } }, // gf2p8affineqb
4712 { ISD::BITREVERSE, MVT::v4i64, { 1, 9, 2, 4 } }, // gf2p8affineqb
4713 { ISD::BITREVERSE, MVT::v8i64, { 1, 9, 2, 4 } }, // gf2p8affineqb
4714 { X86ISD::VROTLI, MVT::v16i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
4715 { X86ISD::VROTLI, MVT::v32i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
4716 { X86ISD::VROTLI, MVT::v64i8, { 1, 6, 1, 2 } }, // gf2p8affineqb
4717 };
4718 static const CostKindTblEntry GLMCostTbl[] = {
4719 { ISD::FSQRT, MVT::f32, { 19, 20, 1, 1 } }, // sqrtss
4720 { ISD::FSQRT, MVT::v4f32, { 37, 41, 1, 5 } }, // sqrtps
4721 { ISD::FSQRT, MVT::f64, { 34, 35, 1, 1 } }, // sqrtsd
4722 { ISD::FSQRT, MVT::v2f64, { 67, 71, 1, 5 } }, // sqrtpd
4723 };
4724 static const CostKindTblEntry SLMCostTbl[] = {
4725 { ISD::BSWAP, MVT::v2i64, { 5, 5, 1, 5 } },
4726 { ISD::BSWAP, MVT::v4i32, { 5, 5, 1, 5 } },
4727 { ISD::BSWAP, MVT::v8i16, { 5, 5, 1, 5 } },
4728 { ISD::FSQRT, MVT::f32, { 20, 20, 1, 1 } }, // sqrtss
4729 { ISD::FSQRT, MVT::v4f32, { 40, 41, 1, 5 } }, // sqrtps
4730 { ISD::FSQRT, MVT::f64, { 35, 35, 1, 1 } }, // sqrtsd
4731 { ISD::FSQRT, MVT::v2f64, { 70, 71, 1, 5 } }, // sqrtpd
4732 };
4733 static const CostKindTblEntry SSE42CostTbl[] = {
4734 { ISD::FMAXNUM, MVT::f32, { 5, 5, 7, 7 } }, // MAXSS + CMPUNORDSS + BLENDVPS
4735 { ISD::FMAXNUM, MVT::v4f32, { 4, 4, 4, 5 } }, // MAXPS + CMPUNORDPS + BLENDVPS
4736 { ISD::FMAXNUM, MVT::f64, { 5, 5, 7, 7 } }, // MAXSD + CMPUNORDSD + BLENDVPD
4737 { ISD::FMAXNUM, MVT::v2f64, { 4, 4, 4, 5 } }, // MAXPD + CMPUNORDPD + BLENDVPD
4738 { ISD::FSQRT, MVT::f32, { 18, 18, 1, 1 } }, // Nehalem from http://www.agner.org/
4739 { ISD::FSQRT, MVT::v4f32, { 18, 18, 1, 1 } }, // Nehalem from http://www.agner.org/
4740 };
4741 static const CostKindTblEntry SSE41CostTbl[] = {
4742 { ISD::ABS, MVT::v2i64, { 3, 4, 3, 5 } }, // BLENDVPD(X,PSUBQ(0,X),X)
4743 { ISD::SADDSAT, MVT::v2i64, { 10, 14, 17, 21 } },
4744 { ISD::SADDSAT, MVT::v4i32, { 5, 11, 8, 10 } },
4745 { ISD::SSUBSAT, MVT::v2i64, { 12, 19, 25, 29 } },
4746 { ISD::SSUBSAT, MVT::v4i32, { 6, 14, 10, 12 } },
4747 { ISD::SMAX, MVT::v2i64, { 3, 7, 2, 3 } },
4748 { ISD::SMAX, MVT::v4i32, { 1, 1, 1, 1 } },
4749 { ISD::SMAX, MVT::v16i8, { 1, 1, 1, 1 } },
4750 { ISD::SMIN, MVT::v2i64, { 3, 7, 2, 3 } },
4751 { ISD::SMIN, MVT::v4i32, { 1, 1, 1, 1 } },
4752 { ISD::SMIN, MVT::v16i8, { 1, 1, 1, 1 } },
4753 { ISD::SMULO, MVT::v2i64, { 9, 11, 13, 17 } },
4754 { ISD::SMULO, MVT::v4i32, { 20, 24, 13, 19 } },
4755 { ISD::SMULO, MVT::v8i16, { 5, 9, 8, 8 } },
4756 { ISD::SMULO, MVT::v16i8, { 13, 22, 24, 25 } },
4757 { ISD::UADDSAT, MVT::v2i64, { 6, 13, 14, 14 } },
4758 { ISD::UADDSAT, MVT::v4i32, { 2, 2, 4, 4 } },
4759 { ISD::USUBSAT, MVT::v2i64, { 6, 10, 14, 14 } },
4760 { ISD::USUBSAT, MVT::v4i32, { 1, 2, 2, 2 } },
4761 { ISD::UMAX, MVT::v2i64, { 2, 11, 6, 7 } },
4762 { ISD::UMAX, MVT::v4i32, { 1, 1, 1, 1 } },
4763 { ISD::UMAX, MVT::v8i16, { 1, 1, 1, 1 } },
4764 { ISD::UMIN, MVT::v2i64, { 2, 11, 6, 7 } },
4765 { ISD::UMIN, MVT::v4i32, { 1, 1, 1, 1 } },
4766 { ISD::UMIN, MVT::v8i16, { 1, 1, 1, 1 } },
4767 { ISD::UMULO, MVT::v2i64, { 14, 20, 15, 20 } },
4768 { ISD::UMULO, MVT::v4i32, { 19, 22, 12, 18 } },
4769 { ISD::UMULO, MVT::v8i16, { 4, 9, 7, 7 } },
4770 { ISD::UMULO, MVT::v16i8, { 13, 19, 18, 20 } },
4771 };
4772 static const CostKindTblEntry SSSE3CostTbl[] = {
4773 { ISD::ABS, MVT::v4i32, { 1, 2, 1, 1 } },
4774 { ISD::ABS, MVT::v8i16, { 1, 2, 1, 1 } },
4775 { ISD::ABS, MVT::v16i8, { 1, 2, 1, 1 } },
4776 { ISD::BITREVERSE, MVT::v2i64, { 16, 20, 11, 21 } },
4777 { ISD::BITREVERSE, MVT::v4i32, { 16, 20, 11, 21 } },
4778 { ISD::BITREVERSE, MVT::v8i16, { 16, 20, 11, 21 } },
4779 { ISD::BITREVERSE, MVT::v16i8, { 11, 12, 10, 16 } },
4780 { ISD::BSWAP, MVT::v2i64, { 2, 3, 1, 5 } },
4781 { ISD::BSWAP, MVT::v4i32, { 2, 3, 1, 5 } },
4782 { ISD::BSWAP, MVT::v8i16, { 2, 3, 1, 5 } },
4783 { ISD::CTLZ, MVT::v2i64, { 18, 28, 28, 35 } },
4784 { ISD::CTLZ, MVT::v4i32, { 15, 20, 22, 28 } },
4785 { ISD::CTLZ, MVT::v8i16, { 13, 17, 16, 22 } },
4786 { ISD::CTLZ, MVT::v16i8, { 11, 15, 10, 16 } },
4787 { ISD::CTPOP, MVT::v2i64, { 13, 19, 12, 18 } },
4788 { ISD::CTPOP, MVT::v4i32, { 18, 24, 16, 22 } },
4789 { ISD::CTPOP, MVT::v8i16, { 13, 18, 14, 20 } },
4790 { ISD::CTPOP, MVT::v16i8, { 11, 12, 10, 16 } },
4791 { ISD::CTTZ, MVT::v2i64, { 13, 25, 15, 22 } },
4792 { ISD::CTTZ, MVT::v4i32, { 18, 26, 19, 25 } },
4793 { ISD::CTTZ, MVT::v8i16, { 13, 20, 17, 23 } },
4794 { ISD::CTTZ, MVT::v16i8, { 11, 16, 13, 19 } }
4795 };
4796 static const CostKindTblEntry SSE2CostTbl[] = {
4797 { ISD::ABS, MVT::v2i64, { 3, 6, 5, 5 } },
4798 { ISD::ABS, MVT::v4i32, { 1, 4, 4, 4 } },
4799 { ISD::ABS, MVT::v8i16, { 1, 2, 3, 3 } },
4800 { ISD::ABS, MVT::v16i8, { 1, 2, 3, 3 } },
4801 { ISD::BITREVERSE, MVT::v2i64, { 16, 20, 32, 32 } },
4802 { ISD::BITREVERSE, MVT::v4i32, { 16, 20, 30, 30 } },
4803 { ISD::BITREVERSE, MVT::v8i16, { 16, 20, 25, 25 } },
4804 { ISD::BITREVERSE, MVT::v16i8, { 11, 12, 21, 21 } },
4805 { ISD::BSWAP, MVT::v2i64, { 5, 6, 11, 11 } },
4806 { ISD::BSWAP, MVT::v4i32, { 5, 5, 9, 9 } },
4807 { ISD::BSWAP, MVT::v8i16, { 5, 5, 4, 5 } },
4808 { ISD::CTLZ, MVT::v2i64, { 10, 45, 36, 38 } },
4809 { ISD::CTLZ, MVT::v4i32, { 10, 45, 38, 40 } },
4810 { ISD::CTLZ, MVT::v8i16, { 9, 38, 32, 34 } },
4811 { ISD::CTLZ, MVT::v16i8, { 8, 39, 29, 32 } },
4812 { ISD::CTPOP, MVT::v2i64, { 12, 26, 16, 18 } },
4813 { ISD::CTPOP, MVT::v4i32, { 15, 29, 21, 23 } },
4814 { ISD::CTPOP, MVT::v8i16, { 13, 25, 18, 20 } },
4815 { ISD::CTPOP, MVT::v16i8, { 10, 21, 14, 16 } },
4816 { ISD::CTTZ, MVT::v2i64, { 14, 28, 19, 21 } },
4817 { ISD::CTTZ, MVT::v4i32, { 18, 31, 24, 26 } },
4818 { ISD::CTTZ, MVT::v8i16, { 16, 27, 21, 23 } },
4819 { ISD::CTTZ, MVT::v16i8, { 13, 23, 17, 19 } },
4820 { ISD::SADDSAT, MVT::v2i64, { 12, 14, 24, 24 } },
4821 { ISD::SADDSAT, MVT::v4i32, { 6, 11, 11, 12 } },
4822 { ISD::SADDSAT, MVT::v8i16, { 1, 2, 1, 1 } },
4823 { ISD::SADDSAT, MVT::v16i8, { 1, 2, 1, 1 } },
4824 { ISD::SMAX, MVT::v2i64, { 4, 8, 15, 15 } },
4825 { ISD::SMAX, MVT::v4i32, { 2, 4, 5, 5 } },
4826 { ISD::SMAX, MVT::v8i16, { 1, 1, 1, 1 } },
4827 { ISD::SMAX, MVT::v16i8, { 2, 4, 5, 5 } },
4828 { ISD::SMIN, MVT::v2i64, { 4, 8, 15, 15 } },
4829 { ISD::SMIN, MVT::v4i32, { 2, 4, 5, 5 } },
4830 { ISD::SMIN, MVT::v8i16, { 1, 1, 1, 1 } },
4831 { ISD::SMIN, MVT::v16i8, { 2, 4, 5, 5 } },
4832 { ISD::SMULO, MVT::v2i64, { 30, 33, 13, 23 } },
4833 { ISD::SMULO, MVT::v4i32, { 20, 24, 23, 23 } },
4834 { ISD::SMULO, MVT::v8i16, { 5, 10, 8, 8 } },
4835 { ISD::SMULO, MVT::v16i8, { 13, 23, 24, 25 } },
4836 { ISD::SSUBSAT, MVT::v2i64, { 16, 19, 31, 31 } },
4837 { ISD::SSUBSAT, MVT::v4i32, { 6, 14, 12, 13 } },
4838 { ISD::SSUBSAT, MVT::v8i16, { 1, 2, 1, 1 } },
4839 { ISD::SSUBSAT, MVT::v16i8, { 1, 2, 1, 1 } },
4840 { ISD::UADDSAT, MVT::v2i64, { 7, 13, 14, 14 } },
4841 { ISD::UADDSAT, MVT::v4i32, { 4, 5, 7, 7 } },
4842 { ISD::UADDSAT, MVT::v8i16, { 1, 2, 1, 1 } },
4843 { ISD::UADDSAT, MVT::v16i8, { 1, 2, 1, 1 } },
4844 { ISD::UMAX, MVT::v2i64, { 4, 8, 15, 15 } },
4845 { ISD::UMAX, MVT::v4i32, { 2, 5, 8, 8 } },
4846 { ISD::UMAX, MVT::v8i16, { 1, 3, 3, 3 } },
4847 { ISD::UMAX, MVT::v16i8, { 1, 1, 1, 1 } },
4848 { ISD::UMIN, MVT::v2i64, { 4, 8, 15, 15 } },
4849 { ISD::UMIN, MVT::v4i32, { 2, 5, 8, 8 } },
4850 { ISD::UMIN, MVT::v8i16, { 1, 3, 3, 3 } },
4851 { ISD::UMIN, MVT::v16i8, { 1, 1, 1, 1 } },
4852 { ISD::UMULO, MVT::v2i64, { 30, 33, 15, 29 } },
4853 { ISD::UMULO, MVT::v4i32, { 19, 22, 14, 18 } },
4854 { ISD::UMULO, MVT::v8i16, { 4, 9, 7, 7 } },
4855 { ISD::UMULO, MVT::v16i8, { 13, 19, 20, 20 } },
4856 { ISD::USUBSAT, MVT::v2i64, { 7, 10, 14, 14 } },
4857 { ISD::USUBSAT, MVT::v4i32, { 4, 4, 7, 7 } },
4858 { ISD::USUBSAT, MVT::v8i16, { 1, 2, 1, 1 } },
4859 { ISD::USUBSAT, MVT::v16i8, { 1, 2, 1, 1 } },
4860 { ISD::FMAXNUM, MVT::f64, { 5, 5, 7, 7 } },
4861 { ISD::FMAXNUM, MVT::v2f64, { 4, 6, 6, 6 } },
4862 { ISD::FSQRT, MVT::f64, { 32, 32, 1, 1 } }, // Nehalem from http://www.agner.org/
4863 { ISD::FSQRT, MVT::v2f64, { 32, 32, 1, 1 } }, // Nehalem from http://www.agner.org/
4864 };
4865 static const CostKindTblEntry SSE1CostTbl[] = {
4866 { ISD::FMAXNUM, MVT::f32, { 5, 5, 7, 7 } },
4867 { ISD::FMAXNUM, MVT::v4f32, { 4, 6, 6, 6 } },
4868 { ISD::FSQRT, MVT::f32, { 28, 30, 1, 2 } }, // Pentium III from http://www.agner.org/
4869 { ISD::FSQRT, MVT::v4f32, { 56, 56, 1, 2 } }, // Pentium III from http://www.agner.org/
4870 };
4871 static const CostKindTblEntry BMI64CostTbl[] = { // 64-bit targets
4872 { ISD::CTTZ, MVT::i64, { 1, 1, 1, 1 } },
4873 };
4874 static const CostKindTblEntry BMI32CostTbl[] = { // 32 or 64-bit targets
4875 { ISD::CTTZ, MVT::i32, { 1, 1, 1, 1 } },
4876 { ISD::CTTZ, MVT::i16, { 2, 1, 1, 1 } },
4877 { ISD::CTTZ, MVT::i8, { 2, 1, 1, 1 } },
4878 };
4879 static const CostKindTblEntry LZCNT64CostTbl[] = { // 64-bit targets
4880 { ISD::CTLZ, MVT::i64, { 1, 1, 1, 1 } },
4881 };
4882 static const CostKindTblEntry LZCNT32CostTbl[] = { // 32 or 64-bit targets
4883 { ISD::CTLZ, MVT::i32, { 1, 1, 1, 1 } },
4884 { ISD::CTLZ, MVT::i16, { 2, 1, 1, 1 } },
4885 { ISD::CTLZ, MVT::i8, { 2, 1, 1, 1 } },
4886 };
4887 static const CostKindTblEntry POPCNT64CostTbl[] = { // 64-bit targets
4888 { ISD::CTPOP, MVT::i64, { 1, 1, 1, 1 } }, // popcnt
4889 };
4890 static const CostKindTblEntry POPCNT32CostTbl[] = { // 32 or 64-bit targets
4891 { ISD::CTPOP, MVT::i32, { 1, 1, 1, 1 } }, // popcnt
4892 { ISD::CTPOP, MVT::i16, { 1, 1, 2, 2 } }, // popcnt(zext())
4893 { ISD::CTPOP, MVT::i8, { 1, 1, 2, 2 } }, // popcnt(zext())
4894 };
4895 static const CostKindTblEntry PCLMULCostTbl[] = {
4896 { ISD::CLMUL, MVT::v2i64, { 3, 12, 4, 8 } }, // MOV+2xPCLMUL+unpack
4897 { ISD::CLMUL, MVT::v4i32, { 8, 18, 12, 16 } }, // MOV+4xPCLMUL+unpack
4898 { ISD::CLMUL, MVT::i64, { 3, 12, 4, 8 } }, // MOV+PCLMUL+MOV
4899 { ISD::CLMUL, MVT::i32, { 3, 12, 4, 8 } }, // MOV+PCLMUL+MOV
4900 { ISD::CLMUL, MVT::i16, { 3, 12, 4, 8 } }, // MOV+PCLMUL+MOV
4901 { ISD::CLMUL, MVT::i8, { 3, 12, 4, 8 } }, // MOV+PCLMUL+MOV
4902 };
4903 static const CostKindTblEntry X64CostTbl[] = { // 64-bit targets
4904 { ISD::ABS, MVT::i64, { 1, 2, 3, 3 } }, // SUB+CMOV
4905 { ISD::BITREVERSE, MVT::i64, { 10, 12, 20, 22 } },
4906 { ISD::BSWAP, MVT::i64, { 1, 2, 1, 2 } },
4907 { ISD::CTLZ, MVT::i64, { 1, 2, 3, 3 } }, // MOV+BSR+XOR
4908 { ISD::CTLZ, MVT::i32, { 1, 2, 3, 3 } }, // MOV+BSR+XOR
4909 { ISD::CTLZ, MVT::i16, { 2, 2, 3, 3 } }, // MOV+BSR+XOR
4910 { ISD::CTLZ, MVT::i8, { 2, 2, 4, 3 } }, // MOV+BSR+XOR
4911 { ISD::CTLZ_ZERO_POISON,MVT::i64,{ 1, 2, 2, 2 } }, // BSR+XOR
4912 { ISD::CTTZ, MVT::i64, { 1, 2, 2, 2 } }, // MOV+BSF
4913 { ISD::CTTZ, MVT::i32, { 1, 2, 2, 2 } }, // MOV+BSF
4914 { ISD::CTTZ, MVT::i16, { 2, 2, 2, 2 } }, // MOV+BSF
4915 { ISD::CTTZ, MVT::i8, { 2, 2, 2, 2 } }, // MOV+BSF
4916 { ISD::CTTZ_ZERO_POISON,MVT::i64,{ 1, 2, 1, 2 } }, // BSF
4917 { ISD::CTPOP, MVT::i64, { 10, 6, 19, 19 } },
4918 { ISD::ROTL, MVT::i64, { 2, 3, 1, 3 } },
4919 { ISD::ROTR, MVT::i64, { 2, 3, 1, 3 } },
4920 { X86ISD::VROTLI, MVT::i64, { 1, 1, 1, 1 } },
4921 { ISD::FSHL, MVT::i64, { 4, 4, 1, 4 } },
4922 { ISD::SADDSAT, MVT::i64, { 4, 4, 7, 10 } },
4923 { ISD::SSUBSAT, MVT::i64, { 4, 5, 8, 11 } },
4924 { ISD::UADDSAT, MVT::i64, { 2, 3, 4, 7 } },
4925 { ISD::USUBSAT, MVT::i64, { 2, 3, 4, 7 } },
4926 { ISD::SMAX, MVT::i64, { 1, 3, 2, 3 } },
4927 { ISD::SMIN, MVT::i64, { 1, 3, 2, 3 } },
4928 { ISD::UMAX, MVT::i64, { 1, 3, 2, 3 } },
4929 { ISD::UMIN, MVT::i64, { 1, 3, 2, 3 } },
4930 { ISD::SADDO, MVT::i64, { 2, 2, 4, 6 } },
4931 { ISD::UADDO, MVT::i64, { 2, 2, 4, 6 } },
4932 { ISD::SMULO, MVT::i64, { 4, 4, 4, 6 } },
4933 { ISD::UMULO, MVT::i64, { 8, 8, 4, 7 } },
4934 };
4935 static const CostKindTblEntry X86CostTbl[] = { // 32 or 64-bit targets
4936 { ISD::ABS, MVT::i32, { 1, 2, 3, 3 } }, // SUB+XOR+SRA or SUB+CMOV
4937 { ISD::ABS, MVT::i16, { 2, 2, 3, 3 } }, // SUB+XOR+SRA or SUB+CMOV
4938 { ISD::ABS, MVT::i8, { 2, 4, 4, 3 } }, // SUB+XOR+SRA
4939 { ISD::BITREVERSE, MVT::i32, { 9, 12, 17, 19 } },
4940 { ISD::BITREVERSE, MVT::i16, { 9, 12, 17, 19 } },
4941 { ISD::BITREVERSE, MVT::i8, { 7, 9, 13, 14 } },
4942 { ISD::BSWAP, MVT::i32, { 1, 1, 1, 1 } },
4943 { ISD::BSWAP, MVT::i16, { 1, 2, 1, 2 } }, // ROL
4944 { ISD::CTLZ, MVT::i32, { 2, 2, 4, 5 } }, // BSR+XOR or BSR+XOR+CMOV
4945 { ISD::CTLZ, MVT::i16, { 2, 2, 4, 5 } }, // BSR+XOR or BSR+XOR+CMOV
4946 { ISD::CTLZ, MVT::i8, { 2, 2, 5, 6 } }, // BSR+XOR or BSR+XOR+CMOV
4947 { ISD::CTLZ_ZERO_POISON,MVT::i32,{ 1, 2, 2, 2 } }, // BSR+XOR
4948 { ISD::CTLZ_ZERO_POISON,MVT::i16,{ 2, 2, 2, 2 } }, // BSR+XOR
4949 { ISD::CTLZ_ZERO_POISON,MVT::i8, { 2, 2, 3, 3 } }, // BSR+XOR
4950 { ISD::CTTZ, MVT::i32, { 2, 2, 3, 3 } }, // TEST+BSF+CMOV/BRANCH
4951 { ISD::CTTZ, MVT::i16, { 2, 2, 2, 3 } }, // TEST+BSF+CMOV/BRANCH
4952 { ISD::CTTZ, MVT::i8, { 2, 2, 2, 3 } }, // TEST+BSF+CMOV/BRANCH
4953 { ISD::CTTZ_ZERO_POISON,MVT::i32,{ 1, 2, 1, 2 } }, // BSF
4954 { ISD::CTTZ_ZERO_POISON,MVT::i16,{ 2, 2, 1, 2 } }, // BSF
4955 { ISD::CTTZ_ZERO_POISON,MVT::i8, { 2, 2, 1, 2 } }, // BSF
4956 { ISD::CTPOP, MVT::i32, { 8, 7, 15, 15 } },
4957 { ISD::CTPOP, MVT::i16, { 9, 8, 17, 17 } },
4958 { ISD::CTPOP, MVT::i8, { 7, 6, 6, 6 } },
4959 { ISD::ROTL, MVT::i32, { 2, 3, 1, 3 } },
4960 { ISD::ROTL, MVT::i16, { 2, 3, 1, 3 } },
4961 { ISD::ROTL, MVT::i8, { 2, 3, 1, 3 } },
4962 { ISD::ROTR, MVT::i32, { 2, 3, 1, 3 } },
4963 { ISD::ROTR, MVT::i16, { 2, 3, 1, 3 } },
4964 { ISD::ROTR, MVT::i8, { 2, 3, 1, 3 } },
4965 { X86ISD::VROTLI, MVT::i32, { 1, 1, 1, 1 } },
4966 { X86ISD::VROTLI, MVT::i16, { 1, 1, 1, 1 } },
4967 { X86ISD::VROTLI, MVT::i8, { 1, 1, 1, 1 } },
4968 { ISD::FSHL, MVT::i32, { 4, 4, 1, 4 } },
4969 { ISD::FSHL, MVT::i16, { 4, 4, 2, 5 } },
4970 { ISD::FSHL, MVT::i8, { 4, 4, 2, 5 } },
4971 { ISD::SADDSAT, MVT::i32, { 3, 4, 6, 9 } },
4972 { ISD::SADDSAT, MVT::i16, { 4, 4, 7, 10 } },
4973 { ISD::SADDSAT, MVT::i8, { 4, 5, 8, 11 } },
4974 { ISD::SSUBSAT, MVT::i32, { 4, 4, 7, 10 } },
4975 { ISD::SSUBSAT, MVT::i16, { 4, 4, 7, 10 } },
4976 { ISD::SSUBSAT, MVT::i8, { 4, 5, 8, 11 } },
4977 { ISD::UADDSAT, MVT::i32, { 2, 3, 4, 7 } },
4978 { ISD::UADDSAT, MVT::i16, { 2, 3, 4, 7 } },
4979 { ISD::UADDSAT, MVT::i8, { 3, 3, 5, 8 } },
4980 { ISD::USUBSAT, MVT::i32, { 2, 3, 4, 7 } },
4981 { ISD::USUBSAT, MVT::i16, { 2, 3, 4, 7 } },
4982 { ISD::USUBSAT, MVT::i8, { 3, 3, 5, 8 } },
4983 { ISD::SMAX, MVT::i32, { 1, 2, 2, 3 } },
4984 { ISD::SMAX, MVT::i16, { 1, 4, 2, 4 } },
4985 { ISD::SMAX, MVT::i8, { 1, 4, 2, 4 } },
4986 { ISD::SMIN, MVT::i32, { 1, 2, 2, 3 } },
4987 { ISD::SMIN, MVT::i16, { 1, 4, 2, 4 } },
4988 { ISD::SMIN, MVT::i8, { 1, 4, 2, 4 } },
4989 { ISD::UMAX, MVT::i32, { 1, 2, 2, 3 } },
4990 { ISD::UMAX, MVT::i16, { 1, 4, 2, 4 } },
4991 { ISD::UMAX, MVT::i8, { 1, 4, 2, 4 } },
4992 { ISD::UMIN, MVT::i32, { 1, 2, 2, 3 } },
4993 { ISD::UMIN, MVT::i16, { 1, 4, 2, 4 } },
4994 { ISD::UMIN, MVT::i8, { 1, 4, 2, 4 } },
4995 { ISD::SADDO, MVT::i32, { 2, 2, 4, 6 } },
4996 { ISD::SADDO, MVT::i16, { 2, 2, 4, 6 } },
4997 { ISD::SADDO, MVT::i8, { 2, 2, 4, 6 } },
4998 { ISD::UADDO, MVT::i32, { 2, 2, 4, 6 } },
4999 { ISD::UADDO, MVT::i16, { 2, 2, 4, 6 } },
5000 { ISD::UADDO, MVT::i8, { 2, 2, 4, 6 } },
5001 { ISD::SMULO, MVT::i32, { 2, 2, 4, 6 } },
5002 { ISD::SMULO, MVT::i16, { 5, 5, 4, 6 } },
5003 { ISD::SMULO, MVT::i8, { 6, 6, 4, 6 } },
5004 { ISD::UMULO, MVT::i32, { 6, 6, 4, 8 } },
5005 { ISD::UMULO, MVT::i16, { 6, 6, 4, 9 } },
5006 { ISD::UMULO, MVT::i8, { 6, 6, 4, 6 } },
5007 };
5008
5009 Type *RetTy = ICA.getReturnType();
5010 Type *OpTy = RetTy;
5011 Intrinsic::ID IID = ICA.getID();
5012 unsigned ISD = ISD::DELETED_NODE;
5013 switch (IID) {
5014 default:
5015 break;
5016 case Intrinsic::abs:
5017 ISD = ISD::ABS;
5018 break;
5019 case Intrinsic::bitreverse:
5021 break;
5022 case Intrinsic::bswap:
5023 ISD = ISD::BSWAP;
5024 break;
5025 case Intrinsic::ctlz:
5026 ISD = ISD::CTLZ;
5027 break;
5028 case Intrinsic::ctpop:
5029 ISD = ISD::CTPOP;
5030 break;
5031 case Intrinsic::cttz:
5032 ISD = ISD::CTTZ;
5033 break;
5034 case Intrinsic::fshl:
5035 ISD = ISD::FSHL;
5036 if (!ICA.isTypeBasedOnly()) {
5037 const SmallVectorImpl<const Value *> &Args = ICA.getArgs();
5038 if (Args[0] == Args[1]) {
5039 ISD = ISD::ROTL;
5040 // Handle uniform constant rotation amounts.
5041 // TODO: Handle funnel-shift cases.
5042 const APInt *Amt;
5043 if (Args[2] &&
5045 ISD = X86ISD::VROTLI;
5046 }
5047 }
5048 break;
5049 case Intrinsic::fshr:
5050 // FSHR has same costs so don't duplicate.
5051 ISD = ISD::FSHL;
5052 if (!ICA.isTypeBasedOnly()) {
5053 const SmallVectorImpl<const Value *> &Args = ICA.getArgs();
5054 if (Args[0] == Args[1]) {
5055 ISD = ISD::ROTR;
5056 // Handle uniform constant rotation amount.
5057 // TODO: Handle funnel-shift cases.
5058 const APInt *Amt;
5059 if (Args[2] &&
5061 ISD = X86ISD::VROTLI;
5062 }
5063 }
5064 break;
5065 case Intrinsic::lrint:
5066 case Intrinsic::llrint: {
5067 // X86 can use the CVTP2SI instructions to lower lrint/llrint calls, which
5068 // have the same costs as the CVTTP2SI (fptosi) instructions
5069 const SmallVectorImpl<Type *> &ArgTys = ICA.getArgTypes();
5070 return getCastInstrCost(Instruction::FPToSI, RetTy, ArgTys[0],
5072 }
5073 case Intrinsic::maxnum:
5074 case Intrinsic::minnum:
5075 // FMINNUM has same costs so don't duplicate.
5076 ISD = ISD::FMAXNUM;
5077 break;
5078 case Intrinsic::sadd_sat:
5079 ISD = ISD::SADDSAT;
5080 break;
5081 case Intrinsic::smax:
5082 ISD = ISD::SMAX;
5083 break;
5084 case Intrinsic::smin:
5085 ISD = ISD::SMIN;
5086 break;
5087 case Intrinsic::ssub_sat:
5088 ISD = ISD::SSUBSAT;
5089 break;
5090 case Intrinsic::uadd_sat:
5091 ISD = ISD::UADDSAT;
5092 break;
5093 case Intrinsic::umax:
5094 ISD = ISD::UMAX;
5095 break;
5096 case Intrinsic::umin:
5097 ISD = ISD::UMIN;
5098 break;
5099 case Intrinsic::usub_sat:
5100 ISD = ISD::USUBSAT;
5101 break;
5102 case Intrinsic::sqrt:
5103 ISD = ISD::FSQRT;
5104 break;
5105 case Intrinsic::sadd_with_overflow:
5106 case Intrinsic::ssub_with_overflow:
5107 // SSUBO has same costs so don't duplicate.
5108 ISD = ISD::SADDO;
5109 OpTy = RetTy->getContainedType(0);
5110 break;
5111 case Intrinsic::uadd_with_overflow:
5112 case Intrinsic::usub_with_overflow:
5113 // USUBO has same costs so don't duplicate.
5114 ISD = ISD::UADDO;
5115 OpTy = RetTy->getContainedType(0);
5116 break;
5117 case Intrinsic::smul_with_overflow:
5118 ISD = ISD::SMULO;
5119 OpTy = RetTy->getContainedType(0);
5120 break;
5121 case Intrinsic::umul_with_overflow:
5122 ISD = ISD::UMULO;
5123 OpTy = RetTy->getContainedType(0);
5124 break;
5125 case Intrinsic::clmul:
5126 ISD = ISD::CLMUL;
5127 break;
5128 }
5129
5130 if (ISD != ISD::DELETED_NODE) {
5131 auto adjustTableCost = [&](int ISD, unsigned Cost,
5132 std::pair<InstructionCost, MVT> LT,
5134 InstructionCost LegalizationCost = LT.first;
5135 MVT MTy = LT.second;
5136
5137 // If there are no NANs to deal with, then these are reduced to a
5138 // single MIN** or MAX** instruction instead of the MIN/CMP/SELECT that we
5139 // assume is used in the non-fast case.
5140 if (ISD == ISD::FMAXNUM || ISD == ISD::FMINNUM) {
5141 if (FMF.noNaNs())
5142 return LegalizationCost * 1;
5143 }
5144
5145 // For cases where some ops can be folded into a load/store, assume free.
5146 if (MTy.isScalarInteger()) {
5147 if (ISD == ISD::BSWAP && ST->hasMOVBE() && ST->hasFastMOVBE()) {
5148 if (const Instruction *II = ICA.getInst()) {
5149 if (II->hasOneUse() && isa<StoreInst>(II->user_back()))
5150 return TTI::TCC_Free;
5151 if (auto *LI = dyn_cast<LoadInst>(II->getOperand(0))) {
5152 if (LI->hasOneUse())
5153 return TTI::TCC_Free;
5154 }
5155 }
5156 }
5157 }
5158
5159 return LegalizationCost * (int)Cost;
5160 };
5161
5162 // Legalize the type.
5163 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(OpTy);
5164 MVT MTy = LT.second;
5165
5166 // Without BMI/LZCNT see if we're only looking for a *_ZERO_POISON cost.
5167 if (((ISD == ISD::CTTZ && !ST->hasBMI()) ||
5168 (ISD == ISD::CTLZ && !ST->hasLZCNT())) &&
5169 !MTy.isVector() && !ICA.isTypeBasedOnly()) {
5170 const SmallVectorImpl<const Value *> &Args = ICA.getArgs();
5171 if (auto *Cst = dyn_cast<ConstantInt>(Args[1]))
5172 if (Cst->isAllOnesValue())
5173 ISD =
5175 }
5176
5177 // FSQRT is a single instruction.
5179 return LT.first;
5180
5181 if (ST->useGLMDivSqrtCosts())
5182 if (const auto *Entry = CostTableLookup(GLMCostTbl, ISD, MTy))
5183 if (auto KindCost = Entry->Cost[CostKind])
5184 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5185
5186 if (ST->useSLMArithCosts())
5187 if (const auto *Entry = CostTableLookup(SLMCostTbl, ISD, MTy))
5188 if (auto KindCost = Entry->Cost[CostKind])
5189 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5190
5191 if (ST->hasVBMI2())
5192 if (const auto *Entry = CostTableLookup(AVX512VBMI2CostTbl, ISD, MTy))
5193 if (auto KindCost = Entry->Cost[CostKind])
5194 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5195
5196 if (ST->hasBITALG())
5197 if (const auto *Entry = CostTableLookup(AVX512BITALGCostTbl, ISD, MTy))
5198 if (auto KindCost = Entry->Cost[CostKind])
5199 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5200
5201 if (ST->hasVPOPCNTDQ())
5202 if (const auto *Entry = CostTableLookup(AVX512VPOPCNTDQCostTbl, ISD, MTy))
5203 if (auto KindCost = Entry->Cost[CostKind])
5204 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5205
5206 if (ST->hasGFNI())
5207 if (const auto *Entry = CostTableLookup(GFNICostTbl, ISD, MTy))
5208 if (auto KindCost = Entry->Cost[CostKind])
5209 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5210
5211 if (ST->hasCDI())
5212 if (const auto *Entry = CostTableLookup(AVX512CDCostTbl, ISD, MTy))
5213 if (auto KindCost = Entry->Cost[CostKind])
5214 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5215
5216 if (ST->hasBWI())
5217 if (const auto *Entry = CostTableLookup(AVX512BWCostTbl, ISD, MTy))
5218 if (auto KindCost = Entry->Cost[CostKind])
5219 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5220
5221 if (ST->hasAVX512())
5222 if (const auto *Entry = CostTableLookup(AVX512CostTbl, ISD, MTy))
5223 if (auto KindCost = Entry->Cost[CostKind])
5224 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5225
5226 if (ST->hasXOP())
5227 if (const auto *Entry = CostTableLookup(XOPCostTbl, ISD, MTy))
5228 if (auto KindCost = Entry->Cost[CostKind])
5229 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5230
5231 if (ST->hasAVX2())
5232 if (const auto *Entry = CostTableLookup(AVX2CostTbl, ISD, MTy))
5233 if (auto KindCost = Entry->Cost[CostKind])
5234 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5235
5236 if (ST->hasAVX())
5237 if (const auto *Entry = CostTableLookup(AVX1CostTbl, ISD, MTy))
5238 if (auto KindCost = Entry->Cost[CostKind])
5239 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5240
5241 if (ST->hasSSE42())
5242 if (const auto *Entry = CostTableLookup(SSE42CostTbl, ISD, MTy))
5243 if (auto KindCost = Entry->Cost[CostKind])
5244 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5245
5246 if (ST->hasSSE41())
5247 if (const auto *Entry = CostTableLookup(SSE41CostTbl, ISD, MTy))
5248 if (auto KindCost = Entry->Cost[CostKind])
5249 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5250
5251 if (ST->hasSSSE3())
5252 if (const auto *Entry = CostTableLookup(SSSE3CostTbl, ISD, MTy))
5253 if (auto KindCost = Entry->Cost[CostKind])
5254 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5255
5256 if (ST->hasSSE2())
5257 if (const auto *Entry = CostTableLookup(SSE2CostTbl, ISD, MTy))
5258 if (auto KindCost = Entry->Cost[CostKind])
5259 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5260
5261 if (ST->hasSSE1())
5262 if (const auto *Entry = CostTableLookup(SSE1CostTbl, ISD, MTy))
5263 if (auto KindCost = Entry->Cost[CostKind])
5264 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5265
5266 if (ST->hasBMI()) {
5267 if (ST->is64Bit())
5268 if (const auto *Entry = CostTableLookup(BMI64CostTbl, ISD, MTy))
5269 if (auto KindCost = Entry->Cost[CostKind])
5270 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5271
5272 if (const auto *Entry = CostTableLookup(BMI32CostTbl, ISD, MTy))
5273 if (auto KindCost = Entry->Cost[CostKind])
5274 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5275 }
5276
5277 if (ST->hasLZCNT()) {
5278 if (ST->is64Bit())
5279 if (const auto *Entry = CostTableLookup(LZCNT64CostTbl, ISD, MTy))
5280 if (auto KindCost = Entry->Cost[CostKind])
5281 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5282
5283 if (const auto *Entry = CostTableLookup(LZCNT32CostTbl, ISD, MTy))
5284 if (auto KindCost = Entry->Cost[CostKind])
5285 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5286 }
5287
5288 if (ST->hasPOPCNT()) {
5289 if (ST->is64Bit())
5290 if (const auto *Entry = CostTableLookup(POPCNT64CostTbl, ISD, MTy))
5291 if (auto KindCost = Entry->Cost[CostKind])
5292 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5293
5294 if (const auto *Entry = CostTableLookup(POPCNT32CostTbl, ISD, MTy))
5295 if (auto KindCost = Entry->Cost[CostKind])
5296 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5297 }
5298
5299 // FIXME: PCLMUL w/ AVX/AVX512 and VPCLMULQDQ are not handled properly.
5300 if (ST->hasPCLMUL())
5301 if (const auto *Entry = CostTableLookup(PCLMULCostTbl, ISD, MTy))
5302 if (auto KindCost = Entry->Cost[CostKind])
5303 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5304
5305 if (ST->is64Bit())
5306 if (const auto *Entry = CostTableLookup(X64CostTbl, ISD, MTy))
5307 if (auto KindCost = Entry->Cost[CostKind])
5308 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5309
5310 if (const auto *Entry = CostTableLookup(X86CostTbl, ISD, MTy))
5311 if (auto KindCost = Entry->Cost[CostKind])
5312 return adjustTableCost(Entry->ISD, *KindCost, LT, ICA.getFlags());
5313
5314 // Without arg data, we need to compute the expanded costs of custom lowered
5315 // intrinsics to prevent use of the (very low) default costs.
5316 if (ICA.isTypeBasedOnly() &&
5317 (IID == Intrinsic::fshl || IID == Intrinsic::fshr)) {
5318 Type *CondTy = RetTy->getWithNewBitWidth(1);
5320 Cost += getArithmeticInstrCost(BinaryOperator::Or, RetTy, CostKind);
5321 Cost += getArithmeticInstrCost(BinaryOperator::Sub, RetTy, CostKind);
5322 Cost += getArithmeticInstrCost(BinaryOperator::Shl, RetTy, CostKind);
5323 Cost += getArithmeticInstrCost(BinaryOperator::LShr, RetTy, CostKind);
5324 Cost += getArithmeticInstrCost(BinaryOperator::And, RetTy, CostKind);
5325 Cost += getCmpSelInstrCost(BinaryOperator::ICmp, RetTy, CondTy,
5327 Cost += getCmpSelInstrCost(BinaryOperator::Select, RetTy, CondTy,
5329 return Cost;
5330 }
5331 }
5332
5334}
5335
5337 unsigned Opcode, Type *Val, TTI::TargetCostKind CostKind, unsigned Index,
5338 const Value *Op0, const Value *Op1, TTI::VectorInstrContext VIC) const {
5339 static const CostTblEntry SLMCostTbl[] = {
5340 { ISD::EXTRACT_VECTOR_ELT, MVT::i8, 4 },
5341 { ISD::EXTRACT_VECTOR_ELT, MVT::i16, 4 },
5342 { ISD::EXTRACT_VECTOR_ELT, MVT::i32, 4 },
5343 { ISD::EXTRACT_VECTOR_ELT, MVT::i64, 7 }
5344 };
5345
5346 assert(Val->isVectorTy() && "This must be a vector type");
5347 auto *VT = cast<VectorType>(Val);
5348 if (VT->isScalableTy())
5350
5351 Type *ScalarType = Val->getScalarType();
5352 InstructionCost RegisterFileMoveCost = 0;
5353
5354 // Non-immediate extraction/insertion can be handled as a sequence of
5355 // aliased loads+stores via the stack.
5356 if (Index == -1U && (Opcode == Instruction::ExtractElement ||
5357 Opcode == Instruction::InsertElement)) {
5358 // TODO: On some SSE41+ targets, we expand to cmp+splat+select patterns:
5359 // inselt N0, N1, N2 --> select (SplatN2 == {0,1,2...}) ? SplatN1 : N0.
5360
5361 // TODO: Move this to BasicTTIImpl.h? We'd need better gep + index handling.
5362 assert(isa<FixedVectorType>(Val) && "Fixed vector type expected");
5363 Align VecAlign = DL.getPrefTypeAlign(Val);
5364 Align SclAlign = DL.getPrefTypeAlign(ScalarType);
5365
5366 // Extract - store vector to stack, load scalar.
5367 if (Opcode == Instruction::ExtractElement) {
5368 return getMemoryOpCost(Instruction::Store, Val, VecAlign, 0, CostKind) +
5369 getMemoryOpCost(Instruction::Load, ScalarType, SclAlign, 0,
5370 CostKind);
5371 }
5372 // Insert - store vector to stack, store scalar, load vector.
5373 if (Opcode == Instruction::InsertElement) {
5374 return getMemoryOpCost(Instruction::Store, Val, VecAlign, 0, CostKind) +
5375 getMemoryOpCost(Instruction::Store, ScalarType, SclAlign, 0,
5376 CostKind) +
5377 getMemoryOpCost(Instruction::Load, Val, VecAlign, 0, CostKind);
5378 }
5379 }
5380
5381 if (Index != -1U && (Opcode == Instruction::ExtractElement ||
5382 Opcode == Instruction::InsertElement)) {
5383 // Extraction of vXi1 elements are now efficiently handled by MOVMSK.
5384 if (Opcode == Instruction::ExtractElement &&
5385 ScalarType->getScalarSizeInBits() == 1 &&
5386 cast<FixedVectorType>(Val)->getNumElements() > 1)
5387 return 1;
5388
5389 // Legalize the type.
5390 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Val);
5391
5392 // This type is legalized to a scalar type.
5393 if (!LT.second.isVector())
5394 return TTI::TCC_Free;
5395
5396 // The type may be split. Normalize the index to the new type.
5397 unsigned SizeInBits = LT.second.getSizeInBits();
5398 unsigned NumElts = LT.second.getVectorNumElements();
5399 unsigned SubNumElts = NumElts;
5400 Index = Index % NumElts;
5401
5402 // For >128-bit vectors, we need to extract higher 128-bit subvectors.
5403 // For inserts, we also need to insert the subvector back.
5404 if (SizeInBits > 128) {
5405 assert((SizeInBits % 128) == 0 && "Illegal vector");
5406 unsigned NumSubVecs = SizeInBits / 128;
5407 SubNumElts = NumElts / NumSubVecs;
5408 if (SubNumElts <= Index) {
5409 RegisterFileMoveCost += (Opcode == Instruction::InsertElement ? 2 : 1);
5410 Index %= SubNumElts;
5411 }
5412 }
5413
5414 MVT MScalarTy = LT.second.getScalarType();
5415 auto IsCheapPInsrPExtrInsertPS = [&]() {
5416 // Assume pinsr/pextr XMM <-> GPR is relatively cheap on all targets.
5417 // Inserting f32 into index0 is just movss.
5418 // Also, assume insertps is relatively cheap on all >= SSE41 targets.
5419 return (MScalarTy == MVT::i16 && ST->hasSSE2()) ||
5420 (MScalarTy.isInteger() && ST->hasSSE41()) ||
5421 (MScalarTy == MVT::f32 && ST->hasSSE1() && Index == 0 &&
5422 Opcode == Instruction::InsertElement) ||
5423 (MScalarTy == MVT::f32 && ST->hasSSE41() &&
5424 Opcode == Instruction::InsertElement);
5425 };
5426
5427 if (Index == 0) {
5428 // Floating point scalars are already located in index #0.
5429 // Many insertions to #0 can fold away for scalar fp-ops, so let's assume
5430 // true for all.
5431 if (ScalarType->isFloatingPointTy() &&
5432 (Opcode != Instruction::InsertElement || !Op0 ||
5433 isa<UndefValue>(Op0)))
5434 return RegisterFileMoveCost;
5435
5436 if (Opcode == Instruction::InsertElement &&
5438 // Consider the gather cost to be cheap.
5440 return RegisterFileMoveCost;
5441 if (!IsCheapPInsrPExtrInsertPS()) {
5442 // mov constant-to-GPR + movd/movq GPR -> XMM.
5443 if (isa_and_nonnull<Constant>(Op1) && Op1->getType()->isIntegerTy())
5444 return 2 + RegisterFileMoveCost;
5445 // Assume movd/movq GPR -> XMM is relatively cheap on all targets.
5446 return 1 + RegisterFileMoveCost;
5447 }
5448 }
5449
5450 // Assume movd/movq XMM -> GPR is relatively cheap on all targets.
5451 if (ScalarType->isIntegerTy() && Opcode == Instruction::ExtractElement)
5452 return 1 + RegisterFileMoveCost;
5453 }
5454
5455 int ISD = TLI->InstructionOpcodeToISD(Opcode);
5456 assert(ISD && "Unexpected vector opcode");
5457 if (ST->useSLMArithCosts())
5458 if (auto *Entry = CostTableLookup(SLMCostTbl, ISD, MScalarTy))
5459 return Entry->Cost + RegisterFileMoveCost;
5460
5461 // Consider cheap cases.
5462 if (IsCheapPInsrPExtrInsertPS())
5463 return 1 + RegisterFileMoveCost;
5464
5465 // For extractions we just need to shuffle the element to index 0, which
5466 // should be very cheap (assume cost = 1). For insertions we need to shuffle
5467 // the elements to its destination. In both cases we must handle the
5468 // subvector move(s).
5469 // If the vector type is already less than 128-bits then don't reduce it.
5470 // TODO: Under what circumstances should we shuffle using the full width?
5471 InstructionCost ShuffleCost = 1;
5472 if (Opcode == Instruction::InsertElement) {
5473 auto *SubTy = cast<VectorType>(Val);
5474 EVT VT = TLI->getValueType(DL, Val);
5475 if (VT.getScalarType() != MScalarTy || VT.getSizeInBits() >= 128)
5476 SubTy = FixedVectorType::get(ScalarType, SubNumElts);
5477 ShuffleCost = getShuffleCost(TTI::SK_PermuteTwoSrc, SubTy, SubTy,
5478 CostKind, {}, 0, SubTy);
5479 }
5480 int IntOrFpCost = ScalarType->isFloatingPointTy() ? 0 : 1;
5481 return ShuffleCost + IntOrFpCost + RegisterFileMoveCost;
5482 }
5483
5484 return BaseT::getVectorInstrCost(Opcode, Val, CostKind, Index, Op0, Op1,
5485 VIC) +
5486 RegisterFileMoveCost;
5487}
5488
5490 VectorType *Ty, const APInt &DemandedElts, bool Insert, bool Extract,
5491 TTI::TargetCostKind CostKind, bool ForPoisonSrc, ArrayRef<Value *> VL,
5492 TTI::VectorInstrContext VIC) const {
5493 assert(DemandedElts.getBitWidth() ==
5494 cast<FixedVectorType>(Ty)->getNumElements() &&
5495 "Vector size mismatch");
5496
5497 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Ty);
5498 MVT MScalarTy = LT.second.getScalarType();
5499 unsigned LegalVectorBitWidth = LT.second.getSizeInBits();
5501
5502 constexpr unsigned LaneBitWidth = 128;
5503 assert((LegalVectorBitWidth < LaneBitWidth ||
5504 (LegalVectorBitWidth % LaneBitWidth) == 0) &&
5505 "Illegal vector");
5506
5507 const int NumLegalVectors = LT.first.getValue();
5508 assert(NumLegalVectors >= 0 && "Negative cost!");
5509
5510 // For insertions, a ISD::BUILD_VECTOR style vector initialization can be much
5511 // cheaper than an accumulation of ISD::INSERT_VECTOR_ELT. SLPVectorizer has
5512 // a special heuristic regarding poison input which is passed here in
5513 // ForPoisonSrc.
5514 if (Insert && !ForPoisonSrc) {
5515 // This is nearly identical to BaseT::getScalarizationOverhead(), except
5516 // it is passing nullptr to getVectorInstrCost() for Op0 (instead of
5517 // Constant::getNullValue()), which makes the X86TTIImpl
5518 // getVectorInstrCost() return 0 instead of 1.
5519 for (unsigned I : seq(DemandedElts.getBitWidth())) {
5520 if (!DemandedElts[I])
5521 continue;
5522 Cost += getVectorInstrCost(Instruction::InsertElement, Ty, CostKind, I,
5524 VL.empty() ? nullptr : VL[I],
5526 }
5527 return Cost;
5528 }
5529
5530 if (Insert) {
5531 if ((MScalarTy == MVT::i16 && ST->hasSSE2()) ||
5532 (MScalarTy.isInteger() && ST->hasSSE41()) ||
5533 (MScalarTy == MVT::f32 && ST->hasSSE41())) {
5534 // For types we can insert directly, insertion into 128-bit sub vectors is
5535 // cheap, followed by a cheap chain of concatenations.
5536 if (LegalVectorBitWidth <= LaneBitWidth) {
5537 Cost += BaseT::getScalarizationOverhead(Ty, DemandedElts, Insert,
5538 /*Extract*/ false, CostKind);
5539 } else {
5540 // In each 128-lane, if at least one index is demanded but not all
5541 // indices are demanded and this 128-lane is not the first 128-lane of
5542 // the legalized-vector, then this 128-lane needs a extracti128; If in
5543 // each 128-lane, there is at least one demanded index, this 128-lane
5544 // needs a inserti128.
5545
5546 // The following cases will help you build a better understanding:
5547 // Assume we insert several elements into a v8i32 vector in avx2,
5548 // Case#1: inserting into 1th index needs vpinsrd + inserti128.
5549 // Case#2: inserting into 5th index needs extracti128 + vpinsrd +
5550 // inserti128.
5551 // Case#3: inserting into 4,5,6,7 index needs 4*vpinsrd + inserti128.
5552 assert((LegalVectorBitWidth % LaneBitWidth) == 0 && "Illegal vector");
5553 unsigned NumLegalLanes = LegalVectorBitWidth / LaneBitWidth;
5554 unsigned NumLanesTotal = NumLegalLanes * NumLegalVectors;
5555 unsigned NumLegalElts =
5556 LT.second.getVectorNumElements() * NumLegalVectors;
5557 assert(NumLegalElts >= DemandedElts.getBitWidth() &&
5558 "Vector has been legalized to smaller element count");
5559 assert((NumLegalElts % NumLanesTotal) == 0 &&
5560 "Unexpected elts per lane");
5561 unsigned NumEltsPerLane = NumLegalElts / NumLanesTotal;
5562
5563 APInt WidenedDemandedElts = DemandedElts.zext(NumLegalElts);
5564 auto *LaneTy =
5565 FixedVectorType::get(Ty->getElementType(), NumEltsPerLane);
5566
5567 for (unsigned I = 0; I != NumLanesTotal; ++I) {
5568 APInt LaneEltMask = WidenedDemandedElts.extractBits(
5569 NumEltsPerLane, NumEltsPerLane * I);
5570 if (LaneEltMask.isZero())
5571 continue;
5572 // FIXME: we don't need to extract if all non-demanded elements
5573 // are legalization-inserted padding.
5574 if (!LaneEltMask.isAllOnes())
5576 {}, I * NumEltsPerLane, LaneTy);
5577 Cost += BaseT::getScalarizationOverhead(LaneTy, LaneEltMask, Insert,
5578 /*Extract*/ false, CostKind);
5579 }
5580
5581 APInt AffectedLanes =
5582 APIntOps::ScaleBitMask(WidenedDemandedElts, NumLanesTotal);
5583 APInt FullyAffectedLegalVectors = APIntOps::ScaleBitMask(
5584 AffectedLanes, NumLegalVectors, /*MatchAllBits=*/true);
5585 for (int LegalVec = 0; LegalVec != NumLegalVectors; ++LegalVec) {
5586 for (unsigned Lane = 0; Lane != NumLegalLanes; ++Lane) {
5587 unsigned I = NumLegalLanes * LegalVec + Lane;
5588 // No need to insert unaffected lane; or lane 0 of each legal vector
5589 // iff ALL lanes of that vector were affected and will be inserted.
5590 if (!AffectedLanes[I] ||
5591 (Lane == 0 && FullyAffectedLegalVectors[LegalVec]))
5592 continue;
5594 {}, I * NumEltsPerLane, LaneTy);
5595 }
5596 }
5597 }
5598 } else if (LT.second.isVector()) {
5599 // Without fast insertion, we need to use MOVD/MOVQ to pass each demanded
5600 // integer element as a SCALAR_TO_VECTOR, then we build the vector as a
5601 // series of UNPCK followed by CONCAT_VECTORS - all of these can be
5602 // considered cheap.
5603 if (Ty->isIntOrIntVectorTy())
5604 Cost += DemandedElts.popcount();
5605
5606 // Get the smaller of the legalized or original pow2-extended number of
5607 // vector elements, which represents the number of unpacks we'll end up
5608 // performing.
5609 unsigned NumElts = LT.second.getVectorNumElements();
5610 unsigned Pow2Elts =
5611 PowerOf2Ceil(cast<FixedVectorType>(Ty)->getNumElements());
5612 Cost += (std::min<unsigned>(NumElts, Pow2Elts) - 1) * LT.first;
5613 }
5614 }
5615
5616 if (Extract) {
5617 // vXi1 can be efficiently extracted with MOVMSK.
5618 // TODO: AVX512 predicate mask handling.
5619 // NOTE: This doesn't work well for roundtrip scalarization.
5620 if (!Insert && Ty->getScalarSizeInBits() == 1 && !ST->hasAVX512()) {
5621 unsigned NumElts = cast<FixedVectorType>(Ty)->getNumElements();
5622 unsigned MaxElts = ST->hasAVX2() ? 32 : 16;
5623 unsigned MOVMSKCost = (NumElts + MaxElts - 1) / MaxElts;
5624 return MOVMSKCost;
5625 }
5626
5627 if (LT.second.isVector()) {
5628 unsigned NumLegalElts =
5629 LT.second.getVectorNumElements() * NumLegalVectors;
5630 assert(NumLegalElts >= DemandedElts.getBitWidth() &&
5631 "Vector has been legalized to smaller element count");
5632
5633 // If we're extracting elements from a 128-bit subvector lane,
5634 // we only need to extract each lane once, not for every element.
5635 if (LegalVectorBitWidth > LaneBitWidth) {
5636 unsigned NumLegalLanes = LegalVectorBitWidth / LaneBitWidth;
5637 unsigned NumLanesTotal = NumLegalLanes * NumLegalVectors;
5638 assert((NumLegalElts % NumLanesTotal) == 0 &&
5639 "Unexpected elts per lane");
5640 unsigned NumEltsPerLane = NumLegalElts / NumLanesTotal;
5641
5642 // Add cost for each demanded 128-bit subvector extraction.
5643 // Luckily this is a lot easier than for insertion.
5644 APInt WidenedDemandedElts = DemandedElts.zext(NumLegalElts);
5645 auto *LaneTy =
5646 FixedVectorType::get(Ty->getElementType(), NumEltsPerLane);
5647
5648 for (unsigned I = 0; I != NumLanesTotal; ++I) {
5649 APInt LaneEltMask = WidenedDemandedElts.extractBits(
5650 NumEltsPerLane, I * NumEltsPerLane);
5651 if (LaneEltMask.isZero())
5652 continue;
5654 I * NumEltsPerLane, LaneTy);
5656 LaneTy, LaneEltMask, /*Insert*/ false, Extract, CostKind);
5657 }
5658
5659 return Cost;
5660 }
5661 }
5662
5663 // Fallback to default extraction.
5664 Cost += BaseT::getScalarizationOverhead(Ty, DemandedElts, /*Insert*/ false,
5665 Extract, CostKind);
5666 }
5667
5668 return Cost;
5669}
5670
5672X86TTIImpl::getReplicationShuffleCost(Type *EltTy, int ReplicationFactor,
5673 int VF, const APInt &DemandedDstElts,
5675 const unsigned EltTyBits = DL.getTypeSizeInBits(EltTy);
5676 // We don't differentiate element types here, only element bit width.
5677 EltTy = IntegerType::getIntNTy(EltTy->getContext(), EltTyBits);
5678
5679 auto bailout = [&]() {
5680 return BaseT::getReplicationShuffleCost(EltTy, ReplicationFactor, VF,
5681 DemandedDstElts, CostKind);
5682 };
5683
5684 // For now, only deal with AVX512 cases.
5685 if (!ST->hasAVX512())
5686 return bailout();
5687
5688 // Do we have a native shuffle for this element type, or should we promote?
5689 unsigned PromEltTyBits = EltTyBits;
5690 switch (EltTyBits) {
5691 case 32:
5692 case 64:
5693 break; // AVX512F.
5694 case 16:
5695 if (!ST->hasBWI())
5696 PromEltTyBits = 32; // promote to i32, AVX512F.
5697 break; // AVX512BW
5698 case 8:
5699 if (!ST->hasVBMI())
5700 PromEltTyBits = 32; // promote to i32, AVX512F.
5701 break; // AVX512VBMI
5702 case 1:
5703 // There is no support for shuffling i1 elements. We *must* promote.
5704 if (ST->hasBWI()) {
5705 if (ST->hasVBMI())
5706 PromEltTyBits = 8; // promote to i8, AVX512VBMI.
5707 else
5708 PromEltTyBits = 16; // promote to i16, AVX512BW.
5709 break;
5710 }
5711 PromEltTyBits = 32; // promote to i32, AVX512F.
5712 break;
5713 default:
5714 return bailout();
5715 }
5716 auto *PromEltTy = IntegerType::getIntNTy(EltTy->getContext(), PromEltTyBits);
5717
5718 auto *SrcVecTy = FixedVectorType::get(EltTy, VF);
5719 auto *PromSrcVecTy = FixedVectorType::get(PromEltTy, VF);
5720
5721 int NumDstElements = VF * ReplicationFactor;
5722 auto *PromDstVecTy = FixedVectorType::get(PromEltTy, NumDstElements);
5723 auto *DstVecTy = FixedVectorType::get(EltTy, NumDstElements);
5724
5725 // Legalize the types.
5726 MVT LegalSrcVecTy = getTypeLegalizationCost(SrcVecTy).second;
5727 MVT LegalPromSrcVecTy = getTypeLegalizationCost(PromSrcVecTy).second;
5728 MVT LegalPromDstVecTy = getTypeLegalizationCost(PromDstVecTy).second;
5729 MVT LegalDstVecTy = getTypeLegalizationCost(DstVecTy).second;
5730 // They should have legalized into vector types.
5731 if (!LegalSrcVecTy.isVector() || !LegalPromSrcVecTy.isVector() ||
5732 !LegalPromDstVecTy.isVector() || !LegalDstVecTy.isVector())
5733 return bailout();
5734
5735 if (PromEltTyBits != EltTyBits) {
5736 // If we have to perform the shuffle with wider elt type than our data type,
5737 // then we will first need to anyext (we don't care about the new bits)
5738 // the source elements, and then truncate Dst elements.
5739 InstructionCost PromotionCost;
5740 PromotionCost += getCastInstrCost(
5741 Instruction::SExt, /*Dst=*/PromSrcVecTy, /*Src=*/SrcVecTy,
5743 PromotionCost +=
5744 getCastInstrCost(Instruction::Trunc, /*Dst=*/DstVecTy,
5745 /*Src=*/PromDstVecTy,
5747 return PromotionCost + getReplicationShuffleCost(PromEltTy,
5748 ReplicationFactor, VF,
5749 DemandedDstElts, CostKind);
5750 }
5751
5752 assert(LegalSrcVecTy.getScalarSizeInBits() == EltTyBits &&
5753 LegalSrcVecTy.getScalarType() == LegalDstVecTy.getScalarType() &&
5754 "We expect that the legalization doesn't affect the element width, "
5755 "doesn't coalesce/split elements.");
5756
5757 unsigned NumEltsPerDstVec = LegalDstVecTy.getVectorNumElements();
5758 unsigned NumDstVectors =
5759 divideCeil(DstVecTy->getNumElements(), NumEltsPerDstVec);
5760
5761 auto *SingleDstVecTy = FixedVectorType::get(EltTy, NumEltsPerDstVec);
5762
5763 // Not all the produced Dst elements may be demanded. In our case,
5764 // given that a single Dst vector is formed by a single shuffle,
5765 // if all elements that will form a single Dst vector aren't demanded,
5766 // then we won't need to do that shuffle, so adjust the cost accordingly.
5767 APInt DemandedDstVectors = APIntOps::ScaleBitMask(
5768 DemandedDstElts.zext(NumDstVectors * NumEltsPerDstVec), NumDstVectors);
5769 unsigned NumDstVectorsDemanded = DemandedDstVectors.popcount();
5770
5771 InstructionCost SingleShuffleCost =
5772 getShuffleCost(TTI::SK_PermuteSingleSrc, SingleDstVecTy, SingleDstVecTy,
5773 CostKind, /*Mask=*/{},
5774 /*Index=*/0, /*SubTp=*/nullptr);
5775 return NumDstVectorsDemanded * SingleShuffleCost;
5776}
5777
5779 Align Alignment,
5780 unsigned AddressSpace,
5782 TTI::OperandValueInfo OpInfo,
5783 const Instruction *I) const {
5784 // FIXME: Load latency isn't handled here
5785 if (Opcode == Instruction::Load && CostKind == TTI::TCK_Latency)
5786 return BaseT::getMemoryOpCost(Opcode, Src, Alignment, AddressSpace,
5787 CostKind, OpInfo, I);
5788
5789 // TODO: Handle other cost kinds.
5791 if (auto *SI = dyn_cast_or_null<StoreInst>(I)) {
5792 // Store instruction with index and scale costs 2 Uops.
5793 // Check the preceding GEP to identify non-const indices.
5794 if (auto *GEP = dyn_cast<GetElementPtrInst>(SI->getPointerOperand())) {
5795 if (!all_of(GEP->indices(), [](Value *V) { return isa<Constant>(V); }))
5796 return TTI::TCC_Basic * 2;
5797 }
5798 }
5799 return TTI::TCC_Basic;
5800 }
5801
5802 assert((Opcode == Instruction::Load || Opcode == Instruction::Store) &&
5803 "Invalid Opcode");
5804 // Type legalization can't handle structs
5805 if (TLI->getValueType(DL, Src, true) == MVT::Other)
5806 return BaseT::getMemoryOpCost(Opcode, Src, Alignment, AddressSpace,
5807 CostKind, OpInfo, I);
5808
5809 // Legalize the type.
5810 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Src);
5811
5812 auto *VTy = dyn_cast<FixedVectorType>(Src);
5813
5815
5816 // Add a cost for constant load to vector.
5817 if (Opcode == Instruction::Store && OpInfo.isConstant())
5818 Cost += getMemoryOpCost(Instruction::Load, Src, DL.getABITypeAlign(Src),
5819 /*AddressSpace=*/0, CostKind, OpInfo);
5820
5821 // Handle the simple case of non-vectors.
5822 // NOTE: this assumes that legalization never creates vector from scalars!
5823 if (!VTy || !LT.second.isVector()) {
5824 // Each load/store unit costs 1.
5825 return (LT.second.isFloatingPoint() ? Cost : 0) + LT.first * 1;
5826 }
5827
5828 bool IsLoad = Opcode == Instruction::Load;
5829
5830 Type *EltTy = VTy->getElementType();
5831
5832 const int EltTyBits = DL.getTypeSizeInBits(EltTy);
5833
5834 // Source of truth: how many elements were there in the original IR vector?
5835 const unsigned SrcNumElt = VTy->getNumElements();
5836
5837 // How far have we gotten?
5838 int NumEltRemaining = SrcNumElt;
5839 // Note that we intentionally capture by-reference, NumEltRemaining changes.
5840 auto NumEltDone = [&]() { return SrcNumElt - NumEltRemaining; };
5841
5842 const int MaxLegalOpSizeBytes = divideCeil(LT.second.getSizeInBits(), 8);
5843
5844 // Note that even if we can store 64 bits of an XMM, we still operate on XMM.
5845 const unsigned XMMBits = 128;
5846 if (XMMBits % EltTyBits != 0)
5847 // Vector size must be a multiple of the element size. I.e. no padding.
5848 return BaseT::getMemoryOpCost(Opcode, Src, Alignment, AddressSpace,
5849 CostKind, OpInfo, I);
5850 const int NumEltPerXMM = XMMBits / EltTyBits;
5851
5852 auto *XMMVecTy = FixedVectorType::get(EltTy, NumEltPerXMM);
5853
5854 for (int CurrOpSizeBytes = MaxLegalOpSizeBytes, SubVecEltsLeft = 0;
5855 NumEltRemaining > 0; CurrOpSizeBytes /= 2) {
5856 // How many elements would a single op deal with at once?
5857 if ((8 * CurrOpSizeBytes) % EltTyBits != 0)
5858 // Vector size must be a multiple of the element size. I.e. no padding.
5859 return BaseT::getMemoryOpCost(Opcode, Src, Alignment, AddressSpace,
5860 CostKind, OpInfo, I);
5861 int CurrNumEltPerOp = (8 * CurrOpSizeBytes) / EltTyBits;
5862
5863 assert(CurrOpSizeBytes > 0 && CurrNumEltPerOp > 0 && "How'd we get here?");
5864 assert((((NumEltRemaining * EltTyBits) < (2 * 8 * CurrOpSizeBytes)) ||
5865 (CurrOpSizeBytes == MaxLegalOpSizeBytes)) &&
5866 "Unless we haven't halved the op size yet, "
5867 "we have less than two op's sized units of work left.");
5868
5869 auto *CurrVecTy = CurrNumEltPerOp > NumEltPerXMM
5870 ? FixedVectorType::get(EltTy, CurrNumEltPerOp)
5871 : XMMVecTy;
5872
5873 assert(CurrVecTy->getNumElements() % CurrNumEltPerOp == 0 &&
5874 "After halving sizes, the vector elt count is no longer a multiple "
5875 "of number of elements per operation?");
5876 auto *CoalescedVecTy =
5877 CurrNumEltPerOp == 1
5878 ? CurrVecTy
5880 IntegerType::get(Src->getContext(),
5881 EltTyBits * CurrNumEltPerOp),
5882 CurrVecTy->getNumElements() / CurrNumEltPerOp);
5883 assert(DL.getTypeSizeInBits(CoalescedVecTy) ==
5884 DL.getTypeSizeInBits(CurrVecTy) &&
5885 "coalesciing elements doesn't change vector width.");
5886
5887 while (NumEltRemaining > 0) {
5888 assert(SubVecEltsLeft >= 0 && "Subreg element count overconsumtion?");
5889
5890 // Can we use this vector size, as per the remaining element count?
5891 // Iff the vector is naturally aligned, we can do a wide load regardless.
5892 if (NumEltRemaining < CurrNumEltPerOp &&
5893 (!IsLoad || Alignment < CurrOpSizeBytes) && CurrOpSizeBytes != 1)
5894 break; // Try smalled vector size.
5895
5896 // This isn't exactly right. We're using slow unaligned 32-byte accesses
5897 // as a proxy for a double-pumped AVX memory interface such as on
5898 // Sandybridge.
5899 // Sub-32-bit loads/stores will be slower either with PINSR*/PEXTR* or
5900 // will be scalarized.
5901 if (CurrOpSizeBytes == 32 && ST->isUnalignedMem32Slow())
5902 Cost += 2;
5903 else if (CurrOpSizeBytes < 4)
5904 Cost += 2;
5905 else
5906 Cost += 1;
5907
5908 // If we're loading a uniform value, then we don't need to split the load,
5909 // loading just a single (widest) vector can be reused by all splits.
5910 if (IsLoad && OpInfo.isUniform())
5911 return Cost;
5912
5913 bool Is0thSubVec = (NumEltDone() % LT.second.getVectorNumElements()) == 0;
5914
5915 // If we have fully processed the previous reg, we need to replenish it.
5916 if (SubVecEltsLeft == 0) {
5917 SubVecEltsLeft += CurrVecTy->getNumElements();
5918 // And that's free only for the 0'th subvector of a legalized vector.
5919 if (!Is0thSubVec)
5920 Cost +=
5923 VTy, VTy, CostKind, {}, NumEltDone(), CurrVecTy);
5924 }
5925
5926 // While we can directly load/store ZMM, YMM, and 64-bit halves of XMM,
5927 // for smaller widths (32/16/8) we have to insert/extract them separately.
5928 // Again, it's free for the 0'th subreg (if op is 32/64 bit wide,
5929 // but let's pretend that it is also true for 16/8 bit wide ops...)
5930 if (CurrOpSizeBytes <= 32 / 8 && !Is0thSubVec) {
5931 int NumEltDoneInCurrXMM = NumEltDone() % NumEltPerXMM;
5932 assert(NumEltDoneInCurrXMM % CurrNumEltPerOp == 0 && "");
5933 int CoalescedVecEltIdx = NumEltDoneInCurrXMM / CurrNumEltPerOp;
5934 APInt DemandedElts =
5935 APInt::getBitsSet(CoalescedVecTy->getNumElements(),
5936 CoalescedVecEltIdx, CoalescedVecEltIdx + 1);
5937 assert(DemandedElts.popcount() == 1 && "Inserting single value");
5938 Cost += getScalarizationOverhead(CoalescedVecTy, DemandedElts, IsLoad,
5939 !IsLoad, CostKind);
5940 }
5941
5942 SubVecEltsLeft -= CurrNumEltPerOp;
5943 NumEltRemaining -= CurrNumEltPerOp;
5944 Alignment = commonAlignment(Alignment, CurrOpSizeBytes);
5945 }
5946 }
5947
5948 assert(NumEltRemaining <= 0 && "Should have processed all the elements.");
5949
5950 return Cost;
5951}
5952
5956 switch (MICA.getID()) {
5957 case Intrinsic::masked_scatter:
5958 case Intrinsic::masked_gather:
5959 return getGatherScatterOpCost(MICA, CostKind);
5960 case Intrinsic::masked_load:
5961 case Intrinsic::masked_store:
5962 return getMaskedMemoryOpCost(MICA, CostKind);
5963 }
5965}
5966
5970 unsigned Opcode = MICA.getID() == Intrinsic::masked_load ? Instruction::Load
5971 : Instruction::Store;
5972 Type *SrcTy = MICA.getDataType();
5973 Align Alignment = MICA.getAlignment();
5974 unsigned AddressSpace = MICA.getAddressSpace();
5975
5976 bool IsLoad = (Instruction::Load == Opcode);
5977 bool IsStore = (Instruction::Store == Opcode);
5978
5979 auto *SrcVTy = dyn_cast<FixedVectorType>(SrcTy);
5980 if (!SrcVTy)
5981 // To calculate scalar take the regular cost, without mask
5982 return getMemoryOpCost(Opcode, SrcTy, Alignment, AddressSpace, CostKind);
5983
5984 unsigned NumElem = SrcVTy->getNumElements();
5985 auto *MaskTy =
5986 FixedVectorType::get(Type::getInt8Ty(SrcVTy->getContext()), NumElem);
5987 if ((IsLoad && !isLegalMaskedLoad(SrcVTy, Alignment, AddressSpace)) ||
5988 (IsStore && !isLegalMaskedStore(SrcVTy, Alignment, AddressSpace))) {
5989 // Scalarization
5990 APInt DemandedElts = APInt::getAllOnes(NumElem);
5992 MaskTy, DemandedElts, /*Insert*/ false, /*Extract*/ true, CostKind);
5993 InstructionCost ScalarCompareCost = getCmpSelInstrCost(
5994 Instruction::ICmp, Type::getInt8Ty(SrcVTy->getContext()), nullptr,
5996 InstructionCost BranchCost = getCFInstrCost(Instruction::CondBr, CostKind);
5997 InstructionCost MaskCmpCost = NumElem * (BranchCost + ScalarCompareCost);
5999 SrcVTy, DemandedElts, IsLoad, IsStore, CostKind);
6000 InstructionCost MemopCost =
6001 NumElem * BaseT::getMemoryOpCost(Opcode, SrcVTy->getScalarType(),
6002 Alignment, AddressSpace, CostKind);
6003 return MemopCost + ValueSplitCost + MaskSplitCost + MaskCmpCost;
6004 }
6005
6006 // Legalize the type.
6007 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(SrcVTy);
6008 auto VT = TLI->getValueType(DL, SrcVTy);
6010 MVT Ty = LT.second;
6011 if (Ty == MVT::i16 || Ty == MVT::i32 || Ty == MVT::i64)
6012 // APX masked load/store for scalar is cheap.
6013 return Cost + LT.first;
6014
6015 if (VT.isSimple() && Ty != VT.getSimpleVT() &&
6016 LT.second.getVectorNumElements() == NumElem)
6017 // Promotion requires extend/truncate for data and a shuffle for mask.
6018 Cost += getShuffleCost(TTI::SK_PermuteTwoSrc, SrcVTy, SrcVTy, CostKind, {},
6019 0, nullptr) +
6020 getShuffleCost(TTI::SK_PermuteTwoSrc, MaskTy, MaskTy, CostKind, {},
6021 0, nullptr);
6022
6023 else if (LT.first * Ty.getVectorNumElements() > NumElem) {
6024 auto *NewMaskTy = FixedVectorType::get(MaskTy->getElementType(),
6025 (unsigned)LT.first.getValue() *
6026 Ty.getVectorNumElements());
6027 // Expanding requires fill mask with zeroes
6028 Cost += getShuffleCost(TTI::SK_InsertSubvector, NewMaskTy, NewMaskTy,
6029 CostKind, {}, 0, MaskTy);
6030 }
6031
6032 // Pre-AVX512 - each maskmov load costs 2 + store costs ~8.
6033 if (!ST->hasAVX512())
6034 return Cost + LT.first * (IsLoad ? 2 : 8);
6035
6036 // AVX-512 masked load/store is cheaper
6037 return Cost + LT.first;
6038}
6039
6041 ArrayRef<const Value *> Ptrs, const Value *Base,
6042 const TTI::PointersChainInfo &Info, Type *AccessTy,
6043 const TTI::TargetCostKind CostKind) const {
6044 if (Info.isSameBase() && Info.isKnownStride()) {
6045 // If all the pointers have known stride all the differences are translated
6046 // into constants. X86 memory addressing allows encoding it into
6047 // displacement. So we just need to take the base GEP cost.
6048 if (const auto *BaseGEP = dyn_cast<GetElementPtrInst>(Base)) {
6049 SmallVector<const Value *> Indices(BaseGEP->indices());
6050 return getGEPCost(BaseGEP->getSourceElementType(),
6051 BaseGEP->getPointerOperand(), Indices, CostKind,
6052 nullptr);
6053 }
6054 return TTI::TCC_Free;
6055 }
6056 return BaseT::getPointersChainCost(Ptrs, Base, Info, AccessTy, CostKind);
6057}
6058
6061 const SCEV *Ptr,
6063 // Address computations in vectorized code with non-consecutive addresses will
6064 // likely result in more instructions compared to scalar code where the
6065 // computation can more often be merged into the index mode. The resulting
6066 // extra micro-ops can significantly decrease throughput.
6067 const unsigned NumVectorInstToHideOverhead = 10;
6068
6069 // Cost modeling of Strided Access Computation is hidden by the indexing
6070 // modes of X86 regardless of the stride value. We dont believe that there
6071 // is a difference between constant strided access in gerenal and constant
6072 // strided value which is less than or equal to 64.
6073 // Even in the case of (loop invariant) stride whose value is not known at
6074 // compile time, the address computation will not incur more than one extra
6075 // ADD instruction.
6076 if (PtrTy->isVectorTy() && SE && !ST->hasAVX2()) {
6077 // TODO: AVX2 is the current cut-off because we don't have correct
6078 // interleaving costs for prior ISA's.
6079 if (!BaseT::isStridedAccess(Ptr))
6080 return NumVectorInstToHideOverhead;
6081 if (!BaseT::getConstantStrideStep(SE, Ptr))
6082 return 1;
6083 }
6084
6085 return BaseT::getAddressComputationCost(PtrTy, SE, Ptr, CostKind);
6086}
6087
6090 std::optional<FastMathFlags> FMF,
6093 return BaseT::getArithmeticReductionCost(Opcode, ValTy, FMF, CostKind);
6094
6095 // We use llvm-mca across all supported CPUs to measure the logic cost stats.
6096 // We use the Intel Architecture Code Analyzer(IACA) to measure the throughput
6097 // and make it as the cost. TODO: Update old IACA numbers to llvm-mca.
6098
6099 static const CostKindTblEntry SLMCostTbl[] = {
6100 { ISD::FADD, MVT::v2f64, {3, 3, 3, 3} },
6101 { ISD::ADD, MVT::v2i64, {5, 5, 5, 5} },
6102 };
6103
6104 static const CostKindTblEntry SSE2CostTbl[] = {
6105 { ISD::FADD, MVT::v2f64, {2, 2, 2, 2} },
6106 { ISD::FADD, MVT::v2f32, {2, 2, 2, 2} },
6107 { ISD::FADD, MVT::v4f32, {4, 4, 4, 4} },
6108 { ISD::ADD, MVT::v2i64, {2, 2, 2, 2} }, // The data reported by the IACA tool is "1.6".
6109 { ISD::ADD, MVT::v2i32, {2, 2, 2, 2} }, // FIXME: chosen to be less than v4i32
6110 { ISD::ADD, MVT::v4i32, {3, 3, 3, 3} }, // The data reported by the IACA tool is "3.3".
6111 { ISD::ADD, MVT::v2i16, {2, 2, 2, 2} }, // The data reported by the IACA tool is "4.3".
6112 { ISD::ADD, MVT::v4i16, {3, 3, 3, 3} }, // The data reported by the IACA tool is "4.3".
6113 { ISD::ADD, MVT::v8i16, {4, 4, 4, 4} }, // The data reported by the IACA tool is "4.3".
6114 { ISD::ADD, MVT::v2i8, {2, 2, 2, 2} },
6115 { ISD::ADD, MVT::v4i8, {2, 2, 2, 2} },
6116 { ISD::ADD, MVT::v8i8, {2, 2, 2, 2} },
6117 { ISD::ADD, MVT::v16i8, {3, 3, 3, 3} },
6118
6119 { ISD::AND, MVT::v2i64, {2, 2, 3, 3} },
6120 { ISD::AND, MVT::v4i32, {3, 4, 5, 5} },
6121 { ISD::AND, MVT::v8i16, {4, 7, 8, 8} },
6122 { ISD::AND, MVT::v16i8, {6,10,11,11} },
6123 { ISD::OR, MVT::v2i64, {2, 2, 3, 3} },
6124 { ISD::OR, MVT::v4i32, {3, 4, 5, 5} },
6125 { ISD::OR, MVT::v8i16, {4, 7, 8, 8} },
6126 { ISD::OR, MVT::v16i8, {6,10,11,11} },
6127 { ISD::XOR, MVT::v2i64, {2, 2, 3, 3} },
6128 { ISD::XOR, MVT::v4i32, {3, 4, 5, 5} },
6129 { ISD::XOR, MVT::v8i16, {4, 7, 8, 8} },
6130 { ISD::XOR, MVT::v16i8, {6,10,11,11} },
6131 };
6132
6133 static const CostKindTblEntry AVX1CostTbl[] = {
6134 { ISD::FADD, MVT::v4f64, {3, 3, 3, 3} },
6135 { ISD::FADD, MVT::v4f32, {3, 3, 3, 3} },
6136 { ISD::FADD, MVT::v8f32, {4, 4, 4, 4} },
6137 { ISD::ADD, MVT::v2i64, {1, 1, 1, 1} }, // The data reported by the IACA tool is "1.5".
6138 { ISD::ADD, MVT::v4i64, {3, 3, 3, 3} },
6139 { ISD::ADD, MVT::v8i32, {5, 5, 5, 5} },
6140 { ISD::ADD, MVT::v16i16, {5, 5, 5, 5} },
6141 { ISD::ADD, MVT::v32i8, {4, 4, 4, 4} },
6142
6143 { ISD::AND, MVT::v4i64, {3, 7, 5, 5} },
6144 { ISD::AND, MVT::v8i32, {4, 9, 7, 7} },
6145 { ISD::AND, MVT::v16i16, {5,11, 9, 9} },
6146 { ISD::AND, MVT::v8i16, {4, 7, 7, 7} },
6147 { ISD::AND, MVT::v32i8, {6,13,11,11} },
6148 { ISD::AND, MVT::v16i8, {5,10, 9, 9} },
6149 { ISD::OR, MVT::v4i64, {3, 7, 5, 5} },
6150 { ISD::OR, MVT::v8i32, {4, 9, 7, 7} },
6151 { ISD::OR, MVT::v16i16, {5,11, 9, 9} },
6152 { ISD::OR, MVT::v8i16, {4, 7, 7, 7} },
6153 { ISD::OR, MVT::v32i8, {6,13,11,11} },
6154 { ISD::OR, MVT::v16i8, {5,10, 9, 9} },
6155 { ISD::XOR, MVT::v4i64, {3, 7, 5, 5} },
6156 { ISD::XOR, MVT::v8i32, {4, 9, 7, 7} },
6157 { ISD::XOR, MVT::v16i16, {5,11, 9, 9} },
6158 { ISD::XOR, MVT::v8i16, {4, 7, 7, 7} },
6159 { ISD::XOR, MVT::v32i8, {6,13,11,11} },
6160 { ISD::XOR, MVT::v16i8, {5,10, 9, 9} },
6161 };
6162
6163 static const CostKindTblEntry AVX2CostTbl[] = {
6164 { ISD::AND, MVT::v4i64, {2, 7, 5, 5} },
6165 { ISD::AND, MVT::v2i64, {1, 2, 3, 3} },
6166 { ISD::AND, MVT::v8i32, {3, 9, 7, 7} },
6167 { ISD::AND, MVT::v4i32, {2, 4, 5, 5} },
6168 { ISD::AND, MVT::v16i16, {3,11, 9, 9} },
6169 { ISD::AND, MVT::v8i16, {2, 6, 7, 7} },
6170 { ISD::AND, MVT::v32i8, {3,13,11,11} },
6171 { ISD::AND, MVT::v16i8, {3, 8, 9, 9} },
6172 { ISD::OR, MVT::v4i64, {2, 7, 5, 5} },
6173 { ISD::OR, MVT::v2i64, {1, 2, 3, 3} },
6174 { ISD::OR, MVT::v8i32, {3, 9, 7, 7} },
6175 { ISD::OR, MVT::v4i32, {2, 4, 5, 5} },
6176 { ISD::OR, MVT::v16i16, {3,11, 9, 9} },
6177 { ISD::OR, MVT::v8i16, {2, 6, 7, 7} },
6178 { ISD::OR, MVT::v32i8, {3,13,11,11} },
6179 { ISD::OR, MVT::v16i8, {3, 8, 9, 9} },
6180 { ISD::XOR, MVT::v4i64, {2, 7, 5, 5} },
6181 { ISD::XOR, MVT::v2i64, {1, 2, 3, 3} },
6182 { ISD::XOR, MVT::v8i32, {3, 9, 7, 7} },
6183 { ISD::XOR, MVT::v4i32, {2, 4, 5, 5} },
6184 { ISD::XOR, MVT::v16i16, {3,11, 9, 9} },
6185 { ISD::XOR, MVT::v8i16, {2, 6, 7, 7} },
6186 { ISD::XOR, MVT::v32i8, {3,13,11,11} },
6187 { ISD::XOR, MVT::v16i8, {3, 8, 9, 9} },
6188 };
6189
6190 static const CostKindTblEntry AVX512FCostTbl[] = {
6191 { ISD::FADD, MVT::v8f64, {4, 4, 4, 4} },
6192 { ISD::FADD, MVT::v16f32, {5, 5, 5, 5} },
6193 { ISD::ADD, MVT::v8i64, {4, 4, 4, 4} },
6194 { ISD::ADD, MVT::v16i32, {6, 6, 6, 6} },
6195
6196 { ISD::AND, MVT::v8i64, {3,10, 7, 7} },
6197 { ISD::AND, MVT::v16i32, {4,12, 9, 9} },
6198 { ISD::AND, MVT::v32i16, {4,14,11,11} },
6199 { ISD::AND, MVT::v64i8, {4,16,13,13} },
6200 { ISD::AND, MVT::v16i8, {2, 8, 9, 9} },
6201 { ISD::OR, MVT::v8i64, {3,10, 7, 7} },
6202 { ISD::OR, MVT::v16i32, {4,12, 9, 9} },
6203 { ISD::OR, MVT::v32i16, {4,14,11,11} },
6204 { ISD::OR, MVT::v64i8, {4,16,13,13} },
6205 { ISD::OR, MVT::v16i8, {2, 8, 9, 9} },
6206 { ISD::XOR, MVT::v8i64, {3,10, 7, 7} },
6207 { ISD::XOR, MVT::v16i32, {4,12, 9, 9} },
6208 { ISD::XOR, MVT::v32i16, {4,14,11,11} },
6209 { ISD::XOR, MVT::v64i8, {4,16,13,13} },
6210 { ISD::XOR, MVT::v16i8, {2, 8, 9, 9} },
6211 };
6212
6213 static const CostKindTblEntry AVX512BWCostTbl[] = {
6214 { ISD::ADD, MVT::v32i16, {7, 7, 7, 7} },
6215 { ISD::ADD, MVT::v64i8, {4, 4, 4, 4} },
6216 };
6217
6218 int ISD = TLI->InstructionOpcodeToISD(Opcode);
6219 assert(ISD && "Invalid opcode");
6220
6221 // Before legalizing the type, give a chance to look up illegal narrow types
6222 // in the table.
6223 // FIXME: Is there a better way to do this?
6224 EVT VT = TLI->getValueType(DL, ValTy);
6225 if (VT.isSimple()) {
6226 MVT MTy = VT.getSimpleVT();
6227 if (ST->useSLMArithCosts())
6228 if (const auto *Entry = CostTableLookup(SLMCostTbl, ISD, MTy))
6229 if (auto KindCost = Entry->Cost[CostKind])
6230 return *KindCost;
6231
6232 if (ST->hasBWI())
6233 if (const auto *Entry = CostTableLookup(AVX512BWCostTbl, ISD, MTy))
6234 if (auto KindCost = Entry->Cost[CostKind])
6235 return *KindCost;
6236
6237 if (ST->hasAVX512())
6238 if (const auto *Entry = CostTableLookup(AVX512FCostTbl, ISD, MTy))
6239 if (auto KindCost = Entry->Cost[CostKind])
6240 return *KindCost;
6241
6242 if (ST->hasAVX2())
6243 if (const auto *Entry = CostTableLookup(AVX2CostTbl, ISD, MTy))
6244 if (auto KindCost = Entry->Cost[CostKind])
6245 return *KindCost;
6246
6247 if (ST->hasAVX())
6248 if (const auto *Entry = CostTableLookup(AVX1CostTbl, ISD, MTy))
6249 if (auto KindCost = Entry->Cost[CostKind])
6250 return *KindCost;
6251
6252 if (ST->hasSSE2())
6253 if (const auto *Entry = CostTableLookup(SSE2CostTbl, ISD, MTy))
6254 if (auto KindCost = Entry->Cost[CostKind])
6255 return *KindCost;
6256 }
6257
6258 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(ValTy);
6259
6260 MVT MTy = LT.second;
6261
6262 auto *ValVTy = cast<FixedVectorType>(ValTy);
6263
6264 InstructionCost ArithmeticCost = 0;
6265 if (LT.first != 1 && MTy.isVector() &&
6266 MTy.getVectorNumElements() < ValVTy->getNumElements()) {
6267 // Type needs to be split. We need LT.first - 1 arithmetic ops.
6268 auto *SingleOpTy = FixedVectorType::get(ValVTy->getElementType(),
6269 MTy.getVectorNumElements());
6270 ArithmeticCost = getArithmeticInstrCost(Opcode, SingleOpTy, CostKind);
6271 ArithmeticCost *= LT.first - 1;
6272 }
6273
6274 // FIXME: These assume a naive kshift+binop lowering, which is probably
6275 // conservative in most cases.
6276 static const CostKindTblEntry AVX512BoolReduction[] = {
6277 { ISD::AND, MVT::v2i1, { 3, 3, 3, 3} },
6278 { ISD::AND, MVT::v4i1, { 5, 5, 5, 5} },
6279 { ISD::AND, MVT::v8i1, { 7, 7, 7, 7} },
6280 { ISD::AND, MVT::v16i1, { 9, 9, 9, 9} },
6281 { ISD::AND, MVT::v32i1, {11,11,11,11} },
6282 { ISD::AND, MVT::v64i1, {13,13,13,13} },
6283 { ISD::OR, MVT::v2i1, { 3, 3, 3, 3} },
6284 { ISD::OR, MVT::v4i1, { 5, 5, 5, 5} },
6285 { ISD::OR, MVT::v8i1, { 7, 7, 7, 7} },
6286 { ISD::OR, MVT::v16i1, { 9, 9, 9, 9} },
6287 { ISD::OR, MVT::v32i1, {11,11,11,11} },
6288 { ISD::OR, MVT::v64i1, {13,13,13,13} },
6289 };
6290
6291 static const CostKindTblEntry AVX2BoolReduction[] = {
6292 { ISD::AND, MVT::v16i16, { 2, 2, 2, 2} }, // vpmovmskb + cmp
6293 { ISD::AND, MVT::v32i8, { 2, 2, 2, 2} }, // vpmovmskb + cmp
6294 { ISD::OR, MVT::v16i16, { 2, 2, 2, 2} }, // vpmovmskb + cmp
6295 { ISD::OR, MVT::v32i8, { 2, 2, 2, 2} }, // vpmovmskb + cmp
6296 };
6297
6298 static const CostKindTblEntry AVX1BoolReduction[] = {
6299 { ISD::AND, MVT::v4i64, {2, 2, 2, 2} }, // vmovmskpd + cmp
6300 { ISD::AND, MVT::v8i32, {2, 2, 2, 2} }, // vmovmskps + cmp
6301 { ISD::AND, MVT::v16i16, {4, 4, 4, 4} }, // vextractf128 + vpand + vpmovmskb + cmp
6302 { ISD::AND, MVT::v32i8, {4, 4, 4, 4} }, // vextractf128 + vpand + vpmovmskb + cmp
6303 { ISD::OR, MVT::v4i64, {2, 2, 2, 2} }, // vmovmskpd + cmp
6304 { ISD::OR, MVT::v8i32, {2, 2, 2, 2} }, // vmovmskps + cmp
6305 { ISD::OR, MVT::v16i16, {4, 4, 4, 4} }, // vextractf128 + vpor + vpmovmskb + cmp
6306 { ISD::OR, MVT::v32i8, {4, 4, 4, 4} }, // vextractf128 + vpor + vpmovmskb + cmp
6307 };
6308
6309 static const CostKindTblEntry SSE2BoolReduction[] = {
6310 { ISD::AND, MVT::v2i64, {2, 2, 2, 2} }, // movmskpd + cmp
6311 { ISD::AND, MVT::v4i32, {2, 2, 2, 2} }, // movmskps + cmp
6312 { ISD::AND, MVT::v8i16, {2, 2, 2, 2} }, // pmovmskb + cmp
6313 { ISD::AND, MVT::v16i8, {2, 2, 2, 2} }, // pmovmskb + cmp
6314 { ISD::OR, MVT::v2i64, {2, 2, 2, 2} }, // movmskpd + cmp
6315 { ISD::OR, MVT::v4i32, {2, 2, 2, 2} }, // movmskps + cmp
6316 { ISD::OR, MVT::v8i16, {2, 2, 2, 2} }, // pmovmskb + cmp
6317 { ISD::OR, MVT::v16i8, {2, 2, 2, 2} }, // pmovmskb + cmp
6318 };
6319
6320 // Handle bool allof/anyof vXi1 patterns before we check legal types.
6321 if (ValVTy->getElementType()->isIntegerTy(1)) {
6322 if (ISD == ISD::ADD) {
6323 // vXi1 addition reduction will bitcast to scalar and perform a popcount.
6324 auto *IntTy = IntegerType::getIntNTy(ValVTy->getContext(),
6325 ValVTy->getNumElements());
6326 IntrinsicCostAttributes ICA(Intrinsic::ctpop, IntTy, {IntTy});
6327 return getCastInstrCost(Instruction::BitCast, IntTy, ValVTy,
6329 CostKind) +
6331 }
6332
6333 if (ST->hasAVX512())
6334 if (const auto *Entry = CostTableLookup(AVX512BoolReduction, ISD, MTy))
6335 if (auto KindCost = Entry->Cost[CostKind])
6336 return ArithmeticCost + *KindCost;
6337 if (ST->hasAVX2())
6338 if (const auto *Entry = CostTableLookup(AVX2BoolReduction, ISD, MTy))
6339 if (auto KindCost = Entry->Cost[CostKind])
6340 return ArithmeticCost + *KindCost;
6341 if (ST->hasAVX())
6342 if (const auto *Entry = CostTableLookup(AVX1BoolReduction, ISD, MTy))
6343 if (auto KindCost = Entry->Cost[CostKind])
6344 return ArithmeticCost + *KindCost;
6345 if (ST->hasSSE2())
6346 if (const auto *Entry = CostTableLookup(SSE2BoolReduction, ISD, MTy))
6347 if (auto KindCost = Entry->Cost[CostKind])
6348 return ArithmeticCost + *KindCost;
6349
6350 return BaseT::getArithmeticReductionCost(Opcode, ValVTy, FMF, CostKind);
6351 }
6352
6353 // Special case: vXi8 mul reductions are performed as vXi16.
6354 if (ISD == ISD::MUL && MTy.getScalarType() == MVT::i8) {
6355 auto *WideSclTy = IntegerType::get(ValVTy->getContext(), 16);
6356 auto *WideVecTy = FixedVectorType::get(WideSclTy, ValVTy->getNumElements());
6357 return getCastInstrCost(Instruction::ZExt, WideVecTy, ValTy,
6359 CostKind) +
6360 getArithmeticReductionCost(Opcode, WideVecTy, FMF, CostKind);
6361 }
6362
6363 if (ST->useSLMArithCosts())
6364 if (const auto *Entry = CostTableLookup(SLMCostTbl, ISD, MTy))
6365 if (auto KindCost = Entry->Cost[CostKind])
6366 return ArithmeticCost + *KindCost;
6367
6368 if (ST->hasBWI())
6369 if (const auto *Entry = CostTableLookup(AVX512BWCostTbl, ISD, MTy))
6370 if (auto KindCost = Entry->Cost[CostKind])
6371 return ArithmeticCost + *KindCost;
6372
6373 if (ST->hasAVX512())
6374 if (const auto *Entry = CostTableLookup(AVX512FCostTbl, ISD, MTy))
6375 if (auto KindCost = Entry->Cost[CostKind])
6376 return ArithmeticCost + *KindCost;
6377
6378 if (ST->hasAVX2())
6379 if (const auto *Entry = CostTableLookup(AVX2CostTbl, ISD, MTy))
6380 if (auto KindCost = Entry->Cost[CostKind])
6381 return ArithmeticCost + *KindCost;
6382
6383 if (ST->hasAVX())
6384 if (const auto *Entry = CostTableLookup(AVX1CostTbl, ISD, MTy))
6385 if (auto KindCost = Entry->Cost[CostKind])
6386 return ArithmeticCost + *KindCost;
6387
6388 if (ST->hasSSE2())
6389 if (const auto *Entry = CostTableLookup(SSE2CostTbl, ISD, MTy))
6390 if (auto KindCost = Entry->Cost[CostKind])
6391 return ArithmeticCost + *KindCost;
6392
6393 unsigned NumVecElts = ValVTy->getNumElements();
6394 unsigned ScalarSize = ValVTy->getScalarSizeInBits();
6395
6396 // Special case power of 2 reductions where the scalar type isn't changed
6397 // by type legalization.
6398 if (!isPowerOf2_32(NumVecElts) || ScalarSize != MTy.getScalarSizeInBits())
6399 return BaseT::getArithmeticReductionCost(Opcode, ValVTy, FMF, CostKind);
6400
6401 InstructionCost ReductionCost = 0;
6402
6403 auto *Ty = ValVTy;
6404 if (LT.first != 1 && MTy.isVector() &&
6405 MTy.getVectorNumElements() < ValVTy->getNumElements()) {
6406 // Type needs to be split. We need LT.first - 1 arithmetic ops.
6407 Ty = FixedVectorType::get(ValVTy->getElementType(),
6408 MTy.getVectorNumElements());
6409 ReductionCost = getArithmeticInstrCost(Opcode, Ty, CostKind);
6410 ReductionCost *= LT.first - 1;
6411 NumVecElts = MTy.getVectorNumElements();
6412 }
6413
6414 // Now handle reduction with the legal type, taking into account size changes
6415 // at each level.
6416 while (NumVecElts > 1) {
6417 // Determine the size of the remaining vector we need to reduce.
6418 unsigned Size = NumVecElts * ScalarSize;
6419 NumVecElts /= 2;
6420 // If we're reducing from 256/512 bits, use an extract_subvector.
6421 if (Size > 128) {
6422 auto *SubTy = FixedVectorType::get(ValVTy->getElementType(), NumVecElts);
6423 ReductionCost += getShuffleCost(TTI::SK_ExtractSubvector, Ty, Ty,
6424 CostKind, {}, NumVecElts, SubTy);
6425 Ty = SubTy;
6426 } else if (Size == 128) {
6427 // Reducing from 128 bits is a permute of v2f64/v2i64.
6428 FixedVectorType *ShufTy;
6429 if (ValVTy->isFloatingPointTy())
6430 ShufTy =
6431 FixedVectorType::get(Type::getDoubleTy(ValVTy->getContext()), 2);
6432 else
6433 ShufTy =
6434 FixedVectorType::get(Type::getInt64Ty(ValVTy->getContext()), 2);
6435 ReductionCost += getShuffleCost(TTI::SK_PermuteSingleSrc, ShufTy, ShufTy,
6436 CostKind, {}, 0, nullptr);
6437 } else if (Size == 64) {
6438 // Reducing from 64 bits is a shuffle of v4f32/v4i32.
6439 FixedVectorType *ShufTy;
6440 if (ValVTy->isFloatingPointTy())
6441 ShufTy =
6442 FixedVectorType::get(Type::getFloatTy(ValVTy->getContext()), 4);
6443 else
6444 ShufTy =
6445 FixedVectorType::get(Type::getInt32Ty(ValVTy->getContext()), 4);
6446 ReductionCost += getShuffleCost(TTI::SK_PermuteSingleSrc, ShufTy, ShufTy,
6447 CostKind, {}, 0, nullptr);
6448 } else {
6449 // Reducing from smaller size is a shift by immediate.
6450 auto *ShiftTy = FixedVectorType::get(
6451 Type::getIntNTy(ValVTy->getContext(), Size), 128 / Size);
6452 ReductionCost += getArithmeticInstrCost(
6453 Instruction::LShr, ShiftTy, CostKind,
6456 }
6457
6458 // Add the arithmetic op for this level.
6459 ReductionCost += getArithmeticInstrCost(Opcode, Ty, CostKind);
6460 }
6461
6462 // Add the final extract element to the cost.
6463 return ReductionCost + getVectorInstrCost(Instruction::ExtractElement, Ty,
6464 CostKind, 0, nullptr, nullptr,
6466}
6467
6470 FastMathFlags FMF) const {
6471 IntrinsicCostAttributes ICA(IID, Ty, {Ty, Ty}, FMF);
6472 return getIntrinsicInstrCost(ICA, CostKind);
6473}
6474
6477 FastMathFlags FMF,
6479 std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(ValTy);
6480
6481 MVT MTy = LT.second;
6482
6484 if (ValTy->isIntOrIntVectorTy()) {
6485 ISD = (IID == Intrinsic::umin || IID == Intrinsic::umax) ? ISD::UMIN
6486 : ISD::SMIN;
6487 } else {
6488 assert(ValTy->isFPOrFPVectorTy() &&
6489 "Expected float point or integer vector type.");
6490 ISD = (IID == Intrinsic::minnum || IID == Intrinsic::maxnum)
6491 ? ISD::FMINNUM
6492 : ISD::FMINIMUM;
6493 }
6494
6495 // We use llvm-mca across all supported CPUs to measure the cost stats.
6496 static const CostKindTblEntry SSE2CostTbl[] = {
6497 {ISD::SMIN, MVT::v2i64, {3, 4, 5, 6}},
6498 {ISD::UMIN, MVT::v2i64, {3, 4, 5, 6}},
6499 {ISD::SMIN, MVT::v2i32, {2, 2, 5, 6}},
6500 {ISD::UMIN, MVT::v2i32, {2, 2, 5, 6}},
6501 {ISD::SMIN, MVT::v4i32, {3, 7,11,12}},
6502 {ISD::UMIN, MVT::v4i32, {4, 7,14,15}},
6503 {ISD::SMIN, MVT::v2i16, {2, 3, 4, 4}},
6504 {ISD::UMIN, MVT::v2i16, {2, 3, 4, 6}},
6505 {ISD::SMIN, MVT::v4i16, {3, 5, 6, 6}},
6506 {ISD::UMIN, MVT::v4i16, {3, 5, 8, 10}},
6507 {ISD::SMIN, MVT::v8i16, {3, 8, 8, 8}},
6508 {ISD::UMIN, MVT::v8i16, {4, 8,12,14}},
6509 {ISD::SMIN, MVT::v2i8, {2, 3, 5, 6}},
6510 {ISD::UMIN, MVT::v2i8, {2, 3, 4, 4}},
6511 {ISD::SMIN, MVT::v4i8, {4, 6,12,13}},
6512 {ISD::UMIN, MVT::v4i8, {3, 6, 7, 7}},
6513 {ISD::SMIN, MVT::v8i8, {5, 9,18,19}},
6514 {ISD::UMIN, MVT::v8i8, {4, 8, 9, 9}},
6515 {ISD::SMIN, MVT::v16i8, {7,13,24,25}},
6516 {ISD::UMIN, MVT::v16i8, {3,10,11,11}},
6517 };
6518
6519 static const CostKindTblEntry SSE41CostTbl[] = {
6520 {ISD::SMIN, MVT::v2i64, {3, 4, 4, 6}},
6521 {ISD::UMIN, MVT::v2i64, {3, 4, 4, 6}},
6522 {ISD::SMIN, MVT::v2i32, {2, 2, 3, 3}},
6523 {ISD::UMIN, MVT::v2i32, {2, 2, 3, 3}},
6524 {ISD::SMIN, MVT::v4i32, {3, 4, 5, 5}},
6525 {ISD::UMIN, MVT::v4i32, {3, 4, 5, 5}},
6526 {ISD::UMIN, MVT::v2i16, {2, 3, 4, 4}},
6527 {ISD::SMIN, MVT::v4i16, {3, 5, 6, 6}},
6528 {ISD::UMIN, MVT::v4i16, {3, 5, 6, 6}},
6529 {ISD::SMIN, MVT::v8i16, {2, 8, 4, 5}},
6530 {ISD::UMIN, MVT::v8i16, {2, 5, 2, 2}},
6531 {ISD::SMIN, MVT::v2i8, {2, 3, 4, 4}},
6532 {ISD::SMIN, MVT::v4i8, {3, 6, 7, 7}},
6533 {ISD::SMIN, MVT::v8i8, {4, 8, 9, 9}},
6534 {ISD::SMIN, MVT::v16i8, {3,10, 7, 8}},
6535 {ISD::UMIN, MVT::v16i8, {3, 8, 5, 5}},
6536 };
6537
6538 static const CostKindTblEntry AVX1CostTbl[] = {
6539 {ISD::SMIN, MVT::v4i64, {5,11, 7,10}},
6540 {ISD::UMIN, MVT::v4i64, {6,12,10,13}},
6541 {ISD::SMIN, MVT::v8i32, {4, 9, 7, 7}},
6542 {ISD::UMIN, MVT::v8i32, {4, 9, 7, 7}},
6543 {ISD::SMIN, MVT::v16i16, {3,15, 6, 7}},
6544 {ISD::UMIN, MVT::v16i16, {2, 9, 4, 4}},
6545 {ISD::SMIN, MVT::v32i8, {4,17, 8, 9}},
6546 {ISD::UMIN, MVT::v32i8, {3,11, 6, 6}},
6547 };
6548
6549 static const CostKindTblEntry AVX2CostTbl[] = {
6550 {ISD::SMIN, MVT::v4i64, {4,11, 7,10}},
6551 {ISD::UMIN, MVT::v4i64, {4,12,10,13}},
6552 {ISD::SMIN, MVT::v2i32, {1, 2, 3, 3}},
6553 {ISD::UMIN, MVT::v2i32, {1, 2, 3, 3}},
6554 {ISD::UMIN, MVT::v4i32, {2, 4, 5, 5}},
6555 {ISD::SMIN, MVT::v4i32, {2, 4, 5, 5}},
6556 {ISD::SMIN, MVT::v8i32, {3, 9, 7, 7}},
6557 {ISD::UMIN, MVT::v8i32, {3, 9, 7, 7}},
6558 {ISD::SMIN, MVT::v4i16, {2, 4, 5, 5}},
6559 {ISD::UMIN, MVT::v4i16, {2, 4, 5, 5}},
6560 {ISD::SMIN, MVT::v16i16, {2,15, 6, 7}},
6561 {ISD::SMIN, MVT::v8i8, {3, 6, 7, 7}},
6562 {ISD::UMIN, MVT::v8i8, {3, 6, 7, 7}},
6563 {ISD::SMIN, MVT::v32i8, {3,17, 8, 9}},
6564 };
6565
6566 static const CostKindTblEntry AVX512FCostTbl[] = {
6567 {ISD::SMIN, MVT::v2i64, {2, 4, 3, 3}},
6568 {ISD::UMIN, MVT::v2i64, {2, 4, 3, 3}},
6569 {ISD::SMIN, MVT::v4i64, {3,10, 5, 5}},
6570 {ISD::UMIN, MVT::v4i64, {3,10, 5, 5}},
6571 {ISD::SMIN, MVT::v8i64, {5,16, 7, 7}},
6572 {ISD::UMIN, MVT::v8i64, {5,16, 7, 7}},
6573 {ISD::SMIN, MVT::v16i32, {4,12, 9, 9}},
6574 {ISD::UMIN, MVT::v16i32, {4,12, 9, 9}},
6575 };
6576
6577 static const CostKindTblEntry AVX512BWCostTbl[] = {
6578 {ISD::SMIN, MVT::v2i16, {1, 2, 3, 3}},
6579 {ISD::UMIN, MVT::v2i16, {1, 2, 3, 3}},
6580 {ISD::SMIN, MVT::v32i16, {2,19, 8, 9}},
6581 {ISD::UMIN, MVT::v32i16, {2,12, 6, 6}},
6582 {ISD::SMIN, MVT::v2i8, {1, 2, 3, 3}},
6583 {ISD::UMIN, MVT::v2i8, {1, 2, 3, 3}},
6584 {ISD::SMIN, MVT::v4i8, {2, 4, 5, 5}},
6585 {ISD::UMIN, MVT::v4i8, {2, 4, 5, 5}},
6586 {ISD::SMIN, MVT::v16i8, {2,10, 6, 7}},
6587 {ISD::UMIN, MVT::v16i8, {2, 6, 4, 4}},
6588 {ISD::SMIN, MVT::v32i8, {2,17, 8, 9}},
6589 {ISD::UMIN, MVT::v32i8, {2,10, 6, 6}},
6590 {ISD::SMIN, MVT::v64i8, {2,21,10,11}},
6591 {ISD::UMIN, MVT::v64i8, {2,14, 8, 8}},
6592 };
6593
6594 // Before legalizing the type, give a chance to look up illegal narrow types
6595 // in the table.
6596 // FIXME: Is there a better way to do this?
6597 EVT VT = TLI->getValueType(DL, ValTy);
6598 if (VT.isSimple()) {
6599 MVT MTy = VT.getSimpleVT();
6600 if (ST->hasBWI())
6601 if (const auto *Entry = CostTableLookup(AVX512BWCostTbl, ISD, MTy))
6602 if (auto KindCost = Entry->Cost[CostKind])
6603 return *KindCost;
6604
6605 if (ST->hasAVX512())
6606 if (const auto *Entry = CostTableLookup(AVX512FCostTbl, ISD, MTy))
6607 if (auto KindCost = Entry->Cost[CostKind])
6608 return *KindCost;
6609
6610 if (ST->hasAVX2())
6611 if (const auto *Entry = CostTableLookup(AVX2CostTbl, ISD, MTy))
6612 if (auto KindCost = Entry->Cost[CostKind])
6613 return *KindCost;
6614
6615 if (ST->hasAVX())
6616 if (const auto *Entry = CostTableLookup(AVX1CostTbl, ISD, MTy))
6617 if (auto KindCost = Entry->Cost[CostKind])
6618 return *KindCost;
6619
6620 if (ST->hasSSE41())
6621 if (const auto *Entry = CostTableLookup(SSE41CostTbl, ISD, MTy))
6622 if (auto KindCost = Entry->Cost[CostKind])
6623 return *KindCost;
6624
6625 if (ST->hasSSE2())
6626 if (const auto *Entry = CostTableLookup(SSE2CostTbl, ISD, MTy))
6627 if (auto KindCost = Entry->Cost[CostKind])
6628 return *KindCost;
6629 }
6630
6631 auto *ValVTy = cast<FixedVectorType>(ValTy);
6632 unsigned NumVecElts = ValVTy->getNumElements();
6633
6634 auto *Ty = ValVTy;
6635 InstructionCost MinMaxCost = 0;
6636 if (LT.first != 1 && MTy.isVector() &&
6637 MTy.getVectorNumElements() < ValVTy->getNumElements()) {
6638 // Type needs to be split. We need LT.first - 1 operations ops.
6639 Ty = FixedVectorType::get(ValVTy->getElementType(),
6640 MTy.getVectorNumElements());
6641 MinMaxCost = getMinMaxCost(IID, Ty, CostKind, FMF);
6642 MinMaxCost *= LT.first - 1;
6643 NumVecElts = MTy.getVectorNumElements();
6644 }
6645
6646 if (ST->hasBWI())
6647 if (const auto *Entry = CostTableLookup(AVX512BWCostTbl, ISD, MTy))
6648 if (auto KindCost = Entry->Cost[CostKind])
6649 return MinMaxCost + *KindCost;
6650
6651 if (ST->hasAVX512())
6652 if (const auto *Entry = CostTableLookup(AVX512FCostTbl, ISD, MTy))
6653 if (auto KindCost = Entry->Cost[CostKind])
6654 return MinMaxCost + *KindCost;
6655
6656 if (ST->hasAVX2())
6657 if (const auto *Entry = CostTableLookup(AVX2CostTbl, ISD, MTy))
6658 if (auto KindCost = Entry->Cost[CostKind])
6659 return MinMaxCost + *KindCost;
6660
6661 if (ST->hasAVX())
6662 if (const auto *Entry = CostTableLookup(AVX1CostTbl, ISD, MTy))
6663 if (auto KindCost = Entry->Cost[CostKind])
6664 return MinMaxCost + *KindCost;
6665
6666 if (ST->hasSSE41())
6667 if (const auto *Entry = CostTableLookup(SSE41CostTbl, ISD, MTy))
6668 if (auto KindCost = Entry->Cost[CostKind])
6669 return MinMaxCost + *KindCost;
6670
6671 if (ST->hasSSE2())
6672 if (const auto *Entry = CostTableLookup(SSE2CostTbl, ISD, MTy))
6673 if (auto KindCost = Entry->Cost[CostKind])
6674 return MinMaxCost + *KindCost;
6675
6676 unsigned ScalarSize = ValTy->getScalarSizeInBits();
6677
6678 // Special case power of 2 reductions where the scalar type isn't changed
6679 // by type legalization.
6680 if (!isPowerOf2_32(ValVTy->getNumElements()) ||
6681 ScalarSize != MTy.getScalarSizeInBits())
6682 return BaseT::getMinMaxReductionCost(IID, ValTy, FMF, CostKind);
6683
6684 // Now handle reduction with the legal type, taking into account size changes
6685 // at each level.
6686 while (NumVecElts > 1) {
6687 // Determine the size of the remaining vector we need to reduce.
6688 unsigned Size = NumVecElts * ScalarSize;
6689 NumVecElts /= 2;
6690 // If we're reducing from 256/512 bits, use an extract_subvector.
6691 if (Size > 128) {
6692 auto *SubTy = FixedVectorType::get(ValVTy->getElementType(), NumVecElts);
6693 MinMaxCost += getShuffleCost(TTI::SK_ExtractSubvector, Ty, Ty, CostKind,
6694 {}, NumVecElts, SubTy);
6695 Ty = SubTy;
6696 } else if (Size == 128) {
6697 // Reducing from 128 bits is a permute of v2f64/v2i64.
6698 VectorType *ShufTy;
6699 if (ValTy->isFloatingPointTy())
6700 ShufTy =
6702 else
6703 ShufTy = FixedVectorType::get(Type::getInt64Ty(ValTy->getContext()), 2);
6704 MinMaxCost += getShuffleCost(TTI::SK_PermuteSingleSrc, ShufTy, ShufTy,
6705 CostKind, {}, 0, nullptr);
6706 } else if (Size == 64) {
6707 // Reducing from 64 bits is a shuffle of v4f32/v4i32.
6708 FixedVectorType *ShufTy;
6709 if (ValTy->isFloatingPointTy())
6710 ShufTy = FixedVectorType::get(Type::getFloatTy(ValTy->getContext()), 4);
6711 else
6712 ShufTy = FixedVectorType::get(Type::getInt32Ty(ValTy->getContext()), 4);
6713 MinMaxCost += getShuffleCost(TTI::SK_PermuteSingleSrc, ShufTy, ShufTy,
6714 CostKind, {}, 0, nullptr);
6715 } else {
6716 // Reducing from smaller size is a shift by immediate.
6717 auto *ShiftTy = FixedVectorType::get(
6718 Type::getIntNTy(ValTy->getContext(), Size), 128 / Size);
6719 MinMaxCost += getArithmeticInstrCost(
6720 Instruction::LShr, ShiftTy, TTI::TCK_RecipThroughput,
6723 }
6724
6725 // Add the arithmetic op for this level.
6726 MinMaxCost += getMinMaxCost(IID, Ty, CostKind, FMF);
6727 }
6728
6729 // Add the final extract element to the cost.
6730 return MinMaxCost + getVectorInstrCost(Instruction::ExtractElement, Ty,
6731 CostKind, 0, nullptr, nullptr,
6733}
6734
6735/// Calculate the cost of materializing a 64-bit value. This helper
6736/// method might only calculate a fraction of a larger immediate. Therefore it
6737/// is valid to return a cost of ZERO.
6739 if (Val == 0)
6740 return TTI::TCC_Free;
6741
6742 if (isInt<32>(Val))
6743 return TTI::TCC_Basic;
6744
6745 return 2 * TTI::TCC_Basic;
6746}
6747
6750 assert(Ty->isIntegerTy());
6751
6752 unsigned BitSize = Ty->getPrimitiveSizeInBits();
6753 if (BitSize == 0)
6754 return ~0U;
6755
6756 // Never hoist constants larger than 128bit, because this might lead to
6757 // incorrect code generation or assertions in codegen.
6758 // Fixme: Create a cost model for types larger than i128 once the codegen
6759 // issues have been fixed.
6760 if (BitSize > 128)
6761 return TTI::TCC_Free;
6762
6763 if (Imm == 0)
6764 return TTI::TCC_Free;
6765
6766 // Sign-extend all constants to a multiple of 64-bit.
6767 APInt ImmVal = Imm;
6768 if (BitSize % 64 != 0)
6769 ImmVal = Imm.sext(alignTo(BitSize, 64));
6770
6771 // Split the constant into 64-bit chunks and calculate the cost for each
6772 // chunk.
6774 for (unsigned ShiftVal = 0; ShiftVal < BitSize; ShiftVal += 64) {
6775 APInt Tmp = ImmVal.ashr(ShiftVal).sextOrTrunc(64);
6776 int64_t Val = Tmp.getSExtValue();
6777 Cost += getIntImmCost(Val);
6778 }
6779 // We need at least one instruction to materialize the constant.
6780 return std::max<InstructionCost>(1, Cost);
6781}
6782
6784 const APInt &Imm, Type *Ty,
6786 Instruction *Inst) const {
6787 assert(Ty->isIntegerTy());
6788
6789 unsigned BitSize = Ty->getPrimitiveSizeInBits();
6790 unsigned ImmBitWidth = Imm.getBitWidth();
6791
6792 // There is no cost model for constants with a bit size of 0. Return TCC_Free
6793 // here, so that constant hoisting will ignore this constant.
6794 if (BitSize == 0)
6795 return TTI::TCC_Free;
6796
6797 unsigned ImmIdx = ~0U;
6798 switch (Opcode) {
6799 default:
6800 return TTI::TCC_Free;
6801 case Instruction::GetElementPtr:
6802 // Always hoist the base address of a GetElementPtr. This prevents the
6803 // creation of new constants for every base constant that gets constant
6804 // folded with the offset.
6805 if (Idx == 0)
6806 return 2 * TTI::TCC_Basic;
6807 return TTI::TCC_Free;
6808 case Instruction::Store:
6809 ImmIdx = 0;
6810 break;
6811 case Instruction::ICmp:
6812 // This is an imperfect hack to prevent constant hoisting of
6813 // compares that might be trying to check if a 64-bit value fits in
6814 // 32-bits. The backend can optimize these cases using a right shift by 32.
6815 // There are other predicates and immediates the backend can use shifts for.
6816 if (Idx == 1 && ImmBitWidth == 64) {
6817 uint64_t ImmVal = Imm.getZExtValue();
6818 if (ImmVal == 0x100000000ULL || ImmVal == 0xffffffff)
6819 return TTI::TCC_Free;
6820
6821 if (auto *Cmp = dyn_cast_or_null<CmpInst>(Inst)) {
6822 if (Cmp->isEquality()) {
6823 KnownBits Known = computeKnownBits(Cmp->getOperand(0), DL);
6824 if (Known.countMinTrailingZeros() >= 32)
6825 return TTI::TCC_Free;
6826 }
6827 }
6828 }
6829 ImmIdx = 1;
6830 break;
6831 case Instruction::And:
6832 // We support 64-bit ANDs with immediates with 32-bits of leading zeroes
6833 // by using a 32-bit operation with implicit zero extension. Detect such
6834 // immediates here as the normal path expects bit 31 to be sign extended.
6835 if (Idx == 1 && ImmBitWidth == 64 && Imm.isIntN(32))
6836 return TTI::TCC_Free;
6837 // If we have BMI then we can use BEXTR/BZHI to mask out upper i64 bits.
6838 if (Idx == 1 && ImmBitWidth == 64 && ST->is64Bit() && ST->hasBMI() &&
6839 Imm.isMask())
6840 return X86TTIImpl::getIntImmCost(ST->hasBMI2() ? 255 : 65535);
6841 ImmIdx = 1;
6842 break;
6843 case Instruction::Add:
6844 case Instruction::Sub:
6845 // For add/sub, we can use the opposite instruction for INT32_MIN.
6846 if (Idx == 1 && ImmBitWidth == 64 && Imm.getZExtValue() == 0x80000000)
6847 return TTI::TCC_Free;
6848 ImmIdx = 1;
6849 break;
6850 case Instruction::UDiv:
6851 case Instruction::SDiv:
6852 case Instruction::URem:
6853 case Instruction::SRem:
6854 // Division by constant is typically expanded later into a different
6855 // instruction sequence. This completely changes the constants.
6856 // Report them as "free" to stop ConstantHoist from marking them as opaque.
6857 return TTI::TCC_Free;
6858 case Instruction::Mul:
6859 case Instruction::Or:
6860 case Instruction::Xor:
6861 ImmIdx = 1;
6862 break;
6863 // Always return TCC_Free for the shift value of a shift instruction.
6864 case Instruction::Shl:
6865 case Instruction::LShr:
6866 case Instruction::AShr:
6867 if (Idx == 1)
6868 return TTI::TCC_Free;
6869 break;
6870 case Instruction::Trunc:
6871 case Instruction::ZExt:
6872 case Instruction::SExt:
6873 case Instruction::IntToPtr:
6874 case Instruction::PtrToInt:
6875 case Instruction::BitCast:
6876 case Instruction::PHI:
6877 case Instruction::Call:
6878 case Instruction::Select:
6879 case Instruction::Ret:
6880 case Instruction::Load:
6881 break;
6882 }
6883
6884 if (Idx == ImmIdx) {
6885 uint64_t NumConstants = divideCeil(BitSize, 64);
6887 return (Cost <= NumConstants * TTI::TCC_Basic)
6888 ? static_cast<int>(TTI::TCC_Free)
6889 : Cost;
6890 }
6891
6893}
6894
6897 const APInt &Imm, Type *Ty,
6899 assert(Ty->isIntegerTy());
6900
6901 unsigned BitSize = Ty->getPrimitiveSizeInBits();
6902 // There is no cost model for constants with a bit size of 0. Return TCC_Free
6903 // here, so that constant hoisting will ignore this constant.
6904 if (BitSize == 0)
6905 return TTI::TCC_Free;
6906
6907 switch (IID) {
6908 default:
6909 return TTI::TCC_Free;
6910 case Intrinsic::sadd_with_overflow:
6911 case Intrinsic::uadd_with_overflow:
6912 case Intrinsic::ssub_with_overflow:
6913 case Intrinsic::usub_with_overflow:
6914 case Intrinsic::smul_with_overflow:
6915 case Intrinsic::umul_with_overflow:
6916 if ((Idx == 1) && Imm.getBitWidth() <= 64 && Imm.isSignedIntN(32))
6917 return TTI::TCC_Free;
6918 break;
6919 case Intrinsic::experimental_stackmap:
6920 if ((Idx < 2) || (Imm.getBitWidth() <= 64 && Imm.isSignedIntN(64)))
6921 return TTI::TCC_Free;
6922 break;
6923 case Intrinsic::experimental_patchpoint_void:
6924 case Intrinsic::experimental_patchpoint:
6925 if ((Idx < 4) || (Imm.getBitWidth() <= 64 && Imm.isSignedIntN(64)))
6926 return TTI::TCC_Free;
6927 break;
6928 }
6930}
6931
6934 const Instruction *I) const {
6936 return Opcode == Instruction::PHI ? TTI::TCC_Free : TTI::TCC_Basic;
6937 // Branches are assumed to be predicted.
6938 return TTI::TCC_Free;
6939}
6940
6941int X86TTIImpl::getGatherOverhead() const {
6942 // Some CPUs have more overhead for gather. The specified overhead is relative
6943 // to the Load operation. "2" is the number provided by Intel architects. This
6944 // parameter is used for cost estimation of Gather Op and comparison with
6945 // other alternatives.
6946 // TODO: Remove the explicit hasAVX512()?, That would mean we would only
6947 // enable gather with a -march.
6948 if (ST->hasAVX512() || (ST->hasAVX2() && ST->hasFastGather()))
6949 return 2;
6950
6951 return 1024;
6952}
6953
6954int X86TTIImpl::getScatterOverhead() const {
6955 if (ST->hasAVX512())
6956 return 2;
6957
6958 return 1024;
6959}
6960
6961// Return an average cost of Gather / Scatter instruction, maybe improved later.
6962InstructionCost X86TTIImpl::getGSVectorCost(unsigned Opcode,
6964 Type *SrcVTy, const Value *Ptr,
6965 Align Alignment,
6966 unsigned AddressSpace) const {
6967
6968 assert(isa<VectorType>(SrcVTy) && "Unexpected type in getGSVectorCost");
6969 unsigned VF = cast<FixedVectorType>(SrcVTy)->getNumElements();
6970
6971 // Try to reduce index size from 64 bit (default for GEP)
6972 // to 32. It is essential for VF 16. If the index can't be reduced to 32, the
6973 // operation will use 16 x 64 indices which do not fit in a zmm and needs
6974 // to split. Also check that the base pointer is the same for all lanes,
6975 // and that there's at most one variable index.
6976 auto getIndexSizeInBits = [](const Value *Ptr, const DataLayout &DL) {
6977 unsigned IndexSize = DL.getPointerSizeInBits();
6978 const GetElementPtrInst *GEP = dyn_cast_or_null<GetElementPtrInst>(Ptr);
6979 if (IndexSize < 64 || !GEP)
6980 return IndexSize;
6981
6982 unsigned NumOfVarIndices = 0;
6983 const Value *Ptrs = GEP->getPointerOperand();
6984 if (Ptrs->getType()->isVectorTy() && !getSplatValue(Ptrs))
6985 return IndexSize;
6986 for (unsigned I = 1, E = GEP->getNumOperands(); I != E; ++I) {
6987 if (isa<Constant>(GEP->getOperand(I)))
6988 continue;
6989 Type *IndxTy = GEP->getOperand(I)->getType();
6990 if (auto *IndexVTy = dyn_cast<VectorType>(IndxTy))
6991 IndxTy = IndexVTy->getElementType();
6992 if ((IndxTy->getPrimitiveSizeInBits() == 64 &&
6993 !isa<SExtInst>(GEP->getOperand(I))) ||
6994 ++NumOfVarIndices > 1)
6995 return IndexSize; // 64
6996 }
6997 return (unsigned)32;
6998 };
6999
7000 // Trying to reduce IndexSize to 32 bits for vector 16.
7001 // By default the IndexSize is equal to pointer size.
7002 unsigned IndexSize = (ST->hasAVX512() && VF >= 16)
7003 ? getIndexSizeInBits(Ptr, DL)
7004 : DL.getPointerSizeInBits();
7005
7006 auto *IndexVTy = FixedVectorType::get(
7007 IntegerType::get(SrcVTy->getContext(), IndexSize), VF);
7008 std::pair<InstructionCost, MVT> IdxsLT = getTypeLegalizationCost(IndexVTy);
7009 std::pair<InstructionCost, MVT> SrcLT = getTypeLegalizationCost(SrcVTy);
7010 InstructionCost::CostType SplitFactor =
7011 std::max(IdxsLT.first, SrcLT.first).getValue();
7012 if (SplitFactor > 1) {
7013 // Handle splitting of vector of pointers
7014 auto *SplitSrcTy =
7015 FixedVectorType::get(SrcVTy->getScalarType(), VF / SplitFactor);
7016 return SplitFactor * getGSVectorCost(Opcode, CostKind, SplitSrcTy, Ptr,
7017 Alignment, AddressSpace);
7018 }
7019
7020 // If we didn't split, this will be a single gather/scatter instruction.
7022 return 1;
7023
7024 // The gather / scatter cost is given by Intel architects. It is a rough
7025 // number since we are looking at one instruction in a time.
7026 const int GSOverhead = (Opcode == Instruction::Load) ? getGatherOverhead()
7027 : getScatterOverhead();
7028 return GSOverhead + VF * getMemoryOpCost(Opcode, SrcVTy->getScalarType(),
7029 Alignment, AddressSpace, CostKind);
7030}
7031
7032/// Calculate the cost of Gather / Scatter operation
7036 bool IsLoad = MICA.getID() == Intrinsic::masked_gather ||
7037 MICA.getID() == Intrinsic::vp_gather;
7038 unsigned Opcode = IsLoad ? Instruction::Load : Instruction::Store;
7039 Type *SrcVTy = MICA.getDataType();
7040 const Value *Ptr = MICA.getPointer();
7041 Align Alignment = MICA.getAlignment();
7042 if ((Opcode == Instruction::Load &&
7043 (!isLegalMaskedGather(SrcVTy, Align(Alignment)) ||
7045 Align(Alignment)))) ||
7046 (Opcode == Instruction::Store &&
7047 (!isLegalMaskedScatter(SrcVTy, Align(Alignment)) ||
7049 Align(Alignment)))))
7051
7052 assert(SrcVTy->isVectorTy() && "Unexpected data type for Gather/Scatter");
7053 unsigned AddressSpace = MICA.getAddressSpace();
7054 return getGSVectorCost(Opcode, CostKind, SrcVTy, Ptr, Alignment,
7055 AddressSpace);
7056}
7057
7059 const TargetTransformInfo::LSRCost &C2) const {
7060 // X86 specific here are "instruction number 1st priority".
7061 return std::tie(C1.Insns, C1.NumRegs, C1.AddRecCost, C1.NumIVMuls,
7062 C1.NumBaseAdds, C1.ScaleCost, C1.ImmCost, C1.SetupCost) <
7063 std::tie(C2.Insns, C2.NumRegs, C2.AddRecCost, C2.NumIVMuls,
7064 C2.NumBaseAdds, C2.ScaleCost, C2.ImmCost, C2.SetupCost);
7065}
7066
7068 return ST->hasMacroFusion() || ST->hasBranchFusion();
7069}
7070
7071static bool isLegalMaskedLoadStore(Type *ScalarTy, const X86Subtarget *ST) {
7072 if (!ST->hasAVX())
7073 return false;
7074
7075 if (ScalarTy->isPointerTy())
7076 return true;
7077
7078 if (ScalarTy->isFloatTy() || ScalarTy->isDoubleTy())
7079 return true;
7080
7081 if (ScalarTy->isHalfTy() && ST->hasBWI())
7082 return true;
7083
7084 if (ScalarTy->isBFloatTy() && ST->hasBF16())
7085 return true;
7086
7087 if (!ScalarTy->isIntegerTy())
7088 return false;
7089
7090 unsigned IntWidth = ScalarTy->getIntegerBitWidth();
7091 return IntWidth == 32 || IntWidth == 64 ||
7092 ((IntWidth == 8 || IntWidth == 16) && ST->hasBWI());
7093}
7094
7096 unsigned AddressSpace,
7097 TTI::MaskKind MaskKind) const {
7098 Type *ScalarTy = DataTy->getScalarType();
7099
7100 // The backend can't handle a single element vector w/o CFCMOV.
7101 if (isa<VectorType>(DataTy) &&
7102 cast<FixedVectorType>(DataTy)->getNumElements() == 1)
7103 return ST->hasCF() &&
7104 hasConditionalLoadStoreForType(ScalarTy, /*IsStore=*/false);
7105
7106 return isLegalMaskedLoadStore(ScalarTy, ST);
7107}
7108
7110 unsigned AddressSpace,
7111 TTI::MaskKind MaskKind) const {
7112 Type *ScalarTy = DataTy->getScalarType();
7113
7114 // The backend can't handle a single element vector w/o CFCMOV.
7115 if (isa<VectorType>(DataTy) &&
7116 cast<FixedVectorType>(DataTy)->getNumElements() == 1)
7117 return ST->hasCF() &&
7118 hasConditionalLoadStoreForType(ScalarTy, /*IsStore=*/true);
7119
7120 return isLegalMaskedLoadStore(ScalarTy, ST);
7121}
7122
7123bool X86TTIImpl::isLegalNTLoad(Type *DataType, Align Alignment) const {
7124 unsigned DataSize = DL.getTypeStoreSize(DataType);
7125 // The only supported nontemporal loads are for aligned vectors of 16 or 32
7126 // bytes. Note that 32-byte nontemporal vector loads are supported by AVX2
7127 // (the equivalent stores only require AVX).
7128 if (Alignment >= DataSize && (DataSize == 16 || DataSize == 32))
7129 return DataSize == 16 ? ST->hasSSE1() : ST->hasAVX2();
7130
7131 return false;
7132}
7133
7134bool X86TTIImpl::isLegalNTStore(Type *DataType, Align Alignment) const {
7135 unsigned DataSize = DL.getTypeStoreSize(DataType);
7136
7137 // SSE4A supports nontemporal stores of float and double at arbitrary
7138 // alignment.
7139 if (ST->hasSSE4A() && (DataType->isFloatTy() || DataType->isDoubleTy()))
7140 return true;
7141
7142 // Besides the SSE4A subtarget exception above, only aligned stores are
7143 // available nontemporaly on any other subtarget. And only stores with a size
7144 // of 4..32 bytes (powers of 2, only) are permitted.
7145 if (Alignment < DataSize || DataSize < 4 || DataSize > 32 ||
7146 !isPowerOf2_32(DataSize))
7147 return false;
7148
7149 // 32-byte vector nontemporal stores are supported by AVX (the equivalent
7150 // loads require AVX2).
7151 if (DataSize == 32)
7152 return ST->hasAVX();
7153 if (DataSize == 16)
7154 return ST->hasSSE1();
7155 return true;
7156}
7157
7159 ElementCount NumElements) const {
7160 // movddup
7161 return ST->hasSSE3() && !NumElements.isScalable() &&
7162 NumElements.getFixedValue() == 2 &&
7163 ElementTy == Type::getDoubleTy(ElementTy->getContext());
7164}
7165
7166bool X86TTIImpl::isLegalMaskedExpandLoad(Type *DataTy, Align Alignment) const {
7167 if (!isa<VectorType>(DataTy))
7168 return false;
7169
7170 if (!ST->hasAVX512())
7171 return false;
7172
7173 // The backend can't handle a single element vector.
7174 if (cast<FixedVectorType>(DataTy)->getNumElements() == 1)
7175 return false;
7176
7177 Type *ScalarTy = cast<VectorType>(DataTy)->getElementType();
7178
7179 if (ScalarTy->isFloatTy() || ScalarTy->isDoubleTy())
7180 return true;
7181
7182 if (!ScalarTy->isIntegerTy())
7183 return false;
7184
7185 unsigned IntWidth = ScalarTy->getIntegerBitWidth();
7186 return IntWidth == 32 || IntWidth == 64 ||
7187 ((IntWidth == 8 || IntWidth == 16) && ST->hasVBMI2());
7188}
7189
7191 Align Alignment) const {
7192 return isLegalMaskedExpandLoad(DataTy, Alignment);
7193}
7194
7195bool X86TTIImpl::supportsGather() const {
7196 // Some CPUs have better gather performance than others.
7197 // TODO: Remove the explicit ST->hasAVX512()?, That would mean we would only
7198 // enable gather with a -march.
7199 return ST->hasAVX512() || (ST->hasFastGather() && ST->hasAVX2());
7200}
7201
7203 Align Alignment) const {
7204 // Gather / Scatter for vector 2 is not profitable on KNL / SKX
7205 // Vector-4 of gather/scatter instruction does not exist on KNL. We can extend
7206 // it to 8 elements, but zeroing upper bits of the mask vector will add more
7207 // instructions. Right now we give the scalar cost of vector-4 for KNL. TODO:
7208 // Check, maybe the gather/scatter instruction is better in the VariableMask
7209 // case.
7210 unsigned NumElts = cast<FixedVectorType>(VTy)->getNumElements();
7211 return NumElts == 1 ||
7212 (ST->hasAVX512() && (NumElts == 2 || (NumElts == 4 && !ST->hasVLX())));
7213}
7214
7216 Align Alignment) const {
7217 Type *ScalarTy = DataTy->getScalarType();
7218 if (ScalarTy->isPointerTy())
7219 return true;
7220
7221 if (ScalarTy->isFloatTy() || ScalarTy->isDoubleTy())
7222 return true;
7223
7224 if (!ScalarTy->isIntegerTy())
7225 return false;
7226
7227 unsigned IntWidth = ScalarTy->getIntegerBitWidth();
7228 return IntWidth == 32 || IntWidth == 64;
7229}
7230
7231bool X86TTIImpl::isLegalMaskedGather(Type *DataTy, Align Alignment) const {
7232 if (!supportsGather() || !ST->preferGather())
7233 return false;
7234 return isLegalMaskedGatherScatter(DataTy, Alignment);
7235}
7236
7237bool X86TTIImpl::isLegalAltInstr(VectorType *VecTy, unsigned Opcode0,
7238 unsigned Opcode1,
7239 const SmallBitVector &OpcodeMask) const {
7240 // ADDSUBPS 4xf32 SSE3
7241 // VADDSUBPS 4xf32 AVX
7242 // VADDSUBPS 8xf32 AVX2
7243 // ADDSUBPD 2xf64 SSE3
7244 // VADDSUBPD 2xf64 AVX
7245 // VADDSUBPD 4xf64 AVX2
7246
7247 unsigned NumElements = cast<FixedVectorType>(VecTy)->getNumElements();
7248 assert(OpcodeMask.size() == NumElements && "Mask and VecTy are incompatible");
7249 if (!isPowerOf2_32(NumElements))
7250 return false;
7251 // Check the opcode pattern. We apply the mask on the opcode arguments and
7252 // then check if it is what we expect.
7253 for (int Lane : seq<int>(0, NumElements)) {
7254 unsigned Opc = OpcodeMask.test(Lane) ? Opcode1 : Opcode0;
7255 // We expect FSub for even lanes and FAdd for odd lanes.
7256 if (Lane % 2 == 0 && Opc != Instruction::FSub)
7257 return false;
7258 if (Lane % 2 == 1 && Opc != Instruction::FAdd)
7259 return false;
7260 }
7261 // Now check that the pattern is supported by the target ISA.
7262 Type *ElemTy = cast<VectorType>(VecTy)->getElementType();
7263 if (ElemTy->isFloatTy())
7264 return ST->hasSSE3() && NumElements % 4 == 0;
7265 if (ElemTy->isDoubleTy())
7266 return ST->hasSSE3() && NumElements % 2 == 0;
7267 return false;
7268}
7269
7270bool X86TTIImpl::isLegalMaskedScatter(Type *DataType, Align Alignment) const {
7271 // AVX2 doesn't support scatter
7272 if (!ST->hasAVX512() || !ST->preferScatter())
7273 return false;
7274 return isLegalMaskedGatherScatter(DataType, Alignment);
7275}
7276
7277bool X86TTIImpl::hasDivRemOp(Type *DataType, bool IsSigned) const {
7278 EVT VT = TLI->getValueType(DL, DataType);
7279 return TLI->isOperationLegal(IsSigned ? ISD::SDIVREM : ISD::UDIVREM, VT);
7280}
7281
7283 // FDIV is always expensive, even if it has a very low uop count.
7284 // TODO: Still necessary for recent CPUs with low latency/throughput fdiv?
7285 if (I->getOpcode() == Instruction::FDiv)
7286 return true;
7287
7289}
7290
7291bool X86TTIImpl::isFCmpOrdCheaperThanFCmpZero(Type *Ty) const { return false; }
7292
7294 const Function *Callee) const {
7295 const TargetMachine &TM = getTLI()->getTargetMachine();
7296
7297 // Work this as a subsetting of subtarget features.
7298 const X86Subtarget &CallerSubtarget = TM.getSubtarget<X86Subtarget>(*Caller);
7299 const X86Subtarget &CalleeSubtarget = TM.getSubtarget<X86Subtarget>(*Callee);
7300 const FeatureBitset &CallerBits = CallerSubtarget.getFeatureBits();
7301 const FeatureBitset &CalleeBits = CalleeSubtarget.getFeatureBits();
7302
7303 // Check whether callee features are a subset of caller features
7304 // (apart from the ignore list).
7305 const FeatureBitset &InlineIgnoreFeatures =
7306 CallerSubtarget.getInlineIgnoreFeatures();
7307 FeatureBitset RealCallerBits = CallerBits & ~InlineIgnoreFeatures;
7308 FeatureBitset RealCalleeBits = CalleeBits & ~InlineIgnoreFeatures;
7309 if ((RealCallerBits & RealCalleeBits) != RealCalleeBits)
7310 return false;
7311
7312 // If the features are not exactly the same (or there is a difference in
7313 // AVX512 register usage), we need to additionally check for calls
7314 // that may become ABI-incompatible as a result of inlining.
7315 if (RealCallerBits == RealCalleeBits &&
7316 CallerSubtarget.useAVX512Regs() == CalleeSubtarget.useAVX512Regs())
7317 return true;
7318
7319 for (const Instruction &I : instructions(Callee)) {
7320 if (const auto *CB = dyn_cast<CallBase>(&I)) {
7321 // Having more target features is fine for inline ASM and intrinsics.
7322 if (CB->isInlineAsm() || CB->getIntrinsicID() != Intrinsic::not_intrinsic)
7323 continue;
7324
7326 for (Value *Arg : CB->args())
7327 Types.push_back(Arg->getType());
7328 if (!CB->getType()->isVoidTy())
7329 Types.push_back(CB->getType());
7330
7331 // Simple types are always ABI compatible.
7332 auto IsSimpleTy = [](Type *Ty) {
7333 return !Ty->isVectorTy() && !Ty->isAggregateType();
7334 };
7335 if (all_of(Types, IsSimpleTy))
7336 continue;
7337
7338 // Do a precise compatibility check.
7339 if (!areTypesABICompatible(Caller, Callee, Types))
7340 return false;
7341 }
7342 }
7343 return true;
7344}
7345
7347 const Function *Callee,
7348 ArrayRef<Type *> Types) const {
7349 const TargetMachine &TM = getTLI()->getTargetMachine();
7350 const TargetLowering *CallerTLI =
7351 TM.getSubtargetImpl(*Caller)->getTargetLowering();
7352 const TargetLowering *CalleeTLI =
7353 TM.getSubtargetImpl(*Callee)->getTargetLowering();
7354
7355 LLVMContext &Ctx = Caller->getContext();
7356 const DataLayout &DL = Caller->getDataLayout();
7357 CallingConv::ID CC = Callee->getCallingConv();
7358 return all_of(Types, [&](Type *Ty) {
7359 SmallVector<EVT> VTs;
7360 ComputeValueVTs(*CallerTLI, DL, Ty, VTs);
7361 return all_of(VTs, [&](EVT VT) {
7362 return CallerTLI->getRegisterTypeForCallingConv(Ctx, CC, VT) ==
7363 CalleeTLI->getRegisterTypeForCallingConv(Ctx, CC, VT);
7364 });
7365 });
7366}
7367
7369X86TTIImpl::enableMemCmpExpansion(bool OptSize, bool IsZeroCmp) const {
7371 Options.MaxNumLoads = TLI->getMaxExpandSizeMemcmp(OptSize);
7372 Options.NumLoadsPerBlock = IsZeroCmp ? 2 : 1;
7373 // All GPR and vector loads can be unaligned.
7374 Options.AllowOverlappingLoads = true;
7375 if (IsZeroCmp) {
7376 // Only enable vector loads for equality comparison. Right now the vector
7377 // version is not as fast for three way compare (see #33329).
7378 const unsigned PreferredWidth = ST->getPreferVectorWidth();
7379 if (PreferredWidth >= 512 && ST->hasAVX512())
7380 Options.LoadSizes.push_back(64);
7381 if (PreferredWidth >= 256 && ST->hasAVX()) Options.LoadSizes.push_back(32);
7382 if (PreferredWidth >= 128 && ST->hasSSE2()) Options.LoadSizes.push_back(16);
7383 }
7384 if (ST->is64Bit()) {
7385 Options.LoadSizes.push_back(8);
7386 }
7387 Options.LoadSizes.push_back(4);
7388 Options.LoadSizes.push_back(2);
7389 Options.LoadSizes.push_back(1);
7390 return Options;
7391}
7392
7394 return supportsGather();
7395}
7396
7398 return false;
7399}
7400
7402 // TODO: We expect this to be beneficial regardless of arch,
7403 // but there are currently some unexplained performance artifacts on Atom.
7404 // As a temporary solution, disable on Atom.
7405 return !(ST->isAtom());
7406}
7407
7409 switch (II->getIntrinsicID()) {
7410 default:
7411 return true;
7412 case Intrinsic::vector_reduce_and:
7413 case Intrinsic::vector_reduce_or:
7414 case Intrinsic::vector_reduce_xor:
7415 case Intrinsic::vector_reduce_mul:
7416 case Intrinsic::vector_reduce_smax:
7417 case Intrinsic::vector_reduce_smin:
7418 case Intrinsic::vector_reduce_umax:
7419 case Intrinsic::vector_reduce_umin:
7420 return false;
7421 }
7422}
7423
7424// Get estimation for interleaved load/store operations and strided load.
7425// \p Indices contains indices for strided load.
7426// \p Factor - the factor of interleaving.
7427// AVX-512 provides 3-src shuffles that significantly reduces the cost.
7429 unsigned Opcode, FixedVectorType *VecTy, unsigned Factor,
7430 ArrayRef<unsigned> Indices, Align Alignment, unsigned AddressSpace,
7431 TTI::TargetCostKind CostKind, bool UseMaskForCond,
7432 bool UseMaskForGaps) const {
7433 // VecTy for interleave memop is <VF*Factor x Elt>.
7434 // So, for VF=4, Interleave Factor = 3, Element type = i32 we have
7435 // VecTy = <12 x i32>.
7436
7437 // Calculate the number of memory operations (NumOfMemOps), required
7438 // for load/store the VecTy.
7439 MVT LegalVT = getTypeLegalizationCost(VecTy).second;
7440 unsigned VecTySize = DL.getTypeStoreSize(VecTy);
7441 unsigned LegalVTSize = LegalVT.getStoreSize();
7442 unsigned NumOfMemOps = (VecTySize + LegalVTSize - 1) / LegalVTSize;
7443
7444 // Get the cost of one memory operation.
7445 auto *SingleMemOpTy = FixedVectorType::get(VecTy->getElementType(),
7446 LegalVT.getVectorNumElements());
7447 InstructionCost MemOpCost;
7448 bool UseMaskedMemOp = UseMaskForCond || UseMaskForGaps;
7449 if (UseMaskedMemOp) {
7450 unsigned IID = Opcode == Instruction::Load ? Intrinsic::masked_load
7451 : Intrinsic::masked_store;
7452 MemOpCost = getMaskedMemoryOpCost(
7453 {IID, SingleMemOpTy, Alignment, AddressSpace}, CostKind);
7454 } else
7455 MemOpCost = getMemoryOpCost(Opcode, SingleMemOpTy, Alignment, AddressSpace,
7456 CostKind);
7457
7458 unsigned VF = VecTy->getNumElements() / Factor;
7459 MVT VT =
7460 MVT::getVectorVT(TLI->getSimpleValueType(DL, VecTy->getScalarType()), VF);
7461
7462 InstructionCost MaskCost;
7463 if (UseMaskedMemOp) {
7464 APInt DemandedLoadStoreElts = APInt::getZero(VecTy->getNumElements());
7465 for (unsigned Index : Indices) {
7466 assert(Index < Factor && "Invalid index for interleaved memory op");
7467 for (unsigned Elm = 0; Elm < VF; Elm++)
7468 DemandedLoadStoreElts.setBit(Index + Elm * Factor);
7469 }
7470
7471 Type *I1Type = Type::getInt1Ty(VecTy->getContext());
7472
7473 MaskCost = getReplicationShuffleCost(
7474 I1Type, Factor, VF,
7475 UseMaskForGaps ? DemandedLoadStoreElts
7477 CostKind);
7478
7479 // The Gaps mask is invariant and created outside the loop, therefore the
7480 // cost of creating it is not accounted for here. However if we have both
7481 // a MaskForGaps and some other mask that guards the execution of the
7482 // memory access, we need to account for the cost of And-ing the two masks
7483 // inside the loop.
7484 if (UseMaskForGaps) {
7485 auto *MaskVT = FixedVectorType::get(I1Type, VecTy->getNumElements());
7486 MaskCost += getArithmeticInstrCost(BinaryOperator::And, MaskVT, CostKind);
7487 }
7488 }
7489
7490 if (Opcode == Instruction::Load) {
7491 // The tables (AVX512InterleavedLoadTbl and AVX512InterleavedStoreTbl)
7492 // contain the cost of the optimized shuffle sequence that the
7493 // X86InterleavedAccess pass will generate.
7494 // The cost of loads and stores are computed separately from the table.
7495
7496 // X86InterleavedAccess support only the following interleaved-access group.
7497 static const CostTblEntry AVX512InterleavedLoadTbl[] = {
7498 {3, MVT::v16i8, 12}, //(load 48i8 and) deinterleave into 3 x 16i8
7499 {3, MVT::v32i8, 14}, //(load 96i8 and) deinterleave into 3 x 32i8
7500 {3, MVT::v64i8, 22}, //(load 96i8 and) deinterleave into 3 x 32i8
7501 };
7502
7503 if (const auto *Entry =
7504 CostTableLookup(AVX512InterleavedLoadTbl, Factor, VT))
7505 return MaskCost + NumOfMemOps * MemOpCost + Entry->Cost;
7506 //If an entry does not exist, fallback to the default implementation.
7507
7508 // Kind of shuffle depends on number of loaded values.
7509 // If we load the entire data in one register, we can use a 1-src shuffle.
7510 // Otherwise, we'll merge 2 sources in each operation.
7511 TTI::ShuffleKind ShuffleKind =
7512 (NumOfMemOps > 1) ? TTI::SK_PermuteTwoSrc : TTI::SK_PermuteSingleSrc;
7513
7514 InstructionCost ShuffleCost = getShuffleCost(
7515 ShuffleKind, SingleMemOpTy, SingleMemOpTy, CostKind, {}, 0, nullptr);
7516
7517 unsigned NumOfLoadsInInterleaveGrp =
7518 Indices.size() ? Indices.size() : Factor;
7519 auto *ResultTy = FixedVectorType::get(VecTy->getElementType(),
7520 VecTy->getNumElements() / Factor);
7521 InstructionCost NumOfResults =
7522 getTypeLegalizationCost(ResultTy).first * NumOfLoadsInInterleaveGrp;
7523
7524 // About a half of the loads may be folded in shuffles when we have only
7525 // one result. If we have more than one result, or the loads are masked,
7526 // we do not fold loads at all.
7527 unsigned NumOfUnfoldedLoads =
7528 UseMaskedMemOp || NumOfResults > 1 ? NumOfMemOps : NumOfMemOps / 2;
7529
7530 // Get a number of shuffle operations per result.
7531 unsigned NumOfShufflesPerResult =
7532 std::max((unsigned)1, (unsigned)(NumOfMemOps - 1));
7533
7534 // The SK_MergeTwoSrc shuffle clobbers one of src operands.
7535 // When we have more than one destination, we need additional instructions
7536 // to keep sources.
7537 InstructionCost NumOfMoves = 0;
7538 if (NumOfResults > 1 && ShuffleKind == TTI::SK_PermuteTwoSrc)
7539 NumOfMoves = NumOfResults * NumOfShufflesPerResult / 2;
7540
7541 InstructionCost Cost = NumOfResults * NumOfShufflesPerResult * ShuffleCost +
7542 MaskCost + NumOfUnfoldedLoads * MemOpCost +
7543 NumOfMoves;
7544
7545 return Cost;
7546 }
7547
7548 // Store.
7549 assert(Opcode == Instruction::Store &&
7550 "Expected Store Instruction at this point");
7551 // X86InterleavedAccess support only the following interleaved-access group.
7552 static const CostTblEntry AVX512InterleavedStoreTbl[] = {
7553 {3, MVT::v16i8, 12}, // interleave 3 x 16i8 into 48i8 (and store)
7554 {3, MVT::v32i8, 14}, // interleave 3 x 32i8 into 96i8 (and store)
7555 {3, MVT::v64i8, 26}, // interleave 3 x 64i8 into 96i8 (and store)
7556
7557 {4, MVT::v8i8, 10}, // interleave 4 x 8i8 into 32i8 (and store)
7558 {4, MVT::v16i8, 11}, // interleave 4 x 16i8 into 64i8 (and store)
7559 {4, MVT::v32i8, 14}, // interleave 4 x 32i8 into 128i8 (and store)
7560 {4, MVT::v64i8, 24} // interleave 4 x 32i8 into 256i8 (and store)
7561 };
7562
7563 if (const auto *Entry =
7564 CostTableLookup(AVX512InterleavedStoreTbl, Factor, VT))
7565 return MaskCost + NumOfMemOps * MemOpCost + Entry->Cost;
7566 //If an entry does not exist, fallback to the default implementation.
7567
7568 // There is no strided stores meanwhile. And store can't be folded in
7569 // shuffle.
7570 unsigned NumOfSources = Factor; // The number of values to be merged.
7571 InstructionCost ShuffleCost =
7572 getShuffleCost(TTI::SK_PermuteTwoSrc, SingleMemOpTy, SingleMemOpTy,
7573 CostKind, {}, 0, nullptr);
7574 unsigned NumOfShufflesPerStore = NumOfSources - 1;
7575
7576 // The SK_MergeTwoSrc shuffle clobbers one of src operands.
7577 // We need additional instructions to keep sources.
7578 unsigned NumOfMoves = NumOfMemOps * NumOfShufflesPerStore / 2;
7580 MaskCost +
7581 NumOfMemOps * (MemOpCost + NumOfShufflesPerStore * ShuffleCost) +
7582 NumOfMoves;
7583 return Cost;
7584}
7585
7587 unsigned Opcode, Type *BaseTy, unsigned Factor, ArrayRef<unsigned> Indices,
7588 Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind,
7589 bool UseMaskForCond, bool UseMaskForGaps) const {
7590 auto *VecTy = cast<FixedVectorType>(BaseTy);
7591
7592 auto isSupportedOnAVX512 = [&](Type *VecTy) {
7593 Type *EltTy = cast<VectorType>(VecTy)->getElementType();
7594 if (EltTy->isFloatTy() || EltTy->isDoubleTy() || EltTy->isIntegerTy(64) ||
7595 EltTy->isIntegerTy(32) || EltTy->isPointerTy())
7596 return true;
7597 if (EltTy->isIntegerTy(16) || EltTy->isIntegerTy(8) || EltTy->isHalfTy())
7598 return ST->hasBWI();
7599 if (EltTy->isBFloatTy())
7600 return ST->hasBF16();
7601 return false;
7602 };
7603 if (ST->hasAVX512() && isSupportedOnAVX512(VecTy))
7605 Opcode, VecTy, Factor, Indices, Alignment,
7606 AddressSpace, CostKind, UseMaskForCond, UseMaskForGaps);
7607
7608 if (UseMaskForCond || UseMaskForGaps)
7609 return BaseT::getInterleavedMemoryOpCost(Opcode, VecTy, Factor, Indices,
7610 Alignment, AddressSpace, CostKind,
7611 UseMaskForCond, UseMaskForGaps);
7612
7613 // Get estimation for interleaved load/store operations for SSE-AVX2.
7614 // As opposed to AVX-512, SSE-AVX2 do not have generic shuffles that allow
7615 // computing the cost using a generic formula as a function of generic
7616 // shuffles. We therefore use a lookup table instead, filled according to
7617 // the instruction sequences that codegen currently generates.
7618
7619 // VecTy for interleave memop is <VF*Factor x Elt>.
7620 // So, for VF=4, Interleave Factor = 3, Element type = i32 we have
7621 // VecTy = <12 x i32>.
7622 MVT LegalVT = getTypeLegalizationCost(VecTy).second;
7623
7624 // This function can be called with VecTy=<6xi128>, Factor=3, in which case
7625 // the VF=2, while v2i128 is an unsupported MVT vector type
7626 // (see MachineValueType.h::getVectorVT()).
7627 if (!LegalVT.isVector())
7628 return BaseT::getInterleavedMemoryOpCost(Opcode, VecTy, Factor, Indices,
7629 Alignment, AddressSpace, CostKind);
7630
7631 unsigned VF = VecTy->getNumElements() / Factor;
7632 Type *ScalarTy = VecTy->getElementType();
7633 // Deduplicate entries, model floats/pointers as appropriately-sized integers.
7634 if (!ScalarTy->isIntegerTy())
7635 ScalarTy =
7636 Type::getIntNTy(ScalarTy->getContext(), DL.getTypeSizeInBits(ScalarTy));
7637
7638 // Get the cost of all the memory operations.
7639 // FIXME: discount dead loads.
7640 InstructionCost MemOpCosts =
7641 getMemoryOpCost(Opcode, VecTy, Alignment, AddressSpace, CostKind);
7642
7643 auto *VT = FixedVectorType::get(ScalarTy, VF);
7644 EVT ETy = TLI->getValueType(DL, VT);
7645 if (!ETy.isSimple())
7646 return BaseT::getInterleavedMemoryOpCost(Opcode, VecTy, Factor, Indices,
7647 Alignment, AddressSpace, CostKind);
7648
7649 // TODO: Complete for other data-types and strides.
7650 // Each combination of Stride, element bit width and VF results in a different
7651 // sequence; The cost tables are therefore accessed with:
7652 // Factor (stride) and VectorType=VFxiN.
7653 // The Cost accounts only for the shuffle sequence;
7654 // The cost of the loads/stores is accounted for separately.
7655 //
7656 static const CostTblEntry AVX2InterleavedLoadTbl[] = {
7657 {2, MVT::v2i8, 2}, // (load 4i8 and) deinterleave into 2 x 2i8
7658 {2, MVT::v4i8, 2}, // (load 8i8 and) deinterleave into 2 x 4i8
7659 {2, MVT::v8i8, 2}, // (load 16i8 and) deinterleave into 2 x 8i8
7660 {2, MVT::v16i8, 4}, // (load 32i8 and) deinterleave into 2 x 16i8
7661 {2, MVT::v32i8, 6}, // (load 64i8 and) deinterleave into 2 x 32i8
7662
7663 {2, MVT::v8i16, 6}, // (load 16i16 and) deinterleave into 2 x 8i16
7664 {2, MVT::v16i16, 9}, // (load 32i16 and) deinterleave into 2 x 16i16
7665 {2, MVT::v32i16, 18}, // (load 64i16 and) deinterleave into 2 x 32i16
7666
7667 {2, MVT::v8i32, 4}, // (load 16i32 and) deinterleave into 2 x 8i32
7668 {2, MVT::v16i32, 8}, // (load 32i32 and) deinterleave into 2 x 16i32
7669 {2, MVT::v32i32, 16}, // (load 64i32 and) deinterleave into 2 x 32i32
7670
7671 {2, MVT::v4i64, 4}, // (load 8i64 and) deinterleave into 2 x 4i64
7672 {2, MVT::v8i64, 8}, // (load 16i64 and) deinterleave into 2 x 8i64
7673 {2, MVT::v16i64, 16}, // (load 32i64 and) deinterleave into 2 x 16i64
7674 {2, MVT::v32i64, 32}, // (load 64i64 and) deinterleave into 2 x 32i64
7675
7676 {3, MVT::v2i8, 3}, // (load 6i8 and) deinterleave into 3 x 2i8
7677 {3, MVT::v4i8, 3}, // (load 12i8 and) deinterleave into 3 x 4i8
7678 {3, MVT::v8i8, 6}, // (load 24i8 and) deinterleave into 3 x 8i8
7679 {3, MVT::v16i8, 11}, // (load 48i8 and) deinterleave into 3 x 16i8
7680 {3, MVT::v32i8, 14}, // (load 96i8 and) deinterleave into 3 x 32i8
7681
7682 {3, MVT::v2i16, 5}, // (load 6i16 and) deinterleave into 3 x 2i16
7683 {3, MVT::v4i16, 7}, // (load 12i16 and) deinterleave into 3 x 4i16
7684 {3, MVT::v8i16, 9}, // (load 24i16 and) deinterleave into 3 x 8i16
7685 {3, MVT::v16i16, 28}, // (load 48i16 and) deinterleave into 3 x 16i16
7686 {3, MVT::v32i16, 56}, // (load 96i16 and) deinterleave into 3 x 32i16
7687
7688 {3, MVT::v2i32, 3}, // (load 6i32 and) deinterleave into 3 x 2i32
7689 {3, MVT::v4i32, 3}, // (load 12i32 and) deinterleave into 3 x 4i32
7690 {3, MVT::v8i32, 7}, // (load 24i32 and) deinterleave into 3 x 8i32
7691 {3, MVT::v16i32, 14}, // (load 48i32 and) deinterleave into 3 x 16i32
7692 {3, MVT::v32i32, 32}, // (load 96i32 and) deinterleave into 3 x 32i32
7693
7694 {3, MVT::v2i64, 1}, // (load 6i64 and) deinterleave into 3 x 2i64
7695 {3, MVT::v4i64, 5}, // (load 12i64 and) deinterleave into 3 x 4i64
7696 {3, MVT::v8i64, 10}, // (load 24i64 and) deinterleave into 3 x 8i64
7697 {3, MVT::v16i64, 20}, // (load 48i64 and) deinterleave into 3 x 16i64
7698
7699 {4, MVT::v2i8, 4}, // (load 8i8 and) deinterleave into 4 x 2i8
7700 {4, MVT::v4i8, 4}, // (load 16i8 and) deinterleave into 4 x 4i8
7701 {4, MVT::v8i8, 12}, // (load 32i8 and) deinterleave into 4 x 8i8
7702 {4, MVT::v16i8, 24}, // (load 64i8 and) deinterleave into 4 x 16i8
7703 {4, MVT::v32i8, 56}, // (load 128i8 and) deinterleave into 4 x 32i8
7704
7705 {4, MVT::v2i16, 6}, // (load 8i16 and) deinterleave into 4 x 2i16
7706 {4, MVT::v4i16, 17}, // (load 16i16 and) deinterleave into 4 x 4i16
7707 {4, MVT::v8i16, 33}, // (load 32i16 and) deinterleave into 4 x 8i16
7708 {4, MVT::v16i16, 75}, // (load 64i16 and) deinterleave into 4 x 16i16
7709 {4, MVT::v32i16, 150}, // (load 128i16 and) deinterleave into 4 x 32i16
7710
7711 {4, MVT::v2i32, 4}, // (load 8i32 and) deinterleave into 4 x 2i32
7712 {4, MVT::v4i32, 8}, // (load 16i32 and) deinterleave into 4 x 4i32
7713 {4, MVT::v8i32, 16}, // (load 32i32 and) deinterleave into 4 x 8i32
7714 {4, MVT::v16i32, 32}, // (load 64i32 and) deinterleave into 4 x 16i32
7715 {4, MVT::v32i32, 68}, // (load 128i32 and) deinterleave into 4 x 32i32
7716
7717 {4, MVT::v2i64, 6}, // (load 8i64 and) deinterleave into 4 x 2i64
7718 {4, MVT::v4i64, 8}, // (load 16i64 and) deinterleave into 4 x 4i64
7719 {4, MVT::v8i64, 20}, // (load 32i64 and) deinterleave into 4 x 8i64
7720 {4, MVT::v16i64, 40}, // (load 64i64 and) deinterleave into 4 x 16i64
7721
7722 {6, MVT::v2i8, 6}, // (load 12i8 and) deinterleave into 6 x 2i8
7723 {6, MVT::v4i8, 14}, // (load 24i8 and) deinterleave into 6 x 4i8
7724 {6, MVT::v8i8, 18}, // (load 48i8 and) deinterleave into 6 x 8i8
7725 {6, MVT::v16i8, 43}, // (load 96i8 and) deinterleave into 6 x 16i8
7726 {6, MVT::v32i8, 82}, // (load 192i8 and) deinterleave into 6 x 32i8
7727
7728 {6, MVT::v2i16, 13}, // (load 12i16 and) deinterleave into 6 x 2i16
7729 {6, MVT::v4i16, 9}, // (load 24i16 and) deinterleave into 6 x 4i16
7730 {6, MVT::v8i16, 39}, // (load 48i16 and) deinterleave into 6 x 8i16
7731 {6, MVT::v16i16, 106}, // (load 96i16 and) deinterleave into 6 x 16i16
7732 {6, MVT::v32i16, 212}, // (load 192i16 and) deinterleave into 6 x 32i16
7733
7734 {6, MVT::v2i32, 6}, // (load 12i32 and) deinterleave into 6 x 2i32
7735 {6, MVT::v4i32, 15}, // (load 24i32 and) deinterleave into 6 x 4i32
7736 {6, MVT::v8i32, 31}, // (load 48i32 and) deinterleave into 6 x 8i32
7737 {6, MVT::v16i32, 64}, // (load 96i32 and) deinterleave into 6 x 16i32
7738
7739 {6, MVT::v2i64, 6}, // (load 12i64 and) deinterleave into 6 x 2i64
7740 {6, MVT::v4i64, 18}, // (load 24i64 and) deinterleave into 6 x 4i64
7741 {6, MVT::v8i64, 36}, // (load 48i64 and) deinterleave into 6 x 8i64
7742
7743 {8, MVT::v8i32, 40} // (load 64i32 and) deinterleave into 8 x 8i32
7744 };
7745
7746 static const CostTblEntry SSSE3InterleavedLoadTbl[] = {
7747 {2, MVT::v4i16, 2}, // (load 8i16 and) deinterleave into 2 x 4i16
7748 };
7749
7750 static const CostTblEntry SSE2InterleavedLoadTbl[] = {
7751 {2, MVT::v2i16, 2}, // (load 4i16 and) deinterleave into 2 x 2i16
7752 {2, MVT::v4i16, 7}, // (load 8i16 and) deinterleave into 2 x 4i16
7753
7754 {2, MVT::v2i32, 2}, // (load 4i32 and) deinterleave into 2 x 2i32
7755 {2, MVT::v4i32, 2}, // (load 8i32 and) deinterleave into 2 x 4i32
7756
7757 {2, MVT::v2i64, 2}, // (load 4i64 and) deinterleave into 2 x 2i64
7758 };
7759
7760 static const CostTblEntry AVX2InterleavedStoreTbl[] = {
7761 {2, MVT::v16i8, 3}, // interleave 2 x 16i8 into 32i8 (and store)
7762 {2, MVT::v32i8, 4}, // interleave 2 x 32i8 into 64i8 (and store)
7763
7764 {2, MVT::v8i16, 3}, // interleave 2 x 8i16 into 16i16 (and store)
7765 {2, MVT::v16i16, 4}, // interleave 2 x 16i16 into 32i16 (and store)
7766 {2, MVT::v32i16, 8}, // interleave 2 x 32i16 into 64i16 (and store)
7767
7768 {2, MVT::v4i32, 2}, // interleave 2 x 4i32 into 8i32 (and store)
7769 {2, MVT::v8i32, 4}, // interleave 2 x 8i32 into 16i32 (and store)
7770 {2, MVT::v16i32, 8}, // interleave 2 x 16i32 into 32i32 (and store)
7771 {2, MVT::v32i32, 16}, // interleave 2 x 32i32 into 64i32 (and store)
7772
7773 {2, MVT::v2i64, 2}, // interleave 2 x 2i64 into 4i64 (and store)
7774 {2, MVT::v4i64, 4}, // interleave 2 x 4i64 into 8i64 (and store)
7775 {2, MVT::v8i64, 8}, // interleave 2 x 8i64 into 16i64 (and store)
7776 {2, MVT::v16i64, 16}, // interleave 2 x 16i64 into 32i64 (and store)
7777 {2, MVT::v32i64, 32}, // interleave 2 x 32i64 into 64i64 (and store)
7778
7779 {3, MVT::v2i8, 4}, // interleave 3 x 2i8 into 6i8 (and store)
7780 {3, MVT::v4i8, 4}, // interleave 3 x 4i8 into 12i8 (and store)
7781 {3, MVT::v8i8, 6}, // interleave 3 x 8i8 into 24i8 (and store)
7782 {3, MVT::v16i8, 11}, // interleave 3 x 16i8 into 48i8 (and store)
7783 {3, MVT::v32i8, 13}, // interleave 3 x 32i8 into 96i8 (and store)
7784
7785 {3, MVT::v2i16, 4}, // interleave 3 x 2i16 into 6i16 (and store)
7786 {3, MVT::v4i16, 6}, // interleave 3 x 4i16 into 12i16 (and store)
7787 {3, MVT::v8i16, 12}, // interleave 3 x 8i16 into 24i16 (and store)
7788 {3, MVT::v16i16, 27}, // interleave 3 x 16i16 into 48i16 (and store)
7789 {3, MVT::v32i16, 54}, // interleave 3 x 32i16 into 96i16 (and store)
7790
7791 {3, MVT::v2i32, 4}, // interleave 3 x 2i32 into 6i32 (and store)
7792 {3, MVT::v4i32, 5}, // interleave 3 x 4i32 into 12i32 (and store)
7793 {3, MVT::v8i32, 11}, // interleave 3 x 8i32 into 24i32 (and store)
7794 {3, MVT::v16i32, 22}, // interleave 3 x 16i32 into 48i32 (and store)
7795 {3, MVT::v32i32, 48}, // interleave 3 x 32i32 into 96i32 (and store)
7796
7797 {3, MVT::v2i64, 4}, // interleave 3 x 2i64 into 6i64 (and store)
7798 {3, MVT::v4i64, 6}, // interleave 3 x 4i64 into 12i64 (and store)
7799 {3, MVT::v8i64, 12}, // interleave 3 x 8i64 into 24i64 (and store)
7800 {3, MVT::v16i64, 24}, // interleave 3 x 16i64 into 48i64 (and store)
7801
7802 {4, MVT::v2i8, 4}, // interleave 4 x 2i8 into 8i8 (and store)
7803 {4, MVT::v4i8, 4}, // interleave 4 x 4i8 into 16i8 (and store)
7804 {4, MVT::v8i8, 4}, // interleave 4 x 8i8 into 32i8 (and store)
7805 {4, MVT::v16i8, 8}, // interleave 4 x 16i8 into 64i8 (and store)
7806 {4, MVT::v32i8, 12}, // interleave 4 x 32i8 into 128i8 (and store)
7807
7808 {4, MVT::v2i16, 2}, // interleave 4 x 2i16 into 8i16 (and store)
7809 {4, MVT::v4i16, 6}, // interleave 4 x 4i16 into 16i16 (and store)
7810 {4, MVT::v8i16, 10}, // interleave 4 x 8i16 into 32i16 (and store)
7811 {4, MVT::v16i16, 32}, // interleave 4 x 16i16 into 64i16 (and store)
7812 {4, MVT::v32i16, 64}, // interleave 4 x 32i16 into 128i16 (and store)
7813
7814 {4, MVT::v2i32, 5}, // interleave 4 x 2i32 into 8i32 (and store)
7815 {4, MVT::v4i32, 6}, // interleave 4 x 4i32 into 16i32 (and store)
7816 {4, MVT::v8i32, 16}, // interleave 4 x 8i32 into 32i32 (and store)
7817 {4, MVT::v16i32, 32}, // interleave 4 x 16i32 into 64i32 (and store)
7818 {4, MVT::v32i32, 64}, // interleave 4 x 32i32 into 128i32 (and store)
7819
7820 {4, MVT::v2i64, 6}, // interleave 4 x 2i64 into 8i64 (and store)
7821 {4, MVT::v4i64, 8}, // interleave 4 x 4i64 into 16i64 (and store)
7822 {4, MVT::v8i64, 20}, // interleave 4 x 8i64 into 32i64 (and store)
7823 {4, MVT::v16i64, 40}, // interleave 4 x 16i64 into 64i64 (and store)
7824
7825 {6, MVT::v2i8, 7}, // interleave 6 x 2i8 into 12i8 (and store)
7826 {6, MVT::v4i8, 9}, // interleave 6 x 4i8 into 24i8 (and store)
7827 {6, MVT::v8i8, 16}, // interleave 6 x 8i8 into 48i8 (and store)
7828 {6, MVT::v16i8, 27}, // interleave 6 x 16i8 into 96i8 (and store)
7829 {6, MVT::v32i8, 90}, // interleave 6 x 32i8 into 192i8 (and store)
7830
7831 {6, MVT::v2i16, 10}, // interleave 6 x 2i16 into 12i16 (and store)
7832 {6, MVT::v4i16, 15}, // interleave 6 x 4i16 into 24i16 (and store)
7833 {6, MVT::v8i16, 21}, // interleave 6 x 8i16 into 48i16 (and store)
7834 {6, MVT::v16i16, 58}, // interleave 6 x 16i16 into 96i16 (and store)
7835 {6, MVT::v32i16, 90}, // interleave 6 x 32i16 into 192i16 (and store)
7836
7837 {6, MVT::v2i32, 9}, // interleave 6 x 2i32 into 12i32 (and store)
7838 {6, MVT::v4i32, 12}, // interleave 6 x 4i32 into 24i32 (and store)
7839 {6, MVT::v8i32, 33}, // interleave 6 x 8i32 into 48i32 (and store)
7840 {6, MVT::v16i32, 66}, // interleave 6 x 16i32 into 96i32 (and store)
7841
7842 {6, MVT::v2i64, 8}, // interleave 6 x 2i64 into 12i64 (and store)
7843 {6, MVT::v4i64, 15}, // interleave 6 x 4i64 into 24i64 (and store)
7844 {6, MVT::v8i64, 30}, // interleave 6 x 8i64 into 48i64 (and store)
7845 };
7846
7847 static const CostTblEntry SSE2InterleavedStoreTbl[] = {
7848 {2, MVT::v2i8, 1}, // interleave 2 x 2i8 into 4i8 (and store)
7849 {2, MVT::v4i8, 1}, // interleave 2 x 4i8 into 8i8 (and store)
7850 {2, MVT::v8i8, 1}, // interleave 2 x 8i8 into 16i8 (and store)
7851
7852 {2, MVT::v2i16, 1}, // interleave 2 x 2i16 into 4i16 (and store)
7853 {2, MVT::v4i16, 1}, // interleave 2 x 4i16 into 8i16 (and store)
7854
7855 {2, MVT::v2i32, 1}, // interleave 2 x 2i32 into 4i32 (and store)
7856 };
7857
7858 if (Opcode == Instruction::Load) {
7859 auto GetDiscountedCost = [Factor, NumMembers = Indices.size(),
7860 MemOpCosts](const CostTblEntry *Entry) {
7861 // NOTE: this is just an approximation!
7862 // It can over/under -estimate the cost!
7863 return MemOpCosts + divideCeil(NumMembers * Entry->Cost, Factor);
7864 };
7865
7866 if (ST->hasAVX2())
7867 if (const auto *Entry = CostTableLookup(AVX2InterleavedLoadTbl, Factor,
7868 ETy.getSimpleVT()))
7869 return GetDiscountedCost(Entry);
7870
7871 if (ST->hasSSSE3())
7872 if (const auto *Entry = CostTableLookup(SSSE3InterleavedLoadTbl, Factor,
7873 ETy.getSimpleVT()))
7874 return GetDiscountedCost(Entry);
7875
7876 if (ST->hasSSE2())
7877 if (const auto *Entry = CostTableLookup(SSE2InterleavedLoadTbl, Factor,
7878 ETy.getSimpleVT()))
7879 return GetDiscountedCost(Entry);
7880 } else {
7881 assert(Opcode == Instruction::Store &&
7882 "Expected Store Instruction at this point");
7883 assert((!Indices.size() || Indices.size() == Factor) &&
7884 "Interleaved store only supports fully-interleaved groups.");
7885 if (ST->hasAVX2())
7886 if (const auto *Entry = CostTableLookup(AVX2InterleavedStoreTbl, Factor,
7887 ETy.getSimpleVT()))
7888 return MemOpCosts + Entry->Cost;
7889
7890 if (ST->hasSSE2())
7891 if (const auto *Entry = CostTableLookup(SSE2InterleavedStoreTbl, Factor,
7892 ETy.getSimpleVT()))
7893 return MemOpCosts + Entry->Cost;
7894 }
7895
7896 return BaseT::getInterleavedMemoryOpCost(Opcode, VecTy, Factor, Indices,
7897 Alignment, AddressSpace, CostKind,
7898 UseMaskForCond, UseMaskForGaps);
7899}
7900
7902 StackOffset BaseOffset,
7903 bool HasBaseReg, int64_t Scale,
7904 unsigned AddrSpace) const {
7905 // Scaling factors are not free at all.
7906 // An indexed folded instruction, i.e., inst (reg1, reg2, scale),
7907 // will take 2 allocations in the out of order engine instead of 1
7908 // for plain addressing mode, i.e. inst (reg1).
7909 // E.g.,
7910 // vaddps (%rsi,%rdx), %ymm0, %ymm1
7911 // Requires two allocations (one for the load, one for the computation)
7912 // whereas:
7913 // vaddps (%rsi), %ymm0, %ymm1
7914 // Requires just 1 allocation, i.e., freeing allocations for other operations
7915 // and having less micro operations to execute.
7916 //
7917 // For some X86 architectures, this is even worse because for instance for
7918 // stores, the complex addressing mode forces the instruction to use the
7919 // "load" ports instead of the dedicated "store" port.
7920 // E.g., on Haswell:
7921 // vmovaps %ymm1, (%r8, %rdi) can use port 2 or 3.
7922 // vmovaps %ymm1, (%r8) can use port 2, 3, or 7.
7924 AM.BaseGV = BaseGV;
7925 AM.BaseOffs = BaseOffset.getFixed();
7926 AM.HasBaseReg = HasBaseReg;
7927 AM.Scale = Scale;
7928 AM.ScalableOffset = BaseOffset.getScalable();
7929 if (getTLI()->isLegalAddressingMode(DL, AM, Ty, AddrSpace))
7930 // Scale represents reg2 * scale, thus account for 1
7931 // as soon as we use a second register.
7932 return AM.Scale != 0;
7934}
7935
7937 // TODO: Hook MispredictPenalty of SchedMachineModel into this.
7938 return 14;
7939}
7940
7942 unsigned Bits = Ty->getScalarSizeInBits();
7943
7944 // XOP has v16i8/v8i16/v4i32/v2i64 variable vector shifts.
7945 // Splitting for v32i8/v16i16 on XOP+AVX2 targets is still preferred.
7946 if (ST->hasXOP() && (Bits == 8 || Bits == 16 || Bits == 32 || Bits == 64))
7947 return false;
7948
7949 // AVX2 has vpsllv[dq] instructions (and other shifts) that make variable
7950 // shifts just as cheap as scalar ones.
7951 if (ST->hasAVX2() && (Bits == 32 || Bits == 64))
7952 return false;
7953
7954 // AVX512BW has shifts such as vpsllvw.
7955 if (ST->hasBWI() && Bits == 16)
7956 return false;
7957
7958 // Otherwise, it's significantly cheaper to shift by a scalar amount than by a
7959 // fully general vector.
7960 return true;
7961}
7962
7963unsigned X86TTIImpl::getStoreMinimumVF(unsigned VF, Type *ScalarMemTy,
7964 Type *ScalarValTy, Align Alignment,
7965 unsigned AddrSpace) const {
7966 if (ST->hasF16C() && ScalarMemTy->isHalfTy()) {
7967 return 4;
7968 }
7969 return BaseT::getStoreMinimumVF(VF, ScalarMemTy, ScalarValTy, Alignment,
7970 AddrSpace);
7971}
7972
7974 SmallVectorImpl<Use *> &Ops) const {
7975 using namespace llvm::PatternMatch;
7976
7977 if (I->getOpcode() == Instruction::And &&
7978 (ST->hasBMI() || (I->getType()->isVectorTy() && ST->hasSSE2()))) {
7979 for (auto &Op : I->operands()) {
7980 // (and X, (not Y)) -> (andn X, Y)
7981 if (match(Op.get(), m_Not(m_Value())) && !I->getType()->isIntegerTy(8)) {
7982 Ops.push_back(&Op);
7983 return true;
7984 }
7985 // (and X, (splat (not Y))) -> (andn X, (splat Y))
7986 if (match(Op.get(),
7988 m_Value(), m_ZeroMask()))) {
7989 Use &InsertElt = cast<Instruction>(Op)->getOperandUse(0);
7990 Use &Not = cast<Instruction>(InsertElt)->getOperandUse(1);
7991 Ops.push_back(&Not);
7992 Ops.push_back(&InsertElt);
7993 Ops.push_back(&Op);
7994 return true;
7995 }
7996 }
7997 }
7998
7999 FixedVectorType *VTy = dyn_cast<FixedVectorType>(I->getType());
8000 if (!VTy)
8001 return false;
8002
8003 if (I->getOpcode() == Instruction::Mul &&
8004 VTy->getElementType()->isIntegerTy(64)) {
8005 for (auto &Op : I->operands()) {
8006 // Make sure we are not already sinking this operand
8007 if (any_of(Ops, [&](Use *U) { return U->get() == Op; }))
8008 continue;
8009
8010 // Look for PMULDQ pattern where the input is a sext_inreg from vXi32 or
8011 // the PMULUDQ pattern where the input is a zext_inreg from vXi32.
8012 if (ST->hasSSE41() &&
8013 match(Op.get(), m_AShr(m_Shl(m_Value(), m_SpecificInt(32)),
8014 m_SpecificInt(32)))) {
8015 Ops.push_back(&cast<Instruction>(Op)->getOperandUse(0));
8016 Ops.push_back(&Op);
8017 } else if (ST->hasSSE2() &&
8018 match(Op.get(),
8019 m_And(m_Value(), m_SpecificInt(UINT64_C(0xffffffff))))) {
8020 Ops.push_back(&Op);
8021 }
8022 }
8023
8024 return !Ops.empty();
8025 }
8026
8027 // A uniform shift amount in a vector shift or funnel shift may be much
8028 // cheaper than a generic variable vector shift, so make that pattern visible
8029 // to SDAG by sinking the shuffle instruction next to the shift.
8030 int ShiftAmountOpNum = -1;
8031 if (I->isShift())
8032 ShiftAmountOpNum = 1;
8033 else if (auto *II = dyn_cast<IntrinsicInst>(I)) {
8034 if (II->getIntrinsicID() == Intrinsic::fshl ||
8035 II->getIntrinsicID() == Intrinsic::fshr)
8036 ShiftAmountOpNum = 2;
8037 }
8038
8039 if (ShiftAmountOpNum == -1)
8040 return false;
8041
8042 auto *Shuf = dyn_cast<ShuffleVectorInst>(I->getOperand(ShiftAmountOpNum));
8043 if (Shuf && getSplatIndex(Shuf->getShuffleMask()) >= 0 &&
8044 isVectorShiftByScalarCheap(I->getType())) {
8045 Ops.push_back(&I->getOperandUse(ShiftAmountOpNum));
8046 return true;
8047 }
8048
8049 return false;
8050}
8051
8053 bool HasEGPR = ST->hasEGPR();
8054 const TargetMachine &TM = getTLI()->getTargetMachine();
8055
8056 for (User *U : F.users()) {
8058 if (!CB || CB->getCalledOperand() != &F)
8059 continue;
8060 Function *CallerFunc = CB->getFunction();
8061 if (TM.getSubtarget<X86Subtarget>(*CallerFunc).hasEGPR() != HasEGPR)
8062 return false;
8063 }
8064
8065 return true;
8066}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
unsigned Imm
Expand Atomic instructions
This file provides a helper that implements much of the TTI interface in terms of the target-independ...
#define X(NUM, ENUM, NAME)
Definition ELF.h:857
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static cl::opt< OutputCostKind > CostKind("cost-kind", cl::desc("Target cost kind"), cl::init(OutputCostKind::RecipThroughput), cl::values(clEnumValN(OutputCostKind::RecipThroughput, "throughput", "Reciprocal throughput"), clEnumValN(OutputCostKind::Latency, "latency", "Instruction latency"), clEnumValN(OutputCostKind::CodeSize, "code-size", "Code size"), clEnumValN(OutputCostKind::SizeAndLatency, "size-latency", "Code size and latency"), clEnumValN(OutputCostKind::All, "all", "Print all cost kinds")))
Cost tables and simple lookup functions.
Hexagon Common GEP
iv users
Definition IVUsers.cpp:48
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static LVOptions Options
Definition LVOptions.cpp:25
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
uint64_t IntrinsicInst * II
#define P(N)
This file implements the SmallBitVector class.
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
This file describes how to lower LLVM code to machine code.
This pass exposes codegen information to IR-level passes.
static unsigned getBitWidth(Type *Ty, const DataLayout &DL)
Returns the bitwidth of the given scalar or pointer type.
CostTblEntryT< CostKindCosts > CostKindTblEntry
static bool isLegalMaskedLoadStore(Type *ScalarTy, const X86Subtarget *ST)
TypeConversionCostTblEntryT< CostKindCosts > TypeConversionCostKindTblEntry
This file a TargetTransformInfoImplBase conforming object specific to the X86 target machine.
static const fltSemantics & IEEEsingle()
Definition APFloat.h:304
static const fltSemantics & IEEEdouble()
Definition APFloat.h:305
static LLVM_ABI unsigned int semanticsPrecision(const fltSemantics &)
Definition APFloat.cpp:318
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:1057
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:1086
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
TTI::ShuffleKind improveShuffleKindFromMask(TTI::ShuffleKind Kind, ArrayRef< int > Mask, VectorType *SrcTy, int &Index, VectorType *&SubTy) const
bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset, bool HasBaseReg, int64_t Scale, unsigned AddrSpace, Instruction *I=nullptr, int64_t ScalableOffset=0) const override
unsigned getStoreMinimumVF(unsigned VF, Type *ScalarMemTy, Type *ScalarValTy, Align Alignment, unsigned AddrSpace) const override
InstructionCost getScalarizationOverhead(VectorType *InTy, const APInt &DemandedElts, bool Insert, bool Extract, TTI::TargetCostKind CostKind, bool ForPoisonSrc=true, ArrayRef< Value * > VL={}, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const override
InstructionCost getArithmeticReductionCost(unsigned Opcode, VectorType *Ty, std::optional< FastMathFlags > FMF, TTI::TargetCostKind CostKind) const override
InstructionCost getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy, CmpInst::Predicate VecPred, TTI::TargetCostKind CostKind, TTI::OperandValueInfo Op1Info={TTI::OK_AnyValue, TTI::OP_None}, TTI::OperandValueInfo Op2Info={TTI::OK_AnyValue, TTI::OP_None}, const Instruction *I=nullptr) const override
InstructionCost getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src, TTI::CastContextHint CCH, TTI::TargetCostKind CostKind, const Instruction *I=nullptr) const override
std::pair< InstructionCost, MVT > getTypeLegalizationCost(Type *Ty) const
InstructionCost getReplicationShuffleCost(Type *EltTy, int ReplicationFactor, int VF, const APInt &DemandedDstElts, TTI::TargetCostKind CostKind) const override
InstructionCost getVectorInstrCost(unsigned Opcode, Type *Val, TTI::TargetCostKind CostKind, unsigned Index, const Value *Op0, const Value *Op1, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const override
InstructionCost getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA, TTI::TargetCostKind CostKind) const override
InstructionCost getAddressComputationCost(Type *PtrTy, ScalarEvolution *, const SCEV *, TTI::TargetCostKind) const override
InstructionCost getGEPCost(Type *PointeeType, const Value *Ptr, ArrayRef< const Value * > Operands, TTI::TargetCostKind CostKind, Type *AccessType) const override
InstructionCost getShuffleCost(TTI::ShuffleKind Kind, VectorType *DstTy, VectorType *SrcTy, TTI::TargetCostKind CostKind, ArrayRef< int > Mask, int Index, VectorType *SubTp, ArrayRef< const Value * > Args={}, const Instruction *CxtI=nullptr) const override
InstructionCost getMemIntrinsicInstrCost(const MemIntrinsicCostAttributes &MICA, TTI::TargetCostKind CostKind) const override
InstructionCost getMemoryOpCost(unsigned Opcode, Type *Src, Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind, TTI::OperandValueInfo OpInfo={TTI::OK_AnyValue, TTI::OP_None}, const Instruction *I=nullptr) const override
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Value * getCalledOperand() const
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition InstrTypes.h:740
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
Definition InstrTypes.h:743
@ ICMP_SLE
signed less or equal
Definition InstrTypes.h:770
@ ICMP_UGE
unsigned greater or equal
Definition InstrTypes.h:764
@ ICMP_UGT
unsigned greater than
Definition InstrTypes.h:763
@ FCMP_ONE
0 1 1 0 True if ordered and operands are unequal
Definition InstrTypes.h:748
@ FCMP_UEQ
1 0 0 1 True if unordered or equal
Definition InstrTypes.h:751
@ ICMP_ULT
unsigned less than
Definition InstrTypes.h:765
@ ICMP_NE
not equal
Definition InstrTypes.h:762
@ ICMP_SGE
signed greater or equal
Definition InstrTypes.h:768
@ ICMP_ULE
unsigned less or equal
Definition InstrTypes.h:766
@ FCMP_UNO
1 0 0 0 True if unordered: isnan(X) | isnan(Y)
Definition InstrTypes.h:750
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
constexpr bool isScalar() const
Exactly one element.
Definition TypeSize.h:316
Convenience struct for specifying and reasoning about fast-math flags.
Definition FMF.h:23
Container class for subtarget features.
Class to represent fixed width SIMD vectors.
unsigned getNumElements() const
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
Definition Type.cpp:843
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition Function.cpp:730
static unsigned getPointerOperandIndex()
static InstructionCost getInvalid(CostType Val=0)
CostType getValue() const
This function is intended to be used as sparingly as possible, since the class provides the full rang...
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
Definition Type.cpp:338
const SmallVectorImpl< Type * > & getArgTypes() const
const SmallVectorImpl< const Value * > & getArgs() const
const IntrinsicInst * getInst() const
A wrapper class for inspecting calls to intrinsic functions.
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
Machine Value Type.
bool is128BitVector() const
Return true if this is a 128-bit vector type.
uint64_t getScalarSizeInBits() const
unsigned getVectorNumElements() const
bool isVector() const
Return true if this is a vector value type.
bool isInteger() const
Return true if this is an integer or a vector integer type.
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
bool isScalarInteger() const
Return true if this is an integer, not including vectors.
static MVT getVectorVT(MVT VT, unsigned NumElements)
MVT getVectorElementType() const
MVT getScalarType() const
If this is a vector, return the element type, otherwise return this.
Information for memory intrinsic cost model.
This class represents an analyzed expression in the program.
The main scalar evolution driver.
static LLVM_ABI bool isIdentityMask(ArrayRef< int > Mask, int NumSrcElts)
Return true if this shuffle mask chooses elements from exactly one source vector without lane crossin...
This is a 'bitvector' (really, a variable-sized bit array), optimized for the case when the array is ...
bool test(unsigned Idx) const
Returns true if bit Idx is set.
size_type size() const
Returns the number of bits in this bitvector.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StackOffset holds a fixed and a scalable offset in bytes.
Definition TypeSize.h:30
static StackOffset getScalable(int64_t Scalable)
Definition TypeSize.h:40
static StackOffset getFixed(int64_t Fixed)
Definition TypeSize.h:39
virtual MVT getRegisterTypeForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const
Certain combinations of ABIs, Targets and features require that types are legal for some operations a...
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
Primary interface to the complete machine description for the target machine.
const STC & getSubtarget(const Function &F) const
This method returns a pointer to the specified type of TargetSubtargetInfo.
virtual const TargetSubtargetInfo * getSubtargetImpl(const Function &) const
Virtual method implemented by subclasses that returns a reference to that target's TargetSubtargetInf...
virtual const TargetLowering * getTargetLowering() const
bool isStridedAccess(const SCEV *Ptr) const
unsigned minRequiredElementSize(const Value *Val, bool &isSigned) const
const SCEVConstant * getConstantStrideStep(ScalarEvolution *SE, const SCEV *Ptr) const
virtual bool isExpensiveToSpeculativelyExecute(const Instruction *I) const
virtual InstructionCost getPointersChainCost(ArrayRef< const Value * > Ptrs, const Value *Base, const TTI::PointersChainInfo &Info, Type *AccessTy, const TTI::TargetCostKind CostKind) const
MaskKind
Some targets only support masked load/store with a constant mask.
TargetCostKind
The kind of cost model.
@ TCK_RecipThroughput
Reciprocal throughput.
@ TCK_CodeSize
Instruction code size.
@ TCK_SizeAndLatency
The weighted sum of size and latency.
@ TCK_Latency
The latency of instruction.
static bool requiresOrderedReduction(std::optional< FastMathFlags > FMF)
A helper function to determine the type of reduction algorithm used for a given Opcode and set of Fas...
PopcntSupportKind
Flags indicating the kind of support for population count.
llvm::VectorInstrContext VectorInstrContext
@ TCC_Free
Expected to fold away in lowering.
@ TCC_Basic
The cost of a typical 'add' instruction.
ShuffleKind
The various kinds of shuffle patterns for vector queries.
@ SK_InsertSubvector
InsertSubvector. Index indicates start offset.
@ SK_Select
Selects elements from the corresponding lane of either source operand.
@ SK_PermuteSingleSrc
Shuffle elements of single source vector with any shuffle mask.
@ SK_Transpose
Transpose two vectors.
@ SK_Splice
Concatenates elements from the first input vector with elements of the second input vector.
@ SK_Broadcast
Broadcast element 0 to all other elements.
@ SK_PermuteTwoSrc
Merge elements from two source vectors into one with any shuffle mask.
@ SK_Reverse
Reverse the order of the vector.
@ SK_ExtractSubvector
ExtractSubvector Index indicates start offset.
CastContextHint
Represents a hint about the context in which a cast is used.
@ None
The cast is not used with a load/store of any kind.
CacheLevel
The possible cache levels.
static constexpr TypeSize getFixed(ScalarTy ExactSize)
Definition TypeSize.h:339
static constexpr TypeSize getScalable(ScalarTy MinimumSize)
Definition TypeSize.h:342
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
Definition Type.cpp:300
LLVM_ABI unsigned getIntegerBitWidth() const
bool isVectorTy() const
True if this is an instance of VectorType.
Definition Type.h:283
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
Definition Type.cpp:299
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
Definition Type.h:258
bool isPointerTy() const
True if this is an instance of PointerType.
Definition Type.h:277
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
Definition Type.h:155
bool isBFloatTy() const
Return true if this is 'bfloat', a 16-bit bfloat type.
Definition Type.h:147
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
Definition Type.cpp:297
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Definition Type.h:363
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
Definition Type.cpp:187
LLVM_ABI Type * getWithNewBitWidth(unsigned NewBitWidth) const
Given an integer or vector type, change the lane bitwidth to NewBitwidth, whilst keeping the old numb...
bool isHalfTy() const
Return true if this is 'half', a 16-bit IEEE fp type.
Definition Type.h:144
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
Definition Type.h:130
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
Definition Type.cpp:222
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
Definition Type.h:158
static LLVM_ABI IntegerType * getInt1Ty(LLVMContext &C)
Definition Type.cpp:296
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
Definition Type.h:186
LLVM_ABI bool isScalableTy() const
Return true if this is a type whose size is a known multiple of vscale.
Definition Type.cpp:61
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:252
static LLVM_ABI IntegerType * getIntNTy(LLVMContext &C, unsigned N)
Definition Type.cpp:303
static LLVM_ABI Type * getDoubleTy(LLVMContext &C)
Definition Type.cpp:277
bool isFPOrFPVectorTy() const
Return true if this is a FP type or a vector of FP.
Definition Type.h:222
Type * getContainedType(unsigned i) const
This method is used to implement the type iterator (defined at the end of the file).
Definition Type.h:392
static LLVM_ABI Type * getFloatTy(LLVMContext &C)
Definition Type.cpp:276
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:257
Base class of all SIMD vector types.
static VectorType * getExtendedElementVectorType(VectorType *VTy)
This static method is like getInteger except that the element types are twice as wide as the elements...
ElementCount getElementCount() const
Return an ElementCount instance to represent the (possibly scalable) number of elements in the vector...
static 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
bool isLegalNTStore(Type *DataType, Align Alignment) const override
InstructionCost getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src, TTI::CastContextHint CCH, TTI::TargetCostKind CostKind, const Instruction *I=nullptr) const override
InstructionCost getInterleavedMemoryOpCostAVX512(unsigned Opcode, FixedVectorType *VecTy, unsigned Factor, ArrayRef< unsigned > Indices, Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind, bool UseMaskForCond=false, bool UseMaskForGaps=false) const
bool isLegalAltInstr(VectorType *VecTy, unsigned Opcode0, unsigned Opcode1, const SmallBitVector &OpcodeMask) const override
TypeSize getRegisterBitWidth(TargetTransformInfo::RegisterKind K) const override
bool isVectorShiftByScalarCheap(Type *Ty) const override
bool isLegalMaskedGather(Type *DataType, Align Alignment) const override
InstructionCost getShuffleCost(TTI::ShuffleKind Kind, VectorType *DstTy, VectorType *SrcTy, TTI::TargetCostKind CostKind, ArrayRef< int > Mask, int Index, VectorType *SubTp, ArrayRef< const Value * > Args={}, const Instruction *CxtI=nullptr) const override
bool shouldExpandReduction(const IntrinsicInst *II) const override
InstructionCost getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, StackOffset BaseOffset, bool HasBaseReg, int64_t Scale, unsigned AddrSpace) const override
Return the cost of the scaling factor used in the addressing mode represented by AM for this target,...
unsigned getAtomicMemIntrinsicMaxElementSize() const override
bool forceScalarizeMaskedGather(VectorType *VTy, Align Alignment) const override
InstructionCost getBranchMispredictPenalty() const override
bool isExpensiveToSpeculativelyExecute(const Instruction *I) const override
bool hasConditionalLoadStoreForType(Type *Ty, bool IsStore) const override
bool isLegalMaskedStore(Type *DataType, Align Alignment, unsigned AddressSpace, TTI::MaskKind MaskKind=TTI::MaskKind::VariableOrConstantMask) const override
std::optional< unsigned > getCacheSize(TargetTransformInfo::CacheLevel Level) const override
InstructionCost getArithmeticInstrCost(unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind, TTI::OperandValueInfo Op1Info={TTI::OK_AnyValue, TTI::OP_None}, TTI::OperandValueInfo Op2Info={TTI::OK_AnyValue, TTI::OP_None}, ArrayRef< const Value * > Args={}, const Instruction *CxtI=nullptr) const override
bool isLegalMaskedGatherScatter(Type *DataType, Align Alignment) const
bool isLegalMaskedLoad(Type *DataType, Align Alignment, unsigned AddressSpace, TTI::MaskKind MaskKind=TTI::MaskKind::VariableOrConstantMask) const override
bool enableInterleavedAccessVectorization() const override
unsigned getLoadStoreVecRegBitWidth(unsigned AS) const override
unsigned getNumberOfRegisters(unsigned ClassID) const override
InstructionCost getVectorInstrCost(unsigned Opcode, Type *Val, TTI::TargetCostKind CostKind, unsigned Index, const Value *Op0, const Value *Op1, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const override
bool isLegalMaskedScatter(Type *DataType, Align Alignment) const override
unsigned getStoreMinimumVF(unsigned VF, Type *ScalarMemTy, Type *ScalarValTy, Align Alignment, unsigned AddrSpace) const override
bool hasDivRemOp(Type *DataType, bool IsSigned) const override
bool isLegalMaskedCompressStore(Type *DataType, Align Alignment) const override
InstructionCost getIntImmCostIntrin(Intrinsic::ID IID, unsigned Idx, const APInt &Imm, Type *Ty, TTI::TargetCostKind CostKind) const override
bool supportsEfficientVectorElementLoadStore() const override
InstructionCost getIntImmCostInst(unsigned Opcode, unsigned Idx, const APInt &Imm, Type *Ty, TTI::TargetCostKind CostKind, Instruction *Inst=nullptr) const override
bool isLegalMaskedExpandLoad(Type *DataType, Align Alignment) const override
TTI::PopcntSupportKind getPopcntSupport(unsigned TyWidth) const override
bool isFCmpOrdCheaperThanFCmpZero(Type *Ty) const override
TTI::MemCmpExpansionOptions enableMemCmpExpansion(bool OptSize, bool IsZeroCmp) const override
InstructionCost getPointersChainCost(ArrayRef< const Value * > Ptrs, const Value *Base, const TTI::PointersChainInfo &Info, Type *AccessTy, const TTI::TargetCostKind CostKind) const override
InstructionCost getIntImmCost(int64_t) const
Calculate the cost of materializing a 64-bit value.
InstructionCost getMinMaxCost(Intrinsic::ID IID, Type *Ty, TTI::TargetCostKind CostKind, FastMathFlags FMF) const
InstructionCost getCFInstrCost(unsigned Opcode, TTI::TargetCostKind CostKind, const Instruction *I=nullptr) const override
InstructionCost getInterleavedMemoryOpCost(unsigned Opcode, Type *VecTy, unsigned Factor, ArrayRef< unsigned > Indices, Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind, bool UseMaskForCond=false, bool UseMaskForGaps=false) const override
bool canMacroFuseCmp() const override
bool areInlineCompatible(const Function *Caller, const Function *Callee) const override
InstructionCost getMaskedMemoryOpCost(const MemIntrinsicCostAttributes &MICA, TTI::TargetCostKind CostKind) const
bool prefersVectorizedAddressing() const override
bool areTypesABICompatible(const Function *Caller, const Function *Callee, ArrayRef< Type * > Type) const override
InstructionCost getAltInstrCost(VectorType *VecTy, unsigned Opcode0, unsigned Opcode1, const SmallBitVector &OpcodeMask, TTI::TargetCostKind CostKind) const override
bool forceScalarizeMaskedScatter(VectorType *VTy, Align Alignment) const override
InstructionCost getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA, TTI::TargetCostKind CostKind) const override
Get intrinsic cost based on arguments.
bool isProfitableToSinkOperands(Instruction *I, SmallVectorImpl< Use * > &Ops) const override
InstructionCost getScalarizationOverhead(VectorType *Ty, const APInt &DemandedElts, bool Insert, bool Extract, TTI::TargetCostKind CostKind, bool ForPoisonSrc=true, ArrayRef< Value * > VL={}, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const override
Estimate the overhead of scalarizing an instruction.
InstructionCost getArithmeticReductionCost(unsigned Opcode, VectorType *Ty, std::optional< FastMathFlags > FMF, TTI::TargetCostKind CostKind) const override
InstructionCost getGatherScatterOpCost(const MemIntrinsicCostAttributes &MICA, TTI::TargetCostKind CostKind) const
Calculate the cost of Gather / Scatter operation.
InstructionCost getMemoryOpCost(unsigned Opcode, Type *Src, Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind, TTI::OperandValueInfo OpInfo={TTI::OK_AnyValue, TTI::OP_None}, const Instruction *I=nullptr) const override
InstructionCost getAddressComputationCost(Type *PtrTy, ScalarEvolution *SE, const SCEV *Ptr, TTI::TargetCostKind CostKind) const override
InstructionCost getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy, CmpInst::Predicate VecPred, TTI::TargetCostKind CostKind, TTI::OperandValueInfo Op1Info={TTI::OK_AnyValue, TTI::OP_None}, TTI::OperandValueInfo Op2Info={TTI::OK_AnyValue, TTI::OP_None}, const Instruction *I=nullptr) const override
bool isLSRCostLess(const TargetTransformInfo::LSRCost &C1, const TargetTransformInfo::LSRCost &C2) const override
constexpr 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:3043
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
ISD namespace - This namespace contains an enum which represents all of the SelectionDAG node types a...
Definition ISDOpcodes.h:24
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
Definition ISDOpcodes.h:41
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
Definition ISDOpcodes.h:829
@ DELETED_NODE
DELETED_NODE - This is an illegal value that is used to catch errors.
Definition ISDOpcodes.h:45
@ 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:541
LLVM_ABI Value * getSplatValue(const Value *V)
Get splat value if the input is a splat vector or return nullptr.
bool isa_and_nonnull(const Y &Val)
Definition Casting.h:676
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
uint64_t PowerOf2Ceil(uint64_t A)
Returns the power of two which is greater than or equal to the given value.
Definition MathExtras.h:380
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h: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:389
DWARFExpression::Operation Op
LLVM_ABI unsigned ComputeNumSignBits(const Value *Op, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true, unsigned Depth=0)
Return the number of times the sign bit of the register is replicated into the other bits.
OutputIt copy(R &&Range, OutputIt Out)
Definition STLExtras.h: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