X86LegalizerInfo.cpp 20 KB

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