Validate OpenCL memory and addressing model environment rules (#2589)
Signed-off-by: Kevin Petit <kevin.petit@arm.com>
diff --git a/source/val/validate_instruction.cpp b/source/val/validate_instruction.cpp
index 1a684f5..b74b535 100644
--- a/source/val/validate_instruction.cpp
+++ b/source/val/validate_instruction.cpp
@@ -511,6 +511,19 @@
<< "Memory model must be VulkanKHR for WebGPU environment.";
}
}
+
+ if (spvIsOpenCLEnv(_.context()->target_env)) {
+ if ((_.addressing_model() != SpvAddressingModelPhysical32) &&
+ (_.addressing_model() != SpvAddressingModelPhysical64)) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "Addressing model must be Physical32 or Physical64 "
+ << "in the OpenCL environment.";
+ }
+ if (_.memory_model() != SpvMemoryModelOpenCL) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "Memory model must be OpenCL in the OpenCL environment.";
+ }
+ }
} else if (opcode == SpvOpExecutionMode) {
const uint32_t entry_point = inst->word(1);
_.RegisterExecutionModeForEntryPoint(entry_point,
diff --git a/test/val/CMakeLists.txt b/test/val/CMakeLists.txt
index 9f538c2..8f4bc33 100644
--- a/test/val/CMakeLists.txt
+++ b/test/val/CMakeLists.txt
@@ -63,6 +63,7 @@
val_memory_test.cpp
val_modes_test.cpp
val_non_uniform_test.cpp
+ val_opencl_test.cpp
val_primitives_test.cpp
${VAL_TEST_COMMON_SRCS}
LIBS ${SPIRV_TOOLS}
diff --git a/test/val/val_opencl_test.cpp b/test/val/val_opencl_test.cpp
new file mode 100644
index 0000000..52e4db6
--- /dev/null
+++ b/test/val/val_opencl_test.cpp
@@ -0,0 +1,61 @@
+// Copyright (c) 2019 The Khronos Group Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Validation tests for OpenCL env specific checks
+
+#include <string>
+
+#include "gmock/gmock.h"
+#include "test/val/val_fixtures.h"
+
+namespace spvtools {
+namespace val {
+namespace {
+
+using testing::HasSubstr;
+
+using ValidateOpenCL = spvtest::ValidateBase<bool>;
+
+TEST_F(ValidateOpenCL, NonPhysicalAddressingModelBad) {
+ std::string spirv = R"(
+ OpCapability Kernel
+ OpMemoryModel Logical OpenCL
+)";
+
+ CompileSuccessfully(spirv);
+
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_OPENCL_1_2));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Addressing model must be Physical32 or Physical64 "
+ "in the OpenCL environment.\n OpMemoryModel Logical "
+ "OpenCL\n"));
+}
+
+TEST_F(ValidateOpenCL, NonOpenCLMemoryModelBad) {
+ std::string spirv = R"(
+ OpCapability Kernel
+ OpMemoryModel Physical32 GLSL450
+)";
+
+ CompileSuccessfully(spirv);
+
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_OPENCL_1_2));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Memory model must be OpenCL in the OpenCL environment."
+ "\n OpMemoryModel Physical32 GLSL450\n"));
+}
+
+} // namespace
+} // namespace val
+} // namespace spvtools
diff --git a/test/val/val_version_test.cpp b/test/val/val_version_test.cpp
index 70eb9b1..2b9542a 100644
--- a/test/val/val_version_test.cpp
+++ b/test/val/val_version_test.cpp
@@ -56,9 +56,10 @@
)";
const std::string opencl_spirv = R"(
+OpCapability Addresses
OpCapability Kernel
OpCapability Linkage
-OpMemoryModel Logical OpenCL
+OpMemoryModel Physical32 OpenCL
)";
std::string version(spv_target_env env) {