@@ -23,6 +23,162 @@ class DummyGISelObserver : public GISelChangeObserver {
2323 void erasingInstr (MachineInstr &MI) override {}
2424};
2525
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+
26182// Test CTTZ expansion when CTTZ_ZERO_UNDEF is legal or custom,
27183// in which case it becomes CTTZ_ZERO_UNDEF with select.
28184TEST_F (AArch64GISelMITest, LowerBitCountingCTTZ0) {
0 commit comments