1317017Sdim//===- X86LegalizerInfo.cpp --------------------------------------*- C++ -*-==// 2317017Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6317017Sdim// 7317017Sdim//===----------------------------------------------------------------------===// 8317017Sdim/// \file 9317017Sdim/// This file implements the targeting of the Machinelegalizer class for X86. 10317017Sdim/// \todo This should be generated by TableGen. 11317017Sdim//===----------------------------------------------------------------------===// 12317017Sdim 13317017Sdim#include "X86LegalizerInfo.h" 14317017Sdim#include "X86Subtarget.h" 15317017Sdim#include "X86TargetMachine.h" 16360784Sdim#include "llvm/CodeGen/GlobalISel/LegalizerHelper.h" 17327952Sdim#include "llvm/CodeGen/TargetOpcodes.h" 18317017Sdim#include "llvm/CodeGen/ValueTypes.h" 19317017Sdim#include "llvm/IR/DerivedTypes.h" 20317017Sdim#include "llvm/IR/Type.h" 21317017Sdim 22317017Sdimusing namespace llvm; 23317017Sdimusing namespace TargetOpcode; 24341825Sdimusing namespace LegalizeActions; 25317017Sdim 26327952Sdim/// FIXME: The following static functions are SizeChangeStrategy functions 27327952Sdim/// that are meant to temporarily mimic the behaviour of the old legalization 28327952Sdim/// based on doubling/halving non-legal types as closely as possible. This is 29327952Sdim/// not entirly possible as only legalizing the types that are exactly a power 30327952Sdim/// of 2 times the size of the legal types would require specifying all those 31327952Sdim/// sizes explicitly. 32327952Sdim/// In practice, not specifying those isn't a problem, and the below functions 33327952Sdim/// should disappear quickly as we add support for legalizing non-power-of-2 34327952Sdim/// sized types further. 35327952Sdimstatic void 36327952SdimaddAndInterleaveWithUnsupported(LegalizerInfo::SizeAndActionsVec &result, 37327952Sdim const LegalizerInfo::SizeAndActionsVec &v) { 38327952Sdim for (unsigned i = 0; i < v.size(); ++i) { 39327952Sdim result.push_back(v[i]); 40327952Sdim if (i + 1 < v[i].first && i + 1 < v.size() && 41327952Sdim v[i + 1].first != v[i].first + 1) 42341825Sdim result.push_back({v[i].first + 1, Unsupported}); 43327952Sdim } 44327952Sdim} 45317017Sdim 46327952Sdimstatic LegalizerInfo::SizeAndActionsVec 47327952Sdimwiden_1(const LegalizerInfo::SizeAndActionsVec &v) { 48327952Sdim assert(v.size() >= 1); 49327952Sdim assert(v[0].first > 1); 50341825Sdim LegalizerInfo::SizeAndActionsVec result = {{1, WidenScalar}, 51341825Sdim {2, Unsupported}}; 52327952Sdim addAndInterleaveWithUnsupported(result, v); 53327952Sdim auto Largest = result.back().first; 54341825Sdim result.push_back({Largest + 1, Unsupported}); 55327952Sdim return result; 56327952Sdim} 57327952Sdim 58317017SdimX86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI, 59317017Sdim const X86TargetMachine &TM) 60317017Sdim : Subtarget(STI), TM(TM) { 61317017Sdim 62317017Sdim setLegalizerInfo32bit(); 63317017Sdim setLegalizerInfo64bit(); 64317017Sdim setLegalizerInfoSSE1(); 65317017Sdim setLegalizerInfoSSE2(); 66317969Sdim setLegalizerInfoSSE41(); 67319164Sdim setLegalizerInfoAVX(); 68317969Sdim setLegalizerInfoAVX2(); 69317969Sdim setLegalizerInfoAVX512(); 70317969Sdim setLegalizerInfoAVX512DQ(); 71317969Sdim setLegalizerInfoAVX512BW(); 72317017Sdim 73327952Sdim setLegalizeScalarToDifferentSizeStrategy(G_PHI, 0, widen_1); 74327952Sdim for (unsigned BinOp : {G_SUB, G_MUL, G_AND, G_OR, G_XOR}) 75327952Sdim setLegalizeScalarToDifferentSizeStrategy(BinOp, 0, widen_1); 76327952Sdim for (unsigned MemOp : {G_LOAD, G_STORE}) 77327952Sdim setLegalizeScalarToDifferentSizeStrategy(MemOp, 0, 78327952Sdim narrowToSmallerAndWidenToSmallest); 79327952Sdim setLegalizeScalarToDifferentSizeStrategy( 80360784Sdim G_PTR_ADD, 1, widenToLargerTypesUnsupportedOtherwise); 81327952Sdim setLegalizeScalarToDifferentSizeStrategy( 82327952Sdim G_CONSTANT, 0, widenToLargerTypesAndNarrowToLargest); 83327952Sdim 84317017Sdim computeTables(); 85341825Sdim verify(*STI.getInstrInfo()); 86317017Sdim} 87317017Sdim 88360784Sdimbool X86LegalizerInfo::legalizeIntrinsic(MachineInstr &MI, 89360784Sdim MachineRegisterInfo &MRI, 90360784Sdim MachineIRBuilder &MIRBuilder) const { 91360784Sdim switch (MI.getIntrinsicID()) { 92360784Sdim case Intrinsic::memcpy: 93360784Sdim case Intrinsic::memset: 94360784Sdim case Intrinsic::memmove: 95360784Sdim if (createMemLibcall(MIRBuilder, MRI, MI) == 96360784Sdim LegalizerHelper::UnableToLegalize) 97360784Sdim return false; 98360784Sdim MI.eraseFromParent(); 99360784Sdim return true; 100360784Sdim default: 101360784Sdim break; 102360784Sdim } 103360784Sdim return true; 104360784Sdim} 105360784Sdim 106317017Sdimvoid X86LegalizerInfo::setLegalizerInfo32bit() { 107317017Sdim 108341825Sdim const LLT p0 = LLT::pointer(0, TM.getPointerSizeInBits(0)); 109317017Sdim const LLT s1 = LLT::scalar(1); 110317017Sdim const LLT s8 = LLT::scalar(8); 111317017Sdim const LLT s16 = LLT::scalar(16); 112317017Sdim const LLT s32 = LLT::scalar(32); 113317017Sdim const LLT s64 = LLT::scalar(64); 114341825Sdim const LLT s128 = LLT::scalar(128); 115317017Sdim 116327952Sdim for (auto Ty : {p0, s1, s8, s16, s32}) 117327952Sdim setAction({G_IMPLICIT_DEF, Ty}, Legal); 118327952Sdim 119327952Sdim for (auto Ty : {s8, s16, s32, p0}) 120327952Sdim setAction({G_PHI, Ty}, Legal); 121327952Sdim 122320572Sdim for (unsigned BinOp : {G_ADD, G_SUB, G_MUL, G_AND, G_OR, G_XOR}) 123317017Sdim for (auto Ty : {s8, s16, s32}) 124317017Sdim setAction({BinOp, Ty}, Legal); 125317017Sdim 126318477Sdim for (unsigned Op : {G_UADDE}) { 127318477Sdim setAction({Op, s32}, Legal); 128318477Sdim setAction({Op, 1, s1}, Legal); 129318477Sdim } 130318477Sdim 131317017Sdim for (unsigned MemOp : {G_LOAD, G_STORE}) { 132317017Sdim for (auto Ty : {s8, s16, s32, p0}) 133317017Sdim setAction({MemOp, Ty}, Legal); 134317017Sdim 135317017Sdim // And everything's fine in addrspace 0. 136317017Sdim setAction({MemOp, 1, p0}, Legal); 137317017Sdim } 138317017Sdim 139317017Sdim // Pointer-handling 140317017Sdim setAction({G_FRAME_INDEX, p0}, Legal); 141320970Sdim setAction({G_GLOBAL_VALUE, p0}, Legal); 142317017Sdim 143360784Sdim setAction({G_PTR_ADD, p0}, Legal); 144360784Sdim setAction({G_PTR_ADD, 1, s32}, Legal); 145317969Sdim 146341825Sdim if (!Subtarget.is64Bit()) { 147341825Sdim getActionDefinitionsBuilder(G_PTRTOINT) 148341825Sdim .legalForCartesianProduct({s1, s8, s16, s32}, {p0}) 149341825Sdim .maxScalar(0, s32) 150341825Sdim .widenScalarToNextPow2(0, /*Min*/ 8); 151341825Sdim getActionDefinitionsBuilder(G_INTTOPTR).legalFor({{p0, s32}}); 152341825Sdim 153341825Sdim // Shifts and SDIV 154344779Sdim getActionDefinitionsBuilder( 155353358Sdim {G_SDIV, G_SREM, G_UDIV, G_UREM}) 156353358Sdim .legalFor({s8, s16, s32}) 157353358Sdim .clampScalar(0, s8, s32); 158353358Sdim 159353358Sdim getActionDefinitionsBuilder( 160353358Sdim {G_SHL, G_LSHR, G_ASHR}) 161353358Sdim .legalFor({{s8, s8}, {s16, s8}, {s32, s8}}) 162353358Sdim .clampScalar(0, s8, s32) 163353358Sdim .clampScalar(1, s8, s8); 164341825Sdim } 165341825Sdim 166327952Sdim // Control-flow 167327952Sdim setAction({G_BRCOND, s1}, Legal); 168317969Sdim 169317017Sdim // Constants 170317017Sdim for (auto Ty : {s8, s16, s32, p0}) 171317017Sdim setAction({TargetOpcode::G_CONSTANT, Ty}, Legal); 172317017Sdim 173317778Sdim // Extensions 174320970Sdim for (auto Ty : {s8, s16, s32}) { 175320970Sdim setAction({G_ZEXT, Ty}, Legal); 176320970Sdim setAction({G_SEXT, Ty}, Legal); 177327952Sdim setAction({G_ANYEXT, Ty}, Legal); 178320970Sdim } 179341825Sdim setAction({G_ANYEXT, s128}, Legal); 180360784Sdim getActionDefinitionsBuilder(G_SEXT_INREG).lower(); 181317778Sdim 182318384Sdim // Comparison 183318384Sdim setAction({G_ICMP, s1}, Legal); 184318384Sdim 185318384Sdim for (auto Ty : {s8, s16, s32, p0}) 186318384Sdim setAction({G_ICMP, 1, Ty}, Legal); 187327952Sdim 188327952Sdim // Merge/Unmerge 189327952Sdim for (const auto &Ty : {s16, s32, s64}) { 190327952Sdim setAction({G_MERGE_VALUES, Ty}, Legal); 191327952Sdim setAction({G_UNMERGE_VALUES, 1, Ty}, Legal); 192327952Sdim } 193327952Sdim for (const auto &Ty : {s8, s16, s32}) { 194327952Sdim setAction({G_MERGE_VALUES, 1, Ty}, Legal); 195327952Sdim setAction({G_UNMERGE_VALUES, Ty}, Legal); 196327952Sdim } 197317017Sdim} 198317017Sdim 199317017Sdimvoid X86LegalizerInfo::setLegalizerInfo64bit() { 200317017Sdim 201317017Sdim if (!Subtarget.is64Bit()) 202317017Sdim return; 203317017Sdim 204341825Sdim const LLT p0 = LLT::pointer(0, TM.getPointerSizeInBits(0)); 205341825Sdim const LLT s1 = LLT::scalar(1); 206341825Sdim const LLT s8 = LLT::scalar(8); 207341825Sdim const LLT s16 = LLT::scalar(16); 208341825Sdim const LLT s32 = LLT::scalar(32); 209317017Sdim const LLT s64 = LLT::scalar(64); 210327952Sdim const LLT s128 = LLT::scalar(128); 211317017Sdim 212327952Sdim setAction({G_IMPLICIT_DEF, s64}, Legal); 213341825Sdim // Need to have that, as tryFoldImplicitDef will create this pattern: 214341825Sdim // s128 = EXTEND (G_IMPLICIT_DEF s32/s64) -> s128 = G_IMPLICIT_DEF 215341825Sdim setAction({G_IMPLICIT_DEF, s128}, Legal); 216327952Sdim 217327952Sdim setAction({G_PHI, s64}, Legal); 218327952Sdim 219320572Sdim for (unsigned BinOp : {G_ADD, G_SUB, G_MUL, G_AND, G_OR, G_XOR}) 220327952Sdim setAction({BinOp, s64}, Legal); 221317017Sdim 222327952Sdim for (unsigned MemOp : {G_LOAD, G_STORE}) 223327952Sdim setAction({MemOp, s64}, Legal); 224317017Sdim 225317017Sdim // Pointer-handling 226360784Sdim setAction({G_PTR_ADD, 1, s64}, Legal); 227341825Sdim getActionDefinitionsBuilder(G_PTRTOINT) 228341825Sdim .legalForCartesianProduct({s1, s8, s16, s32, s64}, {p0}) 229341825Sdim .maxScalar(0, s64) 230341825Sdim .widenScalarToNextPow2(0, /*Min*/ 8); 231341825Sdim getActionDefinitionsBuilder(G_INTTOPTR).legalFor({{p0, s64}}); 232317969Sdim 233317017Sdim // Constants 234327952Sdim setAction({TargetOpcode::G_CONSTANT, s64}, Legal); 235317017Sdim 236317778Sdim // Extensions 237327952Sdim for (unsigned extOp : {G_ZEXT, G_SEXT, G_ANYEXT}) { 238327952Sdim setAction({extOp, s64}, Legal); 239317778Sdim } 240317778Sdim 241341825Sdim getActionDefinitionsBuilder(G_SITOFP) 242341825Sdim .legalForCartesianProduct({s32, s64}) 243341825Sdim .clampScalar(1, s32, s64) 244341825Sdim .widenScalarToNextPow2(1) 245341825Sdim .clampScalar(0, s32, s64) 246341825Sdim .widenScalarToNextPow2(0); 247341825Sdim 248344779Sdim getActionDefinitionsBuilder(G_FPTOSI) 249344779Sdim .legalForCartesianProduct({s32, s64}) 250344779Sdim .clampScalar(1, s32, s64) 251344779Sdim .widenScalarToNextPow2(0) 252344779Sdim .clampScalar(0, s32, s64) 253344779Sdim .widenScalarToNextPow2(1); 254344779Sdim 255318384Sdim // Comparison 256327952Sdim setAction({G_ICMP, 1, s64}, Legal); 257318384Sdim 258344779Sdim getActionDefinitionsBuilder(G_FCMP) 259344779Sdim .legalForCartesianProduct({s8}, {s32, s64}) 260344779Sdim .clampScalar(0, s8, s8) 261344779Sdim .clampScalar(1, s32, s64) 262344779Sdim .widenScalarToNextPow2(1); 263344779Sdim 264353358Sdim // Divisions 265344779Sdim getActionDefinitionsBuilder( 266353358Sdim {G_SDIV, G_SREM, G_UDIV, G_UREM}) 267344779Sdim .legalFor({s8, s16, s32, s64}) 268344779Sdim .clampScalar(0, s8, s64); 269341825Sdim 270353358Sdim // Shifts 271353358Sdim getActionDefinitionsBuilder( 272353358Sdim {G_SHL, G_LSHR, G_ASHR}) 273353358Sdim .legalFor({{s8, s8}, {s16, s8}, {s32, s8}, {s64, s8}}) 274353358Sdim .clampScalar(0, s8, s64) 275353358Sdim .clampScalar(1, s8, s8); 276353358Sdim 277327952Sdim // Merge/Unmerge 278327952Sdim setAction({G_MERGE_VALUES, s128}, Legal); 279327952Sdim setAction({G_UNMERGE_VALUES, 1, s128}, Legal); 280327952Sdim setAction({G_MERGE_VALUES, 1, s128}, Legal); 281327952Sdim setAction({G_UNMERGE_VALUES, s128}, Legal); 282317017Sdim} 283317017Sdim 284317017Sdimvoid X86LegalizerInfo::setLegalizerInfoSSE1() { 285317017Sdim if (!Subtarget.hasSSE1()) 286317017Sdim return; 287317017Sdim 288317017Sdim const LLT s32 = LLT::scalar(32); 289327952Sdim const LLT s64 = LLT::scalar(64); 290317017Sdim const LLT v4s32 = LLT::vector(4, 32); 291317017Sdim const LLT v2s64 = LLT::vector(2, 64); 292317017Sdim 293317017Sdim for (unsigned BinOp : {G_FADD, G_FSUB, G_FMUL, G_FDIV}) 294317017Sdim for (auto Ty : {s32, v4s32}) 295317017Sdim setAction({BinOp, Ty}, Legal); 296317017Sdim 297317017Sdim for (unsigned MemOp : {G_LOAD, G_STORE}) 298317017Sdim for (auto Ty : {v4s32, v2s64}) 299317017Sdim setAction({MemOp, Ty}, Legal); 300327952Sdim 301327952Sdim // Constants 302327952Sdim setAction({TargetOpcode::G_FCONSTANT, s32}, Legal); 303327952Sdim 304327952Sdim // Merge/Unmerge 305327952Sdim for (const auto &Ty : {v4s32, v2s64}) { 306344779Sdim setAction({G_CONCAT_VECTORS, Ty}, Legal); 307327952Sdim setAction({G_UNMERGE_VALUES, 1, Ty}, Legal); 308327952Sdim } 309327952Sdim setAction({G_MERGE_VALUES, 1, s64}, Legal); 310327952Sdim setAction({G_UNMERGE_VALUES, s64}, Legal); 311317017Sdim} 312317017Sdim 313317017Sdimvoid X86LegalizerInfo::setLegalizerInfoSSE2() { 314317017Sdim if (!Subtarget.hasSSE2()) 315317017Sdim return; 316317017Sdim 317327952Sdim const LLT s32 = LLT::scalar(32); 318317017Sdim const LLT s64 = LLT::scalar(64); 319318681Sdim const LLT v16s8 = LLT::vector(16, 8); 320317969Sdim const LLT v8s16 = LLT::vector(8, 16); 321317017Sdim const LLT v4s32 = LLT::vector(4, 32); 322317017Sdim const LLT v2s64 = LLT::vector(2, 64); 323317017Sdim 324327952Sdim const LLT v32s8 = LLT::vector(32, 8); 325327952Sdim const LLT v16s16 = LLT::vector(16, 16); 326327952Sdim const LLT v8s32 = LLT::vector(8, 32); 327327952Sdim const LLT v4s64 = LLT::vector(4, 64); 328327952Sdim 329317017Sdim for (unsigned BinOp : {G_FADD, G_FSUB, G_FMUL, G_FDIV}) 330317017Sdim for (auto Ty : {s64, v2s64}) 331317017Sdim setAction({BinOp, Ty}, Legal); 332317017Sdim 333317017Sdim for (unsigned BinOp : {G_ADD, G_SUB}) 334318681Sdim for (auto Ty : {v16s8, v8s16, v4s32, v2s64}) 335317017Sdim setAction({BinOp, Ty}, Legal); 336317969Sdim 337317969Sdim setAction({G_MUL, v8s16}, Legal); 338327952Sdim 339327952Sdim setAction({G_FPEXT, s64}, Legal); 340327952Sdim setAction({G_FPEXT, 1, s32}, Legal); 341327952Sdim 342344779Sdim setAction({G_FPTRUNC, s32}, Legal); 343344779Sdim setAction({G_FPTRUNC, 1, s64}, Legal); 344344779Sdim 345327952Sdim // Constants 346327952Sdim setAction({TargetOpcode::G_FCONSTANT, s64}, Legal); 347327952Sdim 348327952Sdim // Merge/Unmerge 349327952Sdim for (const auto &Ty : 350327952Sdim {v16s8, v32s8, v8s16, v16s16, v4s32, v8s32, v2s64, v4s64}) { 351344779Sdim setAction({G_CONCAT_VECTORS, Ty}, Legal); 352327952Sdim setAction({G_UNMERGE_VALUES, 1, Ty}, Legal); 353327952Sdim } 354327952Sdim for (const auto &Ty : {v16s8, v8s16, v4s32, v2s64}) { 355344779Sdim setAction({G_CONCAT_VECTORS, 1, Ty}, Legal); 356327952Sdim setAction({G_UNMERGE_VALUES, Ty}, Legal); 357327952Sdim } 358317017Sdim} 359317969Sdim 360317969Sdimvoid X86LegalizerInfo::setLegalizerInfoSSE41() { 361317969Sdim if (!Subtarget.hasSSE41()) 362317969Sdim return; 363317969Sdim 364317969Sdim const LLT v4s32 = LLT::vector(4, 32); 365317969Sdim 366317969Sdim setAction({G_MUL, v4s32}, Legal); 367317969Sdim} 368317969Sdim 369319164Sdimvoid X86LegalizerInfo::setLegalizerInfoAVX() { 370319164Sdim if (!Subtarget.hasAVX()) 371319164Sdim return; 372319164Sdim 373320397Sdim const LLT v16s8 = LLT::vector(16, 8); 374320397Sdim const LLT v8s16 = LLT::vector(8, 16); 375320397Sdim const LLT v4s32 = LLT::vector(4, 32); 376320397Sdim const LLT v2s64 = LLT::vector(2, 64); 377320397Sdim 378320397Sdim const LLT v32s8 = LLT::vector(32, 8); 379327952Sdim const LLT v64s8 = LLT::vector(64, 8); 380320397Sdim const LLT v16s16 = LLT::vector(16, 16); 381327952Sdim const LLT v32s16 = LLT::vector(32, 16); 382319164Sdim const LLT v8s32 = LLT::vector(8, 32); 383327952Sdim const LLT v16s32 = LLT::vector(16, 32); 384319164Sdim const LLT v4s64 = LLT::vector(4, 64); 385327952Sdim const LLT v8s64 = LLT::vector(8, 64); 386319164Sdim 387319164Sdim for (unsigned MemOp : {G_LOAD, G_STORE}) 388319164Sdim for (auto Ty : {v8s32, v4s64}) 389319164Sdim setAction({MemOp, Ty}, Legal); 390320397Sdim 391320572Sdim for (auto Ty : {v32s8, v16s16, v8s32, v4s64}) { 392320397Sdim setAction({G_INSERT, Ty}, Legal); 393320572Sdim setAction({G_EXTRACT, 1, Ty}, Legal); 394320572Sdim } 395320572Sdim for (auto Ty : {v16s8, v8s16, v4s32, v2s64}) { 396320397Sdim setAction({G_INSERT, 1, Ty}, Legal); 397320572Sdim setAction({G_EXTRACT, Ty}, Legal); 398320572Sdim } 399327952Sdim // Merge/Unmerge 400327952Sdim for (const auto &Ty : 401327952Sdim {v32s8, v64s8, v16s16, v32s16, v8s32, v16s32, v4s64, v8s64}) { 402344779Sdim setAction({G_CONCAT_VECTORS, Ty}, Legal); 403327952Sdim setAction({G_UNMERGE_VALUES, 1, Ty}, Legal); 404327952Sdim } 405327952Sdim for (const auto &Ty : 406327952Sdim {v16s8, v32s8, v8s16, v16s16, v4s32, v8s32, v2s64, v4s64}) { 407344779Sdim setAction({G_CONCAT_VECTORS, 1, Ty}, Legal); 408327952Sdim setAction({G_UNMERGE_VALUES, Ty}, Legal); 409327952Sdim } 410319164Sdim} 411319164Sdim 412317969Sdimvoid X86LegalizerInfo::setLegalizerInfoAVX2() { 413317969Sdim if (!Subtarget.hasAVX2()) 414317969Sdim return; 415317969Sdim 416318681Sdim const LLT v32s8 = LLT::vector(32, 8); 417317969Sdim const LLT v16s16 = LLT::vector(16, 16); 418317969Sdim const LLT v8s32 = LLT::vector(8, 32); 419318681Sdim const LLT v4s64 = LLT::vector(4, 64); 420317969Sdim 421327952Sdim const LLT v64s8 = LLT::vector(64, 8); 422327952Sdim const LLT v32s16 = LLT::vector(32, 16); 423327952Sdim const LLT v16s32 = LLT::vector(16, 32); 424327952Sdim const LLT v8s64 = LLT::vector(8, 64); 425327952Sdim 426318681Sdim for (unsigned BinOp : {G_ADD, G_SUB}) 427318681Sdim for (auto Ty : {v32s8, v16s16, v8s32, v4s64}) 428318681Sdim setAction({BinOp, Ty}, Legal); 429318681Sdim 430317969Sdim for (auto Ty : {v16s16, v8s32}) 431317969Sdim setAction({G_MUL, Ty}, Legal); 432327952Sdim 433327952Sdim // Merge/Unmerge 434327952Sdim for (const auto &Ty : {v64s8, v32s16, v16s32, v8s64}) { 435344779Sdim setAction({G_CONCAT_VECTORS, Ty}, Legal); 436327952Sdim setAction({G_UNMERGE_VALUES, 1, Ty}, Legal); 437327952Sdim } 438327952Sdim for (const auto &Ty : {v32s8, v16s16, v8s32, v4s64}) { 439344779Sdim setAction({G_CONCAT_VECTORS, 1, Ty}, Legal); 440327952Sdim setAction({G_UNMERGE_VALUES, Ty}, Legal); 441327952Sdim } 442317969Sdim} 443317969Sdim 444317969Sdimvoid X86LegalizerInfo::setLegalizerInfoAVX512() { 445317969Sdim if (!Subtarget.hasAVX512()) 446317969Sdim return; 447317969Sdim 448320397Sdim const LLT v16s8 = LLT::vector(16, 8); 449320397Sdim const LLT v8s16 = LLT::vector(8, 16); 450320397Sdim const LLT v4s32 = LLT::vector(4, 32); 451320397Sdim const LLT v2s64 = LLT::vector(2, 64); 452320397Sdim 453320397Sdim const LLT v32s8 = LLT::vector(32, 8); 454320397Sdim const LLT v16s16 = LLT::vector(16, 16); 455320397Sdim const LLT v8s32 = LLT::vector(8, 32); 456320397Sdim const LLT v4s64 = LLT::vector(4, 64); 457320397Sdim 458320397Sdim const LLT v64s8 = LLT::vector(64, 8); 459320397Sdim const LLT v32s16 = LLT::vector(32, 16); 460317969Sdim const LLT v16s32 = LLT::vector(16, 32); 461318681Sdim const LLT v8s64 = LLT::vector(8, 64); 462317969Sdim 463318681Sdim for (unsigned BinOp : {G_ADD, G_SUB}) 464318681Sdim for (auto Ty : {v16s32, v8s64}) 465318681Sdim setAction({BinOp, Ty}, Legal); 466318681Sdim 467317969Sdim setAction({G_MUL, v16s32}, Legal); 468317969Sdim 469319164Sdim for (unsigned MemOp : {G_LOAD, G_STORE}) 470319164Sdim for (auto Ty : {v16s32, v8s64}) 471319164Sdim setAction({MemOp, Ty}, Legal); 472319164Sdim 473320572Sdim for (auto Ty : {v64s8, v32s16, v16s32, v8s64}) { 474320397Sdim setAction({G_INSERT, Ty}, Legal); 475320572Sdim setAction({G_EXTRACT, 1, Ty}, Legal); 476320572Sdim } 477320572Sdim for (auto Ty : {v32s8, v16s16, v8s32, v4s64, v16s8, v8s16, v4s32, v2s64}) { 478320397Sdim setAction({G_INSERT, 1, Ty}, Legal); 479320572Sdim setAction({G_EXTRACT, Ty}, Legal); 480320572Sdim } 481320397Sdim 482317969Sdim /************ VLX *******************/ 483317969Sdim if (!Subtarget.hasVLX()) 484317969Sdim return; 485317969Sdim 486317969Sdim for (auto Ty : {v4s32, v8s32}) 487317969Sdim setAction({G_MUL, Ty}, Legal); 488317969Sdim} 489317969Sdim 490317969Sdimvoid X86LegalizerInfo::setLegalizerInfoAVX512DQ() { 491317969Sdim if (!(Subtarget.hasAVX512() && Subtarget.hasDQI())) 492317969Sdim return; 493317969Sdim 494317969Sdim const LLT v8s64 = LLT::vector(8, 64); 495317969Sdim 496317969Sdim setAction({G_MUL, v8s64}, Legal); 497317969Sdim 498317969Sdim /************ VLX *******************/ 499317969Sdim if (!Subtarget.hasVLX()) 500317969Sdim return; 501317969Sdim 502317969Sdim const LLT v2s64 = LLT::vector(2, 64); 503317969Sdim const LLT v4s64 = LLT::vector(4, 64); 504317969Sdim 505317969Sdim for (auto Ty : {v2s64, v4s64}) 506317969Sdim setAction({G_MUL, Ty}, Legal); 507317969Sdim} 508317969Sdim 509317969Sdimvoid X86LegalizerInfo::setLegalizerInfoAVX512BW() { 510317969Sdim if (!(Subtarget.hasAVX512() && Subtarget.hasBWI())) 511317969Sdim return; 512317969Sdim 513318681Sdim const LLT v64s8 = LLT::vector(64, 8); 514317969Sdim const LLT v32s16 = LLT::vector(32, 16); 515317969Sdim 516318681Sdim for (unsigned BinOp : {G_ADD, G_SUB}) 517318681Sdim for (auto Ty : {v64s8, v32s16}) 518318681Sdim setAction({BinOp, Ty}, Legal); 519318681Sdim 520317969Sdim setAction({G_MUL, v32s16}, Legal); 521317969Sdim 522317969Sdim /************ VLX *******************/ 523317969Sdim if (!Subtarget.hasVLX()) 524317969Sdim return; 525317969Sdim 526317969Sdim const LLT v8s16 = LLT::vector(8, 16); 527317969Sdim const LLT v16s16 = LLT::vector(16, 16); 528317969Sdim 529317969Sdim for (auto Ty : {v8s16, v16s16}) 530317969Sdim setAction({G_MUL, Ty}, Legal); 531317969Sdim} 532