X86LegalizerInfo.cpp revision 327952
1//===- X86LegalizerInfo.cpp --------------------------------------*- C++ -*-==// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9/// \file 10/// This file implements the targeting of the Machinelegalizer class for X86. 11/// \todo This should be generated by TableGen. 12//===----------------------------------------------------------------------===// 13 14#include "X86LegalizerInfo.h" 15#include "X86Subtarget.h" 16#include "X86TargetMachine.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; 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, LegalizerInfo::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, LegalizerInfo::WidenScalar}, 50 {2, LegalizerInfo::Unsupported}}; 51 addAndInterleaveWithUnsupported(result, v); 52 auto Largest = result.back().first; 53 result.push_back({Largest + 1, LegalizerInfo::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} 85 86void X86LegalizerInfo::setLegalizerInfo32bit() { 87 88 const LLT p0 = LLT::pointer(0, TM.getPointerSize() * 8); 89 const LLT s1 = LLT::scalar(1); 90 const LLT s8 = LLT::scalar(8); 91 const LLT s16 = LLT::scalar(16); 92 const LLT s32 = LLT::scalar(32); 93 const LLT s64 = LLT::scalar(64); 94 95 for (auto Ty : {p0, s1, s8, s16, s32}) 96 setAction({G_IMPLICIT_DEF, Ty}, Legal); 97 98 for (auto Ty : {s8, s16, s32, p0}) 99 setAction({G_PHI, Ty}, Legal); 100 101 for (unsigned BinOp : {G_ADD, G_SUB, G_MUL, G_AND, G_OR, G_XOR}) 102 for (auto Ty : {s8, s16, s32}) 103 setAction({BinOp, Ty}, Legal); 104 105 for (unsigned Op : {G_UADDE}) { 106 setAction({Op, s32}, Legal); 107 setAction({Op, 1, s1}, Legal); 108 } 109 110 for (unsigned MemOp : {G_LOAD, G_STORE}) { 111 for (auto Ty : {s8, s16, s32, p0}) 112 setAction({MemOp, Ty}, Legal); 113 114 // And everything's fine in addrspace 0. 115 setAction({MemOp, 1, p0}, Legal); 116 } 117 118 // Pointer-handling 119 setAction({G_FRAME_INDEX, p0}, Legal); 120 setAction({G_GLOBAL_VALUE, p0}, Legal); 121 122 setAction({G_GEP, p0}, Legal); 123 setAction({G_GEP, 1, s32}, Legal); 124 125 // Control-flow 126 setAction({G_BRCOND, s1}, Legal); 127 128 // Constants 129 for (auto Ty : {s8, s16, s32, p0}) 130 setAction({TargetOpcode::G_CONSTANT, Ty}, Legal); 131 132 // Extensions 133 for (auto Ty : {s8, s16, s32}) { 134 setAction({G_ZEXT, Ty}, Legal); 135 setAction({G_SEXT, Ty}, Legal); 136 setAction({G_ANYEXT, Ty}, Legal); 137 } 138 139 // Comparison 140 setAction({G_ICMP, s1}, Legal); 141 142 for (auto Ty : {s8, s16, s32, p0}) 143 setAction({G_ICMP, 1, Ty}, Legal); 144 145 // Merge/Unmerge 146 for (const auto &Ty : {s16, s32, s64}) { 147 setAction({G_MERGE_VALUES, Ty}, Legal); 148 setAction({G_UNMERGE_VALUES, 1, Ty}, Legal); 149 } 150 for (const auto &Ty : {s8, s16, s32}) { 151 setAction({G_MERGE_VALUES, 1, Ty}, Legal); 152 setAction({G_UNMERGE_VALUES, Ty}, Legal); 153 } 154} 155 156void X86LegalizerInfo::setLegalizerInfo64bit() { 157 158 if (!Subtarget.is64Bit()) 159 return; 160 161 const LLT s64 = LLT::scalar(64); 162 const LLT s128 = LLT::scalar(128); 163 164 setAction({G_IMPLICIT_DEF, s64}, Legal); 165 166 setAction({G_PHI, s64}, Legal); 167 168 for (unsigned BinOp : {G_ADD, G_SUB, G_MUL, G_AND, G_OR, G_XOR}) 169 setAction({BinOp, s64}, Legal); 170 171 for (unsigned MemOp : {G_LOAD, G_STORE}) 172 setAction({MemOp, s64}, Legal); 173 174 // Pointer-handling 175 setAction({G_GEP, 1, s64}, Legal); 176 177 // Constants 178 setAction({TargetOpcode::G_CONSTANT, s64}, Legal); 179 180 // Extensions 181 for (unsigned extOp : {G_ZEXT, G_SEXT, G_ANYEXT}) { 182 setAction({extOp, s64}, Legal); 183 } 184 185 // Comparison 186 setAction({G_ICMP, 1, s64}, Legal); 187 188 // Merge/Unmerge 189 setAction({G_MERGE_VALUES, s128}, Legal); 190 setAction({G_UNMERGE_VALUES, 1, s128}, Legal); 191 setAction({G_MERGE_VALUES, 1, s128}, Legal); 192 setAction({G_UNMERGE_VALUES, s128}, Legal); 193} 194 195void X86LegalizerInfo::setLegalizerInfoSSE1() { 196 if (!Subtarget.hasSSE1()) 197 return; 198 199 const LLT s32 = LLT::scalar(32); 200 const LLT s64 = LLT::scalar(64); 201 const LLT v4s32 = LLT::vector(4, 32); 202 const LLT v2s64 = LLT::vector(2, 64); 203 204 for (unsigned BinOp : {G_FADD, G_FSUB, G_FMUL, G_FDIV}) 205 for (auto Ty : {s32, v4s32}) 206 setAction({BinOp, Ty}, Legal); 207 208 for (unsigned MemOp : {G_LOAD, G_STORE}) 209 for (auto Ty : {v4s32, v2s64}) 210 setAction({MemOp, Ty}, Legal); 211 212 // Constants 213 setAction({TargetOpcode::G_FCONSTANT, s32}, Legal); 214 215 // Merge/Unmerge 216 for (const auto &Ty : {v4s32, v2s64}) { 217 setAction({G_MERGE_VALUES, Ty}, Legal); 218 setAction({G_UNMERGE_VALUES, 1, Ty}, Legal); 219 } 220 setAction({G_MERGE_VALUES, 1, s64}, Legal); 221 setAction({G_UNMERGE_VALUES, s64}, Legal); 222} 223 224void X86LegalizerInfo::setLegalizerInfoSSE2() { 225 if (!Subtarget.hasSSE2()) 226 return; 227 228 const LLT s32 = LLT::scalar(32); 229 const LLT s64 = LLT::scalar(64); 230 const LLT v16s8 = LLT::vector(16, 8); 231 const LLT v8s16 = LLT::vector(8, 16); 232 const LLT v4s32 = LLT::vector(4, 32); 233 const LLT v2s64 = LLT::vector(2, 64); 234 235 const LLT v32s8 = LLT::vector(32, 8); 236 const LLT v16s16 = LLT::vector(16, 16); 237 const LLT v8s32 = LLT::vector(8, 32); 238 const LLT v4s64 = LLT::vector(4, 64); 239 240 for (unsigned BinOp : {G_FADD, G_FSUB, G_FMUL, G_FDIV}) 241 for (auto Ty : {s64, v2s64}) 242 setAction({BinOp, Ty}, Legal); 243 244 for (unsigned BinOp : {G_ADD, G_SUB}) 245 for (auto Ty : {v16s8, v8s16, v4s32, v2s64}) 246 setAction({BinOp, Ty}, Legal); 247 248 setAction({G_MUL, v8s16}, Legal); 249 250 setAction({G_FPEXT, s64}, Legal); 251 setAction({G_FPEXT, 1, s32}, Legal); 252 253 // Constants 254 setAction({TargetOpcode::G_FCONSTANT, s64}, Legal); 255 256 // Merge/Unmerge 257 for (const auto &Ty : 258 {v16s8, v32s8, v8s16, v16s16, v4s32, v8s32, v2s64, v4s64}) { 259 setAction({G_MERGE_VALUES, Ty}, Legal); 260 setAction({G_UNMERGE_VALUES, 1, Ty}, Legal); 261 } 262 for (const auto &Ty : {v16s8, v8s16, v4s32, v2s64}) { 263 setAction({G_MERGE_VALUES, 1, Ty}, Legal); 264 setAction({G_UNMERGE_VALUES, Ty}, Legal); 265 } 266} 267 268void X86LegalizerInfo::setLegalizerInfoSSE41() { 269 if (!Subtarget.hasSSE41()) 270 return; 271 272 const LLT v4s32 = LLT::vector(4, 32); 273 274 setAction({G_MUL, v4s32}, Legal); 275} 276 277void X86LegalizerInfo::setLegalizerInfoAVX() { 278 if (!Subtarget.hasAVX()) 279 return; 280 281 const LLT v16s8 = LLT::vector(16, 8); 282 const LLT v8s16 = LLT::vector(8, 16); 283 const LLT v4s32 = LLT::vector(4, 32); 284 const LLT v2s64 = LLT::vector(2, 64); 285 286 const LLT v32s8 = LLT::vector(32, 8); 287 const LLT v64s8 = LLT::vector(64, 8); 288 const LLT v16s16 = LLT::vector(16, 16); 289 const LLT v32s16 = LLT::vector(32, 16); 290 const LLT v8s32 = LLT::vector(8, 32); 291 const LLT v16s32 = LLT::vector(16, 32); 292 const LLT v4s64 = LLT::vector(4, 64); 293 const LLT v8s64 = LLT::vector(8, 64); 294 295 for (unsigned MemOp : {G_LOAD, G_STORE}) 296 for (auto Ty : {v8s32, v4s64}) 297 setAction({MemOp, Ty}, Legal); 298 299 for (auto Ty : {v32s8, v16s16, v8s32, v4s64}) { 300 setAction({G_INSERT, Ty}, Legal); 301 setAction({G_EXTRACT, 1, Ty}, Legal); 302 } 303 for (auto Ty : {v16s8, v8s16, v4s32, v2s64}) { 304 setAction({G_INSERT, 1, Ty}, Legal); 305 setAction({G_EXTRACT, Ty}, Legal); 306 } 307 // Merge/Unmerge 308 for (const auto &Ty : 309 {v32s8, v64s8, v16s16, v32s16, v8s32, v16s32, v4s64, v8s64}) { 310 setAction({G_MERGE_VALUES, Ty}, Legal); 311 setAction({G_UNMERGE_VALUES, 1, Ty}, Legal); 312 } 313 for (const auto &Ty : 314 {v16s8, v32s8, v8s16, v16s16, v4s32, v8s32, v2s64, v4s64}) { 315 setAction({G_MERGE_VALUES, 1, Ty}, Legal); 316 setAction({G_UNMERGE_VALUES, Ty}, Legal); 317 } 318} 319 320void X86LegalizerInfo::setLegalizerInfoAVX2() { 321 if (!Subtarget.hasAVX2()) 322 return; 323 324 const LLT v32s8 = LLT::vector(32, 8); 325 const LLT v16s16 = LLT::vector(16, 16); 326 const LLT v8s32 = LLT::vector(8, 32); 327 const LLT v4s64 = LLT::vector(4, 64); 328 329 const LLT v64s8 = LLT::vector(64, 8); 330 const LLT v32s16 = LLT::vector(32, 16); 331 const LLT v16s32 = LLT::vector(16, 32); 332 const LLT v8s64 = LLT::vector(8, 64); 333 334 for (unsigned BinOp : {G_ADD, G_SUB}) 335 for (auto Ty : {v32s8, v16s16, v8s32, v4s64}) 336 setAction({BinOp, Ty}, Legal); 337 338 for (auto Ty : {v16s16, v8s32}) 339 setAction({G_MUL, Ty}, Legal); 340 341 // Merge/Unmerge 342 for (const auto &Ty : {v64s8, v32s16, v16s32, v8s64}) { 343 setAction({G_MERGE_VALUES, Ty}, Legal); 344 setAction({G_UNMERGE_VALUES, 1, Ty}, Legal); 345 } 346 for (const auto &Ty : {v32s8, v16s16, v8s32, v4s64}) { 347 setAction({G_MERGE_VALUES, 1, Ty}, Legal); 348 setAction({G_UNMERGE_VALUES, Ty}, Legal); 349 } 350} 351 352void X86LegalizerInfo::setLegalizerInfoAVX512() { 353 if (!Subtarget.hasAVX512()) 354 return; 355 356 const LLT v16s8 = LLT::vector(16, 8); 357 const LLT v8s16 = LLT::vector(8, 16); 358 const LLT v4s32 = LLT::vector(4, 32); 359 const LLT v2s64 = LLT::vector(2, 64); 360 361 const LLT v32s8 = LLT::vector(32, 8); 362 const LLT v16s16 = LLT::vector(16, 16); 363 const LLT v8s32 = LLT::vector(8, 32); 364 const LLT v4s64 = LLT::vector(4, 64); 365 366 const LLT v64s8 = LLT::vector(64, 8); 367 const LLT v32s16 = LLT::vector(32, 16); 368 const LLT v16s32 = LLT::vector(16, 32); 369 const LLT v8s64 = LLT::vector(8, 64); 370 371 for (unsigned BinOp : {G_ADD, G_SUB}) 372 for (auto Ty : {v16s32, v8s64}) 373 setAction({BinOp, Ty}, Legal); 374 375 setAction({G_MUL, v16s32}, Legal); 376 377 for (unsigned MemOp : {G_LOAD, G_STORE}) 378 for (auto Ty : {v16s32, v8s64}) 379 setAction({MemOp, Ty}, Legal); 380 381 for (auto Ty : {v64s8, v32s16, v16s32, v8s64}) { 382 setAction({G_INSERT, Ty}, Legal); 383 setAction({G_EXTRACT, 1, Ty}, Legal); 384 } 385 for (auto Ty : {v32s8, v16s16, v8s32, v4s64, v16s8, v8s16, v4s32, v2s64}) { 386 setAction({G_INSERT, 1, Ty}, Legal); 387 setAction({G_EXTRACT, Ty}, Legal); 388 } 389 390 /************ VLX *******************/ 391 if (!Subtarget.hasVLX()) 392 return; 393 394 for (auto Ty : {v4s32, v8s32}) 395 setAction({G_MUL, Ty}, Legal); 396} 397 398void X86LegalizerInfo::setLegalizerInfoAVX512DQ() { 399 if (!(Subtarget.hasAVX512() && Subtarget.hasDQI())) 400 return; 401 402 const LLT v8s64 = LLT::vector(8, 64); 403 404 setAction({G_MUL, v8s64}, Legal); 405 406 /************ VLX *******************/ 407 if (!Subtarget.hasVLX()) 408 return; 409 410 const LLT v2s64 = LLT::vector(2, 64); 411 const LLT v4s64 = LLT::vector(4, 64); 412 413 for (auto Ty : {v2s64, v4s64}) 414 setAction({G_MUL, Ty}, Legal); 415} 416 417void X86LegalizerInfo::setLegalizerInfoAVX512BW() { 418 if (!(Subtarget.hasAVX512() && Subtarget.hasBWI())) 419 return; 420 421 const LLT v64s8 = LLT::vector(64, 8); 422 const LLT v32s16 = LLT::vector(32, 16); 423 424 for (unsigned BinOp : {G_ADD, G_SUB}) 425 for (auto Ty : {v64s8, v32s16}) 426 setAction({BinOp, Ty}, Legal); 427 428 setAction({G_MUL, v32s16}, Legal); 429 430 /************ VLX *******************/ 431 if (!Subtarget.hasVLX()) 432 return; 433 434 const LLT v8s16 = LLT::vector(8, 16); 435 const LLT v16s16 = LLT::vector(16, 16); 436 437 for (auto Ty : {v8s16, v16s16}) 438 setAction({G_MUL, Ty}, Legal); 439} 440