1 /**
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "libabckit/include/c/abckit.h"
17 #include "libabckit/include/c/metadata_core.h"
18 #include "libabckit/include/c/ir_core.h"
19
20 #include "helpers/helpers.h"
21 #include "helpers/helpers_runtime.h"
22
23 #include <gtest/gtest.h>
24
25 // NOLINTBEGIN(readability-magic-numbers)
26 namespace libabckit::test {
27
28 namespace {
29 auto g_impl = AbckitGetApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
30 auto g_implI = AbckitGetInspectApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
31 auto g_implM = AbckitGetModifyApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
32 auto g_implG = AbckitGetGraphApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
33 auto g_statG = AbckitGetIsaApiStaticImpl(ABCKIT_VERSION_RELEASE_1_0_0);
34 auto g_dynG = AbckitGetIsaApiDynamicImpl(ABCKIT_VERSION_RELEASE_1_0_0);
35
TransformIrIcreateIf(AbckitGraph * graph)36 void TransformIrIcreateIf(AbckitGraph *graph)
37 {
38 AbckitBasicBlock *startBB = g_implG->gGetStartBasicBlock(graph);
39 std::vector<AbckitBasicBlock *> succBBs = helpers::BBgetSuccBlocks(startBB);
40 AbckitInst *constOne = g_implG->gFindOrCreateConstantU64(graph, 1);
41 AbckitInst *constZero = g_implG->gFindOrCreateConstantU64(graph, 0);
42
43 AbckitBasicBlock *trueBB = succBBs[0];
44 g_implG->bbDisconnectSuccBlock(startBB, ABCKIT_TRUE_SUCC_IDX);
45 AbckitBasicBlock *falseBB = g_implG->bbCreateEmpty(graph);
46 g_implG->bbAppendSuccBlock(falseBB, g_implG->gGetEndBasicBlock(graph));
47 g_implG->bbAddInstBack(falseBB, g_statG->iCreateReturn(graph, constZero));
48 AbckitBasicBlock *ifBB = g_implG->bbCreateEmpty(graph);
49 AbckitInst *ifInst = g_statG->iCreateIf(graph, constOne, constZero, ABCKIT_ISA_API_STATIC_CONDITION_CODE_CC_NE);
50 g_implG->bbAddInstBack(ifBB, ifInst);
51 g_implG->bbAppendSuccBlock(startBB, ifBB);
52 g_implG->bbAppendSuccBlock(ifBB, trueBB);
53 g_implG->bbAppendSuccBlock(ifBB, falseBB);
54 }
55
TransformIrIcreateIfNeg(AbckitGraph * graph)56 void TransformIrIcreateIfNeg(AbckitGraph *graph)
57 {
58 AbckitBasicBlock *startBB = g_implG->gGetStartBasicBlock(graph);
59 std::vector<AbckitBasicBlock *> succBBs = helpers::BBgetSuccBlocks(startBB);
60 AbckitInst *constOne = g_implG->gFindOrCreateConstantU64(graph, 1);
61 AbckitInst *constZero = g_implG->gFindOrCreateConstantU64(graph, 0);
62
63 AbckitBasicBlock *trueBB = succBBs[0];
64 g_implG->bbDisconnectSuccBlock(startBB, ABCKIT_TRUE_SUCC_IDX);
65 AbckitBasicBlock *falseBB = g_implG->bbCreateEmpty(graph);
66 g_implG->bbAppendSuccBlock(falseBB, g_implG->gGetEndBasicBlock(graph));
67 g_implG->bbAddInstBack(falseBB, g_statG->iCreateReturn(graph, constZero));
68 AbckitBasicBlock *ifBB = g_implG->bbCreateEmpty(graph);
69 AbckitInst *ifInst = g_statG->iCreateIf(graph, constOne, constZero, ABCKIT_ISA_API_STATIC_CONDITION_CODE_CC_EQ);
70 g_implG->bbAddInstBack(ifBB, ifInst);
71 g_implG->bbAppendSuccBlock(startBB, ifBB);
72 g_implG->bbAppendSuccBlock(ifBB, trueBB);
73 g_implG->bbAppendSuccBlock(ifBB, falseBB);
74 }
75
TransformIrIsetConditionCode(AbckitGraph * graph)76 void TransformIrIsetConditionCode(AbckitGraph *graph)
77 {
78 AbckitBasicBlock *startBB = g_implG->gGetStartBasicBlock(graph);
79 std::vector<AbckitBasicBlock *> succBBs = helpers::BBgetSuccBlocks(startBB);
80 AbckitInst *constOne = g_implG->gFindOrCreateConstantU64(graph, 1);
81 AbckitInst *constZero = g_implG->gFindOrCreateConstantU64(graph, 0);
82
83 AbckitBasicBlock *trueBB = succBBs[0];
84 g_implG->bbDisconnectSuccBlock(startBB, ABCKIT_TRUE_SUCC_IDX);
85 AbckitBasicBlock *falseBB = g_implG->bbCreateEmpty(graph);
86 g_implG->bbAppendSuccBlock(falseBB, g_implG->gGetEndBasicBlock(graph));
87 g_implG->bbAddInstBack(falseBB, g_statG->iCreateReturn(graph, constZero));
88 AbckitBasicBlock *ifBB = g_implG->bbCreateEmpty(graph);
89 AbckitInst *ifInst = g_statG->iCreateIf(graph, constOne, constZero, ABCKIT_ISA_API_STATIC_CONDITION_CODE_CC_EQ);
90 g_statG->iSetConditionCode(ifInst, ABCKIT_ISA_API_STATIC_CONDITION_CODE_CC_NE);
91 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
92 g_implG->bbAddInstBack(ifBB, ifInst);
93 g_implG->bbAppendSuccBlock(startBB, ifBB);
94 g_implG->bbAppendSuccBlock(ifBB, trueBB);
95 g_implG->bbAppendSuccBlock(ifBB, falseBB);
96 }
97
TransformIrIsetConditionCodeNeg(AbckitGraph * graph)98 void TransformIrIsetConditionCodeNeg(AbckitGraph *graph)
99 {
100 AbckitBasicBlock *startBB = g_implG->gGetStartBasicBlock(graph);
101 std::vector<AbckitBasicBlock *> succBBs = helpers::BBgetSuccBlocks(startBB);
102 AbckitInst *constOne = g_implG->gFindOrCreateConstantU64(graph, 1);
103 AbckitInst *constZero = g_implG->gFindOrCreateConstantU64(graph, 0);
104
105 AbckitBasicBlock *trueBB = succBBs[0];
106 g_implG->bbDisconnectSuccBlock(startBB, ABCKIT_TRUE_SUCC_IDX);
107 AbckitBasicBlock *falseBB = g_implG->bbCreateEmpty(graph);
108 g_implG->bbAppendSuccBlock(falseBB, g_implG->gGetEndBasicBlock(graph));
109 g_implG->bbAddInstBack(falseBB, g_statG->iCreateReturn(graph, constZero));
110 AbckitBasicBlock *ifBB = g_implG->bbCreateEmpty(graph);
111 AbckitInst *ifInst = g_statG->iCreateIf(graph, constOne, constZero, ABCKIT_ISA_API_STATIC_CONDITION_CODE_CC_EQ);
112 g_statG->iSetConditionCode(nullptr, ABCKIT_ISA_API_STATIC_CONDITION_CODE_CC_NE);
113 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_BAD_ARGUMENT);
114 g_implG->bbAddInstBack(ifBB, ifInst);
115 g_implG->bbAppendSuccBlock(startBB, ifBB);
116 g_implG->bbAppendSuccBlock(ifBB, trueBB);
117 g_implG->bbAppendSuccBlock(ifBB, falseBB);
118 }
119
TransformIrIgetConditionCode(AbckitGraph * graph)120 void TransformIrIgetConditionCode(AbckitGraph *graph)
121 {
122 AbckitBasicBlock *startBB = g_implG->gGetStartBasicBlock(graph);
123 std::vector<AbckitBasicBlock *> succBBs = helpers::BBgetSuccBlocks(startBB);
124 AbckitInst *constOne = g_implG->gFindOrCreateConstantU64(graph, 1);
125 AbckitInst *constZero = g_implG->gFindOrCreateConstantU64(graph, 0);
126
127 AbckitBasicBlock *trueBB = succBBs[0];
128 g_implG->bbDisconnectSuccBlock(startBB, ABCKIT_TRUE_SUCC_IDX);
129 AbckitBasicBlock *falseBB = g_implG->bbCreateEmpty(graph);
130 g_implG->bbAppendSuccBlock(falseBB, g_implG->gGetEndBasicBlock(graph));
131 g_implG->bbAddInstBack(falseBB, g_statG->iCreateReturn(graph, constZero));
132 AbckitBasicBlock *ifBB = g_implG->bbCreateEmpty(graph);
133 AbckitInst *ifInst = g_statG->iCreateIf(graph, constOne, constZero, ABCKIT_ISA_API_STATIC_CONDITION_CODE_CC_EQ);
134 AbckitIsaApiStaticConditionCode cc = g_statG->iGetConditionCode(ifInst);
135 ASSERT_EQ(cc, ABCKIT_ISA_API_STATIC_CONDITION_CODE_CC_EQ);
136 g_statG->iSetConditionCode(ifInst, ABCKIT_ISA_API_STATIC_CONDITION_CODE_CC_NE);
137 g_implG->bbAddInstBack(ifBB, ifInst);
138 g_implG->bbAppendSuccBlock(startBB, ifBB);
139 g_implG->bbAppendSuccBlock(ifBB, trueBB);
140 g_implG->bbAppendSuccBlock(ifBB, falseBB);
141 }
142
TransformIrIgetConditionCodeNeg(AbckitGraph * graph)143 void TransformIrIgetConditionCodeNeg(AbckitGraph *graph)
144 {
145 AbckitBasicBlock *startBB = g_implG->gGetStartBasicBlock(graph);
146 std::vector<AbckitBasicBlock *> succBBs = helpers::BBgetSuccBlocks(startBB);
147 AbckitInst *constOne = g_implG->gFindOrCreateConstantU64(graph, 1);
148 AbckitInst *constZero = g_implG->gFindOrCreateConstantU64(graph, 0);
149
150 AbckitBasicBlock *trueBB = succBBs[0];
151 g_implG->bbDisconnectSuccBlock(startBB, ABCKIT_TRUE_SUCC_IDX);
152 AbckitBasicBlock *falseBB = g_implG->bbCreateEmpty(graph);
153 g_implG->bbAppendSuccBlock(falseBB, g_implG->gGetEndBasicBlock(graph));
154 g_implG->bbAddInstBack(falseBB, g_statG->iCreateReturn(graph, constZero));
155 AbckitBasicBlock *ifBB = g_implG->bbCreateEmpty(graph);
156 AbckitInst *ifInst = g_statG->iCreateIf(graph, constOne, constZero, ABCKIT_ISA_API_STATIC_CONDITION_CODE_CC_EQ);
157 AbckitIsaApiStaticConditionCode cc = g_statG->iGetConditionCode(nullptr);
158 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_BAD_ARGUMENT);
159 ASSERT_EQ(cc, ABCKIT_ISA_API_STATIC_CONDITION_CODE_CC_NONE);
160 g_statG->iSetConditionCode(ifInst, ABCKIT_ISA_API_STATIC_CONDITION_CODE_CC_NE);
161 g_implG->bbAddInstBack(ifBB, ifInst);
162 g_implG->bbAppendSuccBlock(startBB, ifBB);
163 g_implG->bbAppendSuccBlock(ifBB, trueBB);
164 g_implG->bbAppendSuccBlock(ifBB, falseBB);
165 }
166 } // namespace
167
168 class LibAbcKitCreateIfStaticTest : public ::testing::Test {};
169
GetSchema1()170 static std::vector<helpers::BBSchema<AbckitIsaApiStaticOpcode>> GetSchema1()
171 {
172 return {{{},
173 {1},
174 {
175 {9, ABCKIT_ISA_API_STATIC_OPCODE_PARAMETER, {}},
176 {0, ABCKIT_ISA_API_STATIC_OPCODE_CONSTANT, {}},
177 {1, ABCKIT_ISA_API_STATIC_OPCODE_CONSTANT, {}},
178 {2, ABCKIT_ISA_API_STATIC_OPCODE_CONSTANT, {}},
179 {3, ABCKIT_ISA_API_STATIC_OPCODE_CONSTANT, {}},
180 {4, ABCKIT_ISA_API_STATIC_OPCODE_CONSTANT, {}},
181 }},
182 {{0},
183 {3, 2},
184 {
185 {5, ABCKIT_ISA_API_STATIC_OPCODE_CMP, {1, 0}},
186 {6, ABCKIT_ISA_API_STATIC_OPCODE_IF, {5, 2}},
187 }},
188 {{1},
189 {4},
190 {
191 {7, ABCKIT_ISA_API_STATIC_OPCODE_RETURN, {4}},
192 }},
193 {{1},
194 {4},
195 {
196 {8, ABCKIT_ISA_API_STATIC_OPCODE_RETURN, {3}},
197 }},
198 {{2, 3}, {}, {}}};
199 }
200
201 // Test: test-kind=api, api=IsaApiStaticImpl::iCreateIf, abc-kind=ArkTS2, category=positive, extension=c
TEST_F(LibAbcKitCreateIfStaticTest,LibAbcKitTestCreateIf)202 TEST_F(LibAbcKitCreateIfStaticTest, LibAbcKitTestCreateIf)
203 {
204 helpers::TransformMethod(
205 ABCKIT_ABC_DIR "ut/isa/isa_static/create_if/create_if_static.abc",
206 ABCKIT_ABC_DIR "ut/isa/isa_static/create_if/create_if_static_modified.abc", "handle",
207 [](AbckitFile * /*file*/, AbckitCoreFunction * /*method*/, AbckitGraph *graph) { TransformIrIcreateIf(graph); },
208 [](AbckitGraph *graph) { helpers::VerifyGraph(graph, GetSchema1()); });
209 auto output = helpers::ExecuteStaticAbc(ABCKIT_ABC_DIR "ut/isa/isa_static/create_if/create_if_static_modified.abc",
210 "create_if_static/ETSGLOBAL", "main");
211 EXPECT_TRUE(helpers::Match(output, "3.14\n"));
212 }
213
214 // Test: test-kind=api, api=IsaApiStaticImpl::iCreateIf, abc-kind=ArkTS2, category=negative
TEST_F(LibAbcKitCreateIfStaticTest,LibAbcKitTestCreateIfNeg)215 TEST_F(LibAbcKitCreateIfStaticTest, LibAbcKitTestCreateIfNeg)
216 {
217 helpers::TransformMethod(
218 ABCKIT_ABC_DIR "ut/isa/isa_static/create_if/create_if_static.abc",
219 ABCKIT_ABC_DIR "ut/isa/isa_static/create_if/create_if_static_modified_neg.abc", "handle",
220 [](AbckitFile * /*file*/, AbckitCoreFunction * /*method*/, AbckitGraph *graph) {
221 TransformIrIcreateIfNeg(graph);
222 },
223 [](AbckitGraph *graph) { helpers::VerifyGraph(graph, GetSchema1()); });
224 auto output =
225 helpers::ExecuteStaticAbc(ABCKIT_ABC_DIR "ut/isa/isa_static/create_if/create_if_static_modified_neg.abc",
226 "create_if_static/ETSGLOBAL", "main");
227 EXPECT_TRUE(helpers::Match(output, "0\n"));
228 }
229
GetSchema2()230 static std::vector<helpers::BBSchema<AbckitIsaApiStaticOpcode>> GetSchema2()
231 {
232 return {{{},
233 {1},
234 {
235 {9, ABCKIT_ISA_API_STATIC_OPCODE_PARAMETER, {}},
236 {0, ABCKIT_ISA_API_STATIC_OPCODE_CONSTANT, {}},
237 {1, ABCKIT_ISA_API_STATIC_OPCODE_CONSTANT, {}},
238 {2, ABCKIT_ISA_API_STATIC_OPCODE_CONSTANT, {}},
239 {3, ABCKIT_ISA_API_STATIC_OPCODE_CONSTANT, {}},
240 {4, ABCKIT_ISA_API_STATIC_OPCODE_CONSTANT, {}},
241 }},
242 {{0},
243 {3, 2},
244 {
245 {5, ABCKIT_ISA_API_STATIC_OPCODE_CMP, {1, 0}},
246 {6, ABCKIT_ISA_API_STATIC_OPCODE_IF, {5, 2}},
247 }},
248 {{1},
249 {4},
250 {
251 {7, ABCKIT_ISA_API_STATIC_OPCODE_RETURN, {4}},
252 }},
253 {{1},
254 {4},
255 {
256 {8, ABCKIT_ISA_API_STATIC_OPCODE_RETURN, {3}},
257 }},
258 {{2, 3}, {}, {}}};
259 }
260
261 // Test: test-kind=api, api=IsaApiStaticImpl::iSetConditionCode, abc-kind=ArkTS2, category=positive, extension=c
TEST_F(LibAbcKitCreateIfStaticTest,LibAbcKitTestSetCondidionCodePos)262 TEST_F(LibAbcKitCreateIfStaticTest, LibAbcKitTestSetCondidionCodePos)
263 {
264 helpers::TransformMethod(
265 ABCKIT_ABC_DIR "ut/isa/isa_static/create_if/create_if_static.abc",
266 ABCKIT_ABC_DIR "ut/isa/isa_static/create_if/create_if_static_modified_set.abc", "handle",
267 [](AbckitFile * /*file*/, AbckitCoreFunction * /*method*/, AbckitGraph *graph) {
268 TransformIrIsetConditionCode(graph);
269 },
270 [](AbckitGraph *graph) { helpers::VerifyGraph(graph, GetSchema2()); });
271 auto output =
272 helpers::ExecuteStaticAbc(ABCKIT_ABC_DIR "ut/isa/isa_static/create_if/create_if_static_modified_set.abc",
273 "create_if_static/ETSGLOBAL", "main");
274 EXPECT_TRUE(helpers::Match(output, "3.14\n"));
275 }
276
277 // Test: test-kind=api, api=IsaApiStaticImpl::iSetConditionCode, abc-kind=ArkTS2, category=negative
TEST_F(LibAbcKitCreateIfStaticTest,LibAbcKitTestSetCondidionCodeNeg)278 TEST_F(LibAbcKitCreateIfStaticTest, LibAbcKitTestSetCondidionCodeNeg)
279 {
280 helpers::TransformMethod(
281 ABCKIT_ABC_DIR "ut/isa/isa_static/create_if/create_if_static.abc",
282 ABCKIT_ABC_DIR "ut/isa/isa_static/create_if/create_if_static_modified_set_neg.abc", "handle",
283 [](AbckitFile * /*file*/, AbckitCoreFunction * /*method*/, AbckitGraph *graph) {
284 TransformIrIsetConditionCodeNeg(graph);
285 },
286 [](AbckitGraph *graph) { helpers::VerifyGraph(graph, GetSchema2()); });
287 }
288
289 // Test: test-kind=api, api=IsaApiStaticImpl::iGetConditionCode, abc-kind=ArkTS2, category=positive, extension=c
TEST_F(LibAbcKitCreateIfStaticTest,LibAbcKitTestGetCondidionCodePos)290 TEST_F(LibAbcKitCreateIfStaticTest, LibAbcKitTestGetCondidionCodePos)
291 {
292 helpers::TransformMethod(
293 ABCKIT_ABC_DIR "ut/isa/isa_static/create_if/create_if_static.abc",
294 ABCKIT_ABC_DIR "ut/isa/isa_static/create_if/create_if_static_modified_get.abc", "handle",
295 [](AbckitFile * /*file*/, AbckitCoreFunction * /*method*/, AbckitGraph *graph) {
296 TransformIrIgetConditionCode(graph);
297 },
298 [](AbckitGraph *graph) { helpers::VerifyGraph(graph, GetSchema2()); });
299 auto output =
300 helpers::ExecuteStaticAbc(ABCKIT_ABC_DIR "ut/isa/isa_static/create_if/create_if_static_modified_get.abc",
301 "create_if_static/ETSGLOBAL", "main");
302 EXPECT_TRUE(helpers::Match(output, "3.14\n"));
303 }
304
305 // Test: test-kind=api, api=IsaApiStaticImpl::iGetConditionCode, abc-kind=ArkTS2, category=negative
TEST_F(LibAbcKitCreateIfStaticTest,LibAbcKitTestGetCondidionCodeNeg)306 TEST_F(LibAbcKitCreateIfStaticTest, LibAbcKitTestGetCondidionCodeNeg)
307 {
308 helpers::TransformMethod(
309 ABCKIT_ABC_DIR "ut/isa/isa_static/create_if/create_if_static.abc",
310 ABCKIT_ABC_DIR "ut/isa/isa_static/create_if/create_if_static_modified_get_neg.abc", "handle",
311 [](AbckitFile * /*file*/, AbckitCoreFunction * /*method*/, AbckitGraph *graph) {
312 TransformIrIgetConditionCodeNeg(graph);
313 },
314 [](AbckitGraph *graph) { helpers::VerifyGraph(graph, GetSchema2()); });
315 }
316
317 } // namespace libabckit::test
318 // NOLINTEND(readability-magic-numbers)
319