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_fixtures.h" 21fd4e5da5Sopenharmony_ci 22fd4e5da5Sopenharmony_cinamespace spvtools { 23fd4e5da5Sopenharmony_cinamespace val { 24fd4e5da5Sopenharmony_cinamespace { 25fd4e5da5Sopenharmony_ci 26fd4e5da5Sopenharmony_ciusing ::testing::HasSubstr; 27fd4e5da5Sopenharmony_ciusing ::testing::Not; 28fd4e5da5Sopenharmony_ci 29fd4e5da5Sopenharmony_ciusing ValidateAtomics = spvtest::ValidateBase<bool>; 30fd4e5da5Sopenharmony_ci 31fd4e5da5Sopenharmony_cistd::string GenerateShaderCodeImpl( 32fd4e5da5Sopenharmony_ci const std::string& body, const std::string& capabilities_and_extensions, 33fd4e5da5Sopenharmony_ci const std::string& definitions, const std::string& memory_model, 34fd4e5da5Sopenharmony_ci const std::string& execution) { 35fd4e5da5Sopenharmony_ci std::ostringstream ss; 36fd4e5da5Sopenharmony_ci ss << R"( 37fd4e5da5Sopenharmony_ciOpCapability Shader 38fd4e5da5Sopenharmony_ci)"; 39fd4e5da5Sopenharmony_ci ss << capabilities_and_extensions; 40fd4e5da5Sopenharmony_ci ss << "OpMemoryModel Logical " << memory_model << "\n"; 41fd4e5da5Sopenharmony_ci ss << execution; 42fd4e5da5Sopenharmony_ci ss << R"( 43fd4e5da5Sopenharmony_ci%void = OpTypeVoid 44fd4e5da5Sopenharmony_ci%func = OpTypeFunction %void 45fd4e5da5Sopenharmony_ci%bool = OpTypeBool 46fd4e5da5Sopenharmony_ci%f32 = OpTypeFloat 32 47fd4e5da5Sopenharmony_ci%u32 = OpTypeInt 32 0 48fd4e5da5Sopenharmony_ci%f32vec4 = OpTypeVector %f32 4 49fd4e5da5Sopenharmony_ci 50fd4e5da5Sopenharmony_ci%f32_0 = OpConstant %f32 0 51fd4e5da5Sopenharmony_ci%f32_1 = OpConstant %f32 1 52fd4e5da5Sopenharmony_ci%u32_0 = OpConstant %u32 0 53fd4e5da5Sopenharmony_ci%u32_1 = OpConstant %u32 1 54fd4e5da5Sopenharmony_ci%f32vec4_0000 = OpConstantComposite %f32vec4 %f32_0 %f32_0 %f32_0 %f32_0 55fd4e5da5Sopenharmony_ci 56fd4e5da5Sopenharmony_ci%cross_device = OpConstant %u32 0 57fd4e5da5Sopenharmony_ci%device = OpConstant %u32 1 58fd4e5da5Sopenharmony_ci%workgroup = OpConstant %u32 2 59fd4e5da5Sopenharmony_ci%subgroup = OpConstant %u32 3 60fd4e5da5Sopenharmony_ci%invocation = OpConstant %u32 4 61fd4e5da5Sopenharmony_ci%queuefamily = OpConstant %u32 5 62fd4e5da5Sopenharmony_ci 63fd4e5da5Sopenharmony_ci%relaxed = OpConstant %u32 0 64fd4e5da5Sopenharmony_ci%acquire = OpConstant %u32 2 65fd4e5da5Sopenharmony_ci%release = OpConstant %u32 4 66fd4e5da5Sopenharmony_ci%acquire_release = OpConstant %u32 8 67fd4e5da5Sopenharmony_ci%acquire_and_release = OpConstant %u32 6 68fd4e5da5Sopenharmony_ci%sequentially_consistent = OpConstant %u32 16 69fd4e5da5Sopenharmony_ci%acquire_release_uniform_workgroup = OpConstant %u32 328 70fd4e5da5Sopenharmony_ci 71fd4e5da5Sopenharmony_ci%f32_ptr = OpTypePointer Workgroup %f32 72fd4e5da5Sopenharmony_ci%f32_var = OpVariable %f32_ptr Workgroup 73fd4e5da5Sopenharmony_ci 74fd4e5da5Sopenharmony_ci%u32_ptr = OpTypePointer Workgroup %u32 75fd4e5da5Sopenharmony_ci%u32_var = OpVariable %u32_ptr Workgroup 76fd4e5da5Sopenharmony_ci 77fd4e5da5Sopenharmony_ci%f32vec4_ptr = OpTypePointer Workgroup %f32vec4 78fd4e5da5Sopenharmony_ci%f32vec4_var = OpVariable %f32vec4_ptr Workgroup 79fd4e5da5Sopenharmony_ci 80fd4e5da5Sopenharmony_ci%f32_ptr_function = OpTypePointer Function %f32 81fd4e5da5Sopenharmony_ci)"; 82fd4e5da5Sopenharmony_ci ss << definitions; 83fd4e5da5Sopenharmony_ci ss << R"( 84fd4e5da5Sopenharmony_ci%main = OpFunction %void None %func 85fd4e5da5Sopenharmony_ci%main_entry = OpLabel 86fd4e5da5Sopenharmony_ci)"; 87fd4e5da5Sopenharmony_ci ss << body; 88fd4e5da5Sopenharmony_ci ss << R"( 89fd4e5da5Sopenharmony_ciOpReturn 90fd4e5da5Sopenharmony_ciOpFunctionEnd)"; 91fd4e5da5Sopenharmony_ci 92fd4e5da5Sopenharmony_ci return ss.str(); 93fd4e5da5Sopenharmony_ci} 94fd4e5da5Sopenharmony_ci 95fd4e5da5Sopenharmony_cistd::string GenerateShaderCode( 96fd4e5da5Sopenharmony_ci const std::string& body, 97fd4e5da5Sopenharmony_ci const std::string& capabilities_and_extensions = "", 98fd4e5da5Sopenharmony_ci const std::string& extra_defs = "", 99fd4e5da5Sopenharmony_ci const std::string& memory_model = "GLSL450") { 100fd4e5da5Sopenharmony_ci const std::string execution = R"( 101fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" 102fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 103fd4e5da5Sopenharmony_ci)"; 104fd4e5da5Sopenharmony_ci const std::string definitions = R"( 105fd4e5da5Sopenharmony_ci%u64 = OpTypeInt 64 0 106fd4e5da5Sopenharmony_ci%s64 = OpTypeInt 64 1 107fd4e5da5Sopenharmony_ci 108fd4e5da5Sopenharmony_ci%u64_1 = OpConstant %u64 1 109fd4e5da5Sopenharmony_ci%s64_1 = OpConstant %s64 1 110fd4e5da5Sopenharmony_ci 111fd4e5da5Sopenharmony_ci%u64_ptr = OpTypePointer Workgroup %u64 112fd4e5da5Sopenharmony_ci%s64_ptr = OpTypePointer Workgroup %s64 113fd4e5da5Sopenharmony_ci%u64_var = OpVariable %u64_ptr Workgroup 114fd4e5da5Sopenharmony_ci%s64_var = OpVariable %s64_ptr Workgroup 115fd4e5da5Sopenharmony_ci)"; 116fd4e5da5Sopenharmony_ci return GenerateShaderCodeImpl( 117fd4e5da5Sopenharmony_ci body, "OpCapability Int64\n" + capabilities_and_extensions, 118fd4e5da5Sopenharmony_ci definitions + extra_defs, memory_model, execution); 119fd4e5da5Sopenharmony_ci} 120fd4e5da5Sopenharmony_ci 121fd4e5da5Sopenharmony_cistd::string GenerateShaderComputeCode( 122fd4e5da5Sopenharmony_ci const std::string& body, 123fd4e5da5Sopenharmony_ci const std::string& capabilities_and_extensions = "", 124fd4e5da5Sopenharmony_ci const std::string& extra_defs = "", 125fd4e5da5Sopenharmony_ci const std::string& memory_model = "GLSL450") { 126fd4e5da5Sopenharmony_ci const std::string execution = R"( 127fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main" 128fd4e5da5Sopenharmony_ciOpExecutionMode %main LocalSize 32 1 1 129fd4e5da5Sopenharmony_ci)"; 130fd4e5da5Sopenharmony_ci const std::string definitions = R"( 131fd4e5da5Sopenharmony_ci%u64 = OpTypeInt 64 0 132fd4e5da5Sopenharmony_ci%s64 = OpTypeInt 64 1 133fd4e5da5Sopenharmony_ci 134fd4e5da5Sopenharmony_ci%u64_1 = OpConstant %u64 1 135fd4e5da5Sopenharmony_ci%s64_1 = OpConstant %s64 1 136fd4e5da5Sopenharmony_ci 137fd4e5da5Sopenharmony_ci%u64_ptr = OpTypePointer Workgroup %u64 138fd4e5da5Sopenharmony_ci%s64_ptr = OpTypePointer Workgroup %s64 139fd4e5da5Sopenharmony_ci%u64_var = OpVariable %u64_ptr Workgroup 140fd4e5da5Sopenharmony_ci%s64_var = OpVariable %s64_ptr Workgroup 141fd4e5da5Sopenharmony_ci)"; 142fd4e5da5Sopenharmony_ci return GenerateShaderCodeImpl( 143fd4e5da5Sopenharmony_ci body, "OpCapability Int64\n" + capabilities_and_extensions, 144fd4e5da5Sopenharmony_ci definitions + extra_defs, memory_model, execution); 145fd4e5da5Sopenharmony_ci} 146fd4e5da5Sopenharmony_ci 147fd4e5da5Sopenharmony_cistd::string GenerateKernelCode( 148fd4e5da5Sopenharmony_ci const std::string& body, 149fd4e5da5Sopenharmony_ci const std::string& capabilities_and_extensions = "") { 150fd4e5da5Sopenharmony_ci std::ostringstream ss; 151fd4e5da5Sopenharmony_ci ss << R"( 152fd4e5da5Sopenharmony_ciOpCapability Addresses 153fd4e5da5Sopenharmony_ciOpCapability Kernel 154fd4e5da5Sopenharmony_ciOpCapability Linkage 155fd4e5da5Sopenharmony_ciOpCapability Int64 156fd4e5da5Sopenharmony_ci)"; 157fd4e5da5Sopenharmony_ci 158fd4e5da5Sopenharmony_ci ss << capabilities_and_extensions; 159fd4e5da5Sopenharmony_ci ss << R"( 160fd4e5da5Sopenharmony_ciOpMemoryModel Physical32 OpenCL 161fd4e5da5Sopenharmony_ci%void = OpTypeVoid 162fd4e5da5Sopenharmony_ci%func = OpTypeFunction %void 163fd4e5da5Sopenharmony_ci%bool = OpTypeBool 164fd4e5da5Sopenharmony_ci%f32 = OpTypeFloat 32 165fd4e5da5Sopenharmony_ci%u32 = OpTypeInt 32 0 166fd4e5da5Sopenharmony_ci%u64 = OpTypeInt 64 0 167fd4e5da5Sopenharmony_ci%f32vec4 = OpTypeVector %f32 4 168fd4e5da5Sopenharmony_ci 169fd4e5da5Sopenharmony_ci%f32_0 = OpConstant %f32 0 170fd4e5da5Sopenharmony_ci%f32_1 = OpConstant %f32 1 171fd4e5da5Sopenharmony_ci%u32_0 = OpConstant %u32 0 172fd4e5da5Sopenharmony_ci%u32_1 = OpConstant %u32 1 173fd4e5da5Sopenharmony_ci%u64_1 = OpConstant %u64 1 174fd4e5da5Sopenharmony_ci%f32vec4_0000 = OpConstantComposite %f32vec4 %f32_0 %f32_0 %f32_0 %f32_0 175fd4e5da5Sopenharmony_ci 176fd4e5da5Sopenharmony_ci%cross_device = OpConstant %u32 0 177fd4e5da5Sopenharmony_ci%device = OpConstant %u32 1 178fd4e5da5Sopenharmony_ci%workgroup = OpConstant %u32 2 179fd4e5da5Sopenharmony_ci%subgroup = OpConstant %u32 3 180fd4e5da5Sopenharmony_ci%invocation = OpConstant %u32 4 181fd4e5da5Sopenharmony_ci 182fd4e5da5Sopenharmony_ci%relaxed = OpConstant %u32 0 183fd4e5da5Sopenharmony_ci%acquire = OpConstant %u32 2 184fd4e5da5Sopenharmony_ci%release = OpConstant %u32 4 185fd4e5da5Sopenharmony_ci%acquire_release = OpConstant %u32 8 186fd4e5da5Sopenharmony_ci%acquire_and_release = OpConstant %u32 6 187fd4e5da5Sopenharmony_ci%sequentially_consistent = OpConstant %u32 16 188fd4e5da5Sopenharmony_ci%acquire_release_uniform_workgroup = OpConstant %u32 328 189fd4e5da5Sopenharmony_ci%acquire_release_atomic_counter_workgroup = OpConstant %u32 1288 190fd4e5da5Sopenharmony_ci 191fd4e5da5Sopenharmony_ci%f32_ptr = OpTypePointer Workgroup %f32 192fd4e5da5Sopenharmony_ci%f32_var = OpVariable %f32_ptr Workgroup 193fd4e5da5Sopenharmony_ci 194fd4e5da5Sopenharmony_ci%u32_ptr = OpTypePointer Workgroup %u32 195fd4e5da5Sopenharmony_ci%u32_var = OpVariable %u32_ptr Workgroup 196fd4e5da5Sopenharmony_ci 197fd4e5da5Sopenharmony_ci%u64_ptr = OpTypePointer Workgroup %u64 198fd4e5da5Sopenharmony_ci%u64_var = OpVariable %u64_ptr Workgroup 199fd4e5da5Sopenharmony_ci 200fd4e5da5Sopenharmony_ci%f32vec4_ptr = OpTypePointer Workgroup %f32vec4 201fd4e5da5Sopenharmony_ci%f32vec4_var = OpVariable %f32vec4_ptr Workgroup 202fd4e5da5Sopenharmony_ci 203fd4e5da5Sopenharmony_ci%f32_ptr_function = OpTypePointer Function %f32 204fd4e5da5Sopenharmony_ci%f32_ptr_uniformconstant = OpTypePointer UniformConstant %f32 205fd4e5da5Sopenharmony_ci%f32_uc_var = OpVariable %f32_ptr_uniformconstant UniformConstant 206fd4e5da5Sopenharmony_ci 207fd4e5da5Sopenharmony_ci%f32_ptr_image = OpTypePointer Image %f32 208fd4e5da5Sopenharmony_ci%f32_im_var = OpVariable %f32_ptr_image Image 209fd4e5da5Sopenharmony_ci 210fd4e5da5Sopenharmony_ci%main = OpFunction %void None %func 211fd4e5da5Sopenharmony_ci%main_entry = OpLabel 212fd4e5da5Sopenharmony_ci)"; 213fd4e5da5Sopenharmony_ci 214fd4e5da5Sopenharmony_ci ss << body; 215fd4e5da5Sopenharmony_ci 216fd4e5da5Sopenharmony_ci ss << R"( 217fd4e5da5Sopenharmony_ciOpReturn 218fd4e5da5Sopenharmony_ciOpFunctionEnd)"; 219fd4e5da5Sopenharmony_ci 220fd4e5da5Sopenharmony_ci return ss.str(); 221fd4e5da5Sopenharmony_ci} 222fd4e5da5Sopenharmony_ci 223fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicLoadShaderSuccess) { 224fd4e5da5Sopenharmony_ci const std::string body = R"( 225fd4e5da5Sopenharmony_ci%val1 = OpAtomicLoad %u32 %u32_var %device %relaxed 226fd4e5da5Sopenharmony_ci%val2 = OpAtomicLoad %u32 %u32_var %workgroup %acquire 227fd4e5da5Sopenharmony_ci)"; 228fd4e5da5Sopenharmony_ci 229fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 230fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); 231fd4e5da5Sopenharmony_ci} 232fd4e5da5Sopenharmony_ci 233fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicLoadKernelSuccess) { 234fd4e5da5Sopenharmony_ci const std::string body = R"( 235fd4e5da5Sopenharmony_ci%val1 = OpAtomicLoad %f32 %f32_var %device %relaxed 236fd4e5da5Sopenharmony_ci%val2 = OpAtomicLoad %u32 %u32_var %workgroup %sequentially_consistent 237fd4e5da5Sopenharmony_ci)"; 238fd4e5da5Sopenharmony_ci 239fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body)); 240fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); 241fd4e5da5Sopenharmony_ci} 242fd4e5da5Sopenharmony_ci 243fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicLoadInt64ShaderSuccess) { 244fd4e5da5Sopenharmony_ci const std::string body = R"( 245fd4e5da5Sopenharmony_ci%val1 = OpAtomicLoad %u64 %u64_var %subgroup %sequentially_consistent 246fd4e5da5Sopenharmony_ci)"; 247fd4e5da5Sopenharmony_ci 248fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body, "OpCapability Int64Atomics\n")); 249fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); 250fd4e5da5Sopenharmony_ci} 251fd4e5da5Sopenharmony_ci 252fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicLoadInt64KernelSuccess) { 253fd4e5da5Sopenharmony_ci const std::string body = R"( 254fd4e5da5Sopenharmony_ci%val1 = OpAtomicLoad %u64 %u64_var %subgroup %acquire 255fd4e5da5Sopenharmony_ci)"; 256fd4e5da5Sopenharmony_ci 257fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body, "OpCapability Int64Atomics\n")); 258fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); 259fd4e5da5Sopenharmony_ci} 260fd4e5da5Sopenharmony_ci 261fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicLoadInt32VulkanSuccess) { 262fd4e5da5Sopenharmony_ci const std::string body = R"( 263fd4e5da5Sopenharmony_ci%val1 = OpAtomicLoad %u32 %u32_var %device %relaxed 264fd4e5da5Sopenharmony_ci%val2 = OpAtomicLoad %u32 %u32_var %workgroup %acquire 265fd4e5da5Sopenharmony_ci%val3 = OpAtomicLoad %u32 %u32_var %invocation %relaxed 266fd4e5da5Sopenharmony_ci)"; 267fd4e5da5Sopenharmony_ci 268fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderComputeCode(body), SPV_ENV_VULKAN_1_0); 269fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 270fd4e5da5Sopenharmony_ci} 271fd4e5da5Sopenharmony_ci 272fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicLoadVulkanWrongStorageClass) { 273fd4e5da5Sopenharmony_ci const std::string body = R"( 274fd4e5da5Sopenharmony_ci%val1 = OpAtomicLoad %u32 %u32_var %device %relaxed 275fd4e5da5Sopenharmony_ci)"; 276fd4e5da5Sopenharmony_ci 277fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body), SPV_ENV_VULKAN_1_0); 278fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 279fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 280fd4e5da5Sopenharmony_ci AnyVUID("VUID-StandaloneSpirv-None-04645")); 281fd4e5da5Sopenharmony_ci EXPECT_THAT( 282fd4e5da5Sopenharmony_ci getDiagnosticString(), 283fd4e5da5Sopenharmony_ci HasSubstr("in Vulkan environment, Workgroup Storage Class is limited to " 284fd4e5da5Sopenharmony_ci "MeshNV, TaskNV, and GLCompute execution model")); 285fd4e5da5Sopenharmony_ci} 286fd4e5da5Sopenharmony_ci 287fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicAddIntVulkanWrongType1) { 288fd4e5da5Sopenharmony_ci const std::string body = R"( 289fd4e5da5Sopenharmony_ci%val1 = OpAtomicIAdd %f32 %f32_var %device %relaxed %f32_1 290fd4e5da5Sopenharmony_ci)"; 291fd4e5da5Sopenharmony_ci 292fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 293fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 294fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 295fd4e5da5Sopenharmony_ci HasSubstr("AtomicIAdd: " 296fd4e5da5Sopenharmony_ci "expected Result Type to be integer scalar type")); 297fd4e5da5Sopenharmony_ci} 298fd4e5da5Sopenharmony_ci 299fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicAddIntVulkanWrongType2) { 300fd4e5da5Sopenharmony_ci const std::string body = R"( 301fd4e5da5Sopenharmony_ci%val1 = OpAtomicIAdd %f32vec4 %f32vec4_var %device %relaxed %f32_1 302fd4e5da5Sopenharmony_ci)"; 303fd4e5da5Sopenharmony_ci 304fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 305fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 306fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 307fd4e5da5Sopenharmony_ci HasSubstr("AtomicIAdd: " 308fd4e5da5Sopenharmony_ci "expected Result Type to be integer scalar type")); 309fd4e5da5Sopenharmony_ci} 310fd4e5da5Sopenharmony_ci 311fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicAddFloatVulkan) { 312fd4e5da5Sopenharmony_ci const std::string body = R"( 313fd4e5da5Sopenharmony_ci%val1 = OpAtomicFAddEXT %f32 %f32_var %device %relaxed %f32_1 314fd4e5da5Sopenharmony_ci)"; 315fd4e5da5Sopenharmony_ci 316fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 317fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_CAPABILITY, ValidateInstructions()); 318fd4e5da5Sopenharmony_ci EXPECT_THAT( 319fd4e5da5Sopenharmony_ci getDiagnosticString(), 320fd4e5da5Sopenharmony_ci HasSubstr("Opcode AtomicFAddEXT requires one of these capabilities: " 321fd4e5da5Sopenharmony_ci "AtomicFloat32AddEXT AtomicFloat64AddEXT AtomicFloat16AddEXT")); 322fd4e5da5Sopenharmony_ci} 323fd4e5da5Sopenharmony_ci 324fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicMinFloatVulkan) { 325fd4e5da5Sopenharmony_ci const std::string body = R"( 326fd4e5da5Sopenharmony_ci%val1 = OpAtomicFMinEXT %f32 %f32_var %device %relaxed %f32_1 327fd4e5da5Sopenharmony_ci)"; 328fd4e5da5Sopenharmony_ci 329fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 330fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_CAPABILITY, ValidateInstructions()); 331fd4e5da5Sopenharmony_ci EXPECT_THAT( 332fd4e5da5Sopenharmony_ci getDiagnosticString(), 333fd4e5da5Sopenharmony_ci HasSubstr("Opcode AtomicFMinEXT requires one of these capabilities: " 334fd4e5da5Sopenharmony_ci "AtomicFloat32MinMaxEXT AtomicFloat64MinMaxEXT AtomicFloat16MinMaxEXT")); 335fd4e5da5Sopenharmony_ci} 336fd4e5da5Sopenharmony_ci 337fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicMaxFloatVulkan) { 338fd4e5da5Sopenharmony_ci const std::string body = R"( 339fd4e5da5Sopenharmony_ci%val1 = OpAtomicFMaxEXT %f32 %f32_var %device %relaxed %f32_1 340fd4e5da5Sopenharmony_ci)"; 341fd4e5da5Sopenharmony_ci 342fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 343fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_CAPABILITY, ValidateInstructions()); 344fd4e5da5Sopenharmony_ci EXPECT_THAT( 345fd4e5da5Sopenharmony_ci getDiagnosticString(), 346fd4e5da5Sopenharmony_ci HasSubstr("Opcode AtomicFMaxEXT requires one of these capabilities: " 347fd4e5da5Sopenharmony_ci "AtomicFloat32MinMaxEXT AtomicFloat64MinMaxEXT AtomicFloat16MinMaxEXT")); 348fd4e5da5Sopenharmony_ci} 349fd4e5da5Sopenharmony_ci 350fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicAddFloatVulkanWrongType1) { 351fd4e5da5Sopenharmony_ci const std::string body = R"( 352fd4e5da5Sopenharmony_ci%val1 = OpAtomicFAddEXT %f32vec4 %f32vec4_var %device %relaxed %f32_1 353fd4e5da5Sopenharmony_ci)"; 354fd4e5da5Sopenharmony_ci const std::string extra = R"( 355fd4e5da5Sopenharmony_ciOpCapability AtomicFloat32AddEXT 356fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_shader_atomic_float_add" 357fd4e5da5Sopenharmony_ci)"; 358fd4e5da5Sopenharmony_ci 359fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body, extra), SPV_ENV_VULKAN_1_0); 360fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 361fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 362fd4e5da5Sopenharmony_ci HasSubstr("AtomicFAddEXT: " 363fd4e5da5Sopenharmony_ci "expected Result Type to be float scalar type")); 364fd4e5da5Sopenharmony_ci} 365fd4e5da5Sopenharmony_ci 366fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicMinFloatVulkanWrongType1) { 367fd4e5da5Sopenharmony_ci const std::string body = R"( 368fd4e5da5Sopenharmony_ci%val1 = OpAtomicFMinEXT %f32vec4 %f32vec4_var %device %relaxed %f32_1 369fd4e5da5Sopenharmony_ci)"; 370fd4e5da5Sopenharmony_ci const std::string extra = R"( 371fd4e5da5Sopenharmony_ciOpCapability AtomicFloat32MinMaxEXT 372fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_shader_atomic_float_min_max" 373fd4e5da5Sopenharmony_ci)"; 374fd4e5da5Sopenharmony_ci 375fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body, extra), SPV_ENV_VULKAN_1_0); 376fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 377fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 378fd4e5da5Sopenharmony_ci HasSubstr("AtomicFMinEXT: " 379fd4e5da5Sopenharmony_ci "expected Result Type to be float scalar type")); 380fd4e5da5Sopenharmony_ci} 381fd4e5da5Sopenharmony_ci 382fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicMaxFloatVulkanWrongType1) { 383fd4e5da5Sopenharmony_ci const std::string body = R"( 384fd4e5da5Sopenharmony_ci%val1 = OpAtomicFMaxEXT %f32vec4 %f32vec4_var %device %relaxed %f32_1 385fd4e5da5Sopenharmony_ci)"; 386fd4e5da5Sopenharmony_ci const std::string extra = R"( 387fd4e5da5Sopenharmony_ciOpCapability AtomicFloat32MinMaxEXT 388fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_shader_atomic_float_min_max" 389fd4e5da5Sopenharmony_ci)"; 390fd4e5da5Sopenharmony_ci 391fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body, extra), SPV_ENV_VULKAN_1_0); 392fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 393fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 394fd4e5da5Sopenharmony_ci HasSubstr("AtomicFMaxEXT: " 395fd4e5da5Sopenharmony_ci "expected Result Type to be float scalar type")); 396fd4e5da5Sopenharmony_ci} 397fd4e5da5Sopenharmony_ci 398fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicAddFloatVulkanWrongType2) { 399fd4e5da5Sopenharmony_ci const std::string body = R"( 400fd4e5da5Sopenharmony_ci%val1 = OpAtomicFAddEXT %u32 %u32_var %device %relaxed %u32_1 401fd4e5da5Sopenharmony_ci)"; 402fd4e5da5Sopenharmony_ci const std::string extra = R"( 403fd4e5da5Sopenharmony_ciOpCapability AtomicFloat32AddEXT 404fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_shader_atomic_float_add" 405fd4e5da5Sopenharmony_ci)"; 406fd4e5da5Sopenharmony_ci 407fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body, extra), SPV_ENV_VULKAN_1_0); 408fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 409fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 410fd4e5da5Sopenharmony_ci HasSubstr("AtomicFAddEXT: " 411fd4e5da5Sopenharmony_ci "expected Result Type to be float scalar type")); 412fd4e5da5Sopenharmony_ci} 413fd4e5da5Sopenharmony_ci 414fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicMinFloatVulkanWrongType2) { 415fd4e5da5Sopenharmony_ci const std::string body = R"( 416fd4e5da5Sopenharmony_ci%val1 = OpAtomicFMinEXT %u32 %u32_var %device %relaxed %u32_1 417fd4e5da5Sopenharmony_ci)"; 418fd4e5da5Sopenharmony_ci const std::string extra = R"( 419fd4e5da5Sopenharmony_ciOpCapability AtomicFloat32MinMaxEXT 420fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_shader_atomic_float_min_max" 421fd4e5da5Sopenharmony_ci)"; 422fd4e5da5Sopenharmony_ci 423fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body, extra), SPV_ENV_VULKAN_1_0); 424fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 425fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 426fd4e5da5Sopenharmony_ci HasSubstr("AtomicFMinEXT: " 427fd4e5da5Sopenharmony_ci "expected Result Type to be float scalar type")); 428fd4e5da5Sopenharmony_ci} 429fd4e5da5Sopenharmony_ci 430fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicMaxFloatVulkanWrongType2) { 431fd4e5da5Sopenharmony_ci const std::string body = R"( 432fd4e5da5Sopenharmony_ci%val1 = OpAtomicFMaxEXT %u32 %u32_var %device %relaxed %u32_1 433fd4e5da5Sopenharmony_ci)"; 434fd4e5da5Sopenharmony_ci const std::string extra = R"( 435fd4e5da5Sopenharmony_ciOpCapability AtomicFloat32MinMaxEXT 436fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_shader_atomic_float_min_max" 437fd4e5da5Sopenharmony_ci)"; 438fd4e5da5Sopenharmony_ci 439fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body, extra), SPV_ENV_VULKAN_1_0); 440fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 441fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 442fd4e5da5Sopenharmony_ci HasSubstr("AtomicFMaxEXT: " 443fd4e5da5Sopenharmony_ci "expected Result Type to be float scalar type")); 444fd4e5da5Sopenharmony_ci} 445fd4e5da5Sopenharmony_ci 446fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicAddFloatVulkanWrongType3) { 447fd4e5da5Sopenharmony_ci const std::string body = R"( 448fd4e5da5Sopenharmony_ci%val1 = OpAtomicFAddEXT %u64 %u64_var %device %relaxed %u64_1 449fd4e5da5Sopenharmony_ci)"; 450fd4e5da5Sopenharmony_ci const std::string extra = R"( 451fd4e5da5Sopenharmony_ciOpCapability AtomicFloat32AddEXT 452fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_shader_atomic_float_add" 453fd4e5da5Sopenharmony_ci)"; 454fd4e5da5Sopenharmony_ci 455fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body, extra), SPV_ENV_VULKAN_1_0); 456fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 457fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 458fd4e5da5Sopenharmony_ci HasSubstr("AtomicFAddEXT: " 459fd4e5da5Sopenharmony_ci "expected Result Type to be float scalar type")); 460fd4e5da5Sopenharmony_ci} 461fd4e5da5Sopenharmony_ci 462fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicMinFloatVulkanWrongType3) { 463fd4e5da5Sopenharmony_ci const std::string body = R"( 464fd4e5da5Sopenharmony_ci%val1 = OpAtomicFMinEXT %u64 %u64_var %device %relaxed %u64_1 465fd4e5da5Sopenharmony_ci)"; 466fd4e5da5Sopenharmony_ci const std::string extra = R"( 467fd4e5da5Sopenharmony_ciOpCapability AtomicFloat32MinMaxEXT 468fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_shader_atomic_float_min_max" 469fd4e5da5Sopenharmony_ci)"; 470fd4e5da5Sopenharmony_ci 471fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body, extra), SPV_ENV_VULKAN_1_0); 472fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 473fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 474fd4e5da5Sopenharmony_ci HasSubstr("AtomicFMinEXT: " 475fd4e5da5Sopenharmony_ci "expected Result Type to be float scalar type")); 476fd4e5da5Sopenharmony_ci} 477fd4e5da5Sopenharmony_ci 478fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicMaxFloatVulkanWrongType3) { 479fd4e5da5Sopenharmony_ci const std::string body = R"( 480fd4e5da5Sopenharmony_ci%val1 = OpAtomicFMaxEXT %u64 %u64_var %device %relaxed %u64_1 481fd4e5da5Sopenharmony_ci)"; 482fd4e5da5Sopenharmony_ci const std::string extra = R"( 483fd4e5da5Sopenharmony_ciOpCapability AtomicFloat32MinMaxEXT 484fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_shader_atomic_float_min_max" 485fd4e5da5Sopenharmony_ci)"; 486fd4e5da5Sopenharmony_ci 487fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body, extra), SPV_ENV_VULKAN_1_0); 488fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 489fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 490fd4e5da5Sopenharmony_ci HasSubstr("AtomicFMaxEXT: " 491fd4e5da5Sopenharmony_ci "expected Result Type to be float scalar type")); 492fd4e5da5Sopenharmony_ci} 493fd4e5da5Sopenharmony_ci 494fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicAddFloatVulkanWrongCapability) { 495fd4e5da5Sopenharmony_ci const std::string body = R"( 496fd4e5da5Sopenharmony_ci%val1 = OpAtomicFAddEXT %f32 %f32_var %device %relaxed %f32_1 497fd4e5da5Sopenharmony_ci)"; 498fd4e5da5Sopenharmony_ci const std::string extra = R"( 499fd4e5da5Sopenharmony_ciOpCapability AtomicFloat64AddEXT 500fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_shader_atomic_float_add" 501fd4e5da5Sopenharmony_ci)"; 502fd4e5da5Sopenharmony_ci 503fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body, extra), SPV_ENV_VULKAN_1_0); 504fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 505fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 506fd4e5da5Sopenharmony_ci HasSubstr("AtomicFAddEXT: float add atomics " 507fd4e5da5Sopenharmony_ci "require the AtomicFloat32AddEXT capability")); 508fd4e5da5Sopenharmony_ci} 509fd4e5da5Sopenharmony_ci 510fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicMinFloatVulkanWrongCapability) { 511fd4e5da5Sopenharmony_ci const std::string body = R"( 512fd4e5da5Sopenharmony_ci%val1 = OpAtomicFMinEXT %f32 %f32_var %device %relaxed %f32_1 513fd4e5da5Sopenharmony_ci)"; 514fd4e5da5Sopenharmony_ci const std::string extra = R"( 515fd4e5da5Sopenharmony_ciOpCapability AtomicFloat64MinMaxEXT 516fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_shader_atomic_float_min_max" 517fd4e5da5Sopenharmony_ci)"; 518fd4e5da5Sopenharmony_ci 519fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body, extra), SPV_ENV_VULKAN_1_0); 520fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 521fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 522fd4e5da5Sopenharmony_ci HasSubstr("AtomicFMinEXT: float min/max atomics " 523fd4e5da5Sopenharmony_ci "require the AtomicFloat32MinMaxEXT capability")); 524fd4e5da5Sopenharmony_ci} 525fd4e5da5Sopenharmony_ci 526fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicMaxFloatVulkanWrongCapability) { 527fd4e5da5Sopenharmony_ci const std::string body = R"( 528fd4e5da5Sopenharmony_ci%val1 = OpAtomicFMaxEXT %f32 %f32_var %device %relaxed %f32_1 529fd4e5da5Sopenharmony_ci)"; 530fd4e5da5Sopenharmony_ci const std::string extra = R"( 531fd4e5da5Sopenharmony_ciOpCapability AtomicFloat64MinMaxEXT 532fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_shader_atomic_float_min_max" 533fd4e5da5Sopenharmony_ci)"; 534fd4e5da5Sopenharmony_ci 535fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body, extra), SPV_ENV_VULKAN_1_0); 536fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 537fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 538fd4e5da5Sopenharmony_ci HasSubstr("AtomicFMaxEXT: float min/max atomics " 539fd4e5da5Sopenharmony_ci "require the AtomicFloat32MinMaxEXT capability")); 540fd4e5da5Sopenharmony_ci} 541fd4e5da5Sopenharmony_ci 542fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicAddFloat16VulkanSuccess) { 543fd4e5da5Sopenharmony_ci const std::string defs = R"( 544fd4e5da5Sopenharmony_ci%f16 = OpTypeFloat 16 545fd4e5da5Sopenharmony_ci%f16_1 = OpConstant %f16 1 546fd4e5da5Sopenharmony_ci%f16_ptr = OpTypePointer Workgroup %f16 547fd4e5da5Sopenharmony_ci%f16_var = OpVariable %f16_ptr Workgroup 548fd4e5da5Sopenharmony_ci)"; 549fd4e5da5Sopenharmony_ci const std::string body = R"( 550fd4e5da5Sopenharmony_ci%val1 = OpAtomicFAddEXT %f16 %f16_var %device %relaxed %f16_1 551fd4e5da5Sopenharmony_ci)"; 552fd4e5da5Sopenharmony_ci const std::string extra = R"( 553fd4e5da5Sopenharmony_ciOpCapability Float16 554fd4e5da5Sopenharmony_ciOpCapability AtomicFloat16AddEXT 555fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_shader_atomic_float16_add" 556fd4e5da5Sopenharmony_ci)"; 557fd4e5da5Sopenharmony_ci 558fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderComputeCode(body, extra, defs), 559fd4e5da5Sopenharmony_ci SPV_ENV_VULKAN_1_0); 560fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 561fd4e5da5Sopenharmony_ci} 562fd4e5da5Sopenharmony_ci 563fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicAddFloatVulkanSuccess) { 564fd4e5da5Sopenharmony_ci const std::string body = R"( 565fd4e5da5Sopenharmony_ci%val1 = OpAtomicFAddEXT %f32 %f32_var %device %relaxed %f32_1 566fd4e5da5Sopenharmony_ci%val2 = OpAtomicFAddEXT %f32 %f32_var %invocation %relaxed %f32_1 567fd4e5da5Sopenharmony_ci)"; 568fd4e5da5Sopenharmony_ci const std::string extra = R"( 569fd4e5da5Sopenharmony_ciOpCapability AtomicFloat32AddEXT 570fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_shader_atomic_float_add" 571fd4e5da5Sopenharmony_ci)"; 572fd4e5da5Sopenharmony_ci 573fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderComputeCode(body, extra), 574fd4e5da5Sopenharmony_ci SPV_ENV_VULKAN_1_0); 575fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 576fd4e5da5Sopenharmony_ci} 577fd4e5da5Sopenharmony_ci 578fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicMinFloat16VulkanSuccess) { 579fd4e5da5Sopenharmony_ci const std::string defs = R"( 580fd4e5da5Sopenharmony_ci%f16 = OpTypeFloat 16 581fd4e5da5Sopenharmony_ci%f16_1 = OpConstant %f16 1 582fd4e5da5Sopenharmony_ci%f16_ptr = OpTypePointer Workgroup %f16 583fd4e5da5Sopenharmony_ci%f16_var = OpVariable %f16_ptr Workgroup 584fd4e5da5Sopenharmony_ci)"; 585fd4e5da5Sopenharmony_ci const std::string body = R"( 586fd4e5da5Sopenharmony_ci%val1 = OpAtomicFMinEXT %f16 %f16_var %device %relaxed %f16_1 587fd4e5da5Sopenharmony_ci)"; 588fd4e5da5Sopenharmony_ci const std::string extra = R"( 589fd4e5da5Sopenharmony_ciOpCapability Float16 590fd4e5da5Sopenharmony_ciOpCapability AtomicFloat16MinMaxEXT 591fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_shader_atomic_float_min_max" 592fd4e5da5Sopenharmony_ci)"; 593fd4e5da5Sopenharmony_ci 594fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderComputeCode(body, extra, defs), 595fd4e5da5Sopenharmony_ci SPV_ENV_VULKAN_1_0); 596fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 597fd4e5da5Sopenharmony_ci} 598fd4e5da5Sopenharmony_ci 599fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicMaxFloat16VulkanSuccess) { 600fd4e5da5Sopenharmony_ci const std::string defs = R"( 601fd4e5da5Sopenharmony_ci%f16 = OpTypeFloat 16 602fd4e5da5Sopenharmony_ci%f16_1 = OpConstant %f16 1 603fd4e5da5Sopenharmony_ci%f16_ptr = OpTypePointer Workgroup %f16 604fd4e5da5Sopenharmony_ci%f16_var = OpVariable %f16_ptr Workgroup 605fd4e5da5Sopenharmony_ci)"; 606fd4e5da5Sopenharmony_ci const std::string body = R"( 607fd4e5da5Sopenharmony_ci%val1 = OpAtomicFMaxEXT %f16 %f16_var %device %relaxed %f16_1 608fd4e5da5Sopenharmony_ci)"; 609fd4e5da5Sopenharmony_ci const std::string extra = R"( 610fd4e5da5Sopenharmony_ciOpCapability Float16 611fd4e5da5Sopenharmony_ciOpCapability AtomicFloat16MinMaxEXT 612fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_shader_atomic_float_min_max" 613fd4e5da5Sopenharmony_ci)"; 614fd4e5da5Sopenharmony_ci 615fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderComputeCode(body, extra, defs), 616fd4e5da5Sopenharmony_ci SPV_ENV_VULKAN_1_0); 617fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 618fd4e5da5Sopenharmony_ci} 619fd4e5da5Sopenharmony_ci 620fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicMinFloat32VulkanSuccess) { 621fd4e5da5Sopenharmony_ci const std::string body = R"( 622fd4e5da5Sopenharmony_ci%val1 = OpAtomicFMinEXT %f32 %f32_var %device %relaxed %f32_1 623fd4e5da5Sopenharmony_ci)"; 624fd4e5da5Sopenharmony_ci const std::string extra = R"( 625fd4e5da5Sopenharmony_ciOpCapability AtomicFloat32MinMaxEXT 626fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_shader_atomic_float_min_max" 627fd4e5da5Sopenharmony_ci)"; 628fd4e5da5Sopenharmony_ci 629fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderComputeCode(body, extra), 630fd4e5da5Sopenharmony_ci SPV_ENV_VULKAN_1_0); 631fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 632fd4e5da5Sopenharmony_ci} 633fd4e5da5Sopenharmony_ci 634fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicMaxFloat32VulkanSuccess) { 635fd4e5da5Sopenharmony_ci const std::string body = R"( 636fd4e5da5Sopenharmony_ci%val1 = OpAtomicFMaxEXT %f32 %f32_var %device %relaxed %f32_1 637fd4e5da5Sopenharmony_ci)"; 638fd4e5da5Sopenharmony_ci const std::string extra = R"( 639fd4e5da5Sopenharmony_ciOpCapability AtomicFloat32MinMaxEXT 640fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_shader_atomic_float_min_max" 641fd4e5da5Sopenharmony_ci)"; 642fd4e5da5Sopenharmony_ci 643fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderComputeCode(body, extra), 644fd4e5da5Sopenharmony_ci SPV_ENV_VULKAN_1_0); 645fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 646fd4e5da5Sopenharmony_ci} 647fd4e5da5Sopenharmony_ci 648fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicMinFloat64VulkanSuccess) { 649fd4e5da5Sopenharmony_ci const std::string defs = R"( 650fd4e5da5Sopenharmony_ci%f64 = OpTypeFloat 64 651fd4e5da5Sopenharmony_ci%f64_1 = OpConstant %f64 1 652fd4e5da5Sopenharmony_ci%f64_ptr = OpTypePointer Workgroup %f64 653fd4e5da5Sopenharmony_ci%f64_var = OpVariable %f64_ptr Workgroup 654fd4e5da5Sopenharmony_ci)"; 655fd4e5da5Sopenharmony_ci const std::string body = R"( 656fd4e5da5Sopenharmony_ci%val1 = OpAtomicFMinEXT %f64 %f64_var %device %relaxed %f64_1 657fd4e5da5Sopenharmony_ci)"; 658fd4e5da5Sopenharmony_ci const std::string extra = R"( 659fd4e5da5Sopenharmony_ciOpCapability Float64 660fd4e5da5Sopenharmony_ciOpCapability AtomicFloat64MinMaxEXT 661fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_shader_atomic_float_min_max" 662fd4e5da5Sopenharmony_ci)"; 663fd4e5da5Sopenharmony_ci 664fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderComputeCode(body, extra, defs), 665fd4e5da5Sopenharmony_ci SPV_ENV_VULKAN_1_0); 666fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 667fd4e5da5Sopenharmony_ci} 668fd4e5da5Sopenharmony_ci 669fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicMaxFloat64VulkanSuccess) { 670fd4e5da5Sopenharmony_ci const std::string defs = R"( 671fd4e5da5Sopenharmony_ci%f64 = OpTypeFloat 64 672fd4e5da5Sopenharmony_ci%f64_1 = OpConstant %f64 1 673fd4e5da5Sopenharmony_ci%f64_ptr = OpTypePointer Workgroup %f64 674fd4e5da5Sopenharmony_ci%f64_var = OpVariable %f64_ptr Workgroup 675fd4e5da5Sopenharmony_ci)"; 676fd4e5da5Sopenharmony_ci const std::string body = R"( 677fd4e5da5Sopenharmony_ci%val1 = OpAtomicFMaxEXT %f64 %f64_var %device %relaxed %f64_1 678fd4e5da5Sopenharmony_ci)"; 679fd4e5da5Sopenharmony_ci const std::string extra = R"( 680fd4e5da5Sopenharmony_ciOpCapability Float64 681fd4e5da5Sopenharmony_ciOpCapability AtomicFloat64MinMaxEXT 682fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_shader_atomic_float_min_max" 683fd4e5da5Sopenharmony_ci)"; 684fd4e5da5Sopenharmony_ci 685fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderComputeCode(body, extra, defs), 686fd4e5da5Sopenharmony_ci SPV_ENV_VULKAN_1_0); 687fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 688fd4e5da5Sopenharmony_ci} 689fd4e5da5Sopenharmony_ci 690fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicLoadFloatVulkan) { 691fd4e5da5Sopenharmony_ci const std::string body = R"( 692fd4e5da5Sopenharmony_ci%val1 = OpAtomicLoad %f32 %f32_var %device %relaxed 693fd4e5da5Sopenharmony_ci%val2 = OpAtomicLoad %f32 %f32_var %workgroup %acquire 694fd4e5da5Sopenharmony_ci)"; 695fd4e5da5Sopenharmony_ci 696fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderComputeCode(body), SPV_ENV_VULKAN_1_0); 697fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 698fd4e5da5Sopenharmony_ci} 699fd4e5da5Sopenharmony_ci 700fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicStoreVulkanWrongStorageClass) { 701fd4e5da5Sopenharmony_ci const std::string body = R"( 702fd4e5da5Sopenharmony_ciOpAtomicStore %f32_var %device %relaxed %f32_1 703fd4e5da5Sopenharmony_ci)"; 704fd4e5da5Sopenharmony_ci 705fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body), SPV_ENV_VULKAN_1_0); 706fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 707fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 708fd4e5da5Sopenharmony_ci AnyVUID("VUID-StandaloneSpirv-None-04645")); 709fd4e5da5Sopenharmony_ci EXPECT_THAT( 710fd4e5da5Sopenharmony_ci getDiagnosticString(), 711fd4e5da5Sopenharmony_ci HasSubstr("in Vulkan environment, Workgroup Storage Class is limited to " 712fd4e5da5Sopenharmony_ci "MeshNV, TaskNV, and GLCompute execution model")); 713fd4e5da5Sopenharmony_ci} 714fd4e5da5Sopenharmony_ci 715fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicStoreFloatVulkan) { 716fd4e5da5Sopenharmony_ci const std::string body = R"( 717fd4e5da5Sopenharmony_ciOpAtomicStore %f32_var %device %relaxed %f32_1 718fd4e5da5Sopenharmony_ci)"; 719fd4e5da5Sopenharmony_ci 720fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderComputeCode(body), SPV_ENV_VULKAN_1_0); 721fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 722fd4e5da5Sopenharmony_ci} 723fd4e5da5Sopenharmony_ci 724fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicExchangeFloatVulkan) { 725fd4e5da5Sopenharmony_ci const std::string body = R"( 726fd4e5da5Sopenharmony_ci%val2 = OpAtomicExchange %f32 %f32_var %device %relaxed %f32_0 727fd4e5da5Sopenharmony_ci)"; 728fd4e5da5Sopenharmony_ci 729fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderComputeCode(body), SPV_ENV_VULKAN_1_0); 730fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 731fd4e5da5Sopenharmony_ci} 732fd4e5da5Sopenharmony_ci 733fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicLoadInt64WithCapabilityVulkanSuccess) { 734fd4e5da5Sopenharmony_ci const std::string body = R"( 735fd4e5da5Sopenharmony_ci %val1 = OpAtomicLoad %u64 %u64_var %device %relaxed 736fd4e5da5Sopenharmony_ci %val2 = OpAtomicLoad %u64 %u64_var %workgroup %acquire 737fd4e5da5Sopenharmony_ci %val3 = OpAtomicLoad %u64 %u64_var %invocation %relaxed 738fd4e5da5Sopenharmony_ci )"; 739fd4e5da5Sopenharmony_ci 740fd4e5da5Sopenharmony_ci CompileSuccessfully( 741fd4e5da5Sopenharmony_ci GenerateShaderComputeCode(body, "OpCapability Int64Atomics\n"), 742fd4e5da5Sopenharmony_ci SPV_ENV_VULKAN_1_0); 743fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 744fd4e5da5Sopenharmony_ci} 745fd4e5da5Sopenharmony_ci 746fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicLoadInt64WithoutCapabilityVulkan) { 747fd4e5da5Sopenharmony_ci const std::string body = R"( 748fd4e5da5Sopenharmony_ci %val1 = OpAtomicLoad %u64 %u64_var %device %relaxed 749fd4e5da5Sopenharmony_ci %val2 = OpAtomicLoad %u64 %u64_var %workgroup %acquire 750fd4e5da5Sopenharmony_ci )"; 751fd4e5da5Sopenharmony_ci 752fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderComputeCode(body), SPV_ENV_VULKAN_1_0); 753fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 754fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 755fd4e5da5Sopenharmony_ci HasSubstr("64-bit atomics require the Int64Atomics capability")); 756fd4e5da5Sopenharmony_ci} 757fd4e5da5Sopenharmony_ci 758fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicStoreOpenCLFunctionPointerStorageTypeSuccess) { 759fd4e5da5Sopenharmony_ci const std::string body = R"( 760fd4e5da5Sopenharmony_ci%f32_var_function = OpVariable %f32_ptr_function Function 761fd4e5da5Sopenharmony_ciOpAtomicStore %f32_var_function %device %relaxed %f32_1 762fd4e5da5Sopenharmony_ci)"; 763fd4e5da5Sopenharmony_ci 764fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body), SPV_ENV_OPENCL_1_2); 765fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_OPENCL_1_2)); 766fd4e5da5Sopenharmony_ci} 767fd4e5da5Sopenharmony_ci 768fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicStoreVulkanFunctionPointerStorageType) { 769fd4e5da5Sopenharmony_ci const std::string body = R"( 770fd4e5da5Sopenharmony_ci%f32_var_function = OpVariable %f32_ptr_function Function 771fd4e5da5Sopenharmony_ciOpAtomicStore %f32_var_function %device %relaxed %f32_1 772fd4e5da5Sopenharmony_ci)"; 773fd4e5da5Sopenharmony_ci 774fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body), SPV_ENV_VULKAN_1_0); 775fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 776fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 777fd4e5da5Sopenharmony_ci AnyVUID("VUID-StandaloneSpirv-None-04686")); 778fd4e5da5Sopenharmony_ci EXPECT_THAT( 779fd4e5da5Sopenharmony_ci getDiagnosticString(), 780fd4e5da5Sopenharmony_ci HasSubstr("AtomicStore: Vulkan spec only allows storage classes for " 781fd4e5da5Sopenharmony_ci "atomic to be: Uniform, Workgroup, Image, StorageBuffer, " 782fd4e5da5Sopenharmony_ci "PhysicalStorageBuffer or TaskPayloadWorkgroupEXT.")); 783fd4e5da5Sopenharmony_ci} 784fd4e5da5Sopenharmony_ci 785fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicStoreFunctionPointerStorageType) { 786fd4e5da5Sopenharmony_ci const std::string body = R"( 787fd4e5da5Sopenharmony_ci%f32_var_function = OpVariable %f32_ptr_function Function 788fd4e5da5Sopenharmony_ciOpAtomicStore %f32_var_function %device %relaxed %f32_1 789fd4e5da5Sopenharmony_ci)"; 790fd4e5da5Sopenharmony_ci 791fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 792fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 793fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 794fd4e5da5Sopenharmony_ci HasSubstr("AtomicStore: Function storage class forbidden when " 795fd4e5da5Sopenharmony_ci "the Shader capability is declared.")); 796fd4e5da5Sopenharmony_ci} 797fd4e5da5Sopenharmony_ci 798fd4e5da5Sopenharmony_ci// TODO(atgoo@github.com): the corresponding check fails Vulkan CTS, 799fd4e5da5Sopenharmony_ci// reenable once fixed. 800fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, DISABLED_AtomicLoadVulkanSubgroup) { 801fd4e5da5Sopenharmony_ci const std::string body = R"( 802fd4e5da5Sopenharmony_ci%val1 = OpAtomicLoad %u32 %u32_var %subgroup %acquire 803fd4e5da5Sopenharmony_ci)"; 804fd4e5da5Sopenharmony_ci 805fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body), SPV_ENV_VULKAN_1_0); 806fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 807fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 808fd4e5da5Sopenharmony_ci HasSubstr("AtomicLoad: in Vulkan environment memory scope is " 809fd4e5da5Sopenharmony_ci "limited to Device, Workgroup and Invocation")); 810fd4e5da5Sopenharmony_ci} 811fd4e5da5Sopenharmony_ci 812fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicLoadVulkanRelease) { 813fd4e5da5Sopenharmony_ci const std::string body = R"( 814fd4e5da5Sopenharmony_ci%val1 = OpAtomicLoad %u32 %u32_var %workgroup %release 815fd4e5da5Sopenharmony_ci)"; 816fd4e5da5Sopenharmony_ci 817fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body), SPV_ENV_VULKAN_1_0); 818fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 819fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 820fd4e5da5Sopenharmony_ci AnyVUID("VUID-StandaloneSpirv-OpAtomicLoad-04731")); 821fd4e5da5Sopenharmony_ci EXPECT_THAT( 822fd4e5da5Sopenharmony_ci getDiagnosticString(), 823fd4e5da5Sopenharmony_ci HasSubstr("Vulkan spec disallows OpAtomicLoad with Memory Semantics " 824fd4e5da5Sopenharmony_ci "Release, AcquireRelease and SequentiallyConsistent")); 825fd4e5da5Sopenharmony_ci} 826fd4e5da5Sopenharmony_ci 827fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicLoadVulkanAcquireRelease) { 828fd4e5da5Sopenharmony_ci const std::string body = R"( 829fd4e5da5Sopenharmony_ci%val1 = OpAtomicLoad %u32 %u32_var %workgroup %acquire_release 830fd4e5da5Sopenharmony_ci)"; 831fd4e5da5Sopenharmony_ci 832fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body), SPV_ENV_VULKAN_1_0); 833fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 834fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 835fd4e5da5Sopenharmony_ci AnyVUID("VUID-StandaloneSpirv-OpAtomicLoad-04731")); 836fd4e5da5Sopenharmony_ci EXPECT_THAT( 837fd4e5da5Sopenharmony_ci getDiagnosticString(), 838fd4e5da5Sopenharmony_ci HasSubstr("Vulkan spec disallows OpAtomicLoad with Memory Semantics " 839fd4e5da5Sopenharmony_ci "Release, AcquireRelease and SequentiallyConsistent")); 840fd4e5da5Sopenharmony_ci} 841fd4e5da5Sopenharmony_ci 842fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicLoadVulkanSequentiallyConsistent) { 843fd4e5da5Sopenharmony_ci const std::string body = R"( 844fd4e5da5Sopenharmony_ci%val1 = OpAtomicLoad %u32 %u32_var %workgroup %sequentially_consistent 845fd4e5da5Sopenharmony_ci)"; 846fd4e5da5Sopenharmony_ci 847fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body), SPV_ENV_VULKAN_1_0); 848fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 849fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 850fd4e5da5Sopenharmony_ci AnyVUID("VUID-StandaloneSpirv-OpAtomicLoad-04731")); 851fd4e5da5Sopenharmony_ci EXPECT_THAT( 852fd4e5da5Sopenharmony_ci getDiagnosticString(), 853fd4e5da5Sopenharmony_ci HasSubstr("Vulkan spec disallows OpAtomicLoad with Memory Semantics " 854fd4e5da5Sopenharmony_ci "Release, AcquireRelease and SequentiallyConsistent")); 855fd4e5da5Sopenharmony_ci} 856fd4e5da5Sopenharmony_ci 857fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicLoadVulkanInvocationSemantics) { 858fd4e5da5Sopenharmony_ci const std::string body = R"( 859fd4e5da5Sopenharmony_ci%val1 = OpAtomicLoad %u32 %u32_var %invocation %acquire 860fd4e5da5Sopenharmony_ci)"; 861fd4e5da5Sopenharmony_ci 862fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body), SPV_ENV_VULKAN_1_0); 863fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 864fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 865fd4e5da5Sopenharmony_ci AnyVUID("VUID-StandaloneSpirv-None-04641")); 866fd4e5da5Sopenharmony_ci EXPECT_THAT( 867fd4e5da5Sopenharmony_ci getDiagnosticString(), 868fd4e5da5Sopenharmony_ci HasSubstr("AtomicLoad: Vulkan specification requires Memory Semantics to " 869fd4e5da5Sopenharmony_ci "be None if used with Invocation Memory Scope")); 870fd4e5da5Sopenharmony_ci} 871fd4e5da5Sopenharmony_ci 872fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicLoadShaderFloat) { 873fd4e5da5Sopenharmony_ci const std::string body = R"( 874fd4e5da5Sopenharmony_ci%val1 = OpAtomicLoad %f32 %f32_var %device %relaxed 875fd4e5da5Sopenharmony_ci)"; 876fd4e5da5Sopenharmony_ci 877fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 878fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); 879fd4e5da5Sopenharmony_ci} 880fd4e5da5Sopenharmony_ci 881fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicLoadVulkanInt64) { 882fd4e5da5Sopenharmony_ci const std::string body = R"( 883fd4e5da5Sopenharmony_ci%val1 = OpAtomicLoad %u64 %u64_var %device %relaxed 884fd4e5da5Sopenharmony_ci)"; 885fd4e5da5Sopenharmony_ci 886fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body), SPV_ENV_VULKAN_1_0); 887fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 888fd4e5da5Sopenharmony_ci EXPECT_THAT( 889fd4e5da5Sopenharmony_ci getDiagnosticString(), 890fd4e5da5Sopenharmony_ci HasSubstr( 891fd4e5da5Sopenharmony_ci "AtomicLoad: 64-bit atomics require the Int64Atomics capability")); 892fd4e5da5Sopenharmony_ci} 893fd4e5da5Sopenharmony_ci 894fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicLoadKernelInt64) { 895fd4e5da5Sopenharmony_ci const std::string body = R"( 896fd4e5da5Sopenharmony_ci%val1 = OpAtomicLoad %u64 %u64_var %device %relaxed 897fd4e5da5Sopenharmony_ci)"; 898fd4e5da5Sopenharmony_ci 899fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body)); 900fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 901fd4e5da5Sopenharmony_ci EXPECT_THAT( 902fd4e5da5Sopenharmony_ci getDiagnosticString(), 903fd4e5da5Sopenharmony_ci HasSubstr( 904fd4e5da5Sopenharmony_ci "AtomicLoad: 64-bit atomics require the Int64Atomics capability")); 905fd4e5da5Sopenharmony_ci} 906fd4e5da5Sopenharmony_ci 907fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicStoreVulkanInt64) { 908fd4e5da5Sopenharmony_ci const std::string body = R"( 909fd4e5da5Sopenharmony_ciOpAtomicStore %u64_var %device %relaxed %u64_1 910fd4e5da5Sopenharmony_ci)"; 911fd4e5da5Sopenharmony_ci 912fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body), SPV_ENV_VULKAN_1_0); 913fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 914fd4e5da5Sopenharmony_ci EXPECT_THAT( 915fd4e5da5Sopenharmony_ci getDiagnosticString(), 916fd4e5da5Sopenharmony_ci HasSubstr( 917fd4e5da5Sopenharmony_ci "AtomicStore: 64-bit atomics require the Int64Atomics capability")); 918fd4e5da5Sopenharmony_ci} 919fd4e5da5Sopenharmony_ci 920fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicStoreKernelInt64) { 921fd4e5da5Sopenharmony_ci const std::string body = R"( 922fd4e5da5Sopenharmony_ciOpAtomicStore %u64_var %device %relaxed %u64_1 923fd4e5da5Sopenharmony_ci)"; 924fd4e5da5Sopenharmony_ci 925fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body)); 926fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 927fd4e5da5Sopenharmony_ci EXPECT_THAT( 928fd4e5da5Sopenharmony_ci getDiagnosticString(), 929fd4e5da5Sopenharmony_ci HasSubstr( 930fd4e5da5Sopenharmony_ci "AtomicStore: 64-bit atomics require the Int64Atomics capability")); 931fd4e5da5Sopenharmony_ci} 932fd4e5da5Sopenharmony_ci 933fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, VK_KHR_shader_atomic_int64Success) { 934fd4e5da5Sopenharmony_ci const std::string body = R"( 935fd4e5da5Sopenharmony_ci%val1 = OpAtomicUMin %u64 %u64_var %device %relaxed %u64_1 936fd4e5da5Sopenharmony_ci%val2 = OpAtomicUMax %u64 %u64_var %device %relaxed %u64_1 937fd4e5da5Sopenharmony_ci%val3 = OpAtomicSMin %u64 %u64_var %device %relaxed %u64_1 938fd4e5da5Sopenharmony_ci%val4 = OpAtomicSMax %u64 %u64_var %device %relaxed %u64_1 939fd4e5da5Sopenharmony_ci%val5 = OpAtomicAnd %u64 %u64_var %device %relaxed %u64_1 940fd4e5da5Sopenharmony_ci%val6 = OpAtomicOr %u64 %u64_var %device %relaxed %u64_1 941fd4e5da5Sopenharmony_ci%val7 = OpAtomicXor %u64 %u64_var %device %relaxed %u64_1 942fd4e5da5Sopenharmony_ci%val8 = OpAtomicIAdd %u64 %u64_var %device %relaxed %u64_1 943fd4e5da5Sopenharmony_ci%val9 = OpAtomicExchange %u64 %u64_var %device %relaxed %u64_1 944fd4e5da5Sopenharmony_ci%val10 = OpAtomicCompareExchange %u64 %u64_var %device %relaxed %relaxed %u64_1 %u64_1 945fd4e5da5Sopenharmony_ci 946fd4e5da5Sopenharmony_ci%val11 = OpAtomicUMin %s64 %s64_var %device %relaxed %s64_1 947fd4e5da5Sopenharmony_ci%val12 = OpAtomicUMax %s64 %s64_var %device %relaxed %s64_1 948fd4e5da5Sopenharmony_ci%val13 = OpAtomicSMin %s64 %s64_var %device %relaxed %s64_1 949fd4e5da5Sopenharmony_ci%val14 = OpAtomicSMax %s64 %s64_var %device %relaxed %s64_1 950fd4e5da5Sopenharmony_ci%val15 = OpAtomicAnd %s64 %s64_var %device %relaxed %s64_1 951fd4e5da5Sopenharmony_ci%val16 = OpAtomicOr %s64 %s64_var %device %relaxed %s64_1 952fd4e5da5Sopenharmony_ci%val17 = OpAtomicXor %s64 %s64_var %device %relaxed %s64_1 953fd4e5da5Sopenharmony_ci%val18 = OpAtomicIAdd %s64 %s64_var %device %relaxed %s64_1 954fd4e5da5Sopenharmony_ci%val19 = OpAtomicExchange %s64 %s64_var %device %relaxed %s64_1 955fd4e5da5Sopenharmony_ci%val20 = OpAtomicCompareExchange %s64 %s64_var %device %relaxed %relaxed %s64_1 %s64_1 956fd4e5da5Sopenharmony_ci 957fd4e5da5Sopenharmony_ci%val21 = OpAtomicLoad %u64 %u64_var %device %relaxed 958fd4e5da5Sopenharmony_ci%val22 = OpAtomicLoad %s64 %s64_var %device %relaxed 959fd4e5da5Sopenharmony_ci 960fd4e5da5Sopenharmony_ciOpAtomicStore %u64_var %device %relaxed %u64_1 961fd4e5da5Sopenharmony_ciOpAtomicStore %s64_var %device %relaxed %s64_1 962fd4e5da5Sopenharmony_ci)"; 963fd4e5da5Sopenharmony_ci 964fd4e5da5Sopenharmony_ci CompileSuccessfully( 965fd4e5da5Sopenharmony_ci GenerateShaderComputeCode(body, "OpCapability Int64Atomics\n"), 966fd4e5da5Sopenharmony_ci SPV_ENV_VULKAN_1_0); 967fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 968fd4e5da5Sopenharmony_ci} 969fd4e5da5Sopenharmony_ci 970fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, VK_KHR_shader_atomic_int64MissingCapability) { 971fd4e5da5Sopenharmony_ci const std::string body = R"( 972fd4e5da5Sopenharmony_ci%val1 = OpAtomicUMin %u64 %u64_var %device %relaxed %u64_1 973fd4e5da5Sopenharmony_ci)"; 974fd4e5da5Sopenharmony_ci 975fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body), SPV_ENV_VULKAN_1_0); 976fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 977fd4e5da5Sopenharmony_ci EXPECT_THAT( 978fd4e5da5Sopenharmony_ci getDiagnosticString(), 979fd4e5da5Sopenharmony_ci HasSubstr( 980fd4e5da5Sopenharmony_ci "AtomicUMin: 64-bit atomics require the Int64Atomics capability")); 981fd4e5da5Sopenharmony_ci} 982fd4e5da5Sopenharmony_ci 983fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicLoadWrongResultType) { 984fd4e5da5Sopenharmony_ci const std::string body = R"( 985fd4e5da5Sopenharmony_ci%val1 = OpAtomicLoad %f32vec4 %f32vec4_var %device %relaxed 986fd4e5da5Sopenharmony_ci)"; 987fd4e5da5Sopenharmony_ci 988fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body)); 989fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 990fd4e5da5Sopenharmony_ci EXPECT_THAT( 991fd4e5da5Sopenharmony_ci getDiagnosticString(), 992fd4e5da5Sopenharmony_ci HasSubstr("AtomicLoad: " 993fd4e5da5Sopenharmony_ci "expected Result Type to be integer or float scalar type")); 994fd4e5da5Sopenharmony_ci} 995fd4e5da5Sopenharmony_ci 996fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicLoadWrongPointerType) { 997fd4e5da5Sopenharmony_ci const std::string body = R"( 998fd4e5da5Sopenharmony_ci%val1 = OpAtomicLoad %f32 %f32_ptr %device %relaxed 999fd4e5da5Sopenharmony_ci)"; 1000fd4e5da5Sopenharmony_ci 1001fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body)); 1002fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); 1003fd4e5da5Sopenharmony_ci EXPECT_THAT( 1004fd4e5da5Sopenharmony_ci getDiagnosticString(), 1005fd4e5da5Sopenharmony_ci HasSubstr("Operand '27[%_ptr_Workgroup_float]' cannot be a type")); 1006fd4e5da5Sopenharmony_ci} 1007fd4e5da5Sopenharmony_ci 1008fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicLoadWrongPointerDataType) { 1009fd4e5da5Sopenharmony_ci const std::string body = R"( 1010fd4e5da5Sopenharmony_ci%val1 = OpAtomicLoad %u32 %f32_var %device %relaxed 1011fd4e5da5Sopenharmony_ci)"; 1012fd4e5da5Sopenharmony_ci 1013fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body)); 1014fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1015fd4e5da5Sopenharmony_ci EXPECT_THAT( 1016fd4e5da5Sopenharmony_ci getDiagnosticString(), 1017fd4e5da5Sopenharmony_ci HasSubstr("AtomicLoad: " 1018fd4e5da5Sopenharmony_ci "expected Pointer to point to a value of type Result Type")); 1019fd4e5da5Sopenharmony_ci} 1020fd4e5da5Sopenharmony_ci 1021fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicLoadWrongScopeType) { 1022fd4e5da5Sopenharmony_ci const std::string body = R"( 1023fd4e5da5Sopenharmony_ci%val1 = OpAtomicLoad %f32 %f32_var %f32_1 %relaxed 1024fd4e5da5Sopenharmony_ci)"; 1025fd4e5da5Sopenharmony_ci 1026fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body)); 1027fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1028fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1029fd4e5da5Sopenharmony_ci HasSubstr("AtomicLoad: expected scope to be a 32-bit int")); 1030fd4e5da5Sopenharmony_ci} 1031fd4e5da5Sopenharmony_ci 1032fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicLoadWrongMemorySemanticsType) { 1033fd4e5da5Sopenharmony_ci const std::string body = R"( 1034fd4e5da5Sopenharmony_ci%val1 = OpAtomicLoad %f32 %f32_var %device %u64_1 1035fd4e5da5Sopenharmony_ci)"; 1036fd4e5da5Sopenharmony_ci 1037fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body)); 1038fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1039fd4e5da5Sopenharmony_ci EXPECT_THAT( 1040fd4e5da5Sopenharmony_ci getDiagnosticString(), 1041fd4e5da5Sopenharmony_ci HasSubstr("AtomicLoad: expected Memory Semantics to be a 32-bit int")); 1042fd4e5da5Sopenharmony_ci} 1043fd4e5da5Sopenharmony_ci 1044fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicStoreKernelSuccess) { 1045fd4e5da5Sopenharmony_ci const std::string body = R"( 1046fd4e5da5Sopenharmony_ciOpAtomicStore %f32_var %device %relaxed %f32_1 1047fd4e5da5Sopenharmony_ciOpAtomicStore %u32_var %subgroup %release %u32_1 1048fd4e5da5Sopenharmony_ci)"; 1049fd4e5da5Sopenharmony_ci 1050fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body)); 1051fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); 1052fd4e5da5Sopenharmony_ci} 1053fd4e5da5Sopenharmony_ci 1054fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicStoreShaderSuccess) { 1055fd4e5da5Sopenharmony_ci const std::string body = R"( 1056fd4e5da5Sopenharmony_ciOpAtomicStore %u32_var %device %release %u32_1 1057fd4e5da5Sopenharmony_ciOpAtomicStore %u32_var %subgroup %sequentially_consistent %u32_1 1058fd4e5da5Sopenharmony_ci)"; 1059fd4e5da5Sopenharmony_ci 1060fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 1061fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); 1062fd4e5da5Sopenharmony_ci} 1063fd4e5da5Sopenharmony_ci 1064fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicStoreVulkanSuccess) { 1065fd4e5da5Sopenharmony_ci const std::string body = R"( 1066fd4e5da5Sopenharmony_ciOpAtomicStore %u32_var %device %release %u32_1 1067fd4e5da5Sopenharmony_ciOpAtomicStore %u32_var %invocation %relaxed %u32_1 1068fd4e5da5Sopenharmony_ci)"; 1069fd4e5da5Sopenharmony_ci 1070fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderComputeCode(body), SPV_ENV_VULKAN_1_0); 1071fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 1072fd4e5da5Sopenharmony_ci} 1073fd4e5da5Sopenharmony_ci 1074fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicStoreVulkanAcquire) { 1075fd4e5da5Sopenharmony_ci const std::string body = R"( 1076fd4e5da5Sopenharmony_ciOpAtomicStore %u32_var %device %acquire %u32_1 1077fd4e5da5Sopenharmony_ci)"; 1078fd4e5da5Sopenharmony_ci 1079fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body), SPV_ENV_VULKAN_1_0); 1080fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 1081fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1082fd4e5da5Sopenharmony_ci AnyVUID("VUID-StandaloneSpirv-OpAtomicStore-04730")); 1083fd4e5da5Sopenharmony_ci EXPECT_THAT( 1084fd4e5da5Sopenharmony_ci getDiagnosticString(), 1085fd4e5da5Sopenharmony_ci HasSubstr("Vulkan spec disallows OpAtomicStore with Memory Semantics " 1086fd4e5da5Sopenharmony_ci "Acquire, AcquireRelease and SequentiallyConsistent")); 1087fd4e5da5Sopenharmony_ci} 1088fd4e5da5Sopenharmony_ci 1089fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicStoreVulkanAcquireRelease) { 1090fd4e5da5Sopenharmony_ci const std::string body = R"( 1091fd4e5da5Sopenharmony_ciOpAtomicStore %u32_var %device %acquire_release %u32_1 1092fd4e5da5Sopenharmony_ci)"; 1093fd4e5da5Sopenharmony_ci 1094fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body), SPV_ENV_VULKAN_1_0); 1095fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 1096fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1097fd4e5da5Sopenharmony_ci AnyVUID("VUID-StandaloneSpirv-OpAtomicStore-04730")); 1098fd4e5da5Sopenharmony_ci EXPECT_THAT( 1099fd4e5da5Sopenharmony_ci getDiagnosticString(), 1100fd4e5da5Sopenharmony_ci HasSubstr("Vulkan spec disallows OpAtomicStore with Memory Semantics " 1101fd4e5da5Sopenharmony_ci "Acquire, AcquireRelease and SequentiallyConsistent")); 1102fd4e5da5Sopenharmony_ci} 1103fd4e5da5Sopenharmony_ci 1104fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicStoreVulkanSequentiallyConsistent) { 1105fd4e5da5Sopenharmony_ci const std::string body = R"( 1106fd4e5da5Sopenharmony_ciOpAtomicStore %u32_var %device %sequentially_consistent %u32_1 1107fd4e5da5Sopenharmony_ci)"; 1108fd4e5da5Sopenharmony_ci 1109fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body), SPV_ENV_VULKAN_1_0); 1110fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 1111fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1112fd4e5da5Sopenharmony_ci AnyVUID("VUID-StandaloneSpirv-OpAtomicStore-04730")); 1113fd4e5da5Sopenharmony_ci EXPECT_THAT( 1114fd4e5da5Sopenharmony_ci getDiagnosticString(), 1115fd4e5da5Sopenharmony_ci HasSubstr("Vulkan spec disallows OpAtomicStore with Memory Semantics " 1116fd4e5da5Sopenharmony_ci "Acquire, AcquireRelease and SequentiallyConsistent")); 1117fd4e5da5Sopenharmony_ci} 1118fd4e5da5Sopenharmony_ci 1119fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicStoreVulkanInvocationSemantics) { 1120fd4e5da5Sopenharmony_ci const std::string body = R"( 1121fd4e5da5Sopenharmony_ciOpAtomicStore %u32_var %invocation %acquire %u32_1 1122fd4e5da5Sopenharmony_ci)"; 1123fd4e5da5Sopenharmony_ci 1124fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body), SPV_ENV_VULKAN_1_0); 1125fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 1126fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1127fd4e5da5Sopenharmony_ci AnyVUID("VUID-StandaloneSpirv-None-04641")); 1128fd4e5da5Sopenharmony_ci EXPECT_THAT( 1129fd4e5da5Sopenharmony_ci getDiagnosticString(), 1130fd4e5da5Sopenharmony_ci HasSubstr("AtomicStore: Vulkan specification requires Memory Semantics " 1131fd4e5da5Sopenharmony_ci "to be None if used with Invocation Memory Scope")); 1132fd4e5da5Sopenharmony_ci} 1133fd4e5da5Sopenharmony_ci 1134fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicStoreWrongPointerType) { 1135fd4e5da5Sopenharmony_ci const std::string body = R"( 1136fd4e5da5Sopenharmony_ciOpAtomicStore %f32_1 %device %relaxed %f32_1 1137fd4e5da5Sopenharmony_ci)"; 1138fd4e5da5Sopenharmony_ci 1139fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body)); 1140fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1141fd4e5da5Sopenharmony_ci EXPECT_THAT( 1142fd4e5da5Sopenharmony_ci getDiagnosticString(), 1143fd4e5da5Sopenharmony_ci HasSubstr("AtomicStore: expected Pointer to be of type OpTypePointer")); 1144fd4e5da5Sopenharmony_ci} 1145fd4e5da5Sopenharmony_ci 1146fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicStoreWrongPointerDataType) { 1147fd4e5da5Sopenharmony_ci const std::string body = R"( 1148fd4e5da5Sopenharmony_ciOpAtomicStore %f32vec4_var %device %relaxed %f32_1 1149fd4e5da5Sopenharmony_ci)"; 1150fd4e5da5Sopenharmony_ci 1151fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body)); 1152fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1153fd4e5da5Sopenharmony_ci EXPECT_THAT( 1154fd4e5da5Sopenharmony_ci getDiagnosticString(), 1155fd4e5da5Sopenharmony_ci HasSubstr( 1156fd4e5da5Sopenharmony_ci "AtomicStore: " 1157fd4e5da5Sopenharmony_ci "expected Pointer to be a pointer to integer or float scalar type")); 1158fd4e5da5Sopenharmony_ci} 1159fd4e5da5Sopenharmony_ci 1160fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicStoreWrongPointerStorageTypeForOpenCL) { 1161fd4e5da5Sopenharmony_ci const std::string body = R"( 1162fd4e5da5Sopenharmony_ciOpAtomicStore %f32_im_var %device %relaxed %f32_1 1163fd4e5da5Sopenharmony_ci)"; 1164fd4e5da5Sopenharmony_ci 1165fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body)); 1166fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_OPENCL_1_2)); 1167fd4e5da5Sopenharmony_ci EXPECT_THAT( 1168fd4e5da5Sopenharmony_ci getDiagnosticString(), 1169fd4e5da5Sopenharmony_ci HasSubstr("AtomicStore: storage class must be Function, Workgroup, " 1170fd4e5da5Sopenharmony_ci "CrossWorkGroup or Generic in the OpenCL environment.")); 1171fd4e5da5Sopenharmony_ci} 1172fd4e5da5Sopenharmony_ci 1173fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicStoreWrongPointerStorageType) { 1174fd4e5da5Sopenharmony_ci const std::string body = R"( 1175fd4e5da5Sopenharmony_ciOpAtomicStore %f32_uc_var %device %relaxed %f32_1 1176fd4e5da5Sopenharmony_ci)"; 1177fd4e5da5Sopenharmony_ci 1178fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body)); 1179fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1180fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1181fd4e5da5Sopenharmony_ci HasSubstr("AtomicStore: storage class forbidden by universal " 1182fd4e5da5Sopenharmony_ci "validation rules.")); 1183fd4e5da5Sopenharmony_ci} 1184fd4e5da5Sopenharmony_ci 1185fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicStoreWrongScopeType) { 1186fd4e5da5Sopenharmony_ci const std::string body = R"( 1187fd4e5da5Sopenharmony_ciOpAtomicStore %f32_var %f32_1 %relaxed %f32_1 1188fd4e5da5Sopenharmony_ci)"; 1189fd4e5da5Sopenharmony_ci 1190fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body)); 1191fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1192fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1193fd4e5da5Sopenharmony_ci HasSubstr("AtomicStore: expected scope to be a 32-bit int\n " 1194fd4e5da5Sopenharmony_ci "OpAtomicStore %28 %float_1 %uint_0_1 %float_1\n")); 1195fd4e5da5Sopenharmony_ci} 1196fd4e5da5Sopenharmony_ci 1197fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicStoreWrongMemorySemanticsType) { 1198fd4e5da5Sopenharmony_ci const std::string body = R"( 1199fd4e5da5Sopenharmony_ciOpAtomicStore %f32_var %device %f32_1 %f32_1 1200fd4e5da5Sopenharmony_ci)"; 1201fd4e5da5Sopenharmony_ci 1202fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body)); 1203fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1204fd4e5da5Sopenharmony_ci EXPECT_THAT( 1205fd4e5da5Sopenharmony_ci getDiagnosticString(), 1206fd4e5da5Sopenharmony_ci HasSubstr("AtomicStore: expected Memory Semantics to be a 32-bit int")); 1207fd4e5da5Sopenharmony_ci} 1208fd4e5da5Sopenharmony_ci 1209fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicStoreWrongValueType) { 1210fd4e5da5Sopenharmony_ci const std::string body = R"( 1211fd4e5da5Sopenharmony_ciOpAtomicStore %f32_var %device %relaxed %u32_1 1212fd4e5da5Sopenharmony_ci)"; 1213fd4e5da5Sopenharmony_ci 1214fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body)); 1215fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1216fd4e5da5Sopenharmony_ci EXPECT_THAT( 1217fd4e5da5Sopenharmony_ci getDiagnosticString(), 1218fd4e5da5Sopenharmony_ci HasSubstr("AtomicStore: " 1219fd4e5da5Sopenharmony_ci "expected Value type and the type pointed to by Pointer to " 1220fd4e5da5Sopenharmony_ci "be the same")); 1221fd4e5da5Sopenharmony_ci} 1222fd4e5da5Sopenharmony_ci 1223fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicExchangeShaderSuccess) { 1224fd4e5da5Sopenharmony_ci const std::string body = R"( 1225fd4e5da5Sopenharmony_ciOpAtomicStore %u32_var %device %relaxed %u32_1 1226fd4e5da5Sopenharmony_ci%val2 = OpAtomicExchange %u32 %u32_var %device %relaxed %u32_0 1227fd4e5da5Sopenharmony_ci)"; 1228fd4e5da5Sopenharmony_ci 1229fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 1230fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); 1231fd4e5da5Sopenharmony_ci} 1232fd4e5da5Sopenharmony_ci 1233fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicExchangeKernelSuccess) { 1234fd4e5da5Sopenharmony_ci const std::string body = R"( 1235fd4e5da5Sopenharmony_ciOpAtomicStore %f32_var %device %relaxed %f32_1 1236fd4e5da5Sopenharmony_ci%val2 = OpAtomicExchange %f32 %f32_var %device %relaxed %f32_0 1237fd4e5da5Sopenharmony_ciOpAtomicStore %u32_var %device %relaxed %u32_1 1238fd4e5da5Sopenharmony_ci%val4 = OpAtomicExchange %u32 %u32_var %device %relaxed %u32_0 1239fd4e5da5Sopenharmony_ci)"; 1240fd4e5da5Sopenharmony_ci 1241fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body)); 1242fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); 1243fd4e5da5Sopenharmony_ci} 1244fd4e5da5Sopenharmony_ci 1245fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicExchangeShaderFloat) { 1246fd4e5da5Sopenharmony_ci const std::string body = R"( 1247fd4e5da5Sopenharmony_ciOpAtomicStore %f32_var %device %relaxed %f32_1 1248fd4e5da5Sopenharmony_ci%val2 = OpAtomicExchange %f32 %f32_var %device %relaxed %f32_0 1249fd4e5da5Sopenharmony_ci)"; 1250fd4e5da5Sopenharmony_ci 1251fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 1252fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); 1253fd4e5da5Sopenharmony_ci} 1254fd4e5da5Sopenharmony_ci 1255fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicExchangeWrongResultType) { 1256fd4e5da5Sopenharmony_ci const std::string body = R"( 1257fd4e5da5Sopenharmony_ciOpStore %f32vec4_var %f32vec4_0000 1258fd4e5da5Sopenharmony_ci%val2 = OpAtomicExchange %f32vec4 %f32vec4_var %device %relaxed %f32vec4_0000 1259fd4e5da5Sopenharmony_ci)"; 1260fd4e5da5Sopenharmony_ci 1261fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body)); 1262fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1263fd4e5da5Sopenharmony_ci EXPECT_THAT( 1264fd4e5da5Sopenharmony_ci getDiagnosticString(), 1265fd4e5da5Sopenharmony_ci HasSubstr("AtomicExchange: " 1266fd4e5da5Sopenharmony_ci "expected Result Type to be integer or float scalar type")); 1267fd4e5da5Sopenharmony_ci} 1268fd4e5da5Sopenharmony_ci 1269fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicExchangeWrongPointerType) { 1270fd4e5da5Sopenharmony_ci const std::string body = R"( 1271fd4e5da5Sopenharmony_ci%val2 = OpAtomicExchange %f32 %f32vec4_ptr %device %relaxed %f32vec4_0000 1272fd4e5da5Sopenharmony_ci)"; 1273fd4e5da5Sopenharmony_ci 1274fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body)); 1275fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); 1276fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1277fd4e5da5Sopenharmony_ci HasSubstr("Operand '33[%_ptr_Workgroup_v4float]' cannot be a " 1278fd4e5da5Sopenharmony_ci "type")); 1279fd4e5da5Sopenharmony_ci} 1280fd4e5da5Sopenharmony_ci 1281fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicExchangeWrongPointerDataType) { 1282fd4e5da5Sopenharmony_ci const std::string body = R"( 1283fd4e5da5Sopenharmony_ciOpStore %f32vec4_var %f32vec4_0000 1284fd4e5da5Sopenharmony_ci%val2 = OpAtomicExchange %f32 %f32vec4_var %device %relaxed %f32vec4_0000 1285fd4e5da5Sopenharmony_ci)"; 1286fd4e5da5Sopenharmony_ci 1287fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body)); 1288fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1289fd4e5da5Sopenharmony_ci EXPECT_THAT( 1290fd4e5da5Sopenharmony_ci getDiagnosticString(), 1291fd4e5da5Sopenharmony_ci HasSubstr("AtomicExchange: " 1292fd4e5da5Sopenharmony_ci "expected Pointer to point to a value of type Result Type")); 1293fd4e5da5Sopenharmony_ci} 1294fd4e5da5Sopenharmony_ci 1295fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicExchangeWrongScopeType) { 1296fd4e5da5Sopenharmony_ci const std::string body = R"( 1297fd4e5da5Sopenharmony_ciOpAtomicStore %f32_var %device %relaxed %f32_1 1298fd4e5da5Sopenharmony_ci%val2 = OpAtomicExchange %f32 %f32_var %f32_1 %relaxed %f32_0 1299fd4e5da5Sopenharmony_ci)"; 1300fd4e5da5Sopenharmony_ci 1301fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body)); 1302fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1303fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1304fd4e5da5Sopenharmony_ci HasSubstr("AtomicExchange: expected scope to be a 32-bit int")); 1305fd4e5da5Sopenharmony_ci} 1306fd4e5da5Sopenharmony_ci 1307fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicExchangeWrongMemorySemanticsType) { 1308fd4e5da5Sopenharmony_ci const std::string body = R"( 1309fd4e5da5Sopenharmony_ciOpAtomicStore %f32_var %device %relaxed %f32_1 1310fd4e5da5Sopenharmony_ci%val2 = OpAtomicExchange %f32 %f32_var %device %f32_1 %f32_0 1311fd4e5da5Sopenharmony_ci)"; 1312fd4e5da5Sopenharmony_ci 1313fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body)); 1314fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1315fd4e5da5Sopenharmony_ci EXPECT_THAT( 1316fd4e5da5Sopenharmony_ci getDiagnosticString(), 1317fd4e5da5Sopenharmony_ci HasSubstr( 1318fd4e5da5Sopenharmony_ci "AtomicExchange: expected Memory Semantics to be a 32-bit int")); 1319fd4e5da5Sopenharmony_ci} 1320fd4e5da5Sopenharmony_ci 1321fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicExchangeWrongValueType) { 1322fd4e5da5Sopenharmony_ci const std::string body = R"( 1323fd4e5da5Sopenharmony_ciOpAtomicStore %f32_var %device %relaxed %f32_1 1324fd4e5da5Sopenharmony_ci%val2 = OpAtomicExchange %f32 %f32_var %device %relaxed %u32_0 1325fd4e5da5Sopenharmony_ci)"; 1326fd4e5da5Sopenharmony_ci 1327fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body)); 1328fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1329fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1330fd4e5da5Sopenharmony_ci HasSubstr("AtomicExchange: " 1331fd4e5da5Sopenharmony_ci "expected Value to be of type Result Type")); 1332fd4e5da5Sopenharmony_ci} 1333fd4e5da5Sopenharmony_ci 1334fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicExchangeVulkanInvocationSemantics) { 1335fd4e5da5Sopenharmony_ci const std::string body = R"( 1336fd4e5da5Sopenharmony_ciOpAtomicStore %u32_var %invocation %relaxed %u32_1 1337fd4e5da5Sopenharmony_ci%val2 = OpAtomicExchange %u32 %u32_var %invocation %acquire %u32_0 1338fd4e5da5Sopenharmony_ci)"; 1339fd4e5da5Sopenharmony_ci 1340fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body), SPV_ENV_VULKAN_1_0); 1341fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 1342fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1343fd4e5da5Sopenharmony_ci AnyVUID("VUID-StandaloneSpirv-None-04641")); 1344fd4e5da5Sopenharmony_ci EXPECT_THAT( 1345fd4e5da5Sopenharmony_ci getDiagnosticString(), 1346fd4e5da5Sopenharmony_ci HasSubstr("AtomicExchange: Vulkan specification requires Memory " 1347fd4e5da5Sopenharmony_ci "Semantics to be None if used with Invocation Memory Scope")); 1348fd4e5da5Sopenharmony_ci} 1349fd4e5da5Sopenharmony_ci 1350fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicCompareExchangeShaderSuccess) { 1351fd4e5da5Sopenharmony_ci const std::string body = R"( 1352fd4e5da5Sopenharmony_ciOpAtomicStore %u32_var %device %relaxed %u32_1 1353fd4e5da5Sopenharmony_ci%val2 = OpAtomicCompareExchange %u32 %u32_var %device %relaxed %relaxed %u32_0 %u32_0 1354fd4e5da5Sopenharmony_ci)"; 1355fd4e5da5Sopenharmony_ci 1356fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 1357fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); 1358fd4e5da5Sopenharmony_ci} 1359fd4e5da5Sopenharmony_ci 1360fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicCompareExchangeKernelSuccess) { 1361fd4e5da5Sopenharmony_ci const std::string body = R"( 1362fd4e5da5Sopenharmony_ciOpAtomicStore %u32_var %device %relaxed %u32_1 1363fd4e5da5Sopenharmony_ci%val2 = OpAtomicCompareExchange %u32 %u32_var %device %relaxed %relaxed %u32_0 %u32_0 1364fd4e5da5Sopenharmony_ci)"; 1365fd4e5da5Sopenharmony_ci 1366fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body)); 1367fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); 1368fd4e5da5Sopenharmony_ci} 1369fd4e5da5Sopenharmony_ci 1370fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicCompareExchangeShaderFloat) { 1371fd4e5da5Sopenharmony_ci const std::string body = R"( 1372fd4e5da5Sopenharmony_ciOpAtomicStore %f32_var %device %relaxed %f32_1 1373fd4e5da5Sopenharmony_ci%val1 = OpAtomicCompareExchange %f32 %f32_var %device %relaxed %relaxed %f32_0 %f32_1 1374fd4e5da5Sopenharmony_ci)"; 1375fd4e5da5Sopenharmony_ci 1376fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 1377fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1378fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1379fd4e5da5Sopenharmony_ci HasSubstr("AtomicCompareExchange: " 1380fd4e5da5Sopenharmony_ci "expected Result Type to be integer scalar type")); 1381fd4e5da5Sopenharmony_ci} 1382fd4e5da5Sopenharmony_ci 1383fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicCompareExchangeWrongResultType) { 1384fd4e5da5Sopenharmony_ci const std::string body = R"( 1385fd4e5da5Sopenharmony_ciOpStore %f32vec4_var %f32vec4_0000 1386fd4e5da5Sopenharmony_ci%val2 = OpAtomicCompareExchange %f32vec4 %f32vec4_var %device %relaxed %relaxed %f32vec4_0000 %f32vec4_0000 1387fd4e5da5Sopenharmony_ci)"; 1388fd4e5da5Sopenharmony_ci 1389fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body)); 1390fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1391fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1392fd4e5da5Sopenharmony_ci HasSubstr("AtomicCompareExchange: " 1393fd4e5da5Sopenharmony_ci "expected Result Type to be integer scalar type")); 1394fd4e5da5Sopenharmony_ci} 1395fd4e5da5Sopenharmony_ci 1396fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicCompareExchangeWrongPointerType) { 1397fd4e5da5Sopenharmony_ci const std::string body = R"( 1398fd4e5da5Sopenharmony_ci%val2 = OpAtomicCompareExchange %f32 %f32vec4_ptr %device %relaxed %relaxed %f32vec4_0000 %f32vec4_0000 1399fd4e5da5Sopenharmony_ci)"; 1400fd4e5da5Sopenharmony_ci 1401fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body)); 1402fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); 1403fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1404fd4e5da5Sopenharmony_ci HasSubstr("Operand '33[%_ptr_Workgroup_v4float]' cannot be a " 1405fd4e5da5Sopenharmony_ci "type")); 1406fd4e5da5Sopenharmony_ci} 1407fd4e5da5Sopenharmony_ci 1408fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicCompareExchangeWrongPointerDataType) { 1409fd4e5da5Sopenharmony_ci const std::string body = R"( 1410fd4e5da5Sopenharmony_ciOpStore %f32vec4_var %f32vec4_0000 1411fd4e5da5Sopenharmony_ci%val2 = OpAtomicCompareExchange %u32 %f32vec4_var %device %relaxed %relaxed %u32_0 %u32_0 1412fd4e5da5Sopenharmony_ci)"; 1413fd4e5da5Sopenharmony_ci 1414fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body)); 1415fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1416fd4e5da5Sopenharmony_ci EXPECT_THAT( 1417fd4e5da5Sopenharmony_ci getDiagnosticString(), 1418fd4e5da5Sopenharmony_ci HasSubstr("AtomicCompareExchange: " 1419fd4e5da5Sopenharmony_ci "expected Pointer to point to a value of type Result Type")); 1420fd4e5da5Sopenharmony_ci} 1421fd4e5da5Sopenharmony_ci 1422fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicCompareExchangeWrongScopeType) { 1423fd4e5da5Sopenharmony_ci const std::string body = R"( 1424fd4e5da5Sopenharmony_ciOpAtomicStore %u64_var %device %relaxed %u64_1 1425fd4e5da5Sopenharmony_ci%val2 = OpAtomicCompareExchange %u64 %u64_var %u64_1 %relaxed %relaxed %u32_0 %u32_0 1426fd4e5da5Sopenharmony_ci)"; 1427fd4e5da5Sopenharmony_ci 1428fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body, "OpCapability Int64Atomics\n")); 1429fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1430fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1431fd4e5da5Sopenharmony_ci HasSubstr("AtomicCompareExchange: expected scope to be a 32-bit " 1432fd4e5da5Sopenharmony_ci "int")); 1433fd4e5da5Sopenharmony_ci} 1434fd4e5da5Sopenharmony_ci 1435fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicCompareExchangeWrongMemorySemanticsType1) { 1436fd4e5da5Sopenharmony_ci const std::string body = R"( 1437fd4e5da5Sopenharmony_ciOpAtomicStore %u32_var %device %relaxed %u32_1 1438fd4e5da5Sopenharmony_ci%val2 = OpAtomicCompareExchange %u32 %u32_var %device %f32_1 %relaxed %u32_0 %u32_0 1439fd4e5da5Sopenharmony_ci)"; 1440fd4e5da5Sopenharmony_ci 1441fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body)); 1442fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1443fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1444fd4e5da5Sopenharmony_ci HasSubstr("AtomicCompareExchange: expected Memory Semantics to " 1445fd4e5da5Sopenharmony_ci "be a 32-bit int")); 1446fd4e5da5Sopenharmony_ci} 1447fd4e5da5Sopenharmony_ci 1448fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicCompareExchangeWrongMemorySemanticsType2) { 1449fd4e5da5Sopenharmony_ci const std::string body = R"( 1450fd4e5da5Sopenharmony_ciOpAtomicStore %u32_var %device %relaxed %u32_1 1451fd4e5da5Sopenharmony_ci%val2 = OpAtomicCompareExchange %u32 %u32_var %device %relaxed %f32_1 %u32_0 %u32_0 1452fd4e5da5Sopenharmony_ci)"; 1453fd4e5da5Sopenharmony_ci 1454fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body)); 1455fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1456fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1457fd4e5da5Sopenharmony_ci HasSubstr("AtomicCompareExchange: expected Memory Semantics to " 1458fd4e5da5Sopenharmony_ci "be a 32-bit int")); 1459fd4e5da5Sopenharmony_ci} 1460fd4e5da5Sopenharmony_ci 1461fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicCompareExchangeUnequalRelease) { 1462fd4e5da5Sopenharmony_ci const std::string body = R"( 1463fd4e5da5Sopenharmony_ciOpAtomicStore %u32_var %device %relaxed %u32_1 1464fd4e5da5Sopenharmony_ci%val2 = OpAtomicCompareExchange %u32 %u32_var %device %relaxed %release %u32_0 %u32_0 1465fd4e5da5Sopenharmony_ci)"; 1466fd4e5da5Sopenharmony_ci 1467fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body)); 1468fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1469fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1470fd4e5da5Sopenharmony_ci HasSubstr("AtomicCompareExchange: Memory Semantics Release and " 1471fd4e5da5Sopenharmony_ci "AcquireRelease cannot be used for operand Unequal")); 1472fd4e5da5Sopenharmony_ci} 1473fd4e5da5Sopenharmony_ci 1474fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicCompareExchangeWrongValueType) { 1475fd4e5da5Sopenharmony_ci const std::string body = R"( 1476fd4e5da5Sopenharmony_ciOpAtomicStore %u32_var %device %relaxed %u32_1 1477fd4e5da5Sopenharmony_ci%val2 = OpAtomicCompareExchange %u32 %u32_var %device %relaxed %relaxed %f32_1 %u32_0 1478fd4e5da5Sopenharmony_ci)"; 1479fd4e5da5Sopenharmony_ci 1480fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body)); 1481fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1482fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1483fd4e5da5Sopenharmony_ci HasSubstr("AtomicCompareExchange: " 1484fd4e5da5Sopenharmony_ci "expected Value to be of type Result Type")); 1485fd4e5da5Sopenharmony_ci} 1486fd4e5da5Sopenharmony_ci 1487fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicCompareExchangeWrongComparatorType) { 1488fd4e5da5Sopenharmony_ci const std::string body = R"( 1489fd4e5da5Sopenharmony_ciOpAtomicStore %u32_var %device %relaxed %u32_1 1490fd4e5da5Sopenharmony_ci%val2 = OpAtomicCompareExchange %u32 %u32_var %device %relaxed %relaxed %u32_0 %f32_0 1491fd4e5da5Sopenharmony_ci)"; 1492fd4e5da5Sopenharmony_ci 1493fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body)); 1494fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1495fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1496fd4e5da5Sopenharmony_ci HasSubstr("AtomicCompareExchange: " 1497fd4e5da5Sopenharmony_ci "expected Comparator to be of type Result Type")); 1498fd4e5da5Sopenharmony_ci} 1499fd4e5da5Sopenharmony_ci 1500fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicCompareExchangeWeakSuccess) { 1501fd4e5da5Sopenharmony_ci const std::string body = R"( 1502fd4e5da5Sopenharmony_ciOpAtomicStore %u32_var %device %relaxed %u32_1 1503fd4e5da5Sopenharmony_ci%val4 = OpAtomicCompareExchangeWeak %u32 %u32_var %device %relaxed %relaxed %u32_0 %u32_0 1504fd4e5da5Sopenharmony_ci)"; 1505fd4e5da5Sopenharmony_ci 1506fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body)); 1507fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); 1508fd4e5da5Sopenharmony_ci} 1509fd4e5da5Sopenharmony_ci 1510fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicCompareExchangeWeakWrongResultType) { 1511fd4e5da5Sopenharmony_ci const std::string body = R"( 1512fd4e5da5Sopenharmony_ciOpAtomicStore %f32_var %device %relaxed %f32_1 1513fd4e5da5Sopenharmony_ci%val2 = OpAtomicCompareExchangeWeak %f32 %f32_var %device %relaxed %relaxed %f32_0 %f32_1 1514fd4e5da5Sopenharmony_ci)"; 1515fd4e5da5Sopenharmony_ci 1516fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body)); 1517fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1518fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1519fd4e5da5Sopenharmony_ci HasSubstr("AtomicCompareExchangeWeak: " 1520fd4e5da5Sopenharmony_ci "expected Result Type to be integer scalar type")); 1521fd4e5da5Sopenharmony_ci} 1522fd4e5da5Sopenharmony_ci 1523fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicCompareExchangeVulkanInvocationSemanticsEqual) { 1524fd4e5da5Sopenharmony_ci const std::string body = R"( 1525fd4e5da5Sopenharmony_ciOpAtomicStore %u32_var %device %relaxed %u32_1 1526fd4e5da5Sopenharmony_ci%val2 = OpAtomicCompareExchange %u32 %u32_var %invocation %release %relaxed %u32_0 %u32_0 1527fd4e5da5Sopenharmony_ci)"; 1528fd4e5da5Sopenharmony_ci 1529fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body), SPV_ENV_VULKAN_1_0); 1530fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 1531fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1532fd4e5da5Sopenharmony_ci AnyVUID("VUID-StandaloneSpirv-None-04641")); 1533fd4e5da5Sopenharmony_ci EXPECT_THAT( 1534fd4e5da5Sopenharmony_ci getDiagnosticString(), 1535fd4e5da5Sopenharmony_ci HasSubstr("AtomicCompareExchange: Vulkan specification requires Memory " 1536fd4e5da5Sopenharmony_ci "Semantics to be None if used with Invocation Memory Scope")); 1537fd4e5da5Sopenharmony_ci} 1538fd4e5da5Sopenharmony_ci 1539fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicCompareExchangeVulkanInvocationSemanticsUnequal) { 1540fd4e5da5Sopenharmony_ci const std::string body = R"( 1541fd4e5da5Sopenharmony_ciOpAtomicStore %u32_var %device %relaxed %u32_1 1542fd4e5da5Sopenharmony_ci%val2 = OpAtomicCompareExchange %u32 %u32_var %invocation %relaxed %acquire %u32_0 %u32_0 1543fd4e5da5Sopenharmony_ci)"; 1544fd4e5da5Sopenharmony_ci 1545fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body), SPV_ENV_VULKAN_1_0); 1546fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); 1547fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1548fd4e5da5Sopenharmony_ci AnyVUID("VUID-StandaloneSpirv-None-04641")); 1549fd4e5da5Sopenharmony_ci EXPECT_THAT( 1550fd4e5da5Sopenharmony_ci getDiagnosticString(), 1551fd4e5da5Sopenharmony_ci HasSubstr("AtomicCompareExchange: Vulkan specification requires Memory " 1552fd4e5da5Sopenharmony_ci "Semantics to be None if used with Invocation Memory Scope")); 1553fd4e5da5Sopenharmony_ci} 1554fd4e5da5Sopenharmony_ci 1555fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicArithmeticsSuccess) { 1556fd4e5da5Sopenharmony_ci const std::string body = R"( 1557fd4e5da5Sopenharmony_ciOpAtomicStore %u32_var %device %relaxed %u32_1 1558fd4e5da5Sopenharmony_ci%val1 = OpAtomicIIncrement %u32 %u32_var %device %acquire_release 1559fd4e5da5Sopenharmony_ci%val2 = OpAtomicIDecrement %u32 %u32_var %device %acquire_release 1560fd4e5da5Sopenharmony_ci%val3 = OpAtomicIAdd %u32 %u32_var %device %acquire_release %u32_1 1561fd4e5da5Sopenharmony_ci%val4 = OpAtomicISub %u32 %u32_var %device %acquire_release %u32_1 1562fd4e5da5Sopenharmony_ci%val5 = OpAtomicUMin %u32 %u32_var %device %acquire_release %u32_1 1563fd4e5da5Sopenharmony_ci%val6 = OpAtomicUMax %u32 %u32_var %device %acquire_release %u32_1 1564fd4e5da5Sopenharmony_ci%val7 = OpAtomicSMin %u32 %u32_var %device %sequentially_consistent %u32_1 1565fd4e5da5Sopenharmony_ci%val8 = OpAtomicSMax %u32 %u32_var %device %sequentially_consistent %u32_1 1566fd4e5da5Sopenharmony_ci%val9 = OpAtomicAnd %u32 %u32_var %device %sequentially_consistent %u32_1 1567fd4e5da5Sopenharmony_ci%val10 = OpAtomicOr %u32 %u32_var %device %sequentially_consistent %u32_1 1568fd4e5da5Sopenharmony_ci%val11 = OpAtomicXor %u32 %u32_var %device %sequentially_consistent %u32_1 1569fd4e5da5Sopenharmony_ci)"; 1570fd4e5da5Sopenharmony_ci 1571fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body)); 1572fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); 1573fd4e5da5Sopenharmony_ci} 1574fd4e5da5Sopenharmony_ci 1575fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicFlagsSuccess) { 1576fd4e5da5Sopenharmony_ci const std::string body = R"( 1577fd4e5da5Sopenharmony_ciOpAtomicFlagClear %u32_var %device %release 1578fd4e5da5Sopenharmony_ci%val1 = OpAtomicFlagTestAndSet %bool %u32_var %device %relaxed 1579fd4e5da5Sopenharmony_ci)"; 1580fd4e5da5Sopenharmony_ci 1581fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body)); 1582fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); 1583fd4e5da5Sopenharmony_ci} 1584fd4e5da5Sopenharmony_ci 1585fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicFlagTestAndSetWrongResultType) { 1586fd4e5da5Sopenharmony_ci const std::string body = R"( 1587fd4e5da5Sopenharmony_ci%val1 = OpAtomicFlagTestAndSet %u32 %u32_var %device %relaxed 1588fd4e5da5Sopenharmony_ci)"; 1589fd4e5da5Sopenharmony_ci 1590fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body)); 1591fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1592fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1593fd4e5da5Sopenharmony_ci HasSubstr("AtomicFlagTestAndSet: " 1594fd4e5da5Sopenharmony_ci "expected Result Type to be bool scalar type")); 1595fd4e5da5Sopenharmony_ci} 1596fd4e5da5Sopenharmony_ci 1597fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicFlagTestAndSetNotPointer) { 1598fd4e5da5Sopenharmony_ci const std::string body = R"( 1599fd4e5da5Sopenharmony_ci%val1 = OpAtomicFlagTestAndSet %bool %u32_1 %device %relaxed 1600fd4e5da5Sopenharmony_ci)"; 1601fd4e5da5Sopenharmony_ci 1602fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body)); 1603fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1604fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1605fd4e5da5Sopenharmony_ci HasSubstr("AtomicFlagTestAndSet: " 1606fd4e5da5Sopenharmony_ci "expected Pointer to be of type OpTypePointer")); 1607fd4e5da5Sopenharmony_ci} 1608fd4e5da5Sopenharmony_ci 1609fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicFlagTestAndSetNotIntPointer) { 1610fd4e5da5Sopenharmony_ci const std::string body = R"( 1611fd4e5da5Sopenharmony_ci%val1 = OpAtomicFlagTestAndSet %bool %f32_var %device %relaxed 1612fd4e5da5Sopenharmony_ci)"; 1613fd4e5da5Sopenharmony_ci 1614fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body)); 1615fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1616fd4e5da5Sopenharmony_ci EXPECT_THAT( 1617fd4e5da5Sopenharmony_ci getDiagnosticString(), 1618fd4e5da5Sopenharmony_ci HasSubstr("AtomicFlagTestAndSet: " 1619fd4e5da5Sopenharmony_ci "expected Pointer to point to a value of 32-bit integer type")); 1620fd4e5da5Sopenharmony_ci} 1621fd4e5da5Sopenharmony_ci 1622fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicFlagTestAndSetNotInt32Pointer) { 1623fd4e5da5Sopenharmony_ci const std::string body = R"( 1624fd4e5da5Sopenharmony_ci%val1 = OpAtomicFlagTestAndSet %bool %u64_var %device %relaxed 1625fd4e5da5Sopenharmony_ci)"; 1626fd4e5da5Sopenharmony_ci 1627fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body, "OpCapability Int64Atomics\n")); 1628fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1629fd4e5da5Sopenharmony_ci EXPECT_THAT( 1630fd4e5da5Sopenharmony_ci getDiagnosticString(), 1631fd4e5da5Sopenharmony_ci HasSubstr("AtomicFlagTestAndSet: " 1632fd4e5da5Sopenharmony_ci "expected Pointer to point to a value of 32-bit integer type")); 1633fd4e5da5Sopenharmony_ci} 1634fd4e5da5Sopenharmony_ci 1635fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicFlagTestAndSetWrongScopeType) { 1636fd4e5da5Sopenharmony_ci const std::string body = R"( 1637fd4e5da5Sopenharmony_ci%val1 = OpAtomicFlagTestAndSet %bool %u32_var %u64_1 %relaxed 1638fd4e5da5Sopenharmony_ci)"; 1639fd4e5da5Sopenharmony_ci 1640fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body)); 1641fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1642fd4e5da5Sopenharmony_ci EXPECT_THAT( 1643fd4e5da5Sopenharmony_ci getDiagnosticString(), 1644fd4e5da5Sopenharmony_ci HasSubstr("AtomicFlagTestAndSet: expected scope to be a 32-bit int")); 1645fd4e5da5Sopenharmony_ci} 1646fd4e5da5Sopenharmony_ci 1647fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicFlagTestAndSetWrongMemorySemanticsType) { 1648fd4e5da5Sopenharmony_ci const std::string body = R"( 1649fd4e5da5Sopenharmony_ci%val1 = OpAtomicFlagTestAndSet %bool %u32_var %device %u64_1 1650fd4e5da5Sopenharmony_ci)"; 1651fd4e5da5Sopenharmony_ci 1652fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body)); 1653fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1654fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1655fd4e5da5Sopenharmony_ci HasSubstr("AtomicFlagTestAndSet: " 1656fd4e5da5Sopenharmony_ci "expected Memory Semantics to be a 32-bit int")); 1657fd4e5da5Sopenharmony_ci} 1658fd4e5da5Sopenharmony_ci 1659fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicFlagClearAcquire) { 1660fd4e5da5Sopenharmony_ci const std::string body = R"( 1661fd4e5da5Sopenharmony_ciOpAtomicFlagClear %u32_var %device %acquire 1662fd4e5da5Sopenharmony_ci)"; 1663fd4e5da5Sopenharmony_ci 1664fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body)); 1665fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1666fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1667fd4e5da5Sopenharmony_ci HasSubstr("Memory Semantics Acquire and AcquireRelease cannot be " 1668fd4e5da5Sopenharmony_ci "used with AtomicFlagClear")); 1669fd4e5da5Sopenharmony_ci} 1670fd4e5da5Sopenharmony_ci 1671fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicFlagClearNotPointer) { 1672fd4e5da5Sopenharmony_ci const std::string body = R"( 1673fd4e5da5Sopenharmony_ciOpAtomicFlagClear %u32_1 %device %relaxed 1674fd4e5da5Sopenharmony_ci)"; 1675fd4e5da5Sopenharmony_ci 1676fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body)); 1677fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1678fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1679fd4e5da5Sopenharmony_ci HasSubstr("AtomicFlagClear: " 1680fd4e5da5Sopenharmony_ci "expected Pointer to be of type OpTypePointer")); 1681fd4e5da5Sopenharmony_ci} 1682fd4e5da5Sopenharmony_ci 1683fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicFlagClearNotIntPointer) { 1684fd4e5da5Sopenharmony_ci const std::string body = R"( 1685fd4e5da5Sopenharmony_ciOpAtomicFlagClear %f32_var %device %relaxed 1686fd4e5da5Sopenharmony_ci)"; 1687fd4e5da5Sopenharmony_ci 1688fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body)); 1689fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1690fd4e5da5Sopenharmony_ci EXPECT_THAT( 1691fd4e5da5Sopenharmony_ci getDiagnosticString(), 1692fd4e5da5Sopenharmony_ci HasSubstr("AtomicFlagClear: " 1693fd4e5da5Sopenharmony_ci "expected Pointer to point to a value of 32-bit integer type")); 1694fd4e5da5Sopenharmony_ci} 1695fd4e5da5Sopenharmony_ci 1696fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicFlagClearNotInt32Pointer) { 1697fd4e5da5Sopenharmony_ci const std::string body = R"( 1698fd4e5da5Sopenharmony_ciOpAtomicFlagClear %u64_var %device %relaxed 1699fd4e5da5Sopenharmony_ci)"; 1700fd4e5da5Sopenharmony_ci 1701fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body, "OpCapability Int64Atomics\n")); 1702fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1703fd4e5da5Sopenharmony_ci EXPECT_THAT( 1704fd4e5da5Sopenharmony_ci getDiagnosticString(), 1705fd4e5da5Sopenharmony_ci HasSubstr("AtomicFlagClear: " 1706fd4e5da5Sopenharmony_ci "expected Pointer to point to a value of 32-bit integer type")); 1707fd4e5da5Sopenharmony_ci} 1708fd4e5da5Sopenharmony_ci 1709fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicFlagClearWrongScopeType) { 1710fd4e5da5Sopenharmony_ci const std::string body = R"( 1711fd4e5da5Sopenharmony_ciOpAtomicFlagClear %u32_var %u64_1 %relaxed 1712fd4e5da5Sopenharmony_ci)"; 1713fd4e5da5Sopenharmony_ci 1714fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body)); 1715fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1716fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1717fd4e5da5Sopenharmony_ci HasSubstr("AtomicFlagClear: expected scope to be a 32-bit " 1718fd4e5da5Sopenharmony_ci "int\n OpAtomicFlagClear %30 %ulong_1 %uint_0_1\n")); 1719fd4e5da5Sopenharmony_ci} 1720fd4e5da5Sopenharmony_ci 1721fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicFlagClearWrongMemorySemanticsType) { 1722fd4e5da5Sopenharmony_ci const std::string body = R"( 1723fd4e5da5Sopenharmony_ciOpAtomicFlagClear %u32_var %device %u64_1 1724fd4e5da5Sopenharmony_ci)"; 1725fd4e5da5Sopenharmony_ci 1726fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body)); 1727fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1728fd4e5da5Sopenharmony_ci EXPECT_THAT( 1729fd4e5da5Sopenharmony_ci getDiagnosticString(), 1730fd4e5da5Sopenharmony_ci HasSubstr( 1731fd4e5da5Sopenharmony_ci "AtomicFlagClear: expected Memory Semantics to be a 32-bit int")); 1732fd4e5da5Sopenharmony_ci} 1733fd4e5da5Sopenharmony_ci 1734fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicIIncrementAcquireAndRelease) { 1735fd4e5da5Sopenharmony_ci const std::string body = R"( 1736fd4e5da5Sopenharmony_ciOpAtomicStore %u32_var %device %relaxed %u32_1 1737fd4e5da5Sopenharmony_ci%val1 = OpAtomicIIncrement %u32 %u32_var %device %acquire_and_release 1738fd4e5da5Sopenharmony_ci)"; 1739fd4e5da5Sopenharmony_ci 1740fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body)); 1741fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1742fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1743fd4e5da5Sopenharmony_ci HasSubstr("AtomicIIncrement: Memory Semantics can have at most " 1744fd4e5da5Sopenharmony_ci "one of the following bits set: Acquire, Release, " 1745fd4e5da5Sopenharmony_ci "AcquireRelease or SequentiallyConsistent")); 1746fd4e5da5Sopenharmony_ci} 1747fd4e5da5Sopenharmony_ci 1748fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicUniformMemorySemanticsShader) { 1749fd4e5da5Sopenharmony_ci const std::string body = R"( 1750fd4e5da5Sopenharmony_ciOpAtomicStore %u32_var %device %relaxed %u32_1 1751fd4e5da5Sopenharmony_ci%val1 = OpAtomicIIncrement %u32 %u32_var %device %acquire_release_uniform_workgroup 1752fd4e5da5Sopenharmony_ci)"; 1753fd4e5da5Sopenharmony_ci 1754fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body)); 1755fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); 1756fd4e5da5Sopenharmony_ci} 1757fd4e5da5Sopenharmony_ci 1758fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicUniformMemorySemanticsKernel) { 1759fd4e5da5Sopenharmony_ci const std::string body = R"( 1760fd4e5da5Sopenharmony_ciOpAtomicStore %u32_var %device %relaxed %u32_1 1761fd4e5da5Sopenharmony_ci%val1 = OpAtomicIIncrement %u32 %u32_var %device %acquire_release_uniform_workgroup 1762fd4e5da5Sopenharmony_ci)"; 1763fd4e5da5Sopenharmony_ci 1764fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body)); 1765fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 1766fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1767fd4e5da5Sopenharmony_ci HasSubstr("AtomicIIncrement: Memory Semantics UniformMemory " 1768fd4e5da5Sopenharmony_ci "requires capability Shader")); 1769fd4e5da5Sopenharmony_ci} 1770fd4e5da5Sopenharmony_ci 1771fd4e5da5Sopenharmony_ci// Lack of the AtomicStorage capability is intentionally ignored, see 1772fd4e5da5Sopenharmony_ci// https://github.com/KhronosGroup/glslang/issues/1618 for the reasoning why. 1773fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicCounterMemorySemanticsNoCapability) { 1774fd4e5da5Sopenharmony_ci const std::string body = R"( 1775fd4e5da5Sopenharmony_ci OpAtomicStore %u32_var %device %relaxed %u32_1 1776fd4e5da5Sopenharmony_ci%val1 = OpAtomicIIncrement %u32 %u32_var %device 1777fd4e5da5Sopenharmony_ci%acquire_release_atomic_counter_workgroup 1778fd4e5da5Sopenharmony_ci)"; 1779fd4e5da5Sopenharmony_ci 1780fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body)); 1781fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); 1782fd4e5da5Sopenharmony_ci} 1783fd4e5da5Sopenharmony_ci 1784fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, AtomicCounterMemorySemanticsWithCapability) { 1785fd4e5da5Sopenharmony_ci const std::string body = R"( 1786fd4e5da5Sopenharmony_ciOpAtomicStore %u32_var %device %relaxed %u32_1 1787fd4e5da5Sopenharmony_ci%val1 = OpAtomicIIncrement %u32 %u32_var %device %acquire_release_atomic_counter_workgroup 1788fd4e5da5Sopenharmony_ci)"; 1789fd4e5da5Sopenharmony_ci 1790fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body, "OpCapability AtomicStorage\n")); 1791fd4e5da5Sopenharmony_ci ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); 1792fd4e5da5Sopenharmony_ci} 1793fd4e5da5Sopenharmony_ci 1794fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, VulkanMemoryModelBanSequentiallyConsistentAtomicLoad) { 1795fd4e5da5Sopenharmony_ci const std::string body = R"( 1796fd4e5da5Sopenharmony_ci%ld = OpAtomicLoad %u32 %u32_var %workgroup %sequentially_consistent 1797fd4e5da5Sopenharmony_ci)"; 1798fd4e5da5Sopenharmony_ci 1799fd4e5da5Sopenharmony_ci const std::string extra = R"( 1800fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR 1801fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model" 1802fd4e5da5Sopenharmony_ci)"; 1803fd4e5da5Sopenharmony_ci 1804fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body, extra, "", "VulkanKHR"), 1805fd4e5da5Sopenharmony_ci SPV_ENV_UNIVERSAL_1_3); 1806fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, 1807fd4e5da5Sopenharmony_ci ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); 1808fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1809fd4e5da5Sopenharmony_ci HasSubstr("SequentiallyConsistent memory semantics cannot be " 1810fd4e5da5Sopenharmony_ci "used with the VulkanKHR memory model.")); 1811fd4e5da5Sopenharmony_ci} 1812fd4e5da5Sopenharmony_ci 1813fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, VulkanMemoryModelBanSequentiallyConsistentAtomicStore) { 1814fd4e5da5Sopenharmony_ci const std::string body = R"( 1815fd4e5da5Sopenharmony_ciOpAtomicStore %u32_var %workgroup %sequentially_consistent %u32_0 1816fd4e5da5Sopenharmony_ci)"; 1817fd4e5da5Sopenharmony_ci 1818fd4e5da5Sopenharmony_ci const std::string extra = R"( 1819fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR 1820fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model" 1821fd4e5da5Sopenharmony_ci)"; 1822fd4e5da5Sopenharmony_ci 1823fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body, extra, "", "VulkanKHR"), 1824fd4e5da5Sopenharmony_ci SPV_ENV_UNIVERSAL_1_3); 1825fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, 1826fd4e5da5Sopenharmony_ci ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); 1827fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1828fd4e5da5Sopenharmony_ci HasSubstr("SequentiallyConsistent memory semantics cannot be " 1829fd4e5da5Sopenharmony_ci "used with the VulkanKHR memory model.")); 1830fd4e5da5Sopenharmony_ci} 1831fd4e5da5Sopenharmony_ci 1832fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, 1833fd4e5da5Sopenharmony_ci VulkanMemoryModelBanSequentiallyConsistentAtomicExchange) { 1834fd4e5da5Sopenharmony_ci const std::string body = R"( 1835fd4e5da5Sopenharmony_ci%ex = OpAtomicExchange %u32 %u32_var %workgroup %sequentially_consistent %u32_0 1836fd4e5da5Sopenharmony_ci)"; 1837fd4e5da5Sopenharmony_ci 1838fd4e5da5Sopenharmony_ci const std::string extra = R"( 1839fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR 1840fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model" 1841fd4e5da5Sopenharmony_ci)"; 1842fd4e5da5Sopenharmony_ci 1843fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body, extra, "", "VulkanKHR"), 1844fd4e5da5Sopenharmony_ci SPV_ENV_UNIVERSAL_1_3); 1845fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, 1846fd4e5da5Sopenharmony_ci ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); 1847fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1848fd4e5da5Sopenharmony_ci HasSubstr("SequentiallyConsistent memory semantics cannot be " 1849fd4e5da5Sopenharmony_ci "used with the VulkanKHR memory model.")); 1850fd4e5da5Sopenharmony_ci} 1851fd4e5da5Sopenharmony_ci 1852fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, 1853fd4e5da5Sopenharmony_ci VulkanMemoryModelBanSequentiallyConsistentAtomicCompareExchangeEqual) { 1854fd4e5da5Sopenharmony_ci const std::string body = R"( 1855fd4e5da5Sopenharmony_ci%ex = OpAtomicCompareExchange %u32 %u32_var %workgroup %sequentially_consistent %relaxed %u32_0 %u32_0 1856fd4e5da5Sopenharmony_ci)"; 1857fd4e5da5Sopenharmony_ci 1858fd4e5da5Sopenharmony_ci const std::string extra = R"( 1859fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR 1860fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model" 1861fd4e5da5Sopenharmony_ci)"; 1862fd4e5da5Sopenharmony_ci 1863fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body, extra, "", "VulkanKHR"), 1864fd4e5da5Sopenharmony_ci SPV_ENV_UNIVERSAL_1_3); 1865fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, 1866fd4e5da5Sopenharmony_ci ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); 1867fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1868fd4e5da5Sopenharmony_ci HasSubstr("SequentiallyConsistent memory semantics cannot be " 1869fd4e5da5Sopenharmony_ci "used with the VulkanKHR memory model.")); 1870fd4e5da5Sopenharmony_ci} 1871fd4e5da5Sopenharmony_ci 1872fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, 1873fd4e5da5Sopenharmony_ci VulkanMemoryModelBanSequentiallyConsistentAtomicCompareExchangeUnequal) { 1874fd4e5da5Sopenharmony_ci const std::string body = R"( 1875fd4e5da5Sopenharmony_ci%ex = OpAtomicCompareExchange %u32 %u32_var %workgroup %relaxed %sequentially_consistent %u32_0 %u32_0 1876fd4e5da5Sopenharmony_ci)"; 1877fd4e5da5Sopenharmony_ci 1878fd4e5da5Sopenharmony_ci const std::string extra = R"( 1879fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR 1880fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model" 1881fd4e5da5Sopenharmony_ci)"; 1882fd4e5da5Sopenharmony_ci 1883fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body, extra, "", "VulkanKHR"), 1884fd4e5da5Sopenharmony_ci SPV_ENV_UNIVERSAL_1_3); 1885fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, 1886fd4e5da5Sopenharmony_ci ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); 1887fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1888fd4e5da5Sopenharmony_ci HasSubstr("SequentiallyConsistent memory semantics cannot be " 1889fd4e5da5Sopenharmony_ci "used with the VulkanKHR memory model.")); 1890fd4e5da5Sopenharmony_ci} 1891fd4e5da5Sopenharmony_ci 1892fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, 1893fd4e5da5Sopenharmony_ci VulkanMemoryModelBanSequentiallyConsistentAtomicIIncrement) { 1894fd4e5da5Sopenharmony_ci const std::string body = R"( 1895fd4e5da5Sopenharmony_ci%inc = OpAtomicIIncrement %u32 %u32_var %workgroup %sequentially_consistent 1896fd4e5da5Sopenharmony_ci)"; 1897fd4e5da5Sopenharmony_ci 1898fd4e5da5Sopenharmony_ci const std::string extra = R"( 1899fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR 1900fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model" 1901fd4e5da5Sopenharmony_ci)"; 1902fd4e5da5Sopenharmony_ci 1903fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body, extra, "", "VulkanKHR"), 1904fd4e5da5Sopenharmony_ci SPV_ENV_UNIVERSAL_1_3); 1905fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, 1906fd4e5da5Sopenharmony_ci ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); 1907fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1908fd4e5da5Sopenharmony_ci HasSubstr("SequentiallyConsistent memory semantics cannot be " 1909fd4e5da5Sopenharmony_ci "used with the VulkanKHR memory model.")); 1910fd4e5da5Sopenharmony_ci} 1911fd4e5da5Sopenharmony_ci 1912fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, 1913fd4e5da5Sopenharmony_ci VulkanMemoryModelBanSequentiallyConsistentAtomicIDecrement) { 1914fd4e5da5Sopenharmony_ci const std::string body = R"( 1915fd4e5da5Sopenharmony_ci%dec = OpAtomicIDecrement %u32 %u32_var %workgroup %sequentially_consistent 1916fd4e5da5Sopenharmony_ci)"; 1917fd4e5da5Sopenharmony_ci 1918fd4e5da5Sopenharmony_ci const std::string extra = R"( 1919fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR 1920fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model" 1921fd4e5da5Sopenharmony_ci)"; 1922fd4e5da5Sopenharmony_ci 1923fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body, extra, "", "VulkanKHR"), 1924fd4e5da5Sopenharmony_ci SPV_ENV_UNIVERSAL_1_3); 1925fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, 1926fd4e5da5Sopenharmony_ci ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); 1927fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1928fd4e5da5Sopenharmony_ci HasSubstr("SequentiallyConsistent memory semantics cannot be " 1929fd4e5da5Sopenharmony_ci "used with the VulkanKHR memory model.")); 1930fd4e5da5Sopenharmony_ci} 1931fd4e5da5Sopenharmony_ci 1932fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, VulkanMemoryModelBanSequentiallyConsistentAtomicIAdd) { 1933fd4e5da5Sopenharmony_ci const std::string body = R"( 1934fd4e5da5Sopenharmony_ci%add = OpAtomicIAdd %u32 %u32_var %workgroup %sequentially_consistent %u32_0 1935fd4e5da5Sopenharmony_ci)"; 1936fd4e5da5Sopenharmony_ci 1937fd4e5da5Sopenharmony_ci const std::string extra = R"( 1938fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR 1939fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model" 1940fd4e5da5Sopenharmony_ci)"; 1941fd4e5da5Sopenharmony_ci 1942fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body, extra, "", "VulkanKHR"), 1943fd4e5da5Sopenharmony_ci SPV_ENV_UNIVERSAL_1_3); 1944fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, 1945fd4e5da5Sopenharmony_ci ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); 1946fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1947fd4e5da5Sopenharmony_ci HasSubstr("SequentiallyConsistent memory semantics cannot be " 1948fd4e5da5Sopenharmony_ci "used with the VulkanKHR memory model.")); 1949fd4e5da5Sopenharmony_ci} 1950fd4e5da5Sopenharmony_ci 1951fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, VulkanMemoryModelBanSequentiallyConsistentAtomicISub) { 1952fd4e5da5Sopenharmony_ci const std::string body = R"( 1953fd4e5da5Sopenharmony_ci%sub = OpAtomicISub %u32 %u32_var %workgroup %sequentially_consistent %u32_0 1954fd4e5da5Sopenharmony_ci)"; 1955fd4e5da5Sopenharmony_ci 1956fd4e5da5Sopenharmony_ci const std::string extra = R"( 1957fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR 1958fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model" 1959fd4e5da5Sopenharmony_ci)"; 1960fd4e5da5Sopenharmony_ci 1961fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body, extra, "", "VulkanKHR"), 1962fd4e5da5Sopenharmony_ci SPV_ENV_UNIVERSAL_1_3); 1963fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, 1964fd4e5da5Sopenharmony_ci ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); 1965fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1966fd4e5da5Sopenharmony_ci HasSubstr("SequentiallyConsistent memory semantics cannot be " 1967fd4e5da5Sopenharmony_ci "used with the VulkanKHR memory model.")); 1968fd4e5da5Sopenharmony_ci} 1969fd4e5da5Sopenharmony_ci 1970fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, VulkanMemoryModelBanSequentiallyConsistentAtomicSMin) { 1971fd4e5da5Sopenharmony_ci const std::string body = R"( 1972fd4e5da5Sopenharmony_ci%min = OpAtomicSMin %u32 %u32_var %workgroup %sequentially_consistent %u32_0 1973fd4e5da5Sopenharmony_ci)"; 1974fd4e5da5Sopenharmony_ci 1975fd4e5da5Sopenharmony_ci const std::string extra = R"( 1976fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR 1977fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model" 1978fd4e5da5Sopenharmony_ci)"; 1979fd4e5da5Sopenharmony_ci 1980fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body, extra, "", "VulkanKHR"), 1981fd4e5da5Sopenharmony_ci SPV_ENV_UNIVERSAL_1_3); 1982fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, 1983fd4e5da5Sopenharmony_ci ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); 1984fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 1985fd4e5da5Sopenharmony_ci HasSubstr("SequentiallyConsistent memory semantics cannot be " 1986fd4e5da5Sopenharmony_ci "used with the VulkanKHR memory model.")); 1987fd4e5da5Sopenharmony_ci} 1988fd4e5da5Sopenharmony_ci 1989fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, VulkanMemoryModelBanSequentiallyConsistentAtomicUMin) { 1990fd4e5da5Sopenharmony_ci const std::string body = R"( 1991fd4e5da5Sopenharmony_ci%min = OpAtomicUMin %u32 %u32_var %workgroup %sequentially_consistent %u32_0 1992fd4e5da5Sopenharmony_ci)"; 1993fd4e5da5Sopenharmony_ci 1994fd4e5da5Sopenharmony_ci const std::string extra = R"( 1995fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR 1996fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model" 1997fd4e5da5Sopenharmony_ci)"; 1998fd4e5da5Sopenharmony_ci 1999fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body, extra, "", "VulkanKHR"), 2000fd4e5da5Sopenharmony_ci SPV_ENV_UNIVERSAL_1_3); 2001fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, 2002fd4e5da5Sopenharmony_ci ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); 2003fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 2004fd4e5da5Sopenharmony_ci HasSubstr("SequentiallyConsistent memory semantics cannot be " 2005fd4e5da5Sopenharmony_ci "used with the VulkanKHR memory model.")); 2006fd4e5da5Sopenharmony_ci} 2007fd4e5da5Sopenharmony_ci 2008fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, VulkanMemoryModelBanSequentiallyConsistentAtomicFMinEXT) { 2009fd4e5da5Sopenharmony_ci const std::string body = R"( 2010fd4e5da5Sopenharmony_ci%max = OpAtomicFMinEXT %f32 %f32_var %workgroup %sequentially_consistent %f32_0 2011fd4e5da5Sopenharmony_ci)"; 2012fd4e5da5Sopenharmony_ci 2013fd4e5da5Sopenharmony_ci const std::string extra = R"( 2014fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR 2015fd4e5da5Sopenharmony_ciOpCapability AtomicFloat32MinMaxEXT 2016fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model" 2017fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_shader_atomic_float_min_max" 2018fd4e5da5Sopenharmony_ci)"; 2019fd4e5da5Sopenharmony_ci 2020fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body, extra, "", "VulkanKHR"), 2021fd4e5da5Sopenharmony_ci SPV_ENV_UNIVERSAL_1_3); 2022fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, 2023fd4e5da5Sopenharmony_ci ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); 2024fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 2025fd4e5da5Sopenharmony_ci HasSubstr("SequentiallyConsistent memory semantics cannot be " 2026fd4e5da5Sopenharmony_ci "used with the VulkanKHR memory model.")); 2027fd4e5da5Sopenharmony_ci} 2028fd4e5da5Sopenharmony_ci 2029fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, VulkanMemoryModelBanSequentiallyConsistentAtomicSMax) { 2030fd4e5da5Sopenharmony_ci const std::string body = R"( 2031fd4e5da5Sopenharmony_ci%max = OpAtomicSMax %u32 %u32_var %workgroup %sequentially_consistent %u32_0 2032fd4e5da5Sopenharmony_ci)"; 2033fd4e5da5Sopenharmony_ci 2034fd4e5da5Sopenharmony_ci const std::string extra = R"( 2035fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR 2036fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model" 2037fd4e5da5Sopenharmony_ci)"; 2038fd4e5da5Sopenharmony_ci 2039fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body, extra, "", "VulkanKHR"), 2040fd4e5da5Sopenharmony_ci SPV_ENV_UNIVERSAL_1_3); 2041fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, 2042fd4e5da5Sopenharmony_ci ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); 2043fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 2044fd4e5da5Sopenharmony_ci HasSubstr("SequentiallyConsistent memory semantics cannot be " 2045fd4e5da5Sopenharmony_ci "used with the VulkanKHR memory model.")); 2046fd4e5da5Sopenharmony_ci} 2047fd4e5da5Sopenharmony_ci 2048fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, VulkanMemoryModelBanSequentiallyConsistentAtomicUMax) { 2049fd4e5da5Sopenharmony_ci const std::string body = R"( 2050fd4e5da5Sopenharmony_ci%max = OpAtomicUMax %u32 %u32_var %workgroup %sequentially_consistent %u32_0 2051fd4e5da5Sopenharmony_ci)"; 2052fd4e5da5Sopenharmony_ci 2053fd4e5da5Sopenharmony_ci const std::string extra = R"( 2054fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR 2055fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model" 2056fd4e5da5Sopenharmony_ci)"; 2057fd4e5da5Sopenharmony_ci 2058fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body, extra, "", "VulkanKHR"), 2059fd4e5da5Sopenharmony_ci SPV_ENV_UNIVERSAL_1_3); 2060fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, 2061fd4e5da5Sopenharmony_ci ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); 2062fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 2063fd4e5da5Sopenharmony_ci HasSubstr("SequentiallyConsistent memory semantics cannot be " 2064fd4e5da5Sopenharmony_ci "used with the VulkanKHR memory model.")); 2065fd4e5da5Sopenharmony_ci} 2066fd4e5da5Sopenharmony_ci 2067fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, VulkanMemoryModelBanSequentiallyConsistentAtomicFMaxEXT) { 2068fd4e5da5Sopenharmony_ci const std::string body = R"( 2069fd4e5da5Sopenharmony_ci%max = OpAtomicFMaxEXT %f32 %f32_var %workgroup %sequentially_consistent %f32_0 2070fd4e5da5Sopenharmony_ci)"; 2071fd4e5da5Sopenharmony_ci 2072fd4e5da5Sopenharmony_ci const std::string extra = R"( 2073fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR 2074fd4e5da5Sopenharmony_ciOpCapability AtomicFloat32MinMaxEXT 2075fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model" 2076fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_shader_atomic_float_min_max" 2077fd4e5da5Sopenharmony_ci)"; 2078fd4e5da5Sopenharmony_ci 2079fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body, extra, "", "VulkanKHR"), 2080fd4e5da5Sopenharmony_ci SPV_ENV_UNIVERSAL_1_3); 2081fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, 2082fd4e5da5Sopenharmony_ci ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); 2083fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 2084fd4e5da5Sopenharmony_ci HasSubstr("SequentiallyConsistent memory semantics cannot be " 2085fd4e5da5Sopenharmony_ci "used with the VulkanKHR memory model.")); 2086fd4e5da5Sopenharmony_ci} 2087fd4e5da5Sopenharmony_ci 2088fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, VulkanMemoryModelBanSequentiallyConsistentAtomicAnd) { 2089fd4e5da5Sopenharmony_ci const std::string body = R"( 2090fd4e5da5Sopenharmony_ci%and = OpAtomicAnd %u32 %u32_var %workgroup %sequentially_consistent %u32_0 2091fd4e5da5Sopenharmony_ci)"; 2092fd4e5da5Sopenharmony_ci 2093fd4e5da5Sopenharmony_ci const std::string extra = R"( 2094fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR 2095fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model" 2096fd4e5da5Sopenharmony_ci)"; 2097fd4e5da5Sopenharmony_ci 2098fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body, extra, "", "VulkanKHR"), 2099fd4e5da5Sopenharmony_ci SPV_ENV_UNIVERSAL_1_3); 2100fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, 2101fd4e5da5Sopenharmony_ci ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); 2102fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 2103fd4e5da5Sopenharmony_ci HasSubstr("SequentiallyConsistent memory semantics cannot be " 2104fd4e5da5Sopenharmony_ci "used with the VulkanKHR memory model.")); 2105fd4e5da5Sopenharmony_ci} 2106fd4e5da5Sopenharmony_ci 2107fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, VulkanMemoryModelBanSequentiallyConsistentAtomicOr) { 2108fd4e5da5Sopenharmony_ci const std::string body = R"( 2109fd4e5da5Sopenharmony_ci%or = OpAtomicOr %u32 %u32_var %workgroup %sequentially_consistent %u32_0 2110fd4e5da5Sopenharmony_ci)"; 2111fd4e5da5Sopenharmony_ci 2112fd4e5da5Sopenharmony_ci const std::string extra = R"( 2113fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR 2114fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model" 2115fd4e5da5Sopenharmony_ci)"; 2116fd4e5da5Sopenharmony_ci 2117fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body, extra, "", "VulkanKHR"), 2118fd4e5da5Sopenharmony_ci SPV_ENV_UNIVERSAL_1_3); 2119fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, 2120fd4e5da5Sopenharmony_ci ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); 2121fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 2122fd4e5da5Sopenharmony_ci HasSubstr("SequentiallyConsistent memory semantics cannot be " 2123fd4e5da5Sopenharmony_ci "used with the VulkanKHR memory model.")); 2124fd4e5da5Sopenharmony_ci} 2125fd4e5da5Sopenharmony_ci 2126fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, VulkanMemoryModelBanSequentiallyConsistentAtomicXor) { 2127fd4e5da5Sopenharmony_ci const std::string body = R"( 2128fd4e5da5Sopenharmony_ci%xor = OpAtomicXor %u32 %u32_var %workgroup %sequentially_consistent %u32_0 2129fd4e5da5Sopenharmony_ci)"; 2130fd4e5da5Sopenharmony_ci 2131fd4e5da5Sopenharmony_ci const std::string extra = R"( 2132fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR 2133fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model" 2134fd4e5da5Sopenharmony_ci)"; 2135fd4e5da5Sopenharmony_ci 2136fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body, extra, "", "VulkanKHR"), 2137fd4e5da5Sopenharmony_ci SPV_ENV_UNIVERSAL_1_3); 2138fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, 2139fd4e5da5Sopenharmony_ci ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); 2140fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 2141fd4e5da5Sopenharmony_ci HasSubstr("SequentiallyConsistent memory semantics cannot be " 2142fd4e5da5Sopenharmony_ci "used with the VulkanKHR memory model.")); 2143fd4e5da5Sopenharmony_ci} 2144fd4e5da5Sopenharmony_ci 2145fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, OutputMemoryKHRRequiresVulkanMemoryModelKHR) { 2146fd4e5da5Sopenharmony_ci const std::string text = R"( 2147fd4e5da5Sopenharmony_ciOpCapability Shader 2148fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 2149fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %1 "func" 2150fd4e5da5Sopenharmony_ciOpExecutionMode %1 OriginUpperLeft 2151fd4e5da5Sopenharmony_ci%2 = OpTypeVoid 2152fd4e5da5Sopenharmony_ci%3 = OpTypeInt 32 0 2153fd4e5da5Sopenharmony_ci%semantics = OpConstant %3 4100 2154fd4e5da5Sopenharmony_ci%5 = OpTypeFunction %2 2155fd4e5da5Sopenharmony_ci%workgroup = OpConstant %3 2 2156fd4e5da5Sopenharmony_ci%ptr = OpTypePointer Workgroup %3 2157fd4e5da5Sopenharmony_ci%var = OpVariable %ptr Workgroup 2158fd4e5da5Sopenharmony_ci%1 = OpFunction %2 None %5 2159fd4e5da5Sopenharmony_ci%7 = OpLabel 2160fd4e5da5Sopenharmony_ciOpAtomicStore %var %workgroup %semantics %workgroup 2161fd4e5da5Sopenharmony_ciOpReturn 2162fd4e5da5Sopenharmony_ciOpFunctionEnd 2163fd4e5da5Sopenharmony_ci)"; 2164fd4e5da5Sopenharmony_ci 2165fd4e5da5Sopenharmony_ci CompileSuccessfully(text); 2166fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 2167fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 2168fd4e5da5Sopenharmony_ci HasSubstr("AtomicStore: Memory Semantics OutputMemoryKHR " 2169fd4e5da5Sopenharmony_ci "requires capability VulkanMemoryModelKHR")); 2170fd4e5da5Sopenharmony_ci} 2171fd4e5da5Sopenharmony_ci 2172fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, MakeAvailableKHRRequiresVulkanMemoryModelKHR) { 2173fd4e5da5Sopenharmony_ci const std::string text = R"( 2174fd4e5da5Sopenharmony_ciOpCapability Shader 2175fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 2176fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %1 "func" 2177fd4e5da5Sopenharmony_ciOpExecutionMode %1 OriginUpperLeft 2178fd4e5da5Sopenharmony_ci%2 = OpTypeVoid 2179fd4e5da5Sopenharmony_ci%3 = OpTypeInt 32 0 2180fd4e5da5Sopenharmony_ci%semantics = OpConstant %3 8196 2181fd4e5da5Sopenharmony_ci%5 = OpTypeFunction %2 2182fd4e5da5Sopenharmony_ci%workgroup = OpConstant %3 2 2183fd4e5da5Sopenharmony_ci%ptr = OpTypePointer Workgroup %3 2184fd4e5da5Sopenharmony_ci%var = OpVariable %ptr Workgroup 2185fd4e5da5Sopenharmony_ci%1 = OpFunction %2 None %5 2186fd4e5da5Sopenharmony_ci%7 = OpLabel 2187fd4e5da5Sopenharmony_ciOpAtomicStore %var %workgroup %semantics %workgroup 2188fd4e5da5Sopenharmony_ciOpReturn 2189fd4e5da5Sopenharmony_ciOpFunctionEnd 2190fd4e5da5Sopenharmony_ci)"; 2191fd4e5da5Sopenharmony_ci 2192fd4e5da5Sopenharmony_ci CompileSuccessfully(text); 2193fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 2194fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 2195fd4e5da5Sopenharmony_ci HasSubstr("AtomicStore: Memory Semantics MakeAvailableKHR " 2196fd4e5da5Sopenharmony_ci "requires capability VulkanMemoryModelKHR")); 2197fd4e5da5Sopenharmony_ci} 2198fd4e5da5Sopenharmony_ci 2199fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, MakeVisibleKHRRequiresVulkanMemoryModelKHR) { 2200fd4e5da5Sopenharmony_ci const std::string text = R"( 2201fd4e5da5Sopenharmony_ciOpCapability Shader 2202fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 2203fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %1 "func" 2204fd4e5da5Sopenharmony_ciOpExecutionMode %1 OriginUpperLeft 2205fd4e5da5Sopenharmony_ci%2 = OpTypeVoid 2206fd4e5da5Sopenharmony_ci%3 = OpTypeInt 32 0 2207fd4e5da5Sopenharmony_ci%semantics = OpConstant %3 16386 2208fd4e5da5Sopenharmony_ci%5 = OpTypeFunction %2 2209fd4e5da5Sopenharmony_ci%workgroup = OpConstant %3 2 2210fd4e5da5Sopenharmony_ci%ptr = OpTypePointer Workgroup %3 2211fd4e5da5Sopenharmony_ci%var = OpVariable %ptr Workgroup 2212fd4e5da5Sopenharmony_ci%1 = OpFunction %2 None %5 2213fd4e5da5Sopenharmony_ci%7 = OpLabel 2214fd4e5da5Sopenharmony_ci%ld = OpAtomicLoad %3 %var %workgroup %semantics 2215fd4e5da5Sopenharmony_ciOpReturn 2216fd4e5da5Sopenharmony_ciOpFunctionEnd 2217fd4e5da5Sopenharmony_ci)"; 2218fd4e5da5Sopenharmony_ci 2219fd4e5da5Sopenharmony_ci CompileSuccessfully(text); 2220fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 2221fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 2222fd4e5da5Sopenharmony_ci HasSubstr("AtomicLoad: Memory Semantics MakeVisibleKHR requires " 2223fd4e5da5Sopenharmony_ci "capability VulkanMemoryModelKHR")); 2224fd4e5da5Sopenharmony_ci} 2225fd4e5da5Sopenharmony_ci 2226fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, MakeAvailableKHRRequiresReleaseSemantics) { 2227fd4e5da5Sopenharmony_ci const std::string text = R"( 2228fd4e5da5Sopenharmony_ciOpCapability Shader 2229fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR 2230fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model" 2231fd4e5da5Sopenharmony_ciOpMemoryModel Logical VulkanKHR 2232fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %1 "func" 2233fd4e5da5Sopenharmony_ciOpExecutionMode %1 OriginUpperLeft 2234fd4e5da5Sopenharmony_ci%2 = OpTypeVoid 2235fd4e5da5Sopenharmony_ci%3 = OpTypeInt 32 0 2236fd4e5da5Sopenharmony_ci%semantics = OpConstant %3 8448 2237fd4e5da5Sopenharmony_ci%5 = OpTypeFunction %2 2238fd4e5da5Sopenharmony_ci%workgroup = OpConstant %3 2 2239fd4e5da5Sopenharmony_ci%ptr = OpTypePointer Workgroup %3 2240fd4e5da5Sopenharmony_ci%var = OpVariable %ptr Workgroup 2241fd4e5da5Sopenharmony_ci%1 = OpFunction %2 None %5 2242fd4e5da5Sopenharmony_ci%7 = OpLabel 2243fd4e5da5Sopenharmony_ciOpAtomicStore %var %workgroup %semantics %workgroup 2244fd4e5da5Sopenharmony_ciOpReturn 2245fd4e5da5Sopenharmony_ciOpFunctionEnd 2246fd4e5da5Sopenharmony_ci)"; 2247fd4e5da5Sopenharmony_ci 2248fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_3); 2249fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, 2250fd4e5da5Sopenharmony_ci ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); 2251fd4e5da5Sopenharmony_ci EXPECT_THAT( 2252fd4e5da5Sopenharmony_ci getDiagnosticString(), 2253fd4e5da5Sopenharmony_ci HasSubstr("AtomicStore: MakeAvailableKHR Memory Semantics also requires " 2254fd4e5da5Sopenharmony_ci "either Release or AcquireRelease Memory Semantics")); 2255fd4e5da5Sopenharmony_ci} 2256fd4e5da5Sopenharmony_ci 2257fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, MakeVisibleKHRRequiresAcquireSemantics) { 2258fd4e5da5Sopenharmony_ci const std::string text = R"( 2259fd4e5da5Sopenharmony_ciOpCapability Shader 2260fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR 2261fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model" 2262fd4e5da5Sopenharmony_ciOpMemoryModel Logical VulkanKHR 2263fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %1 "func" 2264fd4e5da5Sopenharmony_ciOpExecutionMode %1 OriginUpperLeft 2265fd4e5da5Sopenharmony_ci%2 = OpTypeVoid 2266fd4e5da5Sopenharmony_ci%3 = OpTypeInt 32 0 2267fd4e5da5Sopenharmony_ci%semantics = OpConstant %3 16640 2268fd4e5da5Sopenharmony_ci%5 = OpTypeFunction %2 2269fd4e5da5Sopenharmony_ci%workgroup = OpConstant %3 2 2270fd4e5da5Sopenharmony_ci%ptr = OpTypePointer Workgroup %3 2271fd4e5da5Sopenharmony_ci%var = OpVariable %ptr Workgroup 2272fd4e5da5Sopenharmony_ci%1 = OpFunction %2 None %5 2273fd4e5da5Sopenharmony_ci%7 = OpLabel 2274fd4e5da5Sopenharmony_ci%ld = OpAtomicLoad %3 %var %workgroup %semantics 2275fd4e5da5Sopenharmony_ciOpReturn 2276fd4e5da5Sopenharmony_ciOpFunctionEnd 2277fd4e5da5Sopenharmony_ci)"; 2278fd4e5da5Sopenharmony_ci 2279fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_3); 2280fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, 2281fd4e5da5Sopenharmony_ci ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); 2282fd4e5da5Sopenharmony_ci EXPECT_THAT( 2283fd4e5da5Sopenharmony_ci getDiagnosticString(), 2284fd4e5da5Sopenharmony_ci HasSubstr("AtomicLoad: MakeVisibleKHR Memory Semantics also requires " 2285fd4e5da5Sopenharmony_ci "either Acquire or AcquireRelease Memory Semantics")); 2286fd4e5da5Sopenharmony_ci} 2287fd4e5da5Sopenharmony_ci 2288fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, MakeAvailableKHRRequiresStorageSemantics) { 2289fd4e5da5Sopenharmony_ci const std::string text = R"( 2290fd4e5da5Sopenharmony_ciOpCapability Shader 2291fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR 2292fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model" 2293fd4e5da5Sopenharmony_ciOpMemoryModel Logical VulkanKHR 2294fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %1 "func" 2295fd4e5da5Sopenharmony_ciOpExecutionMode %1 OriginUpperLeft 2296fd4e5da5Sopenharmony_ci%2 = OpTypeVoid 2297fd4e5da5Sopenharmony_ci%3 = OpTypeInt 32 0 2298fd4e5da5Sopenharmony_ci%semantics = OpConstant %3 8196 2299fd4e5da5Sopenharmony_ci%5 = OpTypeFunction %2 2300fd4e5da5Sopenharmony_ci%workgroup = OpConstant %3 2 2301fd4e5da5Sopenharmony_ci%ptr = OpTypePointer Workgroup %3 2302fd4e5da5Sopenharmony_ci%var = OpVariable %ptr Workgroup 2303fd4e5da5Sopenharmony_ci%1 = OpFunction %2 None %5 2304fd4e5da5Sopenharmony_ci%7 = OpLabel 2305fd4e5da5Sopenharmony_ciOpAtomicStore %var %workgroup %semantics %workgroup 2306fd4e5da5Sopenharmony_ciOpReturn 2307fd4e5da5Sopenharmony_ciOpFunctionEnd 2308fd4e5da5Sopenharmony_ci)"; 2309fd4e5da5Sopenharmony_ci 2310fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_3); 2311fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, 2312fd4e5da5Sopenharmony_ci ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); 2313fd4e5da5Sopenharmony_ci EXPECT_THAT( 2314fd4e5da5Sopenharmony_ci getDiagnosticString(), 2315fd4e5da5Sopenharmony_ci HasSubstr( 2316fd4e5da5Sopenharmony_ci "AtomicStore: expected Memory Semantics to include a storage class")); 2317fd4e5da5Sopenharmony_ci} 2318fd4e5da5Sopenharmony_ci 2319fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, MakeVisibleKHRRequiresStorageSemantics) { 2320fd4e5da5Sopenharmony_ci const std::string text = R"( 2321fd4e5da5Sopenharmony_ciOpCapability Shader 2322fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR 2323fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model" 2324fd4e5da5Sopenharmony_ciOpMemoryModel Logical VulkanKHR 2325fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %1 "func" 2326fd4e5da5Sopenharmony_ciOpExecutionMode %1 OriginUpperLeft 2327fd4e5da5Sopenharmony_ci%2 = OpTypeVoid 2328fd4e5da5Sopenharmony_ci%3 = OpTypeInt 32 0 2329fd4e5da5Sopenharmony_ci%semantics = OpConstant %3 16386 2330fd4e5da5Sopenharmony_ci%5 = OpTypeFunction %2 2331fd4e5da5Sopenharmony_ci%workgroup = OpConstant %3 2 2332fd4e5da5Sopenharmony_ci%ptr = OpTypePointer Workgroup %3 2333fd4e5da5Sopenharmony_ci%var = OpVariable %ptr Workgroup 2334fd4e5da5Sopenharmony_ci%1 = OpFunction %2 None %5 2335fd4e5da5Sopenharmony_ci%7 = OpLabel 2336fd4e5da5Sopenharmony_ci%ld = OpAtomicLoad %3 %var %workgroup %semantics 2337fd4e5da5Sopenharmony_ciOpReturn 2338fd4e5da5Sopenharmony_ciOpFunctionEnd 2339fd4e5da5Sopenharmony_ci)"; 2340fd4e5da5Sopenharmony_ci 2341fd4e5da5Sopenharmony_ci CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_3); 2342fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, 2343fd4e5da5Sopenharmony_ci ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); 2344fd4e5da5Sopenharmony_ci EXPECT_THAT( 2345fd4e5da5Sopenharmony_ci getDiagnosticString(), 2346fd4e5da5Sopenharmony_ci HasSubstr( 2347fd4e5da5Sopenharmony_ci "AtomicLoad: expected Memory Semantics to include a storage class")); 2348fd4e5da5Sopenharmony_ci} 2349fd4e5da5Sopenharmony_ci 2350fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, VulkanMemoryModelAllowsQueueFamilyKHR) { 2351fd4e5da5Sopenharmony_ci const std::string body = R"( 2352fd4e5da5Sopenharmony_ci%val = OpAtomicAnd %u32 %u32_var %queuefamily %relaxed %u32_1 2353fd4e5da5Sopenharmony_ci)"; 2354fd4e5da5Sopenharmony_ci 2355fd4e5da5Sopenharmony_ci const std::string extra = R"( 2356fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR 2357fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model" 2358fd4e5da5Sopenharmony_ci)"; 2359fd4e5da5Sopenharmony_ci 2360fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderComputeCode(body, extra, "", "VulkanKHR"), 2361fd4e5da5Sopenharmony_ci SPV_ENV_VULKAN_1_1); 2362fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1)); 2363fd4e5da5Sopenharmony_ci} 2364fd4e5da5Sopenharmony_ci 2365fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, NonVulkanMemoryModelDisallowsQueueFamilyKHR) { 2366fd4e5da5Sopenharmony_ci const std::string body = R"( 2367fd4e5da5Sopenharmony_ci%val = OpAtomicAnd %u32 %u32_var %queuefamily %relaxed %u32_1 2368fd4e5da5Sopenharmony_ci)"; 2369fd4e5da5Sopenharmony_ci 2370fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body), SPV_ENV_VULKAN_1_1); 2371fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_1)); 2372fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 2373fd4e5da5Sopenharmony_ci HasSubstr("AtomicAnd: Memory Scope QueueFamilyKHR requires " 2374fd4e5da5Sopenharmony_ci "capability VulkanMemoryModelKHR\n %42 = OpAtomicAnd " 2375fd4e5da5Sopenharmony_ci "%uint %29 %uint_5 %uint_0_1 %uint_1\n")); 2376fd4e5da5Sopenharmony_ci} 2377fd4e5da5Sopenharmony_ci 2378fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, SemanticsSpecConstantShader) { 2379fd4e5da5Sopenharmony_ci const std::string spirv = R"( 2380fd4e5da5Sopenharmony_ciOpCapability Shader 2381fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 2382fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func" 2383fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft 2384fd4e5da5Sopenharmony_ci%void = OpTypeVoid 2385fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 2386fd4e5da5Sopenharmony_ci%spec_const = OpSpecConstant %int 0 2387fd4e5da5Sopenharmony_ci%workgroup = OpConstant %int 2 2388fd4e5da5Sopenharmony_ci%ptr_int_workgroup = OpTypePointer Workgroup %int 2389fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_int_workgroup Workgroup 2390fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void 2391fd4e5da5Sopenharmony_ci%func = OpFunction %void None %voidfn 2392fd4e5da5Sopenharmony_ci%entry = OpLabel 2393fd4e5da5Sopenharmony_ci%ld = OpAtomicLoad %int %var %workgroup %spec_const 2394fd4e5da5Sopenharmony_ciOpReturn 2395fd4e5da5Sopenharmony_ciOpFunctionEnd 2396fd4e5da5Sopenharmony_ci)"; 2397fd4e5da5Sopenharmony_ci 2398fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 2399fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 2400fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 2401fd4e5da5Sopenharmony_ci HasSubstr("Memory Semantics ids must be OpConstant when Shader " 2402fd4e5da5Sopenharmony_ci "capability is present")); 2403fd4e5da5Sopenharmony_ci} 2404fd4e5da5Sopenharmony_ci 2405fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, SemanticsSpecConstantKernel) { 2406fd4e5da5Sopenharmony_ci const std::string spirv = R"( 2407fd4e5da5Sopenharmony_ciOpCapability Kernel 2408fd4e5da5Sopenharmony_ciOpCapability Linkage 2409fd4e5da5Sopenharmony_ciOpMemoryModel Logical OpenCL 2410fd4e5da5Sopenharmony_ci%void = OpTypeVoid 2411fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 2412fd4e5da5Sopenharmony_ci%spec_const = OpSpecConstant %int 0 2413fd4e5da5Sopenharmony_ci%workgroup = OpConstant %int 2 2414fd4e5da5Sopenharmony_ci%ptr_int_workgroup = OpTypePointer Workgroup %int 2415fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_int_workgroup Workgroup 2416fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void 2417fd4e5da5Sopenharmony_ci%func = OpFunction %void None %voidfn 2418fd4e5da5Sopenharmony_ci%entry = OpLabel 2419fd4e5da5Sopenharmony_ci%ld = OpAtomicLoad %int %var %workgroup %spec_const 2420fd4e5da5Sopenharmony_ciOpReturn 2421fd4e5da5Sopenharmony_ciOpFunctionEnd 2422fd4e5da5Sopenharmony_ci)"; 2423fd4e5da5Sopenharmony_ci 2424fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 2425fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_SUCCESS, ValidateInstructions()); 2426fd4e5da5Sopenharmony_ci} 2427fd4e5da5Sopenharmony_ci 2428fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, ScopeSpecConstantShader) { 2429fd4e5da5Sopenharmony_ci const std::string spirv = R"( 2430fd4e5da5Sopenharmony_ciOpCapability Shader 2431fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 2432fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func" 2433fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft 2434fd4e5da5Sopenharmony_ci%void = OpTypeVoid 2435fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 2436fd4e5da5Sopenharmony_ci%spec_const = OpSpecConstant %int 0 2437fd4e5da5Sopenharmony_ci%relaxed = OpConstant %int 0 2438fd4e5da5Sopenharmony_ci%ptr_int_workgroup = OpTypePointer Workgroup %int 2439fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_int_workgroup Workgroup 2440fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void 2441fd4e5da5Sopenharmony_ci%func = OpFunction %void None %voidfn 2442fd4e5da5Sopenharmony_ci%entry = OpLabel 2443fd4e5da5Sopenharmony_ci%ld = OpAtomicLoad %int %var %spec_const %relaxed 2444fd4e5da5Sopenharmony_ciOpReturn 2445fd4e5da5Sopenharmony_ciOpFunctionEnd 2446fd4e5da5Sopenharmony_ci)"; 2447fd4e5da5Sopenharmony_ci 2448fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 2449fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 2450fd4e5da5Sopenharmony_ci EXPECT_THAT( 2451fd4e5da5Sopenharmony_ci getDiagnosticString(), 2452fd4e5da5Sopenharmony_ci HasSubstr( 2453fd4e5da5Sopenharmony_ci "Scope ids must be OpConstant when Shader capability is present")); 2454fd4e5da5Sopenharmony_ci} 2455fd4e5da5Sopenharmony_ci 2456fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, ScopeSpecConstantKernel) { 2457fd4e5da5Sopenharmony_ci const std::string spirv = R"( 2458fd4e5da5Sopenharmony_ciOpCapability Kernel 2459fd4e5da5Sopenharmony_ciOpCapability Linkage 2460fd4e5da5Sopenharmony_ciOpMemoryModel Logical OpenCL 2461fd4e5da5Sopenharmony_ci%void = OpTypeVoid 2462fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 2463fd4e5da5Sopenharmony_ci%spec_const = OpSpecConstant %int 0 2464fd4e5da5Sopenharmony_ci%relaxed = OpConstant %int 0 2465fd4e5da5Sopenharmony_ci%ptr_int_workgroup = OpTypePointer Workgroup %int 2466fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_int_workgroup Workgroup 2467fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void 2468fd4e5da5Sopenharmony_ci%func = OpFunction %void None %voidfn 2469fd4e5da5Sopenharmony_ci%entry = OpLabel 2470fd4e5da5Sopenharmony_ci%ld = OpAtomicLoad %int %var %spec_const %relaxed 2471fd4e5da5Sopenharmony_ciOpReturn 2472fd4e5da5Sopenharmony_ciOpFunctionEnd 2473fd4e5da5Sopenharmony_ci)"; 2474fd4e5da5Sopenharmony_ci 2475fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 2476fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_SUCCESS, ValidateInstructions()); 2477fd4e5da5Sopenharmony_ci} 2478fd4e5da5Sopenharmony_ci 2479fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, VulkanMemoryModelDeviceScopeBad) { 2480fd4e5da5Sopenharmony_ci const std::string body = R"( 2481fd4e5da5Sopenharmony_ci%val = OpAtomicAnd %u32 %u32_var %device %relaxed %u32_1 2482fd4e5da5Sopenharmony_ci)"; 2483fd4e5da5Sopenharmony_ci 2484fd4e5da5Sopenharmony_ci const std::string extra = R"(OpCapability VulkanMemoryModelKHR 2485fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model" 2486fd4e5da5Sopenharmony_ci)"; 2487fd4e5da5Sopenharmony_ci 2488fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body, extra, "", "VulkanKHR"), 2489fd4e5da5Sopenharmony_ci SPV_ENV_UNIVERSAL_1_3); 2490fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, 2491fd4e5da5Sopenharmony_ci ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); 2492fd4e5da5Sopenharmony_ci EXPECT_THAT( 2493fd4e5da5Sopenharmony_ci getDiagnosticString(), 2494fd4e5da5Sopenharmony_ci HasSubstr("Use of device scope with VulkanKHR memory model requires the " 2495fd4e5da5Sopenharmony_ci "VulkanMemoryModelDeviceScopeKHR capability")); 2496fd4e5da5Sopenharmony_ci} 2497fd4e5da5Sopenharmony_ci 2498fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, VulkanMemoryModelDeviceScopeGood) { 2499fd4e5da5Sopenharmony_ci const std::string body = R"( 2500fd4e5da5Sopenharmony_ci%val = OpAtomicAnd %u32 %u32_var %device %relaxed %u32_1 2501fd4e5da5Sopenharmony_ci)"; 2502fd4e5da5Sopenharmony_ci 2503fd4e5da5Sopenharmony_ci const std::string extra = R"(OpCapability VulkanMemoryModelKHR 2504fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelDeviceScopeKHR 2505fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model" 2506fd4e5da5Sopenharmony_ci)"; 2507fd4e5da5Sopenharmony_ci 2508fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateShaderCode(body, extra, "", "VulkanKHR"), 2509fd4e5da5Sopenharmony_ci SPV_ENV_UNIVERSAL_1_3); 2510fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); 2511fd4e5da5Sopenharmony_ci} 2512fd4e5da5Sopenharmony_ci 2513fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, CompareExchangeWeakV13ValV14Good) { 2514fd4e5da5Sopenharmony_ci const std::string body = R"( 2515fd4e5da5Sopenharmony_ci%val1 = OpAtomicCompareExchangeWeak %u32 %u32_var %device %relaxed %relaxed %u32_0 %u32_0 2516fd4e5da5Sopenharmony_ci)"; 2517fd4e5da5Sopenharmony_ci 2518fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body), SPV_ENV_UNIVERSAL_1_3); 2519fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4)); 2520fd4e5da5Sopenharmony_ci} 2521fd4e5da5Sopenharmony_ci 2522fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, CompareExchangeWeakV14Bad) { 2523fd4e5da5Sopenharmony_ci const std::string body = R"( 2524fd4e5da5Sopenharmony_ci%val1 = OpAtomicCompareExchangeWeak %u32 %u32_var %device %relaxed %relaxed %u32_0 %u32_0 2525fd4e5da5Sopenharmony_ci)"; 2526fd4e5da5Sopenharmony_ci 2527fd4e5da5Sopenharmony_ci CompileSuccessfully(GenerateKernelCode(body), SPV_ENV_UNIVERSAL_1_4); 2528fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_WRONG_VERSION, 2529fd4e5da5Sopenharmony_ci ValidateInstructions(SPV_ENV_UNIVERSAL_1_4)); 2530fd4e5da5Sopenharmony_ci EXPECT_THAT( 2531fd4e5da5Sopenharmony_ci getDiagnosticString(), 2532fd4e5da5Sopenharmony_ci HasSubstr( 2533fd4e5da5Sopenharmony_ci "AtomicCompareExchangeWeak requires SPIR-V version 1.3 or earlier")); 2534fd4e5da5Sopenharmony_ci} 2535fd4e5da5Sopenharmony_ci 2536fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, CompareExchangeVolatileMatch) { 2537fd4e5da5Sopenharmony_ci const std::string spirv = R"( 2538fd4e5da5Sopenharmony_ciOpCapability Shader 2539fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR 2540fd4e5da5Sopenharmony_ciOpCapability Linkage 2541fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model" 2542fd4e5da5Sopenharmony_ciOpMemoryModel Logical VulkanKHR 2543fd4e5da5Sopenharmony_ci%void = OpTypeVoid 2544fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 2545fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0 2546fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1 2547fd4e5da5Sopenharmony_ci%workgroup = OpConstant %int 2 2548fd4e5da5Sopenharmony_ci%volatile = OpConstant %int 32768 2549fd4e5da5Sopenharmony_ci%ptr_wg_int = OpTypePointer Workgroup %int 2550fd4e5da5Sopenharmony_ci%wg_var = OpVariable %ptr_wg_int Workgroup 2551fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 2552fd4e5da5Sopenharmony_ci%func = OpFunction %void None %void_fn 2553fd4e5da5Sopenharmony_ci%entry = OpLabel 2554fd4e5da5Sopenharmony_ci%cmp_ex = OpAtomicCompareExchange %int %wg_var %workgroup %volatile %volatile %int_0 %int_1 2555fd4e5da5Sopenharmony_ciOpReturn 2556fd4e5da5Sopenharmony_ciOpFunctionEnd 2557fd4e5da5Sopenharmony_ci)"; 2558fd4e5da5Sopenharmony_ci 2559fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 2560fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_SUCCESS, ValidateInstructions()); 2561fd4e5da5Sopenharmony_ci} 2562fd4e5da5Sopenharmony_ci 2563fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, CompareExchangeVolatileMismatch) { 2564fd4e5da5Sopenharmony_ci const std::string spirv = R"( 2565fd4e5da5Sopenharmony_ciOpCapability Shader 2566fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR 2567fd4e5da5Sopenharmony_ciOpCapability Linkage 2568fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model" 2569fd4e5da5Sopenharmony_ciOpMemoryModel Logical VulkanKHR 2570fd4e5da5Sopenharmony_ci%void = OpTypeVoid 2571fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 2572fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0 2573fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1 2574fd4e5da5Sopenharmony_ci%workgroup = OpConstant %int 2 2575fd4e5da5Sopenharmony_ci%volatile = OpConstant %int 32768 2576fd4e5da5Sopenharmony_ci%non_volatile = OpConstant %int 0 2577fd4e5da5Sopenharmony_ci%ptr_wg_int = OpTypePointer Workgroup %int 2578fd4e5da5Sopenharmony_ci%wg_var = OpVariable %ptr_wg_int Workgroup 2579fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 2580fd4e5da5Sopenharmony_ci%func = OpFunction %void None %void_fn 2581fd4e5da5Sopenharmony_ci%entry = OpLabel 2582fd4e5da5Sopenharmony_ci%cmp_ex = OpAtomicCompareExchange %int %wg_var %workgroup %non_volatile %volatile %int_0 %int_1 2583fd4e5da5Sopenharmony_ciOpReturn 2584fd4e5da5Sopenharmony_ciOpFunctionEnd 2585fd4e5da5Sopenharmony_ci)"; 2586fd4e5da5Sopenharmony_ci 2587fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 2588fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); 2589fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 2590fd4e5da5Sopenharmony_ci HasSubstr("Volatile mask setting must match for Equal and " 2591fd4e5da5Sopenharmony_ci "Unequal memory semantics")); 2592fd4e5da5Sopenharmony_ci} 2593fd4e5da5Sopenharmony_ci 2594fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, CompareExchangeVolatileMismatchCooperativeMatrix) { 2595fd4e5da5Sopenharmony_ci const std::string spirv = R"( 2596fd4e5da5Sopenharmony_ciOpCapability Shader 2597fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR 2598fd4e5da5Sopenharmony_ciOpCapability Linkage 2599fd4e5da5Sopenharmony_ciOpCapability CooperativeMatrixNV 2600fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model" 2601fd4e5da5Sopenharmony_ciOpExtension "SPV_NV_cooperative_matrix" 2602fd4e5da5Sopenharmony_ciOpMemoryModel Logical VulkanKHR 2603fd4e5da5Sopenharmony_ci%void = OpTypeVoid 2604fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 2605fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0 2606fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1 2607fd4e5da5Sopenharmony_ci%workgroup = OpConstant %int 2 2608fd4e5da5Sopenharmony_ci%volatile = OpSpecConstant %int 32768 2609fd4e5da5Sopenharmony_ci%non_volatile = OpSpecConstant %int 32768 2610fd4e5da5Sopenharmony_ci%ptr_wg_int = OpTypePointer Workgroup %int 2611fd4e5da5Sopenharmony_ci%wg_var = OpVariable %ptr_wg_int Workgroup 2612fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 2613fd4e5da5Sopenharmony_ci%func = OpFunction %void None %void_fn 2614fd4e5da5Sopenharmony_ci%entry = OpLabel 2615fd4e5da5Sopenharmony_ci%cmp_ex = OpAtomicCompareExchange %int %wg_var %workgroup %volatile %non_volatile %int_0 %int_1 2616fd4e5da5Sopenharmony_ciOpReturn 2617fd4e5da5Sopenharmony_ciOpFunctionEnd 2618fd4e5da5Sopenharmony_ci)"; 2619fd4e5da5Sopenharmony_ci 2620fd4e5da5Sopenharmony_ci // This is ok because we cannot evaluate the spec constant defaults. 2621fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 2622fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_SUCCESS, ValidateInstructions()); 2623fd4e5da5Sopenharmony_ci} 2624fd4e5da5Sopenharmony_ci 2625fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, VolatileRequiresVulkanMemoryModel) { 2626fd4e5da5Sopenharmony_ci const std::string spirv = R"( 2627fd4e5da5Sopenharmony_ciOpCapability Shader 2628fd4e5da5Sopenharmony_ciOpCapability Linkage 2629fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 2630fd4e5da5Sopenharmony_ci%void = OpTypeVoid 2631fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 2632fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0 2633fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1 2634fd4e5da5Sopenharmony_ci%workgroup = OpConstant %int 2 2635fd4e5da5Sopenharmony_ci%volatile = OpConstant %int 32768 2636fd4e5da5Sopenharmony_ci%ptr_wg_int = OpTypePointer Workgroup %int 2637fd4e5da5Sopenharmony_ci%wg_var = OpVariable %ptr_wg_int Workgroup 2638fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 2639fd4e5da5Sopenharmony_ci%func = OpFunction %void None %void_fn 2640fd4e5da5Sopenharmony_ci%entry = OpLabel 2641fd4e5da5Sopenharmony_ci%ld = OpAtomicLoad %int %wg_var %workgroup %volatile 2642fd4e5da5Sopenharmony_ciOpReturn 2643fd4e5da5Sopenharmony_ciOpFunctionEnd 2644fd4e5da5Sopenharmony_ci)"; 2645fd4e5da5Sopenharmony_ci 2646fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 2647fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 2648fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 2649fd4e5da5Sopenharmony_ci HasSubstr("Memory Semantics Volatile requires capability " 2650fd4e5da5Sopenharmony_ci "VulkanMemoryModelKHR")); 2651fd4e5da5Sopenharmony_ci} 2652fd4e5da5Sopenharmony_ci 2653fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, CooperativeMatrixSemanticsMustBeConstant) { 2654fd4e5da5Sopenharmony_ci const std::string spirv = R"( 2655fd4e5da5Sopenharmony_ciOpCapability Shader 2656fd4e5da5Sopenharmony_ciOpCapability Linkage 2657fd4e5da5Sopenharmony_ciOpCapability CooperativeMatrixNV 2658fd4e5da5Sopenharmony_ciOpExtension "SPV_NV_cooperative_matrix" 2659fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 2660fd4e5da5Sopenharmony_ci%void = OpTypeVoid 2661fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0 2662fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0 2663fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1 2664fd4e5da5Sopenharmony_ci%workgroup = OpConstant %int 2 2665fd4e5da5Sopenharmony_ci%undef = OpUndef %int 2666fd4e5da5Sopenharmony_ci%ptr_wg_int = OpTypePointer Workgroup %int 2667fd4e5da5Sopenharmony_ci%wg_var = OpVariable %ptr_wg_int Workgroup 2668fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 2669fd4e5da5Sopenharmony_ci%func = OpFunction %void None %void_fn 2670fd4e5da5Sopenharmony_ci%entry = OpLabel 2671fd4e5da5Sopenharmony_ci%ld = OpAtomicLoad %int %wg_var %workgroup %undef 2672fd4e5da5Sopenharmony_ciOpReturn 2673fd4e5da5Sopenharmony_ciOpFunctionEnd 2674fd4e5da5Sopenharmony_ci)"; 2675fd4e5da5Sopenharmony_ci 2676fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 2677fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 2678fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 2679fd4e5da5Sopenharmony_ci HasSubstr("Memory Semantics must be a constant instruction when " 2680fd4e5da5Sopenharmony_ci "CooperativeMatrixNV capability is present")); 2681fd4e5da5Sopenharmony_ci} 2682fd4e5da5Sopenharmony_ci 2683fd4e5da5Sopenharmony_ciTEST_F(ValidateAtomics, IIncrementBadPointerDataType) { 2684fd4e5da5Sopenharmony_ci const std::string spirv = R"( 2685fd4e5da5Sopenharmony_ci OpCapability Shader 2686fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 2687fd4e5da5Sopenharmony_ci %uint = OpTypeInt 32 0 2688fd4e5da5Sopenharmony_ci%_ptr_Input_uint = OpTypePointer Input %uint 2689fd4e5da5Sopenharmony_ci %v3uint = OpTypeVector %uint 3 2690fd4e5da5Sopenharmony_ci%_ptr_Input_v3uint = OpTypePointer Input %v3uint 2691fd4e5da5Sopenharmony_ci %void = OpTypeVoid 2692fd4e5da5Sopenharmony_ci %16 = OpTypeFunction %void 2693fd4e5da5Sopenharmony_ci%uint_538976288 = OpConstant %uint 538976288 2694fd4e5da5Sopenharmony_ci %int = OpTypeInt 32 1 2695fd4e5da5Sopenharmony_ci%_runtimearr_int = OpTypeRuntimeArray %int 2696fd4e5da5Sopenharmony_ci %_struct_5 = OpTypeStruct %_runtimearr_int 2697fd4e5da5Sopenharmony_ci%_ptr_Uniform__struct_5 = OpTypePointer Uniform %_struct_5 2698fd4e5da5Sopenharmony_ci %3 = OpVariable %_ptr_Input_v3uint Input 2699fd4e5da5Sopenharmony_ci %7 = OpVariable %_ptr_Uniform__struct_5 Uniform 2700fd4e5da5Sopenharmony_ci %8224 = OpFunction %void None %16 2701fd4e5da5Sopenharmony_ci %65312 = OpLabel 2702fd4e5da5Sopenharmony_ci %25 = OpAccessChain %_ptr_Input_uint %3 %uint_538976288 2703fd4e5da5Sopenharmony_ci %26 = OpLoad %uint %25 2704fd4e5da5Sopenharmony_ci %2097184 = OpAtomicIIncrement %int %7 %uint_538976288 %26 2705fd4e5da5Sopenharmony_ci OpUnreachable 2706fd4e5da5Sopenharmony_ci OpFunctionEnd 2707fd4e5da5Sopenharmony_ci)"; 2708fd4e5da5Sopenharmony_ci 2709fd4e5da5Sopenharmony_ci CompileSuccessfully(spirv); 2710fd4e5da5Sopenharmony_ci EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 2711fd4e5da5Sopenharmony_ci EXPECT_THAT(getDiagnosticString(), 2712fd4e5da5Sopenharmony_ci HasSubstr("AtomicIIncrement: expected Pointer to point to a " 2713fd4e5da5Sopenharmony_ci "value of type Result Type")); 2714fd4e5da5Sopenharmony_ci} 2715fd4e5da5Sopenharmony_ci 2716fd4e5da5Sopenharmony_ci} // namespace 2717fd4e5da5Sopenharmony_ci} // namespace val 2718fd4e5da5Sopenharmony_ci} // namespace spvtools 2719