[PATCH] D34342: [OpenCL] Fix code generation of function-scope constant samplers.

Alexey Bader via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Wed Jun 21 10:39:09 PDT 2017


bader updated this revision to Diff 103421.
bader added a comment.
This revision is now accepted and ready to land.

Added test case reproducing the issue described in the description.
Removed test cases from test/SemaOpenCL/sampler_t.cl covered by test/CodeGenOpenCL/sampler.cl.

While I was moving one test case from test/SemaOpenCL/sampler_t.cl, I found another bug in CodeGen library that crashes the compilation if sampler is initialized with non-constant expression.

Here is a short reproducer:

  int get_sampler_initializer(void);
  kernel void foo() {
    const sampler_t const_smp_func_init = get_sampler_initializer();
  }

The problem is that clang does not discard this code as invalid, but CodeGen library expects sampler initializer to be a constant expression:

  llvm::Value *
  CodeGenModule::createOpenCLIntToSamplerConversion(const Expr *E,
                                                    CodeGenFunction &CGF) {
    llvm::Constant *C = EmitConstantExpr(E, E->getType(), &CGF); // for the reproducer expression here is CallExpr.
    auto SamplerT = getOpenCLRuntime().getSamplerType();
    auto FTy = llvm::FunctionType::get(SamplerT, {C->getType()}, false);
    return CGF.Builder.CreateCall(CreateRuntimeFunction(FTy,
                                  "__translate_sampler_initializer"),
                                  {C});
  }

There are two ways to handle this issue:

1. Implement diagnostics allowing only compile time constant initializers.
2. Add non-constant sampler initializer support to CodeGen library.

OpenCL specification examples give me impression that samplers declared inside OpenCL programs must be known at compile time.
On the other hand OpenCL allows samplers passed via kernel parameters to be unknown at compile time.

Thoughts?


https://reviews.llvm.org/D34342

Files:
  lib/CodeGen/CGDecl.cpp
  test/CodeGenOpenCL/sampler.cl
  test/SemaOpenCL/sampler_t.cl


Index: test/SemaOpenCL/sampler_t.cl
===================================================================
--- test/SemaOpenCL/sampler_t.cl
+++ test/SemaOpenCL/sampler_t.cl
@@ -46,36 +46,11 @@
 
 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}}
-  const sampler_t const_smp = CLK_ADDRESS_CLAMP_TO_EDGE | CLK_NORMALIZED_COORDS_TRUE | CLK_FILTER_LINEAR;
-  const sampler_t const_smp2;
-  const sampler_t const_smp3 = const_smp;
-  const sampler_t const_smp4 = f();
   const sampler_t const_smp5 = 1.0f; // expected-error{{initializing 'const sampler_t' with an expression of incompatible type 'float'}}
   const sampler_t const_smp6 = 0x100000000LL; // expected-error{{sampler_t initialization requires 32-bit integer, not 'long long'}}
 
-  foo(glb_smp);
-  foo(glb_smp2);
-  foo(glb_smp3);
-  foo(glb_smp4);
-  foo(glb_smp5);
-  foo(glb_smp6);
-  foo(glb_smp7);
-  foo(glb_smp8);
-  foo(glb_smp9);
-  foo(smp);
-  foo(sampler_str.smp);
-  foo(const_smp);
-  foo(const_smp2);
-  foo(const_smp3);
-  foo(const_smp4);
-  foo(const_smp5);
-  foo(const_smp6);
-  foo(argsmp);
-  foo(5);
   foo(5.0f); // expected-error {{passing 'float' to parameter of incompatible type 'sampler_t'}}
-  sampler_t sa[] = {argsmp, const_smp}; // expected-error {{array of 'sampler_t' type is invalid in OpenCL}}
-  foo(sa[0]);
-  foo(bad());
+  sampler_t sa[] = {argsmp, glb_smp}; // expected-error {{array of 'sampler_t' type is invalid in OpenCL}}
 }
 
 void bad(sampler_t*); // expected-error{{pointer to type 'sampler_t' is invalid in OpenCL}}
Index: test/CodeGenOpenCL/sampler.cl
===================================================================
--- test/CodeGenOpenCL/sampler.cl
+++ test/CodeGenOpenCL/sampler.cl
@@ -20,6 +20,8 @@
 constant sampler_t glb_smp = CLK_ADDRESS_CLAMP_TO_EDGE | CLK_NORMALIZED_COORDS_TRUE | CLK_FILTER_LINEAR;
 // CHECK-NOT: glb_smp
 
+int get_sampler_initializer(void);
+
 void fnc4smp(sampler_t s) {}
 // CHECK: define spir_func void @fnc4smp(%opencl.sampler_t addrspace(2)* %
 
@@ -58,4 +60,20 @@
   fnc4smp(5);
   // CHECK: [[SAMP:%[0-9]+]] = call %opencl.sampler_t addrspace(2)* @__translate_sampler_initializer(i32 5)
   // 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: 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]]
+  // CHECK: call spir_func void @fnc4smp(%opencl.sampler_t addrspace(2)* [[SAMP]])
+
+  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: call spir_func void @fnc4smp(%opencl.sampler_t addrspace(2)* [[SAMP]])
+
+  // TODO: enable sampler initialization with non-constant integer.
+  //const sampler_t const_smp_func_init = get_sampler_initializer();
 }
Index: lib/CodeGen/CGDecl.cpp
===================================================================
--- lib/CodeGen/CGDecl.cpp
+++ lib/CodeGen/CGDecl.cpp
@@ -161,6 +161,10 @@
   // needs to be emitted like a static variable, e.g. a function-scope
   // variable in constant address space in OpenCL.
   if (D.getStorageDuration() != SD_Automatic) {
+    // Static sampler variables translated to function calls.
+    if (D.getType()->isSamplerT())
+      return;
+
     llvm::GlobalValue::LinkageTypes Linkage =
         CGM.getLLVMLinkageVarDefinition(&D, /*isConstant=*/false);
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D34342.103421.patch
Type: text/x-patch
Size: 4000 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170621/8d988a51/attachment-0001.bin>


More information about the cfe-commits mailing list