1 // Copyright (c) 2018 Google LLC
2 //
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 #include <memory>
16 #include <string>
17
18 #include "gmock/gmock.h"
19 #include "gtest/gtest.h"
20 #include "source/opt/build_module.h"
21 #include "source/opt/constants.h"
22 #include "source/opt/ir_context.h"
23
24 namespace spvtools {
25 namespace opt {
26 namespace analysis {
27 namespace {
28
29 using ConstantManagerTest = ::testing::Test;
30
TEST_F(ConstantManagerTest,GetDefiningInstruction)31 TEST_F(ConstantManagerTest, GetDefiningInstruction) {
32 const std::string text = R"(
33 %int = OpTypeInt 32 0
34 %1 = OpTypeStruct %int
35 %2 = OpTypeStruct %int
36 )";
37
38 std::unique_ptr<IRContext> context =
39 BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text,
40 SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
41 ASSERT_NE(context, nullptr);
42
43 Type* struct_type_1 = context->get_type_mgr()->GetType(1);
44 StructConstant struct_const_1(struct_type_1->AsStruct());
45 Instruction* const_inst_1 =
46 context->get_constant_mgr()->GetDefiningInstruction(&struct_const_1, 1);
47 EXPECT_EQ(const_inst_1->type_id(), 1);
48
49 Type* struct_type_2 = context->get_type_mgr()->GetType(2);
50 StructConstant struct_const_2(struct_type_2->AsStruct());
51 Instruction* const_inst_2 =
52 context->get_constant_mgr()->GetDefiningInstruction(&struct_const_2, 2);
53 EXPECT_EQ(const_inst_2->type_id(), 2);
54 }
55
TEST_F(ConstantManagerTest,GetDefiningInstruction2)56 TEST_F(ConstantManagerTest, GetDefiningInstruction2) {
57 const std::string text = R"(
58 %int = OpTypeInt 32 0
59 %1 = OpTypeStruct %int
60 %2 = OpTypeStruct %int
61 %3 = OpConstantNull %1
62 %4 = OpConstantNull %2
63 )";
64
65 std::unique_ptr<IRContext> context =
66 BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text,
67 SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
68 ASSERT_NE(context, nullptr);
69
70 Type* struct_type_1 = context->get_type_mgr()->GetType(1);
71 NullConstant struct_const_1(struct_type_1->AsStruct());
72 Instruction* const_inst_1 =
73 context->get_constant_mgr()->GetDefiningInstruction(&struct_const_1, 1);
74 EXPECT_EQ(const_inst_1->type_id(), 1);
75 EXPECT_EQ(const_inst_1->result_id(), 3);
76
77 Type* struct_type_2 = context->get_type_mgr()->GetType(2);
78 NullConstant struct_const_2(struct_type_2->AsStruct());
79 Instruction* const_inst_2 =
80 context->get_constant_mgr()->GetDefiningInstruction(&struct_const_2, 2);
81 EXPECT_EQ(const_inst_2->type_id(), 2);
82 EXPECT_EQ(const_inst_2->result_id(), 4);
83 }
84
TEST_F(ConstantManagerTest,GetDefiningInstructionIdOverflow)85 TEST_F(ConstantManagerTest, GetDefiningInstructionIdOverflow) {
86 const std::string text = R"(
87 %1 = OpTypeInt 32 0
88 %3 = OpConstant %1 1
89 %4 = OpConstant %1 2
90 )";
91
92 std::unique_ptr<IRContext> context =
93 BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text,
94 SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
95 ASSERT_NE(context, nullptr);
96
97 // Set the id bound to the max, so the new constant cannot be generated.
98 context->module()->SetIdBound(context->max_id_bound());
99
100 Type* int_type = context->get_type_mgr()->GetType(1);
101 IntConstant int_constant(int_type->AsInteger(), {3});
102 Instruction* inst =
103 context->get_constant_mgr()->GetDefiningInstruction(&int_constant, 1);
104 EXPECT_EQ(inst, nullptr);
105 }
106
107 } // namespace
108 } // namespace analysis
109 } // namespace opt
110 } // namespace spvtools
111