@@ -155,6 +155,188 @@ OpMemoryModel Logical Simple
155155 }
156156}
157157
158+ TEST_F (ConstantManagerTest, NullTensor) {
159+ const std::string text = R"(
160+ %uint = OpTypeInt 32 0
161+ %1 = OpConstant %uint 1
162+ %2 = OpConstant %uint 2
163+ %uint_5 = OpConstant %uint 5
164+ %uint_7 = OpConstant %uint 7
165+ %arr_uint_1 = OpTypeArray %uint %1
166+ %arr_uint_2 = OpTypeArray %uint %2
167+ %10 = OpConstantComposite %arr_uint_1 %uint_7
168+ %11 = OpConstantComposite %arr_uint_2 %uint_5 %uint_7
169+ )" ;
170+
171+ std::unique_ptr<IRContext> context =
172+ BuildModule (SPV_ENV_UNIVERSAL_1_2 , nullptr , text,
173+ SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS );
174+ ASSERT_NE (context, nullptr );
175+ const auto cstmgr = context->get_constant_mgr ();
176+
177+ Integer ty_uint (32 , 0 );
178+
179+ // rank-1 with 7 elements
180+ TensorARM ty_tensor_r1_7 (&ty_uint, 1 , 10 );
181+ auto null_tensor_r1_7 =
182+ cstmgr->GetNullCompositeConstant (&ty_tensor_r1_7)->AsTensorConstant ();
183+ ASSERT_NE (null_tensor_r1_7, nullptr );
184+ ASSERT_EQ (null_tensor_r1_7->GetComponents ().size (), 7 );
185+ ASSERT_TRUE (null_tensor_r1_7->IsZero ());
186+
187+ // rank-2 with 5 elements of rank-1 type with 7 elements
188+ TensorARM ty_tensor_r2_5_7 (&ty_uint, 2 , 11 );
189+ auto null_tensor_r2_5_7 =
190+ cstmgr->GetNullCompositeConstant (&ty_tensor_r2_5_7)->AsTensorConstant ();
191+ ASSERT_NE (null_tensor_r2_5_7, nullptr );
192+ ASSERT_EQ (null_tensor_r2_5_7->GetComponents ().size (), 5 );
193+ ASSERT_TRUE (null_tensor_r2_5_7->IsZero ());
194+ ASSERT_NE (null_tensor_r2_5_7->GetComponents ()[0 ]->AsTensorConstant (),
195+ nullptr );
196+ ASSERT_TRUE (null_tensor_r2_5_7->GetComponents ()[0 ]->type ()->IsSameImpl (
197+ &ty_tensor_r1_7, nullptr ));
198+ }
199+
200+ TEST_F (ConstantManagerTest, TensorConstantFromInstruction) {
201+ const std::string text = R"(
202+ OpCapability TensorsARM
203+ OpExtension "SPV_ARM_tensors"
204+ %1 = OpTypeInt 32 0
205+ %2 = OpConstant %1 1
206+ %3 = OpConstant %1 2
207+ %4 = OpConstant %1 3
208+ %5 = OpTypeArray %1 %2
209+ %6 = OpConstantComposite %5 %4
210+ %7 = OpTypeTensorARM %1 %2 %6
211+ %8 = OpConstantComposite %7 %2 %3 %4
212+ )" ;
213+
214+ std::unique_ptr<IRContext> context =
215+ BuildModule (SPV_ENV_UNIVERSAL_1_2 , nullptr , text,
216+ SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS );
217+ ASSERT_NE (context, nullptr );
218+
219+ const Constant* constant =
220+ context->get_constant_mgr ()->FindDeclaredConstant (8 );
221+ ASSERT_NE (constant, nullptr );
222+ const auto * tensor_const = constant->AsTensorConstant ();
223+ ASSERT_NE (tensor_const, nullptr );
224+ ASSERT_EQ (tensor_const->GetComponents ().size (), 3 );
225+ EXPECT_EQ (tensor_const->GetComponents ()[0 ]->GetZeroExtendedValue (), 1u );
226+ EXPECT_EQ (tensor_const->GetComponents ()[1 ]->GetZeroExtendedValue (), 2u );
227+ EXPECT_EQ (tensor_const->GetComponents ()[2 ]->GetZeroExtendedValue (), 3u );
228+ EXPECT_FALSE (tensor_const->IsZero ());
229+ }
230+
231+ TEST_F (ConstantManagerTest, NestedTensorConstantFromInstruction) {
232+ const std::string text = R"(
233+ OpCapability TensorsARM
234+ OpExtension "SPV_ARM_tensors"
235+ %1 = OpTypeInt 32 0
236+ %2 = OpConstant %1 1
237+ %3 = OpConstant %1 2
238+ %4 = OpConstant %1 3
239+ %5 = OpConstant %1 4
240+ %6 = OpConstant %1 5
241+ %7 = OpConstant %1 6
242+ %8 = OpTypeArray %1 %2
243+ %9 = OpTypeArray %1 %3
244+ %10 = OpConstantComposite %8 %4
245+ %11 = OpConstantComposite %9 %3 %4
246+ %12 = OpTypeTensorARM %1 %2 %10
247+ %13 = OpTypeTensorARM %1 %3 %11
248+ %14 = OpConstantComposite %12 %2 %3 %4
249+ %15 = OpConstantComposite %12 %5 %6 %7
250+ %16 = OpConstantComposite %13 %14 %15
251+ )" ;
252+
253+ std::unique_ptr<IRContext> context =
254+ BuildModule (SPV_ENV_UNIVERSAL_1_2 , nullptr , text,
255+ SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS );
256+ ASSERT_NE (context, nullptr );
257+
258+ const Constant* constant =
259+ context->get_constant_mgr ()->FindDeclaredConstant (16 );
260+ ASSERT_NE (constant, nullptr );
261+ const auto * tensor_const = constant->AsTensorConstant ();
262+ ASSERT_NE (tensor_const, nullptr );
263+ ASSERT_EQ (tensor_const->GetComponents ().size (), 2 );
264+
265+ const auto * row_0 = tensor_const->GetComponents ()[0 ]->AsTensorConstant ();
266+ const auto * row_1 = tensor_const->GetComponents ()[1 ]->AsTensorConstant ();
267+ ASSERT_NE (row_0, nullptr );
268+ ASSERT_NE (row_1, nullptr );
269+ ASSERT_EQ (row_0->GetComponents ().size (), 3 );
270+ ASSERT_EQ (row_1->GetComponents ().size (), 3 );
271+ EXPECT_EQ (row_0->GetComponents ()[0 ]->GetZeroExtendedValue (), 1u );
272+ EXPECT_EQ (row_0->GetComponents ()[1 ]->GetZeroExtendedValue (), 2u );
273+ EXPECT_EQ (row_0->GetComponents ()[2 ]->GetZeroExtendedValue (), 3u );
274+ EXPECT_EQ (row_1->GetComponents ()[0 ]->GetZeroExtendedValue (), 4u );
275+ EXPECT_EQ (row_1->GetComponents ()[1 ]->GetZeroExtendedValue (), 5u );
276+ EXPECT_EQ (row_1->GetComponents ()[2 ]->GetZeroExtendedValue (), 6u );
277+ EXPECT_FALSE (tensor_const->IsZero ());
278+ }
279+
280+ TEST_F (ConstantManagerTest, GetDefiningInstructionForNestedTensorConstant) {
281+ const std::string text = R"(
282+ OpCapability TensorsARM
283+ OpExtension "SPV_ARM_tensors"
284+ %1 = OpTypeInt 32 0
285+ %2 = OpConstant %1 1
286+ %3 = OpConstant %1 2
287+ %4 = OpConstant %1 3
288+ %5 = OpConstant %1 4
289+ %6 = OpConstant %1 5
290+ %7 = OpConstant %1 6
291+ %8 = OpTypeArray %1 %2
292+ %9 = OpTypeArray %1 %3
293+ %10 = OpConstantComposite %8 %4
294+ %11 = OpConstantComposite %9 %3 %4
295+ %12 = OpTypeTensorARM %1 %2 %10
296+ %13 = OpTypeTensorARM %1 %3 %11
297+ )" ;
298+
299+ std::unique_ptr<IRContext> context =
300+ BuildModule (SPV_ENV_UNIVERSAL_1_2 , nullptr , text,
301+ SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS );
302+ ASSERT_NE (context, nullptr );
303+
304+ ConstantManager* const_mgr = context->get_constant_mgr ();
305+ Type* tensor_r1_type = context->get_type_mgr ()->GetType (12 );
306+ Type* tensor_r2_type = context->get_type_mgr ()->GetType (13 );
307+ ASSERT_NE (tensor_r1_type, nullptr );
308+ ASSERT_NE (tensor_r2_type, nullptr );
309+
310+ const Constant* row_0 = const_mgr->GetConstant (tensor_r1_type, {2 , 3 , 4 });
311+ const Constant* row_1 = const_mgr->GetConstant (tensor_r1_type, {5 , 6 , 7 });
312+ ASSERT_NE (row_0, nullptr );
313+ ASSERT_NE (row_1, nullptr );
314+
315+ Instruction* row_0_inst = const_mgr->GetDefiningInstruction (row_0, 12 );
316+ Instruction* row_1_inst = const_mgr->GetDefiningInstruction (row_1, 12 );
317+ ASSERT_NE (row_0_inst, nullptr );
318+ ASSERT_NE (row_1_inst, nullptr );
319+ EXPECT_EQ (row_0_inst->opcode (), spv::Op::OpConstantComposite);
320+ EXPECT_EQ (row_0_inst->type_id (), 12u );
321+ EXPECT_EQ (row_0_inst->NumInOperands (), 3u );
322+ EXPECT_EQ (row_0_inst->GetSingleWordInOperand (0 ), 2u );
323+ EXPECT_EQ (row_0_inst->GetSingleWordInOperand (1 ), 3u );
324+ EXPECT_EQ (row_0_inst->GetSingleWordInOperand (2 ), 4u );
325+
326+ const Constant* tensor_const = const_mgr->GetConstant (
327+ tensor_r2_type, {row_0_inst->result_id (), row_1_inst->result_id ()});
328+ ASSERT_NE (tensor_const, nullptr );
329+
330+ Instruction* tensor_inst =
331+ const_mgr->GetDefiningInstruction (tensor_const, 13 );
332+ ASSERT_NE (tensor_inst, nullptr );
333+ EXPECT_EQ (tensor_inst->opcode (), spv::Op::OpConstantComposite);
334+ EXPECT_EQ (tensor_inst->type_id (), 13u );
335+ EXPECT_EQ (tensor_inst->NumInOperands (), 2u );
336+ EXPECT_EQ (tensor_inst->GetSingleWordInOperand (0 ), row_0_inst->result_id ());
337+ EXPECT_EQ (tensor_inst->GetSingleWordInOperand (1 ), row_1_inst->result_id ());
338+ }
339+
158340} // namespace
159341} // namespace analysis
160342} // namespace opt
0 commit comments