From 38ae617ca442d6d7d286e91db0dcf95c64e9c12a Mon Sep 17 00:00:00 2001 From: Ben Ashbaugh Date: Tue, 2 Jul 2024 09:39:33 -0700 Subject: [PATCH] add testing for OpExpectKHR with boolean sources (#1904) Adds a missing test case for OpExpectKHR with boolean sources. --- .../spirv_new/spirv_asm/expect_bool.spvasm32 | 111 +++++++++++++++++ .../spirv_new/spirv_asm/expect_bool.spvasm64 | 113 ++++++++++++++++++ .../spirv_new/test_cl_khr_expect_assume.cpp | 29 +++-- 3 files changed, 245 insertions(+), 8 deletions(-) create mode 100644 test_conformance/spirv_new/spirv_asm/expect_bool.spvasm32 create mode 100644 test_conformance/spirv_new/spirv_asm/expect_bool.spvasm64 diff --git a/test_conformance/spirv_new/spirv_asm/expect_bool.spvasm32 b/test_conformance/spirv_new/spirv_asm/expect_bool.spvasm32 new file mode 100644 index 0000000000..600d64afe1 --- /dev/null +++ b/test_conformance/spirv_new/spirv_asm/expect_bool.spvasm32 @@ -0,0 +1,111 @@ +; SPIR-V +; Version: 1.0 +; Generator: Khronos LLVM/SPIR-V Translator; 14 +; Bound: 58 +; Schema: 0 + OpCapability Addresses + OpCapability Linkage + OpCapability Kernel + OpCapability Vector16 + OpCapability ExpectAssumeKHR + OpExtension "SPV_KHR_expect_assume" + %1 = OpExtInstImport "OpenCL.std" + OpMemoryModel Physical32 OpenCL + OpEntryPoint Kernel %expect_bool "expect_bool" + OpSource OpenCL_C 102000 + OpDecorate %dst FuncParamAttr NoCapture + OpDecorate %dst Alignment 64 + %void = OpTypeVoid + %bool = OpTypeBool + %bool2 = OpTypeVector %bool 2 + %bool3 = OpTypeVector %bool 3 + %bool4 = OpTypeVector %bool 4 + %bool8 = OpTypeVector %bool 8 + %bool16 = OpTypeVector %bool 16 + %uint = OpTypeInt 32 0 + %uint2 = OpTypeVector %uint 2 + %uint3 = OpTypeVector %uint 3 + %uint4 = OpTypeVector %uint 4 + %uint8 = OpTypeVector %uint 8 + %uint16 = OpTypeVector %uint 16 + %uint_0 = OpConstantNull %uint + %uint2_0 = OpConstantNull %uint2 + %uint3_0 = OpConstantNull %uint3 + %uint4_0 = OpConstantNull %uint4 + %uint8_0 = OpConstantNull %uint8 + %uint16_0 = OpConstantNull %uint16 + %bool_false = OpConstantNull %bool +%bool2_false = OpConstantNull %bool2 +%bool3_false = OpConstantNull %bool3 +%bool4_false = OpConstantNull %bool4 +%bool8_false = OpConstantNull %bool8 +%bool16_false = OpConstantNull %bool16 + %index_1 = OpConstant %uint 1 + %index_2 = OpConstant %uint 2 + %index_3 = OpConstant %uint 3 + %index_4 = OpConstant %uint 4 + %index_5 = OpConstant %uint 5 +%_ptr_CrossWorkgroup_uint16 = OpTypePointer CrossWorkgroup %uint16 + %6 = OpTypeFunction %void %_ptr_CrossWorkgroup_uint16 %uint +%expect_bool = OpFunction %void None %6 + %dst = OpFunctionParameter %_ptr_CrossWorkgroup_uint16 + %value = OpFunctionParameter %uint + %10 = OpLabel + ; setup + %value_vec = OpCompositeInsert %uint2 %value %uint2_0 0 + ; scalar expect: + ; bool test = value == 0 + ; bool t1e = __builtin_expect(test, false); + ; int v1e = t1e ? 0 : value + ; dst[0] = (int16)(v1e, 0, ...); + %test = OpIEqual %bool %value %uint_0 + %t1e = OpExpectKHR %bool %test %bool_false + %v1e = OpSelect %uint %t1e %uint_0 %value + %v1v16 = OpCompositeInsert %uint16 %v1e %uint16_0 0 + OpStore %dst %v1v16 Aligned 64 + ; vec2 expect: + ; int2 v2 = (int2)(value); + ; bool2 test2 = v2 == 0 + ; bool2 t2e = __builtin_expect(test2, false2) + ; int2 v2e = t2e ? : v2; + ; dst[1] = (int16)(v2e, 0, ...); + %v2 = OpVectorShuffle %uint2 %value_vec %value_vec 0 0 + %test2 = OpIEqual %bool2 %v2 %uint2_0 + %t2e = OpExpectKHR %bool2 %test2 %bool2_false + %v2e = OpSelect %uint2 %t2e %uint2_0 %v2 + %v2v16 = OpVectorShuffle %uint16 %v2e %uint2_0 0 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + %dst_1 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_uint16 %dst %index_1 + OpStore %dst_1 %v2v16 Aligned 64 + ; vec3 expect + %v3 = OpVectorShuffle %uint3 %value_vec %value_vec 0 0 0 + %test3 = OpIEqual %bool3 %v3 %uint3_0 + %t3e = OpExpectKHR %bool3 %test3 %bool3_false + %v3e = OpSelect %uint3 %t3e %uint3_0 %v3 + %v3v16 = OpVectorShuffle %uint16 %v3e %uint2_0 0 1 2 3 3 3 3 3 3 3 3 3 3 3 3 3 + %dst_2 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_uint16 %dst %index_2 + OpStore %dst_2 %v3v16 Aligned 64 + ; vec4 expect + %v4 = OpVectorShuffle %uint4 %value_vec %value_vec 0 0 0 0 + %test4 = OpIEqual %bool4 %v4 %uint4_0 + %t4e = OpExpectKHR %bool4 %test4 %bool4_false + %v4e = OpSelect %uint4 %t4e %uint4_0 %v4 + %v4v16 = OpVectorShuffle %uint16 %v4e %uint2_0 0 1 2 3 4 4 4 4 4 4 4 4 4 4 4 4 + %dst_3 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_uint16 %dst %index_3 + OpStore %dst_3 %v4v16 Aligned 64 + ; vec8 expect + %v8 = OpVectorShuffle %uint8 %value_vec %value_vec 0 0 0 0 0 0 0 0 + %test8 = OpIEqual %bool8 %v8 %uint8_0 + %t8e = OpExpectKHR %bool8 %test8 %bool8_false + %v8e = OpSelect %uint8 %t8e %uint8_0 %v8 + %v8v16 = OpVectorShuffle %uint16 %v8e %uint2_0 0 1 2 3 4 5 6 7 8 8 8 8 8 8 8 8 + %dst_4 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_uint16 %dst %index_4 + OpStore %dst_4 %v8v16 Aligned 64 + ; vec16 expect + %v16 = OpVectorShuffle %uint16 %value_vec %value_vec 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + %test16 = OpIEqual %bool16 %v16 %uint16_0 + %t16e = OpExpectKHR %bool16 %test16 %bool16_false + %v16e = OpSelect %uint16 %t16e %uint16_0 %v16 + %dst_5 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_uint16 %dst %index_5 + OpStore %dst_5 %v16e Aligned 64 + OpReturn + OpFunctionEnd diff --git a/test_conformance/spirv_new/spirv_asm/expect_bool.spvasm64 b/test_conformance/spirv_new/spirv_asm/expect_bool.spvasm64 new file mode 100644 index 0000000000..f512a3a98e --- /dev/null +++ b/test_conformance/spirv_new/spirv_asm/expect_bool.spvasm64 @@ -0,0 +1,113 @@ +; SPIR-V +; Version: 1.0 +; Generator: Khronos LLVM/SPIR-V Translator; 14 +; Bound: 58 +; Schema: 0 + OpCapability Addresses + OpCapability Linkage + OpCapability Kernel + OpCapability Vector16 + OpCapability Int64 + OpCapability ExpectAssumeKHR + OpExtension "SPV_KHR_expect_assume" + %1 = OpExtInstImport "OpenCL.std" + OpMemoryModel Physical64 OpenCL + OpEntryPoint Kernel %expect_bool "expect_bool" + OpSource OpenCL_C 102000 + OpDecorate %dst FuncParamAttr NoCapture + OpDecorate %dst Alignment 64 + %void = OpTypeVoid + %bool = OpTypeBool + %bool2 = OpTypeVector %bool 2 + %bool3 = OpTypeVector %bool 3 + %bool4 = OpTypeVector %bool 4 + %bool8 = OpTypeVector %bool 8 + %bool16 = OpTypeVector %bool 16 + %uint = OpTypeInt 32 0 + %uint2 = OpTypeVector %uint 2 + %uint3 = OpTypeVector %uint 3 + %uint4 = OpTypeVector %uint 4 + %uint8 = OpTypeVector %uint 8 + %uint16 = OpTypeVector %uint 16 + %ulong = OpTypeInt 64 0 + %uint_0 = OpConstantNull %uint + %uint2_0 = OpConstantNull %uint2 + %uint3_0 = OpConstantNull %uint3 + %uint4_0 = OpConstantNull %uint4 + %uint8_0 = OpConstantNull %uint8 + %uint16_0 = OpConstantNull %uint16 + %bool_false = OpConstantNull %bool +%bool2_false = OpConstantNull %bool2 +%bool3_false = OpConstantNull %bool3 +%bool4_false = OpConstantNull %bool4 +%bool8_false = OpConstantNull %bool8 +%bool16_false = OpConstantNull %bool16 + %index_1 = OpConstant %ulong 1 + %index_2 = OpConstant %ulong 2 + %index_3 = OpConstant %ulong 3 + %index_4 = OpConstant %ulong 4 + %index_5 = OpConstant %ulong 5 +%_ptr_CrossWorkgroup_uint16 = OpTypePointer CrossWorkgroup %uint16 + %6 = OpTypeFunction %void %_ptr_CrossWorkgroup_uint16 %uint +%expect_bool = OpFunction %void None %6 + %dst = OpFunctionParameter %_ptr_CrossWorkgroup_uint16 + %value = OpFunctionParameter %uint + %10 = OpLabel + ; setup + %value_vec = OpCompositeInsert %uint2 %value %uint2_0 0 + ; scalar expect: + ; bool test = value == 0 + ; bool t1e = __builtin_expect(test, false); + ; int v1e = t1e ? 0 : value + ; dst[0] = (int16)(v1e, 0, ...); + %test = OpIEqual %bool %value %uint_0 + %t1e = OpExpectKHR %bool %test %bool_false + %v1e = OpSelect %uint %t1e %uint_0 %value + %v1v16 = OpCompositeInsert %uint16 %v1e %uint16_0 0 + OpStore %dst %v1v16 Aligned 64 + ; vec2 expect: + ; int2 v2 = (int2)(value); + ; bool2 test2 = v2 == 0 + ; bool2 t2e = __builtin_expect(test2, false2) + ; int2 v2e = t2e ? : v2; + ; dst[1] = (int16)(v2e, 0, ...); + %v2 = OpVectorShuffle %uint2 %value_vec %value_vec 0 0 + %test2 = OpIEqual %bool2 %v2 %uint2_0 + %t2e = OpExpectKHR %bool2 %test2 %bool2_false + %v2e = OpSelect %uint2 %t2e %uint2_0 %v2 + %v2v16 = OpVectorShuffle %uint16 %v2e %uint2_0 0 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + %dst_1 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_uint16 %dst %index_1 + OpStore %dst_1 %v2v16 Aligned 64 + ; vec3 expect + %v3 = OpVectorShuffle %uint3 %value_vec %value_vec 0 0 0 + %test3 = OpIEqual %bool3 %v3 %uint3_0 + %t3e = OpExpectKHR %bool3 %test3 %bool3_false + %v3e = OpSelect %uint3 %t3e %uint3_0 %v3 + %v3v16 = OpVectorShuffle %uint16 %v3e %uint2_0 0 1 2 3 3 3 3 3 3 3 3 3 3 3 3 3 + %dst_2 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_uint16 %dst %index_2 + OpStore %dst_2 %v3v16 Aligned 64 + ; vec4 expect + %v4 = OpVectorShuffle %uint4 %value_vec %value_vec 0 0 0 0 + %test4 = OpIEqual %bool4 %v4 %uint4_0 + %t4e = OpExpectKHR %bool4 %test4 %bool4_false + %v4e = OpSelect %uint4 %t4e %uint4_0 %v4 + %v4v16 = OpVectorShuffle %uint16 %v4e %uint2_0 0 1 2 3 4 4 4 4 4 4 4 4 4 4 4 4 + %dst_3 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_uint16 %dst %index_3 + OpStore %dst_3 %v4v16 Aligned 64 + ; vec8 expect + %v8 = OpVectorShuffle %uint8 %value_vec %value_vec 0 0 0 0 0 0 0 0 + %test8 = OpIEqual %bool8 %v8 %uint8_0 + %t8e = OpExpectKHR %bool8 %test8 %bool8_false + %v8e = OpSelect %uint8 %t8e %uint8_0 %v8 + %v8v16 = OpVectorShuffle %uint16 %v8e %uint2_0 0 1 2 3 4 5 6 7 8 8 8 8 8 8 8 8 + %dst_4 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_uint16 %dst %index_4 + OpStore %dst_4 %v8v16 Aligned 64 + ; vec16 expect + %v16 = OpVectorShuffle %uint16 %value_vec %value_vec 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + %test16 = OpIEqual %bool16 %v16 %uint16_0 + %t16e = OpExpectKHR %bool16 %test16 %bool16_false + %v16e = OpSelect %uint16 %t16e %uint16_0 %v16 + %dst_5 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_uint16 %dst %index_5 + OpStore %dst_5 %v16e Aligned 64 + OpReturn + OpFunctionEnd diff --git a/test_conformance/spirv_new/test_cl_khr_expect_assume.cpp b/test_conformance/spirv_new/test_cl_khr_expect_assume.cpp index 05c5068a03..62a3c2baca 100644 --- a/test_conformance/spirv_new/test_cl_khr_expect_assume.cpp +++ b/test_conformance/spirv_new/test_cl_khr_expect_assume.cpp @@ -23,36 +23,48 @@ template struct TestInfo }; template <> struct TestInfo { + using argType = cl_char; static constexpr const char* typeName = "char"; static constexpr const char* testName = "expect_char"; }; template <> struct TestInfo { + using argType = cl_short; static constexpr const char* typeName = "short"; static constexpr const char* testName = "expect_short"; }; template <> struct TestInfo { + using argType = cl_int; static constexpr const char* typeName = "int"; static constexpr const char* testName = "expect_int"; }; template <> struct TestInfo { + using argType = cl_long; static constexpr const char* typeName = "long"; static constexpr const char* testName = "expect_long"; }; +template <> struct TestInfo +{ + using argType = cl_int; + static constexpr const char* typeName = "bool"; + static constexpr const char* testName = "expect_bool"; +}; template static int test_expect_type(cl_device_id device, cl_context context, cl_command_queue queue) { + using ArgType = typename TestInfo::argType; + log_info(" testing type %s\n", TestInfo::typeName); - const T value = 42; + const ArgType value = 42; cl_int error = CL_SUCCESS; std::vector vecSizes({ 1, 2, 3, 4, 8, 16 }); - std::vector testData; + std::vector testData; testData.reserve(16 * vecSizes.size()); for (auto v : vecSizes) @@ -69,8 +81,8 @@ static int test_expect_type(cl_device_id device, cl_context context, } clMemWrapper dst = - clCreateBuffer(context, CL_MEM_WRITE_ONLY, testData.size() * sizeof(T), - nullptr, &error); + clCreateBuffer(context, CL_MEM_WRITE_ONLY, + testData.size() * sizeof(ArgType), nullptr, &error); test_error(error, "Unable to create destination buffer"); clProgramWrapper prog; @@ -90,10 +102,10 @@ static int test_expect_type(cl_device_id device, cl_context context, NULL, NULL); test_error(error, "Unable to enqueue kernel"); - std::vector resData(testData.size()); - error = - clEnqueueReadBuffer(queue, dst, CL_TRUE, 0, resData.size() * sizeof(T), - resData.data(), 0, NULL, NULL); + std::vector resData(testData.size()); + error = clEnqueueReadBuffer(queue, dst, CL_TRUE, 0, + resData.size() * sizeof(ArgType), + resData.data(), 0, NULL, NULL); test_error(error, "Unable to read destination buffer"); if (resData != testData) @@ -122,6 +134,7 @@ TEST_SPIRV_FUNC(op_expect) { result |= test_expect_type(deviceID, context, queue); } + result |= test_expect_type(deviceID, context, queue); return result; }