• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2022 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 "unit_test.h"
17 #include "optimizer/ir_builder/inst_builder-inl.h"
18 
19 namespace panda::compiler {
operator ==(const Input & lhs,const Inst * rhs)20 inline bool operator==(const Input &lhs, const Inst *rhs)
21 {
22     return lhs.GetInst() == rhs;
23 }
24 
25 class InstTest : public GraphTest {
26 };
27 
TEST_F(InstTest,Dataflow)28 TEST_F(InstTest, Dataflow)
29 {
30     /**
31      * '=' is a definition
32      *
33      *           [2]
34      *            |
35      *    /---------------\
36      *    |               |
37      *   [3]=            [4]=
38      *    |               |
39      *    |          /---------\
40      *   [5]         |         |
41      *    |          |        [6] (need for removing #6)
42      *    |          |         |
43      *    |          |        [7]=
44      *    |          |         |
45      *    \---------[8]--------/
46      *          PHI(1,2,4)
47      *
48      */
49     GRAPH(GetGraph())
50     {
51         CONSTANT(0, 12);
52         CONSTANT(1, 13);
53 
54         BASIC_BLOCK(2, 3, 4)
55         {
56             INST(2, Opcode::Add).u64().Inputs(0, 1);
57             INST(8, Opcode::Compare).b().SrcType(DataType::Type::INT64).Inputs(0, 1);
58             INST(9, Opcode::IfImm).SrcType(DataType::BOOL).CC(CC_NE).Imm(0).Inputs(8);
59         }
60         BASIC_BLOCK(3, 5)
61         {
62             INST(3, Opcode::Not).u64().Inputs(0);
63         }
64         BASIC_BLOCK(4, 8, 6)
65         {
66             INST(4, Opcode::Not).u64().Inputs(1);
67             INST(11, Opcode::Compare).b().SrcType(DataType::Type::INT64).Inputs(0, 1);
68             INST(12, Opcode::IfImm).SrcType(DataType::BOOL).CC(CC_NE).Imm(0).Inputs(11);
69         }
70         BASIC_BLOCK(5, 8)
71         {
72             INST(7, Opcode::Sub).u64().Inputs(3, 2);
73         }
74         BASIC_BLOCK(6, 7) {}
75         BASIC_BLOCK(7, 8)
76         {
77             INST(5, Opcode::Not).u64().Inputs(4);
78         }
79         BASIC_BLOCK(8, -1)
80         {
81             INST(6, Opcode::Phi).u64().Inputs({{5, 3}, {4, 4}, {7, 5}});
82             INST(16, Opcode::ReturnVoid);
83         }
84     }
85 
86     // Check constructed dataflow
87     ASSERT_TRUE(CheckUsers(INS(0), {2, 3, 8, 11}));
88     ASSERT_TRUE(CheckUsers(INS(1), {2, 4, 8, 11}));
89     ASSERT_TRUE(CheckUsers(INS(2), {7}));
90     ASSERT_TRUE(CheckUsers(INS(3), {6, 7}));
91     ASSERT_TRUE(CheckUsers(INS(4), {5, 6}));
92     ASSERT_TRUE(CheckUsers(INS(5), {6}));
93     ASSERT_TRUE(CheckInputs(INS(2), {0, 1}));
94     ASSERT_TRUE(CheckInputs(INS(3), {0}));
95     ASSERT_TRUE(CheckInputs(INS(7), {3, 2}));
96     ASSERT_TRUE(CheckInputs(INS(4), {1}));
97     ASSERT_TRUE(CheckInputs(INS(5), {4}));
98     ASSERT_TRUE(CheckInputs(INS(6), {3, 4, 5}));
99     ASSERT_EQ(static_cast<PhiInst &>(INS(6)).GetPhiInput(&BB(5)), &INS(3));
100     ASSERT_EQ(static_cast<PhiInst &>(INS(6)).GetPhiInput(&BB(4)), &INS(4));
101     ASSERT_EQ(static_cast<PhiInst &>(INS(6)).GetPhiInput(&BB(7)), &INS(5));
102 
103     {  // Test iterating over users of constant instruction
104         const Inst *inst = &INS(2);
105         for (auto &user : inst->GetUsers()) {
106             ASSERT_EQ(inst, user.GetInput());
107         }
108     }
109 
110     {  // Test iterating over users of non-constant instruction
111         Inst *inst = &INS(2);
112         for (auto &user : inst->GetUsers()) {
113             user.GetInst()->SetId(user.GetInst()->GetId());
114         }
115     }
116 
117     // 1. Remove instruction #3, replace its users by its input
118     INS(3).ReplaceUsers(INS(3).GetInput(0).GetInst());
119     INS(3).GetBasicBlock()->RemoveInst(&INS(3));
120     ASSERT_TRUE(INS(6).GetInput(0).GetInst() == &INS(0));
121     ASSERT_TRUE(INS(3).GetInput(0).GetInst() == nullptr);
122     ASSERT_TRUE(CheckUsers(INS(0), {2, 6, 7, 8, 11}));
123     ASSERT_EQ(static_cast<PhiInst &>(INS(6)).GetPhiInput(&BB(5)), &INS(0));
124     GraphChecker(GetGraph()).Check();
125 
126     // TODO(A.Popov): refactor RemovePredsBlocks
127     // 2. Remove basic block #4, phi should be fixed properly
128     // INS(5).RemoveInputs()
129     // INS(5).GetBasicBlock()->EraseInst(&INS(5))
130     // GetGraph()->DisconnectBlock(&BB(7))
131     // ASSERT_TRUE(INS(6).GetInputsCount() == 2)
132     // static_cast<PhiInst&>(INS(6)).GetPhiInput(&BB(5)), &INS(0))
133     // static_cast<PhiInst&>(INS(6)).GetPhiInput(&BB(4)), &INS(4))
134     GraphChecker(GetGraph()).Check();
135 
136     // 3. Append additional inputs into PHI, thereby force it to reallocate inputs storage, dataflow is not valid  from
137     // this moment
138     for (int i = 0; i < 4; ++i) {
139         INS(6).AppendInput(&INS(0));
140     }
141 }
142 
TEST_F(InstTest,Arithmetics)143 TEST_F(InstTest, Arithmetics)
144 {
145     GRAPH(GetGraph())
146     {
147         CONSTANT(0, 12);
148         CONSTANT(1, 17.23);
149 
150         BASIC_BLOCK(2, -1)
151         {
152             INST(2, Opcode::Cast).u64().SrcType(DataType::FLOAT64).Inputs(1);
153             INST(3, Opcode::Add).u64().Inputs(0, 2);
154             INST(4, Opcode::ReturnVoid);
155         }
156     }
157 }
158 
TEST_F(InstTest,Memory)159 TEST_F(InstTest, Memory)
160 {
161     GRAPH(GetGraph())
162     {
163         PARAMETER(0, 0).ref();  // array
164         PARAMETER(1, 1).u64();  // index
165         BASIC_BLOCK(2, -1)
166         {
167             INST(2, Opcode::SaveState).Inputs(0, 1).SrcVregs({0, 1});
168             INST(3, Opcode::NullCheck).ref().Inputs(0, 2);
169             INST(4, Opcode::LenArray).s32().Inputs(3);
170             INST(5, Opcode::BoundsCheck).s32().Inputs(4, 1, 2);
171             INST(6, Opcode::LoadArray).u64().Inputs(3, 5);
172             INST(7, Opcode::Add).u64().Inputs(6, 6);
173             INST(8, Opcode::StoreArray).u64().Inputs(3, 5, 7);
174             INST(9, Opcode::ReturnVoid);
175         }
176     }
177 }
178 
TEST_F(InstTest,Const)179 TEST_F(InstTest, Const)
180 {
181     int32_t int32_const[3] = {-5, 0, 5};
182     int64_t int64_const[3] = {-5, 0, 5};
183     GRAPH(GetGraph())
184     {
185         BASIC_BLOCK(2, -1)
186         {
187             INST(0, Opcode::ReturnVoid);
188         }
189     }
190     auto start = GetGraph()->GetStartBlock();
191     for (auto i = 0; i < 3; i++) {
192         int32_t val = int32_const[i];
193         auto const1 = GetGraph()->FindOrCreateConstant(val);
194         ASSERT_EQ(const1->GetType(), DataType::INT64);
195         ASSERT_EQ(const1->GetBasicBlock(), start);
196         uint64_t val1 = int64_const[i];
197         auto const2 = GetGraph()->FindOrCreateConstant(val1);
198         ASSERT_EQ(const2->GetType(), DataType::INT64);
199         ASSERT_EQ(const1, const2);
200         ASSERT_EQ(const1->GetIntValue(), val1);
201     }
202     GraphChecker(GetGraph()).Check();
203     float float_const[3] = {-5.5f, 0.1f, 5.2f};
204     for (auto i = 0; i < 3; i++) {
205         float val = float_const[i];
206         auto const1 = GetGraph()->FindOrCreateConstant(val);
207         ASSERT_EQ(const1->GetType(), DataType::FLOAT32);
208         ASSERT_EQ(const1->GetBasicBlock(), start);
209         auto const2 = GetGraph()->FindOrCreateConstant(val);
210         ASSERT_EQ(const1, const2);
211         ASSERT_EQ(const1->GetFloatValue(), val);
212     }
213     GraphChecker(GetGraph()).Check();
214     double double_const[3] = {-5.5, 0.1, 5.2};
215     for (auto i = 0; i < 3; i++) {
216         double val = double_const[i];
217         auto const1 = GetGraph()->FindOrCreateConstant(val);
218         ASSERT_EQ(const1->GetType(), DataType::FLOAT64);
219         ASSERT_EQ(const1->GetBasicBlock(), start);
220         auto const2 = GetGraph()->FindOrCreateConstant(val);
221         ASSERT_EQ(const1, const2);
222         ASSERT_EQ(const1->GetDoubleValue(), val);
223     }
224     int i = 0;
225     for (auto current_const = GetGraph()->GetFirstConstInst(); current_const != nullptr;
226          current_const = current_const->GetNextConst()) {
227         i++;
228     }
229     ASSERT_EQ(i, 9);
230 }
231 
TEST_F(InstTest,Const32)232 TEST_F(InstTest, Const32)
233 {
234     int32_t int32_const[3] = {-5, 0, 5};
235     int64_t int64_const[3] = {-5, 0, 5};
236     auto graph = CreateEmptyBytecodeGraph();
237 
238     GRAPH(graph)
239     {
240         BASIC_BLOCK(2, -1)
241         {
242             INST(0, Opcode::ReturnVoid);
243         }
244     }
245     auto start = graph->GetStartBlock();
246     for (auto i = 0; i < 3; i++) {
247         // add first int32 constant
248         int32_t val = int32_const[i];
249         auto const1 = graph->FindOrCreateConstant(val);
250         ASSERT_EQ(const1->GetType(), DataType::INT32);
251         ASSERT_EQ(const1->GetBasicBlock(), start);
252         uint64_t val1 = int64_const[i];
253         // add int64 constant, graph creates new constant
254         auto const2 = graph->FindOrCreateConstant(val1);
255         ASSERT_EQ(const2->GetType(), DataType::INT64);
256         ASSERT_NE(const1, const2);
257         ASSERT_EQ(const2->GetBasicBlock(), start);
258         ASSERT_EQ(const1->GetIntValue(), val1);
259         // add second int32 constant, graph doesn't create new constant
260         int32_t val2 = int32_const[i];
261         auto const3 = graph->FindOrCreateConstant(val2);
262         ASSERT_EQ(const3, const1);
263         ASSERT_EQ(const1->GetInt32Value(), val2);
264     }
265     GraphChecker(graph).Check();
266 }
267 
TEST_F(InstTest,ReturnVoid)268 TEST_F(InstTest, ReturnVoid)
269 {
270     GRAPH(GetGraph())
271     {
272         BASIC_BLOCK(2, -1)
273         {
274             INST(0, Opcode::ReturnVoid);
275         }
276     }
277 }
278 
TEST_F(InstTest,ReturnFloat)279 TEST_F(InstTest, ReturnFloat)
280 {
281     GRAPH(GetGraph())
282     {
283         CONSTANT(0, 1.1f);
284         BASIC_BLOCK(2, -1)
285         {
286             INST(1, Opcode::Return).f32().Inputs(0);
287         }
288     }
289 }
290 
TEST_F(InstTest,ReturnDouble)291 TEST_F(InstTest, ReturnDouble)
292 {
293     GRAPH(GetGraph())
294     {
295         CONSTANT(0, 1.1);
296         BASIC_BLOCK(2, -1)
297         {
298             INST(1, Opcode::Return).f64().Inputs(0);
299         }
300     }
301 }
302 
TEST_F(InstTest,ReturnLong)303 TEST_F(InstTest, ReturnLong)
304 {
305     uint64_t i = 1;
306     GRAPH(GetGraph())
307     {
308         CONSTANT(0, i);
309         BASIC_BLOCK(2, -1)
310         {
311             INST(1, Opcode::Return).u64().Inputs(0);
312         }
313     }
314 }
315 
TEST_F(InstTest,ReturnInt)316 TEST_F(InstTest, ReturnInt)
317 {
318     int32_t i = 1;
319     GRAPH(GetGraph())
320     {
321         CONSTANT(0, i);
322         BASIC_BLOCK(2, -1)
323         {
324             INST(1, Opcode::Return).u32().Inputs(0);
325         }
326     }
327 }
328 
TEST_F(InstTest,ArrayChecks)329 TEST_F(InstTest, ArrayChecks)
330 {
331     GRAPH(GetGraph())
332     {
333         PARAMETER(0, 0).ref();  // array
334         PARAMETER(1, 1).u64();  // index
335         BASIC_BLOCK(2, -1)
336         {
337             INST(2, Opcode::SaveState).Inputs(0, 1).SrcVregs({0, 1});
338             INST(3, Opcode::NullCheck).ref().Inputs(0, 2);
339             INST(4, Opcode::LenArray).s32().Inputs(3);
340             INST(5, Opcode::BoundsCheck).s32().Inputs(4, 1, 2);
341             INST(6, Opcode::LoadArray).u64().Inputs(3, 5);
342             INST(7, Opcode::Add).u64().Inputs(6, 6);
343             INST(8, Opcode::StoreArray).u64().Inputs(3, 5, 7);
344             INST(9, Opcode::ReturnVoid);
345         }
346     }
347 }
348 
TEST_F(InstTest,ZeroCheck)349 TEST_F(InstTest, ZeroCheck)
350 {
351     GRAPH(GetGraph())
352     {
353         PARAMETER(0, 0).u64();
354         PARAMETER(1, 1).u64();
355         BASIC_BLOCK(2, -1)
356         {
357             INST(2, Opcode::SaveState).Inputs(0, 1).SrcVregs({0, 1});
358             INST(3, Opcode::ZeroCheck).u64().Inputs(0, 2);
359             INST(4, Opcode::Div).u64().Inputs(1, 3);
360             INST(5, Opcode::Mod).u64().Inputs(1, 3);
361             INST(6, Opcode::ReturnVoid);
362         }
363     }
364 }
365 
TEST_F(InstTest,Parametr)366 TEST_F(InstTest, Parametr)
367 {
368     GRAPH(GetGraph())
369     {
370         PARAMETER(0, 0).u64();
371         PARAMETER(1, 1).u32();
372         PARAMETER(2, 4).u16();
373         PARAMETER(3, 5).u8();
374         PARAMETER(4, 8).s64();
375         PARAMETER(5, 10).s32();
376         PARAMETER(6, 11).s16();
377         PARAMETER(7, 24).s8();
378         PARAMETER(8, 27).b();
379         PARAMETER(9, 28).f64();
380         PARAMETER(10, 29).f32();
381         PARAMETER(11, 40).ref();
382         BASIC_BLOCK(2, -1)
383         {
384             INST(12, Opcode::Add).u32().Inputs(1, 5);
385             INST(13, Opcode::ReturnVoid);
386         }
387     }
388 }
389 
TEST_F(InstTest,LenArray)390 TEST_F(InstTest, LenArray)
391 {
392     GRAPH(GetGraph())
393     {
394         PARAMETER(0, 40).ref();
395         BASIC_BLOCK(2, -1)
396         {
397             INST(1, Opcode::LenArray).s32().Inputs(0);
398             INST(2, Opcode::ReturnVoid);
399         }
400     }
401 }
402 
TEST_F(InstTest,Call)403 TEST_F(InstTest, Call)
404 {
405     GRAPH(GetGraph())
406     {
407         PARAMETER(0, 1).ref();
408         PARAMETER(1, 2).u32();
409         PARAMETER(2, 4).u16();
410         PARAMETER(3, 5).u8();
411         PARAMETER(4, 8).s64();
412         BASIC_BLOCK(2, -1)
413         {
414             using namespace DataType;
415             INST(8, Opcode::SaveState).NoVregs();
416             INST(5, Opcode::CallVirtual).s32().InputsAutoType(0, 2, 4, 8);
417             INST(6, Opcode::CallStatic).b().InputsAutoType(1, 3, 4, 5, 8);
418             INST(7, Opcode::ReturnVoid);
419         }
420     }
421 }
422 
TEST_F(InstTest,BinaryImmOperation)423 TEST_F(InstTest, BinaryImmOperation)
424 {
425     GRAPH(GetGraph())
426     {
427         PARAMETER(0, 1).u64();
428         PARAMETER(1, 4).s32();
429         BASIC_BLOCK(2, -1)
430         {
431             INST(2, Opcode::AddI).s32().Imm(10ULL).Inputs(1);
432             INST(3, Opcode::SubI).s32().Imm(15ULL).Inputs(2);
433             INST(4, Opcode::AndI).u64().Imm(15ULL).Inputs(0);
434             INST(5, Opcode::OrI).u64().Imm(1ULL).Inputs(4);
435             INST(6, Opcode::XorI).u64().Imm(10ULL).Inputs(5);
436             INST(7, Opcode::ShlI).u64().Imm(5ULL).Inputs(6);
437             INST(8, Opcode::ShrI).u64().Imm(5ULL).Inputs(7);
438             INST(9, Opcode::AShrI).s32().Imm(4ULL).Inputs(3);
439             INST(10, Opcode::ReturnVoid);
440         }
441     }
442 }
443 
TEST_F(InstTest,Fcmp)444 TEST_F(InstTest, Fcmp)
445 {
446     GRAPH(GetGraph())
447     {
448         PARAMETER(0, 0).f32();
449         PARAMETER(1, 1).f32();
450         PARAMETER(2, 2).f64();
451         PARAMETER(3, 3).f64();
452         BASIC_BLOCK(2, -1)
453         {
454             INST(4, Opcode::Cmp).s32().Inputs(0, 1);
455             INST(5, Opcode::Cmp).s32().Inputs(2, 3);
456             INST(6, Opcode::ReturnVoid);
457         }
458     }
459     GraphChecker(GetGraph()).Check();
460     auto inst4 = static_cast<CmpInst *>(&INS(4));
461     auto inst5 = static_cast<CmpInst *>(&INS(5));
462     inst4->SetFcmpl();
463     ASSERT_EQ(inst4->IsFcmpg(), false);
464     ASSERT_EQ(inst4->IsFcmpl(), true);
465     inst4->SetFcmpl(true);
466     ASSERT_EQ(inst4->IsFcmpg(), false);
467     ASSERT_EQ(inst4->IsFcmpl(), true);
468     inst4->SetFcmpl(false);
469     ASSERT_EQ(inst4->IsFcmpg(), true);
470     ASSERT_EQ(inst4->IsFcmpl(), false);
471     inst5->SetFcmpg();
472     ASSERT_EQ(inst5->IsFcmpg(), true);
473     ASSERT_EQ(inst5->IsFcmpl(), false);
474     inst5->SetFcmpg(true);
475     ASSERT_EQ(inst5->IsFcmpg(), true);
476     ASSERT_EQ(inst5->IsFcmpl(), false);
477     inst5->SetFcmpg(false);
478     ASSERT_EQ(inst5->IsFcmpg(), false);
479     ASSERT_EQ(inst5->IsFcmpl(), true);
480 }
481 
TEST_F(InstTest,SpillFill)482 TEST_F(InstTest, SpillFill)
483 {
484     Register R0 = 0;
485     Register R1 = 1;
486     StackSlot slot0 = 0;
487     StackSlot slot1 = 1;
488 
489     auto spill_fill_inst = GetGraph()->CreateInstSpillFill();
490     spill_fill_inst->AddFill(slot0, R0, DataType::UINT64);
491     spill_fill_inst->AddMove(R0, R1, DataType::UINT64);
492     spill_fill_inst->AddSpill(R1, slot1, DataType::UINT64);
493 
494     ASSERT_EQ(spill_fill_inst->GetSpillFills().size(), 3U);
495 }
496 
TEST_F(InstTest,RemovePhiInput)497 TEST_F(InstTest, RemovePhiInput)
498 {
499     GRAPH(GetGraph())
500     {
501         CONSTANT(0, 0);
502         CONSTANT(1, 1);
503         CONSTANT(2, 2);
504         BASIC_BLOCK(2, 3, 5)
505         {
506             INST(5, Opcode::Compare).b().SrcType(DataType::Type::INT64).Inputs(0, 1);
507             INST(6, Opcode::IfImm).SrcType(DataType::BOOL).CC(CC_NE).Imm(0).Inputs(5);
508         }
509         BASIC_BLOCK(3, 5) {}
510         BASIC_BLOCK(5, -1)
511         {
512             INST(3, Opcode::Phi).u64().Inputs({{2, 0}, {3, 1}});
513             INST(4, Opcode::ReturnVoid);
514         }
515     }
516     auto init_inputs = INS(3).GetInputs();
517     auto init_preds = BB(5).GetPredsBlocks();
518 
519     auto pred_bb_idx = INS(3).CastToPhi()->GetPredBlockIndex(&BB(3));
520     BB(5).RemovePred(&BB(3));
521     INS(3).RemoveInput(pred_bb_idx);
522 
523     auto curr_inputs = INS(3).GetInputs();
524     auto curr_preds = BB(5).GetPredsBlocks();
525     for (size_t idx = 0; idx < curr_inputs.size(); idx++) {
526         if (idx != pred_bb_idx) {
527             ASSERT_EQ(init_inputs[idx].GetInst(), curr_inputs[idx].GetInst());
528             ASSERT_EQ(init_preds[idx], curr_preds[idx]);
529         } else {
530             ASSERT_EQ(init_inputs.rbegin()->GetInst(), curr_inputs[idx].GetInst());
531             ASSERT_EQ(init_preds.back(), curr_preds[idx]);
532         }
533     }
534 }
535 
536 /**
537  * Test creating instruction with huge dynamic inputs amount
538  */
TEST_F(InstTest,HugeDynamicOperandsAmount)539 TEST_F(InstTest, HugeDynamicOperandsAmount)
540 {
541     auto graph = CreateGraphStartEndBlocks();
542     const size_t COUNT = 1000;
543     auto save_state = graph->CreateInstSaveState();
544 
545     for (size_t i = 0; i < COUNT; i++) {
546         save_state->AppendInput(graph->FindOrCreateConstant(i));
547         save_state->SetVirtualRegister(i, VirtualRegister(i, false));
548     }
549 
550     for (size_t i = 0; i < COUNT; i++) {
551         auto user = graph->FindOrCreateConstant(i)->GetUsers().begin()->GetInst();
552         ASSERT_EQ(user, save_state);
553     }
554 }
555 
TEST_F(InstTest,FloatConstants)556 TEST_F(InstTest, FloatConstants)
557 {
558     auto graph = CreateGraphStartEndBlocks();
559     graph->GetStartBlock()->AddSucc(graph->GetEndBlock());
560     auto positiv_zero_float = graph->FindOrCreateConstant(0.0f);
561     auto negativ_zero_float = graph->FindOrCreateConstant(-0.0f);
562     auto positiv_zero_double = graph->FindOrCreateConstant(0.0);
563     auto negativ_zero_double = graph->FindOrCreateConstant(-0.0);
564 
565     ASSERT_NE(positiv_zero_float, negativ_zero_float);
566     ASSERT_NE(positiv_zero_double, negativ_zero_double);
567 }
568 
TEST_F(InstTest,Flags)569 TEST_F(InstTest, Flags)
570 {
571     auto initial_mask = inst_flags::GetFlagsMask(Opcode::LoadObject);
572     auto inst = GetGraph()->CreateInstLoadObject();
573     ASSERT_EQ(initial_mask, inst->GetFlagsMask());
574     ASSERT_EQ(inst->GetFlagsMask(), initial_mask);
575     ASSERT_TRUE(inst->IsLoad());
576     inst->SetFlag(inst_flags::ALLOC);
577     ASSERT_EQ(inst->GetFlagsMask(), initial_mask | inst_flags::ALLOC);
578     ASSERT_TRUE(inst->IsAllocation());
579     inst->ClearFlag(inst_flags::LOAD);
580     ASSERT_FALSE(inst->IsLoad());
581     ASSERT_EQ(inst->GetFlagsMask(), (initial_mask | inst_flags::ALLOC) & ~inst_flags::LOAD);
582 }
583 
TEST_F(InstTest,IntrinsicFlags)584 TEST_F(InstTest, IntrinsicFlags)
585 {
586     ArenaAllocator allocator {SpaceType::SPACE_TYPE_COMPILER};
587 #include "intrinsic_flags_test.inl"
588 }
589 
590 }  // namespace panda::compiler
591