llvm.org GIT mirror llvm / 41fccf2
[globalisel] Make LegalizerInfo::LegalizeAction available outside of LegalizerInfo. NFC Summary: The improvements to the LegalizerInfo discussed in D42244 require that LegalizerInfo::LegalizeAction be available for use in other classes. As such, it needs to be moved out of LegalizerInfo. This has been done separately to the next patch to minimize the noise in that patch. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@323669 91177308-0d34-0410-b5e6-96231b3b80d8 Daniel Sanders 2 years ago
9 changed file(s) with 218 addition(s) and 210 deletion(s). Raw diff Collapse all Expand all
277277 /// Checks if the target legalizer info has specified anything about the
278278 /// instruction, or if unsupported.
279279 bool isInstUnsupported(const LegalityQuery &Query) const {
280 using namespace LegalizeActions;
280281 auto Step = LI.getAction(Query);
281 return Step.Action == LegalizerInfo::LegalizeAction::Unsupported ||
282 Step.Action == LegalizerInfo::LegalizeAction::NotFound;
282 return Step.Action == Unsupported || Step.Action == NotFound;
283283 }
284284 };
285285
3333 class MachineIRBuilder;
3434 class MachineRegisterInfo;
3535
36 namespace LegalizeActions {
37 enum LegalizeAction : std::uint8_t {
38 /// The operation is expected to be selectable directly by the target, and
39 /// no transformation is necessary.
40 Legal,
41
42 /// The operation should be synthesized from multiple instructions acting on
43 /// a narrower scalar base-type. For example a 64-bit add might be
44 /// implemented in terms of 32-bit add-with-carry.
45 NarrowScalar,
46
47 /// The operation should be implemented in terms of a wider scalar
48 /// base-type. For example a <2 x s8> add could be implemented as a <2
49 /// x s32> add (ignoring the high bits).
50 WidenScalar,
51
52 /// The (vector) operation should be implemented by splitting it into
53 /// sub-vectors where the operation is legal. For example a <8 x s64> add
54 /// might be implemented as 4 separate <2 x s64> adds.
55 FewerElements,
56
57 /// The (vector) operation should be implemented by widening the input
58 /// vector and ignoring the lanes added by doing so. For example <2 x i8> is
59 /// rarely legal, but you might perform an <8 x i8> and then only look at
60 /// the first two results.
61 MoreElements,
62
63 /// The operation itself must be expressed in terms of simpler actions on
64 /// this target. E.g. a SREM replaced by an SDIV and subtraction.
65 Lower,
66
67 /// The operation should be implemented as a call to some kind of runtime
68 /// support library. For example this usually happens on machines that don't
69 /// support floating-point operations natively.
70 Libcall,
71
72 /// The target wants to do something special with this combination of
73 /// operand and type. A callback will be issued when it is needed.
74 Custom,
75
76 /// This operation is completely unsupported on the target. A programming
77 /// error has occurred.
78 Unsupported,
79
80 /// Sentinel value for when no action was found in the specified table.
81 NotFound,
82 };
83 } // end namespace LegalizeActions
84
85 using LegalizeActions::LegalizeAction;
86
3687 /// Legalization is decided based on an instruction's opcode, which type slot
3788 /// we're considering, and what the existing type is. These aspects are gathered
3889 /// together for convenience in the InstrAspect class.
61112
62113 class LegalizerInfo {
63114 public:
64 enum LegalizeAction : std::uint8_t {
65 /// The operation is expected to be selectable directly by the target, and
66 /// no transformation is necessary.
67 Legal,
68
69 /// The operation should be synthesized from multiple instructions acting on
70 /// a narrower scalar base-type. For example a 64-bit add might be
71 /// implemented in terms of 32-bit add-with-carry.
72 NarrowScalar,
73
74 /// The operation should be implemented in terms of a wider scalar
75 /// base-type. For example a <2 x s8> add could be implemented as a <2
76 /// x s32> add (ignoring the high bits).
77 WidenScalar,
78
79 /// The (vector) operation should be implemented by splitting it into
80 /// sub-vectors where the operation is legal. For example a <8 x s64> add
81 /// might be implemented as 4 separate <2 x s64> adds.
82 FewerElements,
83
84 /// The (vector) operation should be implemented by widening the input
85 /// vector and ignoring the lanes added by doing so. For example <2 x i8> is
86 /// rarely legal, but you might perform an <8 x i8> and then only look at
87 /// the first two results.
88 MoreElements,
89
90 /// The operation itself must be expressed in terms of simpler actions on
91 /// this target. E.g. a SREM replaced by an SDIV and subtraction.
92 Lower,
93
94 /// The operation should be implemented as a call to some kind of runtime
95 /// support library. For example this usually happens on machines that don't
96 /// support floating-point operations natively.
97 Libcall,
98
99 /// The target wants to do something special with this combination of
100 /// operand and type. A callback will be issued when it is needed.
101 Custom,
102
103 /// This operation is completely unsupported on the target. A programming
104 /// error has occurred.
105 Unsupported,
106
107 /// Sentinel value for when no action was found in the specified table.
108 NotFound,
109 };
110
111115 /// The result of a query. It either indicates a final answer of Legal or
112116 /// Unsupported or describes an action that must be taken to make an operation
113117 /// more legal.
138142 void computeTables();
139143
140144 static bool needsLegalizingToDifferentSize(const LegalizeAction Action) {
145 using namespace LegalizeActions;
141146 switch (Action) {
142147 case NarrowScalar:
143148 case WidenScalar:
215220 /// and Unsupported for all other scalar types T.
216221 static SizeAndActionsVec
217222 unsupportedForDifferentSizes(const SizeAndActionsVec &v) {
223 using namespace LegalizeActions;
218224 return increaseToLargerTypesAndDecreaseToLargest(v, Unsupported,
219 Unsupported);
225 Unsupported);
220226 }
221227
222228 /// A SizeChangeStrategy for the common case where legalization for a
225231 /// largest legal type.
226232 static SizeAndActionsVec
227233 widenToLargerTypesAndNarrowToLargest(const SizeAndActionsVec &v) {
234 using namespace LegalizeActions;
228235 assert(v.size() > 0 &&
229236 "At least one size that can be legalized towards is needed"
230237 " for this SizeChangeStrategy");
231238 return increaseToLargerTypesAndDecreaseToLargest(v, WidenScalar,
232 NarrowScalar);
239 NarrowScalar);
233240 }
234241
235242 static SizeAndActionsVec
236243 widenToLargerTypesUnsupportedOtherwise(const SizeAndActionsVec &v) {
244 using namespace LegalizeActions;
237245 return increaseToLargerTypesAndDecreaseToLargest(v, WidenScalar,
238 Unsupported);
246 Unsupported);
239247 }
240248
241249 static SizeAndActionsVec
242250 narrowToSmallerAndUnsupportedIfTooSmall(const SizeAndActionsVec &v) {
251 using namespace LegalizeActions;
243252 return decreaseToSmallerTypesAndIncreaseToSmallest(v, NarrowScalar,
244 Unsupported);
253 Unsupported);
245254 }
246255
247256 static SizeAndActionsVec
248257 narrowToSmallerAndWidenToSmallest(const SizeAndActionsVec &v) {
258 using namespace LegalizeActions;
249259 assert(v.size() > 0 &&
250260 "At least one size that can be legalized towards is needed"
251261 " for this SizeChangeStrategy");
252262 return decreaseToSmallerTypesAndIncreaseToSmallest(v, NarrowScalar,
253 WidenScalar);
263 WidenScalar);
254264 }
255265
256266 /// A SizeChangeStrategy for the common case where legalization for a
273283 /// (FewerElements, vector(4,32)).
274284 static SizeAndActionsVec
275285 moreToWiderTypesAndLessToWidest(const SizeAndActionsVec &v) {
286 using namespace LegalizeActions;
276287 return increaseToLargerTypesAndDecreaseToLargest(v, MoreElements,
277 FewerElements);
288 FewerElements);
278289 }
279290
280291 /// Helper function to implement many typical SizeChangeStrategy functions.
384395 /// A partial SizeAndActionsVec potentially doesn't cover all bit sizes,
385396 /// i.e. it's OK if it doesn't start from size 1.
386397 static void checkPartialSizeAndActionsVector(const SizeAndActionsVec& v) {
398 using namespace LegalizeActions;
387399 #ifndef NDEBUG
388400 // The sizes should be in increasing order
389401 int prev_size = -1;
2525 #define DEBUG_TYPE "legalizer"
2626
2727 using namespace llvm;
28 using namespace LegalizeActions;
2829
2930 LegalizerHelper::LegalizerHelper(MachineFunction &MF)
3031 : MRI(MF.getRegInfo()), LI(*MF.getSubtarget().getLegalizerInfo()) {
3738
3839 auto Step = LI.getAction(MI, MRI);
3940 switch (Step.Action) {
40 case LegalizerInfo::Legal:
41 case Legal:
4142 DEBUG(dbgs() << ".. Already legal\n");
4243 return AlreadyLegal;
43 case LegalizerInfo::Libcall:
44 case Libcall:
4445 DEBUG(dbgs() << ".. Convert to libcall\n");
4546 return libcall(MI);
46 case LegalizerInfo::NarrowScalar:
47 case NarrowScalar:
4748 DEBUG(dbgs() << ".. Narrow scalar\n");
4849 return narrowScalar(MI, Step.TypeIdx, Step.NewType);
49 case LegalizerInfo::WidenScalar:
50 case WidenScalar:
5051 DEBUG(dbgs() << ".. Widen scalar\n");
5152 return widenScalar(MI, Step.TypeIdx, Step.NewType);
52 case LegalizerInfo::Lower:
53 case Lower:
5354 DEBUG(dbgs() << ".. Lower\n");
5455 return lower(MI, Step.TypeIdx, Step.NewType);
55 case LegalizerInfo::FewerElements:
56 case FewerElements:
5657 DEBUG(dbgs() << ".. Reduce number of elements\n");
5758 return fewerElementsVector(MI, Step.TypeIdx, Step.NewType);
58 case LegalizerInfo::Custom:
59 case Custom:
5960 DEBUG(dbgs() << ".. Custom legalization\n");
6061 return LI.legalizeCustom(MI, MRI, MIRBuilder) ? Legalized
6162 : UnableToLegalize;
940941 // Lower (G_FSUB LHS, RHS) to (G_FADD LHS, (G_FNEG RHS)).
941942 // First, check if G_FNEG is marked as Lower. If so, we may
942943 // end up with an infinite loop as G_FSUB is used to legalize G_FNEG.
943 if (LI.getAction({G_FNEG, {Ty}}).Action == LegalizerInfo::Lower)
944 if (LI.getAction({G_FNEG, {Ty}}).Action == Lower)
944945 return UnableToLegalize;
945946 unsigned Res = MI.getOperand(0).getReg();
946947 unsigned LHS = MI.getOperand(1).getReg();
2828 #include "llvm/Support/MathExtras.h"
2929 #include
3030 #include
31
3132 using namespace llvm;
33 using namespace LegalizeActions;
3234
3335 LegalizerInfo::LegalizerInfo() : TablesInitialized(false) {
3436 // Set defaults.
161163 // probably going to need specialized lookup structures for various types before
162164 // we have any hope of doing well with something like <13 x i3>. Even the common
163165 // cases should do better than what we have now.
164 std::pairrInfo::LegalizeAction, LLT>
166 std::pairAction, LLT>
165167 LegalizerInfo::getAspectAction(const InstrAspect &Aspect) const {
166168 assert(TablesInitialized && "backend forgot to call computeTables");
167169 // These *have* to be implemented for now, they're the fundamental basis of
325327 llvm_unreachable("Action has an unknown enum value");
326328 }
327329
328 std::pairrInfo::LegalizeAction, LLT>
330 std::pairAction, LLT>
329331 LegalizerInfo::findScalarLegalAction(const InstrAspect &Aspect) const {
330332 assert(Aspect.Type.isScalar() || Aspect.Type.isPointer());
331333 if (Aspect.Opcode < FirstOp || Aspect.Opcode > LastOp)
354356 SizeAndAction.first)};
355357 }
356358
357 std::pairrInfo::LegalizeAction, LLT>
359 std::pairAction, LLT>
358360 LegalizerInfo::findVectorLegalAction(const InstrAspect &Aspect) const {
359361 assert(Aspect.Type.isVector());
360362 // First legalize the vector element size, then legalize the number of
2222 #include "llvm/IR/Type.h"
2323
2424 using namespace llvm;
25 using namespace LegalizeActions;
2526
2627 /// FIXME: The following static functions are SizeChangeStrategy functions
2728 /// that are meant to temporarily mimic the behaviour of the old legalization
3940 result.push_back(v[i]);
4041 if (i + 1 < v[i].first && i + 1 < v.size() &&
4142 v[i + 1].first != v[i].first + 1)
42 result.push_back({v[i].first + 1, LegalizerInfo::Unsupported});
43 result.push_back({v[i].first + 1, Unsupported});
4344 }
4445 }
4546
4748 widen_1_narrow_128_ToLargest(const LegalizerInfo::SizeAndActionsVec &v) {
4849 assert(v.size() >= 1);
4950 assert(v[0].first > 2);
50 LegalizerInfo::SizeAndActionsVec result = {{1, LegalizerInfo::WidenScalar},
51 {2, LegalizerInfo::Unsupported}};
51 LegalizerInfo::SizeAndActionsVec result = {{1, WidenScalar},
52 {2, Unsupported}};
5253 addAndInterleaveWithUnsupported(result, v);
5354 auto Largest = result.back().first;
5455 assert(Largest + 1 < 128);
55 result.push_back({Largest + 1, LegalizerInfo::Unsupported});
56 result.push_back({128, LegalizerInfo::NarrowScalar});
57 result.push_back({129, LegalizerInfo::Unsupported});
56 result.push_back({Largest + 1, Unsupported});
57 result.push_back({128, NarrowScalar});
58 result.push_back({129, Unsupported});
5859 return result;
5960 }
6061
6263 widen_16(const LegalizerInfo::SizeAndActionsVec &v) {
6364 assert(v.size() >= 1);
6465 assert(v[0].first > 17);
65 LegalizerInfo::SizeAndActionsVec result = {{1, LegalizerInfo::Unsupported},
66 {16, LegalizerInfo::WidenScalar},
67 {17, LegalizerInfo::Unsupported}};
68 addAndInterleaveWithUnsupported(result, v);
69 auto Largest = result.back().first;
70 result.push_back({Largest + 1, LegalizerInfo::Unsupported});
66 LegalizerInfo::SizeAndActionsVec result = {{1, Unsupported},
67 {16, WidenScalar},
68 {17, Unsupported}};
69 addAndInterleaveWithUnsupported(result, v);
70 auto Largest = result.back().first;
71 result.push_back({Largest + 1, Unsupported});
7172 return result;
7273 }
7374
7677 assert(v.size() >= 1);
7778 assert(v[0].first > 9);
7879 LegalizerInfo::SizeAndActionsVec result = {
79 {1, LegalizerInfo::WidenScalar}, {2, LegalizerInfo::Unsupported},
80 {8, LegalizerInfo::WidenScalar}, {9, LegalizerInfo::Unsupported}};
81 addAndInterleaveWithUnsupported(result, v);
82 auto Largest = result.back().first;
83 result.push_back({Largest + 1, LegalizerInfo::Unsupported});
80 {1, WidenScalar}, {2, Unsupported},
81 {8, WidenScalar}, {9, Unsupported}};
82 addAndInterleaveWithUnsupported(result, v);
83 auto Largest = result.back().first;
84 result.push_back({Largest + 1, Unsupported});
8485 return result;
8586 }
8687
8990 assert(v.size() >= 1);
9091 assert(v[0].first > 17);
9192 LegalizerInfo::SizeAndActionsVec result = {
92 {1, LegalizerInfo::WidenScalar}, {2, LegalizerInfo::Unsupported},
93 {8, LegalizerInfo::WidenScalar}, {9, LegalizerInfo::Unsupported},
94 {16, LegalizerInfo::WidenScalar}, {17, LegalizerInfo::Unsupported}};
95 addAndInterleaveWithUnsupported(result, v);
96 auto Largest = result.back().first;
97 result.push_back({Largest + 1, LegalizerInfo::Unsupported});
93 {1, WidenScalar}, {2, Unsupported},
94 {8, WidenScalar}, {9, Unsupported},
95 {16, WidenScalar}, {17, Unsupported}};
96 addAndInterleaveWithUnsupported(result, v);
97 auto Largest = result.back().first;
98 result.push_back({Largest + 1, Unsupported});
9899 return result;
99100 }
100101
103104 assert(v.size() >= 1);
104105 assert(v[0].first > 17);
105106 LegalizerInfo::SizeAndActionsVec result = {
106 {1, LegalizerInfo::WidenScalar}, {2, LegalizerInfo::Unsupported},
107 {8, LegalizerInfo::WidenScalar}, {9, LegalizerInfo::Unsupported},
108 {16, LegalizerInfo::WidenScalar}, {17, LegalizerInfo::Unsupported}};
109 addAndInterleaveWithUnsupported(result, v);
110 auto Largest = result.back().first;
111 result.push_back({Largest + 1, LegalizerInfo::NarrowScalar});
107 {1, WidenScalar}, {2, Unsupported},
108 {8, WidenScalar}, {9, Unsupported},
109 {16, WidenScalar}, {17, Unsupported}};
110 addAndInterleaveWithUnsupported(result, v);
111 auto Largest = result.back().first;
112 result.push_back({Largest + 1, NarrowScalar});
112113 return result;
113114 }
114115
117118 assert(v.size() >= 1);
118119 assert(v[0].first > 33);
119120 LegalizerInfo::SizeAndActionsVec result = {
120 {1, LegalizerInfo::WidenScalar}, {2, LegalizerInfo::Unsupported},
121 {8, LegalizerInfo::WidenScalar}, {9, LegalizerInfo::Unsupported},
122 {16, LegalizerInfo::WidenScalar}, {17, LegalizerInfo::Unsupported},
123 {32, LegalizerInfo::WidenScalar}, {33, LegalizerInfo::Unsupported}};
124 addAndInterleaveWithUnsupported(result, v);
125 auto Largest = result.back().first;
126 result.push_back({Largest + 1, LegalizerInfo::Unsupported});
121 {1, WidenScalar}, {2, Unsupported},
122 {8, WidenScalar}, {9, Unsupported},
123 {16, WidenScalar}, {17, Unsupported},
124 {32, WidenScalar}, {33, Unsupported}};
125 addAndInterleaveWithUnsupported(result, v);
126 auto Largest = result.back().first;
127 result.push_back({Largest + 1, Unsupported});
127128 return result;
128129 }
129130
1919 #include "llvm/Support/Debug.h"
2020
2121 using namespace llvm;
22 using namespace LegalizeActions;
2223
2324 AMDGPULegalizerInfo::AMDGPULegalizerInfo() {
2425 using namespace TargetOpcode;
2222 #include "llvm/IR/Type.h"
2323
2424 using namespace llvm;
25 using namespace LegalizeActions;
2526
2627 /// FIXME: The following static functions are SizeChangeStrategy functions
2728 /// that are meant to temporarily mimic the behaviour of the old legalization
3940 result.push_back(v[i]);
4041 if (i + 1 < v[i].first && i + 1 < v.size() &&
4142 v[i + 1].first != v[i].first + 1)
42 result.push_back({v[i].first + 1, LegalizerInfo::Unsupported});
43 result.push_back({v[i].first + 1, Unsupported});
4344 }
4445 }
4546
4748 widen_8_16(const LegalizerInfo::SizeAndActionsVec &v) {
4849 assert(v.size() >= 1);
4950 assert(v[0].first > 17);
50 LegalizerInfo::SizeAndActionsVec result = {
51 {1, LegalizerInfo::Unsupported},
52 {8, LegalizerInfo::WidenScalar}, {9, LegalizerInfo::Unsupported},
53 {16, LegalizerInfo::WidenScalar}, {17, LegalizerInfo::Unsupported}};
51 LegalizerInfo::SizeAndActionsVec result = {{1, Unsupported},
52 {8, WidenScalar},
53 {9, Unsupported},
54 {16, WidenScalar},
55 {17, Unsupported}};
5456 addAndInterleaveWithUnsupported(result, v);
5557 auto Largest = result.back().first;
56 result.push_back({Largest + 1, LegalizerInfo::Unsupported});
58 result.push_back({Largest + 1, Unsupported});
5759 return result;
5860 }
5961
6264 assert(v.size() >= 1);
6365 assert(v[0].first > 17);
6466 LegalizerInfo::SizeAndActionsVec result = {
65 {1, LegalizerInfo::WidenScalar}, {2, LegalizerInfo::Unsupported},
66 {8, LegalizerInfo::WidenScalar}, {9, LegalizerInfo::Unsupported},
67 {16, LegalizerInfo::WidenScalar}, {17, LegalizerInfo::Unsupported}};
67 {1, WidenScalar}, {2, Unsupported},
68 {8, WidenScalar}, {9, Unsupported},
69 {16, WidenScalar}, {17, Unsupported}};
6870 addAndInterleaveWithUnsupported(result, v);
6971 auto Largest = result.back().first;
70 result.push_back({Largest + 1, LegalizerInfo::NarrowScalar});
72 result.push_back({Largest + 1, NarrowScalar});
7173 return result;
7274 }
7375
2020
2121 using namespace llvm;
2222 using namespace TargetOpcode;
23 using namespace LegalizeActions;
2324
2425 /// FIXME: The following static functions are SizeChangeStrategy functions
2526 /// that are meant to temporarily mimic the behaviour of the old legalization
3738 result.push_back(v[i]);
3839 if (i + 1 < v[i].first && i + 1 < v.size() &&
3940 v[i + 1].first != v[i].first + 1)
40 result.push_back({v[i].first + 1, LegalizerInfo::Unsupported});
41 result.push_back({v[i].first + 1, Unsupported});
4142 }
4243 }
4344
4546 widen_1(const LegalizerInfo::SizeAndActionsVec &v) {
4647 assert(v.size() >= 1);
4748 assert(v[0].first > 1);
48 LegalizerInfo::SizeAndActionsVec result = {{1, LegalizerInfo::WidenScalar},
49 {2, LegalizerInfo::Unsupported}};
49 LegalizerInfo::SizeAndActionsVec result = {{1, WidenScalar},
50 {2, Unsupported}};
5051 addAndInterleaveWithUnsupported(result, v);
5152 auto Largest = result.back().first;
52 result.push_back({Largest + 1, LegalizerInfo::Unsupported});
53 result.push_back({Largest + 1, Unsupported});
5354 return result;
5455 }
5556
1111 #include "gtest/gtest.h"
1212
1313 using namespace llvm;
14 using namespace LegalizeActions;
1415
1516 // Define a couple of pretty printers to help debugging when things go wrong.
1617 namespace llvm {
1718 std::ostream &
18 operator<<(std::ostream &OS, const llvm::LegalizerInfo::LegalizeAction Act) {
19 operator<<(std::ostream &OS, const LegalizeAction Act) {
1920 switch (Act) {
20 case LegalizerInfo::Lower: OS << "Lower"; break;
21 case LegalizerInfo::Legal: OS << "Legal"; break;
22 case LegalizerInfo::NarrowScalar: OS << "NarrowScalar"; break;
23 case LegalizerInfo::WidenScalar: OS << "WidenScalar"; break;
24 case LegalizerInfo::FewerElements: OS << "FewerElements"; break;
25 case LegalizerInfo::MoreElements: OS << "MoreElements"; break;
26 case LegalizerInfo::Libcall: OS << "Libcall"; break;
27 case LegalizerInfo::Custom: OS << "Custom"; break;
28 case LegalizerInfo::Unsupported: OS << "Unsupported"; break;
29 case LegalizerInfo::NotFound: OS << "NotFound";
21 case Lower: OS << "Lower"; break;
22 case Legal: OS << "Legal"; break;
23 case NarrowScalar: OS << "NarrowScalar"; break;
24 case WidenScalar: OS << "WidenScalar"; break;
25 case FewerElements: OS << "FewerElements"; break;
26 case MoreElements: OS << "MoreElements"; break;
27 case Libcall: OS << "Libcall"; break;
28 case Custom: OS << "Custom"; break;
29 case Unsupported: OS << "Unsupported"; break;
30 case NotFound: OS << "NotFound";
3031 }
3132 return OS;
3233 }
5051 // Typical RISCy set of operations based on AArch64.
5152 for (unsigned Op : {G_ADD, G_SUB}) {
5253 for (unsigned Size : {32, 64})
53 L.setAction({Op, 0, LLT::scalar(Size)}, LegalizerInfo::Legal);
54 L.setAction({Op, 0, LLT::scalar(Size)}, Legal);
5455 L.setLegalizeScalarToDifferentSizeStrategy(
5556 Op, 0, LegalizerInfo::widenToLargerTypesAndNarrowToLargest);
5657 }
6061 for (unsigned opcode : {G_ADD, G_SUB}) {
6162 // Check we infer the correct types and actually do what we're told.
6263 ASSERT_EQ(L.getAction({opcode, {LLT::scalar(8)}}),
63 LegalizerInfo::LegalizeActionStep(LegalizerInfo::WidenScalar, 0,
64 LLT::scalar(32)));
64 LegalizerInfo::LegalizeActionStep(WidenScalar, 0, LLT::scalar(32)));
6565 ASSERT_EQ(L.getAction({opcode, {LLT::scalar(16)}}),
66 LegalizerInfo::LegalizeActionStep(LegalizerInfo::WidenScalar, 0,
67 LLT::scalar(32)));
68 ASSERT_EQ(
69 L.getAction({opcode, {LLT::scalar(32)}}),
70 LegalizerInfo::LegalizeActionStep(LegalizerInfo::Legal, 0, LLT{}));
71 ASSERT_EQ(
72 L.getAction({opcode, {LLT::scalar(64)}}),
73 LegalizerInfo::LegalizeActionStep(LegalizerInfo::Legal, 0, LLT{}));
66 LegalizerInfo::LegalizeActionStep(WidenScalar, 0, LLT::scalar(32)));
67 ASSERT_EQ(L.getAction({opcode, {LLT::scalar(32)}}),
68 LegalizerInfo::LegalizeActionStep(Legal, 0, LLT{}));
69 ASSERT_EQ(L.getAction({opcode, {LLT::scalar(64)}}),
70 LegalizerInfo::LegalizeActionStep(Legal, 0, LLT{}));
7471
7572 // Make sure the default for over-sized types applies.
76 ASSERT_EQ(L.getAction({opcode, {LLT::scalar(128)}}),
77 LegalizerInfo::LegalizeActionStep(LegalizerInfo::NarrowScalar, 0,
78 LLT::scalar(64)));
73 ASSERT_EQ(
74 L.getAction({opcode, {LLT::scalar(128)}}),
75 LegalizerInfo::LegalizeActionStep(NarrowScalar, 0, LLT::scalar(64)));
7976 // Make sure we also handle unusual sizes
80 ASSERT_EQ(L.getAction({opcode, {LLT::scalar(1)}}),
81 LegalizerInfo::LegalizeActionStep(LegalizerInfo::WidenScalar, 0,
82 LLT::scalar(32)));
83 ASSERT_EQ(L.getAction({opcode, {LLT::scalar(31)}}),
84 LegalizerInfo::LegalizeActionStep(LegalizerInfo::WidenScalar, 0,
85 LLT::scalar(32)));
86 ASSERT_EQ(L.getAction({opcode, {LLT::scalar(33)}}),
87 LegalizerInfo::LegalizeActionStep(LegalizerInfo::WidenScalar, 0,
88 LLT::scalar(64)));
89 ASSERT_EQ(L.getAction({opcode, {LLT::scalar(63)}}),
90 LegalizerInfo::LegalizeActionStep(LegalizerInfo::WidenScalar, 0,
91 LLT::scalar(64)));
92 ASSERT_EQ(L.getAction({opcode, {LLT::scalar(65)}}),
93 LegalizerInfo::LegalizeActionStep(LegalizerInfo::NarrowScalar, 0,
94 LLT::scalar(64)));
77 ASSERT_EQ(
78 L.getAction({opcode, {LLT::scalar(1)}}),
79 LegalizerInfo::LegalizeActionStep(WidenScalar, 0, LLT::scalar(32)));
80 ASSERT_EQ(
81 L.getAction({opcode, {LLT::scalar(31)}}),
82 LegalizerInfo::LegalizeActionStep(WidenScalar, 0, LLT::scalar(32)));
83 ASSERT_EQ(
84 L.getAction({opcode, {LLT::scalar(33)}}),
85 LegalizerInfo::LegalizeActionStep(WidenScalar, 0, LLT::scalar(64)));
86 ASSERT_EQ(
87 L.getAction({opcode, {LLT::scalar(63)}}),
88 LegalizerInfo::LegalizeActionStep(WidenScalar, 0, LLT::scalar(64)));
89 ASSERT_EQ(
90 L.getAction({opcode, {LLT::scalar(65)}}),
91 LegalizerInfo::LegalizeActionStep(NarrowScalar, 0, LLT::scalar(64)));
9592 }
9693 }
9794
9996 using namespace TargetOpcode;
10097 LegalizerInfo L;
10198 // Typical RISCy set of operations based on ARM.
102 L.setAction({G_ADD, LLT::vector(8, 8)}, LegalizerInfo::Legal);
103 L.setAction({G_ADD, LLT::vector(16, 8)}, LegalizerInfo::Legal);
104 L.setAction({G_ADD, LLT::vector(4, 16)}, LegalizerInfo::Legal);
105 L.setAction({G_ADD, LLT::vector(8, 16)}, LegalizerInfo::Legal);
106 L.setAction({G_ADD, LLT::vector(2, 32)}, LegalizerInfo::Legal);
107 L.setAction({G_ADD, LLT::vector(4, 32)}, LegalizerInfo::Legal);
99 L.setAction({G_ADD, LLT::vector(8, 8)}, Legal);
100 L.setAction({G_ADD, LLT::vector(16, 8)}, Legal);
101 L.setAction({G_ADD, LLT::vector(4, 16)}, Legal);
102 L.setAction({G_ADD, LLT::vector(8, 16)}, Legal);
103 L.setAction({G_ADD, LLT::vector(2, 32)}, Legal);
104 L.setAction({G_ADD, LLT::vector(4, 32)}, Legal);
108105
109106 L.setLegalizeVectorElementToDifferentSizeStrategy(
110107 G_ADD, 0, LegalizerInfo::widenToLargerTypesUnsupportedOtherwise);
111108
112 L.setAction({G_ADD, 0, LLT::scalar(32)}, LegalizerInfo::Legal);
109 L.setAction({G_ADD, 0, LLT::scalar(32)}, Legal);
113110
114111 L.computeTables();
115112
116113 // Check we infer the correct types and actually do what we're told for some
117114 // simple cases.
118115 ASSERT_EQ(L.getAction({G_ADD, {LLT::vector(8, 8)}}),
119 LegalizerInfo::LegalizeActionStep(LegalizerInfo::Legal, 0, LLT{}));
120 ASSERT_EQ(L.getAction({G_ADD, {LLT::vector(8, 7)}}),
121 LegalizerInfo::LegalizeActionStep(LegalizerInfo::WidenScalar, 0,
122 LLT::vector(8, 8)));
123 ASSERT_EQ(L.getAction({G_ADD, {LLT::vector(2, 8)}}),
124 LegalizerInfo::LegalizeActionStep(LegalizerInfo::MoreElements, 0,
125 LLT::vector(8, 8)));
126 ASSERT_EQ(L.getAction({G_ADD, {LLT::vector(8, 32)}}),
127 LegalizerInfo::LegalizeActionStep(LegalizerInfo::FewerElements, 0,
128 LLT::vector(4, 32)));
116 LegalizerInfo::LegalizeActionStep(Legal, 0, LLT{}));
117 ASSERT_EQ(
118 L.getAction({G_ADD, {LLT::vector(8, 7)}}),
119 LegalizerInfo::LegalizeActionStep(WidenScalar, 0, LLT::vector(8, 8)));
120 ASSERT_EQ(
121 L.getAction({G_ADD, {LLT::vector(2, 8)}}),
122 LegalizerInfo::LegalizeActionStep(MoreElements, 0, LLT::vector(8, 8)));
123 ASSERT_EQ(
124 L.getAction({G_ADD, {LLT::vector(8, 32)}}),
125 LegalizerInfo::LegalizeActionStep(FewerElements, 0, LLT::vector(4, 32)));
129126 // Check a few non-power-of-2 sizes:
130 ASSERT_EQ(L.getAction({G_ADD, {LLT::vector(3, 3)}}),
131 LegalizerInfo::LegalizeActionStep(LegalizerInfo::WidenScalar, 0,
132 LLT::vector(3, 8)));
133 ASSERT_EQ(L.getAction({G_ADD, {LLT::vector(3, 8)}}),
134 LegalizerInfo::LegalizeActionStep(LegalizerInfo::MoreElements, 0,
135 LLT::vector(8, 8)));
127 ASSERT_EQ(
128 L.getAction({G_ADD, {LLT::vector(3, 3)}}),
129 LegalizerInfo::LegalizeActionStep(WidenScalar, 0, LLT::vector(3, 8)));
130 ASSERT_EQ(
131 L.getAction({G_ADD, {LLT::vector(3, 8)}}),
132 LegalizerInfo::LegalizeActionStep(MoreElements, 0, LLT::vector(8, 8)));
136133 }
137134
138135 TEST(LegalizerInfoTest, MultipleTypes) {
142139 LLT s64 = LLT::scalar(64);
143140
144141 // Typical RISCy set of operations based on AArch64.
145 L.setAction({G_PTRTOINT, 0, s64}, LegalizerInfo::Legal);
146 L.setAction({G_PTRTOINT, 1, p0}, LegalizerInfo::Legal);
142 L.setAction({G_PTRTOINT, 0, s64}, Legal);
143 L.setAction({G_PTRTOINT, 1, p0}, Legal);
147144
148145 L.setLegalizeScalarToDifferentSizeStrategy(
149146 G_PTRTOINT, 0, LegalizerInfo::widenToLargerTypesAndNarrowToLargest);
152149
153150 // Check we infer the correct types and actually do what we're told.
154151 ASSERT_EQ(L.getAction({G_PTRTOINT, {s64, p0}}),
155 LegalizerInfo::LegalizeActionStep(LegalizerInfo::Legal, 0, LLT{}));
152 LegalizerInfo::LegalizeActionStep(Legal, 0, LLT{}));
156153
157154 // Make sure we also handle unusual sizes
158155 ASSERT_EQ(
159156 L.getAction({G_PTRTOINT, {LLT::scalar(65), s64}}),
160 LegalizerInfo::LegalizeActionStep(LegalizerInfo::NarrowScalar, 0, s64));
161 ASSERT_EQ(L.getAction({G_PTRTOINT, {s64, LLT::pointer(0, 32)}}),
162 LegalizerInfo::LegalizeActionStep(LegalizerInfo::Unsupported, 1,
163 LLT::pointer(0, 32)));
157 LegalizerInfo::LegalizeActionStep(NarrowScalar, 0, s64));
158 ASSERT_EQ(
159 L.getAction({G_PTRTOINT, {s64, LLT::pointer(0, 32)}}),
160 LegalizerInfo::LegalizeActionStep(Unsupported, 1, LLT::pointer(0, 32)));
164161 }
165162
166163 TEST(LegalizerInfoTest, MultipleSteps) {
171168
172169 L.setLegalizeScalarToDifferentSizeStrategy(
173170 G_UREM, 0, LegalizerInfo::widenToLargerTypesUnsupportedOtherwise);
174 L.setAction({G_UREM, 0, s32}, LegalizerInfo::Lower);
175 L.setAction({G_UREM, 0, s64}, LegalizerInfo::Lower);
171 L.setAction({G_UREM, 0, s32}, Lower);
172 L.setAction({G_UREM, 0, s64}, Lower);
176173
177174 L.computeTables();
178175
179176 ASSERT_EQ(L.getAction({G_UREM, {LLT::scalar(16)}}),
180 LegalizerInfo::LegalizeActionStep(LegalizerInfo::WidenScalar, 0,
181 LLT::scalar(32)));
177 LegalizerInfo::LegalizeActionStep(WidenScalar, 0, LLT::scalar(32)));
182178 ASSERT_EQ(L.getAction({G_UREM, {LLT::scalar(32)}}),
183 LegalizerInfo::LegalizeActionStep(LegalizerInfo::Lower, 0,
184 LLT::scalar(32)));
179 LegalizerInfo::LegalizeActionStep(Lower, 0, LLT::scalar(32)));
185180 }
186181
187182 TEST(LegalizerInfoTest, SizeChangeStrategy) {
188183 using namespace TargetOpcode;
189184 LegalizerInfo L;
190185 for (unsigned Size : {1, 8, 16, 32})
191 L.setAction({G_UREM, 0, LLT::scalar(Size)}, LegalizerInfo::Legal);
186 L.setAction({G_UREM, 0, LLT::scalar(Size)}, Legal);
192187
193188 L.setLegalizeScalarToDifferentSizeStrategy(
194189 G_UREM, 0, LegalizerInfo::widenToLargerTypesUnsupportedOtherwise);
196191
197192 // Check we infer the correct types and actually do what we're told.
198193 for (unsigned Size : {1, 8, 16, 32}) {
199 ASSERT_EQ(
200 L.getAction({G_UREM, {LLT::scalar(Size)}}),
201 LegalizerInfo::LegalizeActionStep(LegalizerInfo::Legal, 0, LLT{}));
194 ASSERT_EQ(L.getAction({G_UREM, {LLT::scalar(Size)}}),
195 LegalizerInfo::LegalizeActionStep(Legal, 0, LLT{}));
202196 }
203197 ASSERT_EQ(L.getAction({G_UREM, {LLT::scalar(2)}}),
204 LegalizerInfo::LegalizeActionStep(LegalizerInfo::WidenScalar, 0,
205 LLT::scalar(8)));
198 LegalizerInfo::LegalizeActionStep(WidenScalar, 0, LLT::scalar(8)));
206199 ASSERT_EQ(L.getAction({G_UREM, {LLT::scalar(7)}}),
207 LegalizerInfo::LegalizeActionStep(LegalizerInfo::WidenScalar, 0,
208 LLT::scalar(8)));
200 LegalizerInfo::LegalizeActionStep(WidenScalar, 0, LLT::scalar(8)));
209201 ASSERT_EQ(L.getAction({G_UREM, {LLT::scalar(9)}}),
210 LegalizerInfo::LegalizeActionStep(LegalizerInfo::WidenScalar, 0,
211 LLT::scalar(16)));
202 LegalizerInfo::LegalizeActionStep(WidenScalar, 0, LLT::scalar(16)));
212203 ASSERT_EQ(L.getAction({G_UREM, {LLT::scalar(17)}}),
213 LegalizerInfo::LegalizeActionStep(LegalizerInfo::WidenScalar, 0,
214 LLT::scalar(32)));
204 LegalizerInfo::LegalizeActionStep(WidenScalar, 0, LLT::scalar(32)));
215205 ASSERT_EQ(L.getAction({G_UREM, {LLT::scalar(31)}}),
216 LegalizerInfo::LegalizeActionStep(LegalizerInfo::WidenScalar, 0,
217 LLT::scalar(32)));
206 LegalizerInfo::LegalizeActionStep(WidenScalar, 0, LLT::scalar(32)));
218207 ASSERT_EQ(L.getAction({G_UREM, {LLT::scalar(33)}}),
219 LegalizerInfo::LegalizeActionStep(LegalizerInfo::Unsupported, 0,
220 LLT::scalar(33)));
221 }
222 }
208 LegalizerInfo::LegalizeActionStep(Unsupported, 0, LLT::scalar(33)));
209 }
210 }