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