xref: /llvm-project/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp (revision c0333f7184d09db6e89215d5672183bc6547d23e)
1 //===- PatternMatchTest.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 "LegalizerHelperTest.h"
11 
12 namespace {
13 
14 // Test CTTZ expansion when CTTZ_ZERO_UNDEF is legal or custom,
15 // in which case it becomes CTTZ_ZERO_UNDEF with select.
16 TEST_F(LegalizerHelperTest, LowerBitCountingCTTZ0) {
17   if (!TM)
18     return;
19 
20   // Declare your legalization info
21   DefineLegalizerInfo(
22       A, { getActionDefinitionsBuilder(G_CTTZ_ZERO_UNDEF).legalFor({s64}); });
23   // Build Instr
24   auto MIBCTTZ = B.buildInstr(TargetOpcode::G_CTTZ, LLT::scalar(64), Copies[0]);
25   AInfo Info(MF->getSubtarget());
26   LegalizerHelper Helper(*MF, Info);
27   // Perform Legalization
28   ASSERT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) ==
29               LegalizerHelper::LegalizeResult::Legalized);
30 
31   auto CheckStr = R"(
32   CHECK: [[CZU:%[0-9]+]]:_(s64) = G_CTTZ_ZERO_UNDEF %0
33   CHECK: [[ZERO:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
34   CHECK: [[SIXTY4:%[0-9]+]]:_(s64) = G_CONSTANT i64 64
35   CHECK: [[CMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), %0:_(s64), [[ZERO]]
36   CHECK: [[SEL:%[0-9]+]]:_(s64) = G_SELECT [[CMP]]:_(s1), [[SIXTY4]]:_, [[CZU]]
37   )";
38 
39   // Check
40   ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
41 }
42 
43 // CTTZ expansion in terms of CTLZ
44 TEST_F(LegalizerHelperTest, LowerBitCountingCTTZ1) {
45   if (!TM)
46     return;
47 
48   // Declare your legalization info
49   DefineLegalizerInfo(A,
50                       { getActionDefinitionsBuilder(G_CTLZ).legalFor({s64}); });
51   // Build Instr
52   auto MIBCTTZ = B.buildInstr(TargetOpcode::G_CTTZ, LLT::scalar(64), Copies[0]);
53   AInfo Info(MF->getSubtarget());
54   LegalizerHelper Helper(*MF, Info);
55   // Perform Legalization
56   ASSERT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) ==
57               LegalizerHelper::LegalizeResult::Legalized);
58 
59   auto CheckStr = R"(
60   CHECK: [[NEG1:%[0-9]+]]:_(s64) = G_CONSTANT i64 -1
61   CHECK: [[NOT:%[0-9]+]]:_(s64) = G_XOR %0:_, [[NEG1]]
62   CHECK: [[SUB1:%[0-9]+]]:_(s64) = G_ADD %0:_, [[NEG1]]
63   CHECK: [[AND1:%[0-9]+]]:_(s64) = G_AND [[NOT]]:_, [[SUB1]]:_
64   CHECK: [[CST64:%[0-9]+]]:_(s64) = G_CONSTANT i64 64
65   CHECK: [[CTLZ:%[0-9]+]]:_(s64) = G_CTLZ [[AND1]]:_
66   CHECK: G_SUB [[CST64]]:_, [[CTLZ]]:_
67   )";
68 
69   // Check
70   ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
71 }
72 
73 // CTTZ expansion in terms of CTPOP
74 TEST_F(LegalizerHelperTest, LowerBitCountingCTTZ2) {
75   if (!TM)
76     return;
77 
78   // Declare your legalization info
79   DefineLegalizerInfo(
80       A, { getActionDefinitionsBuilder(G_CTPOP).legalFor({s64}); });
81   // Build
82   auto MIBCTTZ = B.buildInstr(TargetOpcode::G_CTTZ, LLT::scalar(64), Copies[0]);
83   AInfo Info(MF->getSubtarget());
84   LegalizerHelper Helper(*MF, Info);
85   ASSERT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) ==
86               LegalizerHelper::LegalizeResult::Legalized);
87 
88   auto CheckStr = R"(
89   CHECK: [[NEG1:%[0-9]+]]:_(s64) = G_CONSTANT i64 -1
90   CHECK: [[NOT:%[0-9]+]]:_(s64) = G_XOR %0:_, [[NEG1]]
91   CHECK: [[SUB1:%[0-9]+]]:_(s64) = G_ADD %0:_, [[NEG1]]
92   CHECK: [[AND1:%[0-9]+]]:_(s64) = G_AND [[NOT]]:_, [[SUB1]]:_
93   CHECK: [[POP:%[0-9]+]]:_(s64) = G_CTPOP [[AND1]]
94   )";
95 
96   // Check
97   ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
98 }
99 
100 // CTTZ_ZERO_UNDEF expansion in terms of CTTZ
101 TEST_F(LegalizerHelperTest, LowerBitCountingCTTZ3) {
102   if (!TM)
103     return;
104 
105   // Declare your legalization info
106   DefineLegalizerInfo(A,
107                       { getActionDefinitionsBuilder(G_CTTZ).legalFor({s64}); });
108   // Build
109   auto MIBCTTZ =
110       B.buildInstr(TargetOpcode::G_CTTZ_ZERO_UNDEF, LLT::scalar(64), Copies[0]);
111   AInfo Info(MF->getSubtarget());
112   LegalizerHelper Helper(*MF, Info);
113   ASSERT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) ==
114               LegalizerHelper::LegalizeResult::Legalized);
115 
116   auto CheckStr = R"(
117   CHECK: CTTZ
118   )";
119 
120   // Check
121   ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
122 }
123 
124 // CTLZ expansion in terms of CTLZ_ZERO_UNDEF
125 TEST_F(LegalizerHelperTest, LowerBitCountingCTLZ0) {
126   if (!TM)
127     return;
128 
129   // Declare your legalization info
130   DefineLegalizerInfo(
131       A, { getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF).legalFor({s64}); });
132   // Build
133   auto MIBCTLZ = B.buildInstr(TargetOpcode::G_CTLZ, LLT::scalar(64), Copies[0]);
134   AInfo Info(MF->getSubtarget());
135   LegalizerHelper Helper(*MF, Info);
136   ASSERT_TRUE(Helper.lower(*MIBCTLZ, 0, LLT::scalar(64)) ==
137               LegalizerHelper::LegalizeResult::Legalized);
138 
139   auto CheckStr = R"(
140   CHECK: [[CZU:%[0-9]+]]:_(s64) = G_CTLZ_ZERO_UNDEF %0
141   CHECK: [[ZERO:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
142   CHECK: [[SIXTY4:%[0-9]+]]:_(s64) = G_CONSTANT i64 64
143   CHECK: [[CMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), %0:_(s64), [[ZERO]]
144   CHECK: [[SEL:%[0-9]+]]:_(s64) = G_SELECT [[CMP]]:_(s1), [[SIXTY4]]:_, [[CZU]]
145   )";
146 
147   // Check
148   ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
149 }
150 
151 // CTLZ expansion
152 TEST_F(LegalizerHelperTest, LowerBitCountingCTLZ1) {
153   if (!TM)
154     return;
155 
156   // Declare your legalization info
157   DefineLegalizerInfo(A,
158                       { getActionDefinitionsBuilder(G_CTPOP).legalFor({s8}); });
159   // Build
160   // Trunc it to s8.
161   LLT s8{LLT::scalar(8)};
162   auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
163   auto MIBCTLZ = B.buildInstr(TargetOpcode::G_CTLZ, s8, MIBTrunc);
164   AInfo Info(MF->getSubtarget());
165   LegalizerHelper Helper(*MF, Info);
166   ASSERT_TRUE(Helper.lower(*MIBCTLZ, 0, s8) ==
167               LegalizerHelper::LegalizeResult::Legalized);
168 
169   auto CheckStr = R"(
170   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
171   CHECK: [[Cst1:%[0-9]+]]:_(s8) = G_CONSTANT i8 1
172   CHECK: [[Sh1:%[0-9]+]]:_(s8) = G_LSHR [[Trunc]]:_, [[Cst1]]:_
173   CHECK: [[Or1:%[0-9]+]]:_(s8) = G_OR [[Trunc]]:_, [[Sh1]]:_
174   CHECK: [[Cst2:%[0-9]+]]:_(s8) = G_CONSTANT i8 2
175   CHECK: [[Sh2:%[0-9]+]]:_(s8) = G_LSHR [[Or1]]:_, [[Cst2]]:_
176   CHECK: [[Or2:%[0-9]+]]:_(s8) = G_OR [[Or1]]:_, [[Sh2]]:_
177   CHECK: [[Cst4:%[0-9]+]]:_(s8) = G_CONSTANT i8 4
178   CHECK: [[Sh4:%[0-9]+]]:_(s8) = G_LSHR [[Or2]]:_, [[Cst4]]:_
179   CHECK: [[Or4:%[0-9]+]]:_(s8) = G_OR [[Or2]]:_, [[Sh4]]:_
180   CHECK: [[CTPOP:%[0-9]+]]:_(s8) = G_CTPOP [[Or4]]:_
181   CHECK: [[Len:%[0-9]+]]:_(s8) = G_CONSTANT i8 8
182   CHECK: [[Sub:%[0-9]+]]:_(s8) = G_SUB [[Len]]:_, [[CTPOP]]:_
183   )";
184 
185   // Check
186   ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
187 }
188 } // namespace
189