1fd4e5da5Sopenharmony_ci// Copyright (c) 2017 Google Inc. 2fd4e5da5Sopenharmony_ci// 3fd4e5da5Sopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License"); 4fd4e5da5Sopenharmony_ci// you may not use this file except in compliance with the License. 5fd4e5da5Sopenharmony_ci// You may obtain a copy of the License at 6fd4e5da5Sopenharmony_ci// 7fd4e5da5Sopenharmony_ci// http://www.apache.org/licenses/LICENSE-2.0 8fd4e5da5Sopenharmony_ci// 9fd4e5da5Sopenharmony_ci// Unless required by applicable law or agreed to in writing, software 10fd4e5da5Sopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS, 11fd4e5da5Sopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12fd4e5da5Sopenharmony_ci// See the License for the specific language governing permissions and 13fd4e5da5Sopenharmony_ci// limitations under the License. 14fd4e5da5Sopenharmony_ci 15fd4e5da5Sopenharmony_ci#include <sstream> 16fd4e5da5Sopenharmony_ci#include <string> 17fd4e5da5Sopenharmony_ci 18fd4e5da5Sopenharmony_ci#include "gmock/gmock.h" 19fd4e5da5Sopenharmony_ci#include "test/unit_spirv.h" 20fd4e5da5Sopenharmony_ci#include "test/val/val_code_generator.h" 21fd4e5da5Sopenharmony_ci#include "test/val/val_fixtures.h" 22fd4e5da5Sopenharmony_ci 23fd4e5da5Sopenharmony_cinamespace spvtools { 24fd4e5da5Sopenharmony_cinamespace val { 25fd4e5da5Sopenharmony_cinamespace { 26fd4e5da5Sopenharmony_ci 27fd4e5da5Sopenharmony_ciusing ::testing::HasSubstr; 28fd4e5da5Sopenharmony_ciusing ::testing::Not; 29fd4e5da5Sopenharmony_ciusing ::testing::Values; 30fd4e5da5Sopenharmony_ci 31fd4e5da5Sopenharmony_ciusing ValidateComposites = spvtest::ValidateBase<bool>; 32fd4e5da5Sopenharmony_ci 33fd4e5da5Sopenharmony_cistd::string GenerateShaderCode( 34fd4e5da5Sopenharmony_ci const std::string& body, 35fd4e5da5Sopenharmony_ci const std::string& capabilities_and_extensions = "", 36fd4e5da5Sopenharmony_ci const std::string& execution_model = "Fragment") { 37fd4e5da5Sopenharmony_ci std::ostringstream ss; 38fd4e5da5Sopenharmony_ci ss << R"( 39fd4e5da5Sopenharmony_ciOpCapability Shader 40fd4e5da5Sopenharmony_ciOpCapability Float64 41fd4e5da5Sopenharmony_ci)"; 42fd4e5da5Sopenharmony_ci 43fd4e5da5Sopenharmony_ci ss << capabilities_and_extensions; 44fd4e5da5Sopenharmony_ci ss << "OpMemoryModel Logical GLSL450\n"; 45fd4e5da5Sopenharmony_ci ss << "OpEntryPoint " << execution_model << " %main \"main\"\n"; 46fd4e5da5Sopenharmony_ci if (execution_model == "Fragment") { 47fd4e5da5Sopenharmony_ci ss << "OpExecutionMode %main OriginUpperLeft\n"; 48fd4e5da5Sopenharmony_ci } 49fd4e5da5Sopenharmony_ci 50fd4e5da5Sopenharmony_ci ss << R"( 51fd4e5da5Sopenharmony_ci%void = OpTypeVoid 52fd4e5da5Sopenharmony_ci%func = OpTypeFunction %void 53fd4e5da5Sopenharmony_ci%bool = OpTypeBool 54fd4e5da5Sopenharmony_ci%f32 = OpTypeFloat 32 55fd4e5da5Sopenharmony_ci%f64 = OpTypeFloat 64 56fd4e5da5Sopenharmony_ci%u32 = OpTypeInt 32 0 57fd4e5da5Sopenharmony_ci%s32 = OpTypeInt 32 1 58fd4e5da5Sopenharmony_ci%f32vec2 = OpTypeVector %f32 2 59fd4e5da5Sopenharmony_ci%f32vec3 = OpTypeVector %f32 3 60fd4e5da5Sopenharmony_ci%f32vec4 = OpTypeVector %f32 4 61fd4e5da5Sopenharmony_ci%f64vec2 = OpTypeVector %f64 2 62fd4e5da5Sopenharmony_ci%u32vec2 = OpTypeVector %u32 2 63fd4e5da5Sopenharmony_ci%u32vec4 = OpTypeVector %u32 4 64fd4e5da5Sopenharmony_ci%f64mat22 = OpTypeMatrix %f64vec2 2 65fd4e5da5Sopenharmony_ci%f32mat22 = OpTypeMatrix %f32vec2 2 66fd4e5da5Sopenharmony_ci%f32mat23 = OpTypeMatrix %f32vec2 3 67fd4e5da5Sopenharmony_ci%f32mat32 = OpTypeMatrix %f32vec3 2 68fd4e5da5Sopenharmony_ci 69fd4e5da5Sopenharmony_ci%f32_0 = OpConstant %f32 0 70fd4e5da5Sopenharmony_ci%f32_1 = OpConstant %f32 1 71fd4e5da5Sopenharmony_ci%f32_2 = OpConstant %f32 2 72fd4e5da5Sopenharmony_ci%f32_3 = OpConstant %f32 3 73fd4e5da5Sopenharmony_ci%f32vec2_01 = OpConstantComposite %f32vec2 %f32_0 %f32_1 74fd4e5da5Sopenharmony_ci%f32vec2_12 = OpConstantComposite %f32vec2 %f32_1 %f32_2 75fd4e5da5Sopenharmony_ci%f32vec4_0123 = OpConstantComposite %f32vec4 %f32_0 %f32_1 %f32_2 %f32_3 76fd4e5da5Sopenharmony_ci 77fd4e5da5Sopenharmony_ci%u32_0 = OpConstant %u32 0 78fd4e5da5Sopenharmony_ci%u32_1 = OpConstant %u32 1 79fd4e5da5Sopenharmony_ci%u32_2 = OpConstant %u32 2 80fd4e5da5Sopenharmony_ci%u32_3 = OpConstant %u32 3 81fd4e5da5Sopenharmony_ci 82fd4e5da5Sopenharmony_ci%u32vec2_01 = OpConstantComposite %u32vec2 %u32_0 %u32_1 83fd4e5da5Sopenharmony_ci%u32vec4_0123 = OpConstantComposite %u32vec4 %u32_0 %u32_1 %u32_2 %u32_3 84fd4e5da5Sopenharmony_ci 85fd4e5da5Sopenharmony_ci%f32mat22_1212 = OpConstantComposite %f32mat22 %f32vec2_12 %f32vec2_12 86fd4e5da5Sopenharmony_ci%f32mat23_121212 = OpConstantComposite %f32mat23 %f32vec2_12 %f32vec2_12 %f32vec2_12 87fd4e5da5Sopenharmony_ci 88fd4e5da5Sopenharmony_ci%f32vec2arr3 = OpTypeArray %f32vec2 %u32_3 89fd4e5da5Sopenharmony_ci%f32vec2arr2 = OpTypeArray %f32vec2 %u32_2 90fd4e5da5Sopenharmony_ci 91fd4e5da5Sopenharmony_ci%f32u32struct = OpTypeStruct %f32 %u32 92fd4e5da5Sopenharmony_ci%big_struct = OpTypeStruct %f32 %f32vec4 %f32mat23 %f32vec2arr3 %f32vec2arr2 %f32u32struct 93fd4e5da5Sopenharmony_ci 94fd4e5da5Sopenharmony_ci%ptr_big_struct = OpTypePointer Uniform %big_struct 95fd4e5da5Sopenharmony_ci%var_big_struct = OpVariable %ptr_big_struct Uniform 96fd4e5da5Sopenharmony_ci 97fd4e5da5Sopenharmony_ci%main = OpFunction %void None %func 98fd4e5da5Sopenharmony_ci%main_entry = OpLabel 99fd4e5da5Sopenharmony_ci)"; 100fd4e5da5Sopenharmony_ci 101fd4e5da5Sopenharmony_ci ss << body; 102fd4e5da5Sopenharmony_ci 103fd4e5da5Sopenharmony_ci ss << R"( 104fd4e5da5Sopenharmony_ciOpReturn 105fd4e5da5Sopenharmony_ciOpFunctionEnd)"; 106fd4e5da5Sopenharmony_ci 107fd4e5da5Sopenharmony_ci return ss.str(); 108fd4e5da5Sopenharmony_ci} 109fd4e5da5Sopenharmony_ci 110fd4e5da5Sopenharmony_ci// Returns header for legacy tests taken from val_id_test.cpp. 111fd4e5da5Sopenharmony_cistd::string GetHeaderForTestsFromValId() { 112fd4e5da5Sopenharmony_ci return R"( 113fd4e5da5Sopenharmony_ciOpCapability Shader 114fd4e5da5Sopenharmony_ciOpCapability Linkage 115fd4e5da5Sopenharmony_ciOpCapability Addresses 116fd4e5da5Sopenharmony_ciOpCapability Pipes 117fd4e5da5Sopenharmony_ciOpCapability LiteralSampler 118fd4e5da5Sopenharmony_ciOpCapability DeviceEnqueue 119fd4e5da5Sopenharmony_ciOpCapability Vector16 120fd4e5da5Sopenharmony_ciOpCapability Int8 121fd4e5da5Sopenharmony_ciOpCapability Int16 122fd4e5da5Sopenharmony_ciOpCapability Int64 123fd4e5da5Sopenharmony_ciOpCapability Float64 124fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 125fd4e5da5Sopenharmony_ci%void = OpTypeVoid 126fd4e5da5Sopenharmony_ci%void_f = OpTypeFunction %void 127fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 128fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 129fd4e5da5Sopenharmony_ci%v3float = OpTypeVector %float 3 130fd4e5da5Sopenharmony_ci%mat4x3 = OpTypeMatrix %v3float 4 131fd4e5da5Sopenharmony_ci%_ptr_Private_mat4x3 = OpTypePointer Private %mat4x3 132fd4e5da5Sopenharmony_ci%_ptr_Private_float = OpTypePointer Private %float 133fd4e5da5Sopenharmony_ci%my_matrix = OpVariable %_ptr_Private_mat4x3 Private 134fd4e5da5Sopenharmony_ci%my_float_var = OpVariable %_ptr_Private_float Private 135fd4e5da5Sopenharmony_ci%_ptr_Function_float = OpTypePointer Function %float 136fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0 137fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1 138fd4e5da5Sopenharmony_ci%int_2 = OpConstant %int 2 139fd4e5da5Sopenharmony_ci%int_3 = OpConstant %int 3 140fd4e5da5Sopenharmony_ci%int_5 = OpConstant %int 5 141fd4e5da5Sopenharmony_ci 142fd4e5da5Sopenharmony_ci; Making the following nested structures. 143fd4e5da5Sopenharmony_ci; 144fd4e5da5Sopenharmony_ci; struct S { 145fd4e5da5Sopenharmony_ci; bool b; 146fd4e5da5Sopenharmony_ci; vec4 v[5]; 147fd4e5da5Sopenharmony_ci; int i; 148fd4e5da5Sopenharmony_ci; mat4x3 m[5]; 149fd4e5da5Sopenharmony_ci; } 150fd4e5da5Sopenharmony_ci; uniform blockName { 151fd4e5da5Sopenharmony_ci; S s; 152fd4e5da5Sopenharmony_ci; bool cond; 153fd4e5da5Sopenharmony_ci; } 154fd4e5da5Sopenharmony_ci 155fd4e5da5Sopenharmony_ci%f32arr = OpTypeRuntimeArray %float 156fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 157fd4e5da5Sopenharmony_ci%array5_mat4x3 = OpTypeArray %mat4x3 %int_5 158fd4e5da5Sopenharmony_ci%array5_vec4 = OpTypeArray %v4float %int_5 159fd4e5da5Sopenharmony_ci%_ptr_Uniform_float = OpTypePointer Uniform %float 160fd4e5da5Sopenharmony_ci%_ptr_Function_vec4 = OpTypePointer Function %v4float 161fd4e5da5Sopenharmony_ci%_ptr_Uniform_vec4 = OpTypePointer Uniform %v4float 162fd4e5da5Sopenharmony_ci%struct_s = OpTypeStruct %int %array5_vec4 %int %array5_mat4x3 163fd4e5da5Sopenharmony_ci%struct_blockName = OpTypeStruct %struct_s %int 164fd4e5da5Sopenharmony_ci%_ptr_Uniform_blockName = OpTypePointer Uniform %struct_blockName 165fd4e5da5Sopenharmony_ci%_ptr_Uniform_struct_s = OpTypePointer Uniform %struct_s 166fd4e5da5Sopenharmony_ci%_ptr_Uniform_array5_mat4x3 = OpTypePointer Uniform %array5_mat4x3 167fd4e5da5Sopenharmony_ci%_ptr_Uniform_mat4x3 = OpTypePointer Uniform %mat4x3 168fd4e5da5Sopenharmony_ci%_ptr_Uniform_v3float = OpTypePointer Uniform %v3float 169fd4e5da5Sopenharmony_ci%blockName_var = OpVariable %_ptr_Uniform_blockName Uniform 170fd4e5da5Sopenharmony_ci%spec_int = OpSpecConstant %int 2 171fd4e5da5Sopenharmony_ci%func = OpFunction %void None %void_f 172fd4e5da5Sopenharmony_ci%my_label = OpLabel 173fd4e5da5Sopenharmony_ci)"; 174fd4e5da5Sopenharmony_ci} 175fd4e5da5Sopenharmony_ci 176fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, VectorExtractDynamicSuccess) { 177fd4e5da5Sopenharmony_ci const std::string body = R"( 178fd4e5da5Sopenharmony_ci%val1 = OpVectorExtractDynamic %f32 %f32vec4_0123 %u32_0 179fd4e5da5Sopenharmony_ci)"; 180fd4e5da5Sopenharmony_ci 181fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body).c_str()); 182fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); 183fd4e5da5Sopenharmony_ci} 184fd4e5da5Sopenharmony_ci 185fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, VectorExtractDynamicWrongResultType) { 186fd4e5da5Sopenharmony_ci const std::string body = R"( 187fd4e5da5Sopenharmony_ci%val1 = OpVectorExtractDynamic %f32vec4 %f32vec4_0123 %u32_0 188fd4e5da5Sopenharmony_ci)"; 189fd4e5da5Sopenharmony_ci 190fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body).c_str()); 191fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 192fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 193fd4e5da5Sopenharmony_ci HasSubstr("Expected Result Type to be a scalar type")); 194fd4e5da5Sopenharmony_ci} 195fd4e5da5Sopenharmony_ci 196fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, VectorExtractDynamicNotVector) { 197fd4e5da5Sopenharmony_ci const std::string body = R"( 198fd4e5da5Sopenharmony_ci%val1 = OpVectorExtractDynamic %f32 %f32mat22_1212 %u32_0 199fd4e5da5Sopenharmony_ci)"; 200fd4e5da5Sopenharmony_ci 201fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body).c_str()); 202fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 203fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 204fd4e5da5Sopenharmony_ci HasSubstr("Expected Vector type to be OpTypeVector")); 205fd4e5da5Sopenharmony_ci} 206fd4e5da5Sopenharmony_ci 207fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, VectorExtractDynamicWrongVectorComponent) { 208fd4e5da5Sopenharmony_ci const std::string body = R"( 209fd4e5da5Sopenharmony_ci%val1 = OpVectorExtractDynamic %f32 %u32vec4_0123 %u32_0 210fd4e5da5Sopenharmony_ci)"; 211fd4e5da5Sopenharmony_ci 212fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body).c_str()); 213fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 214fd4e5da5Sopenharmony_ci EXPECT_THAT( 215fd4e5da5Sopenharmony_ci getDiagnosticString(), 216fd4e5da5Sopenharmony_ci HasSubstr("Expected Vector component type to be equal to Result Type")); 217fd4e5da5Sopenharmony_ci} 218fd4e5da5Sopenharmony_ci 219fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, VectorExtractDynamicWrongIndexType) { 220fd4e5da5Sopenharmony_ci const std::string body = R"( 221fd4e5da5Sopenharmony_ci%val1 = OpVectorExtractDynamic %f32 %f32vec4_0123 %f32_0 222fd4e5da5Sopenharmony_ci)"; 223fd4e5da5Sopenharmony_ci 224fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body).c_str()); 225fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 226fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 227fd4e5da5Sopenharmony_ci HasSubstr("Expected Index to be int scalar")); 228fd4e5da5Sopenharmony_ci} 229fd4e5da5Sopenharmony_ci 230fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, VectorInsertDynamicSuccess) { 231fd4e5da5Sopenharmony_ci const std::string body = R"( 232fd4e5da5Sopenharmony_ci%val1 = OpVectorInsertDynamic %f32vec4 %f32vec4_0123 %f32_1 %u32_0 233fd4e5da5Sopenharmony_ci)"; 234fd4e5da5Sopenharmony_ci 235fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body).c_str()); 236fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); 237fd4e5da5Sopenharmony_ci} 238fd4e5da5Sopenharmony_ci 239fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, VectorInsertDynamicWrongResultType) { 240fd4e5da5Sopenharmony_ci const std::string body = R"( 241fd4e5da5Sopenharmony_ci%val1 = OpVectorInsertDynamic %f32 %f32vec4_0123 %f32_1 %u32_0 242fd4e5da5Sopenharmony_ci)"; 243fd4e5da5Sopenharmony_ci 244fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body).c_str()); 245fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 246fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 247fd4e5da5Sopenharmony_ci HasSubstr("Expected Result Type to be OpTypeVector")); 248fd4e5da5Sopenharmony_ci} 249fd4e5da5Sopenharmony_ci 250fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, VectorInsertDynamicNotVector) { 251fd4e5da5Sopenharmony_ci const std::string body = R"( 252fd4e5da5Sopenharmony_ci%val1 = OpVectorInsertDynamic %f32vec4 %f32mat22_1212 %f32_1 %u32_0 253fd4e5da5Sopenharmony_ci)"; 254fd4e5da5Sopenharmony_ci 255fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body).c_str()); 256fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 257fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 258fd4e5da5Sopenharmony_ci HasSubstr("Expected Vector type to be equal to Result Type")); 259fd4e5da5Sopenharmony_ci} 260fd4e5da5Sopenharmony_ci 261fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, VectorInsertDynamicWrongComponentType) { 262fd4e5da5Sopenharmony_ci const std::string body = R"( 263fd4e5da5Sopenharmony_ci%val1 = OpVectorInsertDynamic %f32vec4 %f32vec4_0123 %u32_1 %u32_0 264fd4e5da5Sopenharmony_ci)"; 265fd4e5da5Sopenharmony_ci 266fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body).c_str()); 267fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 268fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 269fd4e5da5Sopenharmony_ci HasSubstr("Expected Component type to be equal to Result Type " 270fd4e5da5Sopenharmony_ci "component type")); 271fd4e5da5Sopenharmony_ci} 272fd4e5da5Sopenharmony_ci 273fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, VectorInsertDynamicWrongIndexType) { 274fd4e5da5Sopenharmony_ci const std::string body = R"( 275fd4e5da5Sopenharmony_ci%val1 = OpVectorInsertDynamic %f32vec4 %f32vec4_0123 %f32_1 %f32_0 276fd4e5da5Sopenharmony_ci)"; 277fd4e5da5Sopenharmony_ci 278fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body).c_str()); 279fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 280fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 281fd4e5da5Sopenharmony_ci HasSubstr("Expected Index to be int scalar")); 282fd4e5da5Sopenharmony_ci} 283fd4e5da5Sopenharmony_ci 284fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeConstructNotComposite) { 285fd4e5da5Sopenharmony_ci const std::string body = R"( 286fd4e5da5Sopenharmony_ci%val1 = OpCompositeConstruct %f32 %f32_1 287fd4e5da5Sopenharmony_ci)"; 288fd4e5da5Sopenharmony_ci 289fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body).c_str()); 290fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 291fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 292fd4e5da5Sopenharmony_ci HasSubstr("Expected Result Type to be a composite type")); 293fd4e5da5Sopenharmony_ci} 294fd4e5da5Sopenharmony_ci 295fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeConstructVectorSuccess) { 296fd4e5da5Sopenharmony_ci const std::string body = R"( 297fd4e5da5Sopenharmony_ci%val1 = OpCompositeConstruct %f32vec4 %f32vec2_12 %f32vec2_12 298fd4e5da5Sopenharmony_ci%val2 = OpCompositeConstruct %f32vec4 %f32vec2_12 %f32_0 %f32_0 299fd4e5da5Sopenharmony_ci%val3 = OpCompositeConstruct %f32vec4 %f32_0 %f32_0 %f32vec2_12 300fd4e5da5Sopenharmony_ci%val4 = OpCompositeConstruct %f32vec4 %f32_0 %f32_1 %f32_2 %f32_3 301fd4e5da5Sopenharmony_ci)"; 302fd4e5da5Sopenharmony_ci 303fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body).c_str()); 304fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); 305fd4e5da5Sopenharmony_ci} 306fd4e5da5Sopenharmony_ci 307fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeConstructVectorOnlyOneConstituent) { 308fd4e5da5Sopenharmony_ci const std::string body = R"( 309fd4e5da5Sopenharmony_ci%val1 = OpCompositeConstruct %f32vec4 %f32vec4_0123 310fd4e5da5Sopenharmony_ci)"; 311fd4e5da5Sopenharmony_ci 312fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body).c_str()); 313fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 314fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 315fd4e5da5Sopenharmony_ci HasSubstr("Expected number of constituents to be at least 2")); 316fd4e5da5Sopenharmony_ci} 317fd4e5da5Sopenharmony_ci 318fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeConstructVectorWrongConsituent1) { 319fd4e5da5Sopenharmony_ci const std::string body = R"( 320fd4e5da5Sopenharmony_ci%val1 = OpCompositeConstruct %f32vec4 %f32 %f32vec2_12 321fd4e5da5Sopenharmony_ci)"; 322fd4e5da5Sopenharmony_ci 323fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body).c_str()); 324fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); 325fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 326fd4e5da5Sopenharmony_ci HasSubstr("Operand '5[%float]' cannot be a " 327fd4e5da5Sopenharmony_ci "type")); 328fd4e5da5Sopenharmony_ci} 329fd4e5da5Sopenharmony_ci 330fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeConstructVectorWrongConsituent2) { 331fd4e5da5Sopenharmony_ci const std::string body = R"( 332fd4e5da5Sopenharmony_ci%val1 = OpCompositeConstruct %f32vec4 %f32vec2_12 %u32vec2_01 333fd4e5da5Sopenharmony_ci)"; 334fd4e5da5Sopenharmony_ci 335fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body).c_str()); 336fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 337fd4e5da5Sopenharmony_ci EXPECT_THAT( 338fd4e5da5Sopenharmony_ci getDiagnosticString(), 339fd4e5da5Sopenharmony_ci HasSubstr("Expected Constituents to be scalars or vectors of the same " 340fd4e5da5Sopenharmony_ci "type as Result Type components")); 341fd4e5da5Sopenharmony_ci} 342fd4e5da5Sopenharmony_ci 343fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeConstructVectorWrongConsituent3) { 344fd4e5da5Sopenharmony_ci const std::string body = R"( 345fd4e5da5Sopenharmony_ci%val1 = OpCompositeConstruct %f32vec4 %f32vec2_12 %u32_0 %f32_0 346fd4e5da5Sopenharmony_ci)"; 347fd4e5da5Sopenharmony_ci 348fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body).c_str()); 349fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 350fd4e5da5Sopenharmony_ci EXPECT_THAT( 351fd4e5da5Sopenharmony_ci getDiagnosticString(), 352fd4e5da5Sopenharmony_ci HasSubstr("Expected Constituents to be scalars or vectors of the same " 353fd4e5da5Sopenharmony_ci "type as Result Type components")); 354fd4e5da5Sopenharmony_ci} 355fd4e5da5Sopenharmony_ci 356fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeConstructVectorWrongComponentNumber1) { 357fd4e5da5Sopenharmony_ci const std::string body = R"( 358fd4e5da5Sopenharmony_ci%val1 = OpCompositeConstruct %f32vec4 %f32vec2_12 %f32_0 359fd4e5da5Sopenharmony_ci)"; 360fd4e5da5Sopenharmony_ci 361fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body).c_str()); 362fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 363fd4e5da5Sopenharmony_ci EXPECT_THAT( 364fd4e5da5Sopenharmony_ci getDiagnosticString(), 365fd4e5da5Sopenharmony_ci HasSubstr("Expected total number of given components to be equal to the " 366fd4e5da5Sopenharmony_ci "size of Result Type vector")); 367fd4e5da5Sopenharmony_ci} 368fd4e5da5Sopenharmony_ci 369fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeConstructVectorWrongComponentNumber2) { 370fd4e5da5Sopenharmony_ci const std::string body = R"( 371fd4e5da5Sopenharmony_ci%val1 = OpCompositeConstruct %f32vec4 %f32vec2_12 %f32vec2_12 %f32_0 372fd4e5da5Sopenharmony_ci)"; 373fd4e5da5Sopenharmony_ci 374fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body).c_str()); 375fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 376fd4e5da5Sopenharmony_ci EXPECT_THAT( 377fd4e5da5Sopenharmony_ci getDiagnosticString(), 378fd4e5da5Sopenharmony_ci HasSubstr("Expected total number of given components to be equal to the " 379fd4e5da5Sopenharmony_ci "size of Result Type vector")); 380fd4e5da5Sopenharmony_ci} 381fd4e5da5Sopenharmony_ci 382fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeConstructMatrixSuccess) { 383fd4e5da5Sopenharmony_ci const std::string body = R"( 384fd4e5da5Sopenharmony_ci%val1 = OpCompositeConstruct %f32mat22 %f32vec2_12 %f32vec2_12 385fd4e5da5Sopenharmony_ci%val2 = OpCompositeConstruct %f32mat23 %f32vec2_12 %f32vec2_12 %f32vec2_12 386fd4e5da5Sopenharmony_ci)"; 387fd4e5da5Sopenharmony_ci 388fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body).c_str()); 389fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); 390fd4e5da5Sopenharmony_ci} 391fd4e5da5Sopenharmony_ci 392fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeConstructVectorWrongConsituentNumber1) { 393fd4e5da5Sopenharmony_ci const std::string body = R"( 394fd4e5da5Sopenharmony_ci%val1 = OpCompositeConstruct %f32mat22 %f32vec2_12 395fd4e5da5Sopenharmony_ci)"; 396fd4e5da5Sopenharmony_ci 397fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body).c_str()); 398fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 399fd4e5da5Sopenharmony_ci EXPECT_THAT( 400fd4e5da5Sopenharmony_ci getDiagnosticString(), 401fd4e5da5Sopenharmony_ci HasSubstr("Expected total number of Constituents to be equal to the " 402fd4e5da5Sopenharmony_ci "number of columns of Result Type matrix")); 403fd4e5da5Sopenharmony_ci} 404fd4e5da5Sopenharmony_ci 405fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeConstructVectorWrongConsituentNumber2) { 406fd4e5da5Sopenharmony_ci const std::string body = R"( 407fd4e5da5Sopenharmony_ci%val1 = OpCompositeConstruct %f32mat22 %f32vec2_12 %f32vec2_12 %f32vec2_12 408fd4e5da5Sopenharmony_ci)"; 409fd4e5da5Sopenharmony_ci 410fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body).c_str()); 411fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 412fd4e5da5Sopenharmony_ci EXPECT_THAT( 413fd4e5da5Sopenharmony_ci getDiagnosticString(), 414fd4e5da5Sopenharmony_ci HasSubstr("Expected total number of Constituents to be equal to the " 415fd4e5da5Sopenharmony_ci "number of columns of Result Type matrix")); 416fd4e5da5Sopenharmony_ci} 417fd4e5da5Sopenharmony_ci 418fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeConstructVectorWrongConsituent) { 419fd4e5da5Sopenharmony_ci const std::string body = R"( 420fd4e5da5Sopenharmony_ci%val1 = OpCompositeConstruct %f32mat22 %f32vec2_12 %u32vec2_01 421fd4e5da5Sopenharmony_ci)"; 422fd4e5da5Sopenharmony_ci 423fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body).c_str()); 424fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 425fd4e5da5Sopenharmony_ci EXPECT_THAT( 426fd4e5da5Sopenharmony_ci getDiagnosticString(), 427fd4e5da5Sopenharmony_ci HasSubstr("Expected Constituent type to be equal to the column type " 428fd4e5da5Sopenharmony_ci "Result Type matrix")); 429fd4e5da5Sopenharmony_ci} 430fd4e5da5Sopenharmony_ci 431fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeConstructArraySuccess) { 432fd4e5da5Sopenharmony_ci const std::string body = R"( 433fd4e5da5Sopenharmony_ci%val1 = OpCompositeConstruct %f32vec2arr3 %f32vec2_12 %f32vec2_12 %f32vec2_12 434fd4e5da5Sopenharmony_ci)"; 435fd4e5da5Sopenharmony_ci 436fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body).c_str()); 437fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); 438fd4e5da5Sopenharmony_ci} 439fd4e5da5Sopenharmony_ci 440fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeConstructArrayWrongConsituentNumber1) { 441fd4e5da5Sopenharmony_ci const std::string body = R"( 442fd4e5da5Sopenharmony_ci%val1 = OpCompositeConstruct %f32vec2arr3 %f32vec2_12 %f32vec2_12 443fd4e5da5Sopenharmony_ci)"; 444fd4e5da5Sopenharmony_ci 445fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body).c_str()); 446fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 447fd4e5da5Sopenharmony_ci EXPECT_THAT( 448fd4e5da5Sopenharmony_ci getDiagnosticString(), 449fd4e5da5Sopenharmony_ci HasSubstr("Expected total number of Constituents to be equal to the " 450fd4e5da5Sopenharmony_ci "number of elements of Result Type array")); 451fd4e5da5Sopenharmony_ci} 452fd4e5da5Sopenharmony_ci 453fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeConstructArrayWrongConsituentNumber2) { 454fd4e5da5Sopenharmony_ci const std::string body = R"( 455fd4e5da5Sopenharmony_ci%val1 = OpCompositeConstruct %f32vec2arr3 %f32vec2_12 %f32vec2_12 %f32vec2_12 %f32vec2_12 456fd4e5da5Sopenharmony_ci)"; 457fd4e5da5Sopenharmony_ci 458fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body).c_str()); 459fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 460fd4e5da5Sopenharmony_ci EXPECT_THAT( 461fd4e5da5Sopenharmony_ci getDiagnosticString(), 462fd4e5da5Sopenharmony_ci HasSubstr("Expected total number of Constituents to be equal to the " 463fd4e5da5Sopenharmony_ci "number of elements of Result Type array")); 464fd4e5da5Sopenharmony_ci} 465fd4e5da5Sopenharmony_ci 466fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeConstructArrayWrongConsituent) { 467fd4e5da5Sopenharmony_ci const std::string body = R"( 468fd4e5da5Sopenharmony_ci%val1 = OpCompositeConstruct %f32vec2arr3 %f32vec2_12 %u32vec2_01 %f32vec2_12 469fd4e5da5Sopenharmony_ci)"; 470fd4e5da5Sopenharmony_ci 471fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body).c_str()); 472fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 473fd4e5da5Sopenharmony_ci EXPECT_THAT( 474fd4e5da5Sopenharmony_ci getDiagnosticString(), 475fd4e5da5Sopenharmony_ci HasSubstr("Expected Constituent type to be equal to the column type " 476fd4e5da5Sopenharmony_ci "Result Type array")); 477fd4e5da5Sopenharmony_ci} 478fd4e5da5Sopenharmony_ci 479fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeConstructStructSuccess) { 480fd4e5da5Sopenharmony_ci const std::string body = R"( 481fd4e5da5Sopenharmony_ci%val1 = OpCompositeConstruct %f32u32struct %f32_0 %u32_1 482fd4e5da5Sopenharmony_ci)"; 483fd4e5da5Sopenharmony_ci 484fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body).c_str()); 485fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); 486fd4e5da5Sopenharmony_ci} 487fd4e5da5Sopenharmony_ci 488fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeConstructStructWrongConstituentNumber1) { 489fd4e5da5Sopenharmony_ci const std::string body = R"( 490fd4e5da5Sopenharmony_ci%val1 = OpCompositeConstruct %f32u32struct %f32_0 491fd4e5da5Sopenharmony_ci)"; 492fd4e5da5Sopenharmony_ci 493fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body).c_str()); 494fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 495fd4e5da5Sopenharmony_ci EXPECT_THAT( 496fd4e5da5Sopenharmony_ci getDiagnosticString(), 497fd4e5da5Sopenharmony_ci HasSubstr("Expected total number of Constituents to be equal to the " 498fd4e5da5Sopenharmony_ci "number of members of Result Type struct")); 499fd4e5da5Sopenharmony_ci} 500fd4e5da5Sopenharmony_ci 501fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeConstructStructWrongConstituentNumber2) { 502fd4e5da5Sopenharmony_ci const std::string body = R"( 503fd4e5da5Sopenharmony_ci%val1 = OpCompositeConstruct %f32u32struct %f32_0 %u32_1 %u32_1 504fd4e5da5Sopenharmony_ci)"; 505fd4e5da5Sopenharmony_ci 506fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body).c_str()); 507fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 508fd4e5da5Sopenharmony_ci EXPECT_THAT( 509fd4e5da5Sopenharmony_ci getDiagnosticString(), 510fd4e5da5Sopenharmony_ci HasSubstr("Expected total number of Constituents to be equal to the " 511fd4e5da5Sopenharmony_ci "number of members of Result Type struct")); 512fd4e5da5Sopenharmony_ci} 513fd4e5da5Sopenharmony_ci 514fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeConstructStructWrongConstituent) { 515fd4e5da5Sopenharmony_ci const std::string body = R"( 516fd4e5da5Sopenharmony_ci%val1 = OpCompositeConstruct %f32u32struct %f32_0 %f32_1 517fd4e5da5Sopenharmony_ci)"; 518fd4e5da5Sopenharmony_ci 519fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body).c_str()); 520fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 521fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 522fd4e5da5Sopenharmony_ci HasSubstr("Expected Constituent type to be equal to the " 523fd4e5da5Sopenharmony_ci "corresponding member type of Result Type struct")); 524fd4e5da5Sopenharmony_ci} 525fd4e5da5Sopenharmony_ci 526fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CopyObjectSuccess) { 527fd4e5da5Sopenharmony_ci const std::string body = R"( 528fd4e5da5Sopenharmony_ci%val1 = OpCopyObject %f32 %f32_0 529fd4e5da5Sopenharmony_ci%val2 = OpCopyObject %f32vec4 %f32vec4_0123 530fd4e5da5Sopenharmony_ci)"; 531fd4e5da5Sopenharmony_ci 532fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body).c_str()); 533fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); 534fd4e5da5Sopenharmony_ci} 535fd4e5da5Sopenharmony_ci 536fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CopyObjectResultTypeNotType) { 537fd4e5da5Sopenharmony_ci const std::string body = R"( 538fd4e5da5Sopenharmony_ci%val1 = OpCopyObject %f32_0 %f32_0 539fd4e5da5Sopenharmony_ci)"; 540fd4e5da5Sopenharmony_ci 541fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body).c_str()); 542fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); 543fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 544fd4e5da5Sopenharmony_ci HasSubstr("ID '19[%float_0]' is not a type id")); 545fd4e5da5Sopenharmony_ci} 546fd4e5da5Sopenharmony_ci 547fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CopyObjectWrongOperandType) { 548fd4e5da5Sopenharmony_ci const std::string body = R"( 549fd4e5da5Sopenharmony_ci%val1 = OpCopyObject %f32 %u32_0 550fd4e5da5Sopenharmony_ci)"; 551fd4e5da5Sopenharmony_ci 552fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body).c_str()); 553fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 554fd4e5da5Sopenharmony_ci EXPECT_THAT( 555fd4e5da5Sopenharmony_ci getDiagnosticString(), 556fd4e5da5Sopenharmony_ci HasSubstr("Expected Result Type and Operand type to be the same")); 557fd4e5da5Sopenharmony_ci} 558fd4e5da5Sopenharmony_ci 559fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, TransposeSuccess) { 560fd4e5da5Sopenharmony_ci const std::string body = R"( 561fd4e5da5Sopenharmony_ci%val1 = OpTranspose %f32mat32 %f32mat23_121212 562fd4e5da5Sopenharmony_ci%val2 = OpTranspose %f32mat22 %f32mat22_1212 563fd4e5da5Sopenharmony_ci)"; 564fd4e5da5Sopenharmony_ci 565fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body).c_str()); 566fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); 567fd4e5da5Sopenharmony_ci} 568fd4e5da5Sopenharmony_ci 569fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, TransposeResultTypeNotMatrix) { 570fd4e5da5Sopenharmony_ci const std::string body = R"( 571fd4e5da5Sopenharmony_ci%val1 = OpTranspose %f32vec4 %f32mat22_1212 572fd4e5da5Sopenharmony_ci)"; 573fd4e5da5Sopenharmony_ci 574fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body).c_str()); 575fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 576fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 577fd4e5da5Sopenharmony_ci HasSubstr("Expected Result Type to be a matrix type")); 578fd4e5da5Sopenharmony_ci} 579fd4e5da5Sopenharmony_ci 580fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, TransposeDifferentComponentTypes) { 581fd4e5da5Sopenharmony_ci const std::string body = R"( 582fd4e5da5Sopenharmony_ci%val1 = OpTranspose %f64mat22 %f32mat22_1212 583fd4e5da5Sopenharmony_ci)"; 584fd4e5da5Sopenharmony_ci 585fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body).c_str()); 586fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 587fd4e5da5Sopenharmony_ci EXPECT_THAT( 588fd4e5da5Sopenharmony_ci getDiagnosticString(), 589fd4e5da5Sopenharmony_ci HasSubstr("Expected component types of Matrix and Result Type to be " 590fd4e5da5Sopenharmony_ci "identical")); 591fd4e5da5Sopenharmony_ci} 592fd4e5da5Sopenharmony_ci 593fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, TransposeIncompatibleDimensions1) { 594fd4e5da5Sopenharmony_ci const std::string body = R"( 595fd4e5da5Sopenharmony_ci%val1 = OpTranspose %f32mat23 %f32mat22_1212 596fd4e5da5Sopenharmony_ci)"; 597fd4e5da5Sopenharmony_ci 598fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body).c_str()); 599fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 600fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 601fd4e5da5Sopenharmony_ci HasSubstr("Expected number of columns and the column size " 602fd4e5da5Sopenharmony_ci "of Matrix to be the reverse of those of Result Type")); 603fd4e5da5Sopenharmony_ci} 604fd4e5da5Sopenharmony_ci 605fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, TransposeIncompatibleDimensions2) { 606fd4e5da5Sopenharmony_ci const std::string body = R"( 607fd4e5da5Sopenharmony_ci%val1 = OpTranspose %f32mat32 %f32mat22_1212 608fd4e5da5Sopenharmony_ci)"; 609fd4e5da5Sopenharmony_ci 610fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body).c_str()); 611fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 612fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 613fd4e5da5Sopenharmony_ci HasSubstr("Expected number of columns and the column size " 614fd4e5da5Sopenharmony_ci "of Matrix to be the reverse of those of Result Type")); 615fd4e5da5Sopenharmony_ci} 616fd4e5da5Sopenharmony_ci 617fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, TransposeIncompatibleDimensions3) { 618fd4e5da5Sopenharmony_ci const std::string body = R"( 619fd4e5da5Sopenharmony_ci%val1 = OpTranspose %f32mat23 %f32mat23_121212 620fd4e5da5Sopenharmony_ci)"; 621fd4e5da5Sopenharmony_ci 622fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body).c_str()); 623fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 624fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 625fd4e5da5Sopenharmony_ci HasSubstr("Expected number of columns and the column size " 626fd4e5da5Sopenharmony_ci "of Matrix to be the reverse of those of Result Type")); 627fd4e5da5Sopenharmony_ci} 628fd4e5da5Sopenharmony_ci 629fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeExtractSuccess) { 630fd4e5da5Sopenharmony_ci const std::string body = R"( 631fd4e5da5Sopenharmony_ci%val1 = OpCompositeExtract %f32 %f32vec4_0123 1 632fd4e5da5Sopenharmony_ci%val2 = OpCompositeExtract %u32 %u32vec4_0123 0 633fd4e5da5Sopenharmony_ci%val3 = OpCompositeExtract %f32 %f32mat22_1212 0 1 634fd4e5da5Sopenharmony_ci%val4 = OpCompositeExtract %f32vec2 %f32mat22_1212 0 635fd4e5da5Sopenharmony_ci%array = OpCompositeConstruct %f32vec2arr3 %f32vec2_12 %f32vec2_12 %f32vec2_12 636fd4e5da5Sopenharmony_ci%val5 = OpCompositeExtract %f32vec2 %array 2 637fd4e5da5Sopenharmony_ci%val6 = OpCompositeExtract %f32 %array 2 1 638fd4e5da5Sopenharmony_ci%struct = OpLoad %big_struct %var_big_struct 639fd4e5da5Sopenharmony_ci%val7 = OpCompositeExtract %f32 %struct 0 640fd4e5da5Sopenharmony_ci%val8 = OpCompositeExtract %f32vec4 %struct 1 641fd4e5da5Sopenharmony_ci%val9 = OpCompositeExtract %f32 %struct 1 2 642fd4e5da5Sopenharmony_ci%val10 = OpCompositeExtract %f32mat23 %struct 2 643fd4e5da5Sopenharmony_ci%val11 = OpCompositeExtract %f32vec2 %struct 2 2 644fd4e5da5Sopenharmony_ci%val12 = OpCompositeExtract %f32 %struct 2 2 1 645fd4e5da5Sopenharmony_ci%val13 = OpCompositeExtract %f32vec2 %struct 3 2 646fd4e5da5Sopenharmony_ci%val14 = OpCompositeExtract %f32 %struct 3 2 1 647fd4e5da5Sopenharmony_ci%val15 = OpCompositeExtract %f32vec2 %struct 4 1 648fd4e5da5Sopenharmony_ci%val16 = OpCompositeExtract %f32 %struct 4 0 1 649fd4e5da5Sopenharmony_ci%val17 = OpCompositeExtract %f32 %struct 5 0 650fd4e5da5Sopenharmony_ci%val18 = OpCompositeExtract %u32 %struct 5 1 651fd4e5da5Sopenharmony_ci)"; 652fd4e5da5Sopenharmony_ci 653fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 654fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); 655fd4e5da5Sopenharmony_ci} 656fd4e5da5Sopenharmony_ci 657fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeExtractNotObject) { 658fd4e5da5Sopenharmony_ci const std::string body = R"( 659fd4e5da5Sopenharmony_ci%val1 = OpCompositeExtract %f32 %f32vec4 1 660fd4e5da5Sopenharmony_ci)"; 661fd4e5da5Sopenharmony_ci 662fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 663fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); 664fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), HasSubstr("Operand '11[%v4float]' cannot " 665fd4e5da5Sopenharmony_ci "be a type")); 666fd4e5da5Sopenharmony_ci} 667fd4e5da5Sopenharmony_ci 668fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeExtractNotComposite) { 669fd4e5da5Sopenharmony_ci const std::string body = R"( 670fd4e5da5Sopenharmony_ci%val1 = OpCompositeExtract %f32 %f32_1 0 671fd4e5da5Sopenharmony_ci)"; 672fd4e5da5Sopenharmony_ci 673fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 674fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 675fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 676fd4e5da5Sopenharmony_ci HasSubstr("Reached non-composite type while indexes still remain " 677fd4e5da5Sopenharmony_ci "to be traversed.")); 678fd4e5da5Sopenharmony_ci} 679fd4e5da5Sopenharmony_ci 680fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeExtractVectorOutOfBounds) { 681fd4e5da5Sopenharmony_ci const std::string body = R"( 682fd4e5da5Sopenharmony_ci%val1 = OpCompositeExtract %f32 %f32vec4_0123 4 683fd4e5da5Sopenharmony_ci)"; 684fd4e5da5Sopenharmony_ci 685fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 686fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 687fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 688fd4e5da5Sopenharmony_ci HasSubstr("Vector access is out of bounds, " 689fd4e5da5Sopenharmony_ci "vector size is 4, but access index is 4")); 690fd4e5da5Sopenharmony_ci} 691fd4e5da5Sopenharmony_ci 692fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeExtractMatrixOutOfCols) { 693fd4e5da5Sopenharmony_ci const std::string body = R"( 694fd4e5da5Sopenharmony_ci%val1 = OpCompositeExtract %f32 %f32mat23_121212 3 1 695fd4e5da5Sopenharmony_ci)"; 696fd4e5da5Sopenharmony_ci 697fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 698fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 699fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 700fd4e5da5Sopenharmony_ci HasSubstr("Matrix access is out of bounds, " 701fd4e5da5Sopenharmony_ci "matrix has 3 columns, but access index is 3")); 702fd4e5da5Sopenharmony_ci} 703fd4e5da5Sopenharmony_ci 704fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeExtractMatrixOutOfRows) { 705fd4e5da5Sopenharmony_ci const std::string body = R"( 706fd4e5da5Sopenharmony_ci%val1 = OpCompositeExtract %f32 %f32mat23_121212 2 5 707fd4e5da5Sopenharmony_ci)"; 708fd4e5da5Sopenharmony_ci 709fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 710fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 711fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 712fd4e5da5Sopenharmony_ci HasSubstr("Vector access is out of bounds, " 713fd4e5da5Sopenharmony_ci "vector size is 2, but access index is 5")); 714fd4e5da5Sopenharmony_ci} 715fd4e5da5Sopenharmony_ci 716fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeExtractArrayOutOfBounds) { 717fd4e5da5Sopenharmony_ci const std::string body = R"( 718fd4e5da5Sopenharmony_ci%array = OpCompositeConstruct %f32vec2arr3 %f32vec2_12 %f32vec2_12 %f32vec2_12 719fd4e5da5Sopenharmony_ci%val1 = OpCompositeExtract %f32vec2 %array 3 720fd4e5da5Sopenharmony_ci)"; 721fd4e5da5Sopenharmony_ci 722fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 723fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 724fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 725fd4e5da5Sopenharmony_ci HasSubstr("Array access is out of bounds, " 726fd4e5da5Sopenharmony_ci "array size is 3, but access index is 3")); 727fd4e5da5Sopenharmony_ci} 728fd4e5da5Sopenharmony_ci 729fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeExtractStructOutOfBounds) { 730fd4e5da5Sopenharmony_ci const std::string body = R"( 731fd4e5da5Sopenharmony_ci%struct = OpLoad %big_struct %var_big_struct 732fd4e5da5Sopenharmony_ci%val1 = OpCompositeExtract %f32 %struct 6 733fd4e5da5Sopenharmony_ci)"; 734fd4e5da5Sopenharmony_ci 735fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 736fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 737fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 738fd4e5da5Sopenharmony_ci HasSubstr("Index is out of bounds, can not find index 6 in the " 739fd4e5da5Sopenharmony_ci "structure <id> '37'. This structure has 6 members. " 740fd4e5da5Sopenharmony_ci "Largest valid index is 5.")); 741fd4e5da5Sopenharmony_ci} 742fd4e5da5Sopenharmony_ci 743fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeExtractNestedVectorOutOfBounds) { 744fd4e5da5Sopenharmony_ci const std::string body = R"( 745fd4e5da5Sopenharmony_ci%struct = OpLoad %big_struct %var_big_struct 746fd4e5da5Sopenharmony_ci%val1 = OpCompositeExtract %f32 %struct 3 1 5 747fd4e5da5Sopenharmony_ci)"; 748fd4e5da5Sopenharmony_ci 749fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 750fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 751fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 752fd4e5da5Sopenharmony_ci HasSubstr("Vector access is out of bounds, " 753fd4e5da5Sopenharmony_ci "vector size is 2, but access index is 5")); 754fd4e5da5Sopenharmony_ci} 755fd4e5da5Sopenharmony_ci 756fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeExtractTooManyIndices) { 757fd4e5da5Sopenharmony_ci const std::string body = R"( 758fd4e5da5Sopenharmony_ci%struct = OpLoad %big_struct %var_big_struct 759fd4e5da5Sopenharmony_ci%val1 = OpCompositeExtract %f32 %struct 3 1 1 2 760fd4e5da5Sopenharmony_ci)"; 761fd4e5da5Sopenharmony_ci 762fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 763fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 764fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 765fd4e5da5Sopenharmony_ci HasSubstr("Reached non-composite type while " 766fd4e5da5Sopenharmony_ci "indexes still remain to be traversed.")); 767fd4e5da5Sopenharmony_ci} 768fd4e5da5Sopenharmony_ci 769fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeExtractNoIndices) { 770fd4e5da5Sopenharmony_ci const std::string body = R"( 771fd4e5da5Sopenharmony_ci%struct = OpLoad %big_struct %var_big_struct 772fd4e5da5Sopenharmony_ci%val1 = OpCompositeExtract %big_struct %struct 773fd4e5da5Sopenharmony_ci)"; 774fd4e5da5Sopenharmony_ci 775fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 776fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 777fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 778fd4e5da5Sopenharmony_ci HasSubstr("Expected at least one index to OpCompositeExtract")); 779fd4e5da5Sopenharmony_ci} 780fd4e5da5Sopenharmony_ci 781fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeExtractWrongType1) { 782fd4e5da5Sopenharmony_ci const std::string body = R"( 783fd4e5da5Sopenharmony_ci%struct = OpLoad %big_struct %var_big_struct 784fd4e5da5Sopenharmony_ci%val1 = OpCompositeExtract %f32vec2 %struct 3 1 1 785fd4e5da5Sopenharmony_ci)"; 786fd4e5da5Sopenharmony_ci 787fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 788fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 789fd4e5da5Sopenharmony_ci EXPECT_THAT( 790fd4e5da5Sopenharmony_ci getDiagnosticString(), 791fd4e5da5Sopenharmony_ci HasSubstr( 792fd4e5da5Sopenharmony_ci "Result type (OpTypeVector) does not match the type that results " 793fd4e5da5Sopenharmony_ci "from indexing into the composite (OpTypeFloat).")); 794fd4e5da5Sopenharmony_ci} 795fd4e5da5Sopenharmony_ci 796fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeExtractWrongType2) { 797fd4e5da5Sopenharmony_ci const std::string body = R"( 798fd4e5da5Sopenharmony_ci%struct = OpLoad %big_struct %var_big_struct 799fd4e5da5Sopenharmony_ci%val1 = OpCompositeExtract %f32 %struct 3 1 800fd4e5da5Sopenharmony_ci)"; 801fd4e5da5Sopenharmony_ci 802fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 803fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 804fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 805fd4e5da5Sopenharmony_ci HasSubstr("Result type (OpTypeFloat) does not match the type " 806fd4e5da5Sopenharmony_ci "that results from indexing into the composite " 807fd4e5da5Sopenharmony_ci "(OpTypeVector).")); 808fd4e5da5Sopenharmony_ci} 809fd4e5da5Sopenharmony_ci 810fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeExtractWrongType3) { 811fd4e5da5Sopenharmony_ci const std::string body = R"( 812fd4e5da5Sopenharmony_ci%struct = OpLoad %big_struct %var_big_struct 813fd4e5da5Sopenharmony_ci%val1 = OpCompositeExtract %f32 %struct 2 1 814fd4e5da5Sopenharmony_ci)"; 815fd4e5da5Sopenharmony_ci 816fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 817fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 818fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 819fd4e5da5Sopenharmony_ci HasSubstr("Result type (OpTypeFloat) does not match the type " 820fd4e5da5Sopenharmony_ci "that results from indexing into the composite " 821fd4e5da5Sopenharmony_ci "(OpTypeVector).")); 822fd4e5da5Sopenharmony_ci} 823fd4e5da5Sopenharmony_ci 824fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeExtractWrongType4) { 825fd4e5da5Sopenharmony_ci const std::string body = R"( 826fd4e5da5Sopenharmony_ci%struct = OpLoad %big_struct %var_big_struct 827fd4e5da5Sopenharmony_ci%val1 = OpCompositeExtract %f32 %struct 4 1 828fd4e5da5Sopenharmony_ci)"; 829fd4e5da5Sopenharmony_ci 830fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 831fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 832fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 833fd4e5da5Sopenharmony_ci HasSubstr("Result type (OpTypeFloat) does not match the type " 834fd4e5da5Sopenharmony_ci "that results from indexing into the composite " 835fd4e5da5Sopenharmony_ci "(OpTypeVector).")); 836fd4e5da5Sopenharmony_ci} 837fd4e5da5Sopenharmony_ci 838fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeExtractWrongType5) { 839fd4e5da5Sopenharmony_ci const std::string body = R"( 840fd4e5da5Sopenharmony_ci%struct = OpLoad %big_struct %var_big_struct 841fd4e5da5Sopenharmony_ci%val1 = OpCompositeExtract %f32 %struct 5 1 842fd4e5da5Sopenharmony_ci)"; 843fd4e5da5Sopenharmony_ci 844fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 845fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 846fd4e5da5Sopenharmony_ci EXPECT_THAT( 847fd4e5da5Sopenharmony_ci getDiagnosticString(), 848fd4e5da5Sopenharmony_ci HasSubstr( 849fd4e5da5Sopenharmony_ci "Result type (OpTypeFloat) does not match the " 850fd4e5da5Sopenharmony_ci "type that results from indexing into the composite (OpTypeInt).")); 851fd4e5da5Sopenharmony_ci} 852fd4e5da5Sopenharmony_ci 853fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeInsertSuccess) { 854fd4e5da5Sopenharmony_ci const std::string body = R"( 855fd4e5da5Sopenharmony_ci%val1 = OpCompositeInsert %f32vec4 %f32_1 %f32vec4_0123 0 856fd4e5da5Sopenharmony_ci%val2 = OpCompositeInsert %u32vec4 %u32_1 %u32vec4_0123 0 857fd4e5da5Sopenharmony_ci%val3 = OpCompositeInsert %f32mat22 %f32_2 %f32mat22_1212 0 1 858fd4e5da5Sopenharmony_ci%val4 = OpCompositeInsert %f32mat22 %f32vec2_01 %f32mat22_1212 0 859fd4e5da5Sopenharmony_ci%array = OpCompositeConstruct %f32vec2arr3 %f32vec2_12 %f32vec2_12 %f32vec2_12 860fd4e5da5Sopenharmony_ci%val5 = OpCompositeInsert %f32vec2arr3 %f32vec2_01 %array 2 861fd4e5da5Sopenharmony_ci%val6 = OpCompositeInsert %f32vec2arr3 %f32_3 %array 2 1 862fd4e5da5Sopenharmony_ci%struct = OpLoad %big_struct %var_big_struct 863fd4e5da5Sopenharmony_ci%val7 = OpCompositeInsert %big_struct %f32_3 %struct 0 864fd4e5da5Sopenharmony_ci%val8 = OpCompositeInsert %big_struct %f32vec4_0123 %struct 1 865fd4e5da5Sopenharmony_ci%val9 = OpCompositeInsert %big_struct %f32_3 %struct 1 2 866fd4e5da5Sopenharmony_ci%val10 = OpCompositeInsert %big_struct %f32mat23_121212 %struct 2 867fd4e5da5Sopenharmony_ci%val11 = OpCompositeInsert %big_struct %f32vec2_01 %struct 2 2 868fd4e5da5Sopenharmony_ci%val12 = OpCompositeInsert %big_struct %f32_3 %struct 2 2 1 869fd4e5da5Sopenharmony_ci%val13 = OpCompositeInsert %big_struct %f32vec2_01 %struct 3 2 870fd4e5da5Sopenharmony_ci%val14 = OpCompositeInsert %big_struct %f32_3 %struct 3 2 1 871fd4e5da5Sopenharmony_ci%val15 = OpCompositeInsert %big_struct %f32vec2_01 %struct 4 1 872fd4e5da5Sopenharmony_ci%val16 = OpCompositeInsert %big_struct %f32_3 %struct 4 0 1 873fd4e5da5Sopenharmony_ci%val17 = OpCompositeInsert %big_struct %f32_3 %struct 5 0 874fd4e5da5Sopenharmony_ci%val18 = OpCompositeInsert %big_struct %u32_3 %struct 5 1 875fd4e5da5Sopenharmony_ci)"; 876fd4e5da5Sopenharmony_ci 877fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 878fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); 879fd4e5da5Sopenharmony_ci} 880fd4e5da5Sopenharmony_ci 881fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeInsertResultTypeDifferentFromComposite) { 882fd4e5da5Sopenharmony_ci const std::string body = R"( 883fd4e5da5Sopenharmony_ci%val1 = OpCompositeInsert %f32 %f32_1 %f32vec4_0123 0 884fd4e5da5Sopenharmony_ci)"; 885fd4e5da5Sopenharmony_ci 886fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 887fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 888fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 889fd4e5da5Sopenharmony_ci HasSubstr("The Result Type must be the same as Composite type in " 890fd4e5da5Sopenharmony_ci "OpCompositeInsert yielding Result Id 5.")); 891fd4e5da5Sopenharmony_ci} 892fd4e5da5Sopenharmony_ci 893fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeInsertNotComposite) { 894fd4e5da5Sopenharmony_ci const std::string body = R"( 895fd4e5da5Sopenharmony_ci%val1 = OpCompositeInsert %f32 %f32_1 %f32_0 0 896fd4e5da5Sopenharmony_ci)"; 897fd4e5da5Sopenharmony_ci 898fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 899fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 900fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 901fd4e5da5Sopenharmony_ci HasSubstr("Reached non-composite type while indexes still remain " 902fd4e5da5Sopenharmony_ci "to be traversed.")); 903fd4e5da5Sopenharmony_ci} 904fd4e5da5Sopenharmony_ci 905fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeInsertVectorOutOfBounds) { 906fd4e5da5Sopenharmony_ci const std::string body = R"( 907fd4e5da5Sopenharmony_ci%val1 = OpCompositeInsert %f32vec4 %f32_1 %f32vec4_0123 4 908fd4e5da5Sopenharmony_ci)"; 909fd4e5da5Sopenharmony_ci 910fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 911fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 912fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 913fd4e5da5Sopenharmony_ci HasSubstr("Vector access is out of bounds, " 914fd4e5da5Sopenharmony_ci "vector size is 4, but access index is 4")); 915fd4e5da5Sopenharmony_ci} 916fd4e5da5Sopenharmony_ci 917fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeInsertMatrixOutOfCols) { 918fd4e5da5Sopenharmony_ci const std::string body = R"( 919fd4e5da5Sopenharmony_ci%val1 = OpCompositeInsert %f32mat23 %f32_1 %f32mat23_121212 3 1 920fd4e5da5Sopenharmony_ci)"; 921fd4e5da5Sopenharmony_ci 922fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 923fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 924fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 925fd4e5da5Sopenharmony_ci HasSubstr("Matrix access is out of bounds, " 926fd4e5da5Sopenharmony_ci "matrix has 3 columns, but access index is 3")); 927fd4e5da5Sopenharmony_ci} 928fd4e5da5Sopenharmony_ci 929fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeInsertMatrixOutOfRows) { 930fd4e5da5Sopenharmony_ci const std::string body = R"( 931fd4e5da5Sopenharmony_ci%val1 = OpCompositeInsert %f32mat23 %f32_1 %f32mat23_121212 2 5 932fd4e5da5Sopenharmony_ci)"; 933fd4e5da5Sopenharmony_ci 934fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 935fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 936fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 937fd4e5da5Sopenharmony_ci HasSubstr("Vector access is out of bounds, " 938fd4e5da5Sopenharmony_ci "vector size is 2, but access index is 5")); 939fd4e5da5Sopenharmony_ci} 940fd4e5da5Sopenharmony_ci 941fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeInsertArrayOutOfBounds) { 942fd4e5da5Sopenharmony_ci const std::string body = R"( 943fd4e5da5Sopenharmony_ci%array = OpCompositeConstruct %f32vec2arr3 %f32vec2_12 %f32vec2_12 %f32vec2_12 944fd4e5da5Sopenharmony_ci%val1 = OpCompositeInsert %f32vec2arr3 %f32vec2_01 %array 3 945fd4e5da5Sopenharmony_ci)"; 946fd4e5da5Sopenharmony_ci 947fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 948fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 949fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 950fd4e5da5Sopenharmony_ci HasSubstr("Array access is out of bounds, array " 951fd4e5da5Sopenharmony_ci "size is 3, but access index is 3")); 952fd4e5da5Sopenharmony_ci} 953fd4e5da5Sopenharmony_ci 954fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeInsertStructOutOfBounds) { 955fd4e5da5Sopenharmony_ci const std::string body = R"( 956fd4e5da5Sopenharmony_ci%struct = OpLoad %big_struct %var_big_struct 957fd4e5da5Sopenharmony_ci%val1 = OpCompositeInsert %big_struct %f32_1 %struct 6 958fd4e5da5Sopenharmony_ci)"; 959fd4e5da5Sopenharmony_ci 960fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 961fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 962fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 963fd4e5da5Sopenharmony_ci HasSubstr("Index is out of bounds, can not find index 6 in the " 964fd4e5da5Sopenharmony_ci "structure <id> '37'. This structure has 6 members. " 965fd4e5da5Sopenharmony_ci "Largest valid index is 5.")); 966fd4e5da5Sopenharmony_ci} 967fd4e5da5Sopenharmony_ci 968fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeInsertNestedVectorOutOfBounds) { 969fd4e5da5Sopenharmony_ci const std::string body = R"( 970fd4e5da5Sopenharmony_ci%struct = OpLoad %big_struct %var_big_struct 971fd4e5da5Sopenharmony_ci%val1 = OpCompositeInsert %big_struct %f32_1 %struct 3 1 5 972fd4e5da5Sopenharmony_ci)"; 973fd4e5da5Sopenharmony_ci 974fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 975fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 976fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 977fd4e5da5Sopenharmony_ci HasSubstr("Vector access is out of bounds, " 978fd4e5da5Sopenharmony_ci "vector size is 2, but access index is 5")); 979fd4e5da5Sopenharmony_ci} 980fd4e5da5Sopenharmony_ci 981fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeInsertTooManyIndices) { 982fd4e5da5Sopenharmony_ci const std::string body = R"( 983fd4e5da5Sopenharmony_ci%struct = OpLoad %big_struct %var_big_struct 984fd4e5da5Sopenharmony_ci%val1 = OpCompositeInsert %big_struct %f32_1 %struct 3 1 1 2 985fd4e5da5Sopenharmony_ci)"; 986fd4e5da5Sopenharmony_ci 987fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 988fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 989fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 990fd4e5da5Sopenharmony_ci HasSubstr("Reached non-composite type while indexes still remain " 991fd4e5da5Sopenharmony_ci "to be traversed.")); 992fd4e5da5Sopenharmony_ci} 993fd4e5da5Sopenharmony_ci 994fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeInsertWrongType1) { 995fd4e5da5Sopenharmony_ci const std::string body = R"( 996fd4e5da5Sopenharmony_ci%struct = OpLoad %big_struct %var_big_struct 997fd4e5da5Sopenharmony_ci%val1 = OpCompositeInsert %big_struct %f32vec2_01 %struct 3 1 1 998fd4e5da5Sopenharmony_ci)"; 999fd4e5da5Sopenharmony_ci 1000fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 1001fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1002fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1003fd4e5da5Sopenharmony_ci HasSubstr("The Object type (OpTypeVector) does not match the " 1004fd4e5da5Sopenharmony_ci "type that results from indexing into the Composite " 1005fd4e5da5Sopenharmony_ci "(OpTypeFloat).")); 1006fd4e5da5Sopenharmony_ci} 1007fd4e5da5Sopenharmony_ci 1008fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeInsertWrongType2) { 1009fd4e5da5Sopenharmony_ci const std::string body = R"( 1010fd4e5da5Sopenharmony_ci%struct = OpLoad %big_struct %var_big_struct 1011fd4e5da5Sopenharmony_ci%val1 = OpCompositeInsert %big_struct %f32_1 %struct 3 1 1012fd4e5da5Sopenharmony_ci)"; 1013fd4e5da5Sopenharmony_ci 1014fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 1015fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1016fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1017fd4e5da5Sopenharmony_ci HasSubstr("The Object type (OpTypeFloat) does not match the type " 1018fd4e5da5Sopenharmony_ci "that results from indexing into the Composite " 1019fd4e5da5Sopenharmony_ci "(OpTypeVector).")); 1020fd4e5da5Sopenharmony_ci} 1021fd4e5da5Sopenharmony_ci 1022fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeInsertWrongType3) { 1023fd4e5da5Sopenharmony_ci const std::string body = R"( 1024fd4e5da5Sopenharmony_ci%struct = OpLoad %big_struct %var_big_struct 1025fd4e5da5Sopenharmony_ci%val1 = OpCompositeInsert %big_struct %f32_1 %struct 2 1 1026fd4e5da5Sopenharmony_ci)"; 1027fd4e5da5Sopenharmony_ci 1028fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 1029fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1030fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1031fd4e5da5Sopenharmony_ci HasSubstr("The Object type (OpTypeFloat) does not match the type " 1032fd4e5da5Sopenharmony_ci "that results from indexing into the Composite " 1033fd4e5da5Sopenharmony_ci "(OpTypeVector).")); 1034fd4e5da5Sopenharmony_ci} 1035fd4e5da5Sopenharmony_ci 1036fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeInsertWrongType4) { 1037fd4e5da5Sopenharmony_ci const std::string body = R"( 1038fd4e5da5Sopenharmony_ci%struct = OpLoad %big_struct %var_big_struct 1039fd4e5da5Sopenharmony_ci%val1 = OpCompositeInsert %big_struct %f32_1 %struct 4 1 1040fd4e5da5Sopenharmony_ci)"; 1041fd4e5da5Sopenharmony_ci 1042fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 1043fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1044fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1045fd4e5da5Sopenharmony_ci HasSubstr("The Object type (OpTypeFloat) does not match the type " 1046fd4e5da5Sopenharmony_ci "that results from indexing into the Composite " 1047fd4e5da5Sopenharmony_ci "(OpTypeVector).")); 1048fd4e5da5Sopenharmony_ci} 1049fd4e5da5Sopenharmony_ci 1050fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeInsertWrongType5) { 1051fd4e5da5Sopenharmony_ci const std::string body = R"( 1052fd4e5da5Sopenharmony_ci%struct = OpLoad %big_struct %var_big_struct 1053fd4e5da5Sopenharmony_ci%val1 = OpCompositeInsert %big_struct %f32_1 %struct 5 1 1054fd4e5da5Sopenharmony_ci)"; 1055fd4e5da5Sopenharmony_ci 1056fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 1057fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1058fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1059fd4e5da5Sopenharmony_ci HasSubstr("The Object type (OpTypeFloat) does not match the type " 1060fd4e5da5Sopenharmony_ci "that results from indexing into the Composite " 1061fd4e5da5Sopenharmony_ci "(OpTypeInt).")); 1062fd4e5da5Sopenharmony_ci} 1063fd4e5da5Sopenharmony_ci 1064fd4e5da5Sopenharmony_ci// Tests ported from val_id_test.cpp. 1065fd4e5da5Sopenharmony_ci 1066fd4e5da5Sopenharmony_ci// Valid. Tests both CompositeExtract and CompositeInsert with 255 indexes. 1067fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeExtractInsertLimitsGood) { 1068fd4e5da5Sopenharmony_ci int depth = 255; 1069fd4e5da5Sopenharmony_ci std::string header = GetHeaderForTestsFromValId(); 1070fd4e5da5Sopenharmony_ci header.erase(header.find("%func")); 1071fd4e5da5Sopenharmony_ci std::ostringstream spirv; 1072fd4e5da5Sopenharmony_ci spirv << header << std::endl; 1073fd4e5da5Sopenharmony_ci 1074fd4e5da5Sopenharmony_ci // Build nested structures. Struct 'i' contains struct 'i-1' 1075fd4e5da5Sopenharmony_ci spirv << "%s_depth_1 = OpTypeStruct %float\n"; 1076fd4e5da5Sopenharmony_ci for (int i = 2; i <= depth; ++i) { 1077fd4e5da5Sopenharmony_ci spirv << "%s_depth_" << i << " = OpTypeStruct %s_depth_" << i - 1 << "\n"; 1078fd4e5da5Sopenharmony_ci } 1079fd4e5da5Sopenharmony_ci 1080fd4e5da5Sopenharmony_ci // Define Pointer and Variable to use for CompositeExtract/Insert. 1081fd4e5da5Sopenharmony_ci spirv << "%_ptr_Uniform_deep_struct = OpTypePointer Uniform %s_depth_" 1082fd4e5da5Sopenharmony_ci << depth << "\n"; 1083fd4e5da5Sopenharmony_ci spirv << "%deep_var = OpVariable %_ptr_Uniform_deep_struct Uniform\n"; 1084fd4e5da5Sopenharmony_ci 1085fd4e5da5Sopenharmony_ci // Function Start 1086fd4e5da5Sopenharmony_ci spirv << R"( 1087fd4e5da5Sopenharmony_ci %func = OpFunction %void None %void_f 1088fd4e5da5Sopenharmony_ci %my_label = OpLabel 1089fd4e5da5Sopenharmony_ci )"; 1090fd4e5da5Sopenharmony_ci 1091fd4e5da5Sopenharmony_ci // OpCompositeExtract/Insert with 'n' indexes (n = depth) 1092fd4e5da5Sopenharmony_ci spirv << "%deep = OpLoad %s_depth_" << depth << " %deep_var" << std::endl; 1093fd4e5da5Sopenharmony_ci spirv << "%entry = OpCompositeExtract %float %deep"; 1094fd4e5da5Sopenharmony_ci for (int i = 0; i < depth; ++i) { 1095fd4e5da5Sopenharmony_ci spirv << " 0"; 1096fd4e5da5Sopenharmony_ci } 1097fd4e5da5Sopenharmony_ci spirv << std::endl; 1098fd4e5da5Sopenharmony_ci spirv << "%new_composite = OpCompositeInsert %s_depth_" << depth 1099fd4e5da5Sopenharmony_ci << " %entry %deep"; 1100fd4e5da5Sopenharmony_ci for (int i = 0; i < depth; ++i) { 1101fd4e5da5Sopenharmony_ci spirv << " 0"; 1102fd4e5da5Sopenharmony_ci } 1103fd4e5da5Sopenharmony_ci spirv << std::endl; 1104fd4e5da5Sopenharmony_ci 1105fd4e5da5Sopenharmony_ci // Function end 1106fd4e5da5Sopenharmony_ci spirv << R"( 1107fd4e5da5Sopenharmony_ci OpReturn 1108fd4e5da5Sopenharmony_ci OpFunctionEnd 1109fd4e5da5Sopenharmony_ci )"; 1110fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv.str()); 1111fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_SUCCESS, ValidateInstructions()); 1112fd4e5da5Sopenharmony_ci} 1113fd4e5da5Sopenharmony_ci 1114fd4e5da5Sopenharmony_ci// Invalid: 256 indexes passed to OpCompositeExtract. Limit is 255. 1115fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeExtractArgCountExceededLimitBad) { 1116fd4e5da5Sopenharmony_ci std::ostringstream spirv; 1117fd4e5da5Sopenharmony_ci spirv << GetHeaderForTestsFromValId() << std::endl; 1118fd4e5da5Sopenharmony_ci spirv << "%matrix = OpLoad %mat4x3 %my_matrix" << std::endl; 1119fd4e5da5Sopenharmony_ci spirv << "%entry = OpCompositeExtract %float %matrix"; 1120fd4e5da5Sopenharmony_ci for (int i = 0; i < 256; ++i) { 1121fd4e5da5Sopenharmony_ci spirv << " 0"; 1122fd4e5da5Sopenharmony_ci } 1123fd4e5da5Sopenharmony_ci spirv << R"( 1124fd4e5da5Sopenharmony_ci OpReturn 1125fd4e5da5Sopenharmony_ci OpFunctionEnd 1126fd4e5da5Sopenharmony_ci )"; 1127fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv.str()); 1128fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1129fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1130fd4e5da5Sopenharmony_ci HasSubstr("The number of indexes in OpCompositeExtract may not " 1131fd4e5da5Sopenharmony_ci "exceed 255. Found 256 indexes.")); 1132fd4e5da5Sopenharmony_ci} 1133fd4e5da5Sopenharmony_ci 1134fd4e5da5Sopenharmony_ci// Invalid: 256 indexes passed to OpCompositeInsert. Limit is 255. 1135fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeInsertArgCountExceededLimitBad) { 1136fd4e5da5Sopenharmony_ci std::ostringstream spirv; 1137fd4e5da5Sopenharmony_ci spirv << GetHeaderForTestsFromValId() << std::endl; 1138fd4e5da5Sopenharmony_ci spirv << "%matrix = OpLoad %mat4x3 %my_matrix" << std::endl; 1139fd4e5da5Sopenharmony_ci spirv << "%new_composite = OpCompositeInsert %mat4x3 %int_0 %matrix"; 1140fd4e5da5Sopenharmony_ci for (int i = 0; i < 256; ++i) { 1141fd4e5da5Sopenharmony_ci spirv << " 0"; 1142fd4e5da5Sopenharmony_ci } 1143fd4e5da5Sopenharmony_ci spirv << R"( 1144fd4e5da5Sopenharmony_ci OpReturn 1145fd4e5da5Sopenharmony_ci OpFunctionEnd 1146fd4e5da5Sopenharmony_ci )"; 1147fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv.str()); 1148fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1149fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1150fd4e5da5Sopenharmony_ci HasSubstr("The number of indexes in OpCompositeInsert may not " 1151fd4e5da5Sopenharmony_ci "exceed 255. Found 256 indexes.")); 1152fd4e5da5Sopenharmony_ci} 1153fd4e5da5Sopenharmony_ci 1154fd4e5da5Sopenharmony_ci// Invalid: In OpCompositeInsert, result type must be the same as composite type 1155fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeInsertWrongResultTypeBad) { 1156fd4e5da5Sopenharmony_ci std::ostringstream spirv; 1157fd4e5da5Sopenharmony_ci spirv << GetHeaderForTestsFromValId() << std::endl; 1158fd4e5da5Sopenharmony_ci spirv << "%matrix = OpLoad %mat4x3 %my_matrix" << std::endl; 1159fd4e5da5Sopenharmony_ci spirv << "%float_entry = OpCompositeExtract %float %matrix 0 1" << std::endl; 1160fd4e5da5Sopenharmony_ci spirv << "%new_composite = OpCompositeInsert %float %float_entry %matrix 0 1" 1161fd4e5da5Sopenharmony_ci << std::endl; 1162fd4e5da5Sopenharmony_ci spirv << R"(OpReturn 1163fd4e5da5Sopenharmony_ci OpFunctionEnd)"; 1164fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv.str()); 1165fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1166fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1167fd4e5da5Sopenharmony_ci HasSubstr("The Result Type must be the same as Composite type")); 1168fd4e5da5Sopenharmony_ci} 1169fd4e5da5Sopenharmony_ci 1170fd4e5da5Sopenharmony_ci// Invalid: No Indexes were passed to OpCompositeExtract. 1171fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeExtractNoIndices2) { 1172fd4e5da5Sopenharmony_ci std::ostringstream spirv; 1173fd4e5da5Sopenharmony_ci spirv << GetHeaderForTestsFromValId() << std::endl; 1174fd4e5da5Sopenharmony_ci spirv << "%matrix = OpLoad %mat4x3 %my_matrix" << std::endl; 1175fd4e5da5Sopenharmony_ci spirv << "%float_entry = OpCompositeExtract %mat4x3 %matrix" << std::endl; 1176fd4e5da5Sopenharmony_ci spirv << R"(OpReturn 1177fd4e5da5Sopenharmony_ci OpFunctionEnd)"; 1178fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv.str()); 1179fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1180fd4e5da5Sopenharmony_ci EXPECT_THAT( 1181fd4e5da5Sopenharmony_ci getDiagnosticString(), 1182fd4e5da5Sopenharmony_ci HasSubstr( 1183fd4e5da5Sopenharmony_ci "Expected at least one index to OpCompositeExtract, zero found")); 1184fd4e5da5Sopenharmony_ci} 1185fd4e5da5Sopenharmony_ci 1186fd4e5da5Sopenharmony_ci// Invalid: No Indexes were passed to OpCompositeExtract. 1187fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeExtractNoIndicesWrongResultType) { 1188fd4e5da5Sopenharmony_ci std::ostringstream spirv; 1189fd4e5da5Sopenharmony_ci spirv << GetHeaderForTestsFromValId() << std::endl; 1190fd4e5da5Sopenharmony_ci spirv << "%matrix = OpLoad %mat4x3 %my_matrix" << std::endl; 1191fd4e5da5Sopenharmony_ci spirv << "%float_entry = OpCompositeExtract %float %matrix" << std::endl; 1192fd4e5da5Sopenharmony_ci spirv << R"(OpReturn 1193fd4e5da5Sopenharmony_ci OpFunctionEnd)"; 1194fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv.str()); 1195fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1196fd4e5da5Sopenharmony_ci EXPECT_THAT( 1197fd4e5da5Sopenharmony_ci getDiagnosticString(), 1198fd4e5da5Sopenharmony_ci HasSubstr( 1199fd4e5da5Sopenharmony_ci "Expected at least one index to OpCompositeExtract, zero found")); 1200fd4e5da5Sopenharmony_ci} 1201fd4e5da5Sopenharmony_ci 1202fd4e5da5Sopenharmony_ci// Invalid: No Indices were passed to OpCompositeInsert, and the type of the 1203fd4e5da5Sopenharmony_ci// Object<id> argument matches the Composite type. 1204fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeInsertMissingIndices) { 1205fd4e5da5Sopenharmony_ci std::ostringstream spirv; 1206fd4e5da5Sopenharmony_ci spirv << GetHeaderForTestsFromValId() << std::endl; 1207fd4e5da5Sopenharmony_ci spirv << "%matrix = OpLoad %mat4x3 %my_matrix" << std::endl; 1208fd4e5da5Sopenharmony_ci spirv << "%matrix_2 = OpLoad %mat4x3 %my_matrix" << std::endl; 1209fd4e5da5Sopenharmony_ci spirv << "%new_composite = OpCompositeInsert %mat4x3 %matrix_2 %matrix"; 1210fd4e5da5Sopenharmony_ci spirv << R"( 1211fd4e5da5Sopenharmony_ci OpReturn 1212fd4e5da5Sopenharmony_ci OpFunctionEnd)"; 1213fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv.str()); 1214fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1215fd4e5da5Sopenharmony_ci EXPECT_THAT( 1216fd4e5da5Sopenharmony_ci getDiagnosticString(), 1217fd4e5da5Sopenharmony_ci HasSubstr( 1218fd4e5da5Sopenharmony_ci "Expected at least one index to OpCompositeInsert, zero found")); 1219fd4e5da5Sopenharmony_ci} 1220fd4e5da5Sopenharmony_ci 1221fd4e5da5Sopenharmony_ci// Invalid: No Indices were passed to OpCompositeInsert, but the type of the 1222fd4e5da5Sopenharmony_ci// Object<id> argument does not match the Composite type. 1223fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeInsertMissingIndices2) { 1224fd4e5da5Sopenharmony_ci std::ostringstream spirv; 1225fd4e5da5Sopenharmony_ci spirv << GetHeaderForTestsFromValId() << std::endl; 1226fd4e5da5Sopenharmony_ci spirv << "%matrix = OpLoad %mat4x3 %my_matrix" << std::endl; 1227fd4e5da5Sopenharmony_ci spirv << "%new_composite = OpCompositeInsert %mat4x3 %int_0 %matrix"; 1228fd4e5da5Sopenharmony_ci spirv << R"( 1229fd4e5da5Sopenharmony_ci OpReturn 1230fd4e5da5Sopenharmony_ci OpFunctionEnd)"; 1231fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv.str()); 1232fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1233fd4e5da5Sopenharmony_ci EXPECT_THAT( 1234fd4e5da5Sopenharmony_ci getDiagnosticString(), 1235fd4e5da5Sopenharmony_ci HasSubstr( 1236fd4e5da5Sopenharmony_ci "Expected at least one index to OpCompositeInsert, zero found")); 1237fd4e5da5Sopenharmony_ci} 1238fd4e5da5Sopenharmony_ci 1239fd4e5da5Sopenharmony_ci// Valid: Tests that we can index into Struct, Array, Matrix, and Vector! 1240fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeExtractInsertIndexIntoAllTypesGood) { 1241fd4e5da5Sopenharmony_ci // indexes that we are passing are: 0, 3, 1, 2, 0 1242fd4e5da5Sopenharmony_ci // 0 will select the struct_s within the base struct (blockName) 1243fd4e5da5Sopenharmony_ci // 3 will select the Array that contains 5 matrices 1244fd4e5da5Sopenharmony_ci // 1 will select the Matrix that is at index 1 of the array 1245fd4e5da5Sopenharmony_ci // 2 will select the column (which is a vector) within the matrix at index 2 1246fd4e5da5Sopenharmony_ci // 0 will select the element at the index 0 of the vector. (which is a float). 1247fd4e5da5Sopenharmony_ci std::ostringstream spirv; 1248fd4e5da5Sopenharmony_ci spirv << GetHeaderForTestsFromValId() << R"( 1249fd4e5da5Sopenharmony_ci %myblock = OpLoad %struct_blockName %blockName_var 1250fd4e5da5Sopenharmony_ci %ss = OpCompositeExtract %struct_s %myblock 0 1251fd4e5da5Sopenharmony_ci %sa = OpCompositeExtract %array5_mat4x3 %myblock 0 3 1252fd4e5da5Sopenharmony_ci %sm = OpCompositeExtract %mat4x3 %myblock 0 3 1 1253fd4e5da5Sopenharmony_ci %sc = OpCompositeExtract %v3float %myblock 0 3 1 2 1254fd4e5da5Sopenharmony_ci %fl = OpCompositeExtract %float %myblock 0 3 1 2 0 1255fd4e5da5Sopenharmony_ci ; 1256fd4e5da5Sopenharmony_ci ; Now let's insert back at different levels... 1257fd4e5da5Sopenharmony_ci ; 1258fd4e5da5Sopenharmony_ci %b1 = OpCompositeInsert %struct_blockName %ss %myblock 0 1259fd4e5da5Sopenharmony_ci %b2 = OpCompositeInsert %struct_blockName %sa %myblock 0 3 1260fd4e5da5Sopenharmony_ci %b3 = OpCompositeInsert %struct_blockName %sm %myblock 0 3 1 1261fd4e5da5Sopenharmony_ci %b4 = OpCompositeInsert %struct_blockName %sc %myblock 0 3 1 2 1262fd4e5da5Sopenharmony_ci %b5 = OpCompositeInsert %struct_blockName %fl %myblock 0 3 1 2 0 1263fd4e5da5Sopenharmony_ci OpReturn 1264fd4e5da5Sopenharmony_ci OpFunctionEnd 1265fd4e5da5Sopenharmony_ci )"; 1266fd4e5da5Sopenharmony_ci 1267fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv.str()); 1268fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_SUCCESS, ValidateInstructions()); 1269fd4e5da5Sopenharmony_ci} 1270fd4e5da5Sopenharmony_ci 1271fd4e5da5Sopenharmony_ci// Invalid. More indexes are provided than needed for OpCompositeExtract. 1272fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeExtractReachedScalarBad) { 1273fd4e5da5Sopenharmony_ci // indexes that we are passing are: 0, 3, 1, 2, 0 1274fd4e5da5Sopenharmony_ci // 0 will select the struct_s within the base struct (blockName) 1275fd4e5da5Sopenharmony_ci // 3 will select the Array that contains 5 matrices 1276fd4e5da5Sopenharmony_ci // 1 will select the Matrix that is at index 1 of the array 1277fd4e5da5Sopenharmony_ci // 2 will select the column (which is a vector) within the matrix at index 2 1278fd4e5da5Sopenharmony_ci // 0 will select the element at the index 0 of the vector. (which is a float). 1279fd4e5da5Sopenharmony_ci std::ostringstream spirv; 1280fd4e5da5Sopenharmony_ci spirv << GetHeaderForTestsFromValId() << R"( 1281fd4e5da5Sopenharmony_ci %myblock = OpLoad %struct_blockName %blockName_var 1282fd4e5da5Sopenharmony_ci %fl = OpCompositeExtract %float %myblock 0 3 1 2 0 1 1283fd4e5da5Sopenharmony_ci OpReturn 1284fd4e5da5Sopenharmony_ci OpFunctionEnd 1285fd4e5da5Sopenharmony_ci )"; 1286fd4e5da5Sopenharmony_ci 1287fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv.str()); 1288fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1289fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1290fd4e5da5Sopenharmony_ci HasSubstr("Reached non-composite type while indexes still remain " 1291fd4e5da5Sopenharmony_ci "to be traversed.")); 1292fd4e5da5Sopenharmony_ci} 1293fd4e5da5Sopenharmony_ci 1294fd4e5da5Sopenharmony_ci// Invalid. More indexes are provided than needed for OpCompositeInsert. 1295fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeInsertReachedScalarBad) { 1296fd4e5da5Sopenharmony_ci // indexes that we are passing are: 0, 3, 1, 2, 0 1297fd4e5da5Sopenharmony_ci // 0 will select the struct_s within the base struct (blockName) 1298fd4e5da5Sopenharmony_ci // 3 will select the Array that contains 5 matrices 1299fd4e5da5Sopenharmony_ci // 1 will select the Matrix that is at index 1 of the array 1300fd4e5da5Sopenharmony_ci // 2 will select the column (which is a vector) within the matrix at index 2 1301fd4e5da5Sopenharmony_ci // 0 will select the element at the index 0 of the vector. (which is a float). 1302fd4e5da5Sopenharmony_ci std::ostringstream spirv; 1303fd4e5da5Sopenharmony_ci spirv << GetHeaderForTestsFromValId() << R"( 1304fd4e5da5Sopenharmony_ci %myblock = OpLoad %struct_blockName %blockName_var 1305fd4e5da5Sopenharmony_ci %fl = OpCompositeExtract %float %myblock 0 3 1 2 0 1306fd4e5da5Sopenharmony_ci %b5 = OpCompositeInsert %struct_blockName %fl %myblock 0 3 1 2 0 1 1307fd4e5da5Sopenharmony_ci OpReturn 1308fd4e5da5Sopenharmony_ci OpFunctionEnd 1309fd4e5da5Sopenharmony_ci )"; 1310fd4e5da5Sopenharmony_ci 1311fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv.str()); 1312fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1313fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1314fd4e5da5Sopenharmony_ci HasSubstr("Reached non-composite type while indexes still remain " 1315fd4e5da5Sopenharmony_ci "to be traversed.")); 1316fd4e5da5Sopenharmony_ci} 1317fd4e5da5Sopenharmony_ci 1318fd4e5da5Sopenharmony_ci// Invalid. Result type doesn't match the type we get from indexing into 1319fd4e5da5Sopenharmony_ci// the composite. 1320fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, 1321fd4e5da5Sopenharmony_ci CompositeExtractResultTypeDoesntMatchIndexedTypeBad) { 1322fd4e5da5Sopenharmony_ci // indexes that we are passing are: 0, 3, 1, 2, 0 1323fd4e5da5Sopenharmony_ci // 0 will select the struct_s within the base struct (blockName) 1324fd4e5da5Sopenharmony_ci // 3 will select the Array that contains 5 matrices 1325fd4e5da5Sopenharmony_ci // 1 will select the Matrix that is at index 1 of the array 1326fd4e5da5Sopenharmony_ci // 2 will select the column (which is a vector) within the matrix at index 2 1327fd4e5da5Sopenharmony_ci // 0 will select the element at the index 0 of the vector. (which is a float). 1328fd4e5da5Sopenharmony_ci std::ostringstream spirv; 1329fd4e5da5Sopenharmony_ci spirv << GetHeaderForTestsFromValId() << R"( 1330fd4e5da5Sopenharmony_ci %myblock = OpLoad %struct_blockName %blockName_var 1331fd4e5da5Sopenharmony_ci %fl = OpCompositeExtract %int %myblock 0 3 1 2 0 1332fd4e5da5Sopenharmony_ci OpReturn 1333fd4e5da5Sopenharmony_ci OpFunctionEnd 1334fd4e5da5Sopenharmony_ci )"; 1335fd4e5da5Sopenharmony_ci 1336fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv.str()); 1337fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1338fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1339fd4e5da5Sopenharmony_ci HasSubstr("Result type (OpTypeInt) does not match the type that " 1340fd4e5da5Sopenharmony_ci "results from indexing into the composite " 1341fd4e5da5Sopenharmony_ci "(OpTypeFloat).")); 1342fd4e5da5Sopenharmony_ci} 1343fd4e5da5Sopenharmony_ci 1344fd4e5da5Sopenharmony_ci// Invalid. Given object type doesn't match the type we get from indexing into 1345fd4e5da5Sopenharmony_ci// the composite. 1346fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeInsertObjectTypeDoesntMatchIndexedTypeBad) { 1347fd4e5da5Sopenharmony_ci // indexes that we are passing are: 0, 3, 1, 2, 0 1348fd4e5da5Sopenharmony_ci // 0 will select the struct_s within the base struct (blockName) 1349fd4e5da5Sopenharmony_ci // 3 will select the Array that contains 5 matrices 1350fd4e5da5Sopenharmony_ci // 1 will select the Matrix that is at index 1 of the array 1351fd4e5da5Sopenharmony_ci // 2 will select the column (which is a vector) within the matrix at index 2 1352fd4e5da5Sopenharmony_ci // 0 will select the element at the index 0 of the vector. (which is a float). 1353fd4e5da5Sopenharmony_ci // We are trying to insert an integer where we should be inserting a float. 1354fd4e5da5Sopenharmony_ci std::ostringstream spirv; 1355fd4e5da5Sopenharmony_ci spirv << GetHeaderForTestsFromValId() << R"( 1356fd4e5da5Sopenharmony_ci %myblock = OpLoad %struct_blockName %blockName_var 1357fd4e5da5Sopenharmony_ci %b5 = OpCompositeInsert %struct_blockName %int_0 %myblock 0 3 1 2 0 1358fd4e5da5Sopenharmony_ci OpReturn 1359fd4e5da5Sopenharmony_ci OpFunctionEnd 1360fd4e5da5Sopenharmony_ci )"; 1361fd4e5da5Sopenharmony_ci 1362fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv.str()); 1363fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1364fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1365fd4e5da5Sopenharmony_ci HasSubstr("The Object type (OpTypeInt) does not match the type " 1366fd4e5da5Sopenharmony_ci "that results from indexing into the Composite " 1367fd4e5da5Sopenharmony_ci "(OpTypeFloat).")); 1368fd4e5da5Sopenharmony_ci} 1369fd4e5da5Sopenharmony_ci 1370fd4e5da5Sopenharmony_ci// Invalid. Index into a struct is larger than the number of struct members. 1371fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeExtractStructIndexOutOfBoundBad) { 1372fd4e5da5Sopenharmony_ci // struct_blockName has 3 members (index 0,1,2). We'll try to access index 3. 1373fd4e5da5Sopenharmony_ci std::ostringstream spirv; 1374fd4e5da5Sopenharmony_ci spirv << GetHeaderForTestsFromValId() << R"( 1375fd4e5da5Sopenharmony_ci %myblock = OpLoad %struct_blockName %blockName_var 1376fd4e5da5Sopenharmony_ci %ss = OpCompositeExtract %struct_s %myblock 3 1377fd4e5da5Sopenharmony_ci OpReturn 1378fd4e5da5Sopenharmony_ci OpFunctionEnd 1379fd4e5da5Sopenharmony_ci )"; 1380fd4e5da5Sopenharmony_ci 1381fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv.str()); 1382fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1383fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1384fd4e5da5Sopenharmony_ci HasSubstr("Index is out of bounds, can not find index 3 in the " 1385fd4e5da5Sopenharmony_ci "structure <id> '25'. This structure has 2 members. " 1386fd4e5da5Sopenharmony_ci "Largest valid index is 1.")); 1387fd4e5da5Sopenharmony_ci} 1388fd4e5da5Sopenharmony_ci 1389fd4e5da5Sopenharmony_ci// Invalid. Index into a struct is larger than the number of struct members. 1390fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeInsertStructIndexOutOfBoundBad) { 1391fd4e5da5Sopenharmony_ci // struct_blockName has 3 members (index 0,1,2). We'll try to access index 3. 1392fd4e5da5Sopenharmony_ci std::ostringstream spirv; 1393fd4e5da5Sopenharmony_ci spirv << GetHeaderForTestsFromValId() << R"( 1394fd4e5da5Sopenharmony_ci %myblock = OpLoad %struct_blockName %blockName_var 1395fd4e5da5Sopenharmony_ci %ss = OpCompositeExtract %struct_s %myblock 0 1396fd4e5da5Sopenharmony_ci %new_composite = OpCompositeInsert %struct_blockName %ss %myblock 3 1397fd4e5da5Sopenharmony_ci OpReturn 1398fd4e5da5Sopenharmony_ci OpFunctionEnd 1399fd4e5da5Sopenharmony_ci )"; 1400fd4e5da5Sopenharmony_ci 1401fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv.str()); 1402fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1403fd4e5da5Sopenharmony_ci EXPECT_THAT( 1404fd4e5da5Sopenharmony_ci getDiagnosticString(), 1405fd4e5da5Sopenharmony_ci HasSubstr("Index is out of bounds, can not find index 3 in the structure " 1406fd4e5da5Sopenharmony_ci "<id> '25'. This structure has 2 members. Largest valid index " 1407fd4e5da5Sopenharmony_ci "is 1.")); 1408fd4e5da5Sopenharmony_ci} 1409fd4e5da5Sopenharmony_ci 1410fd4e5da5Sopenharmony_ci// #1403: Ensure that the default spec constant value is not used to check the 1411fd4e5da5Sopenharmony_ci// extract index. 1412fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, ExtractFromSpecConstantSizedArray) { 1413fd4e5da5Sopenharmony_ci std::string spirv = R"( 1414fd4e5da5Sopenharmony_ciOpCapability Kernel 1415fd4e5da5Sopenharmony_ciOpCapability Linkage 1416fd4e5da5Sopenharmony_ciOpMemoryModel Logical OpenCL 1417fd4e5da5Sopenharmony_ciOpDecorate %spec_const SpecId 1 1418fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1419fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 1420fd4e5da5Sopenharmony_ci%spec_const = OpSpecConstant %uint 3 1421fd4e5da5Sopenharmony_ci%uint_array = OpTypeArray %uint %spec_const 1422fd4e5da5Sopenharmony_ci%undef = OpUndef %uint_array 1423fd4e5da5Sopenharmony_ci%voidf = OpTypeFunction %void 1424fd4e5da5Sopenharmony_ci%func = OpFunction %void None %voidf 1425fd4e5da5Sopenharmony_ci%1 = OpLabel 1426fd4e5da5Sopenharmony_ci%2 = OpCompositeExtract %uint %undef 4 1427fd4e5da5Sopenharmony_ciOpReturn 1428fd4e5da5Sopenharmony_ciOpFunctionEnd 1429fd4e5da5Sopenharmony_ci)"; 1430fd4e5da5Sopenharmony_ci 1431fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 1432fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_SUCCESS, ValidateInstructions()); 1433fd4e5da5Sopenharmony_ci} 1434fd4e5da5Sopenharmony_ci 1435fd4e5da5Sopenharmony_ci// #1403: Ensure that spec constant ops do not produce false positives. 1436fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, ExtractFromSpecConstantOpSizedArray) { 1437fd4e5da5Sopenharmony_ci std::string spirv = R"( 1438fd4e5da5Sopenharmony_ciOpCapability Kernel 1439fd4e5da5Sopenharmony_ciOpCapability Linkage 1440fd4e5da5Sopenharmony_ciOpMemoryModel Logical OpenCL 1441fd4e5da5Sopenharmony_ciOpDecorate %spec_const SpecId 1 1442fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1443fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 1444fd4e5da5Sopenharmony_ci%const = OpConstant %uint 1 1445fd4e5da5Sopenharmony_ci%spec_const = OpSpecConstant %uint 3 1446fd4e5da5Sopenharmony_ci%spec_const_op = OpSpecConstantOp %uint IAdd %spec_const %const 1447fd4e5da5Sopenharmony_ci%uint_array = OpTypeArray %uint %spec_const_op 1448fd4e5da5Sopenharmony_ci%undef = OpUndef %uint_array 1449fd4e5da5Sopenharmony_ci%voidf = OpTypeFunction %void 1450fd4e5da5Sopenharmony_ci%func = OpFunction %void None %voidf 1451fd4e5da5Sopenharmony_ci%1 = OpLabel 1452fd4e5da5Sopenharmony_ci%2 = OpCompositeExtract %uint %undef 4 1453fd4e5da5Sopenharmony_ciOpReturn 1454fd4e5da5Sopenharmony_ciOpFunctionEnd 1455fd4e5da5Sopenharmony_ci)"; 1456fd4e5da5Sopenharmony_ci 1457fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 1458fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_SUCCESS, ValidateInstructions()); 1459fd4e5da5Sopenharmony_ci} 1460fd4e5da5Sopenharmony_ci 1461fd4e5da5Sopenharmony_ci// #1403: Ensure that the default spec constant value is not used to check the 1462fd4e5da5Sopenharmony_ci// size of the array for a composite construct. This code has limited actual 1463fd4e5da5Sopenharmony_ci// value as it is incorrect unless the specialization constant is assigned the 1464fd4e5da5Sopenharmony_ci// value of 2, but it is still a valid module. 1465fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CompositeConstructSpecConstantSizedArray) { 1466fd4e5da5Sopenharmony_ci std::string spirv = R"( 1467fd4e5da5Sopenharmony_ciOpCapability Kernel 1468fd4e5da5Sopenharmony_ciOpCapability Linkage 1469fd4e5da5Sopenharmony_ciOpMemoryModel Logical OpenCL 1470fd4e5da5Sopenharmony_ciOpDecorate %spec_const SpecId 1 1471fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1472fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 1473fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0 1474fd4e5da5Sopenharmony_ci%spec_const = OpSpecConstant %uint 3 1475fd4e5da5Sopenharmony_ci%uint_array = OpTypeArray %uint %spec_const 1476fd4e5da5Sopenharmony_ci%voidf = OpTypeFunction %void 1477fd4e5da5Sopenharmony_ci%func = OpFunction %void None %voidf 1478fd4e5da5Sopenharmony_ci%1 = OpLabel 1479fd4e5da5Sopenharmony_ci%2 = OpCompositeConstruct %uint_array %uint_0 %uint_0 1480fd4e5da5Sopenharmony_ciOpReturn 1481fd4e5da5Sopenharmony_ciOpFunctionEnd 1482fd4e5da5Sopenharmony_ci)"; 1483fd4e5da5Sopenharmony_ci 1484fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 1485fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_SUCCESS, ValidateInstructions()); 1486fd4e5da5Sopenharmony_ci} 1487fd4e5da5Sopenharmony_ci 1488fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CoopMatConstantCompositeMismatchFail) { 1489fd4e5da5Sopenharmony_ci const std::string body = R"( 1490fd4e5da5Sopenharmony_ciOpCapability Shader 1491fd4e5da5Sopenharmony_ciOpCapability Float16 1492fd4e5da5Sopenharmony_ciOpCapability CooperativeMatrixNV 1493fd4e5da5Sopenharmony_ciOpExtension "SPV_NV_cooperative_matrix" 1494fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1495fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main" 1496fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1497fd4e5da5Sopenharmony_ci%func = OpTypeFunction %void 1498fd4e5da5Sopenharmony_ci%bool = OpTypeBool 1499fd4e5da5Sopenharmony_ci%f16 = OpTypeFloat 16 1500fd4e5da5Sopenharmony_ci%f32 = OpTypeFloat 32 1501fd4e5da5Sopenharmony_ci%u32 = OpTypeInt 32 0 1502fd4e5da5Sopenharmony_ci 1503fd4e5da5Sopenharmony_ci%u32_8 = OpConstant %u32 8 1504fd4e5da5Sopenharmony_ci%subgroup = OpConstant %u32 3 1505fd4e5da5Sopenharmony_ci 1506fd4e5da5Sopenharmony_ci%f16mat = OpTypeCooperativeMatrixNV %f16 %subgroup %u32_8 %u32_8 1507fd4e5da5Sopenharmony_ci 1508fd4e5da5Sopenharmony_ci%f32_1 = OpConstant %f32 1 1509fd4e5da5Sopenharmony_ci 1510fd4e5da5Sopenharmony_ci%f16mat_1 = OpConstantComposite %f16mat %f32_1 1511fd4e5da5Sopenharmony_ci 1512fd4e5da5Sopenharmony_ci%main = OpFunction %void None %func 1513fd4e5da5Sopenharmony_ci%main_entry = OpLabel 1514fd4e5da5Sopenharmony_ci 1515fd4e5da5Sopenharmony_ciOpReturn 1516fd4e5da5Sopenharmony_ciOpFunctionEnd)"; 1517fd4e5da5Sopenharmony_ci 1518fd4e5da5Sopenharmony_ci CompileSuccessfully(body.c_str()); 1519fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); 1520fd4e5da5Sopenharmony_ci EXPECT_THAT( 1521fd4e5da5Sopenharmony_ci getDiagnosticString(), 1522fd4e5da5Sopenharmony_ci HasSubstr("OpConstantComposite Constituent <id> '11[%float_1]' type does " 1523fd4e5da5Sopenharmony_ci "not match the Result Type <id> '10[%10]'s component type.")); 1524fd4e5da5Sopenharmony_ci} 1525fd4e5da5Sopenharmony_ci 1526fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CoopMatCompositeConstructMismatchFail) { 1527fd4e5da5Sopenharmony_ci const std::string body = R"( 1528fd4e5da5Sopenharmony_ciOpCapability Shader 1529fd4e5da5Sopenharmony_ciOpCapability Float16 1530fd4e5da5Sopenharmony_ciOpCapability CooperativeMatrixNV 1531fd4e5da5Sopenharmony_ciOpExtension "SPV_NV_cooperative_matrix" 1532fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1533fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main" 1534fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1535fd4e5da5Sopenharmony_ci%func = OpTypeFunction %void 1536fd4e5da5Sopenharmony_ci%bool = OpTypeBool 1537fd4e5da5Sopenharmony_ci%f16 = OpTypeFloat 16 1538fd4e5da5Sopenharmony_ci%f32 = OpTypeFloat 32 1539fd4e5da5Sopenharmony_ci%u32 = OpTypeInt 32 0 1540fd4e5da5Sopenharmony_ci 1541fd4e5da5Sopenharmony_ci%u32_8 = OpConstant %u32 8 1542fd4e5da5Sopenharmony_ci%subgroup = OpConstant %u32 3 1543fd4e5da5Sopenharmony_ci 1544fd4e5da5Sopenharmony_ci%f16mat = OpTypeCooperativeMatrixNV %f16 %subgroup %u32_8 %u32_8 1545fd4e5da5Sopenharmony_ci 1546fd4e5da5Sopenharmony_ci%f32_1 = OpConstant %f32 1 1547fd4e5da5Sopenharmony_ci 1548fd4e5da5Sopenharmony_ci%main = OpFunction %void None %func 1549fd4e5da5Sopenharmony_ci%main_entry = OpLabel 1550fd4e5da5Sopenharmony_ci 1551fd4e5da5Sopenharmony_ci%f16mat_1 = OpCompositeConstruct %f16mat %f32_1 1552fd4e5da5Sopenharmony_ci 1553fd4e5da5Sopenharmony_ciOpReturn 1554fd4e5da5Sopenharmony_ciOpFunctionEnd)"; 1555fd4e5da5Sopenharmony_ci 1556fd4e5da5Sopenharmony_ci CompileSuccessfully(body.c_str()); 1557fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1558fd4e5da5Sopenharmony_ci EXPECT_THAT( 1559fd4e5da5Sopenharmony_ci getDiagnosticString(), 1560fd4e5da5Sopenharmony_ci HasSubstr("Expected Constituent type to be equal to the component type")); 1561fd4e5da5Sopenharmony_ci} 1562fd4e5da5Sopenharmony_ci 1563fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CoopMatKHRConstantCompositeMismatchFail) { 1564fd4e5da5Sopenharmony_ci const std::string body = R"( 1565fd4e5da5Sopenharmony_ciOpCapability Shader 1566fd4e5da5Sopenharmony_ciOpCapability Float16 1567fd4e5da5Sopenharmony_ciOpCapability CooperativeMatrixKHR 1568fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_cooperative_matrix" 1569fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model" 1570fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1571fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main" 1572fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1573fd4e5da5Sopenharmony_ci%func = OpTypeFunction %void 1574fd4e5da5Sopenharmony_ci%bool = OpTypeBool 1575fd4e5da5Sopenharmony_ci%f16 = OpTypeFloat 16 1576fd4e5da5Sopenharmony_ci%f32 = OpTypeFloat 32 1577fd4e5da5Sopenharmony_ci%u32 = OpTypeInt 32 0 1578fd4e5da5Sopenharmony_ci 1579fd4e5da5Sopenharmony_ci%u32_16 = OpConstant %u32 16 1580fd4e5da5Sopenharmony_ci%useA = OpConstant %u32 0 1581fd4e5da5Sopenharmony_ci%subgroup = OpConstant %u32 3 1582fd4e5da5Sopenharmony_ci 1583fd4e5da5Sopenharmony_ci%f16mat = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_16 %u32_16 %useA 1584fd4e5da5Sopenharmony_ci 1585fd4e5da5Sopenharmony_ci%f32_1 = OpConstant %f32 1 1586fd4e5da5Sopenharmony_ci 1587fd4e5da5Sopenharmony_ci%f16mat_1 = OpConstantComposite %f16mat %f32_1 1588fd4e5da5Sopenharmony_ci 1589fd4e5da5Sopenharmony_ci%main = OpFunction %void None %func 1590fd4e5da5Sopenharmony_ci%main_entry = OpLabel 1591fd4e5da5Sopenharmony_ci 1592fd4e5da5Sopenharmony_ciOpReturn 1593fd4e5da5Sopenharmony_ciOpFunctionEnd)"; 1594fd4e5da5Sopenharmony_ci 1595fd4e5da5Sopenharmony_ci CompileSuccessfully(body.c_str()); 1596fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); 1597fd4e5da5Sopenharmony_ci EXPECT_THAT( 1598fd4e5da5Sopenharmony_ci getDiagnosticString(), 1599fd4e5da5Sopenharmony_ci HasSubstr( 1600fd4e5da5Sopenharmony_ci "OpConstantComposite Constituent <id> '12[%float_1]' type " 1601fd4e5da5Sopenharmony_ci "does not match the Result Type <id> '11[%11]'s component type.")); 1602fd4e5da5Sopenharmony_ci} 1603fd4e5da5Sopenharmony_ci 1604fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CoopMatKHRCompositeConstructMismatchFail) { 1605fd4e5da5Sopenharmony_ci const std::string body = R"( 1606fd4e5da5Sopenharmony_ciOpCapability Shader 1607fd4e5da5Sopenharmony_ciOpCapability Float16 1608fd4e5da5Sopenharmony_ciOpCapability CooperativeMatrixKHR 1609fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_cooperative_matrix" 1610fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model" 1611fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1612fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main" 1613fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1614fd4e5da5Sopenharmony_ci%func = OpTypeFunction %void 1615fd4e5da5Sopenharmony_ci%bool = OpTypeBool 1616fd4e5da5Sopenharmony_ci%f16 = OpTypeFloat 16 1617fd4e5da5Sopenharmony_ci%f32 = OpTypeFloat 32 1618fd4e5da5Sopenharmony_ci%u32 = OpTypeInt 32 0 1619fd4e5da5Sopenharmony_ci 1620fd4e5da5Sopenharmony_ci%u32_16 = OpConstant %u32 16 1621fd4e5da5Sopenharmony_ci%useA = OpConstant %u32 0 1622fd4e5da5Sopenharmony_ci%subgroup = OpConstant %u32 3 1623fd4e5da5Sopenharmony_ci 1624fd4e5da5Sopenharmony_ci%f16mat = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_16 %u32_16 %useA 1625fd4e5da5Sopenharmony_ci 1626fd4e5da5Sopenharmony_ci%f32_1 = OpConstant %f32 1 1627fd4e5da5Sopenharmony_ci 1628fd4e5da5Sopenharmony_ci%main = OpFunction %void None %func 1629fd4e5da5Sopenharmony_ci%main_entry = OpLabel 1630fd4e5da5Sopenharmony_ci 1631fd4e5da5Sopenharmony_ci%f16mat_1 = OpCompositeConstruct %f16mat %f32_1 1632fd4e5da5Sopenharmony_ci 1633fd4e5da5Sopenharmony_ciOpReturn 1634fd4e5da5Sopenharmony_ciOpFunctionEnd)"; 1635fd4e5da5Sopenharmony_ci 1636fd4e5da5Sopenharmony_ci CompileSuccessfully(body.c_str()); 1637fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1638fd4e5da5Sopenharmony_ci EXPECT_THAT( 1639fd4e5da5Sopenharmony_ci getDiagnosticString(), 1640fd4e5da5Sopenharmony_ci HasSubstr("Expected Constituent type to be equal to the component type")); 1641fd4e5da5Sopenharmony_ci} 1642fd4e5da5Sopenharmony_ci 1643fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, ExtractDynamicLabelIndex) { 1644fd4e5da5Sopenharmony_ci const std::string spirv = R"( 1645fd4e5da5Sopenharmony_ciOpCapability Shader 1646fd4e5da5Sopenharmony_ciOpCapability Linkage 1647fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1648fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1649fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 1650fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 1651fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 1652fd4e5da5Sopenharmony_ci%float_0 = OpConstant %float 0 1653fd4e5da5Sopenharmony_ci%v4float_0 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0 1654fd4e5da5Sopenharmony_ci%func = OpFunction %void None %void_fn 1655fd4e5da5Sopenharmony_ci%1 = OpLabel 1656fd4e5da5Sopenharmony_ci%ex = OpVectorExtractDynamic %float %v4float_0 %v4float_0 1657fd4e5da5Sopenharmony_ciOpReturn 1658fd4e5da5Sopenharmony_ciOpFunctionEnd 1659fd4e5da5Sopenharmony_ci)"; 1660fd4e5da5Sopenharmony_ci 1661fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 1662fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1663fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1664fd4e5da5Sopenharmony_ci HasSubstr("Expected Index to be int scalar")); 1665fd4e5da5Sopenharmony_ci} 1666fd4e5da5Sopenharmony_ci 1667fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CopyLogicalSameType) { 1668fd4e5da5Sopenharmony_ci const std::string spirv = R"( 1669fd4e5da5Sopenharmony_ciOpCapability Shader 1670fd4e5da5Sopenharmony_ciOpCapability Linkage 1671fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1672fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1673fd4e5da5Sopenharmony_ci%struct = OpTypeStruct 1674fd4e5da5Sopenharmony_ci%const_struct = OpConstantComposite %struct 1675fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 1676fd4e5da5Sopenharmony_ci%func = OpFunction %void None %void_fn 1677fd4e5da5Sopenharmony_ci%1 = OpLabel 1678fd4e5da5Sopenharmony_ci%copy = OpCopyLogical %struct %const_struct 1679fd4e5da5Sopenharmony_ciOpReturn 1680fd4e5da5Sopenharmony_ciOpFunctionEnd 1681fd4e5da5Sopenharmony_ci)"; 1682fd4e5da5Sopenharmony_ci 1683fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4); 1684fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4)); 1685fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1686fd4e5da5Sopenharmony_ci HasSubstr("Result Type must not equal the Operand type")); 1687fd4e5da5Sopenharmony_ci} 1688fd4e5da5Sopenharmony_ci 1689fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CopyLogicalSameStructDifferentId) { 1690fd4e5da5Sopenharmony_ci const std::string spirv = R"( 1691fd4e5da5Sopenharmony_ciOpCapability Shader 1692fd4e5da5Sopenharmony_ciOpCapability Linkage 1693fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1694fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1695fd4e5da5Sopenharmony_ci%struct1 = OpTypeStruct 1696fd4e5da5Sopenharmony_ci%struct2 = OpTypeStruct 1697fd4e5da5Sopenharmony_ci%const_struct = OpConstantComposite %struct1 1698fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 1699fd4e5da5Sopenharmony_ci%func = OpFunction %void None %void_fn 1700fd4e5da5Sopenharmony_ci%1 = OpLabel 1701fd4e5da5Sopenharmony_ci%copy = OpCopyLogical %struct2 %const_struct 1702fd4e5da5Sopenharmony_ciOpReturn 1703fd4e5da5Sopenharmony_ciOpFunctionEnd 1704fd4e5da5Sopenharmony_ci)"; 1705fd4e5da5Sopenharmony_ci 1706fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4); 1707fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4)); 1708fd4e5da5Sopenharmony_ci} 1709fd4e5da5Sopenharmony_ci 1710fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CopyLogicalArrayDifferentLength) { 1711fd4e5da5Sopenharmony_ci const std::string spirv = R"( 1712fd4e5da5Sopenharmony_ciOpCapability Shader 1713fd4e5da5Sopenharmony_ciOpCapability Linkage 1714fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1715fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1716fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 1717fd4e5da5Sopenharmony_ci%int_4 = OpConstant %int 4 1718fd4e5da5Sopenharmony_ci%int_5 = OpConstant %int 5 1719fd4e5da5Sopenharmony_ci%array1 = OpTypeArray %int %int_4 1720fd4e5da5Sopenharmony_ci%array2 = OpTypeArray %int %int_5 1721fd4e5da5Sopenharmony_ci%const_array = OpConstantComposite %array1 %int_4 %int_4 %int_4 %int_4 1722fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 1723fd4e5da5Sopenharmony_ci%func = OpFunction %void None %void_fn 1724fd4e5da5Sopenharmony_ci%1 = OpLabel 1725fd4e5da5Sopenharmony_ci%copy = OpCopyLogical %array2 %const_array 1726fd4e5da5Sopenharmony_ciOpReturn 1727fd4e5da5Sopenharmony_ciOpFunctionEnd 1728fd4e5da5Sopenharmony_ci)"; 1729fd4e5da5Sopenharmony_ci 1730fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4); 1731fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4)); 1732fd4e5da5Sopenharmony_ci EXPECT_THAT( 1733fd4e5da5Sopenharmony_ci getDiagnosticString(), 1734fd4e5da5Sopenharmony_ci HasSubstr("Result Type does not logically match the Operand type")); 1735fd4e5da5Sopenharmony_ci} 1736fd4e5da5Sopenharmony_ci 1737fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CopyLogicalArrayDifferentElement) { 1738fd4e5da5Sopenharmony_ci const std::string spirv = R"( 1739fd4e5da5Sopenharmony_ciOpCapability Shader 1740fd4e5da5Sopenharmony_ciOpCapability Linkage 1741fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1742fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1743fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 1744fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 1745fd4e5da5Sopenharmony_ci%int_4 = OpConstant %int 4 1746fd4e5da5Sopenharmony_ci%array1 = OpTypeArray %int %int_4 1747fd4e5da5Sopenharmony_ci%array2 = OpTypeArray %float %int_4 1748fd4e5da5Sopenharmony_ci%const_array = OpConstantComposite %array1 %int_4 %int_4 %int_4 %int_4 1749fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 1750fd4e5da5Sopenharmony_ci%func = OpFunction %void None %void_fn 1751fd4e5da5Sopenharmony_ci%1 = OpLabel 1752fd4e5da5Sopenharmony_ci%copy = OpCopyLogical %array2 %const_array 1753fd4e5da5Sopenharmony_ciOpReturn 1754fd4e5da5Sopenharmony_ciOpFunctionEnd 1755fd4e5da5Sopenharmony_ci)"; 1756fd4e5da5Sopenharmony_ci 1757fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4); 1758fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4)); 1759fd4e5da5Sopenharmony_ci EXPECT_THAT( 1760fd4e5da5Sopenharmony_ci getDiagnosticString(), 1761fd4e5da5Sopenharmony_ci HasSubstr("Result Type does not logically match the Operand type")); 1762fd4e5da5Sopenharmony_ci} 1763fd4e5da5Sopenharmony_ci 1764fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CopyLogicalArrayLogicallyMatchedElement) { 1765fd4e5da5Sopenharmony_ci const std::string spirv = R"( 1766fd4e5da5Sopenharmony_ciOpCapability Shader 1767fd4e5da5Sopenharmony_ciOpCapability Linkage 1768fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1769fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1770fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 1771fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 1772fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1 1773fd4e5da5Sopenharmony_ci%inner1 = OpTypeArray %int %int_1 1774fd4e5da5Sopenharmony_ci%inner2 = OpTypeArray %int %int_1 1775fd4e5da5Sopenharmony_ci%array1 = OpTypeArray %inner1 %int_1 1776fd4e5da5Sopenharmony_ci%array2 = OpTypeArray %inner2 %int_1 1777fd4e5da5Sopenharmony_ci%const_inner = OpConstantComposite %inner1 %int_1 1778fd4e5da5Sopenharmony_ci%const_array = OpConstantComposite %array1 %const_inner 1779fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 1780fd4e5da5Sopenharmony_ci%func = OpFunction %void None %void_fn 1781fd4e5da5Sopenharmony_ci%1 = OpLabel 1782fd4e5da5Sopenharmony_ci%copy = OpCopyLogical %array2 %const_array 1783fd4e5da5Sopenharmony_ciOpReturn 1784fd4e5da5Sopenharmony_ciOpFunctionEnd 1785fd4e5da5Sopenharmony_ci)"; 1786fd4e5da5Sopenharmony_ci 1787fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4); 1788fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4)); 1789fd4e5da5Sopenharmony_ci} 1790fd4e5da5Sopenharmony_ci 1791fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CopyLogicalStructDifferentNumberElements) { 1792fd4e5da5Sopenharmony_ci const std::string spirv = R"( 1793fd4e5da5Sopenharmony_ciOpCapability Shader 1794fd4e5da5Sopenharmony_ciOpCapability Linkage 1795fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1796fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1797fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 1798fd4e5da5Sopenharmony_ci%struct1 = OpTypeStruct 1799fd4e5da5Sopenharmony_ci%struct2 = OpTypeStruct %int 1800fd4e5da5Sopenharmony_ci%const_struct = OpConstantComposite %struct1 1801fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 1802fd4e5da5Sopenharmony_ci%func = OpFunction %void None %void_fn 1803fd4e5da5Sopenharmony_ci%1 = OpLabel 1804fd4e5da5Sopenharmony_ci%copy = OpCopyLogical %struct2 %const_struct 1805fd4e5da5Sopenharmony_ciOpReturn 1806fd4e5da5Sopenharmony_ciOpFunctionEnd 1807fd4e5da5Sopenharmony_ci)"; 1808fd4e5da5Sopenharmony_ci 1809fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4); 1810fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4)); 1811fd4e5da5Sopenharmony_ci EXPECT_THAT( 1812fd4e5da5Sopenharmony_ci getDiagnosticString(), 1813fd4e5da5Sopenharmony_ci HasSubstr("Result Type does not logically match the Operand type")); 1814fd4e5da5Sopenharmony_ci} 1815fd4e5da5Sopenharmony_ci 1816fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CopyLogicalStructDifferentElement) { 1817fd4e5da5Sopenharmony_ci const std::string spirv = R"( 1818fd4e5da5Sopenharmony_ciOpCapability Shader 1819fd4e5da5Sopenharmony_ciOpCapability Linkage 1820fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1821fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1822fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 1823fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1 1824fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0 1825fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0 1826fd4e5da5Sopenharmony_ci%struct1 = OpTypeStruct %int %uint 1827fd4e5da5Sopenharmony_ci%struct2 = OpTypeStruct %int %int 1828fd4e5da5Sopenharmony_ci%const_struct = OpConstantComposite %struct1 %int_0 %uint_0 1829fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 1830fd4e5da5Sopenharmony_ci%func = OpFunction %void None %void_fn 1831fd4e5da5Sopenharmony_ci%1 = OpLabel 1832fd4e5da5Sopenharmony_ci%copy = OpCopyLogical %struct2 %const_struct 1833fd4e5da5Sopenharmony_ciOpReturn 1834fd4e5da5Sopenharmony_ciOpFunctionEnd 1835fd4e5da5Sopenharmony_ci)"; 1836fd4e5da5Sopenharmony_ci 1837fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4); 1838fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4)); 1839fd4e5da5Sopenharmony_ci EXPECT_THAT( 1840fd4e5da5Sopenharmony_ci getDiagnosticString(), 1841fd4e5da5Sopenharmony_ci HasSubstr("Result Type does not logically match the Operand type")); 1842fd4e5da5Sopenharmony_ci} 1843fd4e5da5Sopenharmony_ci 1844fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CopyLogicalStructLogicallyMatch) { 1845fd4e5da5Sopenharmony_ci const std::string spirv = R"( 1846fd4e5da5Sopenharmony_ciOpCapability Shader 1847fd4e5da5Sopenharmony_ciOpCapability Linkage 1848fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 1849fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1850fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 1851fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1 1852fd4e5da5Sopenharmony_ci%array1 = OpTypeArray %int %int_1 1853fd4e5da5Sopenharmony_ci%array2 = OpTypeArray %int %int_1 1854fd4e5da5Sopenharmony_ci%struct1 = OpTypeStruct %int %array1 1855fd4e5da5Sopenharmony_ci%struct2 = OpTypeStruct %int %array2 1856fd4e5da5Sopenharmony_ci%const_array = OpConstantComposite %array1 %int_1 1857fd4e5da5Sopenharmony_ci%const_struct = OpConstantComposite %struct1 %int_1 %const_array 1858fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 1859fd4e5da5Sopenharmony_ci%func = OpFunction %void None %void_fn 1860fd4e5da5Sopenharmony_ci%1 = OpLabel 1861fd4e5da5Sopenharmony_ci%copy = OpCopyLogical %struct2 %const_struct 1862fd4e5da5Sopenharmony_ciOpReturn 1863fd4e5da5Sopenharmony_ciOpFunctionEnd 1864fd4e5da5Sopenharmony_ci)"; 1865fd4e5da5Sopenharmony_ci 1866fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4); 1867fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4)); 1868fd4e5da5Sopenharmony_ci} 1869fd4e5da5Sopenharmony_ci 1870fd4e5da5Sopenharmony_ciusing ValidateSmallComposites = spvtest::ValidateBase<std::string>; 1871fd4e5da5Sopenharmony_ci 1872fd4e5da5Sopenharmony_ciCodeGenerator GetSmallCompositesCodeGenerator() { 1873fd4e5da5Sopenharmony_ci CodeGenerator generator; 1874fd4e5da5Sopenharmony_ci generator.capabilities_ = R"( 1875fd4e5da5Sopenharmony_ciOpCapability Shader 1876fd4e5da5Sopenharmony_ciOpCapability Linkage 1877fd4e5da5Sopenharmony_ciOpCapability UniformAndStorageBuffer16BitAccess 1878fd4e5da5Sopenharmony_ciOpCapability UniformAndStorageBuffer8BitAccess 1879fd4e5da5Sopenharmony_ci)"; 1880fd4e5da5Sopenharmony_ci generator.extensions_ = R"( 1881fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_16bit_storage" 1882fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_8bit_storage" 1883fd4e5da5Sopenharmony_ci)"; 1884fd4e5da5Sopenharmony_ci generator.memory_model_ = "OpMemoryModel Logical GLSL450\n"; 1885fd4e5da5Sopenharmony_ci generator.before_types_ = R"( 1886fd4e5da5Sopenharmony_ciOpDecorate %char_block Block 1887fd4e5da5Sopenharmony_ciOpMemberDecorate %char_block 0 Offset 0 1888fd4e5da5Sopenharmony_ciOpDecorate %short_block Block 1889fd4e5da5Sopenharmony_ciOpMemberDecorate %short_block 0 Offset 0 1890fd4e5da5Sopenharmony_ciOpDecorate %half_block Block 1891fd4e5da5Sopenharmony_ciOpMemberDecorate %half_block 0 Offset 0 1892fd4e5da5Sopenharmony_ci)"; 1893fd4e5da5Sopenharmony_ci generator.types_ = R"( 1894fd4e5da5Sopenharmony_ci%void = OpTypeVoid 1895fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 1896fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0 1897fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1 1898fd4e5da5Sopenharmony_ci%char = OpTypeInt 8 0 1899fd4e5da5Sopenharmony_ci%char2 = OpTypeVector %char 2 1900fd4e5da5Sopenharmony_ci%short = OpTypeInt 16 0 1901fd4e5da5Sopenharmony_ci%short2 = OpTypeVector %short 2 1902fd4e5da5Sopenharmony_ci%half = OpTypeFloat 16 1903fd4e5da5Sopenharmony_ci%half2 = OpTypeVector %half 2 1904fd4e5da5Sopenharmony_ci%char_block = OpTypeStruct %char2 1905fd4e5da5Sopenharmony_ci%short_block = OpTypeStruct %short2 1906fd4e5da5Sopenharmony_ci%half_block = OpTypeStruct %half2 1907fd4e5da5Sopenharmony_ci%ptr_ssbo_char_block = OpTypePointer StorageBuffer %char_block 1908fd4e5da5Sopenharmony_ci%ptr_ssbo_char2 = OpTypePointer StorageBuffer %char2 1909fd4e5da5Sopenharmony_ci%ptr_ssbo_char = OpTypePointer StorageBuffer %char 1910fd4e5da5Sopenharmony_ci%ptr_ssbo_short_block = OpTypePointer StorageBuffer %short_block 1911fd4e5da5Sopenharmony_ci%ptr_ssbo_short2 = OpTypePointer StorageBuffer %short2 1912fd4e5da5Sopenharmony_ci%ptr_ssbo_short = OpTypePointer StorageBuffer %short 1913fd4e5da5Sopenharmony_ci%ptr_ssbo_half_block = OpTypePointer StorageBuffer %half_block 1914fd4e5da5Sopenharmony_ci%ptr_ssbo_half2 = OpTypePointer StorageBuffer %half2 1915fd4e5da5Sopenharmony_ci%ptr_ssbo_half = OpTypePointer StorageBuffer %half 1916fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 1917fd4e5da5Sopenharmony_ci%char_var = OpVariable %ptr_ssbo_char_block StorageBuffer 1918fd4e5da5Sopenharmony_ci%short_var = OpVariable %ptr_ssbo_short_block StorageBuffer 1919fd4e5da5Sopenharmony_ci%half_var = OpVariable %ptr_ssbo_half_block StorageBuffer 1920fd4e5da5Sopenharmony_ci)"; 1921fd4e5da5Sopenharmony_ci generator.after_types_ = R"( 1922fd4e5da5Sopenharmony_ci%func = OpFunction %void None %void_fn 1923fd4e5da5Sopenharmony_ci%entry = OpLabel 1924fd4e5da5Sopenharmony_ci%char2_gep = OpAccessChain %ptr_ssbo_char2 %char_var %int_0 1925fd4e5da5Sopenharmony_ci%ld_char2 = OpLoad %char2 %char2_gep 1926fd4e5da5Sopenharmony_ci%char_gep = OpAccessChain %ptr_ssbo_char %char_var %int_0 %int_0 1927fd4e5da5Sopenharmony_ci%ld_char = OpLoad %char %char_gep 1928fd4e5da5Sopenharmony_ci%short2_gep = OpAccessChain %ptr_ssbo_short2 %short_var %int_0 1929fd4e5da5Sopenharmony_ci%ld_short2 = OpLoad %short2 %short2_gep 1930fd4e5da5Sopenharmony_ci%short_gep = OpAccessChain %ptr_ssbo_short %short_var %int_0 %int_0 1931fd4e5da5Sopenharmony_ci%ld_short = OpLoad %short %short_gep 1932fd4e5da5Sopenharmony_ci%half2_gep = OpAccessChain %ptr_ssbo_half2 %half_var %int_0 1933fd4e5da5Sopenharmony_ci%ld_half2 = OpLoad %half2 %half2_gep 1934fd4e5da5Sopenharmony_ci%half_gep = OpAccessChain %ptr_ssbo_half %half_var %int_0 %int_0 1935fd4e5da5Sopenharmony_ci%ld_half = OpLoad %half %half_gep 1936fd4e5da5Sopenharmony_ci)"; 1937fd4e5da5Sopenharmony_ci generator.add_at_the_end_ = R"( 1938fd4e5da5Sopenharmony_ciOpReturn 1939fd4e5da5Sopenharmony_ciOpFunctionEnd 1940fd4e5da5Sopenharmony_ci)"; 1941fd4e5da5Sopenharmony_ci return generator; 1942fd4e5da5Sopenharmony_ci} 1943fd4e5da5Sopenharmony_ci 1944fd4e5da5Sopenharmony_ciTEST_P(ValidateSmallComposites, VectorExtractDynamic) { 1945fd4e5da5Sopenharmony_ci std::string type = GetParam(); 1946fd4e5da5Sopenharmony_ci CodeGenerator generator = GetSmallCompositesCodeGenerator(); 1947fd4e5da5Sopenharmony_ci std::string inst = 1948fd4e5da5Sopenharmony_ci "%inst = OpVectorExtractDynamic %" + type + " %ld_" + type + "2 %int_0\n"; 1949fd4e5da5Sopenharmony_ci generator.after_types_ += inst; 1950fd4e5da5Sopenharmony_ci CompileSuccessfully(generator.Build(), SPV_ENV_UNIVERSAL_1_3); 1951fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, 1952fd4e5da5Sopenharmony_ci ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); 1953fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1954fd4e5da5Sopenharmony_ci HasSubstr("Cannot extract from a vector of 8- or 16-bit types")); 1955fd4e5da5Sopenharmony_ci} 1956fd4e5da5Sopenharmony_ci 1957fd4e5da5Sopenharmony_ciTEST_P(ValidateSmallComposites, VectorInsertDynamic) { 1958fd4e5da5Sopenharmony_ci std::string type = GetParam(); 1959fd4e5da5Sopenharmony_ci CodeGenerator generator = GetSmallCompositesCodeGenerator(); 1960fd4e5da5Sopenharmony_ci std::string inst = "%inst = OpVectorInsertDynamic %" + type + "2 %ld_" + 1961fd4e5da5Sopenharmony_ci type + "2 %ld_" + type + " %int_0\n"; 1962fd4e5da5Sopenharmony_ci generator.after_types_ += inst; 1963fd4e5da5Sopenharmony_ci CompileSuccessfully(generator.Build(), SPV_ENV_UNIVERSAL_1_3); 1964fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, 1965fd4e5da5Sopenharmony_ci ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); 1966fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1967fd4e5da5Sopenharmony_ci HasSubstr("Cannot insert into a vector of 8- or 16-bit types")); 1968fd4e5da5Sopenharmony_ci} 1969fd4e5da5Sopenharmony_ci 1970fd4e5da5Sopenharmony_ciTEST_P(ValidateSmallComposites, VectorShuffle) { 1971fd4e5da5Sopenharmony_ci std::string type = GetParam(); 1972fd4e5da5Sopenharmony_ci CodeGenerator generator = GetSmallCompositesCodeGenerator(); 1973fd4e5da5Sopenharmony_ci std::string inst = "%inst = OpVectorShuffle %" + type + "2 %ld_" + type + 1974fd4e5da5Sopenharmony_ci "2 %ld_" + type + "2 0 0\n"; 1975fd4e5da5Sopenharmony_ci generator.after_types_ += inst; 1976fd4e5da5Sopenharmony_ci CompileSuccessfully(generator.Build(), SPV_ENV_UNIVERSAL_1_3); 1977fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, 1978fd4e5da5Sopenharmony_ci ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); 1979fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1980fd4e5da5Sopenharmony_ci HasSubstr("Cannot shuffle a vector of 8- or 16-bit types")); 1981fd4e5da5Sopenharmony_ci} 1982fd4e5da5Sopenharmony_ci 1983fd4e5da5Sopenharmony_ciTEST_P(ValidateSmallComposites, CompositeConstruct) { 1984fd4e5da5Sopenharmony_ci std::string type = GetParam(); 1985fd4e5da5Sopenharmony_ci CodeGenerator generator = GetSmallCompositesCodeGenerator(); 1986fd4e5da5Sopenharmony_ci std::string inst = "%inst = OpCompositeConstruct %" + type + "2 %ld_" + type + 1987fd4e5da5Sopenharmony_ci " %ld_" + type + "\n"; 1988fd4e5da5Sopenharmony_ci generator.after_types_ += inst; 1989fd4e5da5Sopenharmony_ci CompileSuccessfully(generator.Build(), SPV_ENV_UNIVERSAL_1_3); 1990fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, 1991fd4e5da5Sopenharmony_ci ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); 1992fd4e5da5Sopenharmony_ci EXPECT_THAT( 1993fd4e5da5Sopenharmony_ci getDiagnosticString(), 1994fd4e5da5Sopenharmony_ci HasSubstr("Cannot create a composite containing 8- or 16-bit types")); 1995fd4e5da5Sopenharmony_ci} 1996fd4e5da5Sopenharmony_ci 1997fd4e5da5Sopenharmony_ciTEST_P(ValidateSmallComposites, CompositeExtract) { 1998fd4e5da5Sopenharmony_ci std::string type = GetParam(); 1999fd4e5da5Sopenharmony_ci CodeGenerator generator = GetSmallCompositesCodeGenerator(); 2000fd4e5da5Sopenharmony_ci std::string inst = 2001fd4e5da5Sopenharmony_ci "%inst = OpCompositeExtract %" + type + " %ld_" + type + "2 0\n"; 2002fd4e5da5Sopenharmony_ci generator.after_types_ += inst; 2003fd4e5da5Sopenharmony_ci CompileSuccessfully(generator.Build(), SPV_ENV_UNIVERSAL_1_3); 2004fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, 2005fd4e5da5Sopenharmony_ci ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); 2006fd4e5da5Sopenharmony_ci EXPECT_THAT( 2007fd4e5da5Sopenharmony_ci getDiagnosticString(), 2008fd4e5da5Sopenharmony_ci HasSubstr("Cannot extract from a composite of 8- or 16-bit types")); 2009fd4e5da5Sopenharmony_ci} 2010fd4e5da5Sopenharmony_ci 2011fd4e5da5Sopenharmony_ciTEST_P(ValidateSmallComposites, CompositeInsert) { 2012fd4e5da5Sopenharmony_ci std::string type = GetParam(); 2013fd4e5da5Sopenharmony_ci CodeGenerator generator = GetSmallCompositesCodeGenerator(); 2014fd4e5da5Sopenharmony_ci std::string inst = "%inst = OpCompositeInsert %" + type + "2 %ld_" + type + 2015fd4e5da5Sopenharmony_ci " %ld_" + type + "2 0\n"; 2016fd4e5da5Sopenharmony_ci generator.after_types_ += inst; 2017fd4e5da5Sopenharmony_ci CompileSuccessfully(generator.Build(), SPV_ENV_UNIVERSAL_1_3); 2018fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, 2019fd4e5da5Sopenharmony_ci ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); 2020fd4e5da5Sopenharmony_ci EXPECT_THAT( 2021fd4e5da5Sopenharmony_ci getDiagnosticString(), 2022fd4e5da5Sopenharmony_ci HasSubstr("Cannot insert into a composite of 8- or 16-bit types")); 2023fd4e5da5Sopenharmony_ci} 2024fd4e5da5Sopenharmony_ci 2025fd4e5da5Sopenharmony_ciTEST_P(ValidateSmallComposites, CopyObject) { 2026fd4e5da5Sopenharmony_ci std::string type = GetParam(); 2027fd4e5da5Sopenharmony_ci CodeGenerator generator = GetSmallCompositesCodeGenerator(); 2028fd4e5da5Sopenharmony_ci std::string inst = "%inst = OpCopyObject %" + type + "2 %ld_" + type + "2\n"; 2029fd4e5da5Sopenharmony_ci generator.after_types_ += inst; 2030fd4e5da5Sopenharmony_ci CompileSuccessfully(generator.Build(), SPV_ENV_UNIVERSAL_1_3); 2031fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); 2032fd4e5da5Sopenharmony_ci} 2033fd4e5da5Sopenharmony_ci 2034fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P(SmallCompositeInstructions, ValidateSmallComposites, 2035fd4e5da5Sopenharmony_ci Values("char", "short", "half")); 2036fd4e5da5Sopenharmony_ci 2037fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, HalfMatrixCannotTranspose) { 2038fd4e5da5Sopenharmony_ci const std::string spirv = R"( 2039fd4e5da5Sopenharmony_ciOpCapability Shader 2040fd4e5da5Sopenharmony_ciOpCapability Linkage 2041fd4e5da5Sopenharmony_ciOpCapability UniformAndStorageBuffer16BitAccess 2042fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_16bit_storage" 2043fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 2044fd4e5da5Sopenharmony_ciOpDecorate %block Block 2045fd4e5da5Sopenharmony_ciOpMemberDecorate %block 0 Offset 0 2046fd4e5da5Sopenharmony_ciOpMemberDecorate %block 0 RowMajor 2047fd4e5da5Sopenharmony_ciOpMemberDecorate %block 0 MatrixStride 8 2048fd4e5da5Sopenharmony_ci%void = OpTypeVoid 2049fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 2050fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0 2051fd4e5da5Sopenharmony_ci%float = OpTypeFloat 16 2052fd4e5da5Sopenharmony_ci%float2 = OpTypeVector %float 2 2053fd4e5da5Sopenharmony_ci%mat2x2 = OpTypeMatrix %float2 2 2054fd4e5da5Sopenharmony_ci%block = OpTypeStruct %mat2x2 2055fd4e5da5Sopenharmony_ci%ptr_ssbo_block = OpTypePointer StorageBuffer %block 2056fd4e5da5Sopenharmony_ci%ptr_ssbo_mat2x2 = OpTypePointer StorageBuffer %mat2x2 2057fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_ssbo_block StorageBuffer 2058fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 2059fd4e5da5Sopenharmony_ci%func = OpFunction %void None %void_fn 2060fd4e5da5Sopenharmony_ci%entry = OpLabel 2061fd4e5da5Sopenharmony_ci%gep = OpAccessChain %ptr_ssbo_mat2x2 %var %int_0 2062fd4e5da5Sopenharmony_ci%ld = OpLoad %mat2x2 %gep 2063fd4e5da5Sopenharmony_ci%inst = OpTranspose %mat2x2 %ld 2064fd4e5da5Sopenharmony_ciOpReturn 2065fd4e5da5Sopenharmony_ciOpFunctionEnd 2066fd4e5da5Sopenharmony_ci)"; 2067fd4e5da5Sopenharmony_ci 2068fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3); 2069fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, 2070fd4e5da5Sopenharmony_ci ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); 2071fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 2072fd4e5da5Sopenharmony_ci HasSubstr("Cannot transpose matrices of 16-bit floats")); 2073fd4e5da5Sopenharmony_ci} 2074fd4e5da5Sopenharmony_ci 2075fd4e5da5Sopenharmony_ciTEST_F(ValidateComposites, CopyObjectVoid) { 2076fd4e5da5Sopenharmony_ci const std::string spirv = R"( 2077fd4e5da5Sopenharmony_ci OpCapability Shader 2078fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 2079fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 2080fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 2081fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 2082fd4e5da5Sopenharmony_ci OpSource ESSL 320 2083fd4e5da5Sopenharmony_ci OpName %4 "main" 2084fd4e5da5Sopenharmony_ci OpName %6 "foo(" 2085fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 2086fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 2087fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 2088fd4e5da5Sopenharmony_ci %5 = OpLabel 2089fd4e5da5Sopenharmony_ci %8 = OpFunctionCall %2 %6 2090fd4e5da5Sopenharmony_ci %20 = OpCopyObject %2 %8 2091fd4e5da5Sopenharmony_ci OpReturn 2092fd4e5da5Sopenharmony_ci OpFunctionEnd 2093fd4e5da5Sopenharmony_ci %6 = OpFunction %2 None %3 2094fd4e5da5Sopenharmony_ci %7 = OpLabel 2095fd4e5da5Sopenharmony_ci OpReturn 2096fd4e5da5Sopenharmony_ci OpFunctionEnd 2097fd4e5da5Sopenharmony_ci)"; 2098fd4e5da5Sopenharmony_ci 2099fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 2100fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 2101fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 2102fd4e5da5Sopenharmony_ci HasSubstr("OpCopyObject cannot have void result type")); 2103fd4e5da5Sopenharmony_ci} 2104fd4e5da5Sopenharmony_ci 2105fd4e5da5Sopenharmony_ci} // namespace 2106fd4e5da5Sopenharmony_ci} // namespace val 2107fd4e5da5Sopenharmony_ci} // namespace spvtools 2108