Index: lib/Headers/opencl-c.h =================================================================== --- lib/Headers/opencl-c.h +++ lib/Headers/opencl-c.h @@ -14468,26 +14468,32 @@ // OpenCL v1.1 s6.11.3, v1.2 s6.12.14, v2.0 s6.13.14 - Image Read and Write Functions // These values need to match the runtime equivalent +// Sampler must specify only one mode from each of the following groups. +// To validate that requirement a bit is reserved for each distinct value +// of Addressing Mode, Coordinates and Filtering Mode. Thus there are no default +// values and all Addressing Mode, Coordinates Normalization, and Filtering +// Mode have to be specified. Any combination of two or more flags from the same +// group leads to an incorrect value which can be detected in a trivial way. // // Addressing Mode. // -#define CLK_ADDRESS_NONE 0 -#define CLK_ADDRESS_CLAMP_TO_EDGE 2 -#define CLK_ADDRESS_CLAMP 4 -#define CLK_ADDRESS_REPEAT 6 -#define CLK_ADDRESS_MIRRORED_REPEAT 8 +#define CLK_ADDRESS_NONE (1 << 2) +#define CLK_ADDRESS_CLAMP (1 << 3) +#define CLK_ADDRESS_CLAMP_TO_EDGE (1 << 4) +#define CLK_ADDRESS_REPEAT (1 << 5) +#define CLK_ADDRESS_MIRRORED_REPEAT (1 << 6) // // Coordination Normalization // -#define CLK_NORMALIZED_COORDS_FALSE 0 -#define CLK_NORMALIZED_COORDS_TRUE 1 +#define CLK_NORMALIZED_COORDS_FALSE (1 << 0) +#define CLK_NORMALIZED_COORDS_TRUE (1 << 1) // // Filtering Mode. // -#define CLK_FILTER_NEAREST 0x10 -#define CLK_FILTER_LINEAR 0x20 +#define CLK_FILTER_NEAREST (1 << 7) +#define CLK_FILTER_LINEAR (1 << 8) #ifdef cl_khr_gl_msaa_sharing #pragma OPENCL EXTENSION cl_khr_gl_msaa_sharing : enable Index: lib/Sema/SemaInit.cpp =================================================================== --- lib/Sema/SemaInit.cpp +++ lib/Sema/SemaInit.cpp @@ -7365,19 +7365,24 @@ // 32-bit value of sampler's initializer is interpreted as // bit-field with the following structure: // |unspecified|Filter|Addressing Mode| Normalized Coords| - // |31 6|5 4|3 1| 0| - // This structure corresponds to enum values of sampler properties - // defined in SPIR spec v1.2 and also opencl-c.h - unsigned AddressingMode = (0x0E & SamplerValue) >> 1; - unsigned FilterMode = (0x30 & SamplerValue) >> 4; + // |31 9|8 7|6 2| 1 0| + unsigned NormalizedCoords = (0x003 & SamplerValue) >> 0; + unsigned AddressingMode = (0x07F & SamplerValue) >> 2; + unsigned FilterMode = (0x1FF & SamplerValue) >> 7; + std::string SamplerWarning {}; + if (NormalizedCoords != 1 && NormalizedCoords != 2) + SamplerWarning += "Normalized Coords"; if (FilterMode != 1 && FilterMode != 2) + SamplerWarning += (SamplerWarning.empty() ? "Filter Mode" + : ", Filter Mode"); + // 0 or more then 1 addressing mode is used + if (!AddressingMode || AddressingMode & (AddressingMode - 1)) + SamplerWarning += (SamplerWarning.empty() ? "Addressing Mode" + : ", Addressing Mode"); + if (!SamplerWarning.empty()) S.Diag(Kind.getLocation(), diag::warn_sampler_initializer_invalid_bits) - << "Filter Mode"; - if (AddressingMode > 4) - S.Diag(Kind.getLocation(), - diag::warn_sampler_initializer_invalid_bits) - << "Addressing Mode"; + << SamplerWarning; } // Cases 1a, 2a and 2b Index: test/CodeGenOpenCL/opencl_types.cl =================================================================== --- test/CodeGenOpenCL/opencl_types.cl +++ test/CodeGenOpenCL/opencl_types.cl @@ -1,10 +1,5 @@ -// RUN: %clang_cc1 -cl-std=CL2.0 %s -triple "spir-unknown-unknown" -emit-llvm -o - -O0 | FileCheck %s --check-prefixes=CHECK-COM,CHECK-SPIR -// RUN: %clang_cc1 -cl-std=CL2.0 %s -triple "amdgcn--amdhsa" -emit-llvm -o - -O0 | FileCheck %s --check-prefixes=CHECK-COM,CHECK-AMDGCN - -#define CLK_ADDRESS_CLAMP_TO_EDGE 2 -#define CLK_NORMALIZED_COORDS_TRUE 1 -#define CLK_FILTER_NEAREST 0x10 -#define CLK_FILTER_LINEAR 0x20 +// RUN: %clang_cc1 -internal-isystem ../../lib/Headers -include opencl-c.h -cl-std=CL2.0 %s -triple "spir-unknown-unknown" -emit-llvm -o - -O0 | FileCheck %s --check-prefixes=CHECK-COM,CHECK-SPIR +// RUN: %clang_cc1 -internal-isystem ../../lib/Headers -include opencl-c.h -cl-std=CL2.0 %s -triple "amdgcn--amdhsa" -emit-llvm -o - -O0 | FileCheck %s --check-prefixes=CHECK-COM,CHECK-AMDGCN constant sampler_t glb_smp = CLK_ADDRESS_CLAMP_TO_EDGE|CLK_NORMALIZED_COORDS_TRUE|CLK_FILTER_NEAREST; // CHECK-COM-NOT: constant i32 Index: test/CodeGenOpenCL/sampler.cl =================================================================== --- test/CodeGenOpenCL/sampler.cl +++ test/CodeGenOpenCL/sampler.cl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -emit-llvm -triple spir-unknown-unknown -o - -O0 | FileCheck %s +// RUN: %clang_cc1 %s -internal-isystem ../../lib/Headers -include opencl-c.h -emit-llvm -triple spir-unknown-unknown -o - -O0 | FileCheck %s // // This test covers 5 cases of sampler initialzation: // 1. function argument passing @@ -9,11 +9,6 @@ // 2a. initializing a file-scope variable // 2b. initializing a function-scope variable -#define CLK_ADDRESS_CLAMP_TO_EDGE 2 -#define CLK_NORMALIZED_COORDS_TRUE 1 -#define CLK_FILTER_NEAREST 0x10 -#define CLK_FILTER_LINEAR 0x20 - // CHECK: %opencl.sampler_t = type opaque // Case 2a @@ -32,24 +27,24 @@ // Case 2b sampler_t smp = CLK_ADDRESS_CLAMP_TO_EDGE | CLK_NORMALIZED_COORDS_TRUE | CLK_FILTER_NEAREST; // CHECK: [[smp_ptr:%[A-Za-z0-9_\.]+]] = alloca %opencl.sampler_t addrspace(2)* - // CHECK: [[SAMP:%[0-9]+]] = call %opencl.sampler_t addrspace(2)* @__translate_sampler_initializer(i32 19) + // CHECK: [[SAMP:%[0-9]+]] = call %opencl.sampler_t addrspace(2)* @__translate_sampler_initializer(i32 146) // CHECK: store %opencl.sampler_t addrspace(2)* [[SAMP]], %opencl.sampler_t addrspace(2)** [[smp_ptr]] // Case 1b fnc4smp(smp); - // CHECK-NOT: call %opencl.sampler_t addrspace(2)* @__translate_sampler_initializer(i32 19) + // CHECK-NOT: call %opencl.sampler_t addrspace(2)* @__translate_sampler_initializer(i32 146) // CHECK: [[SAMP:%[0-9]+]] = load %opencl.sampler_t addrspace(2)*, %opencl.sampler_t addrspace(2)** [[smp_ptr]] // CHECK: call spir_func void @fnc4smp(%opencl.sampler_t addrspace(2)* [[SAMP]]) // Case 1b fnc4smp(smp); - // CHECK-NOT: call %opencl.sampler_t addrspace(2)* @__translate_sampler_initializer(i32 19) + // CHECK-NOT: call %opencl.sampler_t addrspace(2)* @__translate_sampler_initializer(i32 146) // CHECK: [[SAMP:%[0-9]+]] = load %opencl.sampler_t addrspace(2)*, %opencl.sampler_t addrspace(2)** [[smp_ptr]] // CHECK: call spir_func void @fnc4smp(%opencl.sampler_t addrspace(2)* [[SAMP]]) // Case 1a fnc4smp(glb_smp); - // CHECK: [[SAMP:%[0-9]+]] = call %opencl.sampler_t addrspace(2)* @__translate_sampler_initializer(i32 35) + // CHECK: [[SAMP:%[0-9]+]] = call %opencl.sampler_t addrspace(2)* @__translate_sampler_initializer(i32 274) // CHECK: call spir_func void @fnc4smp(%opencl.sampler_t addrspace(2)* [[SAMP]]) // Case 1c @@ -57,13 +52,13 @@ // CHECK: [[SAMP:%[0-9]+]] = load %opencl.sampler_t addrspace(2)*, %opencl.sampler_t addrspace(2)** [[smp_par_ptr]] // CHECK: call spir_func void @fnc4smp(%opencl.sampler_t addrspace(2)* [[SAMP]]) - fnc4smp(5); - // CHECK: [[SAMP:%[0-9]+]] = call %opencl.sampler_t addrspace(2)* @__translate_sampler_initializer(i32 5) + fnc4smp(274); + // CHECK: [[SAMP:%[0-9]+]] = call %opencl.sampler_t addrspace(2)* @__translate_sampler_initializer(i32 274) // CHECK: call spir_func void @fnc4smp(%opencl.sampler_t addrspace(2)* [[SAMP]]) const sampler_t const_smp = CLK_ADDRESS_CLAMP_TO_EDGE | CLK_NORMALIZED_COORDS_TRUE | CLK_FILTER_LINEAR; fnc4smp(const_smp); - // CHECK: [[CONST_SAMP:%[0-9]+]] = call %opencl.sampler_t addrspace(2)* @__translate_sampler_initializer(i32 35) + // CHECK: [[CONST_SAMP:%[0-9]+]] = call %opencl.sampler_t addrspace(2)* @__translate_sampler_initializer(i32 274) // CHECK: store %opencl.sampler_t addrspace(2)* [[CONST_SAMP]], %opencl.sampler_t addrspace(2)** [[CONST_SMP_PTR:%[a-zA-Z0-9]+]] fnc4smp(const_smp); // CHECK: [[SAMP:%[0-9]+]] = load %opencl.sampler_t addrspace(2)*, %opencl.sampler_t addrspace(2)** [[CONST_SMP_PTR]] @@ -71,7 +66,7 @@ constant sampler_t constant_smp = CLK_ADDRESS_CLAMP_TO_EDGE | CLK_NORMALIZED_COORDS_TRUE | CLK_FILTER_LINEAR; fnc4smp(constant_smp); - // CHECK: [[SAMP:%[0-9]+]] = call %opencl.sampler_t addrspace(2)* @__translate_sampler_initializer(i32 35) + // CHECK: [[SAMP:%[0-9]+]] = call %opencl.sampler_t addrspace(2)* @__translate_sampler_initializer(i32 274) // CHECK: call spir_func void @fnc4smp(%opencl.sampler_t addrspace(2)* [[SAMP]]) // TODO: enable sampler initialization with non-constant integer. Index: test/SemaOpenCL/sampler_t.cl =================================================================== --- test/SemaOpenCL/sampler_t.cl +++ test/SemaOpenCL/sampler_t.cl @@ -1,11 +1,6 @@ -// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -DCHECK_SAMPLER_VALUE -Wspir-compat -triple amdgcn--amdhsa -// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -DCHECK_SAMPLER_VALUE -triple spir-unknown-unknown - -#define CLK_ADDRESS_CLAMP_TO_EDGE 2 -#define CLK_NORMALIZED_COORDS_TRUE 1 -#define CLK_FILTER_NEAREST 0x10 -#define CLK_FILTER_LINEAR 0x20 +// RUN: %clang_cc1 %s -internal-isystem ../../lib/Headers -include opencl-c.h -verify -pedantic -fsyntax-only +// RUN: %clang_cc1 %s -internal-isystem ../../lib/Headers -include opencl-c.h -verify -pedantic -fsyntax-only -DCHECK_SAMPLER_VALUE -Wspir-compat -triple amdgcn--amdhsa +// RUN: %clang_cc1 %s -internal-isystem ../../lib/Headers -include opencl-c.h -verify -pedantic -fsyntax-only -DCHECK_SAMPLER_VALUE -triple spir-unknown-unknown constant sampler_t glb_smp = CLK_ADDRESS_CLAMP_TO_EDGE | CLK_NORMALIZED_COORDS_TRUE | CLK_FILTER_LINEAR; constant sampler_t glb_smp2; // expected-error{{variable in constant address space must be initialized}} @@ -14,22 +9,27 @@ constant sampler_t glb_smp4 = 0; #ifdef CHECK_SAMPLER_VALUE -// expected-warning@-2{{sampler initializer has invalid Filter Mode bits}} +// expected-warning@-2{{sampler initializer has invalid Normalized Coords, Filter Mode, Addressing Mode bits}} #endif -constant sampler_t glb_smp5 = 0x1f; +constant sampler_t glb_smp5 = CLK_ADDRESS_CLAMP_TO_EDGE | CLK_ADDRESS_CLAMP | CLK_NORMALIZED_COORDS_TRUE | CLK_FILTER_LINEAR; #ifdef CHECK_SAMPLER_VALUE // expected-warning@-2{{sampler initializer has invalid Addressing Mode bits}} #endif -constant sampler_t glb_smp6 = glb_smp; // expected-error{{initializer element is not a compile-time constant}} +constant sampler_t glb_smp6 = CLK_ADDRESS_CLAMP_TO_EDGE | CLK_NORMALIZED_COORDS_TRUE; +#ifdef CHECK_SAMPLER_VALUE +// expected-warning@-2{{sampler initializer has invalid Filter Mode bits}} +#endif + +constant sampler_t glb_smp7 = glb_smp; // expected-error{{initializer element is not a compile-time constant}} int f(void); -constant sampler_t glb_smp7 = f(); // expected-error{{initializer element is not a compile-time constant}} +constant sampler_t glb_smp8 = f(); // expected-error{{initializer element is not a compile-time constant}} -constant sampler_t glb_smp8 = 1.0f; // expected-error{{initializing '__constant sampler_t' with an expression of incompatible type 'float'}} +constant sampler_t glb_smp9 = 1.0f; // expected-error{{initializing '__constant sampler_t' with an expression of incompatible type 'float'}} -constant sampler_t glb_smp9 = 0x100000000LL; // expected-error{{sampler_t initialization requires 32-bit integer, not 'long long'}} +constant sampler_t glb_smp10 = 0x100000000LL; // expected-error{{sampler_t initialization requires 32-bit integer, not 'long long'}} void foo(sampler_t); // expected-note{{passing argument to parameter here}} @@ -41,8 +41,8 @@ sampler_t global_nonconst_smp = 0; // expected-error {{global sampler requires a const or constant address space qualifier}} -const sampler_t glb_smp10 = CLK_ADDRESS_CLAMP_TO_EDGE | CLK_NORMALIZED_COORDS_TRUE | CLK_FILTER_LINEAR; -const constant sampler_t glb_smp11 = CLK_ADDRESS_CLAMP_TO_EDGE | CLK_NORMALIZED_COORDS_TRUE | CLK_FILTER_LINEAR; +const sampler_t glb_smp11 = CLK_ADDRESS_CLAMP_TO_EDGE | CLK_NORMALIZED_COORDS_TRUE | CLK_FILTER_LINEAR; +const constant sampler_t glb_smp12 = CLK_ADDRESS_CLAMP_TO_EDGE | CLK_NORMALIZED_COORDS_TRUE | CLK_FILTER_LINEAR; void kernel ker(sampler_t argsmp) { local sampler_t smp; // expected-error{{sampler type cannot be used with the __local and __global address space qualifiers}}