xref: /llvm-project/llvm/unittests/CodeGen/GlobalISel/LegalizerInfoTest.cpp (revision 9faff9a09178eee3b79b669859df72d75de412c3)
169fa84a6STim Northover //===- llvm/unittest/CodeGen/GlobalISel/LegalizerInfoTest.cpp -------------===//
269fa84a6STim Northover //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
669fa84a6STim Northover //
769fa84a6STim Northover //===----------------------------------------------------------------------===//
869fa84a6STim Northover 
969fa84a6STim Northover #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
10b3bde2eaSDavid Blaikie #include "llvm/CodeGen/TargetOpcodes.h"
11b3e86709SMatt Arsenault #include "GISelMITest.h"
1269fa84a6STim Northover #include "gtest/gtest.h"
1369fa84a6STim Northover 
1469fa84a6STim Northover using namespace llvm;
159ade5592SDaniel Sanders using namespace LegalizeActions;
1650725982SMatt Arsenault using namespace LegalityPredicates;
1750725982SMatt Arsenault using namespace LegalizeMutations;
1869fa84a6STim Northover 
1969fa84a6STim Northover // Define a couple of pretty printers to help debugging when things go wrong.
2069fa84a6STim Northover namespace llvm {
2169fa84a6STim Northover std::ostream &
operator <<(std::ostream & OS,const LegalizeAction Act)229ade5592SDaniel Sanders operator<<(std::ostream &OS, const LegalizeAction Act) {
2369fa84a6STim Northover   switch (Act) {
249ade5592SDaniel Sanders   case Lower: OS << "Lower"; break;
259ade5592SDaniel Sanders   case Legal: OS << "Legal"; break;
269ade5592SDaniel Sanders   case NarrowScalar: OS << "NarrowScalar"; break;
279ade5592SDaniel Sanders   case WidenScalar:  OS << "WidenScalar"; break;
289ade5592SDaniel Sanders   case FewerElements:  OS << "FewerElements"; break;
299ade5592SDaniel Sanders   case MoreElements:  OS << "MoreElements"; break;
309ade5592SDaniel Sanders   case Libcall: OS << "Libcall"; break;
319ade5592SDaniel Sanders   case Custom: OS << "Custom"; break;
3239c55cefSMatt Arsenault   case Bitcast: OS << "Bitcast"; break;
339ade5592SDaniel Sanders   case Unsupported: OS << "Unsupported"; break;
34760e113aSDaniel Sanders   case NotFound: OS << "NotFound"; break;
3579cb839fSDaniel Sanders   case UseLegacyRules: OS << "UseLegacyRules"; break;
3669fa84a6STim Northover   }
3769fa84a6STim Northover   return OS;
3869fa84a6STim Northover }
3969fa84a6STim Northover 
operator <<(std::ostream & OS,const llvm::LegalizeActionStep Ty)4007238286SMatt Arsenault std::ostream &operator<<(std::ostream &OS, const llvm::LegalizeActionStep Ty) {
4107238286SMatt Arsenault   OS << "LegalizeActionStep(" << Ty.Action << ", " << Ty.TypeIdx << ", "
4207238286SMatt Arsenault      << Ty.NewType << ')';
4307238286SMatt Arsenault   return OS;
4407238286SMatt Arsenault }
4569fa84a6STim Northover }
4669fa84a6STim Northover 
4769fa84a6STim Northover namespace {
4869fa84a6STim Northover 
4969fa84a6STim Northover 
TEST(LegalizerInfoTest,ScalarRISC)5069fa84a6STim Northover TEST(LegalizerInfoTest, ScalarRISC) {
5169fa84a6STim Northover   using namespace TargetOpcode;
5269fa84a6STim Northover   LegalizerInfo L;
53aaac2682SDaniel Sanders   auto &LegacyInfo = L.getLegacyLegalizerInfo();
5469fa84a6STim Northover   // Typical RISCy set of operations based on AArch64.
55d5b7a00fSKristof Beyls   for (unsigned Op : {G_ADD, G_SUB}) {
56af9814a1SKristof Beyls     for (unsigned Size : {32, 64})
57aaac2682SDaniel Sanders       LegacyInfo.setAction({Op, 0, LLT::scalar(Size)},
58aaac2682SDaniel Sanders                            LegacyLegalizeActions::Legal);
59aaac2682SDaniel Sanders     LegacyInfo.setLegalizeScalarToDifferentSizeStrategy(
60aaac2682SDaniel Sanders         Op, 0, LegacyLegalizerInfo::widenToLargerTypesAndNarrowToLargest);
61af9814a1SKristof Beyls   }
62af9814a1SKristof Beyls 
63aaac2682SDaniel Sanders   LegacyInfo.computeTables();
6469fa84a6STim Northover 
65d5b7a00fSKristof Beyls   for (unsigned opcode : {G_ADD, G_SUB}) {
6669fa84a6STim Northover     // Check we infer the correct types and actually do what we're told.
67b3e86709SMatt Arsenault     EXPECT_EQ(L.getAction({opcode, {LLT::scalar(8)}}),
6879cb839fSDaniel Sanders               LegalizeActionStep(WidenScalar, 0, LLT::scalar(32)));
69b3e86709SMatt Arsenault     EXPECT_EQ(L.getAction({opcode, {LLT::scalar(16)}}),
7079cb839fSDaniel Sanders               LegalizeActionStep(WidenScalar, 0, LLT::scalar(32)));
71b3e86709SMatt Arsenault     EXPECT_EQ(L.getAction({opcode, {LLT::scalar(32)}}),
7279cb839fSDaniel Sanders               LegalizeActionStep(Legal, 0, LLT{}));
73b3e86709SMatt Arsenault     EXPECT_EQ(L.getAction({opcode, {LLT::scalar(64)}}),
7479cb839fSDaniel Sanders               LegalizeActionStep(Legal, 0, LLT{}));
7569fa84a6STim Northover 
7669fa84a6STim Northover     // Make sure the default for over-sized types applies.
77b3e86709SMatt Arsenault     EXPECT_EQ(L.getAction({opcode, {LLT::scalar(128)}}),
7879cb839fSDaniel Sanders               LegalizeActionStep(NarrowScalar, 0, LLT::scalar(64)));
79af9814a1SKristof Beyls     // Make sure we also handle unusual sizes
80b3e86709SMatt Arsenault     EXPECT_EQ(L.getAction({opcode, {LLT::scalar(1)}}),
8179cb839fSDaniel Sanders               LegalizeActionStep(WidenScalar, 0, LLT::scalar(32)));
82b3e86709SMatt Arsenault     EXPECT_EQ(L.getAction({opcode, {LLT::scalar(31)}}),
8379cb839fSDaniel Sanders               LegalizeActionStep(WidenScalar, 0, LLT::scalar(32)));
84b3e86709SMatt Arsenault     EXPECT_EQ(L.getAction({opcode, {LLT::scalar(33)}}),
8579cb839fSDaniel Sanders               LegalizeActionStep(WidenScalar, 0, LLT::scalar(64)));
86b3e86709SMatt Arsenault     EXPECT_EQ(L.getAction({opcode, {LLT::scalar(63)}}),
8779cb839fSDaniel Sanders               LegalizeActionStep(WidenScalar, 0, LLT::scalar(64)));
88b3e86709SMatt Arsenault     EXPECT_EQ(L.getAction({opcode, {LLT::scalar(65)}}),
8979cb839fSDaniel Sanders               LegalizeActionStep(NarrowScalar, 0, LLT::scalar(64)));
90af9814a1SKristof Beyls   }
9169fa84a6STim Northover }
9269fa84a6STim Northover 
TEST(LegalizerInfoTest,VectorRISC)9369fa84a6STim Northover TEST(LegalizerInfoTest, VectorRISC) {
9469fa84a6STim Northover   using namespace TargetOpcode;
9569fa84a6STim Northover   LegalizerInfo L;
96aaac2682SDaniel Sanders   auto &LegacyInfo = L.getLegacyLegalizerInfo();
9769fa84a6STim Northover   // Typical RISCy set of operations based on ARM.
98d5e14ba8SSander de Smalen   LegacyInfo.setAction({G_ADD, LLT::fixed_vector(8, 8)},
99aaac2682SDaniel Sanders                        LegacyLegalizeActions::Legal);
100d5e14ba8SSander de Smalen   LegacyInfo.setAction({G_ADD, LLT::fixed_vector(16, 8)},
101aaac2682SDaniel Sanders                        LegacyLegalizeActions::Legal);
102d5e14ba8SSander de Smalen   LegacyInfo.setAction({G_ADD, LLT::fixed_vector(4, 16)},
103aaac2682SDaniel Sanders                        LegacyLegalizeActions::Legal);
104d5e14ba8SSander de Smalen   LegacyInfo.setAction({G_ADD, LLT::fixed_vector(8, 16)},
105aaac2682SDaniel Sanders                        LegacyLegalizeActions::Legal);
106d5e14ba8SSander de Smalen   LegacyInfo.setAction({G_ADD, LLT::fixed_vector(2, 32)},
107aaac2682SDaniel Sanders                        LegacyLegalizeActions::Legal);
108d5e14ba8SSander de Smalen   LegacyInfo.setAction({G_ADD, LLT::fixed_vector(4, 32)},
109aaac2682SDaniel Sanders                        LegacyLegalizeActions::Legal);
110af9814a1SKristof Beyls 
111aaac2682SDaniel Sanders   LegacyInfo.setLegalizeVectorElementToDifferentSizeStrategy(
112aaac2682SDaniel Sanders       G_ADD, 0, LegacyLegalizerInfo::widenToLargerTypesUnsupportedOtherwise);
113af9814a1SKristof Beyls 
114aaac2682SDaniel Sanders   LegacyInfo.setAction({G_ADD, 0, LLT::scalar(32)},
115aaac2682SDaniel Sanders                        LegacyLegalizeActions::Legal);
116af9814a1SKristof Beyls 
117aaac2682SDaniel Sanders   LegacyInfo.computeTables();
11869fa84a6STim Northover 
11969fa84a6STim Northover   // Check we infer the correct types and actually do what we're told for some
12069fa84a6STim Northover   // simple cases.
121d5e14ba8SSander de Smalen   EXPECT_EQ(L.getAction({G_ADD, {LLT::fixed_vector(8, 8)}}),
12279cb839fSDaniel Sanders             LegalizeActionStep(Legal, 0, LLT{}));
123d5e14ba8SSander de Smalen   EXPECT_EQ(L.getAction({G_ADD, {LLT::fixed_vector(8, 7)}}),
124d5e14ba8SSander de Smalen             LegalizeActionStep(WidenScalar, 0, LLT::fixed_vector(8, 8)));
125d5e14ba8SSander de Smalen   EXPECT_EQ(L.getAction({G_ADD, {LLT::fixed_vector(2, 8)}}),
126d5e14ba8SSander de Smalen             LegalizeActionStep(MoreElements, 0, LLT::fixed_vector(8, 8)));
127d5e14ba8SSander de Smalen   EXPECT_EQ(L.getAction({G_ADD, {LLT::fixed_vector(8, 32)}}),
128d5e14ba8SSander de Smalen             LegalizeActionStep(FewerElements, 0, LLT::fixed_vector(4, 32)));
129af9814a1SKristof Beyls   // Check a few non-power-of-2 sizes:
130d5e14ba8SSander de Smalen   EXPECT_EQ(L.getAction({G_ADD, {LLT::fixed_vector(3, 3)}}),
131d5e14ba8SSander de Smalen             LegalizeActionStep(WidenScalar, 0, LLT::fixed_vector(3, 8)));
132d5e14ba8SSander de Smalen   EXPECT_EQ(L.getAction({G_ADD, {LLT::fixed_vector(3, 8)}}),
133d5e14ba8SSander de Smalen             LegalizeActionStep(MoreElements, 0, LLT::fixed_vector(8, 8)));
13469fa84a6STim Northover }
13569fa84a6STim Northover 
TEST(LegalizerInfoTest,MultipleTypes)13669fa84a6STim Northover TEST(LegalizerInfoTest, MultipleTypes) {
13769fa84a6STim Northover   using namespace TargetOpcode;
13869fa84a6STim Northover   LegalizerInfo L;
139aaac2682SDaniel Sanders   auto &LegacyInfo = L.getLegacyLegalizerInfo();
14069fa84a6STim Northover   LLT p0 = LLT::pointer(0, 64);
14169fa84a6STim Northover   LLT s64 = LLT::scalar(64);
14269fa84a6STim Northover 
14369fa84a6STim Northover   // Typical RISCy set of operations based on AArch64.
144aaac2682SDaniel Sanders   LegacyInfo.setAction({G_PTRTOINT, 0, s64}, LegacyLegalizeActions::Legal);
145aaac2682SDaniel Sanders   LegacyInfo.setAction({G_PTRTOINT, 1, p0}, LegacyLegalizeActions::Legal);
14669fa84a6STim Northover 
147aaac2682SDaniel Sanders   LegacyInfo.setLegalizeScalarToDifferentSizeStrategy(
148aaac2682SDaniel Sanders       G_PTRTOINT, 0, LegacyLegalizerInfo::widenToLargerTypesAndNarrowToLargest);
149af9814a1SKristof Beyls 
150aaac2682SDaniel Sanders   LegacyInfo.computeTables();
15169fa84a6STim Northover 
15269fa84a6STim Northover   // Check we infer the correct types and actually do what we're told.
153b3e86709SMatt Arsenault   EXPECT_EQ(L.getAction({G_PTRTOINT, {s64, p0}}),
15479cb839fSDaniel Sanders             LegalizeActionStep(Legal, 0, LLT{}));
155262ed0ecSDaniel Sanders 
156af9814a1SKristof Beyls   // Make sure we also handle unusual sizes
157b3e86709SMatt Arsenault   EXPECT_EQ(
158262ed0ecSDaniel Sanders       L.getAction({G_PTRTOINT, {LLT::scalar(65), s64}}),
15979cb839fSDaniel Sanders       LegalizeActionStep(NarrowScalar, 0, s64));
160b3e86709SMatt Arsenault   EXPECT_EQ(
1619ade5592SDaniel Sanders       L.getAction({G_PTRTOINT, {s64, LLT::pointer(0, 32)}}),
16279cb839fSDaniel Sanders       LegalizeActionStep(Unsupported, 1, LLT::pointer(0, 32)));
16369fa84a6STim Northover }
164b539ea53SKristof Beyls 
TEST(LegalizerInfoTest,MultipleSteps)165b539ea53SKristof Beyls TEST(LegalizerInfoTest, MultipleSteps) {
166b539ea53SKristof Beyls   using namespace TargetOpcode;
167b539ea53SKristof Beyls   LegalizerInfo L;
168aaac2682SDaniel Sanders   auto &LegacyInfo = L.getLegacyLegalizerInfo();
169b539ea53SKristof Beyls   LLT s32 = LLT::scalar(32);
170b539ea53SKristof Beyls   LLT s64 = LLT::scalar(64);
171b539ea53SKristof Beyls 
172aaac2682SDaniel Sanders   LegacyInfo.setLegalizeScalarToDifferentSizeStrategy(
173aaac2682SDaniel Sanders       G_UREM, 0, LegacyLegalizerInfo::widenToLargerTypesUnsupportedOtherwise);
174aaac2682SDaniel Sanders   LegacyInfo.setAction({G_UREM, 0, s32}, LegacyLegalizeActions::Lower);
175aaac2682SDaniel Sanders   LegacyInfo.setAction({G_UREM, 0, s64}, LegacyLegalizeActions::Lower);
176b539ea53SKristof Beyls 
177aaac2682SDaniel Sanders   LegacyInfo.computeTables();
178b539ea53SKristof Beyls 
179b3e86709SMatt Arsenault   EXPECT_EQ(L.getAction({G_UREM, {LLT::scalar(16)}}),
18079cb839fSDaniel Sanders             LegalizeActionStep(WidenScalar, 0, LLT::scalar(32)));
181b3e86709SMatt Arsenault   EXPECT_EQ(L.getAction({G_UREM, {LLT::scalar(32)}}),
18279cb839fSDaniel Sanders             LegalizeActionStep(Lower, 0, LLT::scalar(32)));
183b539ea53SKristof Beyls }
184af9814a1SKristof Beyls 
TEST(LegalizerInfoTest,SizeChangeStrategy)185af9814a1SKristof Beyls TEST(LegalizerInfoTest, SizeChangeStrategy) {
186af9814a1SKristof Beyls   using namespace TargetOpcode;
187af9814a1SKristof Beyls   LegalizerInfo L;
188aaac2682SDaniel Sanders   auto &LegacyInfo = L.getLegacyLegalizerInfo();
189af9814a1SKristof Beyls   for (unsigned Size : {1, 8, 16, 32})
190aaac2682SDaniel Sanders     LegacyInfo.setAction({G_UREM, 0, LLT::scalar(Size)},
191aaac2682SDaniel Sanders                          LegacyLegalizeActions::Legal);
192af9814a1SKristof Beyls 
193aaac2682SDaniel Sanders   LegacyInfo.setLegalizeScalarToDifferentSizeStrategy(
194aaac2682SDaniel Sanders       G_UREM, 0, LegacyLegalizerInfo::widenToLargerTypesUnsupportedOtherwise);
195aaac2682SDaniel Sanders   LegacyInfo.computeTables();
196af9814a1SKristof Beyls 
197af9814a1SKristof Beyls   // Check we infer the correct types and actually do what we're told.
198af9814a1SKristof Beyls   for (unsigned Size : {1, 8, 16, 32}) {
199b3e86709SMatt Arsenault     EXPECT_EQ(L.getAction({G_UREM, {LLT::scalar(Size)}}),
20079cb839fSDaniel Sanders               LegalizeActionStep(Legal, 0, LLT{}));
201af9814a1SKristof Beyls   }
202b3e86709SMatt Arsenault   EXPECT_EQ(L.getAction({G_UREM, {LLT::scalar(2)}}),
20379cb839fSDaniel Sanders             LegalizeActionStep(WidenScalar, 0, LLT::scalar(8)));
204b3e86709SMatt Arsenault   EXPECT_EQ(L.getAction({G_UREM, {LLT::scalar(7)}}),
20579cb839fSDaniel Sanders             LegalizeActionStep(WidenScalar, 0, LLT::scalar(8)));
206b3e86709SMatt Arsenault   EXPECT_EQ(L.getAction({G_UREM, {LLT::scalar(9)}}),
20779cb839fSDaniel Sanders             LegalizeActionStep(WidenScalar, 0, LLT::scalar(16)));
208b3e86709SMatt Arsenault   EXPECT_EQ(L.getAction({G_UREM, {LLT::scalar(17)}}),
20979cb839fSDaniel Sanders             LegalizeActionStep(WidenScalar, 0, LLT::scalar(32)));
210b3e86709SMatt Arsenault   EXPECT_EQ(L.getAction({G_UREM, {LLT::scalar(31)}}),
21179cb839fSDaniel Sanders             LegalizeActionStep(WidenScalar, 0, LLT::scalar(32)));
212b3e86709SMatt Arsenault   EXPECT_EQ(L.getAction({G_UREM, {LLT::scalar(33)}}),
21379cb839fSDaniel Sanders             LegalizeActionStep(Unsupported, 0, LLT::scalar(33)));
214af9814a1SKristof Beyls }
21569fa84a6STim Northover }
21607238286SMatt Arsenault 
21707238286SMatt Arsenault #define EXPECT_ACTION(Action, Index, Type, Query)                              \
21807238286SMatt Arsenault   do {                                                                         \
21907238286SMatt Arsenault     auto A = LI.getAction(Query);                                              \
22007238286SMatt Arsenault     EXPECT_EQ(LegalizeActionStep(Action, Index, Type), A) << A;                \
22107238286SMatt Arsenault   } while (0)
22207238286SMatt Arsenault 
TEST(LegalizerInfoTest,RuleSets)22307238286SMatt Arsenault TEST(LegalizerInfoTest, RuleSets) {
22407238286SMatt Arsenault   using namespace TargetOpcode;
22507238286SMatt Arsenault 
22691be65beSMatt Arsenault   const LLT s5 = LLT::scalar(5);
22791be65beSMatt Arsenault   const LLT s8 = LLT::scalar(8);
22891be65beSMatt Arsenault   const LLT s16 = LLT::scalar(16);
22907238286SMatt Arsenault   const LLT s32 = LLT::scalar(32);
23091be65beSMatt Arsenault   const LLT s33 = LLT::scalar(33);
23191be65beSMatt Arsenault   const LLT s64 = LLT::scalar(64);
23207238286SMatt Arsenault 
233d5e14ba8SSander de Smalen   const LLT v2s5 = LLT::fixed_vector(2, 5);
234d5e14ba8SSander de Smalen   const LLT v2s8 = LLT::fixed_vector(2, 8);
235d5e14ba8SSander de Smalen   const LLT v2s16 = LLT::fixed_vector(2, 16);
236d5e14ba8SSander de Smalen   const LLT v2s32 = LLT::fixed_vector(2, 32);
237d5e14ba8SSander de Smalen   const LLT v3s32 = LLT::fixed_vector(3, 32);
238d5e14ba8SSander de Smalen   const LLT v4s32 = LLT::fixed_vector(4, 32);
23950725982SMatt Arsenault   const LLT v8s32 = LLT::fixed_vector(8, 32);
240d5e14ba8SSander de Smalen   const LLT v2s33 = LLT::fixed_vector(2, 33);
241d5e14ba8SSander de Smalen   const LLT v2s64 = LLT::fixed_vector(2, 64);
24207238286SMatt Arsenault 
24307238286SMatt Arsenault   const LLT p0 = LLT::pointer(0, 32);
24425bcc8c7SAmara Emerson   const LLT v2p0 = LLT::fixed_vector(2, p0);
245d5e14ba8SSander de Smalen   const LLT v3p0 = LLT::fixed_vector(3, p0);
246d5e14ba8SSander de Smalen   const LLT v4p0 = LLT::fixed_vector(4, p0);
24707238286SMatt Arsenault 
24850725982SMatt Arsenault   const LLT s1 = LLT::scalar(1);
24950725982SMatt Arsenault   const LLT v2s1 = LLT::fixed_vector(2, 1);
25050725982SMatt Arsenault   const LLT v4s1 = LLT::fixed_vector(4, 1);
25150725982SMatt Arsenault 
25207238286SMatt Arsenault   {
25307238286SMatt Arsenault     LegalizerInfo LI;
254aaac2682SDaniel Sanders     auto &LegacyInfo = LI.getLegacyLegalizerInfo();
25507238286SMatt Arsenault 
25607238286SMatt Arsenault     LI.getActionDefinitionsBuilder(G_IMPLICIT_DEF)
25707238286SMatt Arsenault       .legalFor({v4s32, v4p0})
25807238286SMatt Arsenault       .moreElementsToNextPow2(0);
259aaac2682SDaniel Sanders     LegacyInfo.computeTables();
26007238286SMatt Arsenault 
26107238286SMatt Arsenault     EXPECT_ACTION(Unsupported, 0, LLT(), LegalityQuery(G_IMPLICIT_DEF, {s32}));
26207238286SMatt Arsenault     EXPECT_ACTION(Unsupported, 0, LLT(), LegalityQuery(G_IMPLICIT_DEF, {v2s32}));
26307238286SMatt Arsenault     EXPECT_ACTION(MoreElements, 0, v4p0, LegalityQuery(G_IMPLICIT_DEF, {v3p0}));
26407238286SMatt Arsenault     EXPECT_ACTION(MoreElements, 0, v4s32, LegalityQuery(G_IMPLICIT_DEF, {v3s32}));
26507238286SMatt Arsenault   }
26691be65beSMatt Arsenault 
26791be65beSMatt Arsenault   // Test minScalarOrElt
26891be65beSMatt Arsenault   {
26991be65beSMatt Arsenault     LegalizerInfo LI;
270aaac2682SDaniel Sanders     auto &LegacyInfo = LI.getLegacyLegalizerInfo();
27191be65beSMatt Arsenault     LI.getActionDefinitionsBuilder(G_OR)
27291be65beSMatt Arsenault       .legalFor({s32})
27391be65beSMatt Arsenault       .minScalarOrElt(0, s32);
274aaac2682SDaniel Sanders     LegacyInfo.computeTables();
27591be65beSMatt Arsenault 
27691be65beSMatt Arsenault     EXPECT_ACTION(WidenScalar, 0, s32, LegalityQuery(G_OR, {s16}));
27791be65beSMatt Arsenault     EXPECT_ACTION(WidenScalar, 0, v2s32, LegalityQuery(G_OR, {v2s16}));
27891be65beSMatt Arsenault   }
27991be65beSMatt Arsenault 
28091be65beSMatt Arsenault   // Test maxScalarOrELt
28191be65beSMatt Arsenault   {
28291be65beSMatt Arsenault     LegalizerInfo LI;
283aaac2682SDaniel Sanders     auto &LegacyInfo = LI.getLegacyLegalizerInfo();
28491be65beSMatt Arsenault     LI.getActionDefinitionsBuilder(G_AND)
28591be65beSMatt Arsenault       .legalFor({s16})
28691be65beSMatt Arsenault       .maxScalarOrElt(0, s16);
287aaac2682SDaniel Sanders     LegacyInfo.computeTables();
28891be65beSMatt Arsenault 
28991be65beSMatt Arsenault     EXPECT_ACTION(NarrowScalar, 0, s16, LegalityQuery(G_AND, {s32}));
29091be65beSMatt Arsenault     EXPECT_ACTION(NarrowScalar, 0, v2s16, LegalityQuery(G_AND, {v2s32}));
29191be65beSMatt Arsenault   }
29291be65beSMatt Arsenault 
29391be65beSMatt Arsenault   // Test clampScalarOrElt
29491be65beSMatt Arsenault   {
29591be65beSMatt Arsenault     LegalizerInfo LI;
296aaac2682SDaniel Sanders     auto &LegacyInfo = LI.getLegacyLegalizerInfo();
29791be65beSMatt Arsenault     LI.getActionDefinitionsBuilder(G_XOR)
29891be65beSMatt Arsenault       .legalFor({s16})
29991be65beSMatt Arsenault       .clampScalarOrElt(0, s16, s32);
300aaac2682SDaniel Sanders     LegacyInfo.computeTables();
30191be65beSMatt Arsenault 
30291be65beSMatt Arsenault     EXPECT_ACTION(NarrowScalar, 0, s32, LegalityQuery(G_XOR, {s64}));
30391be65beSMatt Arsenault     EXPECT_ACTION(WidenScalar, 0, s16, LegalityQuery(G_XOR, {s8}));
30491be65beSMatt Arsenault 
30591be65beSMatt Arsenault     // Make sure the number of elements is preserved.
30691be65beSMatt Arsenault     EXPECT_ACTION(NarrowScalar, 0, v2s32, LegalityQuery(G_XOR, {v2s64}));
30791be65beSMatt Arsenault     EXPECT_ACTION(WidenScalar, 0, v2s16, LegalityQuery(G_XOR, {v2s8}));
30891be65beSMatt Arsenault   }
30991be65beSMatt Arsenault 
31091be65beSMatt Arsenault   // Test minScalar
31191be65beSMatt Arsenault   {
31291be65beSMatt Arsenault     LegalizerInfo LI;
313aaac2682SDaniel Sanders     auto &LegacyInfo = LI.getLegacyLegalizerInfo();
31491be65beSMatt Arsenault     LI.getActionDefinitionsBuilder(G_OR)
31591be65beSMatt Arsenault       .legalFor({s32})
31691be65beSMatt Arsenault       .minScalar(0, s32);
317aaac2682SDaniel Sanders     LegacyInfo.computeTables();
31891be65beSMatt Arsenault 
31991be65beSMatt Arsenault     // Only handle scalars, ignore vectors.
32091be65beSMatt Arsenault     EXPECT_ACTION(WidenScalar, 0, s32, LegalityQuery(G_OR, {s16}));
32191be65beSMatt Arsenault     EXPECT_ACTION(Unsupported, 0, LLT(), LegalityQuery(G_OR, {v2s16}));
32291be65beSMatt Arsenault   }
32391be65beSMatt Arsenault 
324*9faff9a0STies Stuij   // Test minScalarIf
325*9faff9a0STies Stuij   {
326*9faff9a0STies Stuij     bool IfCond = true;
327*9faff9a0STies Stuij     LegalizerInfo LI;
328*9faff9a0STies Stuij     auto &LegacyInfo = LI.getLegacyLegalizerInfo();
329*9faff9a0STies Stuij     LI.getActionDefinitionsBuilder(G_OR)
330*9faff9a0STies Stuij       .legalFor({s32})
331*9faff9a0STies Stuij       .minScalarIf([&](const LegalityQuery &Query) {
332*9faff9a0STies Stuij                      return IfCond;
333*9faff9a0STies Stuij                    }, 0, s32);
334*9faff9a0STies Stuij     LegacyInfo.computeTables();
335*9faff9a0STies Stuij 
336*9faff9a0STies Stuij     // Only handle scalars, ignore vectors.
337*9faff9a0STies Stuij     EXPECT_ACTION(WidenScalar, 0, s32, LegalityQuery(G_OR, {s16}));
338*9faff9a0STies Stuij     EXPECT_ACTION(Unsupported, 0, LLT(), LegalityQuery(G_OR, {v2s16}));
339*9faff9a0STies Stuij 
340*9faff9a0STies Stuij     IfCond = false;
341*9faff9a0STies Stuij     EXPECT_ACTION(Unsupported, 0, LLT(), LegalityQuery(G_OR, {s16}));
342*9faff9a0STies Stuij     EXPECT_ACTION(Unsupported, 0, LLT(), LegalityQuery(G_OR, {v2s16}));
343*9faff9a0STies Stuij   }
344*9faff9a0STies Stuij 
34591be65beSMatt Arsenault   // Test maxScalar
34691be65beSMatt Arsenault   {
34791be65beSMatt Arsenault     LegalizerInfo LI;
348aaac2682SDaniel Sanders     auto &LegacyInfo = LI.getLegacyLegalizerInfo();
34991be65beSMatt Arsenault     LI.getActionDefinitionsBuilder(G_AND)
35091be65beSMatt Arsenault       .legalFor({s16})
35191be65beSMatt Arsenault       .maxScalar(0, s16);
352aaac2682SDaniel Sanders     LegacyInfo.computeTables();
35391be65beSMatt Arsenault 
35491be65beSMatt Arsenault     // Only handle scalars, ignore vectors.
35591be65beSMatt Arsenault     EXPECT_ACTION(NarrowScalar, 0, s16, LegalityQuery(G_AND, {s32}));
35691be65beSMatt Arsenault     EXPECT_ACTION(Unsupported, 0, LLT(), LegalityQuery(G_AND, {v2s32}));
35791be65beSMatt Arsenault   }
35891be65beSMatt Arsenault 
35991be65beSMatt Arsenault   // Test clampScalar
36091be65beSMatt Arsenault   {
36191be65beSMatt Arsenault     LegalizerInfo LI;
362aaac2682SDaniel Sanders     auto &LegacyInfo = LI.getLegacyLegalizerInfo();
36391be65beSMatt Arsenault 
36491be65beSMatt Arsenault     LI.getActionDefinitionsBuilder(G_XOR)
36591be65beSMatt Arsenault       .legalFor({s16})
36691be65beSMatt Arsenault       .clampScalar(0, s16, s32);
367aaac2682SDaniel Sanders     LegacyInfo.computeTables();
36891be65beSMatt Arsenault 
36991be65beSMatt Arsenault     EXPECT_ACTION(NarrowScalar, 0, s32, LegalityQuery(G_XOR, {s64}));
37091be65beSMatt Arsenault     EXPECT_ACTION(WidenScalar, 0, s16, LegalityQuery(G_XOR, {s8}));
37191be65beSMatt Arsenault 
37291be65beSMatt Arsenault     // Only handle scalars, ignore vectors.
37391be65beSMatt Arsenault     EXPECT_ACTION(Unsupported, 0, LLT(), LegalityQuery(G_XOR, {v2s64}));
37491be65beSMatt Arsenault     EXPECT_ACTION(Unsupported, 0, LLT(), LegalityQuery(G_XOR, {v2s8}));
37591be65beSMatt Arsenault   }
37691be65beSMatt Arsenault 
37791be65beSMatt Arsenault   // Test widenScalarOrEltToNextPow2
37891be65beSMatt Arsenault   {
37991be65beSMatt Arsenault     LegalizerInfo LI;
380aaac2682SDaniel Sanders     auto &LegacyInfo = LI.getLegacyLegalizerInfo();
38191be65beSMatt Arsenault 
38291be65beSMatt Arsenault     LI.getActionDefinitionsBuilder(G_AND)
38391be65beSMatt Arsenault       .legalFor({s32})
38491be65beSMatt Arsenault       .widenScalarOrEltToNextPow2(0, 32);
385aaac2682SDaniel Sanders     LegacyInfo.computeTables();
38691be65beSMatt Arsenault 
38791be65beSMatt Arsenault     // Handle scalars and vectors
38891be65beSMatt Arsenault     EXPECT_ACTION(WidenScalar, 0, s32, LegalityQuery(G_AND, {s5}));
38991be65beSMatt Arsenault     EXPECT_ACTION(WidenScalar, 0, v2s32, LegalityQuery(G_AND, {v2s5}));
39091be65beSMatt Arsenault     EXPECT_ACTION(WidenScalar, 0, s64, LegalityQuery(G_AND, {s33}));
39191be65beSMatt Arsenault     EXPECT_ACTION(WidenScalar, 0, v2s64, LegalityQuery(G_AND, {v2s33}));
39291be65beSMatt Arsenault   }
39391be65beSMatt Arsenault 
39491be65beSMatt Arsenault   // Test widenScalarToNextPow2
39591be65beSMatt Arsenault   {
39691be65beSMatt Arsenault     LegalizerInfo LI;
397aaac2682SDaniel Sanders     auto &LegacyInfo = LI.getLegacyLegalizerInfo();
39891be65beSMatt Arsenault 
39991be65beSMatt Arsenault     LI.getActionDefinitionsBuilder(G_AND)
40091be65beSMatt Arsenault       .legalFor({s32})
40191be65beSMatt Arsenault       .widenScalarToNextPow2(0, 32);
402aaac2682SDaniel Sanders     LegacyInfo.computeTables();
40391be65beSMatt Arsenault 
40491be65beSMatt Arsenault     EXPECT_ACTION(WidenScalar, 0, s32, LegalityQuery(G_AND, {s5}));
40591be65beSMatt Arsenault     EXPECT_ACTION(WidenScalar, 0, s64, LegalityQuery(G_AND, {s33}));
40691be65beSMatt Arsenault 
40791be65beSMatt Arsenault     // Do nothing for vectors.
40891be65beSMatt Arsenault     EXPECT_ACTION(Unsupported, 0, LLT(), LegalityQuery(G_AND, {v2s5}));
40991be65beSMatt Arsenault     EXPECT_ACTION(Unsupported, 0, LLT(), LegalityQuery(G_AND, {v2s33}));
41091be65beSMatt Arsenault   }
41150725982SMatt Arsenault 
41250725982SMatt Arsenault   // Test changeElementCountTo
41350725982SMatt Arsenault   {
41450725982SMatt Arsenault     LegalizerInfo LI;
41550725982SMatt Arsenault     auto &LegacyInfo = LI.getLegacyLegalizerInfo();
41650725982SMatt Arsenault 
41750725982SMatt Arsenault     // Type index form
41850725982SMatt Arsenault     LI.getActionDefinitionsBuilder(G_SELECT)
41950725982SMatt Arsenault       .moreElementsIf(isScalar(1), changeElementCountTo(1, 0));
42050725982SMatt Arsenault 
42150725982SMatt Arsenault     // Raw type form
42250725982SMatt Arsenault     LI.getActionDefinitionsBuilder(G_ADD)
42350725982SMatt Arsenault       .fewerElementsIf(typeIs(0, v4s32), changeElementCountTo(0, v2s32))
42450725982SMatt Arsenault       .fewerElementsIf(typeIs(0, v8s32), changeElementCountTo(0, s32))
42550725982SMatt Arsenault       .fewerElementsIf(typeIs(0, LLT::scalable_vector(4, 16)),
42650725982SMatt Arsenault                        changeElementCountTo(0, LLT::scalable_vector(2, 16)))
42750725982SMatt Arsenault       .fewerElementsIf(typeIs(0, LLT::scalable_vector(8, 16)),
42850725982SMatt Arsenault                        changeElementCountTo(0, s16));
42950725982SMatt Arsenault 
43050725982SMatt Arsenault     LegacyInfo.computeTables();
43150725982SMatt Arsenault 
43250725982SMatt Arsenault     EXPECT_ACTION(MoreElements, 1, v4s1, LegalityQuery(G_SELECT, {v4s32, s1}));
43350725982SMatt Arsenault     EXPECT_ACTION(MoreElements, 1, v2s1, LegalityQuery(G_SELECT, {v2s32, s1}));
43450725982SMatt Arsenault     EXPECT_ACTION(MoreElements, 1, v2s1, LegalityQuery(G_SELECT, {v2s32, s1}));
43550725982SMatt Arsenault     EXPECT_ACTION(MoreElements, 1, v4s1, LegalityQuery(G_SELECT, {v4p0, s1}));
43650725982SMatt Arsenault 
43750725982SMatt Arsenault     EXPECT_ACTION(MoreElements, 1, LLT::scalable_vector(2, 1),
43850725982SMatt Arsenault                   LegalityQuery(G_SELECT, {LLT::scalable_vector(2, 32), s1}));
43950725982SMatt Arsenault     EXPECT_ACTION(MoreElements, 1, LLT::scalable_vector(4, 1),
44050725982SMatt Arsenault                   LegalityQuery(G_SELECT, {LLT::scalable_vector(4, 32), s1}));
44150725982SMatt Arsenault     EXPECT_ACTION(MoreElements, 1, LLT::scalable_vector(2, s1),
44250725982SMatt Arsenault                   LegalityQuery(G_SELECT, {LLT::scalable_vector(2, p0), s1}));
44350725982SMatt Arsenault 
44450725982SMatt Arsenault     EXPECT_ACTION(FewerElements, 0, v2s32, LegalityQuery(G_ADD, {v4s32}));
44550725982SMatt Arsenault     EXPECT_ACTION(FewerElements, 0, s32, LegalityQuery(G_ADD, {v8s32}));
44650725982SMatt Arsenault 
44750725982SMatt Arsenault     EXPECT_ACTION(FewerElements, 0, LLT::scalable_vector(2, 16),
44850725982SMatt Arsenault                   LegalityQuery(G_ADD, {LLT::scalable_vector(4, 16)}));
44950725982SMatt Arsenault     EXPECT_ACTION(FewerElements, 0, s16,
45050725982SMatt Arsenault                   LegalityQuery(G_ADD, {LLT::scalable_vector(8, 16)}));
45150725982SMatt Arsenault   }
45225bcc8c7SAmara Emerson 
45325bcc8c7SAmara Emerson   // Test minScalarEltSameAsIf
45425bcc8c7SAmara Emerson   {
45525bcc8c7SAmara Emerson     LegalizerInfo LI;
45625bcc8c7SAmara Emerson     auto &LegacyInfo = LI.getLegacyLegalizerInfo();
45725bcc8c7SAmara Emerson 
45825bcc8c7SAmara Emerson     LI.getActionDefinitionsBuilder(G_SELECT).minScalarEltSameAsIf(
45925bcc8c7SAmara Emerson         all(isVector(0), isVector(1)), 1, 0);
46025bcc8c7SAmara Emerson     LegacyInfo.computeTables();
46125bcc8c7SAmara Emerson     LLT p1 = LLT::pointer(1, 32);
46225bcc8c7SAmara Emerson     LLT v2p1 = LLT::fixed_vector(2, p1);
46325bcc8c7SAmara Emerson 
46425bcc8c7SAmara Emerson     EXPECT_ACTION(WidenScalar, 1, v2s32, LegalityQuery(G_SELECT, {v2p0, v2s1}));
46525bcc8c7SAmara Emerson     EXPECT_ACTION(WidenScalar, 1, v2s32, LegalityQuery(G_SELECT, {v2p1, v2s1}));
46625bcc8c7SAmara Emerson   }
46707238286SMatt Arsenault }
468530d05e9SMatt Arsenault 
TEST(LegalizerInfoTest,MMOAlignment)469530d05e9SMatt Arsenault TEST(LegalizerInfoTest, MMOAlignment) {
470530d05e9SMatt Arsenault   using namespace TargetOpcode;
471530d05e9SMatt Arsenault 
472530d05e9SMatt Arsenault   const LLT s32 = LLT::scalar(32);
473530d05e9SMatt Arsenault   const LLT p0 = LLT::pointer(0, 64);
474530d05e9SMatt Arsenault 
475530d05e9SMatt Arsenault   {
476530d05e9SMatt Arsenault     LegalizerInfo LI;
477aaac2682SDaniel Sanders     auto &LegacyInfo = LI.getLegacyLegalizerInfo();
478530d05e9SMatt Arsenault     LI.getActionDefinitionsBuilder(G_LOAD)
47928f2f662SMatt Arsenault       .legalForTypesWithMemDesc({{s32, p0, s32, 32}});
480530d05e9SMatt Arsenault 
481aaac2682SDaniel Sanders     LegacyInfo.computeTables();
482530d05e9SMatt Arsenault 
483530d05e9SMatt Arsenault     EXPECT_ACTION(Legal, 0, LLT(),
484530d05e9SMatt Arsenault                   LegalityQuery(G_LOAD, {s32, p0},
485530d05e9SMatt Arsenault                                 LegalityQuery::MemDesc{
48628f2f662SMatt Arsenault                                   s32, 32, AtomicOrdering::NotAtomic}));
487530d05e9SMatt Arsenault     EXPECT_ACTION(Unsupported, 0, LLT(),
488530d05e9SMatt Arsenault                   LegalityQuery(G_LOAD, {s32, p0},
489530d05e9SMatt Arsenault                                 LegalityQuery::MemDesc{
49028f2f662SMatt Arsenault                                   s32, 16, AtomicOrdering::NotAtomic }));
491530d05e9SMatt Arsenault     EXPECT_ACTION(Unsupported, 0, LLT(),
492530d05e9SMatt Arsenault                   LegalityQuery(G_LOAD, {s32, p0},
493530d05e9SMatt Arsenault                                 LegalityQuery::MemDesc{
49428f2f662SMatt Arsenault                                   s32, 8, AtomicOrdering::NotAtomic}));
495530d05e9SMatt Arsenault   }
496530d05e9SMatt Arsenault 
497530d05e9SMatt Arsenault   // Test that the maximum supported alignment value isn't truncated
498530d05e9SMatt Arsenault   {
499530d05e9SMatt Arsenault     // Maximum IR defined alignment in bytes.
500530d05e9SMatt Arsenault     const uint64_t MaxAlignment = UINT64_C(1) << 29;
501530d05e9SMatt Arsenault     const uint64_t MaxAlignInBits = 8 * MaxAlignment;
502530d05e9SMatt Arsenault     LegalizerInfo LI;
503aaac2682SDaniel Sanders     auto &LegacyInfo = LI.getLegacyLegalizerInfo();
504530d05e9SMatt Arsenault     LI.getActionDefinitionsBuilder(G_LOAD)
50528f2f662SMatt Arsenault       .legalForTypesWithMemDesc({{s32, p0, s32, MaxAlignInBits}});
506530d05e9SMatt Arsenault 
507aaac2682SDaniel Sanders     LegacyInfo.computeTables();
508530d05e9SMatt Arsenault 
509530d05e9SMatt Arsenault     EXPECT_ACTION(Legal, 0, LLT(),
510530d05e9SMatt Arsenault                   LegalityQuery(G_LOAD, {s32, p0},
51128f2f662SMatt Arsenault                                 LegalityQuery::MemDesc{s32,
512530d05e9SMatt Arsenault                                     MaxAlignInBits, AtomicOrdering::NotAtomic}));
513530d05e9SMatt Arsenault     EXPECT_ACTION(Unsupported, 0, LLT(),
514530d05e9SMatt Arsenault                   LegalityQuery(G_LOAD, {s32, p0},
515530d05e9SMatt Arsenault                                 LegalityQuery::MemDesc{
51628f2f662SMatt Arsenault                                   s32, 8, AtomicOrdering::NotAtomic }));
517530d05e9SMatt Arsenault   }
518530d05e9SMatt Arsenault }
5194e3edef4SReid Kleckner 
5204e3edef4SReid Kleckner // This code sequence doesn't do anything, but it covers a previously uncovered
5214e3edef4SReid Kleckner // codepath that used to crash in MSVC x86_32 debug mode.
TEST(LegalizerInfoTest,MSVCDebugMiscompile)5224e3edef4SReid Kleckner TEST(LegalizerInfoTest, MSVCDebugMiscompile) {
5234e3edef4SReid Kleckner   const LLT S1 = LLT::scalar(1);
5244e3edef4SReid Kleckner   const LLT P0 = LLT::pointer(0, 32);
5254e3edef4SReid Kleckner   LegalizerInfo LI;
5264e3edef4SReid Kleckner   auto Builder = LI.getActionDefinitionsBuilder(TargetOpcode::G_PTRTOINT);
5274e3edef4SReid Kleckner   (void)Builder.legalForCartesianProduct({S1}, {P0});
5284e3edef4SReid Kleckner }
529