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