1fd4e5da5Sopenharmony_ci// Copyright (c) 2019 Google LLC. 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// Validation tests for misc instructions 16fd4e5da5Sopenharmony_ci 17fd4e5da5Sopenharmony_ci#include <string> 18fd4e5da5Sopenharmony_ci#include <vector> 19fd4e5da5Sopenharmony_ci 20fd4e5da5Sopenharmony_ci#include "gmock/gmock.h" 21fd4e5da5Sopenharmony_ci#include "test/unit_spirv.h" 22fd4e5da5Sopenharmony_ci#include "test/val/val_fixtures.h" 23fd4e5da5Sopenharmony_ci 24fd4e5da5Sopenharmony_cinamespace spvtools { 25fd4e5da5Sopenharmony_cinamespace val { 26fd4e5da5Sopenharmony_cinamespace { 27fd4e5da5Sopenharmony_ci 28fd4e5da5Sopenharmony_ciusing ::testing::Eq; 29fd4e5da5Sopenharmony_ciusing ::testing::HasSubstr; 30fd4e5da5Sopenharmony_ci 31fd4e5da5Sopenharmony_ciusing ValidateMisc = spvtest::ValidateBase<bool>; 32fd4e5da5Sopenharmony_ci 33fd4e5da5Sopenharmony_ciTEST_F(ValidateMisc, UndefRestrictedShort) { 34fd4e5da5Sopenharmony_ci const std::string spirv = R"( 35fd4e5da5Sopenharmony_ciOpCapability Shader 36fd4e5da5Sopenharmony_ciOpCapability Linkage 37fd4e5da5Sopenharmony_ciOpCapability StorageBuffer16BitAccess 38fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_16bit_storage" 39fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 40fd4e5da5Sopenharmony_ci%short = OpTypeInt 16 0 41fd4e5da5Sopenharmony_ci%undef = OpUndef %short 42fd4e5da5Sopenharmony_ci)"; 43fd4e5da5Sopenharmony_ci 44fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 45fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); 46fd4e5da5Sopenharmony_ci EXPECT_THAT( 47fd4e5da5Sopenharmony_ci getDiagnosticString(), 48fd4e5da5Sopenharmony_ci HasSubstr("Cannot create undefined values with 8- or 16-bit types")); 49fd4e5da5Sopenharmony_ci} 50fd4e5da5Sopenharmony_ci 51fd4e5da5Sopenharmony_ciTEST_F(ValidateMisc, UndefRestrictedChar) { 52fd4e5da5Sopenharmony_ci const std::string spirv = R"( 53fd4e5da5Sopenharmony_ciOpCapability Shader 54fd4e5da5Sopenharmony_ciOpCapability Linkage 55fd4e5da5Sopenharmony_ciOpCapability StorageBuffer8BitAccess 56fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_8bit_storage" 57fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 58fd4e5da5Sopenharmony_ci%char = OpTypeInt 8 0 59fd4e5da5Sopenharmony_ci%undef = OpUndef %char 60fd4e5da5Sopenharmony_ci)"; 61fd4e5da5Sopenharmony_ci 62fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 63fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); 64fd4e5da5Sopenharmony_ci EXPECT_THAT( 65fd4e5da5Sopenharmony_ci getDiagnosticString(), 66fd4e5da5Sopenharmony_ci HasSubstr("Cannot create undefined values with 8- or 16-bit types")); 67fd4e5da5Sopenharmony_ci} 68fd4e5da5Sopenharmony_ci 69fd4e5da5Sopenharmony_ciTEST_F(ValidateMisc, UndefRestrictedHalf) { 70fd4e5da5Sopenharmony_ci const std::string spirv = R"( 71fd4e5da5Sopenharmony_ciOpCapability Shader 72fd4e5da5Sopenharmony_ciOpCapability Linkage 73fd4e5da5Sopenharmony_ciOpCapability StorageBuffer16BitAccess 74fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_16bit_storage" 75fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 76fd4e5da5Sopenharmony_ci%half = OpTypeFloat 16 77fd4e5da5Sopenharmony_ci%undef = OpUndef %half 78fd4e5da5Sopenharmony_ci)"; 79fd4e5da5Sopenharmony_ci 80fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 81fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); 82fd4e5da5Sopenharmony_ci EXPECT_THAT( 83fd4e5da5Sopenharmony_ci getDiagnosticString(), 84fd4e5da5Sopenharmony_ci HasSubstr("Cannot create undefined values with 8- or 16-bit types")); 85fd4e5da5Sopenharmony_ci} 86fd4e5da5Sopenharmony_ci 87fd4e5da5Sopenharmony_ciconst std::string ShaderClockSpriv = R"( 88fd4e5da5Sopenharmony_ciOpCapability Shader 89fd4e5da5Sopenharmony_ciOpCapability Int64 90fd4e5da5Sopenharmony_ciOpCapability ShaderClockKHR 91fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_shader_clock" 92fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 93fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 94fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" 95fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 96fd4e5da5Sopenharmony_ciOpSource GLSL 450 97fd4e5da5Sopenharmony_ciOpSourceExtension "GL_ARB_gpu_shader_int64" 98fd4e5da5Sopenharmony_ciOpSourceExtension "GL_ARB_shader_clock" 99fd4e5da5Sopenharmony_ciOpSourceExtension "GL_EXT_shader_realtime_clock" 100fd4e5da5Sopenharmony_ciOpName %main "main" 101fd4e5da5Sopenharmony_ciOpName %time1 "time1" 102fd4e5da5Sopenharmony_ci%void = OpTypeVoid 103fd4e5da5Sopenharmony_ci)"; 104fd4e5da5Sopenharmony_ci 105fd4e5da5Sopenharmony_ciTEST_F(ValidateMisc, ShaderClockInt64) { 106fd4e5da5Sopenharmony_ci const std::string spirv = ShaderClockSpriv + R"( 107fd4e5da5Sopenharmony_ci%3 = OpTypeFunction %void 108fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 109fd4e5da5Sopenharmony_ci%_ptr_Function_uint = OpTypePointer Function %uint 110fd4e5da5Sopenharmony_ci%uint_3 = OpConstant %uint 3 111fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1 112fd4e5da5Sopenharmony_ci%main = OpFunction %void None %3 113fd4e5da5Sopenharmony_ci%5 = OpLabel 114fd4e5da5Sopenharmony_ci%time1 = OpVariable %_ptr_Function_uint Function 115fd4e5da5Sopenharmony_ci%11 = OpReadClockKHR %uint %uint_3 116fd4e5da5Sopenharmony_ciOpStore %time1 %11 117fd4e5da5Sopenharmony_ciOpReturn 118fd4e5da5Sopenharmony_ciOpFunctionEnd)"; 119fd4e5da5Sopenharmony_ci 120fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 121fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 122fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), HasSubstr("or 64bit unsigned integer")); 123fd4e5da5Sopenharmony_ci} 124fd4e5da5Sopenharmony_ci 125fd4e5da5Sopenharmony_ciTEST_F(ValidateMisc, ShaderClockVec2) { 126fd4e5da5Sopenharmony_ci const std::string spirv = ShaderClockSpriv + R"( 127fd4e5da5Sopenharmony_ci%3 = OpTypeFunction %void 128fd4e5da5Sopenharmony_ci%ulong = OpTypeInt 64 0 129fd4e5da5Sopenharmony_ci%_ptr_Function_ulong = OpTypePointer Function %ulong 130fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 131fd4e5da5Sopenharmony_ci%uint_3 = OpConstant %uint 3 132fd4e5da5Sopenharmony_ci%v2uint = OpTypeVector %ulong 2 133fd4e5da5Sopenharmony_ci%_ptr_Function_v2uint = OpTypePointer Function %v2uint 134fd4e5da5Sopenharmony_ci%main = OpFunction %void None %3 135fd4e5da5Sopenharmony_ci%5 = OpLabel 136fd4e5da5Sopenharmony_ci%time1 = OpVariable %_ptr_Function_v2uint Function 137fd4e5da5Sopenharmony_ci%15 = OpReadClockKHR %v2uint %uint_3 138fd4e5da5Sopenharmony_ciOpStore %time1 %15 139fd4e5da5Sopenharmony_ciOpReturn 140fd4e5da5Sopenharmony_ciOpFunctionEnd)"; 141fd4e5da5Sopenharmony_ci 142fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 143fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 144fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), HasSubstr("vector of two components")); 145fd4e5da5Sopenharmony_ci} 146fd4e5da5Sopenharmony_ci 147fd4e5da5Sopenharmony_ciTEST_F(ValidateMisc, ShaderClockInvalidScopeValue) { 148fd4e5da5Sopenharmony_ci const std::string spirv = ShaderClockSpriv + R"( 149fd4e5da5Sopenharmony_ci%3 = OpTypeFunction %void 150fd4e5da5Sopenharmony_ci%ulong = OpTypeInt 64 0 151fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 152fd4e5da5Sopenharmony_ci%_ptr_Function_ulong = OpTypePointer Function %ulong 153fd4e5da5Sopenharmony_ci%uint_10 = OpConstant %uint 10 154fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1 155fd4e5da5Sopenharmony_ci%main = OpFunction %void None %3 156fd4e5da5Sopenharmony_ci%5 = OpLabel 157fd4e5da5Sopenharmony_ci%time1 = OpVariable %_ptr_Function_ulong Function 158fd4e5da5Sopenharmony_ci%11 = OpReadClockKHR %ulong %uint_10 159fd4e5da5Sopenharmony_ciOpStore %time1 %11 160fd4e5da5Sopenharmony_ciOpReturn 161fd4e5da5Sopenharmony_ciOpFunctionEnd)"; 162fd4e5da5Sopenharmony_ci 163fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 164fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 165fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), HasSubstr("Invalid scope value")); 166fd4e5da5Sopenharmony_ci} 167fd4e5da5Sopenharmony_ci 168fd4e5da5Sopenharmony_ciTEST_F(ValidateMisc, ShaderClockSubgroupScope) { 169fd4e5da5Sopenharmony_ci const std::string spirv = ShaderClockSpriv + R"( 170fd4e5da5Sopenharmony_ci%3 = OpTypeFunction %void 171fd4e5da5Sopenharmony_ci%ulong = OpTypeInt 64 0 172fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 173fd4e5da5Sopenharmony_ci%_ptr_Function_ulong = OpTypePointer Function %ulong 174fd4e5da5Sopenharmony_ci%subgroup = OpConstant %uint 3 175fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1 176fd4e5da5Sopenharmony_ci%main = OpFunction %void None %3 177fd4e5da5Sopenharmony_ci%5 = OpLabel 178fd4e5da5Sopenharmony_ci%time1 = OpVariable %_ptr_Function_ulong Function 179fd4e5da5Sopenharmony_ci%11 = OpReadClockKHR %ulong %subgroup 180fd4e5da5Sopenharmony_ciOpStore %time1 %11 181fd4e5da5Sopenharmony_ciOpReturn 182fd4e5da5Sopenharmony_ciOpFunctionEnd)"; 183fd4e5da5Sopenharmony_ci 184fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 185fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_SUCCESS, ValidateInstructions()); 186fd4e5da5Sopenharmony_ci} 187fd4e5da5Sopenharmony_ci 188fd4e5da5Sopenharmony_ciTEST_F(ValidateMisc, ShaderClockDeviceScope) { 189fd4e5da5Sopenharmony_ci const std::string spirv = ShaderClockSpriv + R"( 190fd4e5da5Sopenharmony_ci%3 = OpTypeFunction %void 191fd4e5da5Sopenharmony_ci%ulong = OpTypeInt 64 0 192fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 193fd4e5da5Sopenharmony_ci%_ptr_Function_ulong = OpTypePointer Function %ulong 194fd4e5da5Sopenharmony_ci%device = OpConstant %uint 1 195fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1 196fd4e5da5Sopenharmony_ci%main = OpFunction %void None %3 197fd4e5da5Sopenharmony_ci%5 = OpLabel 198fd4e5da5Sopenharmony_ci%time1 = OpVariable %_ptr_Function_ulong Function 199fd4e5da5Sopenharmony_ci%11 = OpReadClockKHR %ulong %device 200fd4e5da5Sopenharmony_ciOpStore %time1 %11 201fd4e5da5Sopenharmony_ciOpReturn 202fd4e5da5Sopenharmony_ciOpFunctionEnd)"; 203fd4e5da5Sopenharmony_ci 204fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 205fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_SUCCESS, ValidateInstructions()); 206fd4e5da5Sopenharmony_ci} 207fd4e5da5Sopenharmony_ci 208fd4e5da5Sopenharmony_ciTEST_F(ValidateMisc, ShaderClockWorkgroupScope) { 209fd4e5da5Sopenharmony_ci const std::string spirv = ShaderClockSpriv + R"( 210fd4e5da5Sopenharmony_ci%3 = OpTypeFunction %void 211fd4e5da5Sopenharmony_ci%ulong = OpTypeInt 64 0 212fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 213fd4e5da5Sopenharmony_ci%_ptr_Function_ulong = OpTypePointer Function %ulong 214fd4e5da5Sopenharmony_ci%workgroup = OpConstant %uint 2 215fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1 216fd4e5da5Sopenharmony_ci%main = OpFunction %void None %3 217fd4e5da5Sopenharmony_ci%5 = OpLabel 218fd4e5da5Sopenharmony_ci%time1 = OpVariable %_ptr_Function_ulong Function 219fd4e5da5Sopenharmony_ci%11 = OpReadClockKHR %ulong %workgroup 220fd4e5da5Sopenharmony_ciOpStore %time1 %11 221fd4e5da5Sopenharmony_ciOpReturn 222fd4e5da5Sopenharmony_ciOpFunctionEnd)"; 223fd4e5da5Sopenharmony_ci 224fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 225fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 226fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 227fd4e5da5Sopenharmony_ci HasSubstr("Scope must be Subgroup or Device")); 228fd4e5da5Sopenharmony_ci} 229fd4e5da5Sopenharmony_ci 230fd4e5da5Sopenharmony_ciTEST_F(ValidateMisc, VulkanShaderClockWorkgroupScope) { 231fd4e5da5Sopenharmony_ci const std::string spirv = ShaderClockSpriv + R"( 232fd4e5da5Sopenharmony_ci%3 = OpTypeFunction %void 233fd4e5da5Sopenharmony_ci%ulong = OpTypeInt 64 0 234fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 235fd4e5da5Sopenharmony_ci%_ptr_Function_ulong = OpTypePointer Function %ulong 236fd4e5da5Sopenharmony_ci%workgroup = OpConstant %uint 2 237fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1 238fd4e5da5Sopenharmony_ci%main = OpFunction %void None %3 239fd4e5da5Sopenharmony_ci%5 = OpLabel 240fd4e5da5Sopenharmony_ci%time1 = OpVariable %_ptr_Function_ulong Function 241fd4e5da5Sopenharmony_ci%11 = OpReadClockKHR %ulong %workgroup 242fd4e5da5Sopenharmony_ciOpStore %time1 %11 243fd4e5da5Sopenharmony_ciOpReturn 244fd4e5da5Sopenharmony_ciOpFunctionEnd)"; 245fd4e5da5Sopenharmony_ci 246fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0); 247fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 248fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 249fd4e5da5Sopenharmony_ci AnyVUID("VUID-StandaloneSpirv-OpReadClockKHR-04652")); 250fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 251fd4e5da5Sopenharmony_ci HasSubstr("Scope must be Subgroup or Device")); 252fd4e5da5Sopenharmony_ci} 253fd4e5da5Sopenharmony_ci 254fd4e5da5Sopenharmony_ciTEST_F(ValidateMisc, UndefVoid) { 255fd4e5da5Sopenharmony_ci const std::string spirv = R"( 256fd4e5da5Sopenharmony_ci OpCapability Shader 257fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 258fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 259fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 260fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 261fd4e5da5Sopenharmony_ci OpSource ESSL 320 262fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 263fd4e5da5Sopenharmony_ci %10 = OpUndef %2 264fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 265fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 266fd4e5da5Sopenharmony_ci %5 = OpLabel 267fd4e5da5Sopenharmony_ci OpReturn 268fd4e5da5Sopenharmony_ci OpFunctionEnd 269fd4e5da5Sopenharmony_ci)"; 270fd4e5da5Sopenharmony_ci 271fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 272fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); 273fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 274fd4e5da5Sopenharmony_ci HasSubstr("Cannot create undefined values with void type")); 275fd4e5da5Sopenharmony_ci} 276fd4e5da5Sopenharmony_ci 277fd4e5da5Sopenharmony_ciTEST_F(ValidateMisc, VulkanInvalidStorageClass) { 278fd4e5da5Sopenharmony_ci const std::string spirv = R"( 279fd4e5da5Sopenharmony_ciOpCapability Shader 280fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 281fd4e5da5Sopenharmony_ciOpEntryPoint Vertex %func "shader" 282fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 283fd4e5da5Sopenharmony_ci%ptr = OpTypePointer CrossWorkgroup %int 284fd4e5da5Sopenharmony_ci%var = OpVariable %ptr CrossWorkgroup 285fd4e5da5Sopenharmony_ci%void = OpTypeVoid 286fd4e5da5Sopenharmony_ci%void_f = OpTypeFunction %void 287fd4e5da5Sopenharmony_ci%func = OpFunction %void None %void_f 288fd4e5da5Sopenharmony_ci%label = OpLabel 289fd4e5da5Sopenharmony_ci OpReturn 290fd4e5da5Sopenharmony_ci OpFunctionEnd 291fd4e5da5Sopenharmony_ci)"; 292fd4e5da5Sopenharmony_ci 293fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0); 294fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_BINARY, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 295fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 296fd4e5da5Sopenharmony_ci AnyVUID("VUID-StandaloneSpirv-None-04643")); 297fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 298fd4e5da5Sopenharmony_ci HasSubstr("Invalid storage class for target environment")); 299fd4e5da5Sopenharmony_ci} 300fd4e5da5Sopenharmony_ci} // namespace 301fd4e5da5Sopenharmony_ci} // namespace val 302fd4e5da5Sopenharmony_ci} // namespace spvtools 303