@@ -23,6 +23,162 @@ class DummyGISelObserver : public GISelChangeObserver {
23
23
void erasingInstr (MachineInstr &MI) override {}
24
24
};
25
25
26
+ // Test G_ROTL/G_ROTR lowering.
27
+ TEST_F (AArch64GISelMITest, LowerRotates) {
28
+ setUp ();
29
+ if (!TM)
30
+ return ;
31
+
32
+ // Declare your legalization info
33
+ DefineLegalizerInfo (A, {
34
+ getActionDefinitionsBuilder ({G_ROTR, G_ROTL}).lower (); });
35
+
36
+ LLT S32 = LLT::scalar (32 );
37
+ auto Src = B.buildTrunc (S32, Copies[0 ]);
38
+ auto Amt = B.buildTrunc (S32, Copies[1 ]);
39
+ auto ROTR = B.buildInstr (TargetOpcode::G_ROTR, {S32}, {Src, Amt});
40
+ auto ROTL = B.buildInstr (TargetOpcode::G_ROTL, {S32}, {Src, Amt});
41
+
42
+ AInfo Info (MF->getSubtarget ());
43
+ DummyGISelObserver Observer;
44
+ LegalizerHelper Helper (*MF, Info, Observer, B);
45
+ // Perform Legalization
46
+ EXPECT_EQ (LegalizerHelper::LegalizeResult::Legalized,
47
+ Helper.lower (*ROTR, 0 , S32));
48
+ EXPECT_EQ (LegalizerHelper::LegalizeResult::Legalized,
49
+ Helper.lower (*ROTL, 0 , S32));
50
+
51
+ auto CheckStr = R"(
52
+ ; Check G_ROTR
53
+ CHECK: [[SRC:%[0-9]+]]:_(s32) = G_TRUNC
54
+ CHECK: [[AMT:%[0-9]+]]:_(s32) = G_TRUNC
55
+ CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
56
+ CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 31
57
+ CHECK: [[SUB:%[0-9]+]]:_(s32) = G_SUB [[C]]:_, [[AMT]]:_
58
+ CHECK: [[AND:%[0-9]+]]:_(s32) = G_AND [[AMT]]:_, [[C1]]:_
59
+ CHECK: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[SRC]]:_, [[AND]]:_(s32)
60
+ CHECK: [[AND1:%[0-9]+]]:_(s32) = G_AND [[SUB]]:_, [[C1]]:_
61
+ CHECK: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[SRC]]:_, [[AND1]]:_(s32)
62
+ CHECK: G_OR [[LSHR]]:_, [[SHL]]:_
63
+
64
+ ; Check G_ROTL
65
+ CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
66
+ CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 31
67
+ CHECK: [[SUB:%[0-9]+]]:_(s32) = G_SUB [[C]]:_, [[AMT]]:_
68
+ CHECK: [[AND:%[0-9]+]]:_(s32) = G_AND [[AMT]]:_, [[C1]]:_
69
+ CHECK: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[SRC]]:_, [[AND]]:_(s32)
70
+ CHECK: [[AND1:%[0-9]+]]:_(s32) = G_AND [[SUB]]:_, [[C1]]:_
71
+ CHECK: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[SRC]]:_, [[AND1]]:_(s32)
72
+ CHECK: G_OR [[SHL]]:_, [[LSHR]]:_
73
+ )" ;
74
+
75
+ // Check
76
+ EXPECT_TRUE (CheckMachineFunction (*MF, CheckStr)) << *MF;
77
+ }
78
+
79
+ // Test G_ROTL/G_ROTR non-pow2 lowering.
80
+ TEST_F (AArch64GISelMITest, LowerRotatesNonPow2) {
81
+ setUp ();
82
+ if (!TM)
83
+ return ;
84
+
85
+ // Declare your legalization info
86
+ DefineLegalizerInfo (A, {
87
+ getActionDefinitionsBuilder ({G_ROTR, G_ROTL}).lower (); });
88
+
89
+ LLT S24 = LLT::scalar (24 );
90
+ auto Src = B.buildTrunc (S24, Copies[0 ]);
91
+ auto Amt = B.buildTrunc (S24, Copies[1 ]);
92
+ auto ROTR = B.buildInstr (TargetOpcode::G_ROTR, {S24}, {Src, Amt});
93
+ auto ROTL = B.buildInstr (TargetOpcode::G_ROTL, {S24}, {Src, Amt});
94
+
95
+ AInfo Info (MF->getSubtarget ());
96
+ DummyGISelObserver Observer;
97
+ LegalizerHelper Helper (*MF, Info, Observer, B);
98
+ // Perform Legalization
99
+ EXPECT_EQ (LegalizerHelper::LegalizeResult::Legalized,
100
+ Helper.lower (*ROTR, 0 , S24));
101
+ EXPECT_EQ (LegalizerHelper::LegalizeResult::Legalized,
102
+ Helper.lower (*ROTL, 0 , S24));
103
+
104
+ auto CheckStr = R"(
105
+ ; Check G_ROTR
106
+ CHECK: [[SRC:%[0-9]+]]:_(s24) = G_TRUNC
107
+ CHECK: [[AMT:%[0-9]+]]:_(s24) = G_TRUNC
108
+ CHECK: [[C:%[0-9]+]]:_(s24) = G_CONSTANT i24 0
109
+ CHECK: [[C1:%[0-9]+]]:_(s24) = G_CONSTANT i24 23
110
+ CHECK: [[C2:%[0-9]+]]:_(s24) = G_CONSTANT i24 24
111
+ CHECK: [[UREM:%[0-9]+]]:_(s24) = G_UREM [[AMT]]:_, [[C2]]:_
112
+ CHECK: [[LSHR:%[0-9]+]]:_(s24) = G_LSHR [[SRC]]:_, [[UREM]]:_(s24)
113
+ CHECK: [[SUB:%[0-9]+]]:_(s24) = G_SUB [[C1]]:_, [[UREM]]:_
114
+ CHECK: [[C4:%[0-9]+]]:_(s24) = G_CONSTANT i24 1
115
+ CHECK: [[SHL:%[0-9]+]]:_(s24) = G_SHL [[SRC]]:_, [[C4]]:_(s24)
116
+ CHECK: [[SHL2:%[0-9]+]]:_(s24) = G_SHL [[SHL]]:_, [[SUB]]:_(s24)
117
+ CHECK: G_OR [[LSHR]]:_, [[SHL2]]:_
118
+
119
+ ; Check G_ROTL
120
+ CHECK: [[C:%[0-9]+]]:_(s24) = G_CONSTANT i24 0
121
+ CHECK: [[C1:%[0-9]+]]:_(s24) = G_CONSTANT i24 23
122
+ CHECK: [[C2:%[0-9]+]]:_(s24) = G_CONSTANT i24 24
123
+ CHECK: [[UREM:%[0-9]+]]:_(s24) = G_UREM [[AMT]]:_, [[C2]]:_
124
+ CHECK: [[SHL:%[0-9]+]]:_(s24) = G_SHL [[SRC]]:_, [[UREM]]:_(s24)
125
+ CHECK: [[SUB:%[0-9]+]]:_(s24) = G_SUB [[C1]]:_, [[UREM]]:_
126
+ CHECK: [[C4:%[0-9]+]]:_(s24) = G_CONSTANT i24 1
127
+ CHECK: [[LSHR:%[0-9]+]]:_(s24) = G_LSHR [[SRC]]:_, [[C4]]:_(s24)
128
+ CHECK: [[LSHR2:%[0-9]+]]:_(s24) = G_LSHR [[LSHR]]:_, [[SUB]]:_(s24)
129
+ CHECK: G_OR [[SHL]]:_, [[LSHR2]]:_
130
+ )" ;
131
+
132
+ // Check
133
+ EXPECT_TRUE (CheckMachineFunction (*MF, CheckStr)) << *MF;
134
+ }
135
+
136
+ // Test vector G_ROTR lowering.
137
+ TEST_F (AArch64GISelMITest, LowerRotatesVector) {
138
+ setUp ();
139
+ if (!TM)
140
+ return ;
141
+
142
+ // Declare your legalization info
143
+ DefineLegalizerInfo (A, {
144
+ getActionDefinitionsBuilder ({G_ROTR, G_ROTL}).lower (); });
145
+
146
+ LLT S32 = LLT::scalar (32 );
147
+ LLT V4S32 = LLT::vector (4 , S32);
148
+ auto SrcTrunc = B.buildTrunc (S32, Copies[0 ]);
149
+ auto Src = B.buildSplatVector (V4S32, SrcTrunc);
150
+ auto AmtTrunc = B.buildTrunc (S32, Copies[1 ]);
151
+ auto Amt = B.buildSplatVector (V4S32, AmtTrunc);
152
+ auto ROTR = B.buildInstr (TargetOpcode::G_ROTR, {V4S32}, {Src, Amt});
153
+
154
+ AInfo Info (MF->getSubtarget ());
155
+ DummyGISelObserver Observer;
156
+ LegalizerHelper Helper (*MF, Info, Observer, B);
157
+ // Perform Legalization
158
+ EXPECT_EQ (LegalizerHelper::LegalizeResult::Legalized,
159
+ Helper.lower (*ROTR, 0 , V4S32));
160
+
161
+ auto CheckStr = R"(
162
+ CHECK: [[SRCTRUNC:%[0-9]+]]:_(s32) = G_TRUNC
163
+ CHECK: [[SRC:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[SRCTRUNC]]
164
+ CHECK: [[AMTTRUNC:%[0-9]+]]:_(s32) = G_TRUNC
165
+ CHECK: [[AMT:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[AMTTRUNC]]
166
+ CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
167
+ CHECK: [[ZERO:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[C]]
168
+ CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 31
169
+ CHECK: [[VEC31:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[C1]]
170
+ CHECK: [[SUB:%[0-9]+]]:_(<4 x s32>) = G_SUB [[ZERO]]:_, [[AMT]]:_
171
+ CHECK: [[AND:%[0-9]+]]:_(<4 x s32>) = G_AND [[AMT]]:_, [[VEC31]]:_
172
+ CHECK: [[LSHR:%[0-9]+]]:_(<4 x s32>) = G_LSHR [[SRC]]:_, [[AND]]:_(<4 x s32>)
173
+ CHECK: [[AND1:%[0-9]+]]:_(<4 x s32>) = G_AND [[SUB]]:_, [[VEC31]]:_
174
+ CHECK: [[SHL:%[0-9]+]]:_(<4 x s32>) = G_SHL [[SRC]]:_, [[AND1]]:_(<4 x s32>)
175
+ CHECK: G_OR [[LSHR]]:_, [[SHL]]:_
176
+ )" ;
177
+
178
+ // Check
179
+ EXPECT_TRUE (CheckMachineFunction (*MF, CheckStr)) << *MF;
180
+ }
181
+
26
182
// Test CTTZ expansion when CTTZ_ZERO_UNDEF is legal or custom,
27
183
// in which case it becomes CTTZ_ZERO_UNDEF with select.
28
184
TEST_F (AArch64GISelMITest, LowerBitCountingCTTZ0) {
0 commit comments