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/metadata_core.h"
17 #include "libabckit/include/c/ir_core.h"
18 #include "libabckit/include/c/abckit.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 static auto g_impl = AbckitGetApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
29 static auto g_implI = AbckitGetInspectApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
30 static auto g_implM = AbckitGetModifyApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
31 static auto g_implG = AbckitGetGraphApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
32 static auto g_statG = AbckitGetIsaApiStaticImpl(ABCKIT_VERSION_RELEASE_1_0_0);
33
34 class LibAbcKitCreateReturnInstTest : public ::testing::Test {};
35
TransformIrCreateReturnInstValid(AbckitGraph * graph)36 static void TransformIrCreateReturnInstValid(AbckitGraph *graph)
37 {
38 AbckitInst *firstInst = g_implG->gFindOrCreateConstantI64(graph, 5);
39 AbckitInst *mainInst = g_statG->iCreateReturn(graph, firstInst);
40 ASSERT_NE(mainInst, nullptr);
41
42 auto retOp = helpers::FindFirstInst(graph, ABCKIT_ISA_API_STATIC_OPCODE_RETURN);
43 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
44 g_implG->iInsertBefore(mainInst, retOp);
45 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
46 g_implG->iRemove(retOp);
47 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
48 }
49
TransformIrCreateReturnVoidInstValid(AbckitGraph * graph)50 static void TransformIrCreateReturnVoidInstValid(AbckitGraph *graph)
51 {
52 AbckitBasicBlock *startBB = g_implG->gGetStartBasicBlock(graph);
53 AbckitInst *inputInst = g_implG->iGetNext(g_implG->bbGetFirstInst(startBB));
54 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
55
56 AbckitInst *mainInst = g_statG->iCreateReturnVoid(graph);
57 ASSERT_NE(mainInst, nullptr);
58
59 auto callVirt = helpers::FindFirstInst(graph, ABCKIT_ISA_API_STATIC_OPCODE_CALL_STATIC);
60 ASSERT_NE(callVirt, nullptr);
61 AbckitInst *nextInst = g_implG->iGetNext(callVirt);
62 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
63 g_implG->iRemove(nextInst);
64 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
65
66 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
67 g_implG->iInsertAfter(mainInst, callVirt);
68 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
69 g_implG->iSetInput(callVirt, inputInst, 1);
70 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
71 }
72
73 // Test: test-kind=api, api=IsaApiStaticImpl::iCreateReturn, abc-kind=ArkTS2, category=positive, extension=c
TEST_F(LibAbcKitCreateReturnInstTest,CreateReturnValid)74 TEST_F(LibAbcKitCreateReturnInstTest, CreateReturnValid)
75 {
76 auto output = helpers::ExecuteStaticAbc(ABCKIT_ABC_DIR "ut/isa/isa_static/return/return_static.abc",
77 "return_static/ETSGLOBAL", "main");
78 EXPECT_TRUE(helpers::Match(output, "10\n11\n"));
79
80 helpers::TransformMethod(
81 ABCKIT_ABC_DIR "ut/isa/isa_static/return/return_static.abc",
82 ABCKIT_ABC_DIR "ut/isa/isa_static/return/return_static_modified.abc", "foo",
83 [](AbckitFile * /*file*/, AbckitCoreFunction * /*method*/, AbckitGraph *graph) {
84 TransformIrCreateReturnInstValid(graph);
85 },
86 [&](AbckitGraph *graph) {
87 std::vector<helpers::BBSchema<AbckitIsaApiStaticOpcode>> bbSchemas(
88 {{{},
89 {1},
90 {{4, ABCKIT_ISA_API_STATIC_OPCODE_PARAMETER, {}},
91 {5, ABCKIT_ISA_API_STATIC_OPCODE_PARAMETER, {}},
92 {2, ABCKIT_ISA_API_STATIC_OPCODE_CONSTANT, {}}}},
93 {{0}, {2}, {{3, ABCKIT_ISA_API_STATIC_OPCODE_RETURN, {2}}}},
94 {{1}, {}, {}}});
95 helpers::VerifyGraph(graph, bbSchemas);
96 });
97
98 output = helpers::ExecuteStaticAbc(ABCKIT_ABC_DIR "ut/isa/isa_static/return/return_static_modified.abc",
99 "return_static/ETSGLOBAL", "main");
100 EXPECT_TRUE(helpers::Match(output, "5\n11\n"));
101 }
102
103 // Test: test-kind=api, api=IsaApiStaticImpl::iCreateReturnVoid, abc-kind=ArkTS2, category=positive, extension=c
TEST_F(LibAbcKitCreateReturnInstTest,CreateReturnVoidValid)104 TEST_F(LibAbcKitCreateReturnInstTest, CreateReturnVoidValid)
105 {
106 auto output = helpers::ExecuteStaticAbc(ABCKIT_ABC_DIR "ut/isa/isa_static/return/return_static.abc",
107 "return_static/ETSGLOBAL", "main");
108 EXPECT_TRUE(helpers::Match(output, "10\n11\n"));
109
110 helpers::TransformMethod(
111 ABCKIT_ABC_DIR "ut/isa/isa_static/return/return_static.abc",
112 ABCKIT_ABC_DIR "ut/isa/isa_static/return/return_static_modified.abc", "foo1",
113 [](AbckitFile * /*file*/, AbckitCoreFunction * /*method*/, AbckitGraph *graph) {
114 TransformIrCreateReturnVoidInstValid(graph);
115 },
116 [&](AbckitGraph *graph) {
117 std::vector<helpers::BBSchema<AbckitIsaApiStaticOpcode>> bbSchemas(
118 {{{},
119 {1},
120 {{7, ABCKIT_ISA_API_STATIC_OPCODE_PARAMETER, {}}, {1, ABCKIT_ISA_API_STATIC_OPCODE_PARAMETER, {}}}},
121 {{0},
122 {2},
123 {{2, ABCKIT_ISA_API_STATIC_OPCODE_LOADSTATIC, {}},
124 {5, ABCKIT_ISA_API_STATIC_OPCODE_CALL_STATIC, {2, 1}},
125 {6, ABCKIT_ISA_API_STATIC_OPCODE_RETURN_VOID, {}}}},
126 {{1}, {}, {}}});
127 helpers::VerifyGraph(graph, bbSchemas);
128 });
129
130 output = helpers::ExecuteStaticAbc(ABCKIT_ABC_DIR "ut/isa/isa_static/return/return_static_modified.abc",
131 "return_static/ETSGLOBAL", "main");
132 EXPECT_TRUE(helpers::Match(output, "10\n10\n"));
133 }
134
135 } // namespace libabckit::test
136 // NOLINTEND(readability-magic-numbers)
137