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

Yaxun Liu via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Tue Jun 27 09:28:08 PDT 2017

yaxunl added a comment.

In https://reviews.llvm.org/D34342#786941, @bader wrote:

> 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?

The OpenCL spec v1.2 s6.9.b:

The sampler type (sampler_t) can only be used as the type of a function argument or a
variable declared in the program scope or the outermost scope of a kernel function. The
behavior of a sampler variable declared in a non-outermost scope of a kernel function is
implementation-defined. A sampler argument or variable cannot be modified.
The sampler type cannot be used to declare a structure or union field, an array of
samplers, a pointer to a sampler, or the return type of a function. The sampler type cannot
be used with the __local and __global address space qualifiers.

So a function returning sampler is invalid. However, the spec does not forbid a sampler
defined in the outermost scope of a kernel function to be initialized dynamically, e.g.

  kernel void f(sampler_t s1, sampler_t s2, int x) {
    sampler_t s = x ? s1 : s2;

The question is: if we allow this, will it cause any issue?


More information about the cfe-commits mailing list