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
TransformIrCreateIfDynamic(AbckitGraph * graph)36 void TransformIrCreateIfDynamic(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_dynG->iCreateReturnundefined(graph));
48 AbckitBasicBlock *ifBB = g_implG->bbCreateEmpty(graph);
49 AbckitInst *intrinsicNoteq = g_dynG->iCreateNoteq(graph, constOne, constZero);
50 AbckitInst *ifInst = g_dynG->iCreateIf(graph, intrinsicNoteq, ABCKIT_ISA_API_DYNAMIC_CONDITION_CODE_CC_NE);
51 g_implG->bbAddInstBack(ifBB, intrinsicNoteq);
52 g_implG->bbAddInstBack(ifBB, ifInst);
53 g_implG->bbAppendSuccBlock(startBB, ifBB);
54 g_implG->bbAppendSuccBlock(ifBB, trueBB);
55 g_implG->bbAppendSuccBlock(ifBB, falseBB);
56 }
57
TransformIrCreateIfDynamicNeg(AbckitGraph * graph)58 void TransformIrCreateIfDynamicNeg(AbckitGraph *graph)
59 {
60 AbckitBasicBlock *startBB = g_implG->gGetStartBasicBlock(graph);
61 std::vector<AbckitBasicBlock *> succBBs = helpers::BBgetSuccBlocks(startBB);
62 AbckitInst *constOne = g_implG->gFindOrCreateConstantU64(graph, 1);
63 AbckitInst *constZero = g_implG->gFindOrCreateConstantU64(graph, 0);
64
65 AbckitBasicBlock *trueBB = succBBs[0];
66 g_implG->bbDisconnectSuccBlock(startBB, ABCKIT_TRUE_SUCC_IDX);
67 AbckitBasicBlock *falseBB = g_implG->bbCreateEmpty(graph);
68 g_implG->bbAppendSuccBlock(falseBB, g_implG->gGetEndBasicBlock(graph));
69 g_implG->bbAddInstBack(falseBB, g_dynG->iCreateReturnundefined(graph));
70 AbckitBasicBlock *ifBB = g_implG->bbCreateEmpty(graph);
71 AbckitInst *intrinsicNoteq = g_dynG->iCreateNoteq(graph, constOne, constZero);
72 AbckitInst *ifInst = g_dynG->iCreateIf(graph, intrinsicNoteq, ABCKIT_ISA_API_DYNAMIC_CONDITION_CODE_CC_GT);
73 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_BAD_ARGUMENT);
74 ASSERT_EQ(ifInst, nullptr);
75 ifInst = g_dynG->iCreateIf(graph, intrinsicNoteq, ABCKIT_ISA_API_DYNAMIC_CONDITION_CODE_CC_NE);
76 g_implG->bbAddInstBack(ifBB, intrinsicNoteq);
77 g_implG->bbAddInstBack(ifBB, ifInst);
78 g_implG->bbAppendSuccBlock(startBB, ifBB);
79 g_implG->bbAppendSuccBlock(ifBB, trueBB);
80 g_implG->bbAppendSuccBlock(ifBB, falseBB);
81 }
82
TransformIrIgetConditionCode(AbckitGraph * graph)83 void TransformIrIgetConditionCode(AbckitGraph *graph)
84 {
85 AbckitBasicBlock *startBB = g_implG->gGetStartBasicBlock(graph);
86 std::vector<AbckitBasicBlock *> succBBs = helpers::BBgetSuccBlocks(startBB);
87 AbckitInst *constOne = g_implG->gFindOrCreateConstantU64(graph, 1);
88 AbckitInst *constZero = g_implG->gFindOrCreateConstantU64(graph, 0);
89
90 AbckitBasicBlock *trueBB = succBBs[0];
91 g_implG->bbDisconnectSuccBlock(startBB, ABCKIT_TRUE_SUCC_IDX);
92 AbckitBasicBlock *falseBB = g_implG->bbCreateEmpty(graph);
93 g_implG->bbAppendSuccBlock(falseBB, g_implG->gGetEndBasicBlock(graph));
94 g_implG->bbAddInstBack(falseBB, g_dynG->iCreateReturnundefined(graph));
95 AbckitBasicBlock *ifBB = g_implG->bbCreateEmpty(graph);
96 AbckitInst *intrinsicNoteq = g_dynG->iCreateNoteq(graph, constOne, constZero);
97 AbckitInst *ifInst = g_dynG->iCreateIf(graph, intrinsicNoteq, ABCKIT_ISA_API_DYNAMIC_CONDITION_CODE_CC_NE);
98 AbckitIsaApiDynamicConditionCode cc = g_dynG->iGetConditionCode(ifInst);
99 ASSERT_EQ(cc, ABCKIT_ISA_API_DYNAMIC_CONDITION_CODE_CC_NE);
100 g_implG->bbAddInstBack(ifBB, intrinsicNoteq);
101 g_implG->bbAddInstBack(ifBB, ifInst);
102 g_implG->bbAppendSuccBlock(startBB, ifBB);
103 g_implG->bbAppendSuccBlock(ifBB, trueBB);
104 g_implG->bbAppendSuccBlock(ifBB, falseBB);
105 }
106
TransformIrIgetConditionCodeNeg(AbckitGraph * graph)107 void TransformIrIgetConditionCodeNeg(AbckitGraph *graph)
108 {
109 AbckitBasicBlock *startBB = g_implG->gGetStartBasicBlock(graph);
110 std::vector<AbckitBasicBlock *> succBBs = helpers::BBgetSuccBlocks(startBB);
111 AbckitInst *constOne = g_implG->gFindOrCreateConstantU64(graph, 1);
112 AbckitInst *constZero = g_implG->gFindOrCreateConstantU64(graph, 0);
113
114 AbckitBasicBlock *trueBB = succBBs[0];
115 g_implG->bbDisconnectSuccBlock(startBB, ABCKIT_TRUE_SUCC_IDX);
116 AbckitBasicBlock *falseBB = g_implG->bbCreateEmpty(graph);
117 g_implG->bbAppendSuccBlock(falseBB, g_implG->gGetEndBasicBlock(graph));
118 g_implG->bbAddInstBack(falseBB, g_dynG->iCreateReturnundefined(graph));
119 AbckitBasicBlock *ifBB = g_implG->bbCreateEmpty(graph);
120 AbckitInst *intrinsicNoteq = g_dynG->iCreateNoteq(graph, constOne, constZero);
121 AbckitInst *ifInst = g_dynG->iCreateIf(graph, intrinsicNoteq, ABCKIT_ISA_API_DYNAMIC_CONDITION_CODE_CC_NE);
122 AbckitIsaApiDynamicConditionCode cc = g_dynG->iGetConditionCode(nullptr);
123 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_BAD_ARGUMENT);
124 ASSERT_EQ(cc, ABCKIT_ISA_API_DYNAMIC_CONDITION_CODE_CC_NONE);
125 g_implG->bbAddInstBack(ifBB, intrinsicNoteq);
126 g_implG->bbAddInstBack(ifBB, ifInst);
127 g_implG->bbAppendSuccBlock(startBB, ifBB);
128 g_implG->bbAppendSuccBlock(ifBB, trueBB);
129 g_implG->bbAppendSuccBlock(ifBB, falseBB);
130 }
131
TransformIrIsetConditionCode(AbckitGraph * graph)132 void TransformIrIsetConditionCode(AbckitGraph *graph)
133 {
134 AbckitBasicBlock *startBB = g_implG->gGetStartBasicBlock(graph);
135 std::vector<AbckitBasicBlock *> succBBs = helpers::BBgetSuccBlocks(startBB);
136 AbckitInst *constOne = g_implG->gFindOrCreateConstantU64(graph, 1);
137 AbckitInst *constZero = g_implG->gFindOrCreateConstantU64(graph, 0);
138
139 AbckitBasicBlock *trueBB = succBBs[0];
140 g_implG->bbDisconnectSuccBlock(startBB, ABCKIT_TRUE_SUCC_IDX);
141 AbckitBasicBlock *falseBB = g_implG->bbCreateEmpty(graph);
142 g_implG->bbAppendSuccBlock(falseBB, g_implG->gGetEndBasicBlock(graph));
143 g_implG->bbAddInstBack(falseBB, g_dynG->iCreateReturnundefined(graph));
144 AbckitBasicBlock *ifBB = g_implG->bbCreateEmpty(graph);
145 AbckitInst *intrinsicNoteq = g_dynG->iCreateNoteq(graph, constOne, constZero);
146 AbckitInst *ifInst = g_dynG->iCreateIf(graph, intrinsicNoteq, ABCKIT_ISA_API_DYNAMIC_CONDITION_CODE_CC_EQ);
147 g_dynG->iSetConditionCode(ifInst, ABCKIT_ISA_API_DYNAMIC_CONDITION_CODE_CC_NE);
148 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
149 g_implG->bbAddInstBack(ifBB, intrinsicNoteq);
150 g_implG->bbAddInstBack(ifBB, ifInst);
151 g_implG->bbAppendSuccBlock(startBB, ifBB);
152 g_implG->bbAppendSuccBlock(ifBB, trueBB);
153 g_implG->bbAppendSuccBlock(ifBB, falseBB);
154 }
155
TransformIrIsetConditionCodeNeg(AbckitGraph * graph)156 void TransformIrIsetConditionCodeNeg(AbckitGraph *graph)
157 {
158 AbckitBasicBlock *startBB = g_implG->gGetStartBasicBlock(graph);
159 std::vector<AbckitBasicBlock *> succBBs = helpers::BBgetSuccBlocks(startBB);
160 AbckitInst *constOne = g_implG->gFindOrCreateConstantU64(graph, 1);
161 AbckitInst *constZero = g_implG->gFindOrCreateConstantU64(graph, 0);
162
163 AbckitBasicBlock *trueBB = succBBs[0];
164 g_implG->bbDisconnectSuccBlock(startBB, ABCKIT_TRUE_SUCC_IDX);
165 AbckitBasicBlock *falseBB = g_implG->bbCreateEmpty(graph);
166 g_implG->bbAppendSuccBlock(falseBB, g_implG->gGetEndBasicBlock(graph));
167 g_implG->bbAddInstBack(falseBB, g_dynG->iCreateReturnundefined(graph));
168 AbckitBasicBlock *ifBB = g_implG->bbCreateEmpty(graph);
169 AbckitInst *intrinsicNoteq = g_dynG->iCreateNoteq(graph, constOne, constZero);
170 AbckitInst *ifInst = g_dynG->iCreateIf(graph, intrinsicNoteq, ABCKIT_ISA_API_DYNAMIC_CONDITION_CODE_CC_NE);
171 g_dynG->iSetConditionCode(nullptr, ABCKIT_ISA_API_DYNAMIC_CONDITION_CODE_CC_NE);
172 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_BAD_ARGUMENT);
173 g_dynG->iSetConditionCode(ifInst, ABCKIT_ISA_API_DYNAMIC_CONDITION_CODE_CC_GT);
174 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_BAD_ARGUMENT);
175 g_implG->bbAddInstBack(ifBB, intrinsicNoteq);
176 g_implG->bbAddInstBack(ifBB, ifInst);
177 g_implG->bbAppendSuccBlock(startBB, ifBB);
178 g_implG->bbAppendSuccBlock(ifBB, trueBB);
179 g_implG->bbAppendSuccBlock(ifBB, falseBB);
180 }
181 } // namespace
182
183 class LibAbcKitCreateIfDynamicTest : public ::testing::Test {};
184
GetSchema()185 static std::vector<helpers::BBSchema<AbckitIsaApiDynamicOpcode>> GetSchema()
186 {
187 return {{{},
188 {1},
189 {
190 {7, ABCKIT_ISA_API_DYNAMIC_OPCODE_PARAMETER, {}},
191 {8, ABCKIT_ISA_API_DYNAMIC_OPCODE_PARAMETER, {}},
192 {9, ABCKIT_ISA_API_DYNAMIC_OPCODE_PARAMETER, {}},
193 {0, ABCKIT_ISA_API_DYNAMIC_OPCODE_CONSTANT, {}},
194 {1, ABCKIT_ISA_API_DYNAMIC_OPCODE_CONSTANT, {}},
195 {2, ABCKIT_ISA_API_DYNAMIC_OPCODE_CONSTANT, {}},
196 }},
197 {{0},
198 {3, 2},
199 {
200 {3, ABCKIT_ISA_API_DYNAMIC_OPCODE_NOTEQ, {0, 1}},
201 {4, ABCKIT_ISA_API_DYNAMIC_OPCODE_IF, {3, 2}},
202 }},
203 {{1},
204 {4},
205 {
206 {5, ABCKIT_ISA_API_DYNAMIC_OPCODE_RETURNUNDEFINED, {}},
207 }},
208 {{1},
209 {4},
210 {
211 {6, ABCKIT_ISA_API_DYNAMIC_OPCODE_RETURN, {1}},
212 }},
213 {{2, 3}, {}, {}}};
214 }
215
216 // Test: test-kind=api, api=IsaApiDynamicImpl::iCreateIf, abc-kind=ArkTS1, category=positive, extension=c
TEST_F(LibAbcKitCreateIfDynamicTest,LibAbcKitTestCreateIfDyn)217 TEST_F(LibAbcKitCreateIfDynamicTest, LibAbcKitTestCreateIfDyn)
218 {
219 helpers::TransformMethod(
220 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/create_if/create_if_dynamic.abc",
221 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/create_if/create_if_dynamic_modified.abc", "foo",
222 [](AbckitFile * /*file*/, AbckitCoreFunction * /*method*/, AbckitGraph *graph) {
223 TransformIrCreateIfDynamic(graph);
224 },
225 [](AbckitGraph *graph) { helpers::VerifyGraph(graph, GetSchema()); });
226
227 auto output = helpers::ExecuteDynamicAbc(
228 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/create_if/create_if_dynamic_modified.abc", "create_if_dynamic");
229 EXPECT_TRUE(helpers::Match(output, "0\n"));
230 }
231
232 // Test: test-kind=api, api=IsaApiDynamicImpl::iCreateIf, abc-kind=ArkTS1, category=negative
TEST_F(LibAbcKitCreateIfDynamicTest,LibAbcKitTestCreateIfDynNeg)233 TEST_F(LibAbcKitCreateIfDynamicTest, LibAbcKitTestCreateIfDynNeg)
234 {
235 helpers::TransformMethod(
236 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/create_if/create_if_dynamic.abc",
237 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/create_if/create_if_dynamic_modified_neg.abc", "foo",
238 [](AbckitFile * /*file*/, AbckitCoreFunction * /*method*/, AbckitGraph *graph) {
239 TransformIrCreateIfDynamicNeg(graph);
240 },
241 [](AbckitGraph *graph) { helpers::VerifyGraph(graph, GetSchema()); });
242
243 auto output = helpers::ExecuteDynamicAbc(
244 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/create_if/create_if_dynamic_modified_neg.abc", "create_if_dynamic");
245 EXPECT_TRUE(helpers::Match(output, "0\n"));
246 }
247
248 // Test: test-kind=api, api=IsaApiDynamicImpl::iGetConditionCode, abc-kind=ArkTS1, category=positive, extension=c
TEST_F(LibAbcKitCreateIfDynamicTest,LibAbcKitTestGetConditionCode)249 TEST_F(LibAbcKitCreateIfDynamicTest, LibAbcKitTestGetConditionCode)
250 {
251 helpers::TransformMethod(
252 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/create_if/create_if_dynamic.abc",
253 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/create_if/create_if_dynamic_modified_get.abc", "foo",
254 [](AbckitFile * /*file*/, AbckitCoreFunction * /*method*/, AbckitGraph *graph) {
255 TransformIrIgetConditionCode(graph);
256 },
257 [](AbckitGraph *graph) { helpers::VerifyGraph(graph, GetSchema()); });
258
259 auto output = helpers::ExecuteDynamicAbc(
260 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/create_if/create_if_dynamic_modified_get.abc", "create_if_dynamic");
261 EXPECT_TRUE(helpers::Match(output, "0\n"));
262 }
263
264 // Test: test-kind=api, api=IsaApiDynamicImpl::iGetConditionCode, abc-kind=ArkTS1, category=negative
TEST_F(LibAbcKitCreateIfDynamicTest,LibAbcKitTestGetConditionCodeNeg)265 TEST_F(LibAbcKitCreateIfDynamicTest, LibAbcKitTestGetConditionCodeNeg)
266 {
267 helpers::TransformMethod(
268 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/create_if/create_if_dynamic.abc",
269 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/create_if/create_if_dynamic_modified_get_neg.abc", "foo",
270 [](AbckitFile * /*file*/, AbckitCoreFunction * /*method*/, AbckitGraph *graph) {
271 TransformIrIgetConditionCodeNeg(graph);
272 },
273 [](AbckitGraph *graph) { helpers::VerifyGraph(graph, GetSchema()); });
274
275 auto output = helpers::ExecuteDynamicAbc(
276 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/create_if/create_if_dynamic_modified_get_neg.abc", "create_if_dynamic");
277 EXPECT_TRUE(helpers::Match(output, "0\n"));
278 }
279
280 // Test: test-kind=api, api=IsaApiDynamicImpl::iSetConditionCode, abc-kind=ArkTS1, category=positive, extension=c
TEST_F(LibAbcKitCreateIfDynamicTest,LibAbcKitTestSetConditionCode)281 TEST_F(LibAbcKitCreateIfDynamicTest, LibAbcKitTestSetConditionCode)
282 {
283 helpers::TransformMethod(
284 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/create_if/create_if_dynamic.abc",
285 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/create_if/create_if_dynamic_modified_set.abc", "foo",
286 [](AbckitFile * /*file*/, AbckitCoreFunction * /*method*/, AbckitGraph *graph) {
287 TransformIrIsetConditionCode(graph);
288 },
289 [](AbckitGraph *graph) { helpers::VerifyGraph(graph, GetSchema()); });
290
291 auto output = helpers::ExecuteDynamicAbc(
292 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/create_if/create_if_dynamic_modified_set.abc", "create_if_dynamic");
293 EXPECT_TRUE(helpers::Match(output, "0\n"));
294 }
295
296 // Test: test-kind=api, api=IsaApiDynamicImpl::iSetConditionCode, abc-kind=ArkTS1, category=negative
TEST_F(LibAbcKitCreateIfDynamicTest,LibAbcKitTestSetConditionCodeNeg)297 TEST_F(LibAbcKitCreateIfDynamicTest, LibAbcKitTestSetConditionCodeNeg)
298 {
299 helpers::TransformMethod(
300 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/create_if/create_if_dynamic.abc",
301 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/create_if/create_if_dynamic_modified_set_neg.abc", "foo",
302 [](AbckitFile * /*file*/, AbckitCoreFunction * /*method*/, AbckitGraph *graph) {
303 TransformIrIsetConditionCodeNeg(graph);
304 },
305 [](AbckitGraph *graph) { helpers::VerifyGraph(graph, GetSchema()); });
306
307 auto output = helpers::ExecuteDynamicAbc(
308 ABCKIT_ABC_DIR "ut/isa/isa_dynamic/create_if/create_if_dynamic_modified_set_neg.abc", "create_if_dynamic");
309 EXPECT_TRUE(helpers::Match(output, "0\n"));
310 }
311
312 } // namespace libabckit::test
313 // NOLINTEND(readability-magic-numbers)
314