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