• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 "compiler/tests/unit_test.h"
17 #include "irtoc/backend/compiler/dangling_pointers_checker.h"
18 #include "irtoc/backend/function.h"
19 #include "irtoc/backend/irtoc_runtime.h"
20 
21 namespace ark::compiler {
22 class DanglingPointersCheckerTest : public GraphTest {};
23 
24 class RelocationHandlerTest : public ark::irtoc::Function {
25 public:
MakeGraphImpl()26     void MakeGraphImpl() override {};
GetName() const27     const char *GetName() const override
28     {
29         return "Test";
30     };
SetTestExternalFunctions(std::initializer_list<std::string> funcs)31     void SetTestExternalFunctions(std::initializer_list<std::string> funcs)
32     {
33         this->SetExternalFunctions(funcs);
34     }
35 };
36 
37 // NOLINTBEGIN(readability-magic-numbers)
38 
39 // Correct load accumulator from frame with one instruction:
40 //    correct_acc_load  := LoadI(LiveIn(frame).ptr).Imm(frame_acc_offset).ref
41 // Correct store into frame with instruction:
42 //    correct_acc_store := StoreI(LiveIn(frame).ptr, correct_acc_load).Imm(frame_acc_offset).ref
TEST_F(DanglingPointersCheckerTest,test0)43 TEST_F(DanglingPointersCheckerTest, test0)
44 {
45     auto arch = ark::RUNTIME_ARCH;
46     SetGraphArch(arch);
47     if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
48         return;
49     }
50     auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
51     auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
52     RelocationHandlerTest relocationHandler;
53     relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
54     GetGraph()->SetRelocationHandler(&relocationHandler);
55     GetGraph()->SetMethod(&relocationHandler);
56     GetGraph()->SetMode(GraphMode::InterpreterEntry());
57 
58     GRAPH(GetGraph())
59     {
60         INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
61         INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
62         INST(2U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
63 
64         BASIC_BLOCK(2U, -1L)
65         {
66             INST(5U, Opcode::LoadI).Inputs(0U).ref().Imm(frameAccOffset);
67             INST(6U, Opcode::StoreI).ref().Inputs(0U, 5U).Imm(frameAccOffset);
68 
69             // store tag
70             INST(30U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
71             INST(31U, Opcode::StoreI).u64().Inputs(30U, 2U).Imm(accTagOffset);
72 
73             INST(3U, Opcode::Call).TypeId(0U).ptr();
74             INST(4U, Opcode::ReturnVoid).v0id();
75         }
76     }
77 
78     irtoc::IrtocRuntimeInterface runtime;
79     GetGraph()->SetRuntime(&runtime);
80 
81     ASSERT_TRUE(GetGraph()->RunPass<ark::compiler::DanglingPointersChecker>());
82 }
83 
84 // Correct load accumulator from frame with two instructions:
85 //    acc_ptr           := AddI(LiveIn(frame).ptr).Imm(frame_acc_offset).ptr
86 //    correct_acc_load  := LoadI(acc_ptr).Imm(frame_acc_offset).ref
87 // Correct store into frame with instruction:
88 //    correct_acc_store := StoreI(LiveIn(frame).ptr, correct_acc_load).Imm(frame_acc_offset).ref
TEST_F(DanglingPointersCheckerTest,test1)89 TEST_F(DanglingPointersCheckerTest, test1)
90 {
91     auto arch = ark::RUNTIME_ARCH;
92     SetGraphArch(arch);
93     if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
94         return;
95     }
96     auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
97     auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
98     RelocationHandlerTest relocationHandler;
99     relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
100     GetGraph()->SetRelocationHandler(&relocationHandler);
101     GetGraph()->SetMethod(&relocationHandler);
102     GetGraph()->SetMode(GraphMode::InterpreterEntry());
103 
104     GRAPH(GetGraph())
105     {
106         INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
107         INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
108         INST(2U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
109         CONSTANT(10U, 10U).i64();
110         CONSTANT(11U, 15U).i64();
111 
112         BASIC_BLOCK(2U, -1L)
113         {
114             INST(5U, Opcode::AddI).Inputs(0U).Imm(frameAccOffset).ptr();
115             INST(6U, Opcode::LoadI).Inputs(5U).ref().Imm(0U);
116             INST(8U, Opcode::StoreI).ref().Inputs(0U, 6U).Imm(frameAccOffset);
117             INST(7U, Opcode::Mul).Inputs(10U, 11U).i64();
118 
119             // store tag
120             INST(30U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
121             INST(31U, Opcode::StoreI).u64().Inputs(30U, 2U).Imm(accTagOffset);
122 
123             INST(3U, Opcode::Call).TypeId(0U).Inputs({{compiler::DataType::INT64, 7U}}).ptr();
124             INST(4U, Opcode::ReturnVoid).v0id();
125         }
126     }
127 
128     irtoc::IrtocRuntimeInterface runtime;
129     GetGraph()->SetRuntime(&runtime);
130 
131     ASSERT_TRUE(GetGraph()->RunPass<ark::compiler::DanglingPointersChecker>());
132 }
133 
134 // Incorrect load accumulator from fake frame with two instructions:
135 //    fake_acc_ptr       := AddI(fake_frame).Imm(frame_acc_offset).ptr
136 //    incorrect_acc_load := LoadI(fake_acc_ptr).Imm(0).ref
137 // Correct store into frame with instruction:
138 //    correct_acc_store  := StoreI(LiveIn(frame).ptr, LiveIn(acc).ptr).Imm(frame_acc_offset)
TEST_F(DanglingPointersCheckerTest,test2)139 TEST_F(DanglingPointersCheckerTest, test2)
140 {
141     auto arch = ark::RUNTIME_ARCH;
142     SetGraphArch(arch);
143     if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
144         return;
145     }
146     auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
147     auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
148     RelocationHandlerTest relocationHandler;
149     relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
150     GetGraph()->SetRelocationHandler(&relocationHandler);
151     GetGraph()->SetMethod(&relocationHandler);
152     GetGraph()->SetMode(GraphMode::InterpreterEntry());
153 
154     GRAPH(GetGraph())
155     {
156         INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
157         INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
158         INST(2U, Opcode::LiveIn).i64().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
159 
160         BASIC_BLOCK(2U, -1L)
161         {
162             INST(5U, Opcode::AddI).Inputs(1U).Imm(frameAccOffset).ptr();
163             INST(6U, Opcode::LoadI).Inputs(5U).ref().Imm(0U);
164             INST(8U, Opcode::StoreI).u64().Inputs(0U, 1U).Imm(frameAccOffset);
165 
166             // store tag
167             INST(30U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
168             INST(31U, Opcode::StoreI).u64().Inputs(30U, 2U).Imm(accTagOffset);
169 
170             INST(3U, Opcode::Call).TypeId(0U).ptr();
171             INST(4U, Opcode::ReturnVoid).v0id();
172         }
173     }
174 
175     irtoc::IrtocRuntimeInterface runtime;
176     GetGraph()->SetRuntime(&runtime);
177 
178     ASSERT_TRUE(GetGraph()->RunPass<ark::compiler::DanglingPointersChecker>());
179 }
180 
181 // Incorrect load accumulator from fake frame with two instructions:
182 //    fake_acc_ptr        := AddI(fake_frame).Imm(frame_acc_offset).ptr
183 //    incorrect_acc_load  := LoadI(fake_acc_ptr).Imm(0).ref
184 // Incorrect store fake_acc_load into frame with instruction:
185 //    incorrect_acc_store := StoreI(LiveIn(frame).ptr, fake_acc_load).Imm(frame_acc_offset)
TEST_F(DanglingPointersCheckerTest,test3)186 TEST_F(DanglingPointersCheckerTest, test3)
187 {
188     auto arch = ark::RUNTIME_ARCH;
189     SetGraphArch(arch);
190     if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
191         return;
192     }
193     auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
194     auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
195     RelocationHandlerTest relocationHandler;
196     relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
197     GetGraph()->SetRelocationHandler(&relocationHandler);
198     GetGraph()->SetMethod(&relocationHandler);
199     GetGraph()->SetMode(GraphMode::InterpreterEntry());
200 
201     GRAPH(GetGraph())
202     {
203         INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
204         INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
205         INST(2U, Opcode::LiveIn).i64().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
206 
207         BASIC_BLOCK(2U, -1L)
208         {
209             INST(5U, Opcode::AddI).Inputs(1U).Imm(frameAccOffset).ptr();
210             INST(6U, Opcode::LoadI).Inputs(5U).ref().Imm(0U);
211             INST(8U, Opcode::StoreI).ref().Inputs(0U, 6U).Imm(frameAccOffset);
212 
213             // store tag
214             INST(30U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
215             INST(31U, Opcode::StoreI).u64().Inputs(30U, 2U).Imm(accTagOffset);
216 
217             INST(3U, Opcode::Call).TypeId(0U).ptr();
218             INST(4U, Opcode::ReturnVoid).v0id();
219         }
220     }
221 
222     irtoc::IrtocRuntimeInterface runtime;
223     GetGraph()->SetRuntime(&runtime);
224 
225     ASSERT_FALSE(GetGraph()->RunPass<ark::compiler::DanglingPointersChecker>());
226 }
227 
228 // Incorrect load accumulator from fake frame with two instructions:
229 //    fake_acc_ptr        := AddI(fake_frame).Imm(frame_acc_offset).ptr
230 //    incorrect_acc_load  := LoadI(fake_acc_ptr).Imm(0).ref
231 // Incorrect store fake_acc_load into frame with instruction:
232 //    incorrect_acc_store := StoreI(LiveIn(frame).ptr, fake_acc_load).Imm(frame_acc_offset)
233 // But acc type is integer: LiveIn(acc).u64; so the check is not performed
TEST_F(DanglingPointersCheckerTest,test4)234 TEST_F(DanglingPointersCheckerTest, test4)
235 {
236     auto arch = ark::RUNTIME_ARCH;
237     SetGraphArch(arch);
238     if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
239         return;
240     }
241     auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
242     auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
243     RelocationHandlerTest relocationHandler;
244     relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
245     GetGraph()->SetRelocationHandler(&relocationHandler);
246     GetGraph()->SetMethod(&relocationHandler);
247     GetGraph()->SetMode(GraphMode::InterpreterEntry());
248 
249     GRAPH(GetGraph())
250     {
251         INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
252         INST(1U, Opcode::LiveIn).u64().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
253         INST(2U, Opcode::LiveIn).i64().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
254         INST(10U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["thread"]);
255 
256         BASIC_BLOCK(2U, -1L)
257         {
258             INST(5U, Opcode::AddI).Inputs(10U).Imm(frameAccOffset).ptr();
259             INST(6U, Opcode::LoadI).Inputs(5U).ref().Imm(0U);
260             INST(8U, Opcode::StoreI).ref().Inputs(0U, 6U).Imm(frameAccOffset);
261 
262             // store tag
263             INST(30U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
264             INST(31U, Opcode::StoreI).u64().Inputs(30U, 2U).Imm(accTagOffset);
265 
266             INST(3U, Opcode::Call).TypeId(0U).ptr();
267             INST(4U, Opcode::ReturnVoid).v0id();
268         }
269     }
270 
271     irtoc::IrtocRuntimeInterface runtime;
272     GetGraph()->SetRuntime(&runtime);
273 
274     ASSERT_TRUE(GetGraph()->RunPass<ark::compiler::DanglingPointersChecker>());
275 }
276 
277 // Correct load accumulator from last frame definition with two instructions:
278 //    last_frame_def    := LoadI(LiveIn(frame).ptr).Imm(GetPrevFrameOffset()).ptr
279 //    acc_ptr           := AddI(last_frame_def).Imm(frame_acc_offset).ptr
280 //    correct_acc_load  := LoadI(acc_ptr).Imm(0).ref
281 // Correct store into frame with instruction:
282 //    correct_acc_store := StoreI(last_frame_def, correct_acc_load).Imm(frame_acc_offset).ref
TEST_F(DanglingPointersCheckerTest,test5)283 TEST_F(DanglingPointersCheckerTest, test5)
284 {
285     auto arch = ark::RUNTIME_ARCH;
286     SetGraphArch(arch);
287     if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
288         return;
289     }
290     auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
291     auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
292     RelocationHandlerTest relocationHandler;
293     relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
294     GetGraph()->SetRelocationHandler(&relocationHandler);
295     GetGraph()->SetMethod(&relocationHandler);
296     GetGraph()->SetMode(GraphMode::InterpreterEntry());
297 
298     GRAPH(GetGraph())
299     {
300         INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
301         INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
302         INST(2U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
303         CONSTANT(10U, 10U).i64();
304         CONSTANT(11U, 15U).i64();
305 
306         BASIC_BLOCK(2U, -1L)
307         {
308             INST(8U, Opcode::LoadI).Inputs(0U).ptr().Imm(Frame::GetPrevFrameOffset());
309             INST(5U, Opcode::AddI).Inputs(8U).Imm(frameAccOffset).ptr();
310             INST(6U, Opcode::LoadI).Inputs(5U).ref().Imm(0U);
311             INST(7U, Opcode::Mul).Inputs(10U, 11U).i64();
312             INST(9U, Opcode::StoreI).ref().Inputs(8U, 6U).Imm(frameAccOffset);
313 
314             // store tag
315             INST(31U, Opcode::StoreI).u64().Inputs(5U, 2U).Imm(accTagOffset);
316 
317             INST(3U, Opcode::Call).TypeId(0U).Inputs({{compiler::DataType::INT64, 7U}}).ptr();
318             INST(4U, Opcode::ReturnVoid).v0id();
319         }
320     }
321 
322     irtoc::IrtocRuntimeInterface runtime;
323     GetGraph()->SetRuntime(&runtime);
324 
325     ASSERT_TRUE(GetGraph()->RunPass<ark::compiler::DanglingPointersChecker>());
326 }
327 
328 // Correct load accumulator from last frame definition with one instructions:
329 //    last_frame_def      := LoadI(LiveIn(frame).ptr).Imm(GetPrevFrameOffset()).ptr
330 //    correct_acc_load    := LoadI(last_frame_def).Imm(frame_acc_offset).ref
331 // Incorrect store into old frame with instruction:
332 //    incorrect_acc_store := StoreI(LiveIn(frame).ptr, correct_acc_load).Imm(frame_acc_offset).ref
TEST_F(DanglingPointersCheckerTest,test6)333 TEST_F(DanglingPointersCheckerTest, test6)
334 {
335     auto arch = ark::RUNTIME_ARCH;
336     SetGraphArch(arch);
337     if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
338         return;
339     }
340     auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
341     auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
342     RelocationHandlerTest relocationHandler;
343     relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
344     GetGraph()->SetRelocationHandler(&relocationHandler);
345     GetGraph()->SetMethod(&relocationHandler);
346     GetGraph()->SetMode(GraphMode::InterpreterEntry());
347 
348     GRAPH(GetGraph())
349     {
350         INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
351         INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
352         INST(2U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["thread"]);
353         INST(10U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
354 
355         BASIC_BLOCK(2U, -1L)
356         {
357             INST(8U, Opcode::LoadI).Inputs(2U).ptr().Imm(ManagedThread::GetFrameOffset());
358             INST(5U, Opcode::LoadI).Inputs(8U).Imm(frameAccOffset).ref();
359             INST(9U, Opcode::StoreI).ref().Inputs(0U, 5U).Imm(frameAccOffset);
360 
361             // store tag
362             INST(30U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
363             INST(31U, Opcode::StoreI).u64().Inputs(30U, 10U).Imm(accTagOffset);
364 
365             INST(3U, Opcode::Call).TypeId(0U).ptr();
366             INST(4U, Opcode::ReturnVoid).v0id();
367         }
368     }
369 
370     irtoc::IrtocRuntimeInterface runtime;
371     GetGraph()->SetRuntime(&runtime);
372 
373     ASSERT_FALSE(GetGraph()->RunPass<ark::compiler::DanglingPointersChecker>());
374 }
375 
376 // Correct load accumulator from last frame definition with one instructions:
377 //    last_frame_def      := LoadI(LiveIn(frame).ptr).Imm(GetPrevFrameOffset()).ptr
378 //    correct_acc_load    := LoadI(last_frame_def).Imm(frame_acc_offset).ref
379 // Incorrect store into old frame with instruction:
380 //    incorrect_acc_store := StoreI(LiveIn(frame).ptr, correct_acc_load).Imm(frame_acc_offset).ref
TEST_F(DanglingPointersCheckerTest,test7)381 TEST_F(DanglingPointersCheckerTest, test7)
382 {
383     auto arch = ark::RUNTIME_ARCH;
384     SetGraphArch(arch);
385     if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
386         return;
387     }
388     auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
389     auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
390     RelocationHandlerTest relocationHandler;
391     relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
392     GetGraph()->SetRelocationHandler(&relocationHandler);
393     GetGraph()->SetMethod(&relocationHandler);
394     GetGraph()->SetMode(GraphMode::InterpreterEntry());
395 
396     GRAPH(GetGraph())
397     {
398         INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
399         INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
400         INST(2U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
401         CONSTANT(10U, 10U).i64();
402         CONSTANT(11U, 15U).i64();
403 
404         BASIC_BLOCK(2U, -1L)
405         {
406             INST(8U, Opcode::LoadI).Inputs(0U).ptr().Imm(Frame::GetPrevFrameOffset());
407             INST(5U, Opcode::AddI).Inputs(8U).Imm(frameAccOffset).ptr();
408             INST(6U, Opcode::LoadI).Inputs(5U).ref().Imm(0U);
409             INST(7U, Opcode::Mul).Inputs(10U, 11U).i64();
410             INST(9U, Opcode::StoreI).ref().Inputs(0U, 6U).Imm(frameAccOffset);
411 
412             // store tag
413             INST(30U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
414             INST(31U, Opcode::StoreI).u64().Inputs(30U, 2U).Imm(accTagOffset);
415 
416             INST(3U, Opcode::Call).TypeId(0U).Inputs({{compiler::DataType::INT64, 7U}}).ptr();
417             INST(4U, Opcode::ReturnVoid).v0id();
418         }
419     }
420 
421     irtoc::IrtocRuntimeInterface runtime;
422     GetGraph()->SetRuntime(&runtime);
423 
424     ASSERT_FALSE(GetGraph()->RunPass<ark::compiler::DanglingPointersChecker>());
425 }
426 
427 // Use old accumulator after Call
TEST_F(DanglingPointersCheckerTest,test8)428 TEST_F(DanglingPointersCheckerTest, test8)
429 {
430     auto arch = ark::RUNTIME_ARCH;
431     SetGraphArch(arch);
432     if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
433         return;
434     }
435     auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
436     auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
437     RelocationHandlerTest relocationHandler;
438     relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
439     GetGraph()->SetRelocationHandler(&relocationHandler);
440     GetGraph()->SetMethod(&relocationHandler);
441     GetGraph()->SetMode(GraphMode::InterpreterEntry());
442 
443     GRAPH(GetGraph())
444     {
445         INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
446         INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
447         INST(2U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
448 
449         BASIC_BLOCK(2U, -1L)
450         {
451             INST(5U, Opcode::LoadI).Inputs(0U).ref().Imm(frameAccOffset);
452             INST(6U, Opcode::StoreI).ref().Inputs(0U, 5U).Imm(frameAccOffset);
453 
454             // store tag
455             INST(30U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
456             INST(31U, Opcode::StoreI).u64().Inputs(30U, 2U).Imm(accTagOffset);
457 
458             INST(3U, Opcode::Call).TypeId(0U).ptr();
459             INST(7U, Opcode::StoreI).ref().Inputs(0U, 5U).Imm(frameAccOffset);
460             INST(4U, Opcode::ReturnVoid).v0id();
461         }
462     }
463 
464     irtoc::IrtocRuntimeInterface runtime;
465     GetGraph()->SetRuntime(&runtime);
466 
467     ASSERT_FALSE(GetGraph()->RunPass<ark::compiler::DanglingPointersChecker>());
468 }
469 
470 // The correct graph. Not use old acc after call.
471 //          start_bb
472 //             |
473 //             V
474 //   ------------------------------------
475 //  | bb_2 | new_acc_load, new_acc_store |
476 //   ------------------------------------
477 //      |
478 //      V
479 //   --------------------    --------------------
480 //  | bb_3 | use_old_acc |  | bb_4 | use_old_acc |
481 //   --------------------    --------------------
482 //      |                      |
483 //      V                      V
484 //    -------------          ------
485 //   | bb_5 | Call |        | bb_8 |
486 //    -------------\        -------
487 //      |           |       A     |
488 //      V           V       |     V
489 //    ------         --------     ------
490 //   | bb_6 |       |  bb_7  |-->| bb_9 |--> end_bb
491 //    ------         --------     ------
492 // CC-OFFNXT(huge_method[C++],G.FUN.01-CPP) graph creation
TEST_F(DanglingPointersCheckerTest,test9)493 TEST_F(DanglingPointersCheckerTest, test9)
494 {
495     auto arch = ark::RUNTIME_ARCH;
496     SetGraphArch(arch);
497     if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
498         return;
499     }
500     auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
501     auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
502     RelocationHandlerTest relocationHandler;
503     relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
504     GetGraph()->SetRelocationHandler(&relocationHandler);
505     GetGraph()->SetMethod(&relocationHandler);
506     GetGraph()->SetMode(GraphMode::InterpreterEntry());
507 
508     GRAPH(GetGraph())
509     {
510         INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
511         INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
512         INST(2U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
513         CONSTANT(10U, 10U);
514         CONSTANT(11U, 11U);
515         CONSTANT(12U, 12U);
516 
517         BASIC_BLOCK(2U, 3U, 4U)
518         {
519             INST(4U, Opcode::LoadI).Inputs(0U).ref().Imm(frameAccOffset);
520             INST(5U, Opcode::StoreI).ref().Inputs(0U, 4U).Imm(frameAccOffset);
521             INST(19U, Opcode::AddI).Inputs(11U).Imm(frameAccOffset).u64();
522             INST(20U, Opcode::Mul).Inputs(12U, 19U).u64();
523             INST(22U, Opcode::If).Inputs(19U, 20U).b().CC(CC_LE);
524         }
525         BASIC_BLOCK(3U, 5U)
526         {
527             INST(6U, Opcode::StoreI).ref().Inputs(0U, 4U).Imm(frameAccOffset);
528         }
529         BASIC_BLOCK(4U, 8U)
530         {
531             INST(7U, Opcode::StoreI).ref().Inputs(0U, 4U).Imm(frameAccOffset);
532         }
533         BASIC_BLOCK(5U, 6U, 7U)
534         {
535             // store tag
536             INST(30U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
537             INST(31U, Opcode::StoreI).u64().Inputs(30U, 2U).Imm(accTagOffset);
538 
539             INST(3U, Opcode::Call).TypeId(0U).ptr();
540             INST(17U, Opcode::AddI).Inputs(11U).Imm(frameAccOffset).u64();
541             INST(18U, Opcode::Mul).Inputs(12U, 17U).u64();
542             INST(21U, Opcode::If).Inputs(17U, 18U).b().CC(CC_NE);
543         }
544         BASIC_BLOCK(6U, 9U)
545         {
546             INST(8U, Opcode::AddI).Inputs(10U).Imm(frameAccOffset).u64();
547         }
548         BASIC_BLOCK(7U, 8U, 9U)
549         {
550             INST(16U, Opcode::AddI).Inputs(11U).Imm(frameAccOffset).u64();
551             INST(9U, Opcode::Mul).Inputs(12U, 16U).u64();
552             INST(15U, Opcode::If).Inputs(9U, 16U).b().CC(CC_EQ);
553         }
554         BASIC_BLOCK(8U, 9U)
555         {
556             INST(13U, Opcode::AddI).Inputs(12U).Imm(frameAccOffset).u64();
557         }
558 
559         BASIC_BLOCK(9U, -1L)
560         {
561             INST(14U, Opcode::ReturnVoid).v0id();
562         }
563     }
564 
565     irtoc::IrtocRuntimeInterface runtime;
566     GetGraph()->SetRuntime(&runtime);
567 
568     ASSERT_TRUE(GetGraph()->RunPass<ark::compiler::DanglingPointersChecker>());
569 }
570 
571 // The incorrect graph. Use old acc after call.
572 //          start_bb
573 //             |
574 //             V
575 //   ------------------------------------
576 //  | bb_2 | new_acc_load, new_acc_store |
577 //   ------------------------------------
578 //      |
579 //      V
580 //   --------------------    --------------------
581 //  | bb_3 | use_old_acc |  | bb_4 | use_old_acc |
582 //   --------------------    --------------------
583 //      |                      |
584 //      V                      V
585 //    -------------          --------------------
586 //   | bb_5 | Call |        | bb_8 | use_old_acc |
587 //    -------------\        ---------------------
588 //      |           |       A     |
589 //      V           V       |     V
590 //    ------         --------     ------
591 //   | bb_6 |       |  bb_7  |-->| bb_9 |--> end_bb
592 //    ------         --------     ------
593 // CC-OFFNXT(huge_method[C++],G.FUN.01-CPP) graph creation
TEST_F(DanglingPointersCheckerTest,test10)594 TEST_F(DanglingPointersCheckerTest, test10)
595 {
596     auto arch = ark::RUNTIME_ARCH;
597     SetGraphArch(arch);
598     if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
599         return;
600     }
601     auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
602     auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
603     RelocationHandlerTest relocationHandler;
604     relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
605     GetGraph()->SetRelocationHandler(&relocationHandler);
606     GetGraph()->SetMethod(&relocationHandler);
607     GetGraph()->SetMode(GraphMode::InterpreterEntry());
608 
609     GRAPH(GetGraph())
610     {
611         INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
612         INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
613         INST(2U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
614         CONSTANT(10U, 10U);
615         CONSTANT(11U, 11U);
616         CONSTANT(12U, 12U);
617 
618         BASIC_BLOCK(2U, 3U, 4U)
619         {
620             INST(4U, Opcode::LoadI).Inputs(0U).ref().Imm(frameAccOffset);
621             INST(5U, Opcode::StoreI).ref().Inputs(0U, 4U).Imm(frameAccOffset);
622             INST(19U, Opcode::AddI).Inputs(11U).Imm(frameAccOffset).u64();
623             INST(20U, Opcode::Mul).Inputs(12U, 19U).u64();
624             INST(22U, Opcode::If).Inputs(19U, 20U).b().CC(CC_LE);
625         }
626         BASIC_BLOCK(3U, 5U)
627         {
628             INST(6U, Opcode::StoreI).ref().Inputs(0U, 4U).Imm(frameAccOffset);
629         }
630         BASIC_BLOCK(4U, 8U)
631         {
632             INST(7U, Opcode::StoreI).ref().Inputs(0U, 4U).Imm(frameAccOffset);
633         }
634         BASIC_BLOCK(5U, 6U, 7U)
635         {
636             // store tag
637             INST(30U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
638             INST(31U, Opcode::StoreI).u64().Inputs(30U, 2U).Imm(accTagOffset);
639 
640             INST(3U, Opcode::Call).TypeId(0U).ptr();
641             INST(17U, Opcode::AddI).Inputs(11U).Imm(frameAccOffset).u64();
642             INST(18U, Opcode::Mul).Inputs(12U, 17U).u64();
643             INST(21U, Opcode::If).Inputs(17U, 18U).b().CC(CC_NE);
644         }
645         BASIC_BLOCK(6U, 9U)
646         {
647             INST(8U, Opcode::AddI).Inputs(10U).Imm(frameAccOffset).u64();
648         }
649         BASIC_BLOCK(7U, 8U, 9U)
650         {
651             INST(16U, Opcode::AddI).Inputs(11U).Imm(frameAccOffset).u64();
652             INST(9U, Opcode::Mul).Inputs(12U, 16U).u64();
653             INST(15U, Opcode::If).Inputs(9U, 16U).b().CC(CC_EQ);
654         }
655         BASIC_BLOCK(8U, 9U)
656         {
657             INST(23U, Opcode::StoreI).ref().Inputs(0U, 4U).Imm(frameAccOffset);
658             INST(13U, Opcode::AddI).Inputs(12U).Imm(frameAccOffset).u64();
659         }
660 
661         BASIC_BLOCK(9U, -1L)
662         {
663             INST(14U, Opcode::ReturnVoid).v0id();
664         }
665     }
666 
667     irtoc::IrtocRuntimeInterface runtime;
668     GetGraph()->SetRuntime(&runtime);
669 
670     ASSERT_FALSE(GetGraph()->RunPass<ark::compiler::DanglingPointersChecker>());
671 }
672 
673 // The correct graph. Use Phi to define acc that has been changed in one branch.
674 //          start_bb
675 //             |
676 //             V
677 //         -----------------------------
678 //        |           bb_2              |
679 //         -----------------------------
680 //         |                           |
681 //         V                           |
682 //   -----------------------------     |
683 //  | bb_3 | load_acc, change_acc |    |
684 //   -----------------------------     |
685 //                             |       |
686 //                             V       V
687 //               ------------------------------------------------
688 //              |      | last_acc_def = Phi(live_in, change_acc) |
689 //              | bb_4 | store(last_acc_def)                     |
690 //              |      | Call                                    |
691 //               ------------------------------------------------
692 //                                     |
693 //                                     V
694 //                                  end_bb
695 
TEST_F(DanglingPointersCheckerTest,test11)696 TEST_F(DanglingPointersCheckerTest, test11)
697 {
698     auto arch = ark::RUNTIME_ARCH;
699     SetGraphArch(arch);
700     if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
701         return;
702     }
703     auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
704     auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
705     RelocationHandlerTest relocationHandler;
706     relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
707     GetGraph()->SetRelocationHandler(&relocationHandler);
708     GetGraph()->SetMethod(&relocationHandler);
709     GetGraph()->SetMode(GraphMode::InterpreterEntry());
710 
711     GRAPH(GetGraph())
712     {
713         INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
714         INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
715         INST(2U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
716         CONSTANT(10U, 10U);
717         CONSTANT(11U, 11U);
718 
719         BASIC_BLOCK(2U, 3U, 4U)
720         {
721             INST(3U, Opcode::AddI).Inputs(10U).Imm(frameAccOffset).u64();
722             INST(4U, Opcode::If).Inputs(3U, 11U).b().CC(CC_NE);
723         }
724         BASIC_BLOCK(3U, 4U)
725         {
726             INST(5U, Opcode::LoadI).Inputs(0U).ref().Imm(frameAccOffset);
727             INST(6U, Opcode::AddI).Inputs(5U).ptr().Imm(10U);
728         }
729         BASIC_BLOCK(4U, -1L)
730         {
731             INST(7U, Opcode::Phi).Inputs(1U, 6U).ptr();
732             INST(8U, Opcode::StoreI).ref().Inputs(0U, 7U).Imm(frameAccOffset);
733 
734             // store tag
735             INST(21U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
736             INST(22U, Opcode::StoreI).u64().Inputs(21U, 2U).Imm(accTagOffset);
737 
738             INST(9U, Opcode::Call).TypeId(0U).ptr();
739             INST(20U, Opcode::ReturnVoid).v0id();
740         }
741     }
742 
743     irtoc::IrtocRuntimeInterface runtime;
744     GetGraph()->SetRuntime(&runtime);
745 
746     ASSERT_TRUE(GetGraph()->RunPass<ark::compiler::DanglingPointersChecker>());
747 }
748 
749 /*
750  * Use object after call
751  * frame_live_in := LiveIn(frame)
752  * Call
753  * frame_use := LoadI(frame_live_in).Imm(frame_acc_offset).i64
754  */
TEST_F(DanglingPointersCheckerTest,test12)755 TEST_F(DanglingPointersCheckerTest, test12)
756 {
757     auto arch = ark::RUNTIME_ARCH;
758     SetGraphArch(arch);
759     if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
760         return;
761     }
762     auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
763     auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
764     RelocationHandlerTest relocationHandler;
765     relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
766     GetGraph()->SetRelocationHandler(&relocationHandler);
767     GetGraph()->SetMethod(&relocationHandler);
768     GetGraph()->SetMode(GraphMode::InterpreterEntry());
769 
770     GRAPH(GetGraph())
771     {
772         INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
773         INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
774         INST(2U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
775 
776         BASIC_BLOCK(2U, -1L)
777         {
778             INST(7U, Opcode::StoreI).ref().Inputs(0U, 1U).Imm(frameAccOffset);
779 
780             // store tag
781             INST(8U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
782             INST(9U, Opcode::StoreI).u64().Inputs(8U, 2U).Imm(accTagOffset);
783 
784             INST(3U, Opcode::Call).TypeId(0U).ptr();
785             INST(5U, Opcode::AddI).Inputs(1U).ptr().Imm(frameAccOffset);
786             INST(4U, Opcode::ReturnVoid).v0id();
787         }
788     }
789 
790     irtoc::IrtocRuntimeInterface runtime;
791     GetGraph()->SetRuntime(&runtime);
792 
793     ASSERT_FALSE(GetGraph()->RunPass<ark::compiler::DanglingPointersChecker>());
794 }
795 
796 /*
797  * Use primitive after call:
798  *    frame_live_in := LiveIn(frame)
799  *    primitive := LoadI(frame_live_in).Imm(offset).u64
800  *    Call
801  *    primitive_use := AddI(not_object).Imm(10).u64
802  */
TEST_F(DanglingPointersCheckerTest,test13)803 TEST_F(DanglingPointersCheckerTest, test13)
804 {
805     auto arch = ark::RUNTIME_ARCH;
806     SetGraphArch(arch);
807     if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
808         return;
809     }
810     auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
811     auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
812     RelocationHandlerTest relocationHandler;
813     relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
814     GetGraph()->SetRelocationHandler(&relocationHandler);
815     GetGraph()->SetMethod(&relocationHandler);
816     GetGraph()->SetMode(GraphMode::InterpreterEntry());
817 
818     GRAPH(GetGraph())
819     {
820         INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
821         INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
822         INST(2U, Opcode::LiveIn).u64().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
823 
824         BASIC_BLOCK(2U, -1L)
825         {
826             INST(6U, Opcode::LoadI).Inputs(0U).u64().Imm(10U);
827             INST(7U, Opcode::StoreI).ref().Inputs(0U, 1U).Imm(frameAccOffset);
828 
829             // store tag
830             INST(8U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
831             INST(9U, Opcode::StoreI).u64().Inputs(8U, 2U).Imm(accTagOffset);
832 
833             INST(3U, Opcode::Call).TypeId(0U).ptr();
834             INST(5U, Opcode::AddI).Inputs(6U).u64().Imm(frameAccOffset);
835             INST(4U, Opcode::ReturnVoid).v0id();
836         }
837     }
838 
839     irtoc::IrtocRuntimeInterface runtime;
840     GetGraph()->SetRuntime(&runtime);
841 
842     ASSERT_TRUE(GetGraph()->RunPass<ark::compiler::DanglingPointersChecker>());
843 }
844 
845 // Use skipped pointer inst after call:
846 //    frame_live_in := LiveIn(frame)
847 //    pointer := AddI(frame_live_in).Imm(frame_acc_offset).ptr
848 //    Call
849 //    primitive := LoadI(pointer).Imm(0).u64
TEST_F(DanglingPointersCheckerTest,test14)850 TEST_F(DanglingPointersCheckerTest, test14)
851 {
852     auto arch = ark::RUNTIME_ARCH;
853     SetGraphArch(arch);
854     if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
855         return;
856     }
857     auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
858     auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
859     RelocationHandlerTest relocationHandler;
860     relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
861     GetGraph()->SetRelocationHandler(&relocationHandler);
862     GetGraph()->SetMethod(&relocationHandler);
863     GetGraph()->SetMode(GraphMode::InterpreterEntry());
864 
865     GRAPH(GetGraph())
866     {
867         INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
868         INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
869         INST(2U, Opcode::LiveIn).u64().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
870 
871         BASIC_BLOCK(2U, -1L)
872         {
873             INST(6U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
874             INST(7U, Opcode::StoreI).ref().Inputs(0U, 1U).Imm(frameAccOffset);
875 
876             // store tag
877             INST(8U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
878             INST(9U, Opcode::StoreI).u64().Inputs(8U, 2U).Imm(accTagOffset);
879 
880             INST(3U, Opcode::Call).TypeId(0U).ptr();
881             INST(5U, Opcode::LoadI).Inputs(6U).u64().Imm(0U);
882             INST(4U, Opcode::ReturnVoid).v0id();
883         }
884     }
885 
886     irtoc::IrtocRuntimeInterface runtime;
887     GetGraph()->SetRuntime(&runtime);
888 
889     ASSERT_TRUE(GetGraph()->RunPass<ark::compiler::DanglingPointersChecker>());
890 }
891 
892 /*
893  * Use ref inst after call:
894  *    pointer := AddI(acc_live_in).Imm(10).ptr
895  *    Call
896  *    primitive := LoadI(pointer).Imm(0).u64
897  */
TEST_F(DanglingPointersCheckerTest,test15)898 TEST_F(DanglingPointersCheckerTest, test15)
899 {
900     auto arch = ark::RUNTIME_ARCH;
901     SetGraphArch(arch);
902     if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
903         return;
904     }
905     auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
906     auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
907     RelocationHandlerTest relocationHandler;
908     relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
909     GetGraph()->SetRelocationHandler(&relocationHandler);
910     GetGraph()->SetMethod(&relocationHandler);
911     GetGraph()->SetMode(GraphMode::InterpreterEntry());
912 
913     GRAPH(GetGraph())
914     {
915         INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
916         INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
917         INST(2U, Opcode::LiveIn).u64().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
918 
919         BASIC_BLOCK(2U, -1L)
920         {
921             INST(10U, Opcode::LoadI).Inputs(0U).ref().Imm(10U);
922             INST(6U, Opcode::AddI).Inputs(1U).ptr().Imm(10U);
923             INST(7U, Opcode::StoreI).ref().Inputs(0U, 1U).Imm(frameAccOffset);
924 
925             // store tag
926             INST(8U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
927             INST(9U, Opcode::StoreI).u64().Inputs(8U, 2U).Imm(accTagOffset);
928 
929             INST(3U, Opcode::Call).TypeId(0U).ptr();
930             INST(5U, Opcode::LoadI).Inputs(10U).u64().Imm(0U);
931             INST(4U, Opcode::ReturnVoid).v0id();
932         }
933     }
934 
935     irtoc::IrtocRuntimeInterface runtime;
936     GetGraph()->SetRuntime(&runtime);
937 
938     ASSERT_FALSE(GetGraph()->RunPass<ark::compiler::DanglingPointersChecker>());
939 }
940 
941 /*
942  * Correct load accumulator from frame:
943  *    correct_acc_load      := LoadI(LiveIn(frame).ptr).Imm(frame_acc_offset).ref
944  * Correct accumulatore and tag store:
945  *    correct_acc_store     := StoreI(LiveIn(frame).ptr, correct_acc_load).Imm(frame_acc_offset).ref
946  *    acc_ptr               := AddI(LiveIn(frame).ptr).Imm(frame_acc_offset).ref
947  *    correct_acc_tag_store := StoreI(acc_ptr, LiveIn(acc_tag).u64).Imm(acc_tag_offset).u64
948  */
TEST_F(DanglingPointersCheckerTest,test16)949 TEST_F(DanglingPointersCheckerTest, test16)
950 {
951     auto arch = ark::RUNTIME_ARCH;
952     SetGraphArch(arch);
953     if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
954         return;
955     }
956     auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
957     auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
958     RelocationHandlerTest relocationHandler;
959     relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
960     GetGraph()->SetRelocationHandler(&relocationHandler);
961     GetGraph()->SetMethod(&relocationHandler);
962     GetGraph()->SetMode(GraphMode::InterpreterEntry());
963 
964     GRAPH(GetGraph())
965     {
966         INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
967         INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
968         INST(2U, Opcode::LiveIn).u64().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
969         INST(3U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["thread"]);
970 
971         BASIC_BLOCK(2U, -1L)
972         {
973             INST(4U, Opcode::LoadI).Inputs(0U).ref().Imm(frameAccOffset);
974             INST(5U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
975             INST(6U, Opcode::StoreI).ref().Inputs(0U, 4U).Imm(frameAccOffset);
976             INST(7U, Opcode::StoreI).u64().Inputs(5U, 2U).Imm(accTagOffset);
977             INST(8U, Opcode::Call).TypeId(0U).ptr();
978             INST(9U, Opcode::ReturnVoid).v0id();
979         }
980     }
981 
982     irtoc::IrtocRuntimeInterface runtime;
983     GetGraph()->SetRuntime(&runtime);
984 
985     ASSERT_TRUE(GetGraph()->RunPass<ark::compiler::DanglingPointersChecker>());
986 }
987 
988 /*
989  * Correct load accumulator and tag:
990  *    acc_ptr               := AddI(LiveIn(frame).ptr).Imm(frame_acc_offset).ptr
991  *    correct_acc_load      := LoadI(acc_ptr).Imm(frame_acc_offset).ref
992  *    correct_acc_tag_load  := LoadI(acc_ptr).Imm(acc_tag_offset).u64
993  * Correct accumulatore and tag store:
994  *    correct_acc_store     := StoreI(LiveIn(frame).ptr, correct_acc_load).Imm(frame_acc_offset).ref
995  *    acc_ptr               := AddI(LiveIn(frame).ptr).Imm(frame_acc_offset).ref
996  *    correct_acc_tag_store := StoreI(acc_ptr, correct_acc_tag_load).Imm(acc_tag_offset).u64
997  */
TEST_F(DanglingPointersCheckerTest,test17)998 TEST_F(DanglingPointersCheckerTest, test17)
999 {
1000     auto arch = ark::RUNTIME_ARCH;
1001     SetGraphArch(arch);
1002     if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
1003         return;
1004     }
1005     auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
1006     auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
1007     RelocationHandlerTest relocationHandler;
1008     relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
1009     GetGraph()->SetRelocationHandler(&relocationHandler);
1010     GetGraph()->SetMethod(&relocationHandler);
1011     GetGraph()->SetMode(GraphMode::InterpreterEntry());
1012 
1013     GRAPH(GetGraph())
1014     {
1015         INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
1016         INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
1017         INST(2U, Opcode::LiveIn).u64().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
1018         INST(3U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["thread"]);
1019 
1020         BASIC_BLOCK(2U, -1L)
1021         {
1022             INST(4U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
1023             INST(5U, Opcode::LoadI).Inputs(4U).ref().Imm(0U);
1024             INST(6U, Opcode::LoadI).Inputs(4U).i64().Imm(accTagOffset);
1025             INST(7U, Opcode::StoreI).ref().Inputs(0U, 5U).Imm(frameAccOffset);
1026             INST(8U, Opcode::StoreI).u64().Inputs(4U, 6U).Imm(accTagOffset);
1027             INST(9U, Opcode::Call).TypeId(0U).ptr();
1028             INST(10U, Opcode::ReturnVoid).v0id();
1029         }
1030     }
1031 
1032     irtoc::IrtocRuntimeInterface runtime;
1033     GetGraph()->SetRuntime(&runtime);
1034 
1035     ASSERT_TRUE(GetGraph()->RunPass<ark::compiler::DanglingPointersChecker>());
1036 }
1037 
1038 /*
1039  * Correct load accumulator and tag:
1040  *    acc_ptr               := AddI(LiveIn(frame).ptr).Imm(frame_acc_offset).ptr
1041  *    correct_acc_load      := LoadI(acc_ptr).Imm(frame_acc_offset).ref
1042  *    acc_tag_ptr           := AddI(acc_ptr).Imm(acc_tag_offset).ref
1043  *    correct_acc_tag_load  := LoadI(acc_tag_ptr).Imm(0).u64
1044  * Correct accumulatore and tag store:
1045  *    correct_acc_store     := StoreI(LiveIn(frame).ptr, correct_acc_load).Imm(frame_acc_offset).ref
1046  *    acc_ptr               := AddI(LiveIn(frame).ptr).Imm(frame_acc_offset).ref
1047  *    correct_acc_tag_store := StoreI(acc_ptr, correct_acc_tag_load).Imm(acc_tag_offset).u64
1048  */
TEST_F(DanglingPointersCheckerTest,test18)1049 TEST_F(DanglingPointersCheckerTest, test18)
1050 {
1051     auto arch = ark::RUNTIME_ARCH;
1052     SetGraphArch(arch);
1053     if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
1054         return;
1055     }
1056     auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
1057     auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
1058     RelocationHandlerTest relocationHandler;
1059     relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
1060     GetGraph()->SetRelocationHandler(&relocationHandler);
1061     GetGraph()->SetMethod(&relocationHandler);
1062     GetGraph()->SetMode(GraphMode::InterpreterEntry());
1063 
1064     GRAPH(GetGraph())
1065     {
1066         INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
1067         INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
1068         INST(2U, Opcode::LiveIn).u64().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
1069         INST(3U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["thread"]);
1070 
1071         BASIC_BLOCK(2U, -1L)
1072         {
1073             INST(4U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
1074             INST(5U, Opcode::LoadI).Inputs(4U).ref().Imm(0U);
1075             INST(6U, Opcode::AddI).Inputs(4U).ptr().Imm(accTagOffset);
1076             INST(7U, Opcode::LoadI).Inputs(6U).i64().Imm(0U);
1077             INST(8U, Opcode::StoreI).ref().Inputs(0U, 5U).Imm(frameAccOffset);
1078             INST(9U, Opcode::StoreI).u64().Inputs(4U, 7U).Imm(accTagOffset);
1079             INST(10U, Opcode::Call).TypeId(0U).ptr();
1080             INST(11U, Opcode::ReturnVoid).v0id();
1081         }
1082     }
1083 
1084     irtoc::IrtocRuntimeInterface runtime;
1085     GetGraph()->SetRuntime(&runtime);
1086 
1087     ASSERT_TRUE(GetGraph()->RunPass<ark::compiler::DanglingPointersChecker>());
1088 }
1089 
1090 /*
1091  * Correct load accumulator and tag:
1092  *    acc_ptr               := AddI(LiveIn(frame).ptr).Imm(frame_acc_offset).ptr
1093  *    correct_acc_load      := LoadI(acc_ptr).Imm(frame_acc_offset).ref
1094  *    acc_tag_ptr           := AddI(acc_ptr).Imm(acc_tag_offset).ref
1095  *    correct_acc_tag_load  := LoadI(acc_tag_ptr).Imm(0).u64
1096  * Correct accumulatore and tag store:
1097  *    correct_acc_store       := StoreI(LiveIn(frame).ptr, correct_acc_load).Imm(frame_acc_offset).ref
1098  *    acc_ptr                 := AddI(LiveIn(frame).ptr).Imm(frame_acc_offset).ref
1099  *    incorrect_acc_tag_store := StoreI(acc_ptr, LiveIn(acc_tag).u64).Imm(acc_tag_offset).u64
1100  */
TEST_F(DanglingPointersCheckerTest,test19)1101 TEST_F(DanglingPointersCheckerTest, test19)
1102 {
1103     auto arch = ark::RUNTIME_ARCH;
1104     SetGraphArch(arch);
1105     if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
1106         return;
1107     }
1108     auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
1109     auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
1110     RelocationHandlerTest relocationHandler;
1111     relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
1112     GetGraph()->SetRelocationHandler(&relocationHandler);
1113     GetGraph()->SetMethod(&relocationHandler);
1114     GetGraph()->SetMode(GraphMode::InterpreterEntry());
1115 
1116     GRAPH(GetGraph())
1117     {
1118         INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
1119         INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
1120         INST(2U, Opcode::LiveIn).u64().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
1121         INST(3U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["thread"]);
1122 
1123         BASIC_BLOCK(2U, -1L)
1124         {
1125             INST(4U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
1126             INST(5U, Opcode::LoadI).Inputs(4U).ref().Imm(0U);
1127             INST(6U, Opcode::AddI).Inputs(4U).ptr().Imm(accTagOffset);
1128             INST(7U, Opcode::LoadI).Inputs(6U).i64().Imm(0U);
1129             INST(8U, Opcode::StoreI).ref().Inputs(0U, 5U).Imm(frameAccOffset);
1130             INST(9U, Opcode::StoreI).u64().Inputs(4U, 2U).Imm(accTagOffset);
1131             INST(10U, Opcode::Call).TypeId(0U).ptr();
1132             INST(11U, Opcode::ReturnVoid).v0id();
1133         }
1134     }
1135 
1136     irtoc::IrtocRuntimeInterface runtime;
1137     GetGraph()->SetRuntime(&runtime);
1138 
1139     ASSERT_FALSE(GetGraph()->RunPass<ark::compiler::DanglingPointersChecker>());
1140 }
1141 
1142 // NOLINTEND(readability-magic-numbers)
1143 }  // namespace ark::compiler
1144