blob: 802f7946cdb19783f34b316f43c8bc52c6c7baad [file] [log] [blame]
Tim Northover69fa84a2016-10-14 22:18:18 +00001//===- llvm/unittest/CodeGen/GlobalISel/LegalizerInfoTest.cpp -------------===//
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
10#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
11#include "llvm/Target/TargetOpcodes.h"
12#include "gtest/gtest.h"
13
14using namespace llvm;
15
16// Define a couple of pretty printers to help debugging when things go wrong.
17namespace llvm {
18std::ostream &
19operator<<(std::ostream &OS, const llvm::LegalizerInfo::LegalizeAction Act) {
20 switch (Act) {
21 case LegalizerInfo::Lower: OS << "Lower"; break;
22 case LegalizerInfo::Legal: OS << "Legal"; break;
23 case LegalizerInfo::NarrowScalar: OS << "NarrowScalar"; break;
24 case LegalizerInfo::WidenScalar: OS << "WidenScalar"; break;
25 case LegalizerInfo::FewerElements: OS << "FewerElements"; break;
26 case LegalizerInfo::MoreElements: OS << "MoreElements"; break;
27 case LegalizerInfo::Libcall: OS << "Libcall"; break;
28 case LegalizerInfo::Custom: OS << "Custom"; break;
29 case LegalizerInfo::Unsupported: OS << "Unsupported"; break;
30 case LegalizerInfo::NotFound: OS << "NotFound";
31 }
32 return OS;
33}
34
35std::ostream &
36operator<<(std::ostream &OS, const llvm::LLT Ty) {
37 std::string Repr;
38 raw_string_ostream SS{Repr};
39 Ty.print(SS);
40 OS << SS.str();
41 return OS;
42}
43}
44
45namespace {
46
47
48TEST(LegalizerInfoTest, ScalarRISC) {
49 using namespace TargetOpcode;
50 LegalizerInfo L;
51 // Typical RISCy set of operations based on AArch64.
Kristof Beylsaf9814a2017-11-07 10:34:34 +000052 for (auto Op : {G_ADD, G_SUB}) {
53 for (unsigned Size : {32, 64})
54 L.setAction({Op, 0, LLT::scalar(Size)}, LegalizerInfo::Legal);
55 L.setLegalizeScalarToDifferentSizeStrategy(
56 Op, 0, LegalizerInfo::widenToLargerTypesAndNarrowToLargest);
57 }
58
Tim Northover69fa84a2016-10-14 22:18:18 +000059 L.computeTables();
60
Kristof Beylsaf9814a2017-11-07 10:34:34 +000061 for (auto &opcode : {G_ADD, G_SUB}) {
62 // Check we infer the correct types and actually do what we're told.
63 ASSERT_EQ(L.getAction({opcode, LLT::scalar(8)}),
64 std::make_pair(LegalizerInfo::WidenScalar, LLT::scalar(32)));
65 ASSERT_EQ(L.getAction({opcode, LLT::scalar(16)}),
66 std::make_pair(LegalizerInfo::WidenScalar, LLT::scalar(32)));
67 ASSERT_EQ(L.getAction({opcode, LLT::scalar(32)}),
68 std::make_pair(LegalizerInfo::Legal, LLT::scalar(32)));
69 ASSERT_EQ(L.getAction({opcode, LLT::scalar(64)}),
70 std::make_pair(LegalizerInfo::Legal, LLT::scalar(64)));
Tim Northover69fa84a2016-10-14 22:18:18 +000071
Kristof Beylsaf9814a2017-11-07 10:34:34 +000072 // Make sure the default for over-sized types applies.
73 ASSERT_EQ(L.getAction({opcode, LLT::scalar(128)}),
74 std::make_pair(LegalizerInfo::NarrowScalar, LLT::scalar(64)));
75 // Make sure we also handle unusual sizes
76 ASSERT_EQ(L.getAction({opcode, LLT::scalar(1)}),
77 std::make_pair(LegalizerInfo::WidenScalar, LLT::scalar(32)));
78 ASSERT_EQ(L.getAction({opcode, LLT::scalar(31)}),
79 std::make_pair(LegalizerInfo::WidenScalar, LLT::scalar(32)));
80 ASSERT_EQ(L.getAction({opcode, LLT::scalar(33)}),
81 std::make_pair(LegalizerInfo::WidenScalar, LLT::scalar(64)));
82 ASSERT_EQ(L.getAction({opcode, LLT::scalar(63)}),
83 std::make_pair(LegalizerInfo::WidenScalar, LLT::scalar(64)));
84 ASSERT_EQ(L.getAction({opcode, LLT::scalar(65)}),
85 std::make_pair(LegalizerInfo::NarrowScalar, LLT::scalar(64)));
86 }
Tim Northover69fa84a2016-10-14 22:18:18 +000087}
88
89TEST(LegalizerInfoTest, VectorRISC) {
90 using namespace TargetOpcode;
91 LegalizerInfo L;
92 // Typical RISCy set of operations based on ARM.
Tim Northover69fa84a2016-10-14 22:18:18 +000093 L.setAction({G_ADD, LLT::vector(8, 8)}, LegalizerInfo::Legal);
94 L.setAction({G_ADD, LLT::vector(16, 8)}, LegalizerInfo::Legal);
95 L.setAction({G_ADD, LLT::vector(4, 16)}, LegalizerInfo::Legal);
96 L.setAction({G_ADD, LLT::vector(8, 16)}, LegalizerInfo::Legal);
97 L.setAction({G_ADD, LLT::vector(2, 32)}, LegalizerInfo::Legal);
98 L.setAction({G_ADD, LLT::vector(4, 32)}, LegalizerInfo::Legal);
Kristof Beylsaf9814a2017-11-07 10:34:34 +000099
100 L.setLegalizeVectorElementToDifferentSizeStrategy(
101 G_ADD, 0, LegalizerInfo::widenToLargerTypesUnsupportedOtherwise);
102
103 L.setAction({G_ADD, 0, LLT::scalar(32)}, LegalizerInfo::Legal);
104
Tim Northover69fa84a2016-10-14 22:18:18 +0000105 L.computeTables();
106
107 // Check we infer the correct types and actually do what we're told for some
108 // simple cases.
Tim Northover69fa84a2016-10-14 22:18:18 +0000109 ASSERT_EQ(L.getAction({G_ADD, LLT::vector(8, 8)}),
110 std::make_pair(LegalizerInfo::Legal, LLT::vector(8, 8)));
Kristof Beylsaf9814a2017-11-07 10:34:34 +0000111 ASSERT_EQ(L.getAction({G_ADD, LLT::vector(8, 7)}),
112 std::make_pair(LegalizerInfo::WidenScalar, LLT::vector(8, 8)));
113 ASSERT_EQ(L.getAction({G_ADD, LLT::vector(2, 8)}),
114 std::make_pair(LegalizerInfo::MoreElements, LLT::vector(8, 8)));
115 ASSERT_EQ(L.getAction({G_ADD, LLT::vector(8, 32)}),
116 std::make_pair(LegalizerInfo::FewerElements, LLT::vector(4, 32)));
117 // Check a few non-power-of-2 sizes:
118 ASSERT_EQ(L.getAction({G_ADD, LLT::vector(3, 3)}),
119 std::make_pair(LegalizerInfo::WidenScalar, LLT::vector(3, 8)));
120 ASSERT_EQ(L.getAction({G_ADD, LLT::vector(3, 8)}),
121 std::make_pair(LegalizerInfo::MoreElements, LLT::vector(8, 8)));
Tim Northover69fa84a2016-10-14 22:18:18 +0000122}
123
124TEST(LegalizerInfoTest, MultipleTypes) {
125 using namespace TargetOpcode;
126 LegalizerInfo L;
127 LLT p0 = LLT::pointer(0, 64);
Tim Northover69fa84a2016-10-14 22:18:18 +0000128 LLT s64 = LLT::scalar(64);
129
130 // Typical RISCy set of operations based on AArch64.
131 L.setAction({G_PTRTOINT, 0, s64}, LegalizerInfo::Legal);
132 L.setAction({G_PTRTOINT, 1, p0}, LegalizerInfo::Legal);
133
Kristof Beylsaf9814a2017-11-07 10:34:34 +0000134 L.setLegalizeScalarToDifferentSizeStrategy(
135 G_PTRTOINT, 0, LegalizerInfo::widenToLargerTypesAndNarrowToLargest);
136
Tim Northover69fa84a2016-10-14 22:18:18 +0000137 L.computeTables();
138
139 // Check we infer the correct types and actually do what we're told.
140 ASSERT_EQ(L.getAction({G_PTRTOINT, 0, s64}),
141 std::make_pair(LegalizerInfo::Legal, s64));
142 ASSERT_EQ(L.getAction({G_PTRTOINT, 1, p0}),
143 std::make_pair(LegalizerInfo::Legal, p0));
Kristof Beylsaf9814a2017-11-07 10:34:34 +0000144 // Make sure we also handle unusual sizes
145 ASSERT_EQ(L.getAction({G_PTRTOINT, 0, LLT::scalar(65)}),
146 std::make_pair(LegalizerInfo::NarrowScalar, s64));
147 ASSERT_EQ(L.getAction({G_PTRTOINT, 1, LLT::pointer(0, 32)}),
148 std::make_pair(LegalizerInfo::Unsupported, LLT::pointer(0, 32)));
Tim Northover69fa84a2016-10-14 22:18:18 +0000149}
Kristof Beylsb539ea52017-06-30 08:26:20 +0000150
151TEST(LegalizerInfoTest, MultipleSteps) {
152 using namespace TargetOpcode;
153 LegalizerInfo L;
Kristof Beylsb539ea52017-06-30 08:26:20 +0000154 LLT s32 = LLT::scalar(32);
155 LLT s64 = LLT::scalar(64);
156
Kristof Beylsaf9814a2017-11-07 10:34:34 +0000157 L.setLegalizeScalarToDifferentSizeStrategy(
158 G_UREM, 0, LegalizerInfo::widenToLargerTypesUnsupportedOtherwise);
Kristof Beylsb539ea52017-06-30 08:26:20 +0000159 L.setAction({G_UREM, 0, s32}, LegalizerInfo::Lower);
160 L.setAction({G_UREM, 0, s64}, LegalizerInfo::Lower);
161
162 L.computeTables();
163
164 ASSERT_EQ(L.getAction({G_UREM, LLT::scalar(16)}),
165 std::make_pair(LegalizerInfo::WidenScalar, LLT::scalar(32)));
166 ASSERT_EQ(L.getAction({G_UREM, LLT::scalar(32)}),
167 std::make_pair(LegalizerInfo::Lower, LLT::scalar(32)));
168}
Kristof Beylsaf9814a2017-11-07 10:34:34 +0000169
170TEST(LegalizerInfoTest, SizeChangeStrategy) {
171 using namespace TargetOpcode;
172 LegalizerInfo L;
173 for (unsigned Size : {1, 8, 16, 32})
174 L.setAction({G_UREM, 0, LLT::scalar(Size)}, LegalizerInfo::Legal);
175
176 L.setLegalizeScalarToDifferentSizeStrategy(
177 G_UREM, 0, LegalizerInfo::widenToLargerTypesUnsupportedOtherwise);
178 L.computeTables();
179
180 // Check we infer the correct types and actually do what we're told.
181 for (unsigned Size : {1, 8, 16, 32}) {
182 ASSERT_EQ(L.getAction({G_UREM, LLT::scalar(Size)}),
183 std::make_pair(LegalizerInfo::Legal, LLT::scalar(Size)));
184 }
185 ASSERT_EQ(L.getAction({G_UREM, LLT::scalar(2)}),
186 std::make_pair(LegalizerInfo::WidenScalar, LLT::scalar(8)));
187 ASSERT_EQ(L.getAction({G_UREM, LLT::scalar(7)}),
188 std::make_pair(LegalizerInfo::WidenScalar, LLT::scalar(8)));
189 ASSERT_EQ(L.getAction({G_UREM, LLT::scalar(9)}),
190 std::make_pair(LegalizerInfo::WidenScalar, LLT::scalar(16)));
191 ASSERT_EQ(L.getAction({G_UREM, LLT::scalar(17)}),
192 std::make_pair(LegalizerInfo::WidenScalar, LLT::scalar(32)));
193 ASSERT_EQ(L.getAction({G_UREM, LLT::scalar(31)}),
194 std::make_pair(LegalizerInfo::WidenScalar, LLT::scalar(32)));
195 ASSERT_EQ(L.getAction({G_UREM, LLT::scalar(33)}),
196 std::make_pair(LegalizerInfo::Unsupported, LLT::scalar(33)));
197}
Tim Northover69fa84a2016-10-14 22:18:18 +0000198}