1//===- X86LegalizerInfo.cpp --------------------------------------*- C++ -*-==// 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 the targeting of the Machinelegalizer class for X86. 10/// \todo This should be generated by TableGen. 11//===----------------------------------------------------------------------===// 12 13#include "X86LegalizerInfo.h" 14#include "X86Subtarget.h" 15#include "X86TargetMachine.h" 16#include "llvm/CodeGen/GlobalISel/LegalizerHelper.h" 17#include "llvm/CodeGen/TargetOpcodes.h" 18#include "llvm/CodeGen/ValueTypes.h" 19#include "llvm/IR/DerivedTypes.h" 20#include "llvm/IR/Type.h" 21 22using namespace llvm; 23using namespace TargetOpcode; 24using namespace LegalizeActions; 25 26/// FIXME: The following static functions are SizeChangeStrategy functions 27/// that are meant to temporarily mimic the behaviour of the old legalization 28/// based on doubling/halving non-legal types as closely as possible. This is 29/// not entirly possible as only legalizing the types that are exactly a power 30/// of 2 times the size of the legal types would require specifying all those 31/// sizes explicitly. 32/// In practice, not specifying those isn't a problem, and the below functions 33/// should disappear quickly as we add support for legalizing non-power-of-2 34/// sized types further. 35static void addAndInterleaveWithUnsupported( 36 LegacyLegalizerInfo::SizeAndActionsVec &result, 37 const LegacyLegalizerInfo::SizeAndActionsVec &v) { 38 for (unsigned i = 0; i < v.size(); ++i) { 39 result.push_back(v[i]); 40 if (i + 1 < v[i].first && i + 1 < v.size() && 41 v[i + 1].first != v[i].first + 1) 42 result.push_back({v[i].first + 1, LegacyLegalizeActions::Unsupported}); 43 } 44} 45 46static LegacyLegalizerInfo::SizeAndActionsVec 47widen_1(const LegacyLegalizerInfo::SizeAndActionsVec &v) { 48 assert(v.size() >= 1); 49 assert(v[0].first > 1); 50 LegacyLegalizerInfo::SizeAndActionsVec result = { 51 {1, LegacyLegalizeActions::WidenScalar}, 52 {2, LegacyLegalizeActions::Unsupported}}; 53 addAndInterleaveWithUnsupported(result, v); 54 auto Largest = result.back().first; 55 result.push_back({Largest + 1, LegacyLegalizeActions::Unsupported}); 56 return result; 57} 58 59X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI, 60 const X86TargetMachine &TM) 61 : Subtarget(STI), TM(TM) { 62 63 setLegalizerInfo32bit(); 64 setLegalizerInfo64bit(); 65 setLegalizerInfoSSE1(); 66 setLegalizerInfoSSE2(); 67 setLegalizerInfoSSE41(); 68 setLegalizerInfoAVX(); 69 setLegalizerInfoAVX2(); 70 setLegalizerInfoAVX512(); 71 setLegalizerInfoAVX512DQ(); 72 setLegalizerInfoAVX512BW(); 73 74 getActionDefinitionsBuilder(G_INTRINSIC_ROUNDEVEN) 75 .scalarize(0) 76 .minScalar(0, LLT::scalar(32)) 77 .libcall(); 78 79 auto &LegacyInfo = getLegacyLegalizerInfo(); 80 LegacyInfo.setLegalizeScalarToDifferentSizeStrategy(G_PHI, 0, widen_1); 81 for (unsigned BinOp : {G_SUB, G_MUL, G_AND, G_OR, G_XOR}) 82 LegacyInfo.setLegalizeScalarToDifferentSizeStrategy(BinOp, 0, widen_1); 83 for (unsigned MemOp : {G_LOAD, G_STORE}) 84 LegacyInfo.setLegalizeScalarToDifferentSizeStrategy( 85 MemOp, 0, LegacyLegalizerInfo::narrowToSmallerAndWidenToSmallest); 86 LegacyInfo.setLegalizeScalarToDifferentSizeStrategy( 87 G_PTR_ADD, 1, 88 LegacyLegalizerInfo::widenToLargerTypesUnsupportedOtherwise); 89 LegacyInfo.setLegalizeScalarToDifferentSizeStrategy( 90 G_CONSTANT, 0, 91 LegacyLegalizerInfo::widenToLargerTypesAndNarrowToLargest); 92 93 getActionDefinitionsBuilder({G_MEMCPY, G_MEMMOVE, G_MEMSET}).libcall(); 94 95 LegacyInfo.computeTables(); 96 verify(*STI.getInstrInfo()); 97} 98 99bool X86LegalizerInfo::legalizeIntrinsic(LegalizerHelper &Helper, 100 MachineInstr &MI) const { 101 return true; 102} 103 104void X86LegalizerInfo::setLegalizerInfo32bit() { 105 106 const LLT p0 = LLT::pointer(0, TM.getPointerSizeInBits(0)); 107 const LLT s1 = LLT::scalar(1); 108 const LLT s8 = LLT::scalar(8); 109 const LLT s16 = LLT::scalar(16); 110 const LLT s32 = LLT::scalar(32); 111 const LLT s64 = LLT::scalar(64); 112 const LLT s128 = LLT::scalar(128); 113 114 auto &LegacyInfo = getLegacyLegalizerInfo(); 115 116 for (auto Ty : {p0, s1, s8, s16, s32}) 117 LegacyInfo.setAction({G_IMPLICIT_DEF, Ty}, LegacyLegalizeActions::Legal); 118 119 for (auto Ty : {s8, s16, s32, p0}) 120 LegacyInfo.setAction({G_PHI, Ty}, LegacyLegalizeActions::Legal); 121 122 for (unsigned BinOp : {G_ADD, G_SUB, G_MUL, G_AND, G_OR, G_XOR}) 123 for (auto Ty : {s8, s16, s32}) 124 LegacyInfo.setAction({BinOp, Ty}, LegacyLegalizeActions::Legal); 125 126 for (unsigned Op : {G_UADDE}) { 127 LegacyInfo.setAction({Op, s32}, LegacyLegalizeActions::Legal); 128 LegacyInfo.setAction({Op, 1, s1}, LegacyLegalizeActions::Legal); 129 } 130 131 for (unsigned MemOp : {G_LOAD, G_STORE}) { 132 for (auto Ty : {s8, s16, s32, p0}) 133 LegacyInfo.setAction({MemOp, Ty}, LegacyLegalizeActions::Legal); 134 135 // And everything's fine in addrspace 0. 136 LegacyInfo.setAction({MemOp, 1, p0}, LegacyLegalizeActions::Legal); 137 } 138 139 // Pointer-handling 140 LegacyInfo.setAction({G_FRAME_INDEX, p0}, LegacyLegalizeActions::Legal); 141 LegacyInfo.setAction({G_GLOBAL_VALUE, p0}, LegacyLegalizeActions::Legal); 142 143 LegacyInfo.setAction({G_PTR_ADD, p0}, LegacyLegalizeActions::Legal); 144 LegacyInfo.setAction({G_PTR_ADD, 1, s32}, LegacyLegalizeActions::Legal); 145 146 if (!Subtarget.is64Bit()) { 147 getActionDefinitionsBuilder(G_PTRTOINT) 148 .legalForCartesianProduct({s1, s8, s16, s32}, {p0}) 149 .maxScalar(0, s32) 150 .widenScalarToNextPow2(0, /*Min*/ 8); 151 getActionDefinitionsBuilder(G_INTTOPTR).legalFor({{p0, s32}}); 152 153 // Shifts and SDIV 154 getActionDefinitionsBuilder( 155 {G_SDIV, G_SREM, G_UDIV, G_UREM}) 156 .legalFor({s8, s16, s32}) 157 .clampScalar(0, s8, s32); 158 159 getActionDefinitionsBuilder( 160 {G_SHL, G_LSHR, G_ASHR}) 161 .legalFor({{s8, s8}, {s16, s8}, {s32, s8}}) 162 .clampScalar(0, s8, s32) 163 .clampScalar(1, s8, s8); 164 165 // Comparison 166 getActionDefinitionsBuilder(G_ICMP) 167 .legalForCartesianProduct({s8}, {s8, s16, s32, p0}) 168 .clampScalar(0, s8, s8); 169 } 170 171 // Control-flow 172 LegacyInfo.setAction({G_BRCOND, s1}, LegacyLegalizeActions::Legal); 173 174 // Constants 175 for (auto Ty : {s8, s16, s32, p0}) 176 LegacyInfo.setAction({TargetOpcode::G_CONSTANT, Ty}, 177 LegacyLegalizeActions::Legal); 178 179 // Extensions 180 for (auto Ty : {s8, s16, s32}) { 181 LegacyInfo.setAction({G_ZEXT, Ty}, LegacyLegalizeActions::Legal); 182 LegacyInfo.setAction({G_SEXT, Ty}, LegacyLegalizeActions::Legal); 183 LegacyInfo.setAction({G_ANYEXT, Ty}, LegacyLegalizeActions::Legal); 184 } 185 LegacyInfo.setAction({G_ANYEXT, s128}, LegacyLegalizeActions::Legal); 186 getActionDefinitionsBuilder(G_SEXT_INREG).lower(); 187 188 // Merge/Unmerge 189 for (const auto &Ty : {s16, s32, s64}) { 190 LegacyInfo.setAction({G_MERGE_VALUES, Ty}, LegacyLegalizeActions::Legal); 191 LegacyInfo.setAction({G_UNMERGE_VALUES, 1, Ty}, 192 LegacyLegalizeActions::Legal); 193 } 194 for (const auto &Ty : {s8, s16, s32}) { 195 LegacyInfo.setAction({G_MERGE_VALUES, 1, Ty}, LegacyLegalizeActions::Legal); 196 LegacyInfo.setAction({G_UNMERGE_VALUES, Ty}, LegacyLegalizeActions::Legal); 197 } 198} 199 200void X86LegalizerInfo::setLegalizerInfo64bit() { 201 202 if (!Subtarget.is64Bit()) 203 return; 204 205 const LLT p0 = LLT::pointer(0, TM.getPointerSizeInBits(0)); 206 const LLT s1 = LLT::scalar(1); 207 const LLT s8 = LLT::scalar(8); 208 const LLT s16 = LLT::scalar(16); 209 const LLT s32 = LLT::scalar(32); 210 const LLT s64 = LLT::scalar(64); 211 const LLT s128 = LLT::scalar(128); 212 213 auto &LegacyInfo = getLegacyLegalizerInfo(); 214 215 LegacyInfo.setAction({G_IMPLICIT_DEF, s64}, LegacyLegalizeActions::Legal); 216 // Need to have that, as tryFoldImplicitDef will create this pattern: 217 // s128 = EXTEND (G_IMPLICIT_DEF s32/s64) -> s128 = G_IMPLICIT_DEF 218 LegacyInfo.setAction({G_IMPLICIT_DEF, s128}, LegacyLegalizeActions::Legal); 219 220 LegacyInfo.setAction({G_PHI, s64}, LegacyLegalizeActions::Legal); 221 222 for (unsigned BinOp : {G_ADD, G_SUB, G_MUL, G_AND, G_OR, G_XOR}) 223 LegacyInfo.setAction({BinOp, s64}, LegacyLegalizeActions::Legal); 224 225 for (unsigned MemOp : {G_LOAD, G_STORE}) 226 LegacyInfo.setAction({MemOp, s64}, LegacyLegalizeActions::Legal); 227 228 // Pointer-handling 229 LegacyInfo.setAction({G_PTR_ADD, 1, s64}, LegacyLegalizeActions::Legal); 230 getActionDefinitionsBuilder(G_PTRTOINT) 231 .legalForCartesianProduct({s1, s8, s16, s32, s64}, {p0}) 232 .maxScalar(0, s64) 233 .widenScalarToNextPow2(0, /*Min*/ 8); 234 getActionDefinitionsBuilder(G_INTTOPTR).legalFor({{p0, s64}}); 235 236 // Constants 237 LegacyInfo.setAction({TargetOpcode::G_CONSTANT, s64}, 238 LegacyLegalizeActions::Legal); 239 240 // Extensions 241 for (unsigned extOp : {G_ZEXT, G_SEXT, G_ANYEXT}) { 242 LegacyInfo.setAction({extOp, s64}, LegacyLegalizeActions::Legal); 243 } 244 245 getActionDefinitionsBuilder(G_SITOFP) 246 .legalForCartesianProduct({s32, s64}) 247 .clampScalar(1, s32, s64) 248 .widenScalarToNextPow2(1) 249 .clampScalar(0, s32, s64) 250 .widenScalarToNextPow2(0); 251 252 getActionDefinitionsBuilder(G_FPTOSI) 253 .legalForCartesianProduct({s32, s64}) 254 .clampScalar(1, s32, s64) 255 .widenScalarToNextPow2(0) 256 .clampScalar(0, s32, s64) 257 .widenScalarToNextPow2(1); 258 259 // Comparison 260 getActionDefinitionsBuilder(G_ICMP) 261 .legalForCartesianProduct({s8}, {s8, s16, s32, s64, p0}) 262 .clampScalar(0, s8, s8); 263 264 getActionDefinitionsBuilder(G_FCMP) 265 .legalForCartesianProduct({s8}, {s32, s64}) 266 .clampScalar(0, s8, s8) 267 .clampScalar(1, s32, s64) 268 .widenScalarToNextPow2(1); 269 270 // Divisions 271 getActionDefinitionsBuilder( 272 {G_SDIV, G_SREM, G_UDIV, G_UREM}) 273 .legalFor({s8, s16, s32, s64}) 274 .clampScalar(0, s8, s64); 275 276 // Shifts 277 getActionDefinitionsBuilder( 278 {G_SHL, G_LSHR, G_ASHR}) 279 .legalFor({{s8, s8}, {s16, s8}, {s32, s8}, {s64, s8}}) 280 .clampScalar(0, s8, s64) 281 .clampScalar(1, s8, s8); 282 283 // Merge/Unmerge 284 LegacyInfo.setAction({G_MERGE_VALUES, s128}, LegacyLegalizeActions::Legal); 285 LegacyInfo.setAction({G_UNMERGE_VALUES, 1, s128}, 286 LegacyLegalizeActions::Legal); 287 LegacyInfo.setAction({G_MERGE_VALUES, 1, s128}, LegacyLegalizeActions::Legal); 288 LegacyInfo.setAction({G_UNMERGE_VALUES, s128}, LegacyLegalizeActions::Legal); 289} 290 291void X86LegalizerInfo::setLegalizerInfoSSE1() { 292 if (!Subtarget.hasSSE1()) 293 return; 294 295 const LLT s32 = LLT::scalar(32); 296 const LLT s64 = LLT::scalar(64); 297 const LLT v4s32 = LLT::fixed_vector(4, 32); 298 const LLT v2s64 = LLT::fixed_vector(2, 64); 299 300 auto &LegacyInfo = getLegacyLegalizerInfo(); 301 302 for (unsigned BinOp : {G_FADD, G_FSUB, G_FMUL, G_FDIV}) 303 for (auto Ty : {s32, v4s32}) 304 LegacyInfo.setAction({BinOp, Ty}, LegacyLegalizeActions::Legal); 305 306 for (unsigned MemOp : {G_LOAD, G_STORE}) 307 for (auto Ty : {v4s32, v2s64}) 308 LegacyInfo.setAction({MemOp, Ty}, LegacyLegalizeActions::Legal); 309 310 // Constants 311 LegacyInfo.setAction({TargetOpcode::G_FCONSTANT, s32}, 312 LegacyLegalizeActions::Legal); 313 314 // Merge/Unmerge 315 for (const auto &Ty : {v4s32, v2s64}) { 316 LegacyInfo.setAction({G_CONCAT_VECTORS, Ty}, LegacyLegalizeActions::Legal); 317 LegacyInfo.setAction({G_UNMERGE_VALUES, 1, Ty}, 318 LegacyLegalizeActions::Legal); 319 } 320 LegacyInfo.setAction({G_MERGE_VALUES, 1, s64}, LegacyLegalizeActions::Legal); 321 LegacyInfo.setAction({G_UNMERGE_VALUES, s64}, LegacyLegalizeActions::Legal); 322} 323 324void X86LegalizerInfo::setLegalizerInfoSSE2() { 325 if (!Subtarget.hasSSE2()) 326 return; 327 328 const LLT s32 = LLT::scalar(32); 329 const LLT s64 = LLT::scalar(64); 330 const LLT v16s8 = LLT::fixed_vector(16, 8); 331 const LLT v8s16 = LLT::fixed_vector(8, 16); 332 const LLT v4s32 = LLT::fixed_vector(4, 32); 333 const LLT v2s64 = LLT::fixed_vector(2, 64); 334 335 const LLT v32s8 = LLT::fixed_vector(32, 8); 336 const LLT v16s16 = LLT::fixed_vector(16, 16); 337 const LLT v8s32 = LLT::fixed_vector(8, 32); 338 const LLT v4s64 = LLT::fixed_vector(4, 64); 339 340 auto &LegacyInfo = getLegacyLegalizerInfo(); 341 342 for (unsigned BinOp : {G_FADD, G_FSUB, G_FMUL, G_FDIV}) 343 for (auto Ty : {s64, v2s64}) 344 LegacyInfo.setAction({BinOp, Ty}, LegacyLegalizeActions::Legal); 345 346 for (unsigned BinOp : {G_ADD, G_SUB}) 347 for (auto Ty : {v16s8, v8s16, v4s32, v2s64}) 348 LegacyInfo.setAction({BinOp, Ty}, LegacyLegalizeActions::Legal); 349 350 LegacyInfo.setAction({G_MUL, v8s16}, LegacyLegalizeActions::Legal); 351 352 LegacyInfo.setAction({G_FPEXT, s64}, LegacyLegalizeActions::Legal); 353 LegacyInfo.setAction({G_FPEXT, 1, s32}, LegacyLegalizeActions::Legal); 354 355 LegacyInfo.setAction({G_FPTRUNC, s32}, LegacyLegalizeActions::Legal); 356 LegacyInfo.setAction({G_FPTRUNC, 1, s64}, LegacyLegalizeActions::Legal); 357 358 // Constants 359 LegacyInfo.setAction({TargetOpcode::G_FCONSTANT, s64}, 360 LegacyLegalizeActions::Legal); 361 362 // Merge/Unmerge 363 for (const auto &Ty : 364 {v16s8, v32s8, v8s16, v16s16, v4s32, v8s32, v2s64, v4s64}) { 365 LegacyInfo.setAction({G_CONCAT_VECTORS, Ty}, LegacyLegalizeActions::Legal); 366 LegacyInfo.setAction({G_UNMERGE_VALUES, 1, Ty}, 367 LegacyLegalizeActions::Legal); 368 } 369 for (const auto &Ty : {v16s8, v8s16, v4s32, v2s64}) { 370 LegacyInfo.setAction({G_CONCAT_VECTORS, 1, Ty}, 371 LegacyLegalizeActions::Legal); 372 LegacyInfo.setAction({G_UNMERGE_VALUES, Ty}, LegacyLegalizeActions::Legal); 373 } 374} 375 376void X86LegalizerInfo::setLegalizerInfoSSE41() { 377 if (!Subtarget.hasSSE41()) 378 return; 379 380 const LLT v4s32 = LLT::fixed_vector(4, 32); 381 382 auto &LegacyInfo = getLegacyLegalizerInfo(); 383 384 LegacyInfo.setAction({G_MUL, v4s32}, LegacyLegalizeActions::Legal); 385} 386 387void X86LegalizerInfo::setLegalizerInfoAVX() { 388 if (!Subtarget.hasAVX()) 389 return; 390 391 const LLT v16s8 = LLT::fixed_vector(16, 8); 392 const LLT v8s16 = LLT::fixed_vector(8, 16); 393 const LLT v4s32 = LLT::fixed_vector(4, 32); 394 const LLT v2s64 = LLT::fixed_vector(2, 64); 395 396 const LLT v32s8 = LLT::fixed_vector(32, 8); 397 const LLT v64s8 = LLT::fixed_vector(64, 8); 398 const LLT v16s16 = LLT::fixed_vector(16, 16); 399 const LLT v32s16 = LLT::fixed_vector(32, 16); 400 const LLT v8s32 = LLT::fixed_vector(8, 32); 401 const LLT v16s32 = LLT::fixed_vector(16, 32); 402 const LLT v4s64 = LLT::fixed_vector(4, 64); 403 const LLT v8s64 = LLT::fixed_vector(8, 64); 404 405 auto &LegacyInfo = getLegacyLegalizerInfo(); 406 407 for (unsigned MemOp : {G_LOAD, G_STORE}) 408 for (auto Ty : {v8s32, v4s64}) 409 LegacyInfo.setAction({MemOp, Ty}, LegacyLegalizeActions::Legal); 410 411 for (auto Ty : {v32s8, v16s16, v8s32, v4s64}) { 412 LegacyInfo.setAction({G_INSERT, Ty}, LegacyLegalizeActions::Legal); 413 LegacyInfo.setAction({G_EXTRACT, 1, Ty}, LegacyLegalizeActions::Legal); 414 } 415 for (auto Ty : {v16s8, v8s16, v4s32, v2s64}) { 416 LegacyInfo.setAction({G_INSERT, 1, Ty}, LegacyLegalizeActions::Legal); 417 LegacyInfo.setAction({G_EXTRACT, Ty}, LegacyLegalizeActions::Legal); 418 } 419 // Merge/Unmerge 420 for (const auto &Ty : 421 {v32s8, v64s8, v16s16, v32s16, v8s32, v16s32, v4s64, v8s64}) { 422 LegacyInfo.setAction({G_CONCAT_VECTORS, Ty}, LegacyLegalizeActions::Legal); 423 LegacyInfo.setAction({G_UNMERGE_VALUES, 1, Ty}, 424 LegacyLegalizeActions::Legal); 425 } 426 for (const auto &Ty : 427 {v16s8, v32s8, v8s16, v16s16, v4s32, v8s32, v2s64, v4s64}) { 428 LegacyInfo.setAction({G_CONCAT_VECTORS, 1, Ty}, 429 LegacyLegalizeActions::Legal); 430 LegacyInfo.setAction({G_UNMERGE_VALUES, Ty}, LegacyLegalizeActions::Legal); 431 } 432} 433 434void X86LegalizerInfo::setLegalizerInfoAVX2() { 435 if (!Subtarget.hasAVX2()) 436 return; 437 438 const LLT v32s8 = LLT::fixed_vector(32, 8); 439 const LLT v16s16 = LLT::fixed_vector(16, 16); 440 const LLT v8s32 = LLT::fixed_vector(8, 32); 441 const LLT v4s64 = LLT::fixed_vector(4, 64); 442 443 const LLT v64s8 = LLT::fixed_vector(64, 8); 444 const LLT v32s16 = LLT::fixed_vector(32, 16); 445 const LLT v16s32 = LLT::fixed_vector(16, 32); 446 const LLT v8s64 = LLT::fixed_vector(8, 64); 447 448 auto &LegacyInfo = getLegacyLegalizerInfo(); 449 450 for (unsigned BinOp : {G_ADD, G_SUB}) 451 for (auto Ty : {v32s8, v16s16, v8s32, v4s64}) 452 LegacyInfo.setAction({BinOp, Ty}, LegacyLegalizeActions::Legal); 453 454 for (auto Ty : {v16s16, v8s32}) 455 LegacyInfo.setAction({G_MUL, Ty}, LegacyLegalizeActions::Legal); 456 457 // Merge/Unmerge 458 for (const auto &Ty : {v64s8, v32s16, v16s32, v8s64}) { 459 LegacyInfo.setAction({G_CONCAT_VECTORS, Ty}, LegacyLegalizeActions::Legal); 460 LegacyInfo.setAction({G_UNMERGE_VALUES, 1, Ty}, 461 LegacyLegalizeActions::Legal); 462 } 463 for (const auto &Ty : {v32s8, v16s16, v8s32, v4s64}) { 464 LegacyInfo.setAction({G_CONCAT_VECTORS, 1, Ty}, 465 LegacyLegalizeActions::Legal); 466 LegacyInfo.setAction({G_UNMERGE_VALUES, Ty}, LegacyLegalizeActions::Legal); 467 } 468} 469 470void X86LegalizerInfo::setLegalizerInfoAVX512() { 471 if (!Subtarget.hasAVX512()) 472 return; 473 474 const LLT v16s8 = LLT::fixed_vector(16, 8); 475 const LLT v8s16 = LLT::fixed_vector(8, 16); 476 const LLT v4s32 = LLT::fixed_vector(4, 32); 477 const LLT v2s64 = LLT::fixed_vector(2, 64); 478 479 const LLT v32s8 = LLT::fixed_vector(32, 8); 480 const LLT v16s16 = LLT::fixed_vector(16, 16); 481 const LLT v8s32 = LLT::fixed_vector(8, 32); 482 const LLT v4s64 = LLT::fixed_vector(4, 64); 483 484 const LLT v64s8 = LLT::fixed_vector(64, 8); 485 const LLT v32s16 = LLT::fixed_vector(32, 16); 486 const LLT v16s32 = LLT::fixed_vector(16, 32); 487 const LLT v8s64 = LLT::fixed_vector(8, 64); 488 489 auto &LegacyInfo = getLegacyLegalizerInfo(); 490 491 for (unsigned BinOp : {G_ADD, G_SUB}) 492 for (auto Ty : {v16s32, v8s64}) 493 LegacyInfo.setAction({BinOp, Ty}, LegacyLegalizeActions::Legal); 494 495 LegacyInfo.setAction({G_MUL, v16s32}, LegacyLegalizeActions::Legal); 496 497 for (unsigned MemOp : {G_LOAD, G_STORE}) 498 for (auto Ty : {v16s32, v8s64}) 499 LegacyInfo.setAction({MemOp, Ty}, LegacyLegalizeActions::Legal); 500 501 for (auto Ty : {v64s8, v32s16, v16s32, v8s64}) { 502 LegacyInfo.setAction({G_INSERT, Ty}, LegacyLegalizeActions::Legal); 503 LegacyInfo.setAction({G_EXTRACT, 1, Ty}, LegacyLegalizeActions::Legal); 504 } 505 for (auto Ty : {v32s8, v16s16, v8s32, v4s64, v16s8, v8s16, v4s32, v2s64}) { 506 LegacyInfo.setAction({G_INSERT, 1, Ty}, LegacyLegalizeActions::Legal); 507 LegacyInfo.setAction({G_EXTRACT, Ty}, LegacyLegalizeActions::Legal); 508 } 509 510 /************ VLX *******************/ 511 if (!Subtarget.hasVLX()) 512 return; 513 514 for (auto Ty : {v4s32, v8s32}) 515 LegacyInfo.setAction({G_MUL, Ty}, LegacyLegalizeActions::Legal); 516} 517 518void X86LegalizerInfo::setLegalizerInfoAVX512DQ() { 519 if (!(Subtarget.hasAVX512() && Subtarget.hasDQI())) 520 return; 521 522 const LLT v8s64 = LLT::fixed_vector(8, 64); 523 524 auto &LegacyInfo = getLegacyLegalizerInfo(); 525 526 LegacyInfo.setAction({G_MUL, v8s64}, LegacyLegalizeActions::Legal); 527 528 /************ VLX *******************/ 529 if (!Subtarget.hasVLX()) 530 return; 531 532 const LLT v2s64 = LLT::fixed_vector(2, 64); 533 const LLT v4s64 = LLT::fixed_vector(4, 64); 534 535 for (auto Ty : {v2s64, v4s64}) 536 LegacyInfo.setAction({G_MUL, Ty}, LegacyLegalizeActions::Legal); 537} 538 539void X86LegalizerInfo::setLegalizerInfoAVX512BW() { 540 if (!(Subtarget.hasAVX512() && Subtarget.hasBWI())) 541 return; 542 543 const LLT v64s8 = LLT::fixed_vector(64, 8); 544 const LLT v32s16 = LLT::fixed_vector(32, 16); 545 546 auto &LegacyInfo = getLegacyLegalizerInfo(); 547 548 for (unsigned BinOp : {G_ADD, G_SUB}) 549 for (auto Ty : {v64s8, v32s16}) 550 LegacyInfo.setAction({BinOp, Ty}, LegacyLegalizeActions::Legal); 551 552 LegacyInfo.setAction({G_MUL, v32s16}, LegacyLegalizeActions::Legal); 553 554 /************ VLX *******************/ 555 if (!Subtarget.hasVLX()) 556 return; 557 558 const LLT v8s16 = LLT::fixed_vector(8, 16); 559 const LLT v16s16 = LLT::fixed_vector(16, 16); 560 561 for (auto Ty : {v8s16, v16s16}) 562 LegacyInfo.setAction({G_MUL, Ty}, LegacyLegalizeActions::Legal); 563} 564