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/ValueTypes.h" 18 #include "llvm/IR/DerivedTypes.h" 19 #include "llvm/IR/Type.h" 20 #include "llvm/Target/TargetOpcodes.h" 21 22 using namespace llvm; 23 using namespace TargetOpcode; 24 25 #ifndef LLVM_BUILD_GLOBAL_ISEL 26 #error "You shouldn't build this" 27 #endif 28 29 X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI, 30 const X86TargetMachine &TM) 31 : Subtarget(STI), TM(TM) { 32 33 setLegalizerInfo32bit(); 34 setLegalizerInfo64bit(); 35 setLegalizerInfoSSE1(); 36 setLegalizerInfoSSE2(); 37 setLegalizerInfoSSE41(); 38 setLegalizerInfoAVX(); 39 setLegalizerInfoAVX2(); 40 setLegalizerInfoAVX512(); 41 setLegalizerInfoAVX512DQ(); 42 setLegalizerInfoAVX512BW(); 43 44 computeTables(); 45 } 46 47 void X86LegalizerInfo::setLegalizerInfo32bit() { 48 49 if (Subtarget.is64Bit()) 50 return; 51 52 const LLT p0 = LLT::pointer(0, 32); 53 const LLT s1 = LLT::scalar(1); 54 const LLT s8 = LLT::scalar(8); 55 const LLT s16 = LLT::scalar(16); 56 const LLT s32 = LLT::scalar(32); 57 const LLT s64 = LLT::scalar(64); 58 59 for (unsigned BinOp : {G_ADD, G_SUB, G_MUL, G_AND, G_OR, G_XOR}) 60 for (auto Ty : {s8, s16, s32}) 61 setAction({BinOp, Ty}, Legal); 62 63 for (unsigned Op : {G_UADDE}) { 64 setAction({Op, s32}, Legal); 65 setAction({Op, 1, s1}, Legal); 66 } 67 68 for (unsigned MemOp : {G_LOAD, G_STORE}) { 69 for (auto Ty : {s8, s16, s32, p0}) 70 setAction({MemOp, Ty}, Legal); 71 72 setAction({MemOp, s1}, WidenScalar); 73 // And everything's fine in addrspace 0. 74 setAction({MemOp, 1, p0}, Legal); 75 } 76 77 // Pointer-handling 78 setAction({G_FRAME_INDEX, p0}, Legal); 79 setAction({G_GLOBAL_VALUE, p0}, Legal); 80 81 setAction({G_GEP, p0}, Legal); 82 setAction({G_GEP, 1, s32}, Legal); 83 84 for (auto Ty : {s1, s8, s16}) 85 setAction({G_GEP, 1, Ty}, WidenScalar); 86 87 // Constants 88 for (auto Ty : {s8, s16, s32, p0}) 89 setAction({TargetOpcode::G_CONSTANT, Ty}, Legal); 90 91 setAction({TargetOpcode::G_CONSTANT, s1}, WidenScalar); 92 setAction({TargetOpcode::G_CONSTANT, s64}, NarrowScalar); 93 94 // Extensions 95 for (auto Ty : {s8, s16, s32}) { 96 setAction({G_ZEXT, Ty}, Legal); 97 setAction({G_SEXT, Ty}, Legal); 98 } 99 100 for (auto Ty : {s1, s8, s16}) { 101 setAction({G_ZEXT, 1, Ty}, Legal); 102 setAction({G_SEXT, 1, Ty}, Legal); 103 } 104 105 // Comparison 106 setAction({G_ICMP, s1}, Legal); 107 108 for (auto Ty : {s8, s16, s32, p0}) 109 setAction({G_ICMP, 1, Ty}, Legal); 110 } 111 112 void X86LegalizerInfo::setLegalizerInfo64bit() { 113 114 if (!Subtarget.is64Bit()) 115 return; 116 117 const LLT p0 = LLT::pointer(0, TM.getPointerSize() * 8); 118 const LLT s1 = LLT::scalar(1); 119 const LLT s8 = LLT::scalar(8); 120 const LLT s16 = LLT::scalar(16); 121 const LLT s32 = LLT::scalar(32); 122 const LLT s64 = LLT::scalar(64); 123 124 for (unsigned BinOp : {G_ADD, G_SUB, G_MUL, G_AND, G_OR, G_XOR}) 125 for (auto Ty : {s8, s16, s32, s64}) 126 setAction({BinOp, Ty}, Legal); 127 128 for (unsigned MemOp : {G_LOAD, G_STORE}) { 129 for (auto Ty : {s8, s16, s32, s64, p0}) 130 setAction({MemOp, Ty}, Legal); 131 132 setAction({MemOp, s1}, WidenScalar); 133 // And everything's fine in addrspace 0. 134 setAction({MemOp, 1, p0}, Legal); 135 } 136 137 // Pointer-handling 138 setAction({G_FRAME_INDEX, p0}, Legal); 139 setAction({G_GLOBAL_VALUE, p0}, Legal); 140 141 setAction({G_GEP, p0}, Legal); 142 setAction({G_GEP, 1, s32}, Legal); 143 setAction({G_GEP, 1, s64}, Legal); 144 145 for (auto Ty : {s1, s8, s16}) 146 setAction({G_GEP, 1, Ty}, WidenScalar); 147 148 // Constants 149 for (auto Ty : {s8, s16, s32, s64, p0}) 150 setAction({TargetOpcode::G_CONSTANT, Ty}, Legal); 151 152 setAction({TargetOpcode::G_CONSTANT, s1}, WidenScalar); 153 154 // Extensions 155 for (auto Ty : {s8, s16, s32, s64}) { 156 setAction({G_ZEXT, Ty}, Legal); 157 setAction({G_SEXT, Ty}, Legal); 158 } 159 160 for (auto Ty : {s1, s8, s16, s32}) { 161 setAction({G_ZEXT, 1, Ty}, Legal); 162 setAction({G_SEXT, 1, Ty}, Legal); 163 } 164 165 // Comparison 166 setAction({G_ICMP, s1}, Legal); 167 168 for (auto Ty : {s8, s16, s32, s64, p0}) 169 setAction({G_ICMP, 1, Ty}, Legal); 170 } 171 172 void X86LegalizerInfo::setLegalizerInfoSSE1() { 173 if (!Subtarget.hasSSE1()) 174 return; 175 176 const LLT s32 = LLT::scalar(32); 177 const LLT v4s32 = LLT::vector(4, 32); 178 const LLT v2s64 = LLT::vector(2, 64); 179 180 for (unsigned BinOp : {G_FADD, G_FSUB, G_FMUL, G_FDIV}) 181 for (auto Ty : {s32, v4s32}) 182 setAction({BinOp, Ty}, Legal); 183 184 for (unsigned MemOp : {G_LOAD, G_STORE}) 185 for (auto Ty : {v4s32, v2s64}) 186 setAction({MemOp, Ty}, Legal); 187 } 188 189 void X86LegalizerInfo::setLegalizerInfoSSE2() { 190 if (!Subtarget.hasSSE2()) 191 return; 192 193 const LLT s64 = LLT::scalar(64); 194 const LLT v16s8 = LLT::vector(16, 8); 195 const LLT v8s16 = LLT::vector(8, 16); 196 const LLT v4s32 = LLT::vector(4, 32); 197 const LLT v2s64 = LLT::vector(2, 64); 198 199 for (unsigned BinOp : {G_FADD, G_FSUB, G_FMUL, G_FDIV}) 200 for (auto Ty : {s64, v2s64}) 201 setAction({BinOp, Ty}, Legal); 202 203 for (unsigned BinOp : {G_ADD, G_SUB}) 204 for (auto Ty : {v16s8, v8s16, v4s32, v2s64}) 205 setAction({BinOp, Ty}, Legal); 206 207 setAction({G_MUL, v8s16}, Legal); 208 } 209 210 void X86LegalizerInfo::setLegalizerInfoSSE41() { 211 if (!Subtarget.hasSSE41()) 212 return; 213 214 const LLT v4s32 = LLT::vector(4, 32); 215 216 setAction({G_MUL, v4s32}, Legal); 217 } 218 219 void X86LegalizerInfo::setLegalizerInfoAVX() { 220 if (!Subtarget.hasAVX()) 221 return; 222 223 const LLT v16s8 = LLT::vector(16, 8); 224 const LLT v8s16 = LLT::vector(8, 16); 225 const LLT v4s32 = LLT::vector(4, 32); 226 const LLT v2s64 = LLT::vector(2, 64); 227 228 const LLT v32s8 = LLT::vector(32, 8); 229 const LLT v16s16 = LLT::vector(16, 16); 230 const LLT v8s32 = LLT::vector(8, 32); 231 const LLT v4s64 = LLT::vector(4, 64); 232 233 for (unsigned MemOp : {G_LOAD, G_STORE}) 234 for (auto Ty : {v8s32, v4s64}) 235 setAction({MemOp, Ty}, Legal); 236 237 for (auto Ty : {v32s8, v16s16, v8s32, v4s64}) { 238 setAction({G_INSERT, Ty}, Legal); 239 setAction({G_EXTRACT, 1, Ty}, Legal); 240 } 241 for (auto Ty : {v16s8, v8s16, v4s32, v2s64}) { 242 setAction({G_INSERT, 1, Ty}, Legal); 243 setAction({G_EXTRACT, Ty}, Legal); 244 } 245 } 246 247 void X86LegalizerInfo::setLegalizerInfoAVX2() { 248 if (!Subtarget.hasAVX2()) 249 return; 250 251 const LLT v32s8 = LLT::vector(32, 8); 252 const LLT v16s16 = LLT::vector(16, 16); 253 const LLT v8s32 = LLT::vector(8, 32); 254 const LLT v4s64 = LLT::vector(4, 64); 255 256 for (unsigned BinOp : {G_ADD, G_SUB}) 257 for (auto Ty : {v32s8, v16s16, v8s32, v4s64}) 258 setAction({BinOp, Ty}, Legal); 259 260 for (auto Ty : {v16s16, v8s32}) 261 setAction({G_MUL, Ty}, Legal); 262 } 263 264 void X86LegalizerInfo::setLegalizerInfoAVX512() { 265 if (!Subtarget.hasAVX512()) 266 return; 267 268 const LLT v16s8 = LLT::vector(16, 8); 269 const LLT v8s16 = LLT::vector(8, 16); 270 const LLT v4s32 = LLT::vector(4, 32); 271 const LLT v2s64 = LLT::vector(2, 64); 272 273 const LLT v32s8 = LLT::vector(32, 8); 274 const LLT v16s16 = LLT::vector(16, 16); 275 const LLT v8s32 = LLT::vector(8, 32); 276 const LLT v4s64 = LLT::vector(4, 64); 277 278 const LLT v64s8 = LLT::vector(64, 8); 279 const LLT v32s16 = LLT::vector(32, 16); 280 const LLT v16s32 = LLT::vector(16, 32); 281 const LLT v8s64 = LLT::vector(8, 64); 282 283 for (unsigned BinOp : {G_ADD, G_SUB}) 284 for (auto Ty : {v16s32, v8s64}) 285 setAction({BinOp, Ty}, Legal); 286 287 setAction({G_MUL, v16s32}, Legal); 288 289 for (unsigned MemOp : {G_LOAD, G_STORE}) 290 for (auto Ty : {v16s32, v8s64}) 291 setAction({MemOp, Ty}, Legal); 292 293 for (auto Ty : {v64s8, v32s16, v16s32, v8s64}) { 294 setAction({G_INSERT, Ty}, Legal); 295 setAction({G_EXTRACT, 1, Ty}, Legal); 296 } 297 for (auto Ty : {v32s8, v16s16, v8s32, v4s64, v16s8, v8s16, v4s32, v2s64}) { 298 setAction({G_INSERT, 1, Ty}, Legal); 299 setAction({G_EXTRACT, Ty}, Legal); 300 } 301 302 /************ VLX *******************/ 303 if (!Subtarget.hasVLX()) 304 return; 305 306 for (auto Ty : {v4s32, v8s32}) 307 setAction({G_MUL, Ty}, Legal); 308 } 309 310 void X86LegalizerInfo::setLegalizerInfoAVX512DQ() { 311 if (!(Subtarget.hasAVX512() && Subtarget.hasDQI())) 312 return; 313 314 const LLT v8s64 = LLT::vector(8, 64); 315 316 setAction({G_MUL, v8s64}, Legal); 317 318 /************ VLX *******************/ 319 if (!Subtarget.hasVLX()) 320 return; 321 322 const LLT v2s64 = LLT::vector(2, 64); 323 const LLT v4s64 = LLT::vector(4, 64); 324 325 for (auto Ty : {v2s64, v4s64}) 326 setAction({G_MUL, Ty}, Legal); 327 } 328 329 void X86LegalizerInfo::setLegalizerInfoAVX512BW() { 330 if (!(Subtarget.hasAVX512() && Subtarget.hasBWI())) 331 return; 332 333 const LLT v64s8 = LLT::vector(64, 8); 334 const LLT v32s16 = LLT::vector(32, 16); 335 336 for (unsigned BinOp : {G_ADD, G_SUB}) 337 for (auto Ty : {v64s8, v32s16}) 338 setAction({BinOp, Ty}, Legal); 339 340 setAction({G_MUL, v32s16}, Legal); 341 342 /************ VLX *******************/ 343 if (!Subtarget.hasVLX()) 344 return; 345 346 const LLT v8s16 = LLT::vector(8, 16); 347 const LLT v16s16 = LLT::vector(16, 16); 348 349 for (auto Ty : {v8s16, v16s16}) 350 setAction({G_MUL, Ty}, Legal); 351 } 352