blob: 0e881759656d9533cb56c14b7d6c558c175e1503 [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.
52 L.setAction({G_ADD, LLT::scalar(8)}, LegalizerInfo::WidenScalar);
53 L.setAction({G_ADD, LLT::scalar(16)}, LegalizerInfo::WidenScalar);
54 L.setAction({G_ADD, LLT::scalar(32)}, LegalizerInfo::Legal);
55 L.setAction({G_ADD, LLT::scalar(64)}, LegalizerInfo::Legal);
56 L.computeTables();
57
58 // Check we infer the correct types and actually do what we're told.
59 ASSERT_EQ(L.getAction({G_ADD, LLT::scalar(8)}),
60 std::make_pair(LegalizerInfo::WidenScalar, LLT::scalar(32)));
61 ASSERT_EQ(L.getAction({G_ADD, LLT::scalar(16)}),
62 std::make_pair(LegalizerInfo::WidenScalar, LLT::scalar(32)));
63 ASSERT_EQ(L.getAction({G_ADD, LLT::scalar(32)}),
64 std::make_pair(LegalizerInfo::Legal, LLT::scalar(32)));
65 ASSERT_EQ(L.getAction({G_ADD, LLT::scalar(64)}),
66 std::make_pair(LegalizerInfo::Legal, LLT::scalar(64)));
67
68 // Make sure the default for over-sized types applies.
69 ASSERT_EQ(L.getAction({G_ADD, LLT::scalar(128)}),
70 std::make_pair(LegalizerInfo::NarrowScalar, LLT::scalar(64)));
71}
72
73TEST(LegalizerInfoTest, VectorRISC) {
74 using namespace TargetOpcode;
75 LegalizerInfo L;
76 // Typical RISCy set of operations based on ARM.
77 L.setScalarInVectorAction(G_ADD, LLT::scalar(8), LegalizerInfo::Legal);
78 L.setScalarInVectorAction(G_ADD, LLT::scalar(16), LegalizerInfo::Legal);
79 L.setScalarInVectorAction(G_ADD, LLT::scalar(32), LegalizerInfo::Legal);
80
81 L.setAction({G_ADD, LLT::vector(8, 8)}, LegalizerInfo::Legal);
82 L.setAction({G_ADD, LLT::vector(16, 8)}, LegalizerInfo::Legal);
83 L.setAction({G_ADD, LLT::vector(4, 16)}, LegalizerInfo::Legal);
84 L.setAction({G_ADD, LLT::vector(8, 16)}, LegalizerInfo::Legal);
85 L.setAction({G_ADD, LLT::vector(2, 32)}, LegalizerInfo::Legal);
86 L.setAction({G_ADD, LLT::vector(4, 32)}, LegalizerInfo::Legal);
87 L.computeTables();
88
89 // Check we infer the correct types and actually do what we're told for some
90 // simple cases.
91 ASSERT_EQ(L.getAction({G_ADD, LLT::vector(2, 8)}),
92 std::make_pair(LegalizerInfo::MoreElements, LLT::vector(8, 8)));
93 ASSERT_EQ(L.getAction({G_ADD, LLT::vector(8, 8)}),
94 std::make_pair(LegalizerInfo::Legal, LLT::vector(8, 8)));
95 ASSERT_EQ(
96 L.getAction({G_ADD, LLT::vector(8, 32)}),
97 std::make_pair(LegalizerInfo::FewerElements, LLT::vector(4, 32)));
98}
99
100TEST(LegalizerInfoTest, MultipleTypes) {
101 using namespace TargetOpcode;
102 LegalizerInfo L;
103 LLT p0 = LLT::pointer(0, 64);
104 LLT s32 = LLT::scalar(32);
105 LLT s64 = LLT::scalar(64);
106
107 // Typical RISCy set of operations based on AArch64.
108 L.setAction({G_PTRTOINT, 0, s64}, LegalizerInfo::Legal);
109 L.setAction({G_PTRTOINT, 1, p0}, LegalizerInfo::Legal);
110
111 L.setAction({G_PTRTOINT, 0, s32}, LegalizerInfo::WidenScalar);
112 L.computeTables();
113
114 // Check we infer the correct types and actually do what we're told.
115 ASSERT_EQ(L.getAction({G_PTRTOINT, 0, s64}),
116 std::make_pair(LegalizerInfo::Legal, s64));
117 ASSERT_EQ(L.getAction({G_PTRTOINT, 1, p0}),
118 std::make_pair(LegalizerInfo::Legal, p0));
119}
Kristof Beylsb539ea52017-06-30 08:26:20 +0000120
121TEST(LegalizerInfoTest, MultipleSteps) {
122 using namespace TargetOpcode;
123 LegalizerInfo L;
124 LLT s16 = LLT::scalar(16);
125 LLT s32 = LLT::scalar(32);
126 LLT s64 = LLT::scalar(64);
127
128 L.setAction({G_UREM, 0, s16}, LegalizerInfo::WidenScalar);
129 L.setAction({G_UREM, 0, s32}, LegalizerInfo::Lower);
130 L.setAction({G_UREM, 0, s64}, LegalizerInfo::Lower);
131
132 L.computeTables();
133
134 ASSERT_EQ(L.getAction({G_UREM, LLT::scalar(16)}),
135 std::make_pair(LegalizerInfo::WidenScalar, LLT::scalar(32)));
136 ASSERT_EQ(L.getAction({G_UREM, LLT::scalar(32)}),
137 std::make_pair(LegalizerInfo::Lower, LLT::scalar(32)));
138}
Tim Northover69fa84a2016-10-14 22:18:18 +0000139}