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 17 /// concrete CPU model. Usually the numbers correspond to CPU where the feature 18 /// apeared at the first time. 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 /// Some examples of other technologies/CPUs: 22 /// SSE 3 - Pentium4 / Athlon64 23 /// SSE 4.1 - Penryn 24 /// SSE 4.2 - Nehalem 25 /// AVX - Sandy Bridge 26 /// AVX2 - Haswell 27 /// AVX-512 - Xeon Phi / Skylake 28 /// And some examples of instruction target dependent costs (latency) 29 /// divss sqrtss rsqrtss 30 /// AMD K7 11-16 19 3 31 /// Piledriver 9-24 13-15 5 32 /// Jaguar 14 16 2 33 /// Pentium II,III 18 30 2 34 /// Nehalem 7-14 7-18 3 35 /// Haswell 10-13 11 5 36 /// TODO: Develop and implement the target dependent cost model and 37 /// specialize cost numbers for different Cost Model Targets such as throughput, 38 /// code size, latency and uop count. 39 //===----------------------------------------------------------------------===// 40 41 #include "X86TargetTransformInfo.h" 42 #include "llvm/Analysis/TargetTransformInfo.h" 43 #include "llvm/CodeGen/BasicTTIImpl.h" 44 #include "llvm/CodeGen/CostTable.h" 45 #include "llvm/CodeGen/TargetLowering.h" 46 #include "llvm/IR/IntrinsicInst.h" 47 #include "llvm/Support/Debug.h" 48 49 using namespace llvm; 50 51 #define DEBUG_TYPE "x86tti" 52 53 //===----------------------------------------------------------------------===// 54 // 55 // X86 cost model. 56 // 57 //===----------------------------------------------------------------------===// 58 59 TargetTransformInfo::PopcntSupportKind 60 X86TTIImpl::getPopcntSupport(unsigned TyWidth) { 61 assert(isPowerOf2_32(TyWidth) && "Ty width must be power of 2"); 62 // TODO: Currently the __builtin_popcount() implementation using SSE3 63 // instructions is inefficient. Once the problem is fixed, we should 64 // call ST->hasSSE3() instead of ST->hasPOPCNT(). 65 return ST->hasPOPCNT() ? TTI::PSK_FastHardware : TTI::PSK_Software; 66 } 67 68 llvm::Optional<unsigned> X86TTIImpl::getCacheSize( 69 TargetTransformInfo::CacheLevel Level) const { 70 switch (Level) { 71 case TargetTransformInfo::CacheLevel::L1D: 72 // - Penryn 73 // - Nehalem 74 // - Westmere 75 // - Sandy Bridge 76 // - Ivy Bridge 77 // - Haswell 78 // - Broadwell 79 // - Skylake 80 // - Kabylake 81 return 32 * 1024; // 32 KByte 82 case TargetTransformInfo::CacheLevel::L2D: 83 // - Penryn 84 // - Nehalem 85 // - Westmere 86 // - Sandy Bridge 87 // - Ivy Bridge 88 // - Haswell 89 // - Broadwell 90 // - Skylake 91 // - Kabylake 92 return 256 * 1024; // 256 KByte 93 } 94 95 llvm_unreachable("Unknown TargetTransformInfo::CacheLevel"); 96 } 97 98 llvm::Optional<unsigned> X86TTIImpl::getCacheAssociativity( 99 TargetTransformInfo::CacheLevel Level) const { 100 // - Penryn 101 // - Nehalem 102 // - Westmere 103 // - Sandy Bridge 104 // - Ivy Bridge 105 // - Haswell 106 // - Broadwell 107 // - Skylake 108 // - Kabylake 109 switch (Level) { 110 case TargetTransformInfo::CacheLevel::L1D: 111 LLVM_FALLTHROUGH; 112 case TargetTransformInfo::CacheLevel::L2D: 113 return 8; 114 } 115 116 llvm_unreachable("Unknown TargetTransformInfo::CacheLevel"); 117 } 118 119 unsigned X86TTIImpl::getNumberOfRegisters(unsigned ClassID) const { 120 bool Vector = (ClassID == 1); 121 if (Vector && !ST->hasSSE1()) 122 return 0; 123 124 if (ST->is64Bit()) { 125 if (Vector && ST->hasAVX512()) 126 return 32; 127 return 16; 128 } 129 return 8; 130 } 131 132 unsigned X86TTIImpl::getRegisterBitWidth(bool Vector) const { 133 unsigned PreferVectorWidth = ST->getPreferVectorWidth(); 134 if (Vector) { 135 if (ST->hasAVX512() && PreferVectorWidth >= 512) 136 return 512; 137 if (ST->hasAVX() && PreferVectorWidth >= 256) 138 return 256; 139 if (ST->hasSSE1() && PreferVectorWidth >= 128) 140 return 128; 141 return 0; 142 } 143 144 if (ST->is64Bit()) 145 return 64; 146 147 return 32; 148 } 149 150 unsigned X86TTIImpl::getLoadStoreVecRegBitWidth(unsigned) const { 151 return getRegisterBitWidth(true); 152 } 153 154 unsigned X86TTIImpl::getMaxInterleaveFactor(unsigned VF) { 155 // If the loop will not be vectorized, don't interleave the loop. 156 // Let regular unroll to unroll the loop, which saves the overflow 157 // check and memory check cost. 158 if (VF == 1) 159 return 1; 160 161 if (ST->isAtom()) 162 return 1; 163 164 // Sandybridge and Haswell have multiple execution ports and pipelined 165 // vector units. 166 if (ST->hasAVX()) 167 return 4; 168 169 return 2; 170 } 171 172 int X86TTIImpl::getArithmeticInstrCost(unsigned Opcode, Type *Ty, 173 TTI::OperandValueKind Op1Info, 174 TTI::OperandValueKind Op2Info, 175 TTI::OperandValueProperties Opd1PropInfo, 176 TTI::OperandValueProperties Opd2PropInfo, 177 ArrayRef<const Value *> Args, 178 const Instruction *CxtI) { 179 // Legalize the type. 180 std::pair<int, MVT> LT = TLI->getTypeLegalizationCost(DL, Ty); 181 182 int ISD = TLI->InstructionOpcodeToISD(Opcode); 183 assert(ISD && "Invalid opcode"); 184 185 static const CostTblEntry GLMCostTable[] = { 186 { ISD::FDIV, MVT::f32, 18 }, // divss 187 { ISD::FDIV, MVT::v4f32, 35 }, // divps 188 { ISD::FDIV, MVT::f64, 33 }, // divsd 189 { ISD::FDIV, MVT::v2f64, 65 }, // divpd 190 }; 191 192 if (ST->useGLMDivSqrtCosts()) 193 if (const auto *Entry = CostTableLookup(GLMCostTable, ISD, 194 LT.second)) 195 return LT.first * Entry->Cost; 196 197 static const CostTblEntry SLMCostTable[] = { 198 { ISD::MUL, MVT::v4i32, 11 }, // pmulld 199 { ISD::MUL, MVT::v8i16, 2 }, // pmullw 200 { ISD::MUL, MVT::v16i8, 14 }, // extend/pmullw/trunc sequence. 201 { ISD::FMUL, MVT::f64, 2 }, // mulsd 202 { ISD::FMUL, MVT::v2f64, 4 }, // mulpd 203 { ISD::FMUL, MVT::v4f32, 2 }, // mulps 204 { ISD::FDIV, MVT::f32, 17 }, // divss 205 { ISD::FDIV, MVT::v4f32, 39 }, // divps 206 { ISD::FDIV, MVT::f64, 32 }, // divsd 207 { ISD::FDIV, MVT::v2f64, 69 }, // divpd 208 { ISD::FADD, MVT::v2f64, 2 }, // addpd 209 { ISD::FSUB, MVT::v2f64, 2 }, // subpd 210 // v2i64/v4i64 mul is custom lowered as a series of long: 211 // multiplies(3), shifts(3) and adds(2) 212 // slm muldq version throughput is 2 and addq throughput 4 213 // thus: 3X2 (muldq throughput) + 3X1 (shift throughput) + 214 // 3X4 (addq throughput) = 17 215 { ISD::MUL, MVT::v2i64, 17 }, 216 // slm addq\subq throughput is 4 217 { ISD::ADD, MVT::v2i64, 4 }, 218 { ISD::SUB, MVT::v2i64, 4 }, 219 }; 220 221 if (ST->isSLM()) { 222 if (Args.size() == 2 && ISD == ISD::MUL && LT.second == MVT::v4i32) { 223 // Check if the operands can be shrinked into a smaller datatype. 224 bool Op1Signed = false; 225 unsigned Op1MinSize = BaseT::minRequiredElementSize(Args[0], Op1Signed); 226 bool Op2Signed = false; 227 unsigned Op2MinSize = BaseT::minRequiredElementSize(Args[1], Op2Signed); 228 229 bool signedMode = Op1Signed | Op2Signed; 230 unsigned OpMinSize = std::max(Op1MinSize, Op2MinSize); 231 232 if (OpMinSize <= 7) 233 return LT.first * 3; // pmullw/sext 234 if (!signedMode && OpMinSize <= 8) 235 return LT.first * 3; // pmullw/zext 236 if (OpMinSize <= 15) 237 return LT.first * 5; // pmullw/pmulhw/pshuf 238 if (!signedMode && OpMinSize <= 16) 239 return LT.first * 5; // pmullw/pmulhw/pshuf 240 } 241 242 if (const auto *Entry = CostTableLookup(SLMCostTable, ISD, 243 LT.second)) { 244 return LT.first * Entry->Cost; 245 } 246 } 247 248 if ((ISD == ISD::SDIV || ISD == ISD::SREM || ISD == ISD::UDIV || 249 ISD == ISD::UREM) && 250 (Op2Info == TargetTransformInfo::OK_UniformConstantValue || 251 Op2Info == TargetTransformInfo::OK_NonUniformConstantValue) && 252 Opd2PropInfo == TargetTransformInfo::OP_PowerOf2) { 253 if (ISD == ISD::SDIV || ISD == ISD::SREM) { 254 // On X86, vector signed division by constants power-of-two are 255 // normally expanded to the sequence SRA + SRL + ADD + SRA. 256 // The OperandValue properties may not be the same as that of the previous 257 // operation; conservatively assume OP_None. 258 int Cost = 259 2 * getArithmeticInstrCost(Instruction::AShr, Ty, Op1Info, Op2Info, 260 TargetTransformInfo::OP_None, 261 TargetTransformInfo::OP_None); 262 Cost += getArithmeticInstrCost(Instruction::LShr, Ty, Op1Info, Op2Info, 263 TargetTransformInfo::OP_None, 264 TargetTransformInfo::OP_None); 265 Cost += getArithmeticInstrCost(Instruction::Add, Ty, Op1Info, Op2Info, 266 TargetTransformInfo::OP_None, 267 TargetTransformInfo::OP_None); 268 269 if (ISD == ISD::SREM) { 270 // For SREM: (X % C) is the equivalent of (X - (X/C)*C) 271 Cost += getArithmeticInstrCost(Instruction::Mul, Ty, Op1Info, Op2Info); 272 Cost += getArithmeticInstrCost(Instruction::Sub, Ty, Op1Info, Op2Info); 273 } 274 275 return Cost; 276 } 277 278 // Vector unsigned division/remainder will be simplified to shifts/masks. 279 if (ISD == ISD::UDIV) 280 return getArithmeticInstrCost(Instruction::LShr, Ty, Op1Info, Op2Info, 281 TargetTransformInfo::OP_None, 282 TargetTransformInfo::OP_None); 283 284 else // UREM 285 return getArithmeticInstrCost(Instruction::And, Ty, Op1Info, Op2Info, 286 TargetTransformInfo::OP_None, 287 TargetTransformInfo::OP_None); 288 } 289 290 static const CostTblEntry AVX512BWUniformConstCostTable[] = { 291 { ISD::SHL, MVT::v64i8, 2 }, // psllw + pand. 292 { ISD::SRL, MVT::v64i8, 2 }, // psrlw + pand. 293 { ISD::SRA, MVT::v64i8, 4 }, // psrlw, pand, pxor, psubb. 294 }; 295 296 if (Op2Info == TargetTransformInfo::OK_UniformConstantValue && 297 ST->hasBWI()) { 298 if (const auto *Entry = CostTableLookup(AVX512BWUniformConstCostTable, ISD, 299 LT.second)) 300 return LT.first * Entry->Cost; 301 } 302 303 static const CostTblEntry AVX512UniformConstCostTable[] = { 304 { ISD::SRA, MVT::v2i64, 1 }, 305 { ISD::SRA, MVT::v4i64, 1 }, 306 { ISD::SRA, MVT::v8i64, 1 }, 307 308 { ISD::SHL, MVT::v64i8, 4 }, // psllw + pand. 309 { ISD::SRL, MVT::v64i8, 4 }, // psrlw + pand. 310 { ISD::SRA, MVT::v64i8, 8 }, // psrlw, pand, pxor, psubb. 311 }; 312 313 if (Op2Info == TargetTransformInfo::OK_UniformConstantValue && 314 ST->hasAVX512()) { 315 if (const auto *Entry = CostTableLookup(AVX512UniformConstCostTable, ISD, 316 LT.second)) 317 return LT.first * Entry->Cost; 318 } 319 320 static const CostTblEntry AVX2UniformConstCostTable[] = { 321 { ISD::SHL, MVT::v32i8, 2 }, // psllw + pand. 322 { ISD::SRL, MVT::v32i8, 2 }, // psrlw + pand. 323 { ISD::SRA, MVT::v32i8, 4 }, // psrlw, pand, pxor, psubb. 324 325 { ISD::SRA, MVT::v4i64, 4 }, // 2 x psrad + shuffle. 326 }; 327 328 if (Op2Info == TargetTransformInfo::OK_UniformConstantValue && 329 ST->hasAVX2()) { 330 if (const auto *Entry = CostTableLookup(AVX2UniformConstCostTable, ISD, 331 LT.second)) 332 return LT.first * Entry->Cost; 333 } 334 335 static const CostTblEntry SSE2UniformConstCostTable[] = { 336 { ISD::SHL, MVT::v16i8, 2 }, // psllw + pand. 337 { ISD::SRL, MVT::v16i8, 2 }, // psrlw + pand. 338 { ISD::SRA, MVT::v16i8, 4 }, // psrlw, pand, pxor, psubb. 339 340 { ISD::SHL, MVT::v32i8, 4+2 }, // 2*(psllw + pand) + split. 341 { ISD::SRL, MVT::v32i8, 4+2 }, // 2*(psrlw + pand) + split. 342 { ISD::SRA, MVT::v32i8, 8+2 }, // 2*(psrlw, pand, pxor, psubb) + split. 343 }; 344 345 // XOP has faster vXi8 shifts. 346 if (Op2Info == TargetTransformInfo::OK_UniformConstantValue && 347 ST->hasSSE2() && !ST->hasXOP()) { 348 if (const auto *Entry = 349 CostTableLookup(SSE2UniformConstCostTable, ISD, LT.second)) 350 return LT.first * Entry->Cost; 351 } 352 353 static const CostTblEntry AVX512BWConstCostTable[] = { 354 { ISD::SDIV, MVT::v64i8, 14 }, // 2*ext+2*pmulhw sequence 355 { ISD::SREM, MVT::v64i8, 16 }, // 2*ext+2*pmulhw+mul+sub sequence 356 { ISD::UDIV, MVT::v64i8, 14 }, // 2*ext+2*pmulhw sequence 357 { ISD::UREM, MVT::v64i8, 16 }, // 2*ext+2*pmulhw+mul+sub sequence 358 { ISD::SDIV, MVT::v32i16, 6 }, // vpmulhw sequence 359 { ISD::SREM, MVT::v32i16, 8 }, // vpmulhw+mul+sub sequence 360 { ISD::UDIV, MVT::v32i16, 6 }, // vpmulhuw sequence 361 { ISD::UREM, MVT::v32i16, 8 }, // vpmulhuw+mul+sub sequence 362 }; 363 364 if ((Op2Info == TargetTransformInfo::OK_UniformConstantValue || 365 Op2Info == TargetTransformInfo::OK_NonUniformConstantValue) && 366 ST->hasBWI()) { 367 if (const auto *Entry = 368 CostTableLookup(AVX512BWConstCostTable, ISD, LT.second)) 369 return LT.first * Entry->Cost; 370 } 371 372 static const CostTblEntry AVX512ConstCostTable[] = { 373 { ISD::SDIV, MVT::v16i32, 15 }, // vpmuldq sequence 374 { ISD::SREM, MVT::v16i32, 17 }, // vpmuldq+mul+sub sequence 375 { ISD::UDIV, MVT::v16i32, 15 }, // vpmuludq sequence 376 { ISD::UREM, MVT::v16i32, 17 }, // vpmuludq+mul+sub sequence 377 { ISD::SDIV, MVT::v64i8, 28 }, // 4*ext+4*pmulhw sequence 378 { ISD::SREM, MVT::v64i8, 32 }, // 4*ext+4*pmulhw+mul+sub sequence 379 { ISD::UDIV, MVT::v64i8, 28 }, // 4*ext+4*pmulhw sequence 380 { ISD::UREM, MVT::v64i8, 32 }, // 4*ext+4*pmulhw+mul+sub sequence 381 { ISD::SDIV, MVT::v32i16, 12 }, // 2*vpmulhw sequence 382 { ISD::SREM, MVT::v32i16, 16 }, // 2*vpmulhw+mul+sub sequence 383 { ISD::UDIV, MVT::v32i16, 12 }, // 2*vpmulhuw sequence 384 { ISD::UREM, MVT::v32i16, 16 }, // 2*vpmulhuw+mul+sub sequence 385 }; 386 387 if ((Op2Info == TargetTransformInfo::OK_UniformConstantValue || 388 Op2Info == TargetTransformInfo::OK_NonUniformConstantValue) && 389 ST->hasAVX512()) { 390 if (const auto *Entry = 391 CostTableLookup(AVX512ConstCostTable, ISD, LT.second)) 392 return LT.first * Entry->Cost; 393 } 394 395 static const CostTblEntry AVX2ConstCostTable[] = { 396 { ISD::SDIV, MVT::v32i8, 14 }, // 2*ext+2*pmulhw sequence 397 { ISD::SREM, MVT::v32i8, 16 }, // 2*ext+2*pmulhw+mul+sub sequence 398 { ISD::UDIV, MVT::v32i8, 14 }, // 2*ext+2*pmulhw sequence 399 { ISD::UREM, MVT::v32i8, 16 }, // 2*ext+2*pmulhw+mul+sub sequence 400 { ISD::SDIV, MVT::v16i16, 6 }, // vpmulhw sequence 401 { ISD::SREM, MVT::v16i16, 8 }, // vpmulhw+mul+sub sequence 402 { ISD::UDIV, MVT::v16i16, 6 }, // vpmulhuw sequence 403 { ISD::UREM, MVT::v16i16, 8 }, // vpmulhuw+mul+sub sequence 404 { ISD::SDIV, MVT::v8i32, 15 }, // vpmuldq sequence 405 { ISD::SREM, MVT::v8i32, 19 }, // vpmuldq+mul+sub sequence 406 { ISD::UDIV, MVT::v8i32, 15 }, // vpmuludq sequence 407 { ISD::UREM, MVT::v8i32, 19 }, // vpmuludq+mul+sub sequence 408 }; 409 410 if ((Op2Info == TargetTransformInfo::OK_UniformConstantValue || 411 Op2Info == TargetTransformInfo::OK_NonUniformConstantValue) && 412 ST->hasAVX2()) { 413 if (const auto *Entry = CostTableLookup(AVX2ConstCostTable, ISD, LT.second)) 414 return LT.first * Entry->Cost; 415 } 416 417 static const CostTblEntry SSE2ConstCostTable[] = { 418 { ISD::SDIV, MVT::v32i8, 28+2 }, // 4*ext+4*pmulhw sequence + split. 419 { ISD::SREM, MVT::v32i8, 32+2 }, // 4*ext+4*pmulhw+mul+sub sequence + split. 420 { ISD::SDIV, MVT::v16i8, 14 }, // 2*ext+2*pmulhw sequence 421 { ISD::SREM, MVT::v16i8, 16 }, // 2*ext+2*pmulhw+mul+sub sequence 422 { ISD::UDIV, MVT::v32i8, 28+2 }, // 4*ext+4*pmulhw sequence + split. 423 { ISD::UREM, MVT::v32i8, 32+2 }, // 4*ext+4*pmulhw+mul+sub sequence + split. 424 { ISD::UDIV, MVT::v16i8, 14 }, // 2*ext+2*pmulhw sequence 425 { ISD::UREM, MVT::v16i8, 16 }, // 2*ext+2*pmulhw+mul+sub sequence 426 { ISD::SDIV, MVT::v16i16, 12+2 }, // 2*pmulhw sequence + split. 427 { ISD::SREM, MVT::v16i16, 16+2 }, // 2*pmulhw+mul+sub sequence + split. 428 { ISD::SDIV, MVT::v8i16, 6 }, // pmulhw sequence 429 { ISD::SREM, MVT::v8i16, 8 }, // pmulhw+mul+sub sequence 430 { ISD::UDIV, MVT::v16i16, 12+2 }, // 2*pmulhuw sequence + split. 431 { ISD::UREM, MVT::v16i16, 16+2 }, // 2*pmulhuw+mul+sub sequence + split. 432 { ISD::UDIV, MVT::v8i16, 6 }, // pmulhuw sequence 433 { ISD::UREM, MVT::v8i16, 8 }, // pmulhuw+mul+sub sequence 434 { ISD::SDIV, MVT::v8i32, 38+2 }, // 2*pmuludq sequence + split. 435 { ISD::SREM, MVT::v8i32, 48+2 }, // 2*pmuludq+mul+sub sequence + split. 436 { ISD::SDIV, MVT::v4i32, 19 }, // pmuludq sequence 437 { ISD::SREM, MVT::v4i32, 24 }, // pmuludq+mul+sub sequence 438 { ISD::UDIV, MVT::v8i32, 30+2 }, // 2*pmuludq sequence + split. 439 { ISD::UREM, MVT::v8i32, 40+2 }, // 2*pmuludq+mul+sub sequence + split. 440 { ISD::UDIV, MVT::v4i32, 15 }, // pmuludq sequence 441 { ISD::UREM, MVT::v4i32, 20 }, // pmuludq+mul+sub sequence 442 }; 443 444 if ((Op2Info == TargetTransformInfo::OK_UniformConstantValue || 445 Op2Info == TargetTransformInfo::OK_NonUniformConstantValue) && 446 ST->hasSSE2()) { 447 // pmuldq sequence. 448 if (ISD == ISD::SDIV && LT.second == MVT::v8i32 && ST->hasAVX()) 449 return LT.first * 32; 450 if (ISD == ISD::SREM && LT.second == MVT::v8i32 && ST->hasAVX()) 451 return LT.first * 38; 452 if (ISD == ISD::SDIV && LT.second == MVT::v4i32 && ST->hasSSE41()) 453 return LT.first * 15; 454 if (ISD == ISD::SREM && LT.second == MVT::v4i32 && ST->hasSSE41()) 455 return LT.first * 20; 456 457 if (const auto *Entry = CostTableLookup(SSE2ConstCostTable, ISD, LT.second)) 458 return LT.first * Entry->Cost; 459 } 460 461 static const CostTblEntry AVX512BWShiftCostTable[] = { 462 { ISD::SHL, MVT::v8i16, 1 }, // vpsllvw 463 { ISD::SRL, MVT::v8i16, 1 }, // vpsrlvw 464 { ISD::SRA, MVT::v8i16, 1 }, // vpsravw 465 466 { ISD::SHL, MVT::v16i16, 1 }, // vpsllvw 467 { ISD::SRL, MVT::v16i16, 1 }, // vpsrlvw 468 { ISD::SRA, MVT::v16i16, 1 }, // vpsravw 469 470 { ISD::SHL, MVT::v32i16, 1 }, // vpsllvw 471 { ISD::SRL, MVT::v32i16, 1 }, // vpsrlvw 472 { ISD::SRA, MVT::v32i16, 1 }, // vpsravw 473 }; 474 475 if (ST->hasBWI()) 476 if (const auto *Entry = CostTableLookup(AVX512BWShiftCostTable, ISD, LT.second)) 477 return LT.first * Entry->Cost; 478 479 static const CostTblEntry AVX2UniformCostTable[] = { 480 // Uniform splats are cheaper for the following instructions. 481 { ISD::SHL, MVT::v16i16, 1 }, // psllw. 482 { ISD::SRL, MVT::v16i16, 1 }, // psrlw. 483 { ISD::SRA, MVT::v16i16, 1 }, // psraw. 484 { ISD::SHL, MVT::v32i16, 2 }, // 2*psllw. 485 { ISD::SRL, MVT::v32i16, 2 }, // 2*psrlw. 486 { ISD::SRA, MVT::v32i16, 2 }, // 2*psraw. 487 }; 488 489 if (ST->hasAVX2() && 490 ((Op2Info == TargetTransformInfo::OK_UniformConstantValue) || 491 (Op2Info == TargetTransformInfo::OK_UniformValue))) { 492 if (const auto *Entry = 493 CostTableLookup(AVX2UniformCostTable, ISD, LT.second)) 494 return LT.first * Entry->Cost; 495 } 496 497 static const CostTblEntry SSE2UniformCostTable[] = { 498 // Uniform splats are cheaper for the following instructions. 499 { ISD::SHL, MVT::v8i16, 1 }, // psllw. 500 { ISD::SHL, MVT::v4i32, 1 }, // pslld 501 { ISD::SHL, MVT::v2i64, 1 }, // psllq. 502 503 { ISD::SRL, MVT::v8i16, 1 }, // psrlw. 504 { ISD::SRL, MVT::v4i32, 1 }, // psrld. 505 { ISD::SRL, MVT::v2i64, 1 }, // psrlq. 506 507 { ISD::SRA, MVT::v8i16, 1 }, // psraw. 508 { ISD::SRA, MVT::v4i32, 1 }, // psrad. 509 }; 510 511 if (ST->hasSSE2() && 512 ((Op2Info == TargetTransformInfo::OK_UniformConstantValue) || 513 (Op2Info == TargetTransformInfo::OK_UniformValue))) { 514 if (const auto *Entry = 515 CostTableLookup(SSE2UniformCostTable, ISD, LT.second)) 516 return LT.first * Entry->Cost; 517 } 518 519 static const CostTblEntry AVX512DQCostTable[] = { 520 { ISD::MUL, MVT::v2i64, 1 }, 521 { ISD::MUL, MVT::v4i64, 1 }, 522 { ISD::MUL, MVT::v8i64, 1 } 523 }; 524 525 // Look for AVX512DQ lowering tricks for custom cases. 526 if (ST->hasDQI()) 527 if (const auto *Entry = CostTableLookup(AVX512DQCostTable, ISD, LT.second)) 528 return LT.first * Entry->Cost; 529 530 static const CostTblEntry AVX512BWCostTable[] = { 531 { ISD::SHL, MVT::v64i8, 11 }, // vpblendvb sequence. 532 { ISD::SRL, MVT::v64i8, 11 }, // vpblendvb sequence. 533 { ISD::SRA, MVT::v64i8, 24 }, // vpblendvb sequence. 534 535 { ISD::MUL, MVT::v64i8, 11 }, // extend/pmullw/trunc sequence. 536 { ISD::MUL, MVT::v32i8, 4 }, // extend/pmullw/trunc sequence. 537 { ISD::MUL, MVT::v16i8, 4 }, // extend/pmullw/trunc sequence. 538 }; 539 540 // Look for AVX512BW lowering tricks for custom cases. 541 if (ST->hasBWI()) 542 if (const auto *Entry = CostTableLookup(AVX512BWCostTable, ISD, LT.second)) 543 return LT.first * Entry->Cost; 544 545 static const CostTblEntry AVX512CostTable[] = { 546 { ISD::SHL, MVT::v16i32, 1 }, 547 { ISD::SRL, MVT::v16i32, 1 }, 548 { ISD::SRA, MVT::v16i32, 1 }, 549 550 { ISD::SHL, MVT::v8i64, 1 }, 551 { ISD::SRL, MVT::v8i64, 1 }, 552 553 { ISD::SRA, MVT::v2i64, 1 }, 554 { ISD::SRA, MVT::v4i64, 1 }, 555 { ISD::SRA, MVT::v8i64, 1 }, 556 557 { ISD::MUL, MVT::v64i8, 26 }, // extend/pmullw/trunc sequence. 558 { ISD::MUL, MVT::v32i8, 13 }, // extend/pmullw/trunc sequence. 559 { ISD::MUL, MVT::v16i8, 5 }, // extend/pmullw/trunc sequence. 560 { ISD::MUL, MVT::v16i32, 1 }, // pmulld (Skylake from agner.org) 561 { ISD::MUL, MVT::v8i32, 1 }, // pmulld (Skylake from agner.org) 562 { ISD::MUL, MVT::v4i32, 1 }, // pmulld (Skylake from agner.org) 563 { ISD::MUL, MVT::v8i64, 8 }, // 3*pmuludq/3*shift/2*add 564 565 { ISD::FADD, MVT::v8f64, 1 }, // Skylake from http://www.agner.org/ 566 { ISD::FSUB, MVT::v8f64, 1 }, // Skylake from http://www.agner.org/ 567 { ISD::FMUL, MVT::v8f64, 1 }, // Skylake from http://www.agner.org/ 568 569 { ISD::FADD, MVT::v16f32, 1 }, // Skylake from http://www.agner.org/ 570 { ISD::FSUB, MVT::v16f32, 1 }, // Skylake from http://www.agner.org/ 571 { ISD::FMUL, MVT::v16f32, 1 }, // Skylake from http://www.agner.org/ 572 }; 573 574 if (ST->hasAVX512()) 575 if (const auto *Entry = CostTableLookup(AVX512CostTable, ISD, LT.second)) 576 return LT.first * Entry->Cost; 577 578 static const CostTblEntry AVX2ShiftCostTable[] = { 579 // Shifts on v4i64/v8i32 on AVX2 is legal even though we declare to 580 // customize them to detect the cases where shift amount is a scalar one. 581 { ISD::SHL, MVT::v4i32, 1 }, 582 { ISD::SRL, MVT::v4i32, 1 }, 583 { ISD::SRA, MVT::v4i32, 1 }, 584 { ISD::SHL, MVT::v8i32, 1 }, 585 { ISD::SRL, MVT::v8i32, 1 }, 586 { ISD::SRA, MVT::v8i32, 1 }, 587 { ISD::SHL, MVT::v2i64, 1 }, 588 { ISD::SRL, MVT::v2i64, 1 }, 589 { ISD::SHL, MVT::v4i64, 1 }, 590 { ISD::SRL, MVT::v4i64, 1 }, 591 }; 592 593 if (ST->hasAVX512()) { 594 if (ISD == ISD::SHL && LT.second == MVT::v32i16 && 595 (Op2Info == TargetTransformInfo::OK_UniformConstantValue || 596 Op2Info == TargetTransformInfo::OK_NonUniformConstantValue)) 597 // On AVX512, a packed v32i16 shift left by a constant build_vector 598 // is lowered into a vector multiply (vpmullw). 599 return getArithmeticInstrCost(Instruction::Mul, Ty, Op1Info, Op2Info, 600 TargetTransformInfo::OP_None, 601 TargetTransformInfo::OP_None); 602 } 603 604 // Look for AVX2 lowering tricks. 605 if (ST->hasAVX2()) { 606 if (ISD == ISD::SHL && LT.second == MVT::v16i16 && 607 (Op2Info == TargetTransformInfo::OK_UniformConstantValue || 608 Op2Info == TargetTransformInfo::OK_NonUniformConstantValue)) 609 // On AVX2, a packed v16i16 shift left by a constant build_vector 610 // is lowered into a vector multiply (vpmullw). 611 return getArithmeticInstrCost(Instruction::Mul, Ty, Op1Info, Op2Info, 612 TargetTransformInfo::OP_None, 613 TargetTransformInfo::OP_None); 614 615 if (const auto *Entry = CostTableLookup(AVX2ShiftCostTable, ISD, LT.second)) 616 return LT.first * Entry->Cost; 617 } 618 619 static const CostTblEntry XOPShiftCostTable[] = { 620 // 128bit shifts take 1cy, but right shifts require negation beforehand. 621 { ISD::SHL, MVT::v16i8, 1 }, 622 { ISD::SRL, MVT::v16i8, 2 }, 623 { ISD::SRA, MVT::v16i8, 2 }, 624 { ISD::SHL, MVT::v8i16, 1 }, 625 { ISD::SRL, MVT::v8i16, 2 }, 626 { ISD::SRA, MVT::v8i16, 2 }, 627 { ISD::SHL, MVT::v4i32, 1 }, 628 { ISD::SRL, MVT::v4i32, 2 }, 629 { ISD::SRA, MVT::v4i32, 2 }, 630 { ISD::SHL, MVT::v2i64, 1 }, 631 { ISD::SRL, MVT::v2i64, 2 }, 632 { ISD::SRA, MVT::v2i64, 2 }, 633 // 256bit shifts require splitting if AVX2 didn't catch them above. 634 { ISD::SHL, MVT::v32i8, 2+2 }, 635 { ISD::SRL, MVT::v32i8, 4+2 }, 636 { ISD::SRA, MVT::v32i8, 4+2 }, 637 { ISD::SHL, MVT::v16i16, 2+2 }, 638 { ISD::SRL, MVT::v16i16, 4+2 }, 639 { ISD::SRA, MVT::v16i16, 4+2 }, 640 { ISD::SHL, MVT::v8i32, 2+2 }, 641 { ISD::SRL, MVT::v8i32, 4+2 }, 642 { ISD::SRA, MVT::v8i32, 4+2 }, 643 { ISD::SHL, MVT::v4i64, 2+2 }, 644 { ISD::SRL, MVT::v4i64, 4+2 }, 645 { ISD::SRA, MVT::v4i64, 4+2 }, 646 }; 647 648 // Look for XOP lowering tricks. 649 if (ST->hasXOP()) { 650 // If the right shift is constant then we'll fold the negation so 651 // it's as cheap as a left shift. 652 int ShiftISD = ISD; 653 if ((ShiftISD == ISD::SRL || ShiftISD == ISD::SRA) && 654 (Op2Info == TargetTransformInfo::OK_UniformConstantValue || 655 Op2Info == TargetTransformInfo::OK_NonUniformConstantValue)) 656 ShiftISD = ISD::SHL; 657 if (const auto *Entry = 658 CostTableLookup(XOPShiftCostTable, ShiftISD, LT.second)) 659 return LT.first * Entry->Cost; 660 } 661 662 static const CostTblEntry SSE2UniformShiftCostTable[] = { 663 // Uniform splats are cheaper for the following instructions. 664 { ISD::SHL, MVT::v16i16, 2+2 }, // 2*psllw + split. 665 { ISD::SHL, MVT::v8i32, 2+2 }, // 2*pslld + split. 666 { ISD::SHL, MVT::v4i64, 2+2 }, // 2*psllq + split. 667 668 { ISD::SRL, MVT::v16i16, 2+2 }, // 2*psrlw + split. 669 { ISD::SRL, MVT::v8i32, 2+2 }, // 2*psrld + split. 670 { ISD::SRL, MVT::v4i64, 2+2 }, // 2*psrlq + split. 671 672 { ISD::SRA, MVT::v16i16, 2+2 }, // 2*psraw + split. 673 { ISD::SRA, MVT::v8i32, 2+2 }, // 2*psrad + split. 674 { ISD::SRA, MVT::v2i64, 4 }, // 2*psrad + shuffle. 675 { ISD::SRA, MVT::v4i64, 8+2 }, // 2*(2*psrad + shuffle) + split. 676 }; 677 678 if (ST->hasSSE2() && 679 ((Op2Info == TargetTransformInfo::OK_UniformConstantValue) || 680 (Op2Info == TargetTransformInfo::OK_UniformValue))) { 681 682 // Handle AVX2 uniform v4i64 ISD::SRA, it's not worth a table. 683 if (ISD == ISD::SRA && LT.second == MVT::v4i64 && ST->hasAVX2()) 684 return LT.first * 4; // 2*psrad + shuffle. 685 686 if (const auto *Entry = 687 CostTableLookup(SSE2UniformShiftCostTable, ISD, LT.second)) 688 return LT.first * Entry->Cost; 689 } 690 691 if (ISD == ISD::SHL && 692 Op2Info == TargetTransformInfo::OK_NonUniformConstantValue) { 693 MVT VT = LT.second; 694 // Vector shift left by non uniform constant can be lowered 695 // into vector multiply. 696 if (((VT == MVT::v8i16 || VT == MVT::v4i32) && ST->hasSSE2()) || 697 ((VT == MVT::v16i16 || VT == MVT::v8i32) && ST->hasAVX())) 698 ISD = ISD::MUL; 699 } 700 701 static const CostTblEntry AVX2CostTable[] = { 702 { ISD::SHL, MVT::v32i8, 11 }, // vpblendvb sequence. 703 { ISD::SHL, MVT::v64i8, 22 }, // 2*vpblendvb sequence. 704 { ISD::SHL, MVT::v16i16, 10 }, // extend/vpsrlvd/pack sequence. 705 { ISD::SHL, MVT::v32i16, 20 }, // 2*extend/vpsrlvd/pack sequence. 706 707 { ISD::SRL, MVT::v32i8, 11 }, // vpblendvb sequence. 708 { ISD::SRL, MVT::v64i8, 22 }, // 2*vpblendvb sequence. 709 { ISD::SRL, MVT::v16i16, 10 }, // extend/vpsrlvd/pack sequence. 710 { ISD::SRL, MVT::v32i16, 20 }, // 2*extend/vpsrlvd/pack sequence. 711 712 { ISD::SRA, MVT::v32i8, 24 }, // vpblendvb sequence. 713 { ISD::SRA, MVT::v64i8, 48 }, // 2*vpblendvb sequence. 714 { ISD::SRA, MVT::v16i16, 10 }, // extend/vpsravd/pack sequence. 715 { ISD::SRA, MVT::v32i16, 20 }, // 2*extend/vpsravd/pack sequence. 716 { ISD::SRA, MVT::v2i64, 4 }, // srl/xor/sub sequence. 717 { ISD::SRA, MVT::v4i64, 4 }, // srl/xor/sub sequence. 718 719 { ISD::SUB, MVT::v32i8, 1 }, // psubb 720 { ISD::ADD, MVT::v32i8, 1 }, // paddb 721 { ISD::SUB, MVT::v16i16, 1 }, // psubw 722 { ISD::ADD, MVT::v16i16, 1 }, // paddw 723 { ISD::SUB, MVT::v8i32, 1 }, // psubd 724 { ISD::ADD, MVT::v8i32, 1 }, // paddd 725 { ISD::SUB, MVT::v4i64, 1 }, // psubq 726 { ISD::ADD, MVT::v4i64, 1 }, // paddq 727 728 { ISD::MUL, MVT::v32i8, 17 }, // extend/pmullw/trunc sequence. 729 { ISD::MUL, MVT::v16i8, 7 }, // extend/pmullw/trunc sequence. 730 { ISD::MUL, MVT::v16i16, 1 }, // pmullw 731 { ISD::MUL, MVT::v8i32, 2 }, // pmulld (Haswell from agner.org) 732 { ISD::MUL, MVT::v4i64, 8 }, // 3*pmuludq/3*shift/2*add 733 734 { ISD::FADD, MVT::v4f64, 1 }, // Haswell from http://www.agner.org/ 735 { ISD::FADD, MVT::v8f32, 1 }, // Haswell from http://www.agner.org/ 736 { ISD::FSUB, MVT::v4f64, 1 }, // Haswell from http://www.agner.org/ 737 { ISD::FSUB, MVT::v8f32, 1 }, // Haswell from http://www.agner.org/ 738 { ISD::FMUL, MVT::v4f64, 1 }, // Haswell from http://www.agner.org/ 739 { ISD::FMUL, MVT::v8f32, 1 }, // Haswell from http://www.agner.org/ 740 741 { ISD::FDIV, MVT::f32, 7 }, // Haswell from http://www.agner.org/ 742 { ISD::FDIV, MVT::v4f32, 7 }, // Haswell from http://www.agner.org/ 743 { ISD::FDIV, MVT::v8f32, 14 }, // Haswell from http://www.agner.org/ 744 { ISD::FDIV, MVT::f64, 14 }, // Haswell from http://www.agner.org/ 745 { ISD::FDIV, MVT::v2f64, 14 }, // Haswell from http://www.agner.org/ 746 { ISD::FDIV, MVT::v4f64, 28 }, // Haswell from http://www.agner.org/ 747 }; 748 749 // Look for AVX2 lowering tricks for custom cases. 750 if (ST->hasAVX2()) 751 if (const auto *Entry = CostTableLookup(AVX2CostTable, ISD, LT.second)) 752 return LT.first * Entry->Cost; 753 754 static const CostTblEntry AVX1CostTable[] = { 755 // We don't have to scalarize unsupported ops. We can issue two half-sized 756 // operations and we only need to extract the upper YMM half. 757 // Two ops + 1 extract + 1 insert = 4. 758 { ISD::MUL, MVT::v16i16, 4 }, 759 { ISD::MUL, MVT::v8i32, 4 }, 760 { ISD::SUB, MVT::v32i8, 4 }, 761 { ISD::ADD, MVT::v32i8, 4 }, 762 { ISD::SUB, MVT::v16i16, 4 }, 763 { ISD::ADD, MVT::v16i16, 4 }, 764 { ISD::SUB, MVT::v8i32, 4 }, 765 { ISD::ADD, MVT::v8i32, 4 }, 766 { ISD::SUB, MVT::v4i64, 4 }, 767 { ISD::ADD, MVT::v4i64, 4 }, 768 769 // A v4i64 multiply is custom lowered as two split v2i64 vectors that then 770 // are lowered as a series of long multiplies(3), shifts(3) and adds(2) 771 // Because we believe v4i64 to be a legal type, we must also include the 772 // extract+insert in the cost table. Therefore, the cost here is 18 773 // instead of 8. 774 { ISD::MUL, MVT::v4i64, 18 }, 775 776 { ISD::MUL, MVT::v32i8, 26 }, // extend/pmullw/trunc sequence. 777 778 { ISD::FDIV, MVT::f32, 14 }, // SNB from http://www.agner.org/ 779 { ISD::FDIV, MVT::v4f32, 14 }, // SNB from http://www.agner.org/ 780 { ISD::FDIV, MVT::v8f32, 28 }, // SNB from http://www.agner.org/ 781 { ISD::FDIV, MVT::f64, 22 }, // SNB from http://www.agner.org/ 782 { ISD::FDIV, MVT::v2f64, 22 }, // SNB from http://www.agner.org/ 783 { ISD::FDIV, MVT::v4f64, 44 }, // SNB from http://www.agner.org/ 784 }; 785 786 if (ST->hasAVX()) 787 if (const auto *Entry = CostTableLookup(AVX1CostTable, ISD, LT.second)) 788 return LT.first * Entry->Cost; 789 790 static const CostTblEntry SSE42CostTable[] = { 791 { ISD::FADD, MVT::f64, 1 }, // Nehalem from http://www.agner.org/ 792 { ISD::FADD, MVT::f32, 1 }, // Nehalem from http://www.agner.org/ 793 { ISD::FADD, MVT::v2f64, 1 }, // Nehalem from http://www.agner.org/ 794 { ISD::FADD, MVT::v4f32, 1 }, // Nehalem from http://www.agner.org/ 795 796 { ISD::FSUB, MVT::f64, 1 }, // Nehalem from http://www.agner.org/ 797 { ISD::FSUB, MVT::f32 , 1 }, // Nehalem from http://www.agner.org/ 798 { ISD::FSUB, MVT::v2f64, 1 }, // Nehalem from http://www.agner.org/ 799 { ISD::FSUB, MVT::v4f32, 1 }, // Nehalem from http://www.agner.org/ 800 801 { ISD::FMUL, MVT::f64, 1 }, // Nehalem from http://www.agner.org/ 802 { ISD::FMUL, MVT::f32, 1 }, // Nehalem from http://www.agner.org/ 803 { ISD::FMUL, MVT::v2f64, 1 }, // Nehalem from http://www.agner.org/ 804 { ISD::FMUL, MVT::v4f32, 1 }, // Nehalem from http://www.agner.org/ 805 806 { ISD::FDIV, MVT::f32, 14 }, // Nehalem from http://www.agner.org/ 807 { ISD::FDIV, MVT::v4f32, 14 }, // Nehalem from http://www.agner.org/ 808 { ISD::FDIV, MVT::f64, 22 }, // Nehalem from http://www.agner.org/ 809 { ISD::FDIV, MVT::v2f64, 22 }, // Nehalem from http://www.agner.org/ 810 }; 811 812 if (ST->hasSSE42()) 813 if (const auto *Entry = CostTableLookup(SSE42CostTable, ISD, LT.second)) 814 return LT.first * Entry->Cost; 815 816 static const CostTblEntry SSE41CostTable[] = { 817 { ISD::SHL, MVT::v16i8, 11 }, // pblendvb sequence. 818 { ISD::SHL, MVT::v32i8, 2*11+2 }, // pblendvb sequence + split. 819 { ISD::SHL, MVT::v8i16, 14 }, // pblendvb sequence. 820 { ISD::SHL, MVT::v16i16, 2*14+2 }, // pblendvb sequence + split. 821 { ISD::SHL, MVT::v4i32, 4 }, // pslld/paddd/cvttps2dq/pmulld 822 { ISD::SHL, MVT::v8i32, 2*4+2 }, // pslld/paddd/cvttps2dq/pmulld + split 823 824 { ISD::SRL, MVT::v16i8, 12 }, // pblendvb sequence. 825 { ISD::SRL, MVT::v32i8, 2*12+2 }, // pblendvb sequence + split. 826 { ISD::SRL, MVT::v8i16, 14 }, // pblendvb sequence. 827 { ISD::SRL, MVT::v16i16, 2*14+2 }, // pblendvb sequence + split. 828 { ISD::SRL, MVT::v4i32, 11 }, // Shift each lane + blend. 829 { ISD::SRL, MVT::v8i32, 2*11+2 }, // Shift each lane + blend + split. 830 831 { ISD::SRA, MVT::v16i8, 24 }, // pblendvb sequence. 832 { ISD::SRA, MVT::v32i8, 2*24+2 }, // pblendvb sequence + split. 833 { ISD::SRA, MVT::v8i16, 14 }, // pblendvb sequence. 834 { ISD::SRA, MVT::v16i16, 2*14+2 }, // pblendvb sequence + split. 835 { ISD::SRA, MVT::v4i32, 12 }, // Shift each lane + blend. 836 { ISD::SRA, MVT::v8i32, 2*12+2 }, // Shift each lane + blend + split. 837 838 { ISD::MUL, MVT::v4i32, 2 } // pmulld (Nehalem from agner.org) 839 }; 840 841 if (ST->hasSSE41()) 842 if (const auto *Entry = CostTableLookup(SSE41CostTable, ISD, LT.second)) 843 return LT.first * Entry->Cost; 844 845 static const CostTblEntry SSE2CostTable[] = { 846 // We don't correctly identify costs of casts because they are marked as 847 // custom. 848 { ISD::SHL, MVT::v16i8, 26 }, // cmpgtb sequence. 849 { ISD::SHL, MVT::v8i16, 32 }, // cmpgtb sequence. 850 { ISD::SHL, MVT::v4i32, 2*5 }, // We optimized this using mul. 851 { ISD::SHL, MVT::v2i64, 4 }, // splat+shuffle sequence. 852 { ISD::SHL, MVT::v4i64, 2*4+2 }, // splat+shuffle sequence + split. 853 854 { ISD::SRL, MVT::v16i8, 26 }, // cmpgtb sequence. 855 { ISD::SRL, MVT::v8i16, 32 }, // cmpgtb sequence. 856 { ISD::SRL, MVT::v4i32, 16 }, // Shift each lane + blend. 857 { ISD::SRL, MVT::v2i64, 4 }, // splat+shuffle sequence. 858 { ISD::SRL, MVT::v4i64, 2*4+2 }, // splat+shuffle sequence + split. 859 860 { ISD::SRA, MVT::v16i8, 54 }, // unpacked cmpgtb sequence. 861 { ISD::SRA, MVT::v8i16, 32 }, // cmpgtb sequence. 862 { ISD::SRA, MVT::v4i32, 16 }, // Shift each lane + blend. 863 { ISD::SRA, MVT::v2i64, 12 }, // srl/xor/sub sequence. 864 { ISD::SRA, MVT::v4i64, 2*12+2 }, // srl/xor/sub sequence+split. 865 866 { ISD::MUL, MVT::v16i8, 12 }, // extend/pmullw/trunc sequence. 867 { ISD::MUL, MVT::v8i16, 1 }, // pmullw 868 { ISD::MUL, MVT::v4i32, 6 }, // 3*pmuludq/4*shuffle 869 { ISD::MUL, MVT::v2i64, 8 }, // 3*pmuludq/3*shift/2*add 870 871 { ISD::FDIV, MVT::f32, 23 }, // Pentium IV from http://www.agner.org/ 872 { ISD::FDIV, MVT::v4f32, 39 }, // Pentium IV from http://www.agner.org/ 873 { ISD::FDIV, MVT::f64, 38 }, // Pentium IV from http://www.agner.org/ 874 { ISD::FDIV, MVT::v2f64, 69 }, // Pentium IV from http://www.agner.org/ 875 876 { ISD::FADD, MVT::f32, 2 }, // Pentium IV from http://www.agner.org/ 877 { ISD::FADD, MVT::f64, 2 }, // Pentium IV from http://www.agner.org/ 878 879 { ISD::FSUB, MVT::f32, 2 }, // Pentium IV from http://www.agner.org/ 880 { ISD::FSUB, MVT::f64, 2 }, // Pentium IV from http://www.agner.org/ 881 }; 882 883 if (ST->hasSSE2()) 884 if (const auto *Entry = CostTableLookup(SSE2CostTable, ISD, LT.second)) 885 return LT.first * Entry->Cost; 886 887 static const CostTblEntry SSE1CostTable[] = { 888 { ISD::FDIV, MVT::f32, 17 }, // Pentium III from http://www.agner.org/ 889 { ISD::FDIV, MVT::v4f32, 34 }, // Pentium III from http://www.agner.org/ 890 891 { ISD::FADD, MVT::f32, 1 }, // Pentium III from http://www.agner.org/ 892 { ISD::FADD, MVT::v4f32, 2 }, // Pentium III from http://www.agner.org/ 893 894 { ISD::FSUB, MVT::f32, 1 }, // Pentium III from http://www.agner.org/ 895 { ISD::FSUB, MVT::v4f32, 2 }, // Pentium III from http://www.agner.org/ 896 897 { ISD::ADD, MVT::i8, 1 }, // Pentium III from http://www.agner.org/ 898 { ISD::ADD, MVT::i16, 1 }, // Pentium III from http://www.agner.org/ 899 { ISD::ADD, MVT::i32, 1 }, // Pentium III from http://www.agner.org/ 900 901 { ISD::SUB, MVT::i8, 1 }, // Pentium III from http://www.agner.org/ 902 { ISD::SUB, MVT::i16, 1 }, // Pentium III from http://www.agner.org/ 903 { ISD::SUB, MVT::i32, 1 }, // Pentium III from http://www.agner.org/ 904 }; 905 906 if (ST->hasSSE1()) 907 if (const auto *Entry = CostTableLookup(SSE1CostTable, ISD, LT.second)) 908 return LT.first * Entry->Cost; 909 910 // It is not a good idea to vectorize division. We have to scalarize it and 911 // in the process we will often end up having to spilling regular 912 // registers. The overhead of division is going to dominate most kernels 913 // anyways so try hard to prevent vectorization of division - it is 914 // generally a bad idea. Assume somewhat arbitrarily that we have to be able 915 // to hide "20 cycles" for each lane. 916 if (LT.second.isVector() && (ISD == ISD::SDIV || ISD == ISD::SREM || 917 ISD == ISD::UDIV || ISD == ISD::UREM)) { 918 int ScalarCost = getArithmeticInstrCost( 919 Opcode, Ty->getScalarType(), Op1Info, Op2Info, 920 TargetTransformInfo::OP_None, TargetTransformInfo::OP_None); 921 return 20 * LT.first * LT.second.getVectorNumElements() * ScalarCost; 922 } 923 924 // Fallback to the default implementation. 925 return BaseT::getArithmeticInstrCost(Opcode, Ty, Op1Info, Op2Info); 926 } 927 928 int X86TTIImpl::getShuffleCost(TTI::ShuffleKind Kind, Type *Tp, int Index, 929 Type *SubTp) { 930 // 64-bit packed float vectors (v2f32) are widened to type v4f32. 931 // 64-bit packed integer vectors (v2i32) are widened to type v4i32. 932 std::pair<int, MVT> LT = TLI->getTypeLegalizationCost(DL, Tp); 933 934 // Treat Transpose as 2-op shuffles - there's no difference in lowering. 935 if (Kind == TTI::SK_Transpose) 936 Kind = TTI::SK_PermuteTwoSrc; 937 938 // For Broadcasts we are splatting the first element from the first input 939 // register, so only need to reference that input and all the output 940 // registers are the same. 941 if (Kind == TTI::SK_Broadcast) 942 LT.first = 1; 943 944 // Subvector extractions are free if they start at the beginning of a 945 // vector and cheap if the subvectors are aligned. 946 if (Kind == TTI::SK_ExtractSubvector && LT.second.isVector()) { 947 int NumElts = LT.second.getVectorNumElements(); 948 if ((Index % NumElts) == 0) 949 return 0; 950 std::pair<int, MVT> SubLT = TLI->getTypeLegalizationCost(DL, SubTp); 951 if (SubLT.second.isVector()) { 952 int NumSubElts = SubLT.second.getVectorNumElements(); 953 if ((Index % NumSubElts) == 0 && (NumElts % NumSubElts) == 0) 954 return SubLT.first; 955 // Handle some cases for widening legalization. For now we only handle 956 // cases where the original subvector was naturally aligned and evenly 957 // fit in its legalized subvector type. 958 // FIXME: Remove some of the alignment restrictions. 959 // FIXME: We can use permq for 64-bit or larger extracts from 256-bit 960 // vectors. 961 int OrigSubElts = SubTp->getVectorNumElements(); 962 if (NumSubElts > OrigSubElts && 963 (Index % OrigSubElts) == 0 && (NumSubElts % OrigSubElts) == 0 && 964 LT.second.getVectorElementType() == 965 SubLT.second.getVectorElementType() && 966 LT.second.getVectorElementType().getSizeInBits() == 967 Tp->getVectorElementType()->getPrimitiveSizeInBits()) { 968 assert(NumElts >= NumSubElts && NumElts > OrigSubElts && 969 "Unexpected number of elements!"); 970 Type *VecTy = VectorType::get(Tp->getVectorElementType(), 971 LT.second.getVectorNumElements()); 972 Type *SubTy = VectorType::get(Tp->getVectorElementType(), 973 SubLT.second.getVectorNumElements()); 974 int ExtractIndex = alignDown((Index % NumElts), NumSubElts); 975 int ExtractCost = getShuffleCost(TTI::SK_ExtractSubvector, VecTy, 976 ExtractIndex, SubTy); 977 978 // If the original size is 32-bits or more, we can use pshufd. Otherwise 979 // if we have SSSE3 we can use pshufb. 980 if (SubTp->getPrimitiveSizeInBits() >= 32 || ST->hasSSSE3()) 981 return ExtractCost + 1; // pshufd or pshufb 982 983 assert(SubTp->getPrimitiveSizeInBits() == 16 && 984 "Unexpected vector size"); 985 986 return ExtractCost + 2; // worst case pshufhw + pshufd 987 } 988 } 989 } 990 991 // Handle some common (illegal) sub-vector types as they are often very cheap 992 // to shuffle even on targets without PSHUFB. 993 EVT VT = TLI->getValueType(DL, Tp); 994 if (VT.isSimple() && VT.isVector() && VT.getSizeInBits() < 128 && 995 !ST->hasSSSE3()) { 996 static const CostTblEntry SSE2SubVectorShuffleTbl[] = { 997 {TTI::SK_Broadcast, MVT::v4i16, 1}, // pshuflw 998 {TTI::SK_Broadcast, MVT::v2i16, 1}, // pshuflw 999 {TTI::SK_Broadcast, MVT::v8i8, 2}, // punpck/pshuflw 1000 {TTI::SK_Broadcast, MVT::v4i8, 2}, // punpck/pshuflw 1001 {TTI::SK_Broadcast, MVT::v2i8, 1}, // punpck 1002 1003 {TTI::SK_Reverse, MVT::v4i16, 1}, // pshuflw 1004 {TTI::SK_Reverse, MVT::v2i16, 1}, // pshuflw 1005 {TTI::SK_Reverse, MVT::v4i8, 3}, // punpck/pshuflw/packus 1006 {TTI::SK_Reverse, MVT::v2i8, 1}, // punpck 1007 1008 {TTI::SK_PermuteTwoSrc, MVT::v4i16, 2}, // punpck/pshuflw 1009 {TTI::SK_PermuteTwoSrc, MVT::v2i16, 2}, // punpck/pshuflw 1010 {TTI::SK_PermuteTwoSrc, MVT::v8i8, 7}, // punpck/pshuflw 1011 {TTI::SK_PermuteTwoSrc, MVT::v4i8, 4}, // punpck/pshuflw 1012 {TTI::SK_PermuteTwoSrc, MVT::v2i8, 2}, // punpck 1013 1014 {TTI::SK_PermuteSingleSrc, MVT::v4i16, 1}, // pshuflw 1015 {TTI::SK_PermuteSingleSrc, MVT::v2i16, 1}, // pshuflw 1016 {TTI::SK_PermuteSingleSrc, MVT::v8i8, 5}, // punpck/pshuflw 1017 {TTI::SK_PermuteSingleSrc, MVT::v4i8, 3}, // punpck/pshuflw 1018 {TTI::SK_PermuteSingleSrc, MVT::v2i8, 1}, // punpck 1019 }; 1020 1021 if (ST->hasSSE2()) 1022 if (const auto *Entry = 1023 CostTableLookup(SSE2SubVectorShuffleTbl, Kind, VT.getSimpleVT())) 1024 return Entry->Cost; 1025 } 1026 1027 // We are going to permute multiple sources and the result will be in multiple 1028 // destinations. Providing an accurate cost only for splits where the element 1029 // type remains the same. 1030 if (Kind == TTI::SK_PermuteSingleSrc && LT.first != 1) { 1031 MVT LegalVT = LT.second; 1032 if (LegalVT.isVector() && 1033 LegalVT.getVectorElementType().getSizeInBits() == 1034 Tp->getVectorElementType()->getPrimitiveSizeInBits() && 1035 LegalVT.getVectorNumElements() < Tp->getVectorNumElements()) { 1036 1037 unsigned VecTySize = DL.getTypeStoreSize(Tp); 1038 unsigned LegalVTSize = LegalVT.getStoreSize(); 1039 // Number of source vectors after legalization: 1040 unsigned NumOfSrcs = (VecTySize + LegalVTSize - 1) / LegalVTSize; 1041 // Number of destination vectors after legalization: 1042 unsigned NumOfDests = LT.first; 1043 1044 Type *SingleOpTy = VectorType::get(Tp->getVectorElementType(), 1045 LegalVT.getVectorNumElements()); 1046 1047 unsigned NumOfShuffles = (NumOfSrcs - 1) * NumOfDests; 1048 return NumOfShuffles * 1049 getShuffleCost(TTI::SK_PermuteTwoSrc, SingleOpTy, 0, nullptr); 1050 } 1051 1052 return BaseT::getShuffleCost(Kind, Tp, Index, SubTp); 1053 } 1054 1055 // For 2-input shuffles, we must account for splitting the 2 inputs into many. 1056 if (Kind == TTI::SK_PermuteTwoSrc && LT.first != 1) { 1057 // We assume that source and destination have the same vector type. 1058 int NumOfDests = LT.first; 1059 int NumOfShufflesPerDest = LT.first * 2 - 1; 1060 LT.first = NumOfDests * NumOfShufflesPerDest; 1061 } 1062 1063 static const CostTblEntry AVX512VBMIShuffleTbl[] = { 1064 {TTI::SK_Reverse, MVT::v64i8, 1}, // vpermb 1065 {TTI::SK_Reverse, MVT::v32i8, 1}, // vpermb 1066 1067 {TTI::SK_PermuteSingleSrc, MVT::v64i8, 1}, // vpermb 1068 {TTI::SK_PermuteSingleSrc, MVT::v32i8, 1}, // vpermb 1069 1070 {TTI::SK_PermuteTwoSrc, MVT::v64i8, 1}, // vpermt2b 1071 {TTI::SK_PermuteTwoSrc, MVT::v32i8, 1}, // vpermt2b 1072 {TTI::SK_PermuteTwoSrc, MVT::v16i8, 1} // vpermt2b 1073 }; 1074 1075 if (ST->hasVBMI()) 1076 if (const auto *Entry = 1077 CostTableLookup(AVX512VBMIShuffleTbl, Kind, LT.second)) 1078 return LT.first * Entry->Cost; 1079 1080 static const CostTblEntry AVX512BWShuffleTbl[] = { 1081 {TTI::SK_Broadcast, MVT::v32i16, 1}, // vpbroadcastw 1082 {TTI::SK_Broadcast, MVT::v64i8, 1}, // vpbroadcastb 1083 1084 {TTI::SK_Reverse, MVT::v32i16, 1}, // vpermw 1085 {TTI::SK_Reverse, MVT::v16i16, 1}, // vpermw 1086 {TTI::SK_Reverse, MVT::v64i8, 2}, // pshufb + vshufi64x2 1087 1088 {TTI::SK_PermuteSingleSrc, MVT::v32i16, 1}, // vpermw 1089 {TTI::SK_PermuteSingleSrc, MVT::v16i16, 1}, // vpermw 1090 {TTI::SK_PermuteSingleSrc, MVT::v8i16, 1}, // vpermw 1091 {TTI::SK_PermuteSingleSrc, MVT::v64i8, 8}, // extend to v32i16 1092 {TTI::SK_PermuteSingleSrc, MVT::v32i8, 3}, // vpermw + zext/trunc 1093 1094 {TTI::SK_PermuteTwoSrc, MVT::v32i16, 1}, // vpermt2w 1095 {TTI::SK_PermuteTwoSrc, MVT::v16i16, 1}, // vpermt2w 1096 {TTI::SK_PermuteTwoSrc, MVT::v8i16, 1}, // vpermt2w 1097 {TTI::SK_PermuteTwoSrc, MVT::v32i8, 3}, // zext + vpermt2w + trunc 1098 {TTI::SK_PermuteTwoSrc, MVT::v64i8, 19}, // 6 * v32i8 + 1 1099 {TTI::SK_PermuteTwoSrc, MVT::v16i8, 3} // zext + vpermt2w + trunc 1100 }; 1101 1102 if (ST->hasBWI()) 1103 if (const auto *Entry = 1104 CostTableLookup(AVX512BWShuffleTbl, Kind, LT.second)) 1105 return LT.first * Entry->Cost; 1106 1107 static const CostTblEntry AVX512ShuffleTbl[] = { 1108 {TTI::SK_Broadcast, MVT::v8f64, 1}, // vbroadcastpd 1109 {TTI::SK_Broadcast, MVT::v16f32, 1}, // vbroadcastps 1110 {TTI::SK_Broadcast, MVT::v8i64, 1}, // vpbroadcastq 1111 {TTI::SK_Broadcast, MVT::v16i32, 1}, // vpbroadcastd 1112 {TTI::SK_Broadcast, MVT::v32i16, 1}, // vpbroadcastw 1113 {TTI::SK_Broadcast, MVT::v64i8, 1}, // vpbroadcastb 1114 1115 {TTI::SK_Reverse, MVT::v8f64, 1}, // vpermpd 1116 {TTI::SK_Reverse, MVT::v16f32, 1}, // vpermps 1117 {TTI::SK_Reverse, MVT::v8i64, 1}, // vpermq 1118 {TTI::SK_Reverse, MVT::v16i32, 1}, // vpermd 1119 1120 {TTI::SK_PermuteSingleSrc, MVT::v8f64, 1}, // vpermpd 1121 {TTI::SK_PermuteSingleSrc, MVT::v4f64, 1}, // vpermpd 1122 {TTI::SK_PermuteSingleSrc, MVT::v2f64, 1}, // vpermpd 1123 {TTI::SK_PermuteSingleSrc, MVT::v16f32, 1}, // vpermps 1124 {TTI::SK_PermuteSingleSrc, MVT::v8f32, 1}, // vpermps 1125 {TTI::SK_PermuteSingleSrc, MVT::v4f32, 1}, // vpermps 1126 {TTI::SK_PermuteSingleSrc, MVT::v8i64, 1}, // vpermq 1127 {TTI::SK_PermuteSingleSrc, MVT::v4i64, 1}, // vpermq 1128 {TTI::SK_PermuteSingleSrc, MVT::v2i64, 1}, // vpermq 1129 {TTI::SK_PermuteSingleSrc, MVT::v16i32, 1}, // vpermd 1130 {TTI::SK_PermuteSingleSrc, MVT::v8i32, 1}, // vpermd 1131 {TTI::SK_PermuteSingleSrc, MVT::v4i32, 1}, // vpermd 1132 {TTI::SK_PermuteSingleSrc, MVT::v16i8, 1}, // pshufb 1133 1134 {TTI::SK_PermuteTwoSrc, MVT::v8f64, 1}, // vpermt2pd 1135 {TTI::SK_PermuteTwoSrc, MVT::v16f32, 1}, // vpermt2ps 1136 {TTI::SK_PermuteTwoSrc, MVT::v8i64, 1}, // vpermt2q 1137 {TTI::SK_PermuteTwoSrc, MVT::v16i32, 1}, // vpermt2d 1138 {TTI::SK_PermuteTwoSrc, MVT::v4f64, 1}, // vpermt2pd 1139 {TTI::SK_PermuteTwoSrc, MVT::v8f32, 1}, // vpermt2ps 1140 {TTI::SK_PermuteTwoSrc, MVT::v4i64, 1}, // vpermt2q 1141 {TTI::SK_PermuteTwoSrc, MVT::v8i32, 1}, // vpermt2d 1142 {TTI::SK_PermuteTwoSrc, MVT::v2f64, 1}, // vpermt2pd 1143 {TTI::SK_PermuteTwoSrc, MVT::v4f32, 1}, // vpermt2ps 1144 {TTI::SK_PermuteTwoSrc, MVT::v2i64, 1}, // vpermt2q 1145 {TTI::SK_PermuteTwoSrc, MVT::v4i32, 1}, // vpermt2d 1146 1147 // FIXME: This just applies the type legalization cost rules above 1148 // assuming these completely split. 1149 {TTI::SK_PermuteSingleSrc, MVT::v32i16, 14}, 1150 {TTI::SK_PermuteSingleSrc, MVT::v64i8, 14}, 1151 {TTI::SK_PermuteTwoSrc, MVT::v32i16, 42}, 1152 {TTI::SK_PermuteTwoSrc, MVT::v64i8, 42}, 1153 }; 1154 1155 if (ST->hasAVX512()) 1156 if (const auto *Entry = CostTableLookup(AVX512ShuffleTbl, Kind, LT.second)) 1157 return LT.first * Entry->Cost; 1158 1159 static const CostTblEntry AVX2ShuffleTbl[] = { 1160 {TTI::SK_Broadcast, MVT::v4f64, 1}, // vbroadcastpd 1161 {TTI::SK_Broadcast, MVT::v8f32, 1}, // vbroadcastps 1162 {TTI::SK_Broadcast, MVT::v4i64, 1}, // vpbroadcastq 1163 {TTI::SK_Broadcast, MVT::v8i32, 1}, // vpbroadcastd 1164 {TTI::SK_Broadcast, MVT::v16i16, 1}, // vpbroadcastw 1165 {TTI::SK_Broadcast, MVT::v32i8, 1}, // vpbroadcastb 1166 1167 {TTI::SK_Reverse, MVT::v4f64, 1}, // vpermpd 1168 {TTI::SK_Reverse, MVT::v8f32, 1}, // vpermps 1169 {TTI::SK_Reverse, MVT::v4i64, 1}, // vpermq 1170 {TTI::SK_Reverse, MVT::v8i32, 1}, // vpermd 1171 {TTI::SK_Reverse, MVT::v16i16, 2}, // vperm2i128 + pshufb 1172 {TTI::SK_Reverse, MVT::v32i8, 2}, // vperm2i128 + pshufb 1173 1174 {TTI::SK_Select, MVT::v16i16, 1}, // vpblendvb 1175 {TTI::SK_Select, MVT::v32i8, 1}, // vpblendvb 1176 1177 {TTI::SK_PermuteSingleSrc, MVT::v4f64, 1}, // vpermpd 1178 {TTI::SK_PermuteSingleSrc, MVT::v8f32, 1}, // vpermps 1179 {TTI::SK_PermuteSingleSrc, MVT::v4i64, 1}, // vpermq 1180 {TTI::SK_PermuteSingleSrc, MVT::v8i32, 1}, // vpermd 1181 {TTI::SK_PermuteSingleSrc, MVT::v16i16, 4}, // vperm2i128 + 2*vpshufb 1182 // + vpblendvb 1183 {TTI::SK_PermuteSingleSrc, MVT::v32i8, 4}, // vperm2i128 + 2*vpshufb 1184 // + vpblendvb 1185 1186 {TTI::SK_PermuteTwoSrc, MVT::v4f64, 3}, // 2*vpermpd + vblendpd 1187 {TTI::SK_PermuteTwoSrc, MVT::v8f32, 3}, // 2*vpermps + vblendps 1188 {TTI::SK_PermuteTwoSrc, MVT::v4i64, 3}, // 2*vpermq + vpblendd 1189 {TTI::SK_PermuteTwoSrc, MVT::v8i32, 3}, // 2*vpermd + vpblendd 1190 {TTI::SK_PermuteTwoSrc, MVT::v16i16, 7}, // 2*vperm2i128 + 4*vpshufb 1191 // + vpblendvb 1192 {TTI::SK_PermuteTwoSrc, MVT::v32i8, 7}, // 2*vperm2i128 + 4*vpshufb 1193 // + vpblendvb 1194 }; 1195 1196 if (ST->hasAVX2()) 1197 if (const auto *Entry = CostTableLookup(AVX2ShuffleTbl, Kind, LT.second)) 1198 return LT.first * Entry->Cost; 1199 1200 static const CostTblEntry XOPShuffleTbl[] = { 1201 {TTI::SK_PermuteSingleSrc, MVT::v4f64, 2}, // vperm2f128 + vpermil2pd 1202 {TTI::SK_PermuteSingleSrc, MVT::v8f32, 2}, // vperm2f128 + vpermil2ps 1203 {TTI::SK_PermuteSingleSrc, MVT::v4i64, 2}, // vperm2f128 + vpermil2pd 1204 {TTI::SK_PermuteSingleSrc, MVT::v8i32, 2}, // vperm2f128 + vpermil2ps 1205 {TTI::SK_PermuteSingleSrc, MVT::v16i16, 4}, // vextractf128 + 2*vpperm 1206 // + vinsertf128 1207 {TTI::SK_PermuteSingleSrc, MVT::v32i8, 4}, // vextractf128 + 2*vpperm 1208 // + vinsertf128 1209 1210 {TTI::SK_PermuteTwoSrc, MVT::v16i16, 9}, // 2*vextractf128 + 6*vpperm 1211 // + vinsertf128 1212 {TTI::SK_PermuteTwoSrc, MVT::v8i16, 1}, // vpperm 1213 {TTI::SK_PermuteTwoSrc, MVT::v32i8, 9}, // 2*vextractf128 + 6*vpperm 1214 // + vinsertf128 1215 {TTI::SK_PermuteTwoSrc, MVT::v16i8, 1}, // vpperm 1216 }; 1217 1218 if (ST->hasXOP()) 1219 if (const auto *Entry = CostTableLookup(XOPShuffleTbl, Kind, LT.second)) 1220 return LT.first * Entry->Cost; 1221 1222 static const CostTblEntry AVX1ShuffleTbl[] = { 1223 {TTI::SK_Broadcast, MVT::v4f64, 2}, // vperm2f128 + vpermilpd 1224 {TTI::SK_Broadcast, MVT::v8f32, 2}, // vperm2f128 + vpermilps 1225 {TTI::SK_Broadcast, MVT::v4i64, 2}, // vperm2f128 + vpermilpd 1226 {TTI::SK_Broadcast, MVT::v8i32, 2}, // vperm2f128 + vpermilps 1227 {TTI::SK_Broadcast, MVT::v16i16, 3}, // vpshuflw + vpshufd + vinsertf128 1228 {TTI::SK_Broadcast, MVT::v32i8, 2}, // vpshufb + vinsertf128 1229 1230 {TTI::SK_Reverse, MVT::v4f64, 2}, // vperm2f128 + vpermilpd 1231 {TTI::SK_Reverse, MVT::v8f32, 2}, // vperm2f128 + vpermilps 1232 {TTI::SK_Reverse, MVT::v4i64, 2}, // vperm2f128 + vpermilpd 1233 {TTI::SK_Reverse, MVT::v8i32, 2}, // vperm2f128 + vpermilps 1234 {TTI::SK_Reverse, MVT::v16i16, 4}, // vextractf128 + 2*pshufb 1235 // + vinsertf128 1236 {TTI::SK_Reverse, MVT::v32i8, 4}, // vextractf128 + 2*pshufb 1237 // + vinsertf128 1238 1239 {TTI::SK_Select, MVT::v4i64, 1}, // vblendpd 1240 {TTI::SK_Select, MVT::v4f64, 1}, // vblendpd 1241 {TTI::SK_Select, MVT::v8i32, 1}, // vblendps 1242 {TTI::SK_Select, MVT::v8f32, 1}, // vblendps 1243 {TTI::SK_Select, MVT::v16i16, 3}, // vpand + vpandn + vpor 1244 {TTI::SK_Select, MVT::v32i8, 3}, // vpand + vpandn + vpor 1245 1246 {TTI::SK_PermuteSingleSrc, MVT::v4f64, 2}, // vperm2f128 + vshufpd 1247 {TTI::SK_PermuteSingleSrc, MVT::v4i64, 2}, // vperm2f128 + vshufpd 1248 {TTI::SK_PermuteSingleSrc, MVT::v8f32, 4}, // 2*vperm2f128 + 2*vshufps 1249 {TTI::SK_PermuteSingleSrc, MVT::v8i32, 4}, // 2*vperm2f128 + 2*vshufps 1250 {TTI::SK_PermuteSingleSrc, MVT::v16i16, 8}, // vextractf128 + 4*pshufb 1251 // + 2*por + vinsertf128 1252 {TTI::SK_PermuteSingleSrc, MVT::v32i8, 8}, // vextractf128 + 4*pshufb 1253 // + 2*por + vinsertf128 1254 1255 {TTI::SK_PermuteTwoSrc, MVT::v4f64, 3}, // 2*vperm2f128 + vshufpd 1256 {TTI::SK_PermuteTwoSrc, MVT::v4i64, 3}, // 2*vperm2f128 + vshufpd 1257 {TTI::SK_PermuteTwoSrc, MVT::v8f32, 4}, // 2*vperm2f128 + 2*vshufps 1258 {TTI::SK_PermuteTwoSrc, MVT::v8i32, 4}, // 2*vperm2f128 + 2*vshufps 1259 {TTI::SK_PermuteTwoSrc, MVT::v16i16, 15}, // 2*vextractf128 + 8*pshufb 1260 // + 4*por + vinsertf128 1261 {TTI::SK_PermuteTwoSrc, MVT::v32i8, 15}, // 2*vextractf128 + 8*pshufb 1262 // + 4*por + vinsertf128 1263 }; 1264 1265 if (ST->hasAVX()) 1266 if (const auto *Entry = CostTableLookup(AVX1ShuffleTbl, Kind, LT.second)) 1267 return LT.first * Entry->Cost; 1268 1269 static const CostTblEntry SSE41ShuffleTbl[] = { 1270 {TTI::SK_Select, MVT::v2i64, 1}, // pblendw 1271 {TTI::SK_Select, MVT::v2f64, 1}, // movsd 1272 {TTI::SK_Select, MVT::v4i32, 1}, // pblendw 1273 {TTI::SK_Select, MVT::v4f32, 1}, // blendps 1274 {TTI::SK_Select, MVT::v8i16, 1}, // pblendw 1275 {TTI::SK_Select, MVT::v16i8, 1} // pblendvb 1276 }; 1277 1278 if (ST->hasSSE41()) 1279 if (const auto *Entry = CostTableLookup(SSE41ShuffleTbl, Kind, LT.second)) 1280 return LT.first * Entry->Cost; 1281 1282 static const CostTblEntry SSSE3ShuffleTbl[] = { 1283 {TTI::SK_Broadcast, MVT::v8i16, 1}, // pshufb 1284 {TTI::SK_Broadcast, MVT::v16i8, 1}, // pshufb 1285 1286 {TTI::SK_Reverse, MVT::v8i16, 1}, // pshufb 1287 {TTI::SK_Reverse, MVT::v16i8, 1}, // pshufb 1288 1289 {TTI::SK_Select, MVT::v8i16, 3}, // 2*pshufb + por 1290 {TTI::SK_Select, MVT::v16i8, 3}, // 2*pshufb + por 1291 1292 {TTI::SK_PermuteSingleSrc, MVT::v8i16, 1}, // pshufb 1293 {TTI::SK_PermuteSingleSrc, MVT::v16i8, 1}, // pshufb 1294 1295 {TTI::SK_PermuteTwoSrc, MVT::v8i16, 3}, // 2*pshufb + por 1296 {TTI::SK_PermuteTwoSrc, MVT::v16i8, 3}, // 2*pshufb + por 1297 }; 1298 1299 if (ST->hasSSSE3()) 1300 if (const auto *Entry = CostTableLookup(SSSE3ShuffleTbl, Kind, LT.second)) 1301 return LT.first * Entry->Cost; 1302 1303 static const CostTblEntry SSE2ShuffleTbl[] = { 1304 {TTI::SK_Broadcast, MVT::v2f64, 1}, // shufpd 1305 {TTI::SK_Broadcast, MVT::v2i64, 1}, // pshufd 1306 {TTI::SK_Broadcast, MVT::v4i32, 1}, // pshufd 1307 {TTI::SK_Broadcast, MVT::v8i16, 2}, // pshuflw + pshufd 1308 {TTI::SK_Broadcast, MVT::v16i8, 3}, // unpck + pshuflw + pshufd 1309 1310 {TTI::SK_Reverse, MVT::v2f64, 1}, // shufpd 1311 {TTI::SK_Reverse, MVT::v2i64, 1}, // pshufd 1312 {TTI::SK_Reverse, MVT::v4i32, 1}, // pshufd 1313 {TTI::SK_Reverse, MVT::v8i16, 3}, // pshuflw + pshufhw + pshufd 1314 {TTI::SK_Reverse, MVT::v16i8, 9}, // 2*pshuflw + 2*pshufhw 1315 // + 2*pshufd + 2*unpck + packus 1316 1317 {TTI::SK_Select, MVT::v2i64, 1}, // movsd 1318 {TTI::SK_Select, MVT::v2f64, 1}, // movsd 1319 {TTI::SK_Select, MVT::v4i32, 2}, // 2*shufps 1320 {TTI::SK_Select, MVT::v8i16, 3}, // pand + pandn + por 1321 {TTI::SK_Select, MVT::v16i8, 3}, // pand + pandn + por 1322 1323 {TTI::SK_PermuteSingleSrc, MVT::v2f64, 1}, // shufpd 1324 {TTI::SK_PermuteSingleSrc, MVT::v2i64, 1}, // pshufd 1325 {TTI::SK_PermuteSingleSrc, MVT::v4i32, 1}, // pshufd 1326 {TTI::SK_PermuteSingleSrc, MVT::v8i16, 5}, // 2*pshuflw + 2*pshufhw 1327 // + pshufd/unpck 1328 { TTI::SK_PermuteSingleSrc, MVT::v16i8, 10 }, // 2*pshuflw + 2*pshufhw 1329 // + 2*pshufd + 2*unpck + 2*packus 1330 1331 { TTI::SK_PermuteTwoSrc, MVT::v2f64, 1 }, // shufpd 1332 { TTI::SK_PermuteTwoSrc, MVT::v2i64, 1 }, // shufpd 1333 { TTI::SK_PermuteTwoSrc, MVT::v4i32, 2 }, // 2*{unpck,movsd,pshufd} 1334 { TTI::SK_PermuteTwoSrc, MVT::v8i16, 8 }, // blend+permute 1335 { TTI::SK_PermuteTwoSrc, MVT::v16i8, 13 }, // blend+permute 1336 }; 1337 1338 if (ST->hasSSE2()) 1339 if (const auto *Entry = CostTableLookup(SSE2ShuffleTbl, Kind, LT.second)) 1340 return LT.first * Entry->Cost; 1341 1342 static const CostTblEntry SSE1ShuffleTbl[] = { 1343 { TTI::SK_Broadcast, MVT::v4f32, 1 }, // shufps 1344 { TTI::SK_Reverse, MVT::v4f32, 1 }, // shufps 1345 { TTI::SK_Select, MVT::v4f32, 2 }, // 2*shufps 1346 { TTI::SK_PermuteSingleSrc, MVT::v4f32, 1 }, // shufps 1347 { TTI::SK_PermuteTwoSrc, MVT::v4f32, 2 }, // 2*shufps 1348 }; 1349 1350 if (ST->hasSSE1()) 1351 if (const auto *Entry = CostTableLookup(SSE1ShuffleTbl, Kind, LT.second)) 1352 return LT.first * Entry->Cost; 1353 1354 return BaseT::getShuffleCost(Kind, Tp, Index, SubTp); 1355 } 1356 1357 int X86TTIImpl::getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src, 1358 const Instruction *I) { 1359 int ISD = TLI->InstructionOpcodeToISD(Opcode); 1360 assert(ISD && "Invalid opcode"); 1361 1362 // FIXME: Need a better design of the cost table to handle non-simple types of 1363 // potential massive combinations (elem_num x src_type x dst_type). 1364 1365 static const TypeConversionCostTblEntry AVX512BWConversionTbl[] { 1366 { ISD::SIGN_EXTEND, MVT::v32i16, MVT::v32i8, 1 }, 1367 { ISD::ZERO_EXTEND, MVT::v32i16, MVT::v32i8, 1 }, 1368 1369 // Mask sign extend has an instruction. 1370 { ISD::SIGN_EXTEND, MVT::v32i16, MVT::v32i1, 1 }, 1371 { ISD::SIGN_EXTEND, MVT::v64i8, MVT::v64i1, 1 }, 1372 1373 // Mask zero extend is a load + broadcast. 1374 { ISD::ZERO_EXTEND, MVT::v32i16, MVT::v32i1, 2 }, 1375 { ISD::ZERO_EXTEND, MVT::v64i8, MVT::v64i1, 2 }, 1376 1377 { ISD::TRUNCATE, MVT::v32i8, MVT::v32i16, 1 }, 1378 }; 1379 1380 static const TypeConversionCostTblEntry AVX512DQConversionTbl[] = { 1381 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v8i64, 1 }, 1382 { ISD::SINT_TO_FP, MVT::v8f64, MVT::v8i64, 1 }, 1383 1384 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i64, 1 }, 1385 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i64, 1 }, 1386 1387 { ISD::FP_TO_SINT, MVT::v8i64, MVT::v8f32, 1 }, 1388 { ISD::FP_TO_SINT, MVT::v8i64, MVT::v8f64, 1 }, 1389 1390 { ISD::FP_TO_UINT, MVT::v8i64, MVT::v8f32, 1 }, 1391 { ISD::FP_TO_UINT, MVT::v8i64, MVT::v8f64, 1 }, 1392 }; 1393 1394 // TODO: For AVX512DQ + AVX512VL, we also have cheap casts for 128-bit and 1395 // 256-bit wide vectors. 1396 1397 static const TypeConversionCostTblEntry AVX512FConversionTbl[] = { 1398 { ISD::FP_EXTEND, MVT::v8f64, MVT::v8f32, 1 }, 1399 { ISD::FP_EXTEND, MVT::v8f64, MVT::v16f32, 3 }, 1400 { ISD::FP_ROUND, MVT::v8f32, MVT::v8f64, 1 }, 1401 1402 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i32, 1 }, 1403 { ISD::TRUNCATE, MVT::v16i16, MVT::v16i32, 1 }, 1404 { ISD::TRUNCATE, MVT::v8i8, MVT::v8i64, 2 }, 1405 { ISD::TRUNCATE, MVT::v8i16, MVT::v8i64, 1 }, 1406 { ISD::TRUNCATE, MVT::v8i32, MVT::v8i64, 1 }, 1407 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i64, 7 },// 2*vpmovqd+concat+vpmovdb 1408 1409 { ISD::TRUNCATE, MVT::v32i8, MVT::v32i16, 9 }, // FIXME 1410 1411 // v16i1 -> v16i32 - load + broadcast 1412 { ISD::SIGN_EXTEND, MVT::v16i32, MVT::v16i1, 2 }, 1413 { ISD::ZERO_EXTEND, MVT::v16i32, MVT::v16i1, 2 }, 1414 { ISD::SIGN_EXTEND, MVT::v16i32, MVT::v16i8, 1 }, 1415 { ISD::ZERO_EXTEND, MVT::v16i32, MVT::v16i8, 1 }, 1416 { ISD::SIGN_EXTEND, MVT::v16i32, MVT::v16i16, 1 }, 1417 { ISD::ZERO_EXTEND, MVT::v16i32, MVT::v16i16, 1 }, 1418 { ISD::SIGN_EXTEND, MVT::v8i64, MVT::v8i8, 1 }, 1419 { ISD::ZERO_EXTEND, MVT::v8i64, MVT::v8i8, 1 }, 1420 { ISD::SIGN_EXTEND, MVT::v8i64, MVT::v8i16, 1 }, 1421 { ISD::ZERO_EXTEND, MVT::v8i64, MVT::v8i16, 1 }, 1422 { ISD::SIGN_EXTEND, MVT::v8i64, MVT::v8i32, 1 }, 1423 { ISD::ZERO_EXTEND, MVT::v8i64, MVT::v8i32, 1 }, 1424 1425 { ISD::SIGN_EXTEND, MVT::v32i16, MVT::v32i8, 3 }, // FIXME: May not be right 1426 { ISD::ZERO_EXTEND, MVT::v32i16, MVT::v32i8, 3 }, // FIXME: May not be right 1427 1428 { ISD::SINT_TO_FP, MVT::v8f64, MVT::v8i1, 4 }, 1429 { ISD::SINT_TO_FP, MVT::v16f32, MVT::v16i1, 3 }, 1430 { ISD::SINT_TO_FP, MVT::v8f64, MVT::v8i8, 2 }, 1431 { ISD::SINT_TO_FP, MVT::v16f32, MVT::v16i8, 2 }, 1432 { ISD::SINT_TO_FP, MVT::v8f64, MVT::v8i16, 2 }, 1433 { ISD::SINT_TO_FP, MVT::v16f32, MVT::v16i16, 2 }, 1434 { ISD::SINT_TO_FP, MVT::v16f32, MVT::v16i32, 1 }, 1435 { ISD::SINT_TO_FP, MVT::v8f64, MVT::v8i32, 1 }, 1436 1437 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i1, 4 }, 1438 { ISD::UINT_TO_FP, MVT::v16f32, MVT::v16i1, 3 }, 1439 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i8, 2 }, 1440 { ISD::UINT_TO_FP, MVT::v16f32, MVT::v16i8, 2 }, 1441 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i16, 2 }, 1442 { ISD::UINT_TO_FP, MVT::v16f32, MVT::v16i16, 2 }, 1443 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i32, 1 }, 1444 { ISD::UINT_TO_FP, MVT::v16f32, MVT::v16i32, 1 }, 1445 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i64, 26 }, 1446 { ISD::UINT_TO_FP, MVT::v8f64, MVT::v8i64, 5 }, 1447 1448 { ISD::FP_TO_UINT, MVT::v8i32, MVT::v8f64, 1 }, 1449 { ISD::FP_TO_UINT, MVT::v8i16, MVT::v8f64, 2 }, 1450 { ISD::FP_TO_UINT, MVT::v8i8, MVT::v8f64, 2 }, 1451 { ISD::FP_TO_UINT, MVT::v16i32, MVT::v16f32, 1 }, 1452 { ISD::FP_TO_UINT, MVT::v16i16, MVT::v16f32, 2 }, 1453 { ISD::FP_TO_UINT, MVT::v16i8, MVT::v16f32, 2 }, 1454 }; 1455 1456 static const TypeConversionCostTblEntry AVX512BWVLConversionTbl[] { 1457 // Mask sign extend has an instruction. 1458 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v8i1, 1 }, 1459 { ISD::SIGN_EXTEND, MVT::v16i8, MVT::v16i1, 1 }, 1460 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i1, 1 }, 1461 { ISD::SIGN_EXTEND, MVT::v32i8, MVT::v32i1, 1 }, 1462 1463 // Mask zero extend is a load + broadcast. 1464 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v8i1, 2 }, 1465 { ISD::ZERO_EXTEND, MVT::v16i8, MVT::v16i1, 2 }, 1466 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i1, 2 }, 1467 { ISD::ZERO_EXTEND, MVT::v32i8, MVT::v32i1, 2 }, 1468 }; 1469 1470 static const TypeConversionCostTblEntry AVX512DQVLConversionTbl[] = { 1471 { ISD::SINT_TO_FP, MVT::v2f32, MVT::v2i64, 1 }, 1472 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v2i64, 1 }, 1473 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v4i64, 1 }, 1474 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v4i64, 1 }, 1475 1476 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i64, 1 }, 1477 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i64, 1 }, 1478 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i64, 1 }, 1479 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i64, 1 }, 1480 1481 { ISD::FP_TO_SINT, MVT::v2i64, MVT::v2f32, 1 }, 1482 { ISD::FP_TO_SINT, MVT::v4i64, MVT::v4f32, 1 }, 1483 { ISD::FP_TO_SINT, MVT::v2i64, MVT::v2f64, 1 }, 1484 { ISD::FP_TO_SINT, MVT::v4i64, MVT::v4f64, 1 }, 1485 1486 { ISD::FP_TO_UINT, MVT::v2i64, MVT::v2f32, 1 }, 1487 { ISD::FP_TO_UINT, MVT::v4i64, MVT::v4f32, 1 }, 1488 { ISD::FP_TO_UINT, MVT::v2i64, MVT::v2f64, 1 }, 1489 { ISD::FP_TO_UINT, MVT::v4i64, MVT::v4f64, 1 }, 1490 }; 1491 1492 static const TypeConversionCostTblEntry AVX512VLConversionTbl[] = { 1493 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i8, 2 }, 1494 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i8, 2 }, 1495 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i8, 2 }, 1496 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i16, 5 }, 1497 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i16, 2 }, 1498 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i16, 2 }, 1499 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i32, 2 }, 1500 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i32, 1 }, 1501 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i32, 1 }, 1502 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i32, 1 }, 1503 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i32, 1 }, 1504 { ISD::UINT_TO_FP, MVT::v2f32, MVT::v2i64, 5 }, 1505 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i64, 5 }, 1506 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i64, 5 }, 1507 1508 { ISD::UINT_TO_FP, MVT::f32, MVT::i64, 1 }, 1509 { ISD::UINT_TO_FP, MVT::f64, MVT::i64, 1 }, 1510 { ISD::FP_TO_UINT, MVT::i64, MVT::f32, 1 }, 1511 { ISD::FP_TO_UINT, MVT::i64, MVT::f64, 1 }, 1512 1513 { ISD::FP_TO_UINT, MVT::v2i32, MVT::v2f32, 1 }, 1514 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f32, 1 }, 1515 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f64, 1 }, 1516 { ISD::FP_TO_UINT, MVT::v8i32, MVT::v8f32, 1 }, 1517 }; 1518 1519 static const TypeConversionCostTblEntry AVX2ConversionTbl[] = { 1520 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i1, 3 }, 1521 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i1, 3 }, 1522 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i1, 3 }, 1523 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i1, 3 }, 1524 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i8, 1 }, 1525 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i8, 1 }, 1526 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i8, 1 }, 1527 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i8, 1 }, 1528 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i8, 1 }, 1529 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i8, 1 }, 1530 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i16, 1 }, 1531 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i16, 1 }, 1532 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i16, 1 }, 1533 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i16, 1 }, 1534 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i32, 1 }, 1535 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i32, 1 }, 1536 { ISD::ZERO_EXTEND, MVT::v16i32, MVT::v16i16, 3 }, 1537 { ISD::SIGN_EXTEND, MVT::v16i32, MVT::v16i16, 3 }, 1538 1539 { ISD::TRUNCATE, MVT::v4i8, MVT::v4i64, 2 }, 1540 { ISD::TRUNCATE, MVT::v4i16, MVT::v4i64, 2 }, 1541 { ISD::TRUNCATE, MVT::v4i32, MVT::v4i64, 2 }, 1542 { ISD::TRUNCATE, MVT::v8i8, MVT::v8i32, 2 }, 1543 { ISD::TRUNCATE, MVT::v8i16, MVT::v8i32, 2 }, 1544 { ISD::TRUNCATE, MVT::v8i32, MVT::v8i64, 4 }, 1545 1546 { ISD::FP_EXTEND, MVT::v8f64, MVT::v8f32, 3 }, 1547 { ISD::FP_ROUND, MVT::v8f32, MVT::v8f64, 3 }, 1548 1549 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i32, 8 }, 1550 }; 1551 1552 static const TypeConversionCostTblEntry AVXConversionTbl[] = { 1553 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i1, 6 }, 1554 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i1, 4 }, 1555 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i1, 7 }, 1556 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i1, 4 }, 1557 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i8, 4 }, 1558 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i8, 4 }, 1559 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i8, 4 }, 1560 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i8, 4 }, 1561 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i8, 4 }, 1562 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i8, 4 }, 1563 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i16, 4 }, 1564 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i16, 3 }, 1565 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i16, 4 }, 1566 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i16, 4 }, 1567 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i32, 4 }, 1568 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i32, 4 }, 1569 1570 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i16, 4 }, 1571 { ISD::TRUNCATE, MVT::v8i8, MVT::v8i32, 4 }, 1572 { ISD::TRUNCATE, MVT::v8i16, MVT::v8i32, 5 }, 1573 { ISD::TRUNCATE, MVT::v4i8, MVT::v4i64, 4 }, 1574 { ISD::TRUNCATE, MVT::v4i16, MVT::v4i64, 4 }, 1575 { ISD::TRUNCATE, MVT::v4i32, MVT::v4i64, 4 }, 1576 { ISD::TRUNCATE, MVT::v8i8, MVT::v8i64, 11 }, 1577 { ISD::TRUNCATE, MVT::v8i16, MVT::v8i64, 9 }, 1578 { ISD::TRUNCATE, MVT::v8i32, MVT::v8i64, 9 }, 1579 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i64, 11 }, 1580 1581 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v4i1, 3 }, 1582 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v4i1, 3 }, 1583 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v8i1, 8 }, 1584 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v4i8, 3 }, 1585 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v4i8, 3 }, 1586 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v8i8, 8 }, 1587 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v4i16, 3 }, 1588 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v4i16, 3 }, 1589 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v8i16, 5 }, 1590 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v4i32, 1 }, 1591 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v4i32, 1 }, 1592 { ISD::SINT_TO_FP, MVT::v8f32, MVT::v8i32, 1 }, 1593 1594 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i1, 7 }, 1595 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i1, 7 }, 1596 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i1, 6 }, 1597 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i8, 2 }, 1598 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i8, 2 }, 1599 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i8, 5 }, 1600 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i16, 2 }, 1601 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i16, 2 }, 1602 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i16, 5 }, 1603 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i32, 6 }, 1604 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i32, 6 }, 1605 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i32, 6 }, 1606 { ISD::UINT_TO_FP, MVT::v8f32, MVT::v8i32, 9 }, 1607 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i64, 5 }, 1608 { ISD::UINT_TO_FP, MVT::v4f64, MVT::v4i64, 6 }, 1609 // The generic code to compute the scalar overhead is currently broken. 1610 // Workaround this limitation by estimating the scalarization overhead 1611 // here. We have roughly 10 instructions per scalar element. 1612 // Multiply that by the vector width. 1613 // FIXME: remove that when PR19268 is fixed. 1614 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v4i64, 13 }, 1615 { ISD::SINT_TO_FP, MVT::v4f64, MVT::v4i64, 13 }, 1616 1617 { ISD::FP_TO_SINT, MVT::v4i8, MVT::v4f32, 1 }, 1618 { ISD::FP_TO_SINT, MVT::v8i8, MVT::v8f32, 7 }, 1619 // This node is expanded into scalarized operations but BasicTTI is overly 1620 // optimistic estimating its cost. It computes 3 per element (one 1621 // vector-extract, one scalar conversion and one vector-insert). The 1622 // problem is that the inserts form a read-modify-write chain so latency 1623 // should be factored in too. Inflating the cost per element by 1. 1624 { ISD::FP_TO_UINT, MVT::v8i32, MVT::v8f32, 8*4 }, 1625 { ISD::FP_TO_UINT, MVT::v4i32, MVT::v4f64, 4*4 }, 1626 1627 { ISD::FP_EXTEND, MVT::v4f64, MVT::v4f32, 1 }, 1628 { ISD::FP_ROUND, MVT::v4f32, MVT::v4f64, 1 }, 1629 }; 1630 1631 static const TypeConversionCostTblEntry SSE41ConversionTbl[] = { 1632 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i8, 2 }, 1633 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i8, 2 }, 1634 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i16, 2 }, 1635 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i16, 2 }, 1636 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i32, 2 }, 1637 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i32, 2 }, 1638 1639 { ISD::ZERO_EXTEND, MVT::v4i16, MVT::v4i8, 1 }, 1640 { ISD::SIGN_EXTEND, MVT::v4i16, MVT::v4i8, 2 }, 1641 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v4i8, 1 }, 1642 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v4i8, 1 }, 1643 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v8i8, 1 }, 1644 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v8i8, 1 }, 1645 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i8, 2 }, 1646 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i8, 2 }, 1647 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i8, 2 }, 1648 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i8, 2 }, 1649 { ISD::ZERO_EXTEND, MVT::v16i32, MVT::v16i8, 4 }, 1650 { ISD::SIGN_EXTEND, MVT::v16i32, MVT::v16i8, 4 }, 1651 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v4i16, 1 }, 1652 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v4i16, 1 }, 1653 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i16, 2 }, 1654 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i16, 2 }, 1655 { ISD::ZERO_EXTEND, MVT::v16i32, MVT::v16i16, 4 }, 1656 { ISD::SIGN_EXTEND, MVT::v16i32, MVT::v16i16, 4 }, 1657 1658 { ISD::TRUNCATE, MVT::v4i8, MVT::v4i16, 2 }, 1659 { ISD::TRUNCATE, MVT::v8i8, MVT::v8i16, 1 }, 1660 { ISD::TRUNCATE, MVT::v4i8, MVT::v4i32, 1 }, 1661 { ISD::TRUNCATE, MVT::v4i16, MVT::v4i32, 1 }, 1662 { ISD::TRUNCATE, MVT::v8i8, MVT::v8i32, 3 }, 1663 { ISD::TRUNCATE, MVT::v8i16, MVT::v8i32, 3 }, 1664 { ISD::TRUNCATE, MVT::v16i16, MVT::v16i32, 6 }, 1665 { ISD::TRUNCATE, MVT::v2i8, MVT::v2i64, 1 }, // PSHUFB 1666 1667 { ISD::UINT_TO_FP, MVT::f32, MVT::i64, 4 }, 1668 { ISD::UINT_TO_FP, MVT::f64, MVT::i64, 4 }, 1669 }; 1670 1671 static const TypeConversionCostTblEntry SSE2ConversionTbl[] = { 1672 // These are somewhat magic numbers justified by looking at the output of 1673 // Intel's IACA, running some kernels and making sure when we take 1674 // legalization into account the throughput will be overestimated. 1675 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v16i8, 8 }, 1676 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v16i8, 16*10 }, 1677 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v8i16, 15 }, 1678 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v8i16, 8*10 }, 1679 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v4i32, 5 }, 1680 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v4i32, 2*10 }, 1681 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v2i32, 2*10 }, 1682 { ISD::SINT_TO_FP, MVT::v4f32, MVT::v2i64, 15 }, 1683 { ISD::SINT_TO_FP, MVT::v2f64, MVT::v2i64, 2*10 }, 1684 1685 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v16i8, 16*10 }, 1686 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v16i8, 8 }, 1687 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v8i16, 15 }, 1688 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v8i16, 8*10 }, 1689 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v4i32, 4*10 }, 1690 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v4i32, 8 }, 1691 { ISD::UINT_TO_FP, MVT::v2f64, MVT::v2i64, 6 }, 1692 { ISD::UINT_TO_FP, MVT::v4f32, MVT::v2i64, 15 }, 1693 1694 { ISD::FP_TO_SINT, MVT::v4i16, MVT::v4f32, 2 }, 1695 { ISD::FP_TO_SINT, MVT::v2i16, MVT::v2f64, 2 }, 1696 1697 { ISD::FP_TO_SINT, MVT::v2i32, MVT::v2f64, 3 }, 1698 1699 { ISD::UINT_TO_FP, MVT::f32, MVT::i64, 6 }, 1700 { ISD::UINT_TO_FP, MVT::f64, MVT::i64, 6 }, 1701 1702 { ISD::FP_TO_UINT, MVT::i64, MVT::f32, 4 }, 1703 { ISD::FP_TO_UINT, MVT::i64, MVT::f64, 4 }, 1704 1705 { ISD::ZERO_EXTEND, MVT::v4i16, MVT::v4i8, 1 }, 1706 { ISD::SIGN_EXTEND, MVT::v4i16, MVT::v4i8, 6 }, 1707 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v4i8, 2 }, 1708 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v4i8, 3 }, 1709 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i8, 4 }, 1710 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i8, 8 }, 1711 { ISD::ZERO_EXTEND, MVT::v8i16, MVT::v8i8, 1 }, 1712 { ISD::SIGN_EXTEND, MVT::v8i16, MVT::v8i8, 2 }, 1713 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i8, 6 }, 1714 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i8, 6 }, 1715 { ISD::ZERO_EXTEND, MVT::v16i16, MVT::v16i8, 3 }, 1716 { ISD::SIGN_EXTEND, MVT::v16i16, MVT::v16i8, 4 }, 1717 { ISD::ZERO_EXTEND, MVT::v16i32, MVT::v16i8, 9 }, 1718 { ISD::SIGN_EXTEND, MVT::v16i32, MVT::v16i8, 12 }, 1719 { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v4i16, 1 }, 1720 { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v4i16, 2 }, 1721 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i16, 3 }, 1722 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i16, 10 }, 1723 { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i16, 3 }, 1724 { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i16, 4 }, 1725 { ISD::ZERO_EXTEND, MVT::v16i32, MVT::v16i16, 6 }, 1726 { ISD::SIGN_EXTEND, MVT::v16i32, MVT::v16i16, 8 }, 1727 { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i32, 3 }, 1728 { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i32, 5 }, 1729 1730 { ISD::TRUNCATE, MVT::v2i8, MVT::v2i16, 2 }, // PAND+PACKUSWB 1731 { ISD::TRUNCATE, MVT::v4i8, MVT::v4i16, 4 }, 1732 { ISD::TRUNCATE, MVT::v8i8, MVT::v8i16, 2 }, 1733 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i16, 3 }, 1734 { ISD::TRUNCATE, MVT::v2i8, MVT::v2i32, 3 }, // PAND+3*PACKUSWB 1735 { ISD::TRUNCATE, MVT::v2i16, MVT::v2i32, 1 }, 1736 { ISD::TRUNCATE, MVT::v4i8, MVT::v4i32, 3 }, 1737 { ISD::TRUNCATE, MVT::v4i16, MVT::v4i32, 3 }, 1738 { ISD::TRUNCATE, MVT::v8i8, MVT::v8i32, 4 }, 1739 { ISD::TRUNCATE, MVT::v16i8, MVT::v16i32, 7 }, 1740 { ISD::TRUNCATE, MVT::v8i16, MVT::v8i32, 5 }, 1741 { ISD::TRUNCATE, MVT::v16i16, MVT::v16i32, 10 }, 1742 { ISD::TRUNCATE, MVT::v2i8, MVT::v2i64, 4 }, // PAND+3*PACKUSWB 1743 { ISD::TRUNCATE, MVT::v2i16, MVT::v2i64, 2 }, // PSHUFD+PSHUFLW 1744 { ISD::TRUNCATE, MVT::v2i32, MVT::v2i64, 1 }, // PSHUFD 1745 }; 1746 1747 std::pair<int, MVT> LTSrc = TLI->getTypeLegalizationCost(DL, Src); 1748 std::pair<int, MVT> LTDest = TLI->getTypeLegalizationCost(DL, Dst); 1749 1750 if (ST->hasSSE2() && !ST->hasAVX()) { 1751 if (const auto *Entry = ConvertCostTableLookup(SSE2ConversionTbl, ISD, 1752 LTDest.second, LTSrc.second)) 1753 return LTSrc.first * Entry->Cost; 1754 } 1755 1756 EVT SrcTy = TLI->getValueType(DL, Src); 1757 EVT DstTy = TLI->getValueType(DL, Dst); 1758 1759 // The function getSimpleVT only handles simple value types. 1760 if (!SrcTy.isSimple() || !DstTy.isSimple()) 1761 return BaseT::getCastInstrCost(Opcode, Dst, Src); 1762 1763 MVT SimpleSrcTy = SrcTy.getSimpleVT(); 1764 MVT SimpleDstTy = DstTy.getSimpleVT(); 1765 1766 if (ST->useAVX512Regs()) { 1767 if (ST->hasBWI()) 1768 if (const auto *Entry = ConvertCostTableLookup(AVX512BWConversionTbl, ISD, 1769 SimpleDstTy, SimpleSrcTy)) 1770 return Entry->Cost; 1771 1772 if (ST->hasDQI()) 1773 if (const auto *Entry = ConvertCostTableLookup(AVX512DQConversionTbl, ISD, 1774 SimpleDstTy, SimpleSrcTy)) 1775 return Entry->Cost; 1776 1777 if (ST->hasAVX512()) 1778 if (const auto *Entry = ConvertCostTableLookup(AVX512FConversionTbl, ISD, 1779 SimpleDstTy, SimpleSrcTy)) 1780 return Entry->Cost; 1781 } 1782 1783 if (ST->hasBWI()) 1784 if (const auto *Entry = ConvertCostTableLookup(AVX512BWVLConversionTbl, ISD, 1785 SimpleDstTy, SimpleSrcTy)) 1786 return Entry->Cost; 1787 1788 if (ST->hasDQI()) 1789 if (const auto *Entry = ConvertCostTableLookup(AVX512DQVLConversionTbl, ISD, 1790 SimpleDstTy, SimpleSrcTy)) 1791 return Entry->Cost; 1792 1793 if (ST->hasAVX512()) 1794 if (const auto *Entry = ConvertCostTableLookup(AVX512VLConversionTbl, ISD, 1795 SimpleDstTy, SimpleSrcTy)) 1796 return Entry->Cost; 1797 1798 if (ST->hasAVX2()) { 1799 if (const auto *Entry = ConvertCostTableLookup(AVX2ConversionTbl, ISD, 1800 SimpleDstTy, SimpleSrcTy)) 1801 return Entry->Cost; 1802 } 1803 1804 if (ST->hasAVX()) { 1805 if (const auto *Entry = ConvertCostTableLookup(AVXConversionTbl, ISD, 1806 SimpleDstTy, SimpleSrcTy)) 1807 return Entry->Cost; 1808 } 1809 1810 if (ST->hasSSE41()) { 1811 if (const auto *Entry = ConvertCostTableLookup(SSE41ConversionTbl, ISD, 1812 SimpleDstTy, SimpleSrcTy)) 1813 return Entry->Cost; 1814 } 1815 1816 if (ST->hasSSE2()) { 1817 if (const auto *Entry = ConvertCostTableLookup(SSE2ConversionTbl, ISD, 1818 SimpleDstTy, SimpleSrcTy)) 1819 return Entry->Cost; 1820 } 1821 1822 return BaseT::getCastInstrCost(Opcode, Dst, Src, I); 1823 } 1824 1825 int X86TTIImpl::getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy, 1826 const Instruction *I) { 1827 // Legalize the type. 1828 std::pair<int, MVT> LT = TLI->getTypeLegalizationCost(DL, ValTy); 1829 1830 MVT MTy = LT.second; 1831 1832 int ISD = TLI->InstructionOpcodeToISD(Opcode); 1833 assert(ISD && "Invalid opcode"); 1834 1835 unsigned ExtraCost = 0; 1836 if (I && (Opcode == Instruction::ICmp || Opcode == Instruction::FCmp)) { 1837 // Some vector comparison predicates cost extra instructions. 1838 if (MTy.isVector() && 1839 !((ST->hasXOP() && (!ST->hasAVX2() || MTy.is128BitVector())) || 1840 (ST->hasAVX512() && 32 <= MTy.getScalarSizeInBits()) || 1841 ST->hasBWI())) { 1842 switch (cast<CmpInst>(I)->getPredicate()) { 1843 case CmpInst::Predicate::ICMP_NE: 1844 // xor(cmpeq(x,y),-1) 1845 ExtraCost = 1; 1846 break; 1847 case CmpInst::Predicate::ICMP_SGE: 1848 case CmpInst::Predicate::ICMP_SLE: 1849 // xor(cmpgt(x,y),-1) 1850 ExtraCost = 1; 1851 break; 1852 case CmpInst::Predicate::ICMP_ULT: 1853 case CmpInst::Predicate::ICMP_UGT: 1854 // cmpgt(xor(x,signbit),xor(y,signbit)) 1855 // xor(cmpeq(pmaxu(x,y),x),-1) 1856 ExtraCost = 2; 1857 break; 1858 case CmpInst::Predicate::ICMP_ULE: 1859 case CmpInst::Predicate::ICMP_UGE: 1860 if ((ST->hasSSE41() && MTy.getScalarSizeInBits() == 32) || 1861 (ST->hasSSE2() && MTy.getScalarSizeInBits() < 32)) { 1862 // cmpeq(psubus(x,y),0) 1863 // cmpeq(pminu(x,y),x) 1864 ExtraCost = 1; 1865 } else { 1866 // xor(cmpgt(xor(x,signbit),xor(y,signbit)),-1) 1867 ExtraCost = 3; 1868 } 1869 break; 1870 default: 1871 break; 1872 } 1873 } 1874 } 1875 1876 static const CostTblEntry SLMCostTbl[] = { 1877 // slm pcmpeq/pcmpgt throughput is 2 1878 { ISD::SETCC, MVT::v2i64, 2 }, 1879 }; 1880 1881 static const CostTblEntry AVX512BWCostTbl[] = { 1882 { ISD::SETCC, MVT::v32i16, 1 }, 1883 { ISD::SETCC, MVT::v64i8, 1 }, 1884 1885 { ISD::SELECT, MVT::v32i16, 1 }, 1886 { ISD::SELECT, MVT::v64i8, 1 }, 1887 }; 1888 1889 static const CostTblEntry AVX512CostTbl[] = { 1890 { ISD::SETCC, MVT::v8i64, 1 }, 1891 { ISD::SETCC, MVT::v16i32, 1 }, 1892 { ISD::SETCC, MVT::v8f64, 1 }, 1893 { ISD::SETCC, MVT::v16f32, 1 }, 1894 1895 { ISD::SELECT, MVT::v8i64, 1 }, 1896 { ISD::SELECT, MVT::v16i32, 1 }, 1897 { ISD::SELECT, MVT::v8f64, 1 }, 1898 { ISD::SELECT, MVT::v16f32, 1 }, 1899 1900 { ISD::SETCC, MVT::v32i16, 2 }, // FIXME: should probably be 4 1901 { ISD::SETCC, MVT::v64i8, 2 }, // FIXME: should probably be 4 1902 1903 { ISD::SELECT, MVT::v32i16, 2 }, // FIXME: should be 3 1904 { ISD::SELECT, MVT::v64i8, 2 }, // FIXME: should be 3 1905 }; 1906 1907 static const CostTblEntry AVX2CostTbl[] = { 1908 { ISD::SETCC, MVT::v4i64, 1 }, 1909 { ISD::SETCC, MVT::v8i32, 1 }, 1910 { ISD::SETCC, MVT::v16i16, 1 }, 1911 { ISD::SETCC, MVT::v32i8, 1 }, 1912 1913 { ISD::SELECT, MVT::v4i64, 1 }, // pblendvb 1914 { ISD::SELECT, MVT::v8i32, 1 }, // pblendvb 1915 { ISD::SELECT, MVT::v16i16, 1 }, // pblendvb 1916 { ISD::SELECT, MVT::v32i8, 1 }, // pblendvb 1917 }; 1918 1919 static const CostTblEntry AVX1CostTbl[] = { 1920 { ISD::SETCC, MVT::v4f64, 1 }, 1921 { ISD::SETCC, MVT::v8f32, 1 }, 1922 // AVX1 does not support 8-wide integer compare. 1923 { ISD::SETCC, MVT::v4i64, 4 }, 1924 { ISD::SETCC, MVT::v8i32, 4 }, 1925 { ISD::SETCC, MVT::v16i16, 4 }, 1926 { ISD::SETCC, MVT::v32i8, 4 }, 1927 1928 { ISD::SELECT, MVT::v4f64, 1 }, // vblendvpd 1929 { ISD::SELECT, MVT::v8f32, 1 }, // vblendvps 1930 { ISD::SELECT, MVT::v4i64, 1 }, // vblendvpd 1931 { ISD::SELECT, MVT::v8i32, 1 }, // vblendvps 1932 { ISD::SELECT, MVT::v16i16, 3 }, // vandps + vandnps + vorps 1933 { ISD::SELECT, MVT::v32i8, 3 }, // vandps + vandnps + vorps 1934 }; 1935 1936 static const CostTblEntry SSE42CostTbl[] = { 1937 { ISD::SETCC, MVT::v2f64, 1 }, 1938 { ISD::SETCC, MVT::v4f32, 1 }, 1939 { ISD::SETCC, MVT::v2i64, 1 }, 1940 }; 1941 1942 static const CostTblEntry SSE41CostTbl[] = { 1943 { ISD::SELECT, MVT::v2f64, 1 }, // blendvpd 1944 { ISD::SELECT, MVT::v4f32, 1 }, // blendvps 1945 { ISD::SELECT, MVT::v2i64, 1 }, // pblendvb 1946 { ISD::SELECT, MVT::v4i32, 1 }, // pblendvb 1947 { ISD::SELECT, MVT::v8i16, 1 }, // pblendvb 1948 { ISD::SELECT, MVT::v16i8, 1 }, // pblendvb 1949 }; 1950 1951 static const CostTblEntry SSE2CostTbl[] = { 1952 { ISD::SETCC, MVT::v2f64, 2 }, 1953 { ISD::SETCC, MVT::f64, 1 }, 1954 { ISD::SETCC, MVT::v2i64, 8 }, 1955 { ISD::SETCC, MVT::v4i32, 1 }, 1956 { ISD::SETCC, MVT::v8i16, 1 }, 1957 { ISD::SETCC, MVT::v16i8, 1 }, 1958 1959 { ISD::SELECT, MVT::v2f64, 3 }, // andpd + andnpd + orpd 1960 { ISD::SELECT, MVT::v2i64, 3 }, // pand + pandn + por 1961 { ISD::SELECT, MVT::v4i32, 3 }, // pand + pandn + por 1962 { ISD::SELECT, MVT::v8i16, 3 }, // pand + pandn + por 1963 { ISD::SELECT, MVT::v16i8, 3 }, // pand + pandn + por 1964 }; 1965 1966 static const CostTblEntry SSE1CostTbl[] = { 1967 { ISD::SETCC, MVT::v4f32, 2 }, 1968 { ISD::SETCC, MVT::f32, 1 }, 1969 1970 { ISD::SELECT, MVT::v4f32, 3 }, // andps + andnps + orps 1971 }; 1972 1973 if (ST->isSLM()) 1974 if (const auto *Entry = CostTableLookup(SLMCostTbl, ISD, MTy)) 1975 return LT.first * (ExtraCost + Entry->Cost); 1976 1977 if (ST->hasBWI()) 1978 if (const auto *Entry = CostTableLookup(AVX512BWCostTbl, ISD, MTy)) 1979 return LT.first * (ExtraCost + Entry->Cost); 1980 1981 if (ST->hasAVX512()) 1982 if (const auto *Entry = CostTableLookup(AVX512CostTbl, ISD, MTy)) 1983 return LT.first * (ExtraCost + Entry->Cost); 1984 1985 if (ST->hasAVX2()) 1986 if (const auto *Entry = CostTableLookup(AVX2CostTbl, ISD, MTy)) 1987 return LT.first * (ExtraCost + Entry->Cost); 1988 1989 if (ST->hasAVX()) 1990 if (const auto *Entry = CostTableLookup(AVX1CostTbl, ISD, MTy)) 1991 return LT.first * (ExtraCost + Entry->Cost); 1992 1993 if (ST->hasSSE42()) 1994 if (const auto *Entry = CostTableLookup(SSE42CostTbl, ISD, MTy)) 1995 return LT.first * (ExtraCost + Entry->Cost); 1996 1997 if (ST->hasSSE41()) 1998 if (const auto *Entry = CostTableLookup(SSE41CostTbl, ISD, MTy)) 1999 return LT.first * (ExtraCost + Entry->Cost); 2000 2001 if (ST->hasSSE2()) 2002 if (const auto *Entry = CostTableLookup(SSE2CostTbl, ISD, MTy)) 2003 return LT.first * (ExtraCost + Entry->Cost); 2004 2005 if (ST->hasSSE1()) 2006 if (const auto *Entry = CostTableLookup(SSE1CostTbl, ISD, MTy)) 2007 return LT.first * (ExtraCost + Entry->Cost); 2008 2009 return BaseT::getCmpSelInstrCost(Opcode, ValTy, CondTy, I); 2010 } 2011 2012 unsigned X86TTIImpl::getAtomicMemIntrinsicMaxElementSize() const { return 16; } 2013 2014 int X86TTIImpl::getIntrinsicInstrCost(Intrinsic::ID IID, Type *RetTy, 2015 ArrayRef<Type *> Tys, FastMathFlags FMF, 2016 unsigned ScalarizationCostPassed, 2017 const Instruction *I) { 2018 // Costs should match the codegen from: 2019 // BITREVERSE: llvm\test\CodeGen\X86\vector-bitreverse.ll 2020 // BSWAP: llvm\test\CodeGen\X86\bswap-vector.ll 2021 // CTLZ: llvm\test\CodeGen\X86\vector-lzcnt-*.ll 2022 // CTPOP: llvm\test\CodeGen\X86\vector-popcnt-*.ll 2023 // CTTZ: llvm\test\CodeGen\X86\vector-tzcnt-*.ll 2024 static const CostTblEntry AVX512CDCostTbl[] = { 2025 { ISD::CTLZ, MVT::v8i64, 1 }, 2026 { ISD::CTLZ, MVT::v16i32, 1 }, 2027 { ISD::CTLZ, MVT::v32i16, 8 }, 2028 { ISD::CTLZ, MVT::v64i8, 20 }, 2029 { ISD::CTLZ, MVT::v4i64, 1 }, 2030 { ISD::CTLZ, MVT::v8i32, 1 }, 2031 { ISD::CTLZ, MVT::v16i16, 4 }, 2032 { ISD::CTLZ, MVT::v32i8, 10 }, 2033 { ISD::CTLZ, MVT::v2i64, 1 }, 2034 { ISD::CTLZ, MVT::v4i32, 1 }, 2035 { ISD::CTLZ, MVT::v8i16, 4 }, 2036 { ISD::CTLZ, MVT::v16i8, 4 }, 2037 }; 2038 static const CostTblEntry AVX512BWCostTbl[] = { 2039 { ISD::BITREVERSE, MVT::v8i64, 5 }, 2040 { ISD::BITREVERSE, MVT::v16i32, 5 }, 2041 { ISD::BITREVERSE, MVT::v32i16, 5 }, 2042 { ISD::BITREVERSE, MVT::v64i8, 5 }, 2043 { ISD::CTLZ, MVT::v8i64, 23 }, 2044 { ISD::CTLZ, MVT::v16i32, 22 }, 2045 { ISD::CTLZ, MVT::v32i16, 18 }, 2046 { ISD::CTLZ, MVT::v64i8, 17 }, 2047 { ISD::CTPOP, MVT::v8i64, 7 }, 2048 { ISD::CTPOP, MVT::v16i32, 11 }, 2049 { ISD::CTPOP, MVT::v32i16, 9 }, 2050 { ISD::CTPOP, MVT::v64i8, 6 }, 2051 { ISD::CTTZ, MVT::v8i64, 10 }, 2052 { ISD::CTTZ, MVT::v16i32, 14 }, 2053 { ISD::CTTZ, MVT::v32i16, 12 }, 2054 { ISD::CTTZ, MVT::v64i8, 9 }, 2055 { ISD::SADDSAT, MVT::v32i16, 1 }, 2056 { ISD::SADDSAT, MVT::v64i8, 1 }, 2057 { ISD::SSUBSAT, MVT::v32i16, 1 }, 2058 { ISD::SSUBSAT, MVT::v64i8, 1 }, 2059 { ISD::UADDSAT, MVT::v32i16, 1 }, 2060 { ISD::UADDSAT, MVT::v64i8, 1 }, 2061 { ISD::USUBSAT, MVT::v32i16, 1 }, 2062 { ISD::USUBSAT, MVT::v64i8, 1 }, 2063 }; 2064 static const CostTblEntry AVX512CostTbl[] = { 2065 { ISD::BITREVERSE, MVT::v8i64, 36 }, 2066 { ISD::BITREVERSE, MVT::v16i32, 24 }, 2067 { ISD::BITREVERSE, MVT::v32i16, 10 }, 2068 { ISD::BITREVERSE, MVT::v64i8, 10 }, 2069 { ISD::CTLZ, MVT::v8i64, 29 }, 2070 { ISD::CTLZ, MVT::v16i32, 35 }, 2071 { ISD::CTLZ, MVT::v32i16, 28 }, 2072 { ISD::CTLZ, MVT::v64i8, 18 }, 2073 { ISD::CTPOP, MVT::v8i64, 16 }, 2074 { ISD::CTPOP, MVT::v16i32, 24 }, 2075 { ISD::CTPOP, MVT::v32i16, 18 }, 2076 { ISD::CTPOP, MVT::v64i8, 12 }, 2077 { ISD::CTTZ, MVT::v8i64, 20 }, 2078 { ISD::CTTZ, MVT::v16i32, 28 }, 2079 { ISD::CTTZ, MVT::v32i16, 24 }, 2080 { ISD::CTTZ, MVT::v64i8, 18 }, 2081 { ISD::USUBSAT, MVT::v16i32, 2 }, // pmaxud + psubd 2082 { ISD::USUBSAT, MVT::v2i64, 2 }, // pmaxuq + psubq 2083 { ISD::USUBSAT, MVT::v4i64, 2 }, // pmaxuq + psubq 2084 { ISD::USUBSAT, MVT::v8i64, 2 }, // pmaxuq + psubq 2085 { ISD::UADDSAT, MVT::v16i32, 3 }, // not + pminud + paddd 2086 { ISD::UADDSAT, MVT::v2i64, 3 }, // not + pminuq + paddq 2087 { ISD::UADDSAT, MVT::v4i64, 3 }, // not + pminuq + paddq 2088 { ISD::UADDSAT, MVT::v8i64, 3 }, // not + pminuq + paddq 2089 { ISD::SADDSAT, MVT::v32i16, 2 }, // FIXME: include split 2090 { ISD::SADDSAT, MVT::v64i8, 2 }, // FIXME: include split 2091 { ISD::SSUBSAT, MVT::v32i16, 2 }, // FIXME: include split 2092 { ISD::SSUBSAT, MVT::v64i8, 2 }, // FIXME: include split 2093 { ISD::UADDSAT, MVT::v32i16, 2 }, // FIXME: include split 2094 { ISD::UADDSAT, MVT::v64i8, 2 }, // FIXME: include split 2095 { ISD::USUBSAT, MVT::v32i16, 2 }, // FIXME: include split 2096 { ISD::USUBSAT, MVT::v64i8, 2 }, // FIXME: include split 2097 { ISD::FMAXNUM, MVT::f32, 2 }, 2098 { ISD::FMAXNUM, MVT::v4f32, 2 }, 2099 { ISD::FMAXNUM, MVT::v8f32, 2 }, 2100 { ISD::FMAXNUM, MVT::v16f32, 2 }, 2101 { ISD::FMAXNUM, MVT::f64, 2 }, 2102 { ISD::FMAXNUM, MVT::v2f64, 2 }, 2103 { ISD::FMAXNUM, MVT::v4f64, 2 }, 2104 { ISD::FMAXNUM, MVT::v8f64, 2 }, 2105 }; 2106 static const CostTblEntry XOPCostTbl[] = { 2107 { ISD::BITREVERSE, MVT::v4i64, 4 }, 2108 { ISD::BITREVERSE, MVT::v8i32, 4 }, 2109 { ISD::BITREVERSE, MVT::v16i16, 4 }, 2110 { ISD::BITREVERSE, MVT::v32i8, 4 }, 2111 { ISD::BITREVERSE, MVT::v2i64, 1 }, 2112 { ISD::BITREVERSE, MVT::v4i32, 1 }, 2113 { ISD::BITREVERSE, MVT::v8i16, 1 }, 2114 { ISD::BITREVERSE, MVT::v16i8, 1 }, 2115 { ISD::BITREVERSE, MVT::i64, 3 }, 2116 { ISD::BITREVERSE, MVT::i32, 3 }, 2117 { ISD::BITREVERSE, MVT::i16, 3 }, 2118 { ISD::BITREVERSE, MVT::i8, 3 } 2119 }; 2120 static const CostTblEntry AVX2CostTbl[] = { 2121 { ISD::BITREVERSE, MVT::v4i64, 5 }, 2122 { ISD::BITREVERSE, MVT::v8i32, 5 }, 2123 { ISD::BITREVERSE, MVT::v16i16, 5 }, 2124 { ISD::BITREVERSE, MVT::v32i8, 5 }, 2125 { ISD::BSWAP, MVT::v4i64, 1 }, 2126 { ISD::BSWAP, MVT::v8i32, 1 }, 2127 { ISD::BSWAP, MVT::v16i16, 1 }, 2128 { ISD::CTLZ, MVT::v4i64, 23 }, 2129 { ISD::CTLZ, MVT::v8i32, 18 }, 2130 { ISD::CTLZ, MVT::v16i16, 14 }, 2131 { ISD::CTLZ, MVT::v32i8, 9 }, 2132 { ISD::CTPOP, MVT::v4i64, 7 }, 2133 { ISD::CTPOP, MVT::v8i32, 11 }, 2134 { ISD::CTPOP, MVT::v16i16, 9 }, 2135 { ISD::CTPOP, MVT::v32i8, 6 }, 2136 { ISD::CTTZ, MVT::v4i64, 10 }, 2137 { ISD::CTTZ, MVT::v8i32, 14 }, 2138 { ISD::CTTZ, MVT::v16i16, 12 }, 2139 { ISD::CTTZ, MVT::v32i8, 9 }, 2140 { ISD::SADDSAT, MVT::v16i16, 1 }, 2141 { ISD::SADDSAT, MVT::v32i8, 1 }, 2142 { ISD::SSUBSAT, MVT::v16i16, 1 }, 2143 { ISD::SSUBSAT, MVT::v32i8, 1 }, 2144 { ISD::UADDSAT, MVT::v16i16, 1 }, 2145 { ISD::UADDSAT, MVT::v32i8, 1 }, 2146 { ISD::UADDSAT, MVT::v8i32, 3 }, // not + pminud + paddd 2147 { ISD::USUBSAT, MVT::v16i16, 1 }, 2148 { ISD::USUBSAT, MVT::v32i8, 1 }, 2149 { ISD::USUBSAT, MVT::v8i32, 2 }, // pmaxud + psubd 2150 { ISD::FSQRT, MVT::f32, 7 }, // Haswell from http://www.agner.org/ 2151 { ISD::FSQRT, MVT::v4f32, 7 }, // Haswell from http://www.agner.org/ 2152 { ISD::FSQRT, MVT::v8f32, 14 }, // Haswell from http://www.agner.org/ 2153 { ISD::FSQRT, MVT::f64, 14 }, // Haswell from http://www.agner.org/ 2154 { ISD::FSQRT, MVT::v2f64, 14 }, // Haswell from http://www.agner.org/ 2155 { ISD::FSQRT, MVT::v4f64, 28 }, // Haswell from http://www.agner.org/ 2156 }; 2157 static const CostTblEntry AVX1CostTbl[] = { 2158 { ISD::BITREVERSE, MVT::v4i64, 12 }, // 2 x 128-bit Op + extract/insert 2159 { ISD::BITREVERSE, MVT::v8i32, 12 }, // 2 x 128-bit Op + extract/insert 2160 { ISD::BITREVERSE, MVT::v16i16, 12 }, // 2 x 128-bit Op + extract/insert 2161 { ISD::BITREVERSE, MVT::v32i8, 12 }, // 2 x 128-bit Op + extract/insert 2162 { ISD::BSWAP, MVT::v4i64, 4 }, 2163 { ISD::BSWAP, MVT::v8i32, 4 }, 2164 { ISD::BSWAP, MVT::v16i16, 4 }, 2165 { ISD::CTLZ, MVT::v4i64, 48 }, // 2 x 128-bit Op + extract/insert 2166 { ISD::CTLZ, MVT::v8i32, 38 }, // 2 x 128-bit Op + extract/insert 2167 { ISD::CTLZ, MVT::v16i16, 30 }, // 2 x 128-bit Op + extract/insert 2168 { ISD::CTLZ, MVT::v32i8, 20 }, // 2 x 128-bit Op + extract/insert 2169 { ISD::CTPOP, MVT::v4i64, 16 }, // 2 x 128-bit Op + extract/insert 2170 { ISD::CTPOP, MVT::v8i32, 24 }, // 2 x 128-bit Op + extract/insert 2171 { ISD::CTPOP, MVT::v16i16, 20 }, // 2 x 128-bit Op + extract/insert 2172 { ISD::CTPOP, MVT::v32i8, 14 }, // 2 x 128-bit Op + extract/insert 2173 { ISD::CTTZ, MVT::v4i64, 22 }, // 2 x 128-bit Op + extract/insert 2174 { ISD::CTTZ, MVT::v8i32, 30 }, // 2 x 128-bit Op + extract/insert 2175 { ISD::CTTZ, MVT::v16i16, 26 }, // 2 x 128-bit Op + extract/insert 2176 { ISD::CTTZ, MVT::v32i8, 20 }, // 2 x 128-bit Op + extract/insert 2177 { ISD::SADDSAT, MVT::v16i16, 4 }, // 2 x 128-bit Op + extract/insert 2178 { ISD::SADDSAT, MVT::v32i8, 4 }, // 2 x 128-bit Op + extract/insert 2179 { ISD::SSUBSAT, MVT::v16i16, 4 }, // 2 x 128-bit Op + extract/insert 2180 { ISD::SSUBSAT, MVT::v32i8, 4 }, // 2 x 128-bit Op + extract/insert 2181 { ISD::UADDSAT, MVT::v16i16, 4 }, // 2 x 128-bit Op + extract/insert 2182 { ISD::UADDSAT, MVT::v32i8, 4 }, // 2 x 128-bit Op + extract/insert 2183 { ISD::UADDSAT, MVT::v8i32, 8 }, // 2 x 128-bit Op + extract/insert 2184 { ISD::USUBSAT, MVT::v16i16, 4 }, // 2 x 128-bit Op + extract/insert 2185 { ISD::USUBSAT, MVT::v32i8, 4 }, // 2 x 128-bit Op + extract/insert 2186 { ISD::USUBSAT, MVT::v8i32, 6 }, // 2 x 128-bit Op + extract/insert 2187 { ISD::FMAXNUM, MVT::f32, 3 }, 2188 { ISD::FMAXNUM, MVT::v4f32, 3 }, 2189 { ISD::FMAXNUM, MVT::v8f32, 5 }, 2190 { ISD::FMAXNUM, MVT::f64, 3 }, 2191 { ISD::FMAXNUM, MVT::v2f64, 3 }, 2192 { ISD::FMAXNUM, MVT::v4f64, 5 }, 2193 { ISD::FSQRT, MVT::f32, 14 }, // SNB from http://www.agner.org/ 2194 { ISD::FSQRT, MVT::v4f32, 14 }, // SNB from http://www.agner.org/ 2195 { ISD::FSQRT, MVT::v8f32, 28 }, // SNB from http://www.agner.org/ 2196 { ISD::FSQRT, MVT::f64, 21 }, // SNB from http://www.agner.org/ 2197 { ISD::FSQRT, MVT::v2f64, 21 }, // SNB from http://www.agner.org/ 2198 { ISD::FSQRT, MVT::v4f64, 43 }, // SNB from http://www.agner.org/ 2199 }; 2200 static const CostTblEntry GLMCostTbl[] = { 2201 { ISD::FSQRT, MVT::f32, 19 }, // sqrtss 2202 { ISD::FSQRT, MVT::v4f32, 37 }, // sqrtps 2203 { ISD::FSQRT, MVT::f64, 34 }, // sqrtsd 2204 { ISD::FSQRT, MVT::v2f64, 67 }, // sqrtpd 2205 }; 2206 static const CostTblEntry SLMCostTbl[] = { 2207 { ISD::FSQRT, MVT::f32, 20 }, // sqrtss 2208 { ISD::FSQRT, MVT::v4f32, 40 }, // sqrtps 2209 { ISD::FSQRT, MVT::f64, 35 }, // sqrtsd 2210 { ISD::FSQRT, MVT::v2f64, 70 }, // sqrtpd 2211 }; 2212 static const CostTblEntry SSE42CostTbl[] = { 2213 { ISD::USUBSAT, MVT::v4i32, 2 }, // pmaxud + psubd 2214 { ISD::UADDSAT, MVT::v4i32, 3 }, // not + pminud + paddd 2215 { ISD::FSQRT, MVT::f32, 18 }, // Nehalem from http://www.agner.org/ 2216 { ISD::FSQRT, MVT::v4f32, 18 }, // Nehalem from http://www.agner.org/ 2217 }; 2218 static const CostTblEntry SSSE3CostTbl[] = { 2219 { ISD::BITREVERSE, MVT::v2i64, 5 }, 2220 { ISD::BITREVERSE, MVT::v4i32, 5 }, 2221 { ISD::BITREVERSE, MVT::v8i16, 5 }, 2222 { ISD::BITREVERSE, MVT::v16i8, 5 }, 2223 { ISD::BSWAP, MVT::v2i64, 1 }, 2224 { ISD::BSWAP, MVT::v4i32, 1 }, 2225 { ISD::BSWAP, MVT::v8i16, 1 }, 2226 { ISD::CTLZ, MVT::v2i64, 23 }, 2227 { ISD::CTLZ, MVT::v4i32, 18 }, 2228 { ISD::CTLZ, MVT::v8i16, 14 }, 2229 { ISD::CTLZ, MVT::v16i8, 9 }, 2230 { ISD::CTPOP, MVT::v2i64, 7 }, 2231 { ISD::CTPOP, MVT::v4i32, 11 }, 2232 { ISD::CTPOP, MVT::v8i16, 9 }, 2233 { ISD::CTPOP, MVT::v16i8, 6 }, 2234 { ISD::CTTZ, MVT::v2i64, 10 }, 2235 { ISD::CTTZ, MVT::v4i32, 14 }, 2236 { ISD::CTTZ, MVT::v8i16, 12 }, 2237 { ISD::CTTZ, MVT::v16i8, 9 } 2238 }; 2239 static const CostTblEntry SSE2CostTbl[] = { 2240 { ISD::BITREVERSE, MVT::v2i64, 29 }, 2241 { ISD::BITREVERSE, MVT::v4i32, 27 }, 2242 { ISD::BITREVERSE, MVT::v8i16, 27 }, 2243 { ISD::BITREVERSE, MVT::v16i8, 20 }, 2244 { ISD::BSWAP, MVT::v2i64, 7 }, 2245 { ISD::BSWAP, MVT::v4i32, 7 }, 2246 { ISD::BSWAP, MVT::v8i16, 7 }, 2247 { ISD::CTLZ, MVT::v2i64, 25 }, 2248 { ISD::CTLZ, MVT::v4i32, 26 }, 2249 { ISD::CTLZ, MVT::v8i16, 20 }, 2250 { ISD::CTLZ, MVT::v16i8, 17 }, 2251 { ISD::CTPOP, MVT::v2i64, 12 }, 2252 { ISD::CTPOP, MVT::v4i32, 15 }, 2253 { ISD::CTPOP, MVT::v8i16, 13 }, 2254 { ISD::CTPOP, MVT::v16i8, 10 }, 2255 { ISD::CTTZ, MVT::v2i64, 14 }, 2256 { ISD::CTTZ, MVT::v4i32, 18 }, 2257 { ISD::CTTZ, MVT::v8i16, 16 }, 2258 { ISD::CTTZ, MVT::v16i8, 13 }, 2259 { ISD::SADDSAT, MVT::v8i16, 1 }, 2260 { ISD::SADDSAT, MVT::v16i8, 1 }, 2261 { ISD::SSUBSAT, MVT::v8i16, 1 }, 2262 { ISD::SSUBSAT, MVT::v16i8, 1 }, 2263 { ISD::UADDSAT, MVT::v8i16, 1 }, 2264 { ISD::UADDSAT, MVT::v16i8, 1 }, 2265 { ISD::USUBSAT, MVT::v8i16, 1 }, 2266 { ISD::USUBSAT, MVT::v16i8, 1 }, 2267 { ISD::FMAXNUM, MVT::f64, 4 }, 2268 { ISD::FMAXNUM, MVT::v2f64, 4 }, 2269 { ISD::FSQRT, MVT::f64, 32 }, // Nehalem from http://www.agner.org/ 2270 { ISD::FSQRT, MVT::v2f64, 32 }, // Nehalem from http://www.agner.org/ 2271 }; 2272 static const CostTblEntry SSE1CostTbl[] = { 2273 { ISD::FMAXNUM, MVT::f32, 4 }, 2274 { ISD::FMAXNUM, MVT::v4f32, 4 }, 2275 { ISD::FSQRT, MVT::f32, 28 }, // Pentium III from http://www.agner.org/ 2276 { ISD::FSQRT, MVT::v4f32, 56 }, // Pentium III from http://www.agner.org/ 2277 }; 2278 static const CostTblEntry BMI64CostTbl[] = { // 64-bit targets 2279 { ISD::CTTZ, MVT::i64, 1 }, 2280 }; 2281 static const CostTblEntry BMI32CostTbl[] = { // 32 or 64-bit targets 2282 { ISD::CTTZ, MVT::i32, 1 }, 2283 { ISD::CTTZ, MVT::i16, 1 }, 2284 { ISD::CTTZ, MVT::i8, 1 }, 2285 }; 2286 static const CostTblEntry LZCNT64CostTbl[] = { // 64-bit targets 2287 { ISD::CTLZ, MVT::i64, 1 }, 2288 }; 2289 static const CostTblEntry LZCNT32CostTbl[] = { // 32 or 64-bit targets 2290 { ISD::CTLZ, MVT::i32, 1 }, 2291 { ISD::CTLZ, MVT::i16, 1 }, 2292 { ISD::CTLZ, MVT::i8, 1 }, 2293 }; 2294 static const CostTblEntry POPCNT64CostTbl[] = { // 64-bit targets 2295 { ISD::CTPOP, MVT::i64, 1 }, 2296 }; 2297 static const CostTblEntry POPCNT32CostTbl[] = { // 32 or 64-bit targets 2298 { ISD::CTPOP, MVT::i32, 1 }, 2299 { ISD::CTPOP, MVT::i16, 1 }, 2300 { ISD::CTPOP, MVT::i8, 1 }, 2301 }; 2302 static const CostTblEntry X64CostTbl[] = { // 64-bit targets 2303 { ISD::BITREVERSE, MVT::i64, 14 }, 2304 { ISD::CTLZ, MVT::i64, 4 }, // BSR+XOR or BSR+XOR+CMOV 2305 { ISD::CTTZ, MVT::i64, 3 }, // TEST+BSF+CMOV/BRANCH 2306 { ISD::CTPOP, MVT::i64, 10 }, 2307 { ISD::SADDO, MVT::i64, 1 }, 2308 { ISD::UADDO, MVT::i64, 1 }, 2309 }; 2310 static const CostTblEntry X86CostTbl[] = { // 32 or 64-bit targets 2311 { ISD::BITREVERSE, MVT::i32, 14 }, 2312 { ISD::BITREVERSE, MVT::i16, 14 }, 2313 { ISD::BITREVERSE, MVT::i8, 11 }, 2314 { ISD::CTLZ, MVT::i32, 4 }, // BSR+XOR or BSR+XOR+CMOV 2315 { ISD::CTLZ, MVT::i16, 4 }, // BSR+XOR or BSR+XOR+CMOV 2316 { ISD::CTLZ, MVT::i8, 4 }, // BSR+XOR or BSR+XOR+CMOV 2317 { ISD::CTTZ, MVT::i32, 3 }, // TEST+BSF+CMOV/BRANCH 2318 { ISD::CTTZ, MVT::i16, 3 }, // TEST+BSF+CMOV/BRANCH 2319 { ISD::CTTZ, MVT::i8, 3 }, // TEST+BSF+CMOV/BRANCH 2320 { ISD::CTPOP, MVT::i32, 8 }, 2321 { ISD::CTPOP, MVT::i16, 9 }, 2322 { ISD::CTPOP, MVT::i8, 7 }, 2323 { ISD::SADDO, MVT::i32, 1 }, 2324 { ISD::SADDO, MVT::i16, 1 }, 2325 { ISD::SADDO, MVT::i8, 1 }, 2326 { ISD::UADDO, MVT::i32, 1 }, 2327 { ISD::UADDO, MVT::i16, 1 }, 2328 { ISD::UADDO, MVT::i8, 1 }, 2329 }; 2330 2331 Type *OpTy = RetTy; 2332 unsigned ISD = ISD::DELETED_NODE; 2333 switch (IID) { 2334 default: 2335 break; 2336 case Intrinsic::bitreverse: 2337 ISD = ISD::BITREVERSE; 2338 break; 2339 case Intrinsic::bswap: 2340 ISD = ISD::BSWAP; 2341 break; 2342 case Intrinsic::ctlz: 2343 ISD = ISD::CTLZ; 2344 break; 2345 case Intrinsic::ctpop: 2346 ISD = ISD::CTPOP; 2347 break; 2348 case Intrinsic::cttz: 2349 ISD = ISD::CTTZ; 2350 break; 2351 case Intrinsic::maxnum: 2352 case Intrinsic::minnum: 2353 // FMINNUM has same costs so don't duplicate. 2354 ISD = ISD::FMAXNUM; 2355 break; 2356 case Intrinsic::sadd_sat: 2357 ISD = ISD::SADDSAT; 2358 break; 2359 case Intrinsic::ssub_sat: 2360 ISD = ISD::SSUBSAT; 2361 break; 2362 case Intrinsic::uadd_sat: 2363 ISD = ISD::UADDSAT; 2364 break; 2365 case Intrinsic::usub_sat: 2366 ISD = ISD::USUBSAT; 2367 break; 2368 case Intrinsic::sqrt: 2369 ISD = ISD::FSQRT; 2370 break; 2371 case Intrinsic::sadd_with_overflow: 2372 case Intrinsic::ssub_with_overflow: 2373 // SSUBO has same costs so don't duplicate. 2374 ISD = ISD::SADDO; 2375 OpTy = RetTy->getContainedType(0); 2376 break; 2377 case Intrinsic::uadd_with_overflow: 2378 case Intrinsic::usub_with_overflow: 2379 // USUBO has same costs so don't duplicate. 2380 ISD = ISD::UADDO; 2381 OpTy = RetTy->getContainedType(0); 2382 break; 2383 } 2384 2385 if (ISD != ISD::DELETED_NODE) { 2386 // Legalize the type. 2387 std::pair<int, MVT> LT = TLI->getTypeLegalizationCost(DL, OpTy); 2388 MVT MTy = LT.second; 2389 2390 // Attempt to lookup cost. 2391 if (ST->useGLMDivSqrtCosts()) 2392 if (const auto *Entry = CostTableLookup(GLMCostTbl, ISD, MTy)) 2393 return LT.first * Entry->Cost; 2394 2395 if (ST->isSLM()) 2396 if (const auto *Entry = CostTableLookup(SLMCostTbl, ISD, MTy)) 2397 return LT.first * Entry->Cost; 2398 2399 if (ST->hasCDI()) 2400 if (const auto *Entry = CostTableLookup(AVX512CDCostTbl, ISD, MTy)) 2401 return LT.first * Entry->Cost; 2402 2403 if (ST->hasBWI()) 2404 if (const auto *Entry = CostTableLookup(AVX512BWCostTbl, ISD, MTy)) 2405 return LT.first * Entry->Cost; 2406 2407 if (ST->hasAVX512()) 2408 if (const auto *Entry = CostTableLookup(AVX512CostTbl, ISD, MTy)) 2409 return LT.first * Entry->Cost; 2410 2411 if (ST->hasXOP()) 2412 if (const auto *Entry = CostTableLookup(XOPCostTbl, ISD, MTy)) 2413 return LT.first * Entry->Cost; 2414 2415 if (ST->hasAVX2()) 2416 if (const auto *Entry = CostTableLookup(AVX2CostTbl, ISD, MTy)) 2417 return LT.first * Entry->Cost; 2418 2419 if (ST->hasAVX()) 2420 if (const auto *Entry = CostTableLookup(AVX1CostTbl, ISD, MTy)) 2421 return LT.first * Entry->Cost; 2422 2423 if (ST->hasSSE42()) 2424 if (const auto *Entry = CostTableLookup(SSE42CostTbl, ISD, MTy)) 2425 return LT.first * Entry->Cost; 2426 2427 if (ST->hasSSSE3()) 2428 if (const auto *Entry = CostTableLookup(SSSE3CostTbl, ISD, MTy)) 2429 return LT.first * Entry->Cost; 2430 2431 if (ST->hasSSE2()) 2432 if (const auto *Entry = CostTableLookup(SSE2CostTbl, ISD, MTy)) 2433 return LT.first * Entry->Cost; 2434 2435 if (ST->hasSSE1()) 2436 if (const auto *Entry = CostTableLookup(SSE1CostTbl, ISD, MTy)) 2437 return LT.first * Entry->Cost; 2438 2439 if (ST->hasBMI()) { 2440 if (ST->is64Bit()) 2441 if (const auto *Entry = CostTableLookup(BMI64CostTbl, ISD, MTy)) 2442 return LT.first * Entry->Cost; 2443 2444 if (const auto *Entry = CostTableLookup(BMI32CostTbl, ISD, MTy)) 2445 return LT.first * Entry->Cost; 2446 } 2447 2448 if (ST->hasLZCNT()) { 2449 if (ST->is64Bit()) 2450 if (const auto *Entry = CostTableLookup(LZCNT64CostTbl, ISD, MTy)) 2451 return LT.first * Entry->Cost; 2452 2453 if (const auto *Entry = CostTableLookup(LZCNT32CostTbl, ISD, MTy)) 2454 return LT.first * Entry->Cost; 2455 } 2456 2457 if (ST->hasPOPCNT()) { 2458 if (ST->is64Bit()) 2459 if (const auto *Entry = CostTableLookup(POPCNT64CostTbl, ISD, MTy)) 2460 return LT.first * Entry->Cost; 2461 2462 if (const auto *Entry = CostTableLookup(POPCNT32CostTbl, ISD, MTy)) 2463 return LT.first * Entry->Cost; 2464 } 2465 2466 // TODO - add BMI (TZCNT) scalar handling 2467 2468 if (ST->is64Bit()) 2469 if (const auto *Entry = CostTableLookup(X64CostTbl, ISD, MTy)) 2470 return LT.first * Entry->Cost; 2471 2472 if (const auto *Entry = CostTableLookup(X86CostTbl, ISD, MTy)) 2473 return LT.first * Entry->Cost; 2474 } 2475 2476 return BaseT::getIntrinsicInstrCost(IID, RetTy, Tys, FMF, 2477 ScalarizationCostPassed, I); 2478 } 2479 2480 int X86TTIImpl::getIntrinsicInstrCost(Intrinsic::ID IID, Type *RetTy, 2481 ArrayRef<Value *> Args, FastMathFlags FMF, 2482 unsigned VF, const Instruction *I) { 2483 static const CostTblEntry AVX512CostTbl[] = { 2484 { ISD::ROTL, MVT::v8i64, 1 }, 2485 { ISD::ROTL, MVT::v4i64, 1 }, 2486 { ISD::ROTL, MVT::v2i64, 1 }, 2487 { ISD::ROTL, MVT::v16i32, 1 }, 2488 { ISD::ROTL, MVT::v8i32, 1 }, 2489 { ISD::ROTL, MVT::v4i32, 1 }, 2490 { ISD::ROTR, MVT::v8i64, 1 }, 2491 { ISD::ROTR, MVT::v4i64, 1 }, 2492 { ISD::ROTR, MVT::v2i64, 1 }, 2493 { ISD::ROTR, MVT::v16i32, 1 }, 2494 { ISD::ROTR, MVT::v8i32, 1 }, 2495 { ISD::ROTR, MVT::v4i32, 1 } 2496 }; 2497 // XOP: ROTL = VPROT(X,Y), ROTR = VPROT(X,SUB(0,Y)) 2498 static const CostTblEntry XOPCostTbl[] = { 2499 { ISD::ROTL, MVT::v4i64, 4 }, 2500 { ISD::ROTL, MVT::v8i32, 4 }, 2501 { ISD::ROTL, MVT::v16i16, 4 }, 2502 { ISD::ROTL, MVT::v32i8, 4 }, 2503 { ISD::ROTL, MVT::v2i64, 1 }, 2504 { ISD::ROTL, MVT::v4i32, 1 }, 2505 { ISD::ROTL, MVT::v8i16, 1 }, 2506 { ISD::ROTL, MVT::v16i8, 1 }, 2507 { ISD::ROTR, MVT::v4i64, 6 }, 2508 { ISD::ROTR, MVT::v8i32, 6 }, 2509 { ISD::ROTR, MVT::v16i16, 6 }, 2510 { ISD::ROTR, MVT::v32i8, 6 }, 2511 { ISD::ROTR, MVT::v2i64, 2 }, 2512 { ISD::ROTR, MVT::v4i32, 2 }, 2513 { ISD::ROTR, MVT::v8i16, 2 }, 2514 { ISD::ROTR, MVT::v16i8, 2 } 2515 }; 2516 static const CostTblEntry X64CostTbl[] = { // 64-bit targets 2517 { ISD::ROTL, MVT::i64, 1 }, 2518 { ISD::ROTR, MVT::i64, 1 }, 2519 { ISD::FSHL, MVT::i64, 4 } 2520 }; 2521 static const CostTblEntry X86CostTbl[] = { // 32 or 64-bit targets 2522 { ISD::ROTL, MVT::i32, 1 }, 2523 { ISD::ROTL, MVT::i16, 1 }, 2524 { ISD::ROTL, MVT::i8, 1 }, 2525 { ISD::ROTR, MVT::i32, 1 }, 2526 { ISD::ROTR, MVT::i16, 1 }, 2527 { ISD::ROTR, MVT::i8, 1 }, 2528 { ISD::FSHL, MVT::i32, 4 }, 2529 { ISD::FSHL, MVT::i16, 4 }, 2530 { ISD::FSHL, MVT::i8, 4 } 2531 }; 2532 2533 unsigned ISD = ISD::DELETED_NODE; 2534 switch (IID) { 2535 default: 2536 break; 2537 case Intrinsic::fshl: 2538 ISD = ISD::FSHL; 2539 if (Args[0] == Args[1]) 2540 ISD = ISD::ROTL; 2541 break; 2542 case Intrinsic::fshr: 2543 // FSHR has same costs so don't duplicate. 2544 ISD = ISD::FSHL; 2545 if (Args[0] == Args[1]) 2546 ISD = ISD::ROTR; 2547 break; 2548 } 2549 2550 if (ISD != ISD::DELETED_NODE) { 2551 // Legalize the type. 2552 std::pair<int, MVT> LT = TLI->getTypeLegalizationCost(DL, RetTy); 2553 MVT MTy = LT.second; 2554 2555 // Attempt to lookup cost. 2556 if (ST->hasAVX512()) 2557 if (const auto *Entry = CostTableLookup(AVX512CostTbl, ISD, MTy)) 2558 return LT.first * Entry->Cost; 2559 2560 if (ST->hasXOP()) 2561 if (const auto *Entry = CostTableLookup(XOPCostTbl, ISD, MTy)) 2562 return LT.first * Entry->Cost; 2563 2564 if (ST->is64Bit()) 2565 if (const auto *Entry = CostTableLookup(X64CostTbl, ISD, MTy)) 2566 return LT.first * Entry->Cost; 2567 2568 if (const auto *Entry = CostTableLookup(X86CostTbl, ISD, MTy)) 2569 return LT.first * Entry->Cost; 2570 } 2571 2572 return BaseT::getIntrinsicInstrCost(IID, RetTy, Args, FMF, VF, I); 2573 } 2574 2575 int X86TTIImpl::getVectorInstrCost(unsigned Opcode, Type *Val, unsigned Index) { 2576 static const CostTblEntry SLMCostTbl[] = { 2577 { ISD::EXTRACT_VECTOR_ELT, MVT::i8, 4 }, 2578 { ISD::EXTRACT_VECTOR_ELT, MVT::i16, 4 }, 2579 { ISD::EXTRACT_VECTOR_ELT, MVT::i32, 4 }, 2580 { ISD::EXTRACT_VECTOR_ELT, MVT::i64, 7 } 2581 }; 2582 2583 assert(Val->isVectorTy() && "This must be a vector type"); 2584 Type *ScalarType = Val->getScalarType(); 2585 int RegisterFileMoveCost = 0; 2586 2587 if (Index != -1U && (Opcode == Instruction::ExtractElement || 2588 Opcode == Instruction::InsertElement)) { 2589 // Legalize the type. 2590 std::pair<int, MVT> LT = TLI->getTypeLegalizationCost(DL, Val); 2591 2592 // This type is legalized to a scalar type. 2593 if (!LT.second.isVector()) 2594 return 0; 2595 2596 // The type may be split. Normalize the index to the new type. 2597 unsigned NumElts = LT.second.getVectorNumElements(); 2598 unsigned SubNumElts = NumElts; 2599 Index = Index % NumElts; 2600 2601 // For >128-bit vectors, we need to extract higher 128-bit subvectors. 2602 // For inserts, we also need to insert the subvector back. 2603 if (LT.second.getSizeInBits() > 128) { 2604 assert((LT.second.getSizeInBits() % 128) == 0 && "Illegal vector"); 2605 unsigned NumSubVecs = LT.second.getSizeInBits() / 128; 2606 SubNumElts = NumElts / NumSubVecs; 2607 if (SubNumElts <= Index) { 2608 RegisterFileMoveCost += (Opcode == Instruction::InsertElement ? 2 : 1); 2609 Index %= SubNumElts; 2610 } 2611 } 2612 2613 if (Index == 0) { 2614 // Floating point scalars are already located in index #0. 2615 // Many insertions to #0 can fold away for scalar fp-ops, so let's assume 2616 // true for all. 2617 if (ScalarType->isFloatingPointTy()) 2618 return RegisterFileMoveCost; 2619 2620 // Assume movd/movq XMM -> GPR is relatively cheap on all targets. 2621 if (ScalarType->isIntegerTy() && Opcode == Instruction::ExtractElement) 2622 return 1 + RegisterFileMoveCost; 2623 } 2624 2625 int ISD = TLI->InstructionOpcodeToISD(Opcode); 2626 assert(ISD && "Unexpected vector opcode"); 2627 MVT MScalarTy = LT.second.getScalarType(); 2628 if (ST->isSLM()) 2629 if (auto *Entry = CostTableLookup(SLMCostTbl, ISD, MScalarTy)) 2630 return Entry->Cost + RegisterFileMoveCost; 2631 2632 // Assume pinsr/pextr XMM <-> GPR is relatively cheap on all targets. 2633 if ((MScalarTy == MVT::i16 && ST->hasSSE2()) || 2634 (MScalarTy.isInteger() && ST->hasSSE41())) 2635 return 1 + RegisterFileMoveCost; 2636 2637 // Assume insertps is relatively cheap on all targets. 2638 if (MScalarTy == MVT::f32 && ST->hasSSE41() && 2639 Opcode == Instruction::InsertElement) 2640 return 1 + RegisterFileMoveCost; 2641 2642 // For extractions we just need to shuffle the element to index 0, which 2643 // should be very cheap (assume cost = 1). For insertions we need to shuffle 2644 // the elements to its destination. In both cases we must handle the 2645 // subvector move(s). 2646 // If the vector type is already less than 128-bits then don't reduce it. 2647 // TODO: Under what circumstances should we shuffle using the full width? 2648 int ShuffleCost = 1; 2649 if (Opcode == Instruction::InsertElement) { 2650 Type *SubTy = Val; 2651 EVT VT = TLI->getValueType(DL, Val); 2652 if (VT.getScalarType() != MScalarTy || VT.getSizeInBits() >= 128) 2653 SubTy = VectorType::get(ScalarType, SubNumElts); 2654 ShuffleCost = getShuffleCost(TTI::SK_PermuteTwoSrc, SubTy, 0, SubTy); 2655 } 2656 int IntOrFpCost = ScalarType->isFloatingPointTy() ? 0 : 1; 2657 return ShuffleCost + IntOrFpCost + RegisterFileMoveCost; 2658 } 2659 2660 // Add to the base cost if we know that the extracted element of a vector is 2661 // destined to be moved to and used in the integer register file. 2662 if (Opcode == Instruction::ExtractElement && ScalarType->isPointerTy()) 2663 RegisterFileMoveCost += 1; 2664 2665 return BaseT::getVectorInstrCost(Opcode, Val, Index) + RegisterFileMoveCost; 2666 } 2667 2668 unsigned X86TTIImpl::getScalarizationOverhead(Type *Ty, bool Insert, 2669 bool Extract) { 2670 return BaseT::getScalarizationOverhead(Ty, Insert, Extract); 2671 } 2672 2673 int X86TTIImpl::getMemoryOpCost(unsigned Opcode, Type *Src, 2674 MaybeAlign Alignment, unsigned AddressSpace, 2675 const Instruction *I) { 2676 // Handle non-power-of-two vectors such as <3 x float> 2677 if (VectorType *VTy = dyn_cast<VectorType>(Src)) { 2678 unsigned NumElem = VTy->getVectorNumElements(); 2679 2680 // Handle a few common cases: 2681 // <3 x float> 2682 if (NumElem == 3 && VTy->getScalarSizeInBits() == 32) 2683 // Cost = 64 bit store + extract + 32 bit store. 2684 return 3; 2685 2686 // <3 x double> 2687 if (NumElem == 3 && VTy->getScalarSizeInBits() == 64) 2688 // Cost = 128 bit store + unpack + 64 bit store. 2689 return 3; 2690 2691 // Assume that all other non-power-of-two numbers are scalarized. 2692 if (!isPowerOf2_32(NumElem)) { 2693 int Cost = BaseT::getMemoryOpCost(Opcode, VTy->getScalarType(), Alignment, 2694 AddressSpace); 2695 int SplitCost = getScalarizationOverhead(Src, Opcode == Instruction::Load, 2696 Opcode == Instruction::Store); 2697 return NumElem * Cost + SplitCost; 2698 } 2699 } 2700 2701 // Legalize the type. 2702 std::pair<int, MVT> LT = TLI->getTypeLegalizationCost(DL, Src); 2703 assert((Opcode == Instruction::Load || Opcode == Instruction::Store) && 2704 "Invalid Opcode"); 2705 2706 // Each load/store unit costs 1. 2707 int Cost = LT.first * 1; 2708 2709 // This isn't exactly right. We're using slow unaligned 32-byte accesses as a 2710 // proxy for a double-pumped AVX memory interface such as on Sandybridge. 2711 if (LT.second.getStoreSize() == 32 && ST->isUnalignedMem32Slow()) 2712 Cost *= 2; 2713 2714 return Cost; 2715 } 2716 2717 int X86TTIImpl::getMaskedMemoryOpCost(unsigned Opcode, Type *SrcTy, 2718 unsigned Alignment, 2719 unsigned AddressSpace) { 2720 bool IsLoad = (Instruction::Load == Opcode); 2721 bool IsStore = (Instruction::Store == Opcode); 2722 2723 VectorType *SrcVTy = dyn_cast<VectorType>(SrcTy); 2724 if (!SrcVTy) 2725 // To calculate scalar take the regular cost, without mask 2726 return getMemoryOpCost(Opcode, SrcTy, MaybeAlign(Alignment), AddressSpace); 2727 2728 unsigned NumElem = SrcVTy->getVectorNumElements(); 2729 VectorType *MaskTy = 2730 VectorType::get(Type::getInt8Ty(SrcVTy->getContext()), NumElem); 2731 if ((IsLoad && !isLegalMaskedLoad(SrcVTy, MaybeAlign(Alignment))) || 2732 (IsStore && !isLegalMaskedStore(SrcVTy, MaybeAlign(Alignment))) || 2733 !isPowerOf2_32(NumElem)) { 2734 // Scalarization 2735 int MaskSplitCost = getScalarizationOverhead(MaskTy, false, true); 2736 int ScalarCompareCost = getCmpSelInstrCost( 2737 Instruction::ICmp, Type::getInt8Ty(SrcVTy->getContext()), nullptr); 2738 int BranchCost = getCFInstrCost(Instruction::Br); 2739 int MaskCmpCost = NumElem * (BranchCost + ScalarCompareCost); 2740 2741 int ValueSplitCost = getScalarizationOverhead(SrcVTy, IsLoad, IsStore); 2742 int MemopCost = 2743 NumElem * BaseT::getMemoryOpCost(Opcode, SrcVTy->getScalarType(), 2744 MaybeAlign(Alignment), AddressSpace); 2745 return MemopCost + ValueSplitCost + MaskSplitCost + MaskCmpCost; 2746 } 2747 2748 // Legalize the type. 2749 std::pair<int, MVT> LT = TLI->getTypeLegalizationCost(DL, SrcVTy); 2750 auto VT = TLI->getValueType(DL, SrcVTy); 2751 int Cost = 0; 2752 if (VT.isSimple() && LT.second != VT.getSimpleVT() && 2753 LT.second.getVectorNumElements() == NumElem) 2754 // Promotion requires expand/truncate for data and a shuffle for mask. 2755 Cost += getShuffleCost(TTI::SK_PermuteTwoSrc, SrcVTy, 0, nullptr) + 2756 getShuffleCost(TTI::SK_PermuteTwoSrc, MaskTy, 0, nullptr); 2757 2758 else if (LT.second.getVectorNumElements() > NumElem) { 2759 VectorType *NewMaskTy = VectorType::get(MaskTy->getVectorElementType(), 2760 LT.second.getVectorNumElements()); 2761 // Expanding requires fill mask with zeroes 2762 Cost += getShuffleCost(TTI::SK_InsertSubvector, NewMaskTy, 0, MaskTy); 2763 } 2764 2765 // Pre-AVX512 - each maskmov load costs 2 + store costs ~8. 2766 if (!ST->hasAVX512()) 2767 return Cost + LT.first * (IsLoad ? 2 : 8); 2768 2769 // AVX-512 masked load/store is cheapper 2770 return Cost + LT.first; 2771 } 2772 2773 int X86TTIImpl::getAddressComputationCost(Type *Ty, ScalarEvolution *SE, 2774 const SCEV *Ptr) { 2775 // Address computations in vectorized code with non-consecutive addresses will 2776 // likely result in more instructions compared to scalar code where the 2777 // computation can more often be merged into the index mode. The resulting 2778 // extra micro-ops can significantly decrease throughput. 2779 const unsigned NumVectorInstToHideOverhead = 10; 2780 2781 // Cost modeling of Strided Access Computation is hidden by the indexing 2782 // modes of X86 regardless of the stride value. We dont believe that there 2783 // is a difference between constant strided access in gerenal and constant 2784 // strided value which is less than or equal to 64. 2785 // Even in the case of (loop invariant) stride whose value is not known at 2786 // compile time, the address computation will not incur more than one extra 2787 // ADD instruction. 2788 if (Ty->isVectorTy() && SE) { 2789 if (!BaseT::isStridedAccess(Ptr)) 2790 return NumVectorInstToHideOverhead; 2791 if (!BaseT::getConstantStrideStep(SE, Ptr)) 2792 return 1; 2793 } 2794 2795 return BaseT::getAddressComputationCost(Ty, SE, Ptr); 2796 } 2797 2798 int X86TTIImpl::getArithmeticReductionCost(unsigned Opcode, Type *ValTy, 2799 bool IsPairwise) { 2800 // Just use the default implementation for pair reductions. 2801 if (IsPairwise) 2802 return BaseT::getArithmeticReductionCost(Opcode, ValTy, IsPairwise); 2803 2804 // We use the Intel Architecture Code Analyzer(IACA) to measure the throughput 2805 // and make it as the cost. 2806 2807 static const CostTblEntry SLMCostTblNoPairWise[] = { 2808 { ISD::FADD, MVT::v2f64, 3 }, 2809 { ISD::ADD, MVT::v2i64, 5 }, 2810 }; 2811 2812 static const CostTblEntry SSE2CostTblNoPairWise[] = { 2813 { ISD::FADD, MVT::v2f64, 2 }, 2814 { ISD::FADD, MVT::v4f32, 4 }, 2815 { ISD::ADD, MVT::v2i64, 2 }, // The data reported by the IACA tool is "1.6". 2816 { ISD::ADD, MVT::v2i32, 2 }, // FIXME: chosen to be less than v4i32 2817 { ISD::ADD, MVT::v4i32, 3 }, // The data reported by the IACA tool is "3.3". 2818 { ISD::ADD, MVT::v2i16, 2 }, // The data reported by the IACA tool is "4.3". 2819 { ISD::ADD, MVT::v4i16, 3 }, // The data reported by the IACA tool is "4.3". 2820 { ISD::ADD, MVT::v8i16, 4 }, // The data reported by the IACA tool is "4.3". 2821 { ISD::ADD, MVT::v2i8, 2 }, 2822 { ISD::ADD, MVT::v4i8, 2 }, 2823 { ISD::ADD, MVT::v8i8, 2 }, 2824 { ISD::ADD, MVT::v16i8, 3 }, 2825 }; 2826 2827 static const CostTblEntry AVX1CostTblNoPairWise[] = { 2828 { ISD::FADD, MVT::v4f64, 3 }, 2829 { ISD::FADD, MVT::v4f32, 3 }, 2830 { ISD::FADD, MVT::v8f32, 4 }, 2831 { ISD::ADD, MVT::v2i64, 1 }, // The data reported by the IACA tool is "1.5". 2832 { ISD::ADD, MVT::v4i64, 3 }, 2833 { ISD::ADD, MVT::v8i32, 5 }, 2834 { ISD::ADD, MVT::v16i16, 5 }, 2835 { ISD::ADD, MVT::v32i8, 4 }, 2836 }; 2837 2838 int ISD = TLI->InstructionOpcodeToISD(Opcode); 2839 assert(ISD && "Invalid opcode"); 2840 2841 // Before legalizing the type, give a chance to look up illegal narrow types 2842 // in the table. 2843 // FIXME: Is there a better way to do this? 2844 EVT VT = TLI->getValueType(DL, ValTy); 2845 if (VT.isSimple()) { 2846 MVT MTy = VT.getSimpleVT(); 2847 if (ST->isSLM()) 2848 if (const auto *Entry = CostTableLookup(SLMCostTblNoPairWise, ISD, MTy)) 2849 return Entry->Cost; 2850 2851 if (ST->hasAVX()) 2852 if (const auto *Entry = CostTableLookup(AVX1CostTblNoPairWise, ISD, MTy)) 2853 return Entry->Cost; 2854 2855 if (ST->hasSSE2()) 2856 if (const auto *Entry = CostTableLookup(SSE2CostTblNoPairWise, ISD, MTy)) 2857 return Entry->Cost; 2858 } 2859 2860 std::pair<int, MVT> LT = TLI->getTypeLegalizationCost(DL, ValTy); 2861 2862 MVT MTy = LT.second; 2863 2864 unsigned ArithmeticCost = 0; 2865 if (LT.first != 1 && MTy.isVector() && 2866 MTy.getVectorNumElements() < ValTy->getVectorNumElements()) { 2867 // Type needs to be split. We need LT.first - 1 arithmetic ops. 2868 Type *SingleOpTy = VectorType::get(ValTy->getVectorElementType(), 2869 MTy.getVectorNumElements()); 2870 ArithmeticCost = getArithmeticInstrCost(Opcode, SingleOpTy); 2871 ArithmeticCost *= LT.first - 1; 2872 } 2873 2874 if (ST->isSLM()) 2875 if (const auto *Entry = CostTableLookup(SLMCostTblNoPairWise, ISD, MTy)) 2876 return ArithmeticCost + Entry->Cost; 2877 2878 if (ST->hasAVX()) 2879 if (const auto *Entry = CostTableLookup(AVX1CostTblNoPairWise, ISD, MTy)) 2880 return ArithmeticCost + Entry->Cost; 2881 2882 if (ST->hasSSE2()) 2883 if (const auto *Entry = CostTableLookup(SSE2CostTblNoPairWise, ISD, MTy)) 2884 return ArithmeticCost + Entry->Cost; 2885 2886 // FIXME: These assume a naive kshift+binop lowering, which is probably 2887 // conservative in most cases. 2888 static const CostTblEntry AVX512BoolReduction[] = { 2889 { ISD::AND, MVT::v2i1, 3 }, 2890 { ISD::AND, MVT::v4i1, 5 }, 2891 { ISD::AND, MVT::v8i1, 7 }, 2892 { ISD::AND, MVT::v16i1, 9 }, 2893 { ISD::AND, MVT::v32i1, 11 }, 2894 { ISD::AND, MVT::v64i1, 13 }, 2895 { ISD::OR, MVT::v2i1, 3 }, 2896 { ISD::OR, MVT::v4i1, 5 }, 2897 { ISD::OR, MVT::v8i1, 7 }, 2898 { ISD::OR, MVT::v16i1, 9 }, 2899 { ISD::OR, MVT::v32i1, 11 }, 2900 { ISD::OR, MVT::v64i1, 13 }, 2901 }; 2902 2903 static const CostTblEntry AVX2BoolReduction[] = { 2904 { ISD::AND, MVT::v16i16, 2 }, // vpmovmskb + cmp 2905 { ISD::AND, MVT::v32i8, 2 }, // vpmovmskb + cmp 2906 { ISD::OR, MVT::v16i16, 2 }, // vpmovmskb + cmp 2907 { ISD::OR, MVT::v32i8, 2 }, // vpmovmskb + cmp 2908 }; 2909 2910 static const CostTblEntry AVX1BoolReduction[] = { 2911 { ISD::AND, MVT::v4i64, 2 }, // vmovmskpd + cmp 2912 { ISD::AND, MVT::v8i32, 2 }, // vmovmskps + cmp 2913 { ISD::AND, MVT::v16i16, 4 }, // vextractf128 + vpand + vpmovmskb + cmp 2914 { ISD::AND, MVT::v32i8, 4 }, // vextractf128 + vpand + vpmovmskb + cmp 2915 { ISD::OR, MVT::v4i64, 2 }, // vmovmskpd + cmp 2916 { ISD::OR, MVT::v8i32, 2 }, // vmovmskps + cmp 2917 { ISD::OR, MVT::v16i16, 4 }, // vextractf128 + vpor + vpmovmskb + cmp 2918 { ISD::OR, MVT::v32i8, 4 }, // vextractf128 + vpor + vpmovmskb + cmp 2919 }; 2920 2921 static const CostTblEntry SSE2BoolReduction[] = { 2922 { ISD::AND, MVT::v2i64, 2 }, // movmskpd + cmp 2923 { ISD::AND, MVT::v4i32, 2 }, // movmskps + cmp 2924 { ISD::AND, MVT::v8i16, 2 }, // pmovmskb + cmp 2925 { ISD::AND, MVT::v16i8, 2 }, // pmovmskb + cmp 2926 { ISD::OR, MVT::v2i64, 2 }, // movmskpd + cmp 2927 { ISD::OR, MVT::v4i32, 2 }, // movmskps + cmp 2928 { ISD::OR, MVT::v8i16, 2 }, // pmovmskb + cmp 2929 { ISD::OR, MVT::v16i8, 2 }, // pmovmskb + cmp 2930 }; 2931 2932 // Handle bool allof/anyof patterns. 2933 if (ValTy->getVectorElementType()->isIntegerTy(1)) { 2934 unsigned ArithmeticCost = 0; 2935 if (LT.first != 1 && MTy.isVector() && 2936 MTy.getVectorNumElements() < ValTy->getVectorNumElements()) { 2937 // Type needs to be split. We need LT.first - 1 arithmetic ops. 2938 Type *SingleOpTy = VectorType::get(ValTy->getVectorElementType(), 2939 MTy.getVectorNumElements()); 2940 ArithmeticCost = getArithmeticInstrCost(Opcode, SingleOpTy); 2941 ArithmeticCost *= LT.first - 1; 2942 } 2943 2944 if (ST->hasAVX512()) 2945 if (const auto *Entry = CostTableLookup(AVX512BoolReduction, ISD, MTy)) 2946 return ArithmeticCost + Entry->Cost; 2947 if (ST->hasAVX2()) 2948 if (const auto *Entry = CostTableLookup(AVX2BoolReduction, ISD, MTy)) 2949 return ArithmeticCost + Entry->Cost; 2950 if (ST->hasAVX()) 2951 if (const auto *Entry = CostTableLookup(AVX1BoolReduction, ISD, MTy)) 2952 return ArithmeticCost + Entry->Cost; 2953 if (ST->hasSSE2()) 2954 if (const auto *Entry = CostTableLookup(SSE2BoolReduction, ISD, MTy)) 2955 return ArithmeticCost + Entry->Cost; 2956 2957 return BaseT::getArithmeticReductionCost(Opcode, ValTy, IsPairwise); 2958 } 2959 2960 unsigned NumVecElts = ValTy->getVectorNumElements(); 2961 unsigned ScalarSize = ValTy->getScalarSizeInBits(); 2962 2963 // Special case power of 2 reductions where the scalar type isn't changed 2964 // by type legalization. 2965 if (!isPowerOf2_32(NumVecElts) || ScalarSize != MTy.getScalarSizeInBits()) 2966 return BaseT::getArithmeticReductionCost(Opcode, ValTy, IsPairwise); 2967 2968 unsigned ReductionCost = 0; 2969 2970 Type *Ty = ValTy; 2971 if (LT.first != 1 && MTy.isVector() && 2972 MTy.getVectorNumElements() < ValTy->getVectorNumElements()) { 2973 // Type needs to be split. We need LT.first - 1 arithmetic ops. 2974 Ty = VectorType::get(ValTy->getVectorElementType(), 2975 MTy.getVectorNumElements()); 2976 ReductionCost = getArithmeticInstrCost(Opcode, Ty); 2977 ReductionCost *= LT.first - 1; 2978 NumVecElts = MTy.getVectorNumElements(); 2979 } 2980 2981 // Now handle reduction with the legal type, taking into account size changes 2982 // at each level. 2983 while (NumVecElts > 1) { 2984 // Determine the size of the remaining vector we need to reduce. 2985 unsigned Size = NumVecElts * ScalarSize; 2986 NumVecElts /= 2; 2987 // If we're reducing from 256/512 bits, use an extract_subvector. 2988 if (Size > 128) { 2989 Type *SubTy = VectorType::get(ValTy->getVectorElementType(), NumVecElts); 2990 ReductionCost += 2991 getShuffleCost(TTI::SK_ExtractSubvector, Ty, NumVecElts, SubTy); 2992 Ty = SubTy; 2993 } else if (Size == 128) { 2994 // Reducing from 128 bits is a permute of v2f64/v2i64. 2995 Type *ShufTy; 2996 if (ValTy->isFloatingPointTy()) 2997 ShufTy = VectorType::get(Type::getDoubleTy(ValTy->getContext()), 2); 2998 else 2999 ShufTy = VectorType::get(Type::getInt64Ty(ValTy->getContext()), 2); 3000 ReductionCost += 3001 getShuffleCost(TTI::SK_PermuteSingleSrc, ShufTy, 0, nullptr); 3002 } else if (Size == 64) { 3003 // Reducing from 64 bits is a shuffle of v4f32/v4i32. 3004 Type *ShufTy; 3005 if (ValTy->isFloatingPointTy()) 3006 ShufTy = VectorType::get(Type::getFloatTy(ValTy->getContext()), 4); 3007 else 3008 ShufTy = VectorType::get(Type::getInt32Ty(ValTy->getContext()), 4); 3009 ReductionCost += 3010 getShuffleCost(TTI::SK_PermuteSingleSrc, ShufTy, 0, nullptr); 3011 } else { 3012 // Reducing from smaller size is a shift by immediate. 3013 Type *ShiftTy = VectorType::get( 3014 Type::getIntNTy(ValTy->getContext(), Size), 128 / Size); 3015 ReductionCost += getArithmeticInstrCost( 3016 Instruction::LShr, ShiftTy, TargetTransformInfo::OK_AnyValue, 3017 TargetTransformInfo::OK_UniformConstantValue, 3018 TargetTransformInfo::OP_None, TargetTransformInfo::OP_None); 3019 } 3020 3021 // Add the arithmetic op for this level. 3022 ReductionCost += getArithmeticInstrCost(Opcode, Ty); 3023 } 3024 3025 // Add the final extract element to the cost. 3026 return ReductionCost + getVectorInstrCost(Instruction::ExtractElement, Ty, 0); 3027 } 3028 3029 int X86TTIImpl::getMinMaxCost(Type *Ty, Type *CondTy, bool IsUnsigned) { 3030 std::pair<int, MVT> LT = TLI->getTypeLegalizationCost(DL, Ty); 3031 3032 MVT MTy = LT.second; 3033 3034 int ISD; 3035 if (Ty->isIntOrIntVectorTy()) { 3036 ISD = IsUnsigned ? ISD::UMIN : ISD::SMIN; 3037 } else { 3038 assert(Ty->isFPOrFPVectorTy() && 3039 "Expected float point or integer vector type."); 3040 ISD = ISD::FMINNUM; 3041 } 3042 3043 static const CostTblEntry SSE1CostTbl[] = { 3044 {ISD::FMINNUM, MVT::v4f32, 1}, 3045 }; 3046 3047 static const CostTblEntry SSE2CostTbl[] = { 3048 {ISD::FMINNUM, MVT::v2f64, 1}, 3049 {ISD::SMIN, MVT::v8i16, 1}, 3050 {ISD::UMIN, MVT::v16i8, 1}, 3051 }; 3052 3053 static const CostTblEntry SSE41CostTbl[] = { 3054 {ISD::SMIN, MVT::v4i32, 1}, 3055 {ISD::UMIN, MVT::v4i32, 1}, 3056 {ISD::UMIN, MVT::v8i16, 1}, 3057 {ISD::SMIN, MVT::v16i8, 1}, 3058 }; 3059 3060 static const CostTblEntry SSE42CostTbl[] = { 3061 {ISD::UMIN, MVT::v2i64, 3}, // xor+pcmpgtq+blendvpd 3062 }; 3063 3064 static const CostTblEntry AVX1CostTbl[] = { 3065 {ISD::FMINNUM, MVT::v8f32, 1}, 3066 {ISD::FMINNUM, MVT::v4f64, 1}, 3067 {ISD::SMIN, MVT::v8i32, 3}, 3068 {ISD::UMIN, MVT::v8i32, 3}, 3069 {ISD::SMIN, MVT::v16i16, 3}, 3070 {ISD::UMIN, MVT::v16i16, 3}, 3071 {ISD::SMIN, MVT::v32i8, 3}, 3072 {ISD::UMIN, MVT::v32i8, 3}, 3073 }; 3074 3075 static const CostTblEntry AVX2CostTbl[] = { 3076 {ISD::SMIN, MVT::v8i32, 1}, 3077 {ISD::UMIN, MVT::v8i32, 1}, 3078 {ISD::SMIN, MVT::v16i16, 1}, 3079 {ISD::UMIN, MVT::v16i16, 1}, 3080 {ISD::SMIN, MVT::v32i8, 1}, 3081 {ISD::UMIN, MVT::v32i8, 1}, 3082 }; 3083 3084 static const CostTblEntry AVX512CostTbl[] = { 3085 {ISD::FMINNUM, MVT::v16f32, 1}, 3086 {ISD::FMINNUM, MVT::v8f64, 1}, 3087 {ISD::SMIN, MVT::v2i64, 1}, 3088 {ISD::UMIN, MVT::v2i64, 1}, 3089 {ISD::SMIN, MVT::v4i64, 1}, 3090 {ISD::UMIN, MVT::v4i64, 1}, 3091 {ISD::SMIN, MVT::v8i64, 1}, 3092 {ISD::UMIN, MVT::v8i64, 1}, 3093 {ISD::SMIN, MVT::v16i32, 1}, 3094 {ISD::UMIN, MVT::v16i32, 1}, 3095 }; 3096 3097 static const CostTblEntry AVX512BWCostTbl[] = { 3098 {ISD::SMIN, MVT::v32i16, 1}, 3099 {ISD::UMIN, MVT::v32i16, 1}, 3100 {ISD::SMIN, MVT::v64i8, 1}, 3101 {ISD::UMIN, MVT::v64i8, 1}, 3102 }; 3103 3104 // If we have a native MIN/MAX instruction for this type, use it. 3105 if (ST->hasBWI()) 3106 if (const auto *Entry = CostTableLookup(AVX512BWCostTbl, ISD, MTy)) 3107 return LT.first * Entry->Cost; 3108 3109 if (ST->hasAVX512()) 3110 if (const auto *Entry = CostTableLookup(AVX512CostTbl, ISD, MTy)) 3111 return LT.first * Entry->Cost; 3112 3113 if (ST->hasAVX2()) 3114 if (const auto *Entry = CostTableLookup(AVX2CostTbl, ISD, MTy)) 3115 return LT.first * Entry->Cost; 3116 3117 if (ST->hasAVX()) 3118 if (const auto *Entry = CostTableLookup(AVX1CostTbl, ISD, MTy)) 3119 return LT.first * Entry->Cost; 3120 3121 if (ST->hasSSE42()) 3122 if (const auto *Entry = CostTableLookup(SSE42CostTbl, ISD, MTy)) 3123 return LT.first * Entry->Cost; 3124 3125 if (ST->hasSSE41()) 3126 if (const auto *Entry = CostTableLookup(SSE41CostTbl, ISD, MTy)) 3127 return LT.first * Entry->Cost; 3128 3129 if (ST->hasSSE2()) 3130 if (const auto *Entry = CostTableLookup(SSE2CostTbl, ISD, MTy)) 3131 return LT.first * Entry->Cost; 3132 3133 if (ST->hasSSE1()) 3134 if (const auto *Entry = CostTableLookup(SSE1CostTbl, ISD, MTy)) 3135 return LT.first * Entry->Cost; 3136 3137 unsigned CmpOpcode; 3138 if (Ty->isFPOrFPVectorTy()) { 3139 CmpOpcode = Instruction::FCmp; 3140 } else { 3141 assert(Ty->isIntOrIntVectorTy() && 3142 "expecting floating point or integer type for min/max reduction"); 3143 CmpOpcode = Instruction::ICmp; 3144 } 3145 3146 // Otherwise fall back to cmp+select. 3147 return getCmpSelInstrCost(CmpOpcode, Ty, CondTy, nullptr) + 3148 getCmpSelInstrCost(Instruction::Select, Ty, CondTy, nullptr); 3149 } 3150 3151 int X86TTIImpl::getMinMaxReductionCost(Type *ValTy, Type *CondTy, 3152 bool IsPairwise, bool IsUnsigned) { 3153 // Just use the default implementation for pair reductions. 3154 if (IsPairwise) 3155 return BaseT::getMinMaxReductionCost(ValTy, CondTy, IsPairwise, IsUnsigned); 3156 3157 std::pair<int, MVT> LT = TLI->getTypeLegalizationCost(DL, ValTy); 3158 3159 MVT MTy = LT.second; 3160 3161 int ISD; 3162 if (ValTy->isIntOrIntVectorTy()) { 3163 ISD = IsUnsigned ? ISD::UMIN : ISD::SMIN; 3164 } else { 3165 assert(ValTy->isFPOrFPVectorTy() && 3166 "Expected float point or integer vector type."); 3167 ISD = ISD::FMINNUM; 3168 } 3169 3170 // We use the Intel Architecture Code Analyzer(IACA) to measure the throughput 3171 // and make it as the cost. 3172 3173 static const CostTblEntry SSE2CostTblNoPairWise[] = { 3174 {ISD::UMIN, MVT::v2i16, 5}, // need pxors to use pminsw/pmaxsw 3175 {ISD::UMIN, MVT::v4i16, 7}, // need pxors to use pminsw/pmaxsw 3176 {ISD::UMIN, MVT::v8i16, 9}, // need pxors to use pminsw/pmaxsw 3177 }; 3178 3179 static const CostTblEntry SSE41CostTblNoPairWise[] = { 3180 {ISD::SMIN, MVT::v2i16, 3}, // same as sse2 3181 {ISD::SMIN, MVT::v4i16, 5}, // same as sse2 3182 {ISD::UMIN, MVT::v2i16, 5}, // same as sse2 3183 {ISD::UMIN, MVT::v4i16, 7}, // same as sse2 3184 {ISD::SMIN, MVT::v8i16, 4}, // phminposuw+xor 3185 {ISD::UMIN, MVT::v8i16, 4}, // FIXME: umin is cheaper than umax 3186 {ISD::SMIN, MVT::v2i8, 3}, // pminsb 3187 {ISD::SMIN, MVT::v4i8, 5}, // pminsb 3188 {ISD::SMIN, MVT::v8i8, 7}, // pminsb 3189 {ISD::SMIN, MVT::v16i8, 6}, 3190 {ISD::UMIN, MVT::v2i8, 3}, // same as sse2 3191 {ISD::UMIN, MVT::v4i8, 5}, // same as sse2 3192 {ISD::UMIN, MVT::v8i8, 7}, // same as sse2 3193 {ISD::UMIN, MVT::v16i8, 6}, // FIXME: umin is cheaper than umax 3194 }; 3195 3196 static const CostTblEntry AVX1CostTblNoPairWise[] = { 3197 {ISD::SMIN, MVT::v16i16, 6}, 3198 {ISD::UMIN, MVT::v16i16, 6}, // FIXME: umin is cheaper than umax 3199 {ISD::SMIN, MVT::v32i8, 8}, 3200 {ISD::UMIN, MVT::v32i8, 8}, 3201 }; 3202 3203 static const CostTblEntry AVX512BWCostTblNoPairWise[] = { 3204 {ISD::SMIN, MVT::v32i16, 8}, 3205 {ISD::UMIN, MVT::v32i16, 8}, // FIXME: umin is cheaper than umax 3206 {ISD::SMIN, MVT::v64i8, 10}, 3207 {ISD::UMIN, MVT::v64i8, 10}, 3208 }; 3209 3210 // Before legalizing the type, give a chance to look up illegal narrow types 3211 // in the table. 3212 // FIXME: Is there a better way to do this? 3213 EVT VT = TLI->getValueType(DL, ValTy); 3214 if (VT.isSimple()) { 3215 MVT MTy = VT.getSimpleVT(); 3216 if (ST->hasBWI()) 3217 if (const auto *Entry = CostTableLookup(AVX512BWCostTblNoPairWise, ISD, MTy)) 3218 return Entry->Cost; 3219 3220 if (ST->hasAVX()) 3221 if (const auto *Entry = CostTableLookup(AVX1CostTblNoPairWise, ISD, MTy)) 3222 return Entry->Cost; 3223 3224 if (ST->hasSSE41()) 3225 if (const auto *Entry = CostTableLookup(SSE41CostTblNoPairWise, ISD, MTy)) 3226 return Entry->Cost; 3227 3228 if (ST->hasSSE2()) 3229 if (const auto *Entry = CostTableLookup(SSE2CostTblNoPairWise, ISD, MTy)) 3230 return Entry->Cost; 3231 } 3232 3233 unsigned NumVecElts = ValTy->getVectorNumElements(); 3234 3235 Type *Ty = ValTy; 3236 unsigned MinMaxCost = 0; 3237 if (LT.first != 1 && MTy.isVector() && 3238 MTy.getVectorNumElements() < ValTy->getVectorNumElements()) { 3239 // Type needs to be split. We need LT.first - 1 operations ops. 3240 Ty = VectorType::get(ValTy->getVectorElementType(), 3241 MTy.getVectorNumElements()); 3242 Type *SubCondTy = VectorType::get(CondTy->getVectorElementType(), 3243 MTy.getVectorNumElements()); 3244 MinMaxCost = getMinMaxCost(Ty, SubCondTy, IsUnsigned); 3245 MinMaxCost *= LT.first - 1; 3246 NumVecElts = MTy.getVectorNumElements(); 3247 } 3248 3249 if (ST->hasBWI()) 3250 if (const auto *Entry = CostTableLookup(AVX512BWCostTblNoPairWise, ISD, MTy)) 3251 return MinMaxCost + Entry->Cost; 3252 3253 if (ST->hasAVX()) 3254 if (const auto *Entry = CostTableLookup(AVX1CostTblNoPairWise, ISD, MTy)) 3255 return MinMaxCost + Entry->Cost; 3256 3257 if (ST->hasSSE41()) 3258 if (const auto *Entry = CostTableLookup(SSE41CostTblNoPairWise, ISD, MTy)) 3259 return MinMaxCost + Entry->Cost; 3260 3261 if (ST->hasSSE2()) 3262 if (const auto *Entry = CostTableLookup(SSE2CostTblNoPairWise, ISD, MTy)) 3263 return MinMaxCost + Entry->Cost; 3264 3265 unsigned ScalarSize = ValTy->getScalarSizeInBits(); 3266 3267 // Special case power of 2 reductions where the scalar type isn't changed 3268 // by type legalization. 3269 if (!isPowerOf2_32(ValTy->getVectorNumElements()) || 3270 ScalarSize != MTy.getScalarSizeInBits()) 3271 return BaseT::getMinMaxReductionCost(ValTy, CondTy, IsPairwise, IsUnsigned); 3272 3273 // Now handle reduction with the legal type, taking into account size changes 3274 // at each level. 3275 while (NumVecElts > 1) { 3276 // Determine the size of the remaining vector we need to reduce. 3277 unsigned Size = NumVecElts * ScalarSize; 3278 NumVecElts /= 2; 3279 // If we're reducing from 256/512 bits, use an extract_subvector. 3280 if (Size > 128) { 3281 Type *SubTy = VectorType::get(ValTy->getVectorElementType(), NumVecElts); 3282 MinMaxCost += 3283 getShuffleCost(TTI::SK_ExtractSubvector, Ty, NumVecElts, SubTy); 3284 Ty = SubTy; 3285 } else if (Size == 128) { 3286 // Reducing from 128 bits is a permute of v2f64/v2i64. 3287 Type *ShufTy; 3288 if (ValTy->isFloatingPointTy()) 3289 ShufTy = VectorType::get(Type::getDoubleTy(ValTy->getContext()), 2); 3290 else 3291 ShufTy = VectorType::get(Type::getInt64Ty(ValTy->getContext()), 2); 3292 MinMaxCost += 3293 getShuffleCost(TTI::SK_PermuteSingleSrc, ShufTy, 0, nullptr); 3294 } else if (Size == 64) { 3295 // Reducing from 64 bits is a shuffle of v4f32/v4i32. 3296 Type *ShufTy; 3297 if (ValTy->isFloatingPointTy()) 3298 ShufTy = VectorType::get(Type::getFloatTy(ValTy->getContext()), 4); 3299 else 3300 ShufTy = VectorType::get(Type::getInt32Ty(ValTy->getContext()), 4); 3301 MinMaxCost += 3302 getShuffleCost(TTI::SK_PermuteSingleSrc, ShufTy, 0, nullptr); 3303 } else { 3304 // Reducing from smaller size is a shift by immediate. 3305 Type *ShiftTy = VectorType::get( 3306 Type::getIntNTy(ValTy->getContext(), Size), 128 / Size); 3307 MinMaxCost += getArithmeticInstrCost( 3308 Instruction::LShr, ShiftTy, TargetTransformInfo::OK_AnyValue, 3309 TargetTransformInfo::OK_UniformConstantValue, 3310 TargetTransformInfo::OP_None, TargetTransformInfo::OP_None); 3311 } 3312 3313 // Add the arithmetic op for this level. 3314 Type *SubCondTy = VectorType::get(CondTy->getVectorElementType(), 3315 Ty->getVectorNumElements()); 3316 MinMaxCost += getMinMaxCost(Ty, SubCondTy, IsUnsigned); 3317 } 3318 3319 // Add the final extract element to the cost. 3320 return MinMaxCost + getVectorInstrCost(Instruction::ExtractElement, Ty, 0); 3321 } 3322 3323 /// Calculate the cost of materializing a 64-bit value. This helper 3324 /// method might only calculate a fraction of a larger immediate. Therefore it 3325 /// is valid to return a cost of ZERO. 3326 int X86TTIImpl::getIntImmCost(int64_t Val) { 3327 if (Val == 0) 3328 return TTI::TCC_Free; 3329 3330 if (isInt<32>(Val)) 3331 return TTI::TCC_Basic; 3332 3333 return 2 * TTI::TCC_Basic; 3334 } 3335 3336 int X86TTIImpl::getIntImmCost(const APInt &Imm, Type *Ty) { 3337 assert(Ty->isIntegerTy()); 3338 3339 unsigned BitSize = Ty->getPrimitiveSizeInBits(); 3340 if (BitSize == 0) 3341 return ~0U; 3342 3343 // Never hoist constants larger than 128bit, because this might lead to 3344 // incorrect code generation or assertions in codegen. 3345 // Fixme: Create a cost model for types larger than i128 once the codegen 3346 // issues have been fixed. 3347 if (BitSize > 128) 3348 return TTI::TCC_Free; 3349 3350 if (Imm == 0) 3351 return TTI::TCC_Free; 3352 3353 // Sign-extend all constants to a multiple of 64-bit. 3354 APInt ImmVal = Imm; 3355 if (BitSize % 64 != 0) 3356 ImmVal = Imm.sext(alignTo(BitSize, 64)); 3357 3358 // Split the constant into 64-bit chunks and calculate the cost for each 3359 // chunk. 3360 int Cost = 0; 3361 for (unsigned ShiftVal = 0; ShiftVal < BitSize; ShiftVal += 64) { 3362 APInt Tmp = ImmVal.ashr(ShiftVal).sextOrTrunc(64); 3363 int64_t Val = Tmp.getSExtValue(); 3364 Cost += getIntImmCost(Val); 3365 } 3366 // We need at least one instruction to materialize the constant. 3367 return std::max(1, Cost); 3368 } 3369 3370 int X86TTIImpl::getIntImmCostInst(unsigned Opcode, unsigned Idx, const APInt &Imm, 3371 Type *Ty) { 3372 assert(Ty->isIntegerTy()); 3373 3374 unsigned BitSize = Ty->getPrimitiveSizeInBits(); 3375 // There is no cost model for constants with a bit size of 0. Return TCC_Free 3376 // here, so that constant hoisting will ignore this constant. 3377 if (BitSize == 0) 3378 return TTI::TCC_Free; 3379 3380 unsigned ImmIdx = ~0U; 3381 switch (Opcode) { 3382 default: 3383 return TTI::TCC_Free; 3384 case Instruction::GetElementPtr: 3385 // Always hoist the base address of a GetElementPtr. This prevents the 3386 // creation of new constants for every base constant that gets constant 3387 // folded with the offset. 3388 if (Idx == 0) 3389 return 2 * TTI::TCC_Basic; 3390 return TTI::TCC_Free; 3391 case Instruction::Store: 3392 ImmIdx = 0; 3393 break; 3394 case Instruction::ICmp: 3395 // This is an imperfect hack to prevent constant hoisting of 3396 // compares that might be trying to check if a 64-bit value fits in 3397 // 32-bits. The backend can optimize these cases using a right shift by 32. 3398 // Ideally we would check the compare predicate here. There also other 3399 // similar immediates the backend can use shifts for. 3400 if (Idx == 1 && Imm.getBitWidth() == 64) { 3401 uint64_t ImmVal = Imm.getZExtValue(); 3402 if (ImmVal == 0x100000000ULL || ImmVal == 0xffffffff) 3403 return TTI::TCC_Free; 3404 } 3405 ImmIdx = 1; 3406 break; 3407 case Instruction::And: 3408 // We support 64-bit ANDs with immediates with 32-bits of leading zeroes 3409 // by using a 32-bit operation with implicit zero extension. Detect such 3410 // immediates here as the normal path expects bit 31 to be sign extended. 3411 if (Idx == 1 && Imm.getBitWidth() == 64 && isUInt<32>(Imm.getZExtValue())) 3412 return TTI::TCC_Free; 3413 ImmIdx = 1; 3414 break; 3415 case Instruction::Add: 3416 case Instruction::Sub: 3417 // For add/sub, we can use the opposite instruction for INT32_MIN. 3418 if (Idx == 1 && Imm.getBitWidth() == 64 && Imm.getZExtValue() == 0x80000000) 3419 return TTI::TCC_Free; 3420 ImmIdx = 1; 3421 break; 3422 case Instruction::UDiv: 3423 case Instruction::SDiv: 3424 case Instruction::URem: 3425 case Instruction::SRem: 3426 // Division by constant is typically expanded later into a different 3427 // instruction sequence. This completely changes the constants. 3428 // Report them as "free" to stop ConstantHoist from marking them as opaque. 3429 return TTI::TCC_Free; 3430 case Instruction::Mul: 3431 case Instruction::Or: 3432 case Instruction::Xor: 3433 ImmIdx = 1; 3434 break; 3435 // Always return TCC_Free for the shift value of a shift instruction. 3436 case Instruction::Shl: 3437 case Instruction::LShr: 3438 case Instruction::AShr: 3439 if (Idx == 1) 3440 return TTI::TCC_Free; 3441 break; 3442 case Instruction::Trunc: 3443 case Instruction::ZExt: 3444 case Instruction::SExt: 3445 case Instruction::IntToPtr: 3446 case Instruction::PtrToInt: 3447 case Instruction::BitCast: 3448 case Instruction::PHI: 3449 case Instruction::Call: 3450 case Instruction::Select: 3451 case Instruction::Ret: 3452 case Instruction::Load: 3453 break; 3454 } 3455 3456 if (Idx == ImmIdx) { 3457 int NumConstants = divideCeil(BitSize, 64); 3458 int Cost = X86TTIImpl::getIntImmCost(Imm, Ty); 3459 return (Cost <= NumConstants * TTI::TCC_Basic) 3460 ? static_cast<int>(TTI::TCC_Free) 3461 : Cost; 3462 } 3463 3464 return X86TTIImpl::getIntImmCost(Imm, Ty); 3465 } 3466 3467 int X86TTIImpl::getIntImmCostIntrin(Intrinsic::ID IID, unsigned Idx, 3468 const APInt &Imm, Type *Ty) { 3469 assert(Ty->isIntegerTy()); 3470 3471 unsigned BitSize = Ty->getPrimitiveSizeInBits(); 3472 // There is no cost model for constants with a bit size of 0. Return TCC_Free 3473 // here, so that constant hoisting will ignore this constant. 3474 if (BitSize == 0) 3475 return TTI::TCC_Free; 3476 3477 switch (IID) { 3478 default: 3479 return TTI::TCC_Free; 3480 case Intrinsic::sadd_with_overflow: 3481 case Intrinsic::uadd_with_overflow: 3482 case Intrinsic::ssub_with_overflow: 3483 case Intrinsic::usub_with_overflow: 3484 case Intrinsic::smul_with_overflow: 3485 case Intrinsic::umul_with_overflow: 3486 if ((Idx == 1) && Imm.getBitWidth() <= 64 && isInt<32>(Imm.getSExtValue())) 3487 return TTI::TCC_Free; 3488 break; 3489 case Intrinsic::experimental_stackmap: 3490 if ((Idx < 2) || (Imm.getBitWidth() <= 64 && isInt<64>(Imm.getSExtValue()))) 3491 return TTI::TCC_Free; 3492 break; 3493 case Intrinsic::experimental_patchpoint_void: 3494 case Intrinsic::experimental_patchpoint_i64: 3495 if ((Idx < 4) || (Imm.getBitWidth() <= 64 && isInt<64>(Imm.getSExtValue()))) 3496 return TTI::TCC_Free; 3497 break; 3498 } 3499 return X86TTIImpl::getIntImmCost(Imm, Ty); 3500 } 3501 3502 unsigned X86TTIImpl::getUserCost(const User *U, 3503 ArrayRef<const Value *> Operands) { 3504 if (isa<StoreInst>(U)) { 3505 Value *Ptr = U->getOperand(1); 3506 // Store instruction with index and scale costs 2 Uops. 3507 // Check the preceding GEP to identify non-const indices. 3508 if (auto GEP = dyn_cast<GetElementPtrInst>(Ptr)) { 3509 if (!all_of(GEP->indices(), [](Value *V) { return isa<Constant>(V); })) 3510 return TTI::TCC_Basic * 2; 3511 } 3512 return TTI::TCC_Basic; 3513 } 3514 return BaseT::getUserCost(U, Operands); 3515 } 3516 3517 // Return an average cost of Gather / Scatter instruction, maybe improved later 3518 int X86TTIImpl::getGSVectorCost(unsigned Opcode, Type *SrcVTy, Value *Ptr, 3519 unsigned Alignment, unsigned AddressSpace) { 3520 3521 assert(isa<VectorType>(SrcVTy) && "Unexpected type in getGSVectorCost"); 3522 unsigned VF = SrcVTy->getVectorNumElements(); 3523 3524 // Try to reduce index size from 64 bit (default for GEP) 3525 // to 32. It is essential for VF 16. If the index can't be reduced to 32, the 3526 // operation will use 16 x 64 indices which do not fit in a zmm and needs 3527 // to split. Also check that the base pointer is the same for all lanes, 3528 // and that there's at most one variable index. 3529 auto getIndexSizeInBits = [](Value *Ptr, const DataLayout& DL) { 3530 unsigned IndexSize = DL.getPointerSizeInBits(); 3531 GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Ptr); 3532 if (IndexSize < 64 || !GEP) 3533 return IndexSize; 3534 3535 unsigned NumOfVarIndices = 0; 3536 Value *Ptrs = GEP->getPointerOperand(); 3537 if (Ptrs->getType()->isVectorTy() && !getSplatValue(Ptrs)) 3538 return IndexSize; 3539 for (unsigned i = 1; i < GEP->getNumOperands(); ++i) { 3540 if (isa<Constant>(GEP->getOperand(i))) 3541 continue; 3542 Type *IndxTy = GEP->getOperand(i)->getType(); 3543 if (IndxTy->isVectorTy()) 3544 IndxTy = IndxTy->getVectorElementType(); 3545 if ((IndxTy->getPrimitiveSizeInBits() == 64 && 3546 !isa<SExtInst>(GEP->getOperand(i))) || 3547 ++NumOfVarIndices > 1) 3548 return IndexSize; // 64 3549 } 3550 return (unsigned)32; 3551 }; 3552 3553 3554 // Trying to reduce IndexSize to 32 bits for vector 16. 3555 // By default the IndexSize is equal to pointer size. 3556 unsigned IndexSize = (ST->hasAVX512() && VF >= 16) 3557 ? getIndexSizeInBits(Ptr, DL) 3558 : DL.getPointerSizeInBits(); 3559 3560 Type *IndexVTy = VectorType::get(IntegerType::get(SrcVTy->getContext(), 3561 IndexSize), VF); 3562 std::pair<int, MVT> IdxsLT = TLI->getTypeLegalizationCost(DL, IndexVTy); 3563 std::pair<int, MVT> SrcLT = TLI->getTypeLegalizationCost(DL, SrcVTy); 3564 int SplitFactor = std::max(IdxsLT.first, SrcLT.first); 3565 if (SplitFactor > 1) { 3566 // Handle splitting of vector of pointers 3567 Type *SplitSrcTy = VectorType::get(SrcVTy->getScalarType(), VF / SplitFactor); 3568 return SplitFactor * getGSVectorCost(Opcode, SplitSrcTy, Ptr, Alignment, 3569 AddressSpace); 3570 } 3571 3572 // The gather / scatter cost is given by Intel architects. It is a rough 3573 // number since we are looking at one instruction in a time. 3574 const int GSOverhead = (Opcode == Instruction::Load) 3575 ? ST->getGatherOverhead() 3576 : ST->getScatterOverhead(); 3577 return GSOverhead + VF * getMemoryOpCost(Opcode, SrcVTy->getScalarType(), 3578 MaybeAlign(Alignment), AddressSpace); 3579 } 3580 3581 /// Return the cost of full scalarization of gather / scatter operation. 3582 /// 3583 /// Opcode - Load or Store instruction. 3584 /// SrcVTy - The type of the data vector that should be gathered or scattered. 3585 /// VariableMask - The mask is non-constant at compile time. 3586 /// Alignment - Alignment for one element. 3587 /// AddressSpace - pointer[s] address space. 3588 /// 3589 int X86TTIImpl::getGSScalarCost(unsigned Opcode, Type *SrcVTy, 3590 bool VariableMask, unsigned Alignment, 3591 unsigned AddressSpace) { 3592 unsigned VF = SrcVTy->getVectorNumElements(); 3593 3594 int MaskUnpackCost = 0; 3595 if (VariableMask) { 3596 VectorType *MaskTy = 3597 VectorType::get(Type::getInt1Ty(SrcVTy->getContext()), VF); 3598 MaskUnpackCost = getScalarizationOverhead(MaskTy, false, true); 3599 int ScalarCompareCost = 3600 getCmpSelInstrCost(Instruction::ICmp, Type::getInt1Ty(SrcVTy->getContext()), 3601 nullptr); 3602 int BranchCost = getCFInstrCost(Instruction::Br); 3603 MaskUnpackCost += VF * (BranchCost + ScalarCompareCost); 3604 } 3605 3606 // The cost of the scalar loads/stores. 3607 int MemoryOpCost = VF * getMemoryOpCost(Opcode, SrcVTy->getScalarType(), 3608 MaybeAlign(Alignment), AddressSpace); 3609 3610 int InsertExtractCost = 0; 3611 if (Opcode == Instruction::Load) 3612 for (unsigned i = 0; i < VF; ++i) 3613 // Add the cost of inserting each scalar load into the vector 3614 InsertExtractCost += 3615 getVectorInstrCost(Instruction::InsertElement, SrcVTy, i); 3616 else 3617 for (unsigned i = 0; i < VF; ++i) 3618 // Add the cost of extracting each element out of the data vector 3619 InsertExtractCost += 3620 getVectorInstrCost(Instruction::ExtractElement, SrcVTy, i); 3621 3622 return MemoryOpCost + MaskUnpackCost + InsertExtractCost; 3623 } 3624 3625 /// Calculate the cost of Gather / Scatter operation 3626 int X86TTIImpl::getGatherScatterOpCost(unsigned Opcode, Type *SrcVTy, 3627 Value *Ptr, bool VariableMask, 3628 unsigned Alignment, 3629 const Instruction *I = nullptr) { 3630 assert(SrcVTy->isVectorTy() && "Unexpected data type for Gather/Scatter"); 3631 unsigned VF = SrcVTy->getVectorNumElements(); 3632 PointerType *PtrTy = dyn_cast<PointerType>(Ptr->getType()); 3633 if (!PtrTy && Ptr->getType()->isVectorTy()) 3634 PtrTy = dyn_cast<PointerType>(Ptr->getType()->getVectorElementType()); 3635 assert(PtrTy && "Unexpected type for Ptr argument"); 3636 unsigned AddressSpace = PtrTy->getAddressSpace(); 3637 3638 bool Scalarize = false; 3639 if ((Opcode == Instruction::Load && 3640 !isLegalMaskedGather(SrcVTy, MaybeAlign(Alignment))) || 3641 (Opcode == Instruction::Store && 3642 !isLegalMaskedScatter(SrcVTy, MaybeAlign(Alignment)))) 3643 Scalarize = true; 3644 // Gather / Scatter for vector 2 is not profitable on KNL / SKX 3645 // Vector-4 of gather/scatter instruction does not exist on KNL. 3646 // We can extend it to 8 elements, but zeroing upper bits of 3647 // the mask vector will add more instructions. Right now we give the scalar 3648 // cost of vector-4 for KNL. TODO: Check, maybe the gather/scatter instruction 3649 // is better in the VariableMask case. 3650 if (ST->hasAVX512() && (VF == 2 || (VF == 4 && !ST->hasVLX()))) 3651 Scalarize = true; 3652 3653 if (Scalarize) 3654 return getGSScalarCost(Opcode, SrcVTy, VariableMask, Alignment, 3655 AddressSpace); 3656 3657 return getGSVectorCost(Opcode, SrcVTy, Ptr, Alignment, AddressSpace); 3658 } 3659 3660 bool X86TTIImpl::isLSRCostLess(TargetTransformInfo::LSRCost &C1, 3661 TargetTransformInfo::LSRCost &C2) { 3662 // X86 specific here are "instruction number 1st priority". 3663 return std::tie(C1.Insns, C1.NumRegs, C1.AddRecCost, 3664 C1.NumIVMuls, C1.NumBaseAdds, 3665 C1.ScaleCost, C1.ImmCost, C1.SetupCost) < 3666 std::tie(C2.Insns, C2.NumRegs, C2.AddRecCost, 3667 C2.NumIVMuls, C2.NumBaseAdds, 3668 C2.ScaleCost, C2.ImmCost, C2.SetupCost); 3669 } 3670 3671 bool X86TTIImpl::canMacroFuseCmp() { 3672 return ST->hasMacroFusion() || ST->hasBranchFusion(); 3673 } 3674 3675 bool X86TTIImpl::isLegalMaskedLoad(Type *DataTy, MaybeAlign Alignment) { 3676 if (!ST->hasAVX()) 3677 return false; 3678 3679 // The backend can't handle a single element vector. 3680 if (isa<VectorType>(DataTy) && DataTy->getVectorNumElements() == 1) 3681 return false; 3682 Type *ScalarTy = DataTy->getScalarType(); 3683 3684 if (ScalarTy->isPointerTy()) 3685 return true; 3686 3687 if (ScalarTy->isFloatTy() || ScalarTy->isDoubleTy()) 3688 return true; 3689 3690 if (!ScalarTy->isIntegerTy()) 3691 return false; 3692 3693 unsigned IntWidth = ScalarTy->getIntegerBitWidth(); 3694 return IntWidth == 32 || IntWidth == 64 || 3695 ((IntWidth == 8 || IntWidth == 16) && ST->hasBWI()); 3696 } 3697 3698 bool X86TTIImpl::isLegalMaskedStore(Type *DataType, MaybeAlign Alignment) { 3699 return isLegalMaskedLoad(DataType, Alignment); 3700 } 3701 3702 bool X86TTIImpl::isLegalNTLoad(Type *DataType, Align Alignment) { 3703 unsigned DataSize = DL.getTypeStoreSize(DataType); 3704 // The only supported nontemporal loads are for aligned vectors of 16 or 32 3705 // bytes. Note that 32-byte nontemporal vector loads are supported by AVX2 3706 // (the equivalent stores only require AVX). 3707 if (Alignment >= DataSize && (DataSize == 16 || DataSize == 32)) 3708 return DataSize == 16 ? ST->hasSSE1() : ST->hasAVX2(); 3709 3710 return false; 3711 } 3712 3713 bool X86TTIImpl::isLegalNTStore(Type *DataType, Align Alignment) { 3714 unsigned DataSize = DL.getTypeStoreSize(DataType); 3715 3716 // SSE4A supports nontemporal stores of float and double at arbitrary 3717 // alignment. 3718 if (ST->hasSSE4A() && (DataType->isFloatTy() || DataType->isDoubleTy())) 3719 return true; 3720 3721 // Besides the SSE4A subtarget exception above, only aligned stores are 3722 // available nontemporaly on any other subtarget. And only stores with a size 3723 // of 4..32 bytes (powers of 2, only) are permitted. 3724 if (Alignment < DataSize || DataSize < 4 || DataSize > 32 || 3725 !isPowerOf2_32(DataSize)) 3726 return false; 3727 3728 // 32-byte vector nontemporal stores are supported by AVX (the equivalent 3729 // loads require AVX2). 3730 if (DataSize == 32) 3731 return ST->hasAVX(); 3732 else if (DataSize == 16) 3733 return ST->hasSSE1(); 3734 return true; 3735 } 3736 3737 bool X86TTIImpl::isLegalMaskedExpandLoad(Type *DataTy) { 3738 if (!isa<VectorType>(DataTy)) 3739 return false; 3740 3741 if (!ST->hasAVX512()) 3742 return false; 3743 3744 // The backend can't handle a single element vector. 3745 if (DataTy->getVectorNumElements() == 1) 3746 return false; 3747 3748 Type *ScalarTy = DataTy->getVectorElementType(); 3749 3750 if (ScalarTy->isFloatTy() || ScalarTy->isDoubleTy()) 3751 return true; 3752 3753 if (!ScalarTy->isIntegerTy()) 3754 return false; 3755 3756 unsigned IntWidth = ScalarTy->getIntegerBitWidth(); 3757 return IntWidth == 32 || IntWidth == 64 || 3758 ((IntWidth == 8 || IntWidth == 16) && ST->hasVBMI2()); 3759 } 3760 3761 bool X86TTIImpl::isLegalMaskedCompressStore(Type *DataTy) { 3762 return isLegalMaskedExpandLoad(DataTy); 3763 } 3764 3765 bool X86TTIImpl::isLegalMaskedGather(Type *DataTy, MaybeAlign Alignment) { 3766 // Some CPUs have better gather performance than others. 3767 // TODO: Remove the explicit ST->hasAVX512()?, That would mean we would only 3768 // enable gather with a -march. 3769 if (!(ST->hasAVX512() || (ST->hasFastGather() && ST->hasAVX2()))) 3770 return false; 3771 3772 // This function is called now in two cases: from the Loop Vectorizer 3773 // and from the Scalarizer. 3774 // When the Loop Vectorizer asks about legality of the feature, 3775 // the vectorization factor is not calculated yet. The Loop Vectorizer 3776 // sends a scalar type and the decision is based on the width of the 3777 // scalar element. 3778 // Later on, the cost model will estimate usage this intrinsic based on 3779 // the vector type. 3780 // The Scalarizer asks again about legality. It sends a vector type. 3781 // In this case we can reject non-power-of-2 vectors. 3782 // We also reject single element vectors as the type legalizer can't 3783 // scalarize it. 3784 if (isa<VectorType>(DataTy)) { 3785 unsigned NumElts = DataTy->getVectorNumElements(); 3786 if (NumElts == 1 || !isPowerOf2_32(NumElts)) 3787 return false; 3788 } 3789 Type *ScalarTy = DataTy->getScalarType(); 3790 if (ScalarTy->isPointerTy()) 3791 return true; 3792 3793 if (ScalarTy->isFloatTy() || ScalarTy->isDoubleTy()) 3794 return true; 3795 3796 if (!ScalarTy->isIntegerTy()) 3797 return false; 3798 3799 unsigned IntWidth = ScalarTy->getIntegerBitWidth(); 3800 return IntWidth == 32 || IntWidth == 64; 3801 } 3802 3803 bool X86TTIImpl::isLegalMaskedScatter(Type *DataType, MaybeAlign Alignment) { 3804 // AVX2 doesn't support scatter 3805 if (!ST->hasAVX512()) 3806 return false; 3807 return isLegalMaskedGather(DataType, Alignment); 3808 } 3809 3810 bool X86TTIImpl::hasDivRemOp(Type *DataType, bool IsSigned) { 3811 EVT VT = TLI->getValueType(DL, DataType); 3812 return TLI->isOperationLegal(IsSigned ? ISD::SDIVREM : ISD::UDIVREM, VT); 3813 } 3814 3815 bool X86TTIImpl::isFCmpOrdCheaperThanFCmpZero(Type *Ty) { 3816 return false; 3817 } 3818 3819 bool X86TTIImpl::areInlineCompatible(const Function *Caller, 3820 const Function *Callee) const { 3821 const TargetMachine &TM = getTLI()->getTargetMachine(); 3822 3823 // Work this as a subsetting of subtarget features. 3824 const FeatureBitset &CallerBits = 3825 TM.getSubtargetImpl(*Caller)->getFeatureBits(); 3826 const FeatureBitset &CalleeBits = 3827 TM.getSubtargetImpl(*Callee)->getFeatureBits(); 3828 3829 FeatureBitset RealCallerBits = CallerBits & ~InlineFeatureIgnoreList; 3830 FeatureBitset RealCalleeBits = CalleeBits & ~InlineFeatureIgnoreList; 3831 return (RealCallerBits & RealCalleeBits) == RealCalleeBits; 3832 } 3833 3834 bool X86TTIImpl::areFunctionArgsABICompatible( 3835 const Function *Caller, const Function *Callee, 3836 SmallPtrSetImpl<Argument *> &Args) const { 3837 if (!BaseT::areFunctionArgsABICompatible(Caller, Callee, Args)) 3838 return false; 3839 3840 // If we get here, we know the target features match. If one function 3841 // considers 512-bit vectors legal and the other does not, consider them 3842 // incompatible. 3843 // FIXME Look at the arguments and only consider 512 bit or larger vectors? 3844 const TargetMachine &TM = getTLI()->getTargetMachine(); 3845 3846 return TM.getSubtarget<X86Subtarget>(*Caller).useAVX512Regs() == 3847 TM.getSubtarget<X86Subtarget>(*Callee).useAVX512Regs(); 3848 } 3849 3850 X86TTIImpl::TTI::MemCmpExpansionOptions 3851 X86TTIImpl::enableMemCmpExpansion(bool OptSize, bool IsZeroCmp) const { 3852 TTI::MemCmpExpansionOptions Options; 3853 Options.MaxNumLoads = TLI->getMaxExpandSizeMemcmp(OptSize); 3854 Options.NumLoadsPerBlock = 2; 3855 // All GPR and vector loads can be unaligned. 3856 Options.AllowOverlappingLoads = true; 3857 if (IsZeroCmp) { 3858 // Only enable vector loads for equality comparison. Right now the vector 3859 // version is not as fast for three way compare (see #33329). 3860 const unsigned PreferredWidth = ST->getPreferVectorWidth(); 3861 if (PreferredWidth >= 512 && ST->hasAVX512()) Options.LoadSizes.push_back(64); 3862 if (PreferredWidth >= 256 && ST->hasAVX()) Options.LoadSizes.push_back(32); 3863 if (PreferredWidth >= 128 && ST->hasSSE2()) Options.LoadSizes.push_back(16); 3864 } 3865 if (ST->is64Bit()) { 3866 Options.LoadSizes.push_back(8); 3867 } 3868 Options.LoadSizes.push_back(4); 3869 Options.LoadSizes.push_back(2); 3870 Options.LoadSizes.push_back(1); 3871 return Options; 3872 } 3873 3874 bool X86TTIImpl::enableInterleavedAccessVectorization() { 3875 // TODO: We expect this to be beneficial regardless of arch, 3876 // but there are currently some unexplained performance artifacts on Atom. 3877 // As a temporary solution, disable on Atom. 3878 return !(ST->isAtom()); 3879 } 3880 3881 // Get estimation for interleaved load/store operations for AVX2. 3882 // \p Factor is the interleaved-access factor (stride) - number of 3883 // (interleaved) elements in the group. 3884 // \p Indices contains the indices for a strided load: when the 3885 // interleaved load has gaps they indicate which elements are used. 3886 // If Indices is empty (or if the number of indices is equal to the size 3887 // of the interleaved-access as given in \p Factor) the access has no gaps. 3888 // 3889 // As opposed to AVX-512, AVX2 does not have generic shuffles that allow 3890 // computing the cost using a generic formula as a function of generic 3891 // shuffles. We therefore use a lookup table instead, filled according to 3892 // the instruction sequences that codegen currently generates. 3893 int X86TTIImpl::getInterleavedMemoryOpCostAVX2(unsigned Opcode, Type *VecTy, 3894 unsigned Factor, 3895 ArrayRef<unsigned> Indices, 3896 unsigned Alignment, 3897 unsigned AddressSpace, 3898 bool UseMaskForCond, 3899 bool UseMaskForGaps) { 3900 3901 if (UseMaskForCond || UseMaskForGaps) 3902 return BaseT::getInterleavedMemoryOpCost(Opcode, VecTy, Factor, Indices, 3903 Alignment, AddressSpace, 3904 UseMaskForCond, UseMaskForGaps); 3905 3906 // We currently Support only fully-interleaved groups, with no gaps. 3907 // TODO: Support also strided loads (interleaved-groups with gaps). 3908 if (Indices.size() && Indices.size() != Factor) 3909 return BaseT::getInterleavedMemoryOpCost(Opcode, VecTy, Factor, Indices, 3910 Alignment, AddressSpace); 3911 3912 // VecTy for interleave memop is <VF*Factor x Elt>. 3913 // So, for VF=4, Interleave Factor = 3, Element type = i32 we have 3914 // VecTy = <12 x i32>. 3915 MVT LegalVT = getTLI()->getTypeLegalizationCost(DL, VecTy).second; 3916 3917 // This function can be called with VecTy=<6xi128>, Factor=3, in which case 3918 // the VF=2, while v2i128 is an unsupported MVT vector type 3919 // (see MachineValueType.h::getVectorVT()). 3920 if (!LegalVT.isVector()) 3921 return BaseT::getInterleavedMemoryOpCost(Opcode, VecTy, Factor, Indices, 3922 Alignment, AddressSpace); 3923 3924 unsigned VF = VecTy->getVectorNumElements() / Factor; 3925 Type *ScalarTy = VecTy->getVectorElementType(); 3926 3927 // Calculate the number of memory operations (NumOfMemOps), required 3928 // for load/store the VecTy. 3929 unsigned VecTySize = DL.getTypeStoreSize(VecTy); 3930 unsigned LegalVTSize = LegalVT.getStoreSize(); 3931 unsigned NumOfMemOps = (VecTySize + LegalVTSize - 1) / LegalVTSize; 3932 3933 // Get the cost of one memory operation. 3934 Type *SingleMemOpTy = VectorType::get(VecTy->getVectorElementType(), 3935 LegalVT.getVectorNumElements()); 3936 unsigned MemOpCost = getMemoryOpCost(Opcode, SingleMemOpTy, 3937 MaybeAlign(Alignment), AddressSpace); 3938 3939 VectorType *VT = VectorType::get(ScalarTy, VF); 3940 EVT ETy = TLI->getValueType(DL, VT); 3941 if (!ETy.isSimple()) 3942 return BaseT::getInterleavedMemoryOpCost(Opcode, VecTy, Factor, Indices, 3943 Alignment, AddressSpace); 3944 3945 // TODO: Complete for other data-types and strides. 3946 // Each combination of Stride, ElementTy and VF results in a different 3947 // sequence; The cost tables are therefore accessed with: 3948 // Factor (stride) and VectorType=VFxElemType. 3949 // The Cost accounts only for the shuffle sequence; 3950 // The cost of the loads/stores is accounted for separately. 3951 // 3952 static const CostTblEntry AVX2InterleavedLoadTbl[] = { 3953 { 2, MVT::v4i64, 6 }, //(load 8i64 and) deinterleave into 2 x 4i64 3954 { 2, MVT::v4f64, 6 }, //(load 8f64 and) deinterleave into 2 x 4f64 3955 3956 { 3, MVT::v2i8, 10 }, //(load 6i8 and) deinterleave into 3 x 2i8 3957 { 3, MVT::v4i8, 4 }, //(load 12i8 and) deinterleave into 3 x 4i8 3958 { 3, MVT::v8i8, 9 }, //(load 24i8 and) deinterleave into 3 x 8i8 3959 { 3, MVT::v16i8, 11}, //(load 48i8 and) deinterleave into 3 x 16i8 3960 { 3, MVT::v32i8, 13}, //(load 96i8 and) deinterleave into 3 x 32i8 3961 { 3, MVT::v8f32, 17 }, //(load 24f32 and)deinterleave into 3 x 8f32 3962 3963 { 4, MVT::v2i8, 12 }, //(load 8i8 and) deinterleave into 4 x 2i8 3964 { 4, MVT::v4i8, 4 }, //(load 16i8 and) deinterleave into 4 x 4i8 3965 { 4, MVT::v8i8, 20 }, //(load 32i8 and) deinterleave into 4 x 8i8 3966 { 4, MVT::v16i8, 39 }, //(load 64i8 and) deinterleave into 4 x 16i8 3967 { 4, MVT::v32i8, 80 }, //(load 128i8 and) deinterleave into 4 x 32i8 3968 3969 { 8, MVT::v8f32, 40 } //(load 64f32 and)deinterleave into 8 x 8f32 3970 }; 3971 3972 static const CostTblEntry AVX2InterleavedStoreTbl[] = { 3973 { 2, MVT::v4i64, 6 }, //interleave into 2 x 4i64 into 8i64 (and store) 3974 { 2, MVT::v4f64, 6 }, //interleave into 2 x 4f64 into 8f64 (and store) 3975 3976 { 3, MVT::v2i8, 7 }, //interleave 3 x 2i8 into 6i8 (and store) 3977 { 3, MVT::v4i8, 8 }, //interleave 3 x 4i8 into 12i8 (and store) 3978 { 3, MVT::v8i8, 11 }, //interleave 3 x 8i8 into 24i8 (and store) 3979 { 3, MVT::v16i8, 11 }, //interleave 3 x 16i8 into 48i8 (and store) 3980 { 3, MVT::v32i8, 13 }, //interleave 3 x 32i8 into 96i8 (and store) 3981 3982 { 4, MVT::v2i8, 12 }, //interleave 4 x 2i8 into 8i8 (and store) 3983 { 4, MVT::v4i8, 9 }, //interleave 4 x 4i8 into 16i8 (and store) 3984 { 4, MVT::v8i8, 10 }, //interleave 4 x 8i8 into 32i8 (and store) 3985 { 4, MVT::v16i8, 10 }, //interleave 4 x 16i8 into 64i8 (and store) 3986 { 4, MVT::v32i8, 12 } //interleave 4 x 32i8 into 128i8 (and store) 3987 }; 3988 3989 if (Opcode == Instruction::Load) { 3990 if (const auto *Entry = 3991 CostTableLookup(AVX2InterleavedLoadTbl, Factor, ETy.getSimpleVT())) 3992 return NumOfMemOps * MemOpCost + Entry->Cost; 3993 } else { 3994 assert(Opcode == Instruction::Store && 3995 "Expected Store Instruction at this point"); 3996 if (const auto *Entry = 3997 CostTableLookup(AVX2InterleavedStoreTbl, Factor, ETy.getSimpleVT())) 3998 return NumOfMemOps * MemOpCost + Entry->Cost; 3999 } 4000 4001 return BaseT::getInterleavedMemoryOpCost(Opcode, VecTy, Factor, Indices, 4002 Alignment, AddressSpace); 4003 } 4004 4005 // Get estimation for interleaved load/store operations and strided load. 4006 // \p Indices contains indices for strided load. 4007 // \p Factor - the factor of interleaving. 4008 // AVX-512 provides 3-src shuffles that significantly reduces the cost. 4009 int X86TTIImpl::getInterleavedMemoryOpCostAVX512(unsigned Opcode, Type *VecTy, 4010 unsigned Factor, 4011 ArrayRef<unsigned> Indices, 4012 unsigned Alignment, 4013 unsigned AddressSpace, 4014 bool UseMaskForCond, 4015 bool UseMaskForGaps) { 4016 4017 if (UseMaskForCond || UseMaskForGaps) 4018 return BaseT::getInterleavedMemoryOpCost(Opcode, VecTy, Factor, Indices, 4019 Alignment, AddressSpace, 4020 UseMaskForCond, UseMaskForGaps); 4021 4022 // VecTy for interleave memop is <VF*Factor x Elt>. 4023 // So, for VF=4, Interleave Factor = 3, Element type = i32 we have 4024 // VecTy = <12 x i32>. 4025 4026 // Calculate the number of memory operations (NumOfMemOps), required 4027 // for load/store the VecTy. 4028 MVT LegalVT = getTLI()->getTypeLegalizationCost(DL, VecTy).second; 4029 unsigned VecTySize = DL.getTypeStoreSize(VecTy); 4030 unsigned LegalVTSize = LegalVT.getStoreSize(); 4031 unsigned NumOfMemOps = (VecTySize + LegalVTSize - 1) / LegalVTSize; 4032 4033 // Get the cost of one memory operation. 4034 Type *SingleMemOpTy = VectorType::get(VecTy->getVectorElementType(), 4035 LegalVT.getVectorNumElements()); 4036 unsigned MemOpCost = getMemoryOpCost(Opcode, SingleMemOpTy, 4037 MaybeAlign(Alignment), AddressSpace); 4038 4039 unsigned VF = VecTy->getVectorNumElements() / Factor; 4040 MVT VT = MVT::getVectorVT(MVT::getVT(VecTy->getScalarType()), VF); 4041 4042 if (Opcode == Instruction::Load) { 4043 // The tables (AVX512InterleavedLoadTbl and AVX512InterleavedStoreTbl) 4044 // contain the cost of the optimized shuffle sequence that the 4045 // X86InterleavedAccess pass will generate. 4046 // The cost of loads and stores are computed separately from the table. 4047 4048 // X86InterleavedAccess support only the following interleaved-access group. 4049 static const CostTblEntry AVX512InterleavedLoadTbl[] = { 4050 {3, MVT::v16i8, 12}, //(load 48i8 and) deinterleave into 3 x 16i8 4051 {3, MVT::v32i8, 14}, //(load 96i8 and) deinterleave into 3 x 32i8 4052 {3, MVT::v64i8, 22}, //(load 96i8 and) deinterleave into 3 x 32i8 4053 }; 4054 4055 if (const auto *Entry = 4056 CostTableLookup(AVX512InterleavedLoadTbl, Factor, VT)) 4057 return NumOfMemOps * MemOpCost + Entry->Cost; 4058 //If an entry does not exist, fallback to the default implementation. 4059 4060 // Kind of shuffle depends on number of loaded values. 4061 // If we load the entire data in one register, we can use a 1-src shuffle. 4062 // Otherwise, we'll merge 2 sources in each operation. 4063 TTI::ShuffleKind ShuffleKind = 4064 (NumOfMemOps > 1) ? TTI::SK_PermuteTwoSrc : TTI::SK_PermuteSingleSrc; 4065 4066 unsigned ShuffleCost = 4067 getShuffleCost(ShuffleKind, SingleMemOpTy, 0, nullptr); 4068 4069 unsigned NumOfLoadsInInterleaveGrp = 4070 Indices.size() ? Indices.size() : Factor; 4071 Type *ResultTy = VectorType::get(VecTy->getVectorElementType(), 4072 VecTy->getVectorNumElements() / Factor); 4073 unsigned NumOfResults = 4074 getTLI()->getTypeLegalizationCost(DL, ResultTy).first * 4075 NumOfLoadsInInterleaveGrp; 4076 4077 // About a half of the loads may be folded in shuffles when we have only 4078 // one result. If we have more than one result, we do not fold loads at all. 4079 unsigned NumOfUnfoldedLoads = 4080 NumOfResults > 1 ? NumOfMemOps : NumOfMemOps / 2; 4081 4082 // Get a number of shuffle operations per result. 4083 unsigned NumOfShufflesPerResult = 4084 std::max((unsigned)1, (unsigned)(NumOfMemOps - 1)); 4085 4086 // The SK_MergeTwoSrc shuffle clobbers one of src operands. 4087 // When we have more than one destination, we need additional instructions 4088 // to keep sources. 4089 unsigned NumOfMoves = 0; 4090 if (NumOfResults > 1 && ShuffleKind == TTI::SK_PermuteTwoSrc) 4091 NumOfMoves = NumOfResults * NumOfShufflesPerResult / 2; 4092 4093 int Cost = NumOfResults * NumOfShufflesPerResult * ShuffleCost + 4094 NumOfUnfoldedLoads * MemOpCost + NumOfMoves; 4095 4096 return Cost; 4097 } 4098 4099 // Store. 4100 assert(Opcode == Instruction::Store && 4101 "Expected Store Instruction at this point"); 4102 // X86InterleavedAccess support only the following interleaved-access group. 4103 static const CostTblEntry AVX512InterleavedStoreTbl[] = { 4104 {3, MVT::v16i8, 12}, // interleave 3 x 16i8 into 48i8 (and store) 4105 {3, MVT::v32i8, 14}, // interleave 3 x 32i8 into 96i8 (and store) 4106 {3, MVT::v64i8, 26}, // interleave 3 x 64i8 into 96i8 (and store) 4107 4108 {4, MVT::v8i8, 10}, // interleave 4 x 8i8 into 32i8 (and store) 4109 {4, MVT::v16i8, 11}, // interleave 4 x 16i8 into 64i8 (and store) 4110 {4, MVT::v32i8, 14}, // interleave 4 x 32i8 into 128i8 (and store) 4111 {4, MVT::v64i8, 24} // interleave 4 x 32i8 into 256i8 (and store) 4112 }; 4113 4114 if (const auto *Entry = 4115 CostTableLookup(AVX512InterleavedStoreTbl, Factor, VT)) 4116 return NumOfMemOps * MemOpCost + Entry->Cost; 4117 //If an entry does not exist, fallback to the default implementation. 4118 4119 // There is no strided stores meanwhile. And store can't be folded in 4120 // shuffle. 4121 unsigned NumOfSources = Factor; // The number of values to be merged. 4122 unsigned ShuffleCost = 4123 getShuffleCost(TTI::SK_PermuteTwoSrc, SingleMemOpTy, 0, nullptr); 4124 unsigned NumOfShufflesPerStore = NumOfSources - 1; 4125 4126 // The SK_MergeTwoSrc shuffle clobbers one of src operands. 4127 // We need additional instructions to keep sources. 4128 unsigned NumOfMoves = NumOfMemOps * NumOfShufflesPerStore / 2; 4129 int Cost = NumOfMemOps * (MemOpCost + NumOfShufflesPerStore * ShuffleCost) + 4130 NumOfMoves; 4131 return Cost; 4132 } 4133 4134 int X86TTIImpl::getInterleavedMemoryOpCost(unsigned Opcode, Type *VecTy, 4135 unsigned Factor, 4136 ArrayRef<unsigned> Indices, 4137 unsigned Alignment, 4138 unsigned AddressSpace, 4139 bool UseMaskForCond, 4140 bool UseMaskForGaps) { 4141 auto isSupportedOnAVX512 = [](Type *VecTy, bool HasBW) { 4142 Type *EltTy = VecTy->getVectorElementType(); 4143 if (EltTy->isFloatTy() || EltTy->isDoubleTy() || EltTy->isIntegerTy(64) || 4144 EltTy->isIntegerTy(32) || EltTy->isPointerTy()) 4145 return true; 4146 if (EltTy->isIntegerTy(16) || EltTy->isIntegerTy(8)) 4147 return HasBW; 4148 return false; 4149 }; 4150 if (ST->hasAVX512() && isSupportedOnAVX512(VecTy, ST->hasBWI())) 4151 return getInterleavedMemoryOpCostAVX512(Opcode, VecTy, Factor, Indices, 4152 Alignment, AddressSpace, 4153 UseMaskForCond, UseMaskForGaps); 4154 if (ST->hasAVX2()) 4155 return getInterleavedMemoryOpCostAVX2(Opcode, VecTy, Factor, Indices, 4156 Alignment, AddressSpace, 4157 UseMaskForCond, UseMaskForGaps); 4158 4159 return BaseT::getInterleavedMemoryOpCost(Opcode, VecTy, Factor, Indices, 4160 Alignment, AddressSpace, 4161 UseMaskForCond, UseMaskForGaps); 4162 } 4163