[PATCH] D33483: [OpenCL] reserve_id_t cannot be used as argument to kernel function
echuraev created this revision. Herald added a subscriber: yaxunl. https://reviews.llvm.org/D33483 Files: lib/Sema/SemaDecl.cpp test/SemaOpenCL/invalid-pipes-cl2.0.cl Index: test/SemaOpenCL/invalid-pipes-cl2.0.cl === --- test/SemaOpenCL/invalid-pipes-cl2.0.cl +++ test/SemaOpenCL/invalid-pipes-cl2.0.cl @@ -3,6 +3,11 @@ global pipe int gp;// expected-error {{type '__global read_only pipe int' can only be used as a function parameter in OpenCL}} global reserve_id_t rid; // expected-error {{the '__global reserve_id_t' type cannot be used to declare a program scope variable}} +extern pipe write_only int get_pipe(); // expected-error {{type '__global write_only pipe int ()' can only be used as a function parameter in OpenCL}} + +kernel void test_invalid_reserved_id(reserve_id_t ID) { // expected-error {{'reserve_id_t' cannot be used as the type of a kernel parameter}} +} + void test1(pipe int *p) {// expected-error {{pipes packet types cannot be of reference type}} } void test2(pipe p) {// expected-error {{missing actual type specifier for pipe}} Index: lib/Sema/SemaDecl.cpp === --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -7917,10 +7917,7 @@ if (PT->isImageType()) return PtrKernelParam; - if (PT->isBooleanType()) -return InvalidKernelParam; - - if (PT->isEventT()) + if (PT->isBooleanType() || PT->isEventT() || PT->isReserveIDT()) return InvalidKernelParam; // OpenCL extension spec v1.2 s9.5: Index: test/SemaOpenCL/invalid-pipes-cl2.0.cl === --- test/SemaOpenCL/invalid-pipes-cl2.0.cl +++ test/SemaOpenCL/invalid-pipes-cl2.0.cl @@ -3,6 +3,11 @@ global pipe int gp;// expected-error {{type '__global read_only pipe int' can only be used as a function parameter in OpenCL}} global reserve_id_t rid; // expected-error {{the '__global reserve_id_t' type cannot be used to declare a program scope variable}} +extern pipe write_only int get_pipe(); // expected-error {{type '__global write_only pipe int ()' can only be used as a function parameter in OpenCL}} + +kernel void test_invalid_reserved_id(reserve_id_t ID) { // expected-error {{'reserve_id_t' cannot be used as the type of a kernel parameter}} +} + void test1(pipe int *p) {// expected-error {{pipes packet types cannot be of reference type}} } void test2(pipe p) {// expected-error {{missing actual type specifier for pipe}} Index: lib/Sema/SemaDecl.cpp === --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -7917,10 +7917,7 @@ if (PT->isImageType()) return PtrKernelParam; - if (PT->isBooleanType()) -return InvalidKernelParam; - - if (PT->isEventT()) + if (PT->isBooleanType() || PT->isEventT() || PT->isReserveIDT()) return InvalidKernelParam; // OpenCL extension spec v1.2 s9.5: ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D33489: [OpenCL] Added regression test on invalid vector initialization.
echuraev created this revision. Herald added a subscriber: yaxunl. This patch increases code coverage. https://reviews.llvm.org/D33489 Files: test/SemaOpenCL/vector_literals_invalid.cl Index: test/SemaOpenCL/vector_literals_invalid.cl === --- test/SemaOpenCL/vector_literals_invalid.cl +++ test/SemaOpenCL/vector_literals_invalid.cl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -verify %s +// RUN: %clang_cc1 -verify %s typedef __attribute__(( ext_vector_type(4) )) float float4; typedef __attribute__(( ext_vector_type(4) )) int int4; @@ -10,4 +10,5 @@ int4 b = (int4)(1,2,3,4,5); // expected-error{{excess elements in vector}} ((float4)(1.0f))++; // expected-error{{cannot increment value of type 'float4'}} int8 d = (int8)(a,(float4)(1)); // expected-error{{initializing 'int' with an expression of incompatible type 'float4'}} + ((int4)(0)).x = 8; // expected-error{{expression is not assignable}} } Index: test/SemaOpenCL/vector_literals_invalid.cl === --- test/SemaOpenCL/vector_literals_invalid.cl +++ test/SemaOpenCL/vector_literals_invalid.cl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -verify %s +// RUN: %clang_cc1 -verify %s typedef __attribute__(( ext_vector_type(4) )) float float4; typedef __attribute__(( ext_vector_type(4) )) int int4; @@ -10,4 +10,5 @@ int4 b = (int4)(1,2,3,4,5); // expected-error{{excess elements in vector}} ((float4)(1.0f))++; // expected-error{{cannot increment value of type 'float4'}} int8 d = (int8)(a,(float4)(1)); // expected-error{{initializing 'int' with an expression of incompatible type 'float4'}} + ((int4)(0)).x = 8; // expected-error{{expression is not assignable}} } ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31745: [OpenCL] Added diagnostic for implicit declaration of function in OpenCL
echuraev updated this revision to Diff 100210. https://reviews.llvm.org/D31745 Files: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaDecl.cpp test/SemaOpenCL/clang-builtin-version.cl test/SemaOpenCL/to_addr_builtin.cl Index: test/SemaOpenCL/to_addr_builtin.cl === --- test/SemaOpenCL/to_addr_builtin.cl +++ test/SemaOpenCL/to_addr_builtin.cl @@ -10,7 +10,7 @@ glob = to_global(glob, loc); #if __OPENCL_C_VERSION__ < CL_VERSION_2_0 - // expected-warning@-2{{implicit declaration of function 'to_global' is invalid in C99}} + // expected-error@-2{{implicit declaration of function 'to_global' is invalid in OpenCL}} // expected-warning@-3{{incompatible integer to pointer conversion assigning to '__global int *' from 'int'}} #else // expected-error@-5{{invalid number of arguments to function: 'to_global'}} Index: test/SemaOpenCL/clang-builtin-version.cl === --- test/SemaOpenCL/clang-builtin-version.cl +++ test/SemaOpenCL/clang-builtin-version.cl @@ -4,41 +4,62 @@ kernel void dse_builtins() { int tmp; - enqueue_kernel(tmp, tmp, tmp, ^(void) { // expected-warning{{implicit declaration of function 'enqueue_kernel' is invalid in C99}} + enqueue_kernel(tmp, tmp, tmp, ^(void) { // expected-error{{implicit declaration of function 'enqueue_kernel' is invalid in OpenCL}} return; }); - unsigned size = get_kernel_work_group_size(^(void) { // expected-warning{{implicit declaration of function 'get_kernel_work_group_size' is invalid in C99}} + unsigned size = get_kernel_work_group_size(^(void) { // expected-error{{implicit declaration of function 'get_kernel_work_group_size' is invalid in OpenCL}} return; }); - size = get_kernel_preferred_work_group_size_multiple(^(void) { // expected-warning{{implicit declaration of function 'get_kernel_preferred_work_group_size_multiple' is invalid in C99}} + size = get_kernel_preferred_work_group_size_multiple(^(void) { // expected-error{{implicit declaration of function 'get_kernel_preferred_work_group_size_multiple' is invalid in OpenCL}} return; }); } void pipe_builtins() { int tmp; - read_pipe(tmp, tmp); // expected-warning{{implicit declaration of function 'read_pipe' is invalid in C99}} - write_pipe(tmp, tmp); // expected-warning{{implicit declaration of function 'write_pipe' is invalid in C99}} + foo(void); // expected-error{{implicit declaration of function 'foo' is invalid in OpenCL}} + // expected-note@-1{{'foo' declared here}} + // expected-error@-2{{expected expression}} + boo(); // expected-error{{implicit declaration of function 'boo' is invalid in OpenCL}} + // expected-note@-1{{did you mean 'foo'?}} - reserve_read_pipe(tmp, tmp); // expected-warning{{implicit declaration of function 'reserve_read_pipe' is invalid in C99}} - reserve_write_pipe(tmp, tmp); // expected-warning{{implicit declaration of function 'reserve_write_pipe' is invalid in C99}} + read_pipe(tmp, tmp); // expected-error{{implicit declaration of function 'read_pipe' is invalid in OpenCL}} + write_pipe(tmp, tmp); // expected-error{{implicit declaration of function 'write_pipe' is invalid in OpenCL}} - work_group_reserve_read_pipe(tmp, tmp); // expected-warning{{implicit declaration of function 'work_group_reserve_read_pipe' is invalid in C99}} - work_group_reserve_write_pipe(tmp, tmp); // expected-warning{{implicit declaration of function 'work_group_reserve_write_pipe' is invalid in C99}} + reserve_read_pipe(tmp, tmp); // expected-error{{implicit declaration of function 'reserve_read_pipe' is invalid in OpenCL}} + // expected-note@-1{{'reserve_read_pipe' declared here}} + reserve_write_pipe(tmp, tmp); // expected-error{{implicit declaration of function 'reserve_write_pipe' is invalid in OpenCL}} + // expected-note@-1{{did you mean 'reserve_read_pipe'?}} - sub_group_reserve_write_pipe(tmp, tmp); // expected-warning{{implicit declaration of function 'sub_group_reserve_write_pipe' is invalid in C99}} - sub_group_reserve_read_pipe(tmp, tmp); // expected-warning{{implicit declaration of function 'sub_group_reserve_read_pipe' is invalid in C99}} + work_group_reserve_read_pipe(tmp, tmp); // expected-error{{implicit declaration of function 'work_group_reserve_read_pipe' is invalid in OpenCL}} + // expected-note@-1 2{{'work_group_reserve_read_pipe' declared here}} + work_group_reserve_write_pipe(tmp, tmp); // expected-error{{implicit declaration of function 'work_group_reserve_write_pipe' is invalid in OpenCL}} + // expected-note@-1{{did you mean 'work_group_reserve_read_pipe'?}} + // expected-note@-2{{'work_group_reserve_write_pipe' declared here}} - commit_read_pipe(tmp, tmp); // expected-warning{{implicit declaration of function 'commit_read_pipe' is invalid in C99}} - commit_write_pipe(tmp, tmp); // expected-warning{{implicit declaration of function 'commit_write_pipe' is
[PATCH] D33353: [OpenCL] An error shall occur if any scalar operand has greater rank than the type of the vector element
echuraev updated this revision to Diff 100219. echuraev marked 2 inline comments as done. https://reviews.llvm.org/D33353 Files: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaExpr.cpp test/SemaOpenCL/arithmetic-conversions.cl test/SemaOpenCL/cond.cl Index: test/SemaOpenCL/cond.cl === --- test/SemaOpenCL/cond.cl +++ test/SemaOpenCL/cond.cl @@ -89,7 +89,7 @@ float2 ntest05(int2 C, int2 X, float Y) { - return C ? X : Y; // expected-error {{cannot convert between vector values of different size ('int2' (vector of 2 'int' values) and 'float')}} + return C ? X : Y; // expected-error {{scalar operand type has greater rank than the type of the vector element. ('int2' (vector of 2 'int' values) and 'float'}} } char2 ntest06(int2 C, char2 X, char2 Y) Index: test/SemaOpenCL/arithmetic-conversions.cl === --- /dev/null +++ test/SemaOpenCL/arithmetic-conversions.cl @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL1.2 + +typedef float float2 __attribute__((ext_vector_type(2))); +typedef long long2 __attribute__((ext_vector_type(2))); +typedef int int2 __attribute__((ext_vector_type(2))); + +kernel void foo1(float2 in, global float2 *out) { *out = in + 0.5;} // expected-error {{scalar operand type has greater rank than the type of the vector element. ('float2' (vector of 2 'float' values) and 'double')}} + +kernel void foo2(float2 in, global float2 *out) { *out = 0.5 + in;} // expected-error {{scalar operand type has greater rank than the type of the vector element. ('double' and 'float2' (vector of 2 'float' values))}} + +kernel void foo3(float2 in, global float2 *out) { *out = 0.5f + in;} + +kernel void foo4(long2 in, global long2 *out) { *out = 5 + in;} + +kernel void foo5(float2 in, global float2 *out) { +float* f; +*out = f + in; // expected-error{{cannot convert between vector and non-scalar values ('float *' and 'float2' (vector of 2 'float' values))}} +} + +kernel void foo6(int2 in, global int2 *out) { +int* f; +*out = f + in; // expected-error{{cannot convert between vector and non-scalar values ('int *' and 'int2' (vector of 2 'int' values))}} +} Index: lib/Sema/SemaExpr.cpp === --- lib/Sema/SemaExpr.cpp +++ lib/Sema/SemaExpr.cpp @@ -8064,28 +8064,38 @@ /// rank; for C, Obj-C, and C++ we allow any real scalar conversion except /// for float->int. /// +/// OpenCL V2.0 6.2.6.p2: +/// An error shall occur if any scalar operand type has greater rank +/// than the type of the vector element. +/// /// \param scalar - if non-null, actually perform the conversions /// \return true if the operation fails (but without diagnosing the failure) static bool tryVectorConvertAndSplat(Sema &S, ExprResult *scalar, QualType scalarTy, QualType vectorEltTy, - QualType vectorTy) { + QualType vectorTy, + unsigned &DiagID) { // The conversion to apply to the scalar before splatting it, // if necessary. CastKind scalarCast = CK_Invalid; if (vectorEltTy->isIntegralType(S.Context)) { -if (!scalarTy->isIntegralType(S.Context)) +if (S.getLangOpts().OpenCL && (scalarTy->isRealFloatingType() || +(scalarTy->isIntegerType() && + S.Context.getIntegerTypeOrder(vectorEltTy, scalarTy) < 0))) { + DiagID = diag::err_opencl_scalar_type_rank_greater_than_vector_type; return true; -if (S.getLangOpts().OpenCL && -S.Context.getIntegerTypeOrder(vectorEltTy, scalarTy) < 0) +} +if (!scalarTy->isIntegralType(S.Context)) return true; scalarCast = CK_IntegralCast; } else if (vectorEltTy->isRealFloatingType()) { if (scalarTy->isRealFloatingType()) { if (S.getLangOpts().OpenCL && - S.Context.getFloatingTypeOrder(vectorEltTy, scalarTy) < 0) + S.Context.getFloatingTypeOrder(vectorEltTy, scalarTy) < 0) { +DiagID = diag::err_opencl_scalar_type_rank_greater_than_vector_type; return true; + } scalarCast = CK_FloatingCast; } else if (scalarTy->isIntegralType(S.Context)) @@ -8331,10 +8341,12 @@ // If there's a vector type and a scalar, try to convert the scalar to // the vector element type and splat. + unsigned DiagID = diag::err_typecheck_vector_not_convertable; if (!RHSVecType) { if (isa(LHSVecType)) { if (!tryVectorConvertAndSplat(*this, &RHS, RHSType, -LHSVecType->getElementType(), LHSType)) +LHSVecType->getElementType(), LHSType, +DiagID)) return LHSType; } else { if (!tryGCCVectorConvertAndSplat(*this, &RHS,
[PATCH] D33592: [OpenCL] Test on half immediate support.
echuraev created this revision. Herald added a subscriber: yaxunl. https://reviews.llvm.org/D33592 Files: test/CodeGenOpenCL/half.cl Index: test/CodeGenOpenCL/half.cl === --- test/CodeGenOpenCL/half.cl +++ test/CodeGenOpenCL/half.cl @@ -21,3 +21,20 @@ { return ++x; } + +__attribute__((overloadable)) int min(int, int); +__attribute__((overloadable)) half min(half, half); +__attribute__((overloadable)) float min(float, float); + +__kernel void foo( __global half* buf, __global float* buf2 ) +{ +buf[0] = min( buf[0], 1.5h ); +// CHECK: half 0xH3E00 +buf[0] = min( buf2[0], 1.5f ); +// CHECK: float 1.50e+00 + +const half one = 1.; +buf[1] = min( buf[1], one ); +// CHECK: half 0xH3EAB +} + Index: test/CodeGenOpenCL/half.cl === --- test/CodeGenOpenCL/half.cl +++ test/CodeGenOpenCL/half.cl @@ -21,3 +21,20 @@ { return ++x; } + +__attribute__((overloadable)) int min(int, int); +__attribute__((overloadable)) half min(half, half); +__attribute__((overloadable)) float min(float, float); + +__kernel void foo( __global half* buf, __global float* buf2 ) +{ +buf[0] = min( buf[0], 1.5h ); +// CHECK: half 0xH3E00 +buf[0] = min( buf2[0], 1.5f ); +// CHECK: float 1.50e+00 + +const half one = 1.; +buf[1] = min( buf[1], one ); +// CHECK: half 0xH3EAB +} + ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D33353: [OpenCL] An error shall occur if any scalar operand has greater rank than the type of the vector element
echuraev added a comment. Hi all, I tried to reproduce this problem but I'm not able to do it... I tried to do it in two different ways: 1. I tried to build llvm by the following steps: 1.1. Checkout llvm and clang: svn co https://echur...@llvm.org/svn/llvm-project/llvm/trunk llvm svn co https://echur...@llvm.org/svn/llvm-project/cfe/trunk llvm/tools/clang 1.2. Applied patch by the following line: `arc patch D33353` 1.3. Build llvm: mkdir build cd build cmake -G "Unix Makefiles" ../llvm make -j 8 1.4. Run tests: `make check-clang` Also, I tried to run `make check-all` 1.5. As a result: all tests were passed. 2. I tried to build llvm with ninja. 2.1. This step is the same with 1.1. In the next steps I used commands from the following log: http://lab.llvm.org:8011/builders/clang-s390x-linux/builds/8741 2.2. Go to llvm dir and update svn to the target revision: `cd llvm && svn update --non-interactive --no-auth-cache --revision 303986` 2.3. Go to clang dif and update svn to the target revision: `cd tools/clang/ && svn update --non-interactive --no-auth-cache --revision 303986` 2.4. Create extra dir and update svn: `mkdir tools/extra && cd tools/extra && svn update --non-interactive --no-auth-cache --revision 303986` 2.5. Create compiler-rt dir and update svn: `cd ../../../../projects && mkdir compiler-rt && cd compiler-rt && svn update --non-interactive --no-auth-cache --revision 303986` 2.6. Generate build ninja files: cd ../../../ mkdir ninja_build && cd ninja_build cmake -G Ninja ../llvm -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_ASSERTIONS=True '-DLLVM_LIT_ARGS='"'"'-v'"'"'' -DCMAKE_INSTALL_PREFIX=../stage1.install -DLLVM_ENABLE_ASSERTIONS=ON 2.7. Run build by the following command: `ninja` 2.8. Run tests: `ninja check-all` 2.9. And also all tests were passed. Could you please help me? How can I reproduce this issue? Thank you in advance! https://reviews.llvm.org/D33353 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D33648: [OpenCL] An error shall occur if any scalar operand has greater rank than the type of the vector element
echuraev created this revision. Herald added a subscriber: yaxunl. This is the fix for patch https://reviews.llvm.org/D33353 @uweigand, could you please verify that everything will be good on SystemZ? I added triple spir-unknown-unknown. Thank you in advance! https://reviews.llvm.org/D33648 Files: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaExpr.cpp test/SemaOpenCL/arithmetic-conversions.cl test/SemaOpenCL/cond.cl Index: test/SemaOpenCL/cond.cl === --- test/SemaOpenCL/cond.cl +++ test/SemaOpenCL/cond.cl @@ -89,7 +89,7 @@ float2 ntest05(int2 C, int2 X, float Y) { - return C ? X : Y; // expected-error {{cannot convert between vector values of different size ('int2' (vector of 2 'int' values) and 'float')}} + return C ? X : Y; // expected-error {{scalar operand type has greater rank than the type of the vector element. ('int2' (vector of 2 'int' values) and 'float'}} } char2 ntest06(int2 C, char2 X, char2 Y) Index: test/SemaOpenCL/arithmetic-conversions.cl === --- /dev/null +++ test/SemaOpenCL/arithmetic-conversions.cl @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 %s -triple spir-unknown-unknown -verify -pedantic -fsyntax-only -cl-std=CL1.2 + +typedef float float2 __attribute__((ext_vector_type(2))); +typedef long long2 __attribute__((ext_vector_type(2))); +typedef int int2 __attribute__((ext_vector_type(2))); + +kernel void foo1(float2 in, global float2 *out) { *out = in + 0.5;} // expected-error {{scalar operand type has greater rank than the type of the vector element. ('float2' (vector of 2 'float' values) and 'double')}} + +kernel void foo2(float2 in, global float2 *out) { *out = 0.5 + in;} // expected-error {{scalar operand type has greater rank than the type of the vector element. ('double' and 'float2' (vector of 2 'float' values))}} + +kernel void foo3(float2 in, global float2 *out) { *out = 0.5f + in;} + +kernel void foo4(long2 in, global long2 *out) { *out = 5 + in;} + +kernel void foo5(float2 in, global float2 *out) { +float* f; +*out = f + in; // expected-error{{cannot convert between vector and non-scalar values ('float *' and 'float2' (vector of 2 'float' values))}} +} + +kernel void foo6(int2 in, global int2 *out) { +int* f; +*out = f + in; // expected-error{{cannot convert between vector and non-scalar values ('int *' and 'int2' (vector of 2 'int' values))}} +} Index: lib/Sema/SemaExpr.cpp === --- lib/Sema/SemaExpr.cpp +++ lib/Sema/SemaExpr.cpp @@ -8064,28 +8064,38 @@ /// rank; for C, Obj-C, and C++ we allow any real scalar conversion except /// for float->int. /// +/// OpenCL V2.0 6.2.6.p2: +/// An error shall occur if any scalar operand type has greater rank +/// than the type of the vector element. +/// /// \param scalar - if non-null, actually perform the conversions /// \return true if the operation fails (but without diagnosing the failure) static bool tryVectorConvertAndSplat(Sema &S, ExprResult *scalar, QualType scalarTy, QualType vectorEltTy, - QualType vectorTy) { + QualType vectorTy, + unsigned &DiagID) { // The conversion to apply to the scalar before splatting it, // if necessary. CastKind scalarCast = CK_Invalid; if (vectorEltTy->isIntegralType(S.Context)) { -if (!scalarTy->isIntegralType(S.Context)) +if (S.getLangOpts().OpenCL && (scalarTy->isRealFloatingType() || +(scalarTy->isIntegerType() && + S.Context.getIntegerTypeOrder(vectorEltTy, scalarTy) < 0))) { + DiagID = diag::err_opencl_scalar_type_rank_greater_than_vector_type; return true; -if (S.getLangOpts().OpenCL && -S.Context.getIntegerTypeOrder(vectorEltTy, scalarTy) < 0) +} +if (!scalarTy->isIntegralType(S.Context)) return true; scalarCast = CK_IntegralCast; } else if (vectorEltTy->isRealFloatingType()) { if (scalarTy->isRealFloatingType()) { if (S.getLangOpts().OpenCL && - S.Context.getFloatingTypeOrder(vectorEltTy, scalarTy) < 0) + S.Context.getFloatingTypeOrder(vectorEltTy, scalarTy) < 0) { +DiagID = diag::err_opencl_scalar_type_rank_greater_than_vector_type; return true; + } scalarCast = CK_FloatingCast; } else if (scalarTy->isIntegralType(S.Context)) @@ -8331,10 +8341,12 @@ // If there's a vector type and a scalar, try to convert the scalar to // the vector element type and splat. + unsigned DiagID = diag::err_typecheck_vector_not_convertable; if (!RHSVecType) { if (isa(LHSVecType)) { if (!tryVectorConvertAndSplat(*this, &RHS, RHSType, -LHSVecType->getElementType(), LHSType)) +
[PATCH] D27569: [OpenCL] Enabling the usage of CLK_NULL_QUEUE as compare operand.
echuraev updated this revision to Diff 81742. echuraev marked 3 inline comments as done. https://reviews.llvm.org/D27569 Files: include/clang/AST/OperationKinds.def include/clang/Sema/Initialization.h include/clang/Sema/Overload.h lib/AST/ExprConstant.cpp lib/CodeGen/CGExprAgg.cpp lib/CodeGen/CGExprComplex.cpp lib/CodeGen/CGExprScalar.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaExprCXX.cpp lib/Sema/SemaInit.cpp lib/Sema/SemaOverload.cpp test/CodeGenOpenCL/null_queue.cl test/SemaOpenCL/null_queue.cl test/SemaOpenCL/queue_t_overload.cl Index: test/SemaOpenCL/queue_t_overload.cl === --- /dev/null +++ test/SemaOpenCL/queue_t_overload.cl @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 %s -cl-std=CL2.0 -verify -pedantic -fsyntax-only + +void __attribute__((overloadable)) foo(queue_t, __local char *); // expected-note {{candidate function}} +void __attribute__((overloadable)) foo(queue_t, __local float *); // expected-note {{candidate function}} + +void kernel ker(__local char *src1, __local float *src2, __global int *src3) { + queue_t q; + foo(q, src1); + foo(0, src2); + foo(q, src3); // expected-error {{call to 'foo' is ambiguous}} +} Index: test/SemaOpenCL/null_queue.cl === --- /dev/null +++ test/SemaOpenCL/null_queue.cl @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 %s -cl-std=CL2.0 -verify -pedantic -fsyntax-only +extern queue_t get_default_queue(); + +bool compare() { + return 1 == get_default_queue() && // expected-error{{invalid operands to binary expression ('int' and 'queue_t')}} + get_default_queue() == 1; // expected-error{{invalid operands to binary expression ('queue_t' and 'int')}} +} + +void init() { + queue_t q1 = 1; // expected-error{{initializing 'queue_t' with an expression of incompatible type 'int'}} + queue_t q = 0; +} Index: test/CodeGenOpenCL/null_queue.cl === --- /dev/null +++ test/CodeGenOpenCL/null_queue.cl @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -O0 -cl-std=CL2.0 -emit-llvm %s -o - | FileCheck %s +extern queue_t get_default_queue(); + +bool compare() { + return 0 == get_default_queue() && + get_default_queue() == 0; + // CHECK: icmp eq %opencl.queue_t* null, %{{.*}} + // CHECK: icmp eq %opencl.queue_t* %{{.*}}, null +} + +void func(queue_t q); + +void init() { + queue_t q = 0; + func(0); + // CHECK: store %opencl.queue_t* null, %opencl.queue_t** %q + // CHECK: call void @func(%opencl.queue_t* null) +} Index: lib/Sema/SemaOverload.cpp === --- lib/Sema/SemaOverload.cpp +++ lib/Sema/SemaOverload.cpp @@ -1781,6 +1781,11 @@ From->EvaluateKnownConstInt(S.getASTContext()) == 0) { SCS.Second = ICK_Zero_Event_Conversion; FromType = ToType; + } else if (ToType->isQueueT() && + From->isIntegerConstantExpr(S.getASTContext()) && + (From->EvaluateKnownConstInt(S.getASTContext()) == 0)) { +SCS.Second = ICK_Zero_Queue_Conversion; +FromType = ToType; } else { // No second conversion required. SCS.Second = ICK_Identity; @@ -5155,6 +5160,7 @@ case ICK_Function_Conversion: case ICK_Integral_Promotion: case ICK_Integral_Conversion: // Narrowing conversions are checked elsewhere. + case ICK_Zero_Queue_Conversion: return true; case ICK_Boolean_Conversion: Index: lib/Sema/SemaInit.cpp === --- lib/Sema/SemaInit.cpp +++ lib/Sema/SemaInit.cpp @@ -3073,6 +3073,7 @@ case SK_StdInitializerListConstructorCall: case SK_OCLSamplerInit: case SK_OCLZeroEvent: + case SK_OCLZeroQueue: break; case SK_ConversionSequence: @@ -3334,6 +3335,13 @@ Steps.push_back(S); } +void InitializationSequence::AddOCLZeroQueueStep(QualType T) { + Step S; + S.Kind = SK_OCLZeroQueue; + S.Type = T; + Steps.push_back(S); +} + void InitializationSequence::RewrapReferenceInitList(QualType T, InitListExpr *Syntactic) { assert(Syntactic->getNumInits() == 1 && @@ -4981,6 +4989,20 @@ return true; } +static bool TryOCLZeroQueueInitialization(Sema &S, + InitializationSequence &Sequence, + QualType DestType, + Expr *Initializer) { + if (!S.getLangOpts().OpenCL || S.getLangOpts().OpenCLVersion < 200 || + !DestType->isQueueT() || + !Initializer->isIntegerConstantExpr(S.getASTContext()) || + (Initializer->EvaluateKnownConstInt(S.getASTContext()) != 0)) +return false; + + Sequence.AddOCLZeroQueueStep(DestType); + return true; +} + InitializationSequence::InitializationSequence(Sema &S, const InitializedEntity &Entity,
[PATCH] D27569: [OpenCL] Enabling the usage of CLK_NULL_QUEUE as compare operand.
echuraev updated this revision to Diff 81917. echuraev marked an inline comment as done. https://reviews.llvm.org/D27569 Files: include/clang/AST/OperationKinds.def include/clang/Sema/Initialization.h include/clang/Sema/Overload.h lib/AST/ExprConstant.cpp lib/CodeGen/CGExprAgg.cpp lib/CodeGen/CGExprComplex.cpp lib/CodeGen/CGExprScalar.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaExprCXX.cpp lib/Sema/SemaInit.cpp lib/Sema/SemaOverload.cpp test/CodeGenOpenCL/null_queue.cl test/SemaOpenCL/null_queue.cl test/SemaOpenCL/queue_t_overload.cl Index: test/SemaOpenCL/queue_t_overload.cl === --- /dev/null +++ test/SemaOpenCL/queue_t_overload.cl @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 %s -cl-std=CL2.0 -verify -pedantic -fsyntax-only + +void __attribute__((overloadable)) foo(queue_t, __local char *); // expected-note {{candidate function not viable: no known conversion from 'int' to 'queue_t' for 1st argument}} // expected-note {{candidate function}} +void __attribute__((overloadable)) foo(queue_t, __local float *); // expected-note {{candidate function not viable: no known conversion from 'int' to 'queue_t' for 1st argument}} // expected-note {{candidate function}} + +void kernel ker(__local char *src1, __local float *src2, __global int *src3) { + queue_t q; + foo(q, src1); + foo(0, src2); + foo(q, src3); // expected-error {{call to 'foo' is ambiguous}} + foo(1, src3); // expected-error {{no matching function for call to 'foo'}} +} Index: test/SemaOpenCL/null_queue.cl === --- /dev/null +++ test/SemaOpenCL/null_queue.cl @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 %s -cl-std=CL2.0 -verify -pedantic -fsyntax-only +extern queue_t get_default_queue(); + +bool compare() { + return 1 == get_default_queue() && // expected-error{{invalid operands to binary expression ('int' and 'queue_t')}} + get_default_queue() == 1; // expected-error{{invalid operands to binary expression ('queue_t' and 'int')}} +} + +void init() { + queue_t q1 = 1; // expected-error{{initializing 'queue_t' with an expression of incompatible type 'int'}} + queue_t q = 0; +} Index: test/CodeGenOpenCL/null_queue.cl === --- /dev/null +++ test/CodeGenOpenCL/null_queue.cl @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -O0 -cl-std=CL2.0 -emit-llvm %s -o - | FileCheck %s +extern queue_t get_default_queue(); + +bool compare() { + return 0 == get_default_queue() && + get_default_queue() == 0; + // CHECK: icmp eq %opencl.queue_t* null, %{{.*}} + // CHECK: icmp eq %opencl.queue_t* %{{.*}}, null +} + +void func(queue_t q); + +void init() { + queue_t q = 0; + func(0); + // CHECK: store %opencl.queue_t* null, %opencl.queue_t** %q + // CHECK: call void @func(%opencl.queue_t* null) +} Index: lib/Sema/SemaOverload.cpp === --- lib/Sema/SemaOverload.cpp +++ lib/Sema/SemaOverload.cpp @@ -1781,6 +1781,11 @@ From->EvaluateKnownConstInt(S.getASTContext()) == 0) { SCS.Second = ICK_Zero_Event_Conversion; FromType = ToType; + } else if (ToType->isQueueT() && + From->isIntegerConstantExpr(S.getASTContext()) && + (From->EvaluateKnownConstInt(S.getASTContext()) == 0)) { +SCS.Second = ICK_Zero_Queue_Conversion; +FromType = ToType; } else { // No second conversion required. SCS.Second = ICK_Identity; @@ -5155,6 +5160,7 @@ case ICK_Function_Conversion: case ICK_Integral_Promotion: case ICK_Integral_Conversion: // Narrowing conversions are checked elsewhere. + case ICK_Zero_Queue_Conversion: return true; case ICK_Boolean_Conversion: Index: lib/Sema/SemaInit.cpp === --- lib/Sema/SemaInit.cpp +++ lib/Sema/SemaInit.cpp @@ -3073,6 +3073,7 @@ case SK_StdInitializerListConstructorCall: case SK_OCLSamplerInit: case SK_OCLZeroEvent: + case SK_OCLZeroQueue: break; case SK_ConversionSequence: @@ -3334,6 +3335,13 @@ Steps.push_back(S); } +void InitializationSequence::AddOCLZeroQueueStep(QualType T) { + Step S; + S.Kind = SK_OCLZeroQueue; + S.Type = T; + Steps.push_back(S); +} + void InitializationSequence::RewrapReferenceInitList(QualType T, InitListExpr *Syntactic) { assert(Syntactic->getNumInits() == 1 && @@ -4981,6 +4989,20 @@ return true; } +static bool TryOCLZeroQueueInitialization(Sema &S, + InitializationSequence &Sequence, + QualType DestType, + Expr *Initializer) { + if (!S.getLangOpts().OpenCL || S.getLangOpts().OpenCLVersion < 200 || + !DestType->isQueueT() || + !Initializer->isIntegerConstantExpr(S.getASTContext()) || + (I
[PATCH] D27917: [OpenCL] Improve diagnostics for double type
echuraev created this revision. echuraev added a reviewer: Anastasia. echuraev added subscribers: bader, cfe-commits, yaxunl. https://reviews.llvm.org/D27917 Files: include/clang/AST/Type.h lib/AST/Type.cpp lib/Sema/SemaType.cpp test/SemaOpenCL/unknown_type.cl Index: test/SemaOpenCL/unknown_type.cl === --- /dev/null +++ test/SemaOpenCL/unknown_type.cl @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -cl-std=CL1.1 -fsyntax-only -verify %s +typedef double double2 __attribute__((ext_vector_type(2))); // expected-error {{use of type 'double' requires cl_khr_fp64 extension to be enabled}} +typedef double double16 __attribute__((ext_vector_type(16))); // expected-error {{use of type 'double' requires cl_khr_fp64 extension to be enabled}} +#pragma OPENCL EXTENSION all : disable +void foo() +{ +(double)(3.14); // expected-error {{use of type 'double' requires cl_khr_fp64 extension to be enabled}} // expected-warning {{double precision constant requires cl_khr_fp64, casting to single precision}} +(double2)(1.0, 3.14); // expected-error {{use of type 'double2' (vector of 2 'double' values) requires cl_khr_fp64 extension to be enabled}} +// expected-warning@-1 2{{double precision constant requires cl_khr_fp64, casting to single precision}} +(double16)(123455.134, 123455.134, 2.0, -12345.032, -12345.032, 1.0, 1.0, 2.0, 2.0, 0.0, 0.0, 0.0, -1.23, -1.23, 1.0, 123455.134); // expected-error {{use of type 'double16' (vector of 16 'double' values) requires cl_khr_fp64 extension to be enabled}} +// expected-warning@-1 16{{double precision constant requires cl_khr_fp64, casting to single precision}} +} Index: lib/Sema/SemaType.cpp === --- lib/Sema/SemaType.cpp +++ lib/Sema/SemaType.cpp @@ -1500,6 +1500,12 @@ S.Diag(DS.getTypeSpecTypeLoc(), diag::err_type_requires_extension) << Result << "cl_khr_gl_msaa_sharing"; declarator.setInvalidType(true); + } else if ((Result->isDoubleType() || Result->isDoubleVecType()) && + S.getLangOpts().OpenCLVersion < 120 && + !S.getOpenCLOptions().cl_khr_fp64) { +S.Diag(DS.getTypeSpecTypeLoc(), diag::err_type_requires_extension) +<< Result << "cl_khr_fp64"; +declarator.setInvalidType(true); } } Index: lib/AST/Type.cpp === --- lib/AST/Type.cpp +++ lib/AST/Type.cpp @@ -1809,6 +1809,19 @@ return false; } +bool Type::isDoubleType() const { + if (const BuiltinType *BT = dyn_cast(CanonicalType)) +return BT->getKind() >= BuiltinType::Double && + BT->getKind() <= BuiltinType::LongDouble; + return false; +} + +bool Type::isDoubleVecType() const { + if (const VectorType *VT = dyn_cast(CanonicalType)) +return VT->getElementType()->isDoubleType(); + return false; +} + bool Type::hasFloatingRepresentation() const { if (const VectorType *VT = dyn_cast(CanonicalType)) return VT->getElementType()->isFloatingType(); Index: include/clang/AST/Type.h === --- include/clang/AST/Type.h +++ include/clang/AST/Type.h @@ -1649,6 +1649,8 @@ bool isAnyComplexType() const; // C99 6.2.5p11 (complex) + Complex Int. bool isFloatingType() const; // C99 6.2.5p11 (real floating + complex) bool isHalfType() const; // OpenCL 6.1.1.1, NEON (IEEE 754-2008 half) + bool isDoubleType() const; // (double + long double) + bool isDoubleVecType() const; bool isRealType() const; // C99 6.2.5p17 (real floating + integer) bool isArithmeticType() const; // C99 6.2.5p18 (integer + floating) bool isVoidType() const; // C99 6.2.5p19 Index: test/SemaOpenCL/unknown_type.cl === --- /dev/null +++ test/SemaOpenCL/unknown_type.cl @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -cl-std=CL1.1 -fsyntax-only -verify %s +typedef double double2 __attribute__((ext_vector_type(2))); // expected-error {{use of type 'double' requires cl_khr_fp64 extension to be enabled}} +typedef double double16 __attribute__((ext_vector_type(16))); // expected-error {{use of type 'double' requires cl_khr_fp64 extension to be enabled}} +#pragma OPENCL EXTENSION all : disable +void foo() +{ +(double)(3.14); // expected-error {{use of type 'double' requires cl_khr_fp64 extension to be enabled}} // expected-warning {{double precision constant requires cl_khr_fp64, casting to single precision}} +(double2)(1.0, 3.14); // expected-error {{use of type 'double2' (vector of 2 'double' values) requires cl_khr_fp64 extension to be enabled}} +// expected-warning@-1 2{{double precision constant requires cl_khr_fp64, casting to single precision}} +(double16)(123455.134, 123455.134, 2.0, -12345.032, -12345.032, 1.0, 1.0, 2.0, 2.0, 0.0,
[PATCH] D27981: Fix problems in "[OpenCL] Enabling the usage of CLK_NULL_QUEUE as compare operand."
echuraev created this revision. echuraev added reviewers: djasper, Anastasia. echuraev added subscribers: bader, cfe-commits, yaxunl. Fixed warnings in commit: https://reviews.llvm.org/rL290171 https://reviews.llvm.org/D27981 Files: include/clang/AST/OperationKinds.def include/clang/Sema/Initialization.h include/clang/Sema/Overload.h lib/AST/Expr.cpp lib/AST/ExprConstant.cpp lib/CodeGen/CGExpr.cpp lib/CodeGen/CGExprAgg.cpp lib/CodeGen/CGExprComplex.cpp lib/CodeGen/CGExprConstant.cpp lib/CodeGen/CGExprScalar.cpp lib/Edit/RewriteObjCFoundationAPI.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaExprCXX.cpp lib/Sema/SemaInit.cpp lib/Sema/SemaOverload.cpp lib/StaticAnalyzer/Core/ExprEngineC.cpp test/CodeGenOpenCL/null_queue.cl test/SemaOpenCL/null_queue.cl test/SemaOpenCL/queue_t_overload.cl Index: test/SemaOpenCL/queue_t_overload.cl === --- /dev/null +++ test/SemaOpenCL/queue_t_overload.cl @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 %s -cl-std=CL2.0 -verify -pedantic -fsyntax-only + +void __attribute__((overloadable)) foo(queue_t, __local char *); // expected-note {{candidate function not viable: no known conversion from 'int' to 'queue_t' for 1st argument}} // expected-note {{candidate function}} +void __attribute__((overloadable)) foo(queue_t, __local float *); // expected-note {{candidate function not viable: no known conversion from 'int' to 'queue_t' for 1st argument}} // expected-note {{candidate function}} + +void kernel ker(__local char *src1, __local float *src2, __global int *src3) { + queue_t q; + foo(q, src1); + foo(0, src2); + foo(q, src3); // expected-error {{call to 'foo' is ambiguous}} + foo(1, src3); // expected-error {{no matching function for call to 'foo'}} +} Index: test/SemaOpenCL/null_queue.cl === --- /dev/null +++ test/SemaOpenCL/null_queue.cl @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 %s -cl-std=CL2.0 -verify -pedantic -fsyntax-only +extern queue_t get_default_queue(); + +bool compare() { + return 1 == get_default_queue() && // expected-error{{invalid operands to binary expression ('int' and 'queue_t')}} + get_default_queue() == 1; // expected-error{{invalid operands to binary expression ('queue_t' and 'int')}} +} + +void init() { + queue_t q1 = 1; // expected-error{{initializing 'queue_t' with an expression of incompatible type 'int'}} + queue_t q = 0; +} Index: test/CodeGenOpenCL/null_queue.cl === --- /dev/null +++ test/CodeGenOpenCL/null_queue.cl @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -O0 -cl-std=CL2.0 -emit-llvm %s -o - | FileCheck %s +extern queue_t get_default_queue(); + +bool compare() { + return 0 == get_default_queue() && + get_default_queue() == 0; + // CHECK: icmp eq %opencl.queue_t* null, %{{.*}} + // CHECK: icmp eq %opencl.queue_t* %{{.*}}, null +} + +void func(queue_t q); + +void init() { + queue_t q = 0; + func(0); + // CHECK: store %opencl.queue_t* null, %opencl.queue_t** %q + // CHECK: call void @func(%opencl.queue_t* null) +} Index: lib/StaticAnalyzer/Core/ExprEngineC.cpp === --- lib/StaticAnalyzer/Core/ExprEngineC.cpp +++ lib/StaticAnalyzer/Core/ExprEngineC.cpp @@ -341,6 +341,7 @@ case CK_AnyPointerToBlockPointerCast: case CK_ObjCObjectLValueCast: case CK_ZeroToOCLEvent: + case CK_ZeroToOCLQueue: case CK_IntToOCLSampler: case CK_LValueBitCast: { // Delegate to SValBuilder to process. Index: lib/Sema/SemaOverload.cpp === --- lib/Sema/SemaOverload.cpp +++ lib/Sema/SemaOverload.cpp @@ -1781,6 +1781,11 @@ From->EvaluateKnownConstInt(S.getASTContext()) == 0) { SCS.Second = ICK_Zero_Event_Conversion; FromType = ToType; + } else if (ToType->isQueueT() && + From->isIntegerConstantExpr(S.getASTContext()) && + (From->EvaluateKnownConstInt(S.getASTContext()) == 0)) { +SCS.Second = ICK_Zero_Queue_Conversion; +FromType = ToType; } else { // No second conversion required. SCS.Second = ICK_Identity; @@ -5155,6 +5160,7 @@ case ICK_Function_Conversion: case ICK_Integral_Promotion: case ICK_Integral_Conversion: // Narrowing conversions are checked elsewhere. + case ICK_Zero_Queue_Conversion: return true; case ICK_Boolean_Conversion: Index: lib/Sema/SemaInit.cpp === --- lib/Sema/SemaInit.cpp +++ lib/Sema/SemaInit.cpp @@ -3073,6 +3073,7 @@ case SK_StdInitializerListConstructorCall: case SK_OCLSamplerInit: case SK_OCLZeroEvent: + case SK_OCLZeroQueue: break; case SK_ConversionSequence: @@ -3334,6 +3335,13 @@ Steps.push_back(S); } +void InitializationSequence::AddOCLZeroQueueStep(QualType T) { + Ste
[PATCH] D27917: [OpenCL] Improve diagnostics for double type
echuraev updated this revision to Diff 82094. echuraev marked an inline comment as done. https://reviews.llvm.org/D27917 Files: include/clang/AST/Type.h lib/AST/Type.cpp lib/Sema/SemaType.cpp test/SemaOpenCL/unknown_type.cl Index: test/SemaOpenCL/unknown_type.cl === --- /dev/null +++ test/SemaOpenCL/unknown_type.cl @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -cl-std=CL1.1 -fsyntax-only -verify %s +typedef double double2 __attribute__((ext_vector_type(2))); // expected-error {{use of type 'double' requires cl_khr_fp64 extension to be enabled}} +typedef double double16 __attribute__((ext_vector_type(16))); // expected-error {{use of type 'double' requires cl_khr_fp64 extension to be enabled}} +#pragma OPENCL EXTENSION all : disable +void foo() +{ +(double)(3.14); // expected-error {{use of type 'double' requires cl_khr_fp64 extension to be enabled}} // expected-warning {{double precision constant requires cl_khr_fp64, casting to single precision}} +(double2)(1.0, 3.14); // expected-error {{use of type 'double2' (vector of 2 'double' values) requires cl_khr_fp64 extension to be enabled}} +// expected-warning@-1 2{{double precision constant requires cl_khr_fp64, casting to single precision}} +(double16)(123455.134, 123455.134, 2.0, -12345.032, -12345.032, 1.0, 1.0, 2.0, 2.0, 0.0, 0.0, 0.0, -1.23, -1.23, 1.0, 123455.134); // expected-error {{use of type 'double16' (vector of 16 'double' values) requires cl_khr_fp64 extension to be enabled}} +// expected-warning@-1 16{{double precision constant requires cl_khr_fp64, casting to single precision}} +} Index: lib/Sema/SemaType.cpp === --- lib/Sema/SemaType.cpp +++ lib/Sema/SemaType.cpp @@ -1500,6 +1500,12 @@ S.Diag(DS.getTypeSpecTypeLoc(), diag::err_type_requires_extension) << Result << "cl_khr_gl_msaa_sharing"; declarator.setInvalidType(true); + } else if ((Result->isDoubleType() || Result->isDoubleVecType()) && + S.getLangOpts().OpenCLVersion < 120 && + !S.getOpenCLOptions().isEnabled("cl_khr_fp64")) { +S.Diag(DS.getTypeSpecTypeLoc(), diag::err_type_requires_extension) +<< Result << "cl_khr_fp64"; +declarator.setInvalidType(true); } } Index: lib/AST/Type.cpp === --- lib/AST/Type.cpp +++ lib/AST/Type.cpp @@ -1809,6 +1809,19 @@ return false; } +bool Type::isDoubleType() const { + if (const BuiltinType *BT = dyn_cast(CanonicalType)) +return BT->getKind() >= BuiltinType::Double && + BT->getKind() <= BuiltinType::LongDouble; + return false; +} + +bool Type::isDoubleVecType() const { + if (const VectorType *VT = dyn_cast(CanonicalType)) +return VT->getElementType()->isDoubleType(); + return false; +} + bool Type::hasFloatingRepresentation() const { if (const VectorType *VT = dyn_cast(CanonicalType)) return VT->getElementType()->isFloatingType(); Index: include/clang/AST/Type.h === --- include/clang/AST/Type.h +++ include/clang/AST/Type.h @@ -1649,6 +1649,8 @@ bool isAnyComplexType() const; // C99 6.2.5p11 (complex) + Complex Int. bool isFloatingType() const; // C99 6.2.5p11 (real floating + complex) bool isHalfType() const; // OpenCL 6.1.1.1, NEON (IEEE 754-2008 half) + bool isDoubleType() const; // (double + long double) + bool isDoubleVecType() const; bool isRealType() const; // C99 6.2.5p17 (real floating + integer) bool isArithmeticType() const; // C99 6.2.5p18 (integer + floating) bool isVoidType() const; // C99 6.2.5p19 Index: test/SemaOpenCL/unknown_type.cl === --- /dev/null +++ test/SemaOpenCL/unknown_type.cl @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -cl-std=CL1.1 -fsyntax-only -verify %s +typedef double double2 __attribute__((ext_vector_type(2))); // expected-error {{use of type 'double' requires cl_khr_fp64 extension to be enabled}} +typedef double double16 __attribute__((ext_vector_type(16))); // expected-error {{use of type 'double' requires cl_khr_fp64 extension to be enabled}} +#pragma OPENCL EXTENSION all : disable +void foo() +{ +(double)(3.14); // expected-error {{use of type 'double' requires cl_khr_fp64 extension to be enabled}} // expected-warning {{double precision constant requires cl_khr_fp64, casting to single precision}} +(double2)(1.0, 3.14); // expected-error {{use of type 'double2' (vector of 2 'double' values) requires cl_khr_fp64 extension to be enabled}} +// expected-warning@-1 2{{double precision constant requires cl_khr_fp64, casting to single precision}} +(double16)(123455.134, 123455.134, 2.0, -12345.032, -12345.032, 1.0, 1.0, 2.0, 2.0, 0.0, 0.0, 0.0, -1.23, -1.23,
[PATCH] D28048: [OpenCL] Align fake address space map with the SPIR target maps.
echuraev created this revision. echuraev added a reviewer: Anastasia. echuraev added subscribers: cfe-commits, bader, yaxunl. We compile user opencl kernel code with spir triple. But built-ins are written in OpenCL and we compile it with triple x86_64 to be able to use x86 intrinsics. And we need address spaces to match in both cases. So, we change fake address space map in OpenCL for matching with spir. On CPU address spaces are not really important but we'd like to preserve address space information in order to perform optimizations relying on this info like enhanced alias analysis. https://reviews.llvm.org/D28048 Files: lib/AST/ASTContext.cpp test/CodeGen/blocks-opencl.cl test/CodeGenOpenCL/address-space-constant-initializers.cl test/CodeGenOpenCL/address-spaces-mangling.cl test/CodeGenOpenCL/address-spaces.cl test/CodeGenOpenCL/cl20-device-side-enqueue.cl test/CodeGenOpenCL/const-str-array-decay.cl test/CodeGenOpenCL/constant-addr-space-globals.cl test/CodeGenOpenCL/local-initializer-undef.cl test/CodeGenOpenCL/local.cl test/CodeGenOpenCL/memcpy.cl test/CodeGenOpenCL/str_literals.cl test/SemaOpenCL/extern.cl Index: test/SemaOpenCL/extern.cl === --- test/SemaOpenCL/extern.cl +++ test/SemaOpenCL/extern.cl @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -x cl -cl-opt-disable -cl-std=CL1.2 -emit-llvm -ffake-address-space-map %s -o - -verify | FileCheck %s // expected-no-diagnostics -// CHECK: @foo = external addrspace(3) constant float +// CHECK: @foo = external addrspace(2) constant float extern constant float foo; kernel void test(global float* buf) { Index: test/CodeGenOpenCL/str_literals.cl === --- test/CodeGenOpenCL/str_literals.cl +++ test/CodeGenOpenCL/str_literals.cl @@ -3,7 +3,7 @@ __constant char * __constant x = "hello world"; __constant char * __constant y = "hello world"; -// CHECK: unnamed_addr addrspace(3) constant -// CHECK-NOT: addrspace(3) unnamed_addr constant -// CHECK: @x = addrspace(3) constant i8 addrspace(3)* -// CHECK: @y = addrspace(3) constant i8 addrspace(3)* +// CHECK: unnamed_addr addrspace(2) constant +// CHECK-NOT: addrspace(2) unnamed_addr constant +// CHECK: @x = addrspace(2) constant i8 addrspace(2)* +// CHECK: @y = addrspace(2) constant i8 addrspace(2)* Index: test/CodeGenOpenCL/memcpy.cl === --- test/CodeGenOpenCL/memcpy.cl +++ test/CodeGenOpenCL/memcpy.cl @@ -2,7 +2,7 @@ // CHECK-LABEL: @test // CHECK-NOT: addrspacecast -// CHECK: call void @llvm.memcpy.p1i8.p3i8 +// CHECK: call void @llvm.memcpy.p1i8.p2i8 kernel void test(global float *g, constant float *c) { __builtin_memcpy(g, c, 32); } Index: test/CodeGenOpenCL/local.cl === --- test/CodeGenOpenCL/local.cl +++ test/CodeGenOpenCL/local.cl @@ -3,7 +3,7 @@ void func(local int*); __kernel void foo(void) { - // CHECK: @foo.i = internal addrspace(2) global i32 undef + // CHECK: @foo.i = internal addrspace(3) global i32 undef __local int i; func(&i); } Index: test/CodeGenOpenCL/local-initializer-undef.cl === --- test/CodeGenOpenCL/local-initializer-undef.cl +++ test/CodeGenOpenCL/local-initializer-undef.cl @@ -6,10 +6,10 @@ float z; } Foo; -// CHECK-DAG: @test.lds_int = internal addrspace(2) global i32 undef -// CHECK-DAG: @test.lds_int_arr = internal addrspace(2) global [128 x i32] undef -// CHECK-DAG: @test.lds_struct = internal addrspace(2) global %struct.Foo undef -// CHECK-DAG: @test.lds_struct_arr = internal addrspace(2) global [64 x %struct.Foo] undef +// CHECK-DAG: @test.lds_int = internal addrspace(3) global i32 undef +// CHECK-DAG: @test.lds_int_arr = internal addrspace(3) global [128 x i32] undef +// CHECK-DAG: @test.lds_struct = internal addrspace(3) global %struct.Foo undef +// CHECK-DAG: @test.lds_struct_arr = internal addrspace(3) global [64 x %struct.Foo] undef __kernel void test() { __local int lds_int; Index: test/CodeGenOpenCL/constant-addr-space-globals.cl === --- test/CodeGenOpenCL/constant-addr-space-globals.cl +++ test/CodeGenOpenCL/constant-addr-space-globals.cl @@ -12,9 +12,9 @@ // in the constant address space). void foo(constant const int *p1, const int *p2, const int *p3); -// CHECK: @k.arr1 = internal addrspace(3) constant [3 x i32] [i32 1, i32 2, i32 3] -// CHECK: @k.arr2 = private unnamed_addr addrspace(3) constant [3 x i32] [i32 4, i32 5, i32 6] -// CHECK: @k.arr3 = private unnamed_addr addrspace(3) constant [3 x i32] [i32 7, i32 8, i32 9] +// CHECK: @k.arr1 = internal addrspace(2) constant [3 x i32] [i32 1, i32 2, i32 3] +// CHECK: @k.arr2 = private unnamed_addr addrspace(2) constant [3 x i32] [i32 4, i32 5, i32 6] +// CHECK: @k.arr3 = pr
[PATCH] D28136: [OpenCL] Implement as_type operator as alias of __builtin_astype.
echuraev created this revision. echuraev added a reviewer: Anastasia. echuraev added subscribers: bader, yaxunl, cfe-commits. https://reviews.llvm.org/D28136 Files: lib/Headers/opencl-c.h Index: lib/Headers/opencl-c.h === --- lib/Headers/opencl-c.h +++ lib/Headers/opencl-c.h @@ -6578,777 +6578,86 @@ * OpenCL v1.1/1.2/2.0 s6.2.4.2 - as_type operators * Reinterprets a data type as another data type of the same size */ -char __ovld __cnfn as_char(char); -char __ovld __cnfn as_char(uchar); - -char2 __ovld __cnfn as_char2(char2); -char2 __ovld __cnfn as_char2(uchar2); -char2 __ovld __cnfn as_char2(short); -char2 __ovld __cnfn as_char2(ushort); - -char3 __ovld __cnfn as_char3(char3); -char3 __ovld __cnfn as_char3(char4); -char3 __ovld __cnfn as_char3(uchar3); -char3 __ovld __cnfn as_char3(uchar4); -char3 __ovld __cnfn as_char3(short2); -char3 __ovld __cnfn as_char3(ushort2); -char3 __ovld __cnfn as_char3(int); -char3 __ovld __cnfn as_char3(uint); -char3 __ovld __cnfn as_char3(float); - -char4 __ovld __cnfn as_char4(char3); -char4 __ovld __cnfn as_char4(char4); -char4 __ovld __cnfn as_char4(uchar3); -char4 __ovld __cnfn as_char4(uchar4); -char4 __ovld __cnfn as_char4(short2); -char4 __ovld __cnfn as_char4(ushort2); -char4 __ovld __cnfn as_char4(int); -char4 __ovld __cnfn as_char4(uint); -char4 __ovld __cnfn as_char4(float); - -char8 __ovld __cnfn as_char8(char8); -char8 __ovld __cnfn as_char8(uchar8); -char8 __ovld __cnfn as_char8(short3); -char8 __ovld __cnfn as_char8(short4); -char8 __ovld __cnfn as_char8(ushort3); -char8 __ovld __cnfn as_char8(ushort4); -char8 __ovld __cnfn as_char8(int2); -char8 __ovld __cnfn as_char8(uint2); -char8 __ovld __cnfn as_char8(long); -char8 __ovld __cnfn as_char8(ulong); -char8 __ovld __cnfn as_char8(float2); - -char16 __ovld __cnfn as_char16(char16); -char16 __ovld __cnfn as_char16(uchar16); -char16 __ovld __cnfn as_char16(short8); -char16 __ovld __cnfn as_char16(ushort8); -char16 __ovld __cnfn as_char16(int3); -char16 __ovld __cnfn as_char16(int4); -char16 __ovld __cnfn as_char16(uint3); -char16 __ovld __cnfn as_char16(uint4); -char16 __ovld __cnfn as_char16(long2); -char16 __ovld __cnfn as_char16(ulong2); -char16 __ovld __cnfn as_char16(float3); -char16 __ovld __cnfn as_char16(float4); - -uchar __ovld __cnfn as_uchar(char); -uchar __ovld __cnfn as_uchar(uchar); - -uchar2 __ovld __cnfn as_uchar2(char2); -uchar2 __ovld __cnfn as_uchar2(uchar2); -uchar2 __ovld __cnfn as_uchar2(short); -uchar2 __ovld __cnfn as_uchar2(ushort); - -uchar3 __ovld __cnfn as_uchar3(char3); -uchar3 __ovld __cnfn as_uchar3(char4); -uchar3 __ovld __cnfn as_uchar3(uchar3); -uchar3 __ovld __cnfn as_uchar3(uchar4); -uchar3 __ovld __cnfn as_uchar3(short2); -uchar3 __ovld __cnfn as_uchar3(ushort2); -uchar3 __ovld __cnfn as_uchar3(int); -uchar3 __ovld __cnfn as_uchar3(uint); -uchar3 __ovld __cnfn as_uchar3(float); - -uchar4 __ovld __cnfn as_uchar4(char3); -uchar4 __ovld __cnfn as_uchar4(char4); -uchar4 __ovld __cnfn as_uchar4(uchar3); -uchar4 __ovld __cnfn as_uchar4(uchar4); -uchar4 __ovld __cnfn as_uchar4(short2); -uchar4 __ovld __cnfn as_uchar4(ushort2); -uchar4 __ovld __cnfn as_uchar4(int); -uchar4 __ovld __cnfn as_uchar4(uint); -uchar4 __ovld __cnfn as_uchar4(float); - -uchar8 __ovld __cnfn as_uchar8(char8); -uchar8 __ovld __cnfn as_uchar8(uchar8); -uchar8 __ovld __cnfn as_uchar8(short3); -uchar8 __ovld __cnfn as_uchar8(short4); -uchar8 __ovld __cnfn as_uchar8(ushort3); -uchar8 __ovld __cnfn as_uchar8(ushort4); -uchar8 __ovld __cnfn as_uchar8(int2); -uchar8 __ovld __cnfn as_uchar8(uint2); -uchar8 __ovld __cnfn as_uchar8(long); -uchar8 __ovld __cnfn as_uchar8(ulong); -uchar8 __ovld __cnfn as_uchar8(float2); - -uchar16 __ovld __cnfn as_uchar16(char16); -uchar16 __ovld __cnfn as_uchar16(uchar16); -uchar16 __ovld __cnfn as_uchar16(short8); -uchar16 __ovld __cnfn as_uchar16(ushort8); -uchar16 __ovld __cnfn as_uchar16(int3); -uchar16 __ovld __cnfn as_uchar16(int4); -uchar16 __ovld __cnfn as_uchar16(uint3); -uchar16 __ovld __cnfn as_uchar16(uint4); -uchar16 __ovld __cnfn as_uchar16(long2); -uchar16 __ovld __cnfn as_uchar16(ulong2); -uchar16 __ovld __cnfn as_uchar16(float3); -uchar16 __ovld __cnfn as_uchar16(float4); - -short __ovld __cnfn as_short(char2); -short __ovld __cnfn as_short(uchar2); -short __ovld __cnfn as_short(short); -short __ovld __cnfn as_short(ushort); - -short2 __ovld __cnfn as_short2(char3); -short2 __ovld __cnfn as_short2(char4); -short2 __ovld __cnfn as_short2(uchar3); -short2 __ovld __cnfn as_short2(uchar4); -short2 __ovld __cnfn as_short2(short2); -short2 __ovld __cnfn as_short2(ushort2); -short2 __ovld __cnfn as_short2(int); -short2 __ovld __cnfn as_short2(uint); -short2 __ovld __cnfn as_short2(float); - -short3 __ovld __cnfn as_short3(char8); -short3 __ovld __cnfn as_short3(uchar8); -short3 __ovld __cnfn as_short3(short3); -short3 __ovld __cnfn as_short3(short4); -short3 __ovld __cnfn as_short3(ushort3); -short3 __ovl
[PATCH] D30937: [OpenCL] Added diagnostic for checking length of vector
echuraev updated this revision to Diff 91890. echuraev marked 5 inline comments as done. Herald added a subscriber: yaxunl. https://reviews.llvm.org/D30937 Files: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaExprMember.cpp test/SemaOpenCL/vector_swizzle_length.cl Index: test/SemaOpenCL/vector_swizzle_length.cl === --- /dev/null +++ test/SemaOpenCL/vector_swizzle_length.cl @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only + +typedef float float8 __attribute__((ext_vector_type(8))); + +void foo() { +float8 f2 = (float8)(0, 0, 0, 0, 0, 0, 0, 0); + +f2.s01234; // expected-error {{vector component access has invalid length 5. Supported: 1,2,3,4,8,16}} +f2.xyzxy; // expected-error {{vector component access has invalid length 5. Supported: 1,2,3,4,8,16}} +} Index: lib/Sema/SemaExprMember.cpp === --- lib/Sema/SemaExprMember.cpp +++ lib/Sema/SemaExprMember.cpp @@ -284,6 +284,14 @@ } } +// OpenCL v1.1, s6.1.7 +// The component swizzle length must be in accordance with the acceptable +// vector sizes. +static bool IsValidOpenCLComponentSwizzleLength(unsigned len) +{ + return (len >= 1 && len <= 4) || len == 8 || len == 16; +} + /// Check an ext-vector component access expression. /// /// VK should be set in advance to the value kind of the base @@ -376,6 +384,19 @@ } } + if (!HalvingSwizzle) { +unsigned SwizzleLength = CompName->getLength(); + +if (HexSwizzle) + SwizzleLength--; + +if (IsValidOpenCLComponentSwizzleLength(SwizzleLength) == false) { + S.Diag(OpLoc, diag::err_opencl_ext_vector_component_invalid_length) +<< SwizzleLength << SourceRange(CompLoc); + return QualType(); +} + } + // The component accessor looks fine - now we need to compute the actual type. // The vector type is implied by the component accessor. For example, // vec4.b is a float, vec4.xy is a vec2, vec4.rgb is a vec3, etc. Index: include/clang/Basic/DiagnosticSemaKinds.td === --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -8236,6 +8236,8 @@ def err_kernel_arg_address_space : Error< "pointer arguments to kernel functions must reside in '__global', " "'__constant' or '__local' address space">; +def err_opencl_ext_vector_component_invalid_length : Error< + "vector component access has invalid length %0. Supported: 1,2,3,4,8,16.">; def err_opencl_function_variable : Error< "%select{non-kernel function|function scope}0 variable cannot be declared in %1 address space">; def err_static_function_scope : Error< Index: test/SemaOpenCL/vector_swizzle_length.cl === --- /dev/null +++ test/SemaOpenCL/vector_swizzle_length.cl @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only + +typedef float float8 __attribute__((ext_vector_type(8))); + +void foo() { +float8 f2 = (float8)(0, 0, 0, 0, 0, 0, 0, 0); + +f2.s01234; // expected-error {{vector component access has invalid length 5. Supported: 1,2,3,4,8,16}} +f2.xyzxy; // expected-error {{vector component access has invalid length 5. Supported: 1,2,3,4,8,16}} +} Index: lib/Sema/SemaExprMember.cpp === --- lib/Sema/SemaExprMember.cpp +++ lib/Sema/SemaExprMember.cpp @@ -284,6 +284,14 @@ } } +// OpenCL v1.1, s6.1.7 +// The component swizzle length must be in accordance with the acceptable +// vector sizes. +static bool IsValidOpenCLComponentSwizzleLength(unsigned len) +{ + return (len >= 1 && len <= 4) || len == 8 || len == 16; +} + /// Check an ext-vector component access expression. /// /// VK should be set in advance to the value kind of the base @@ -376,6 +384,19 @@ } } + if (!HalvingSwizzle) { +unsigned SwizzleLength = CompName->getLength(); + +if (HexSwizzle) + SwizzleLength--; + +if (IsValidOpenCLComponentSwizzleLength(SwizzleLength) == false) { + S.Diag(OpLoc, diag::err_opencl_ext_vector_component_invalid_length) +<< SwizzleLength << SourceRange(CompLoc); + return QualType(); +} + } + // The component accessor looks fine - now we need to compute the actual type. // The vector type is implied by the component accessor. For example, // vec4.b is a float, vec4.xy is a vec2, vec4.rgb is a vec3, etc. Index: include/clang/Basic/DiagnosticSemaKinds.td === --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -8236,6 +8236,8 @@ def err_kernel_arg_address_space : Error< "pointer arguments to kernel functions must reside in '__global', " "'__constant' or '__local' address space">; +def err_opencl_
[PATCH] D31183: [OpenCL] Added parsing for OpenCL vector types.
echuraev created this revision. Herald added a subscriber: yaxunl. https://reviews.llvm.org/D31183 Files: include/clang/Parse/Parser.h lib/Parse/ParseExpr.cpp test/Parser/vector-cast-define.cl Index: test/Parser/vector-cast-define.cl === --- /dev/null +++ test/Parser/vector-cast-define.cl @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only +// expected-no-diagnostics + +typedef int int3 __attribute__((ext_vector_type(3))); + +#define i3(x, y, z) (int3)(x, y, z) +#define dgSize i3(32+2,32+2,32+2) + +void test() +{ +int index = dgSize.x * dgSize.y; +} + Index: lib/Parse/ParseExpr.cpp === --- lib/Parse/ParseExpr.cpp +++ lib/Parse/ParseExpr.cpp @@ -473,12 +473,14 @@ /// ExprResult Parser::ParseCastExpression(bool isUnaryExpression, bool isAddressOfOperand, - TypeCastState isTypeCast) { + TypeCastState isTypeCast, + bool isVectorLiteral) { bool NotCastExpr; ExprResult Res = ParseCastExpression(isUnaryExpression, isAddressOfOperand, NotCastExpr, - isTypeCast); + isTypeCast, + isVectorLiteral); if (NotCastExpr) Diag(Tok, diag::err_expected_expression); return Res; @@ -694,7 +696,8 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression, bool isAddressOfOperand, bool &NotCastExpr, - TypeCastState isTypeCast) { + TypeCastState isTypeCast, + bool isVectorLiteral) { ExprResult Res; tok::TokenKind SavedKind = Tok.getKind(); NotCastExpr = false; @@ -722,6 +725,9 @@ Res = ParseParenExpression(ParenExprType, false/*stopIfCastExr*/, isTypeCast == IsTypeCast, CastTy, RParenLoc); +if (isVectorLiteral) +return Res; + switch (ParenExprType) { case SimpleExpr: break;// Nothing else to do. case CompoundStmt: break; // Nothing else to do. @@ -2350,6 +2356,48 @@ return ParseCompoundLiteralExpression(Ty.get(), OpenLoc, RParenLoc); } + if (Tok.is(tok::l_paren)) { +// This could be OpenCL vector Literals +if (getLangOpts().OpenCL) +{ + TypeResult Ty; + { +InMessageExpressionRAIIObject InMessage(*this, false); +Ty = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); + } + if(Ty.isInvalid()) + { + return ExprError(); + } + QualType QT = Ty.get().get().getCanonicalType(); + if (QT->isVectorType()) + { +// We parsed '(' vector-type-name ')' followed by '(' + +// Parse the cast-expression that follows it next. +// isVectorLiteral = true will make sure we don't parse any +// Postfix expression yet +Result = ParseCastExpression(/*isUnaryExpression=*/false, + /*isAddressOfOperand=*/false, + /*isTypeCast=*/IsTypeCast, + /*isVectorLiteral=*/true); + +if (!Result.isInvalid()) { + Result = Actions.ActOnCastExpr(getCurScope(), OpenLoc, + DeclaratorInfo, CastTy, + RParenLoc, Result.get()); +} + +// After we performed the cast we can check for postfix-expr pieces. +if (!Result.isInvalid()) { + Result = ParsePostfixExpressionSuffix(Result); +} + +return Result; + } +} + } + if (ExprType == CastExpr) { // We parsed '(' type-name ')' and the thing after it wasn't a '{'. @@ -2379,10 +2427,13 @@ } // Parse the cast-expression that follows it next. +// isVectorLiteral = true will make sure we don't parse any +// Postfix expression yet // TODO: For cast expression with CastTy. Result = ParseCastExpression(/*isUnaryExpression=*/false, /*isAddressOfOperand=*/false, - /*isTypeCast=*/IsTypeCast); + /*isTypeCast=*/IsTypeCast, + /*isVectorLiteral=*/true); if (!Result.isInvalid()) { Result = Actions.ActOnCastExpr(getCurScope(), OpenLoc, Declara
[PATCH] D31183: [OpenCL] Added parsing for OpenCL vector types.
echuraev added a comment. In https://reviews.llvm.org/D31183#708833, @yaxunl wrote: > I think this is a good feature for the convenience of user. I've seen usage > like this. I agree. I don't see any reasons why this case doesn't have the right to exist. I don't think that using extra parenthesis is a good solution for solving this problem. https://reviews.llvm.org/D31183 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31321: [OpenCL] Do not generate "kernel_arg_type_qual" metadata for non-pointer args
echuraev created this revision. Herald added a subscriber: yaxunl. "kernel_arg_type_qual" metadata should contain const/volatile/restrict tags only for pointer types to match the corresponding requirement of the OpenCL specification. OpenCL 2.0 spec 5.9.3 Kernel Object Queries: CL_KERNEL_ARG_TYPE_VOLATILE is returned if the argument is a pointer and the referenced type is declared with the volatile qualifier. [...] Similarly, CL_KERNEL_ARG_TYPE_CONST is returned if the argument is a pointer and the referenced type is declared with the restrict or const qualifier. [...] CL_KERNEL_ARG_TYPE_RESTRICT will be returned if the pointer type is marked restrict. https://reviews.llvm.org/D31321 Files: lib/CodeGen/CodeGenFunction.cpp test/CodeGenOpenCL/kernel-arg-info.cl Index: test/CodeGenOpenCL/kernel-arg-info.cl === --- test/CodeGenOpenCL/kernel-arg-info.cl +++ test/CodeGenOpenCL/kernel-arg-info.cl @@ -63,7 +63,7 @@ // CHECK: ![[MD11]] = !{i32 1, i32 0, i32 0, i32 2} // CHECK: ![[MD12]] = !{!"none", !"none", !"none", !"none"} // CHECK: ![[MD13]] = !{!"int*", !"int", !"int", !"float*"} -// CHECK: ![[MD14]] = !{!"restrict", !"const", !"volatile", !"restrict const"} +// CHECK: ![[MD14]] = !{!"restrict", !"", !"", !"restrict const"} // ARGINFO: ![[MD15]] = !{!"X", !"Y", !"anotherArg", !"Z"} // CHECK: ![[MD21]] = !{i32 1, i32 1, i32 1, i32 1} // CHECK: ![[MD22]] = !{!"read_only", !"read_only", !"write_only", !"read_write"} Index: lib/CodeGen/CodeGenFunction.cpp === --- lib/CodeGen/CodeGenFunction.cpp +++ lib/CodeGen/CodeGenFunction.cpp @@ -610,11 +610,6 @@ argBaseTypeNames.push_back(llvm::MDString::get(Context, baseTypeName)); - // Get argument type qualifiers: - if (ty.isConstQualified()) -typeQuals = "const"; - if (ty.isVolatileQualified()) -typeQuals += typeQuals.empty() ? "volatile" : " volatile"; if (isPipe) typeQuals = "pipe"; } Index: test/CodeGenOpenCL/kernel-arg-info.cl === --- test/CodeGenOpenCL/kernel-arg-info.cl +++ test/CodeGenOpenCL/kernel-arg-info.cl @@ -63,7 +63,7 @@ // CHECK: ![[MD11]] = !{i32 1, i32 0, i32 0, i32 2} // CHECK: ![[MD12]] = !{!"none", !"none", !"none", !"none"} // CHECK: ![[MD13]] = !{!"int*", !"int", !"int", !"float*"} -// CHECK: ![[MD14]] = !{!"restrict", !"const", !"volatile", !"restrict const"} +// CHECK: ![[MD14]] = !{!"restrict", !"", !"", !"restrict const"} // ARGINFO: ![[MD15]] = !{!"X", !"Y", !"anotherArg", !"Z"} // CHECK: ![[MD21]] = !{i32 1, i32 1, i32 1, i32 1} // CHECK: ![[MD22]] = !{!"read_only", !"read_only", !"write_only", !"read_write"} Index: lib/CodeGen/CodeGenFunction.cpp === --- lib/CodeGen/CodeGenFunction.cpp +++ lib/CodeGen/CodeGenFunction.cpp @@ -610,11 +610,6 @@ argBaseTypeNames.push_back(llvm::MDString::get(Context, baseTypeName)); - // Get argument type qualifiers: - if (ty.isConstQualified()) -typeQuals = "const"; - if (ty.isVolatileQualified()) -typeQuals += typeQuals.empty() ? "volatile" : " volatile"; if (isPipe) typeQuals = "pipe"; } ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31324: [OpenCL] Extended mapping of parcing CodeGen arguments
echuraev created this revision. Herald added a subscriber: yaxunl. Enable cl_mad_enamle and cl_no_signed_zeros options when user turns on cl_unsafe_math_optimizations or cl_fast_relaxed_math options. https://reviews.llvm.org/D31324 Files: lib/Frontend/CompilerInvocation.cpp test/CodeGenOpenCL/relaxed-fpmath.cl Index: test/CodeGenOpenCL/relaxed-fpmath.cl === --- test/CodeGenOpenCL/relaxed-fpmath.cl +++ test/CodeGenOpenCL/relaxed-fpmath.cl @@ -2,33 +2,54 @@ // RUN: %clang_cc1 %s -emit-llvm -cl-fast-relaxed-math -o - | FileCheck %s -check-prefix=FAST // RUN: %clang_cc1 %s -emit-llvm -cl-finite-math-only -o - | FileCheck %s -check-prefix=FINITE // RUN: %clang_cc1 %s -emit-llvm -cl-unsafe-math-optimizations -o - | FileCheck %s -check-prefix=UNSAFE - -typedef __attribute__(( ext_vector_type(4) )) float float4; +// RUN: %clang_cc1 %s -emit-llvm -cl-mad-enable -o - | FileCheck %s -check-prefix=MAD +// RUN: %clang_cc1 %s -emit-llvm -cl-no-signed-zeros -o - | FileCheck %s -check-prefix=NOSIGNED float spscalardiv(float a, float b) { // CHECK: @spscalardiv( - // NORMAL: fdiv float + // NORMAL: fdiv float // FAST: fdiv fast float // FINITE: fdiv nnan ninf float - // UNSAFE: fdiv nnan float + // UNSAFE: fdiv nnan nsz float + // MAD: fdiv float + // NOSIGNED: fdiv nsz float return a / b; } // CHECK: attributes +// NORMAL: "less-precise-fpmad"="false" // NORMAL: "no-infs-fp-math"="false" // NORMAL: "no-nans-fp-math"="false" +// NORMAL: "no-signed-zeros-fp-math"="false" // NORMAL: "unsafe-fp-math"="false" +// FAST: "less-precise-fpmad"="true" // FAST: "no-infs-fp-math"="true" // FAST: "no-nans-fp-math"="true" +// FAST: "no-signed-zeros-fp-math"="true" // FAST: "unsafe-fp-math"="true" +// FINITE: "less-precise-fpmad"="false" // FINITE: "no-infs-fp-math"="true" // FINITE: "no-nans-fp-math"="true" +// FINITE: "no-signed-zeros-fp-math"="false" // FINITE: "unsafe-fp-math"="false" +// UNSAFE: "less-precise-fpmad"="true" // UNSAFE: "no-infs-fp-math"="false" // UNSAFE: "no-nans-fp-math"="true" +// UNSAFE: "no-signed-zeros-fp-math"="true" // UNSAFE: "unsafe-fp-math"="true" +// MAD: "less-precise-fpmad"="true" +// MAD: "no-infs-fp-math"="false" +// MAD: "no-nans-fp-math"="false" +// MAD: "no-signed-zeros-fp-math"="false" +// MAD: "unsafe-fp-math"="false" + +// NOSIGNED: "less-precise-fpmad"="false" +// NOSIGNED: "no-infs-fp-math"="false" +// NOSIGNED: "no-nans-fp-math"="false" +// NOSIGNED: "no-signed-zeros-fp-math"="true" +// NOSIGNED: "unsafe-fp-math"="false" Index: lib/Frontend/CompilerInvocation.cpp === --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -573,7 +573,9 @@ Opts.DiscardValueNames = Args.hasArg(OPT_discard_value_names); Opts.DisableTailCalls = Args.hasArg(OPT_mdisable_tail_calls); Opts.FloatABI = Args.getLastArgValue(OPT_mfloat_abi); - Opts.LessPreciseFPMAD = Args.hasArg(OPT_cl_mad_enable); + Opts.LessPreciseFPMAD = Args.hasArg(OPT_cl_mad_enable) || + Args.hasArg(OPT_cl_unsafe_math_optimizations) || + Args.hasArg(OPT_cl_fast_relaxed_math); Opts.LimitFloatPrecision = Args.getLastArgValue(OPT_mlimit_float_precision); Opts.NoInfsFPMath = (Args.hasArg(OPT_menable_no_infinities) || Args.hasArg(OPT_cl_finite_math_only) || @@ -583,7 +585,9 @@ Args.hasArg(OPT_cl_finite_math_only) || Args.hasArg(OPT_cl_fast_relaxed_math)); Opts.NoSignedZeros = (Args.hasArg(OPT_fno_signed_zeros) || -Args.hasArg(OPT_cl_no_signed_zeros)); +Args.hasArg(OPT_cl_no_signed_zeros) || +Args.hasArg(OPT_cl_unsafe_math_optimizations) || +Args.hasArg(OPT_cl_fast_relaxed_math)); Opts.FlushDenorm = Args.hasArg(OPT_cl_denorms_are_zero); Opts.CorrectlyRoundedDivSqrt = Args.hasArg(OPT_cl_fp32_correctly_rounded_divide_sqrt); Index: test/CodeGenOpenCL/relaxed-fpmath.cl === --- test/CodeGenOpenCL/relaxed-fpmath.cl +++ test/CodeGenOpenCL/relaxed-fpmath.cl @@ -2,33 +2,54 @@ // RUN: %clang_cc1 %s -emit-llvm -cl-fast-relaxed-math -o - | FileCheck %s -check-prefix=FAST // RUN: %clang_cc1 %s -emit-llvm -cl-finite-math-only -o - | FileCheck %s -check-prefix=FINITE // RUN: %clang_cc1 %s -emit-llvm -cl-unsafe-math-optimizations -o - | FileCheck %s -check-prefix=UNSAFE - -typedef __attribute__(( ext_vector_type(4) )) float float4; +// RUN: %clang_cc1 %s -emit-llvm -cl-mad-enable -o - | FileCheck %s -check-prefix=MAD +// RUN: %clang_cc1 %s -emit-llvm -cl-no-signed-zeros -o - | FileCheck %s -check-prefix=NOSIGNED float spscalardiv(float a, float b) { // CHECK: @spscalardiv( - // NORMAL: fdiv float + // NORMAL: fdiv float
[PATCH] D31183: [OpenCL] Added parsing for OpenCL vector types.
echuraev added a comment. In https://reviews.llvm.org/D31183#710202, @Anastasia wrote: > In https://reviews.llvm.org/D31183#709566, @echuraev wrote: > > > In https://reviews.llvm.org/D31183#708833, @yaxunl wrote: > > > > > I think this is a good feature for the convenience of user. I've seen > > > usage like this. > > > > > > I agree. I don't see any reasons why this case doesn't have the right to > > exist. I don't think that using extra parenthesis is a good solution for > > solving this problem. > > > I am just saying that I don't see a big use case for this. I am guessing it > can largely come from the macro expansions, but those are generally good > style to parenthesize. Ok. But in current implementation if I forget to parenthesize the defined expression (as in the test) I will get the following message: "error: member reference base type 'int' is not a structure or union". I don't think that the message is clear to understand that you just forgot to add parenthesis. So, should we change the diagnostic message to do it more understandable or push this patch because it can be more convenience for users? https://reviews.llvm.org/D31183 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30643: [OpenCL] Extended diagnostics for atomic initialization
echuraev updated this revision to Diff 93113. echuraev marked 2 inline comments as done. echuraev removed a reviewer: bader. echuraev added a subscriber: bader. https://reviews.llvm.org/D30643 Files: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaExpr.cpp lib/Sema/SemaInit.cpp test/Parser/opencl-atomics-cl20.cl test/SemaOpenCL/atomic-init.cl Index: test/SemaOpenCL/atomic-init.cl === --- /dev/null +++ test/SemaOpenCL/atomic-init.cl @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -O0 -cl-std=CL2.0 -fsyntax-only -verify %s + +global atomic_int a1 = 0; + +kernel void test_atomic_initialization() { + a1 = 1; // expected-error {{atomic variable can only be assigned to a compile time constant and to variables in global adress space}} + atomic_int a2 = 0; // expected-error {{atomic variable can only be assigned to a compile time constant and to variables in global adress space}} + private atomic_int a3 = 0; // expected-error {{atomic variable can only be assigned to a compile time constant and to variables in global adress space}} + local atomic_int a4 = 0; // expected-error {{'__local' variable cannot have an initializer}} + global atomic_int a5 = 0; // expected-error {{function scope variable cannot be declared in global address space}} +} Index: test/Parser/opencl-atomics-cl20.cl === --- test/Parser/opencl-atomics-cl20.cl +++ test/Parser/opencl-atomics-cl20.cl @@ -67,7 +67,7 @@ foo(&i); // OpenCL v2.0 s6.13.11.8, arithemtic operations are not permitted on atomic types. i++; // expected-error {{invalid argument type 'atomic_int' (aka '_Atomic(int)') to unary expression}} - i = 1; // expected-error {{atomic variable can only be assigned to a compile time constant in the declaration statement in the program scope}} + i = 1; // expected-error {{atomic variable can only be assigned to a compile time constant and to variables in global adress space}} i += 1; // expected-error {{invalid operands to binary expression ('atomic_int' (aka '_Atomic(int)') and 'int')}} i = i + i; // expected-error {{invalid operands to binary expression ('atomic_int' (aka '_Atomic(int)') and 'atomic_int')}} } Index: lib/Sema/SemaInit.cpp === --- lib/Sema/SemaInit.cpp +++ lib/Sema/SemaInit.cpp @@ -6502,6 +6502,20 @@ << Init->getSourceRange(); } + // OpenCL v2.0 s6.13.11.1. atomic variables can be initialized in global scope + QualType ETy = Entity.getType(); + Qualifiers TyQualifiers = ETy.getQualifiers(); + bool HasGlobalAS = TyQualifiers.hasAddressSpace() && + TyQualifiers.getAddressSpace() == LangAS::opencl_global; + + if (S.getLangOpts().OpenCLVersion >= 200 && + ETy->isAtomicType() && !HasGlobalAS && + Entity.getKind() == InitializedEntity::EK_Variable && Args.size() > 0) { +S.Diag(Args[0]->getLocStart(), diag::err_opencl_atomic_init) << +SourceRange(Entity.getDecl()->getLocStart(), Args[0]->getLocEnd()); +return ExprError(); + } + // Diagnose cases where we initialize a pointer to an array temporary, and the // pointer obviously outlives the temporary. if (Args.size() == 1 && Args[0]->getType()->isArrayType() && Index: lib/Sema/SemaExpr.cpp === --- lib/Sema/SemaExpr.cpp +++ lib/Sema/SemaExpr.cpp @@ -2,7 +2,7 @@ if (LHSTy->isAtomicType() || RHSTy->isAtomicType()) { SourceRange SR(LHSExpr->getLocStart(), RHSExpr->getLocEnd()); if (BO_Assign == Opc) -Diag(OpLoc, diag::err_atomic_init_constant) << SR; +Diag(OpLoc, diag::err_opencl_atomic_init) << SR; else ResultTy = InvalidOperands(OpLoc, LHS, RHS); return ExprError(); Index: include/clang/Basic/DiagnosticSemaKinds.td === --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -8284,9 +8284,8 @@ "return value cannot be qualified with address space">; def err_opencl_constant_no_init : Error< "variable in constant address space must be initialized">; -def err_atomic_init_constant : Error< - "atomic variable can only be assigned to a compile time constant" - " in the declaration statement in the program scope">; +def err_opencl_atomic_init: Error< + "atomic variable can only be assigned to a compile time constant and to variables in global adress space">; def err_opencl_implicit_vector_conversion : Error< "implicit conversions between vector types (%0 and %1) are not permitted">; def err_opencl_invalid_type_array : Error< Index: test/SemaOpenCL/atomic-init.cl === --- /dev/null +++ test/SemaOpenCL/atomic-init.cl @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -O0 -cl-std=CL2.0 -fsyntax-only
[PATCH] D31183: [OpenCL] Added parsing for OpenCL vector types.
echuraev updated this revision to Diff 93132. echuraev marked an inline comment as done. https://reviews.llvm.org/D31183 Files: include/clang/Parse/Parser.h lib/Parse/ParseExpr.cpp test/Parser/vector-cast-define.cl Index: test/Parser/vector-cast-define.cl === --- /dev/null +++ test/Parser/vector-cast-define.cl @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only +// expected-no-diagnostics + +typedef int int3 __attribute__((ext_vector_type(3))); + +void test() +{ +int index = (int3)(1, 2, 3).x * (int3)(3, 2, 1).y; +} + Index: lib/Parse/ParseExpr.cpp === --- lib/Parse/ParseExpr.cpp +++ lib/Parse/ParseExpr.cpp @@ -473,12 +473,14 @@ /// ExprResult Parser::ParseCastExpression(bool isUnaryExpression, bool isAddressOfOperand, - TypeCastState isTypeCast) { + TypeCastState isTypeCast, + bool isVectorLiteral) { bool NotCastExpr; ExprResult Res = ParseCastExpression(isUnaryExpression, isAddressOfOperand, NotCastExpr, - isTypeCast); + isTypeCast, + isVectorLiteral); if (NotCastExpr) Diag(Tok, diag::err_expected_expression); return Res; @@ -694,7 +696,8 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression, bool isAddressOfOperand, bool &NotCastExpr, - TypeCastState isTypeCast) { + TypeCastState isTypeCast, + bool isVectorLiteral) { ExprResult Res; tok::TokenKind SavedKind = Tok.getKind(); NotCastExpr = false; @@ -722,6 +725,9 @@ Res = ParseParenExpression(ParenExprType, false/*stopIfCastExr*/, isTypeCast == IsTypeCast, CastTy, RParenLoc); +if (isVectorLiteral) +return Res; + switch (ParenExprType) { case SimpleExpr: break;// Nothing else to do. case CompoundStmt: break; // Nothing else to do. @@ -2350,6 +2356,48 @@ return ParseCompoundLiteralExpression(Ty.get(), OpenLoc, RParenLoc); } + if (Tok.is(tok::l_paren)) { +// This could be OpenCL vector Literals +if (getLangOpts().OpenCL) +{ + TypeResult Ty; + { +InMessageExpressionRAIIObject InMessage(*this, false); +Ty = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); + } + if(Ty.isInvalid()) + { + return ExprError(); + } + QualType QT = Ty.get().get().getCanonicalType(); + if (QT->isVectorType()) + { +// We parsed '(' vector-type-name ')' followed by '(' + +// Parse the cast-expression that follows it next. +// isVectorLiteral = true will make sure we don't parse any +// Postfix expression yet +Result = ParseCastExpression(/*isUnaryExpression=*/false, + /*isAddressOfOperand=*/false, + /*isTypeCast=*/IsTypeCast, + /*isVectorLiteral=*/true); + +if (!Result.isInvalid()) { + Result = Actions.ActOnCastExpr(getCurScope(), OpenLoc, + DeclaratorInfo, CastTy, + RParenLoc, Result.get()); +} + +// After we performed the cast we can check for postfix-expr pieces. +if (!Result.isInvalid()) { + Result = ParsePostfixExpressionSuffix(Result); +} + +return Result; + } +} + } + if (ExprType == CastExpr) { // We parsed '(' type-name ')' and the thing after it wasn't a '{'. @@ -2379,10 +2427,13 @@ } // Parse the cast-expression that follows it next. +// isVectorLiteral = true will make sure we don't parse any +// Postfix expression yet // TODO: For cast expression with CastTy. Result = ParseCastExpression(/*isUnaryExpression=*/false, /*isAddressOfOperand=*/false, - /*isTypeCast=*/IsTypeCast); + /*isTypeCast=*/IsTypeCast, + /*isVectorLiteral=*/true); if (!Result.isInvalid()) { Result = Actions.ActOnCastExpr(getCurScope(), OpenLoc, DeclaratorInfo, CastTy, Index: include/c
[PATCH] D31321: [OpenCL] Do not generate "kernel_arg_type_qual" metadata for non-pointer args
echuraev added inline comments. Comment at: test/CodeGenOpenCL/kernel-arg-info.cl:66 // CHECK: ![[MD13]] = !{!"int*", !"int", !"int", !"float*"} -// CHECK: ![[MD14]] = !{!"restrict", !"const", !"volatile", !"restrict const"} // ARGINFO: ![[MD15]] = !{!"X", !"Y", !"anotherArg", !"Z"} Anastasia wrote: > Could we modify the test to check that const and volatile are added for the > pointers though? Added test case only for volatile pointer because const is checked in the Z argument of foo function. https://reviews.llvm.org/D31321 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31321: [OpenCL] Do not generate "kernel_arg_type_qual" metadata for non-pointer args
echuraev updated this revision to Diff 93357. echuraev marked an inline comment as done. https://reviews.llvm.org/D31321 Files: lib/CodeGen/CodeGenFunction.cpp test/CodeGenOpenCL/kernel-arg-info.cl Index: test/CodeGenOpenCL/kernel-arg-info.cl === --- test/CodeGenOpenCL/kernel-arg-info.cl +++ test/CodeGenOpenCL/kernel-arg-info.cl @@ -2,7 +2,8 @@ // RUN: %clang_cc1 %s -cl-std=CL2.0 -emit-llvm -o - -triple spir-unknown-unknown -cl-kernel-arg-info | FileCheck %s -check-prefix ARGINFO kernel void foo(__global int * restrict X, const int Y, -volatile int anotherArg, __constant float * restrict Z) { +volatile int anotherArg, __constant float * restrict Z, +__global volatile int * V) { *X = Y + anotherArg; } // CHECK: define spir_kernel void @foo{{[^!]+}} @@ -60,11 +61,11 @@ // CHECK-NOT: !kernel_arg_name // ARGINFO: !kernel_arg_name ![[MD54:[0-9]+]] -// CHECK: ![[MD11]] = !{i32 1, i32 0, i32 0, i32 2} -// CHECK: ![[MD12]] = !{!"none", !"none", !"none", !"none"} -// CHECK: ![[MD13]] = !{!"int*", !"int", !"int", !"float*"} -// CHECK: ![[MD14]] = !{!"restrict", !"const", !"volatile", !"restrict const"} -// ARGINFO: ![[MD15]] = !{!"X", !"Y", !"anotherArg", !"Z"} +// CHECK: ![[MD11]] = !{i32 1, i32 0, i32 0, i32 2, i32 1} +// CHECK: ![[MD12]] = !{!"none", !"none", !"none", !"none", !"none"} +// CHECK: ![[MD13]] = !{!"int*", !"int", !"int", !"float*", !"int*"} +// CHECK: ![[MD14]] = !{!"restrict", !"", !"", !"restrict const", !"volatile"} +// ARGINFO: ![[MD15]] = !{!"X", !"Y", !"anotherArg", !"Z", !"V"} // CHECK: ![[MD21]] = !{i32 1, i32 1, i32 1, i32 1} // CHECK: ![[MD22]] = !{!"read_only", !"read_only", !"write_only", !"read_write"} // CHECK: ![[MD23]] = !{!"image1d_t", !"image2d_t", !"image2d_array_t", !"image1d_t"} Index: lib/CodeGen/CodeGenFunction.cpp === --- lib/CodeGen/CodeGenFunction.cpp +++ lib/CodeGen/CodeGenFunction.cpp @@ -610,11 +610,6 @@ argBaseTypeNames.push_back(llvm::MDString::get(Context, baseTypeName)); - // Get argument type qualifiers: - if (ty.isConstQualified()) -typeQuals = "const"; - if (ty.isVolatileQualified()) -typeQuals += typeQuals.empty() ? "volatile" : " volatile"; if (isPipe) typeQuals = "pipe"; } Index: test/CodeGenOpenCL/kernel-arg-info.cl === --- test/CodeGenOpenCL/kernel-arg-info.cl +++ test/CodeGenOpenCL/kernel-arg-info.cl @@ -2,7 +2,8 @@ // RUN: %clang_cc1 %s -cl-std=CL2.0 -emit-llvm -o - -triple spir-unknown-unknown -cl-kernel-arg-info | FileCheck %s -check-prefix ARGINFO kernel void foo(__global int * restrict X, const int Y, -volatile int anotherArg, __constant float * restrict Z) { +volatile int anotherArg, __constant float * restrict Z, +__global volatile int * V) { *X = Y + anotherArg; } // CHECK: define spir_kernel void @foo{{[^!]+}} @@ -60,11 +61,11 @@ // CHECK-NOT: !kernel_arg_name // ARGINFO: !kernel_arg_name ![[MD54:[0-9]+]] -// CHECK: ![[MD11]] = !{i32 1, i32 0, i32 0, i32 2} -// CHECK: ![[MD12]] = !{!"none", !"none", !"none", !"none"} -// CHECK: ![[MD13]] = !{!"int*", !"int", !"int", !"float*"} -// CHECK: ![[MD14]] = !{!"restrict", !"const", !"volatile", !"restrict const"} -// ARGINFO: ![[MD15]] = !{!"X", !"Y", !"anotherArg", !"Z"} +// CHECK: ![[MD11]] = !{i32 1, i32 0, i32 0, i32 2, i32 1} +// CHECK: ![[MD12]] = !{!"none", !"none", !"none", !"none", !"none"} +// CHECK: ![[MD13]] = !{!"int*", !"int", !"int", !"float*", !"int*"} +// CHECK: ![[MD14]] = !{!"restrict", !"", !"", !"restrict const", !"volatile"} +// ARGINFO: ![[MD15]] = !{!"X", !"Y", !"anotherArg", !"Z", !"V"} // CHECK: ![[MD21]] = !{i32 1, i32 1, i32 1, i32 1} // CHECK: ![[MD22]] = !{!"read_only", !"read_only", !"write_only", !"read_write"} // CHECK: ![[MD23]] = !{!"image1d_t", !"image2d_t", !"image2d_array_t", !"image1d_t"} Index: lib/CodeGen/CodeGenFunction.cpp === --- lib/CodeGen/CodeGenFunction.cpp +++ lib/CodeGen/CodeGenFunction.cpp @@ -610,11 +610,6 @@ argBaseTypeNames.push_back(llvm::MDString::get(Context, baseTypeName)); - // Get argument type qualifiers: - if (ty.isConstQualified()) -typeQuals = "const"; - if (ty.isVolatileQualified()) -typeQuals += typeQuals.empty() ? "volatile" : " volatile"; if (isPipe) typeQuals = "pipe"; } ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30643: [OpenCL] Extended diagnostics for atomic initialization
echuraev updated this revision to Diff 93368. echuraev marked 2 inline comments as done. https://reviews.llvm.org/D30643 Files: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaExpr.cpp lib/Sema/SemaInit.cpp test/Parser/opencl-atomics-cl20.cl test/SemaOpenCL/atomic-init.cl Index: test/SemaOpenCL/atomic-init.cl === --- /dev/null +++ test/SemaOpenCL/atomic-init.cl @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -O0 -cl-std=CL2.0 -fsyntax-only -verify %s + +global atomic_int a1 = 0; + +kernel void test_atomic_initialization() { + a1 = 1; // expected-error {{atomic variable can only be assigned to a compile time constant}} + atomic_int a2 = 0; // expected-error {{atomic variable can only be assigned to a variable in global adress space}} + private atomic_int a3 = 0; // expected-error {{atomic variable can only be assigned to a variable in global adress space}} + local atomic_int a4 = 0; // expected-error {{'__local' variable cannot have an initializer}} + global atomic_int a5 = 0; // expected-error {{function scope variable cannot be declared in global address space}} + static global atomic_int a6 = 0; +} Index: test/Parser/opencl-atomics-cl20.cl === --- test/Parser/opencl-atomics-cl20.cl +++ test/Parser/opencl-atomics-cl20.cl @@ -67,7 +67,7 @@ foo(&i); // OpenCL v2.0 s6.13.11.8, arithemtic operations are not permitted on atomic types. i++; // expected-error {{invalid argument type 'atomic_int' (aka '_Atomic(int)') to unary expression}} - i = 1; // expected-error {{atomic variable can only be assigned to a compile time constant in the declaration statement in the program scope}} + i = 1; // expected-error {{atomic variable can only be assigned to a compile time constant}} i += 1; // expected-error {{invalid operands to binary expression ('atomic_int' (aka '_Atomic(int)') and 'int')}} i = i + i; // expected-error {{invalid operands to binary expression ('atomic_int' (aka '_Atomic(int)') and 'atomic_int')}} } Index: lib/Sema/SemaInit.cpp === --- lib/Sema/SemaInit.cpp +++ lib/Sema/SemaInit.cpp @@ -6502,6 +6502,20 @@ << Init->getSourceRange(); } + // OpenCL v2.0 s6.13.11.1. atomic variables can be initialized in global scope + QualType ETy = Entity.getType(); + Qualifiers TyQualifiers = ETy.getQualifiers(); + bool HasGlobalAS = TyQualifiers.hasAddressSpace() && + TyQualifiers.getAddressSpace() == LangAS::opencl_global; + + if (S.getLangOpts().OpenCLVersion >= 200 && + ETy->isAtomicType() && !HasGlobalAS && + Entity.getKind() == InitializedEntity::EK_Variable && Args.size() > 0) { +S.Diag(Args[0]->getLocStart(), diag::err_opencl_atomic_init) << 1 << +SourceRange(Entity.getDecl()->getLocStart(), Args[0]->getLocEnd()); +return ExprError(); + } + // Diagnose cases where we initialize a pointer to an array temporary, and the // pointer obviously outlives the temporary. if (Args.size() == 1 && Args[0]->getType()->isArrayType() && Index: lib/Sema/SemaExpr.cpp === --- lib/Sema/SemaExpr.cpp +++ lib/Sema/SemaExpr.cpp @@ -2,7 +2,7 @@ if (LHSTy->isAtomicType() || RHSTy->isAtomicType()) { SourceRange SR(LHSExpr->getLocStart(), RHSExpr->getLocEnd()); if (BO_Assign == Opc) -Diag(OpLoc, diag::err_atomic_init_constant) << SR; +Diag(OpLoc, diag::err_opencl_atomic_init) << 0 << SR; else ResultTy = InvalidOperands(OpLoc, LHS, RHS); return ExprError(); Index: include/clang/Basic/DiagnosticSemaKinds.td === --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -8284,9 +8284,9 @@ "return value cannot be qualified with address space">; def err_opencl_constant_no_init : Error< "variable in constant address space must be initialized">; -def err_atomic_init_constant : Error< - "atomic variable can only be assigned to a compile time constant" - " in the declaration statement in the program scope">; +def err_opencl_atomic_init: Error< + "atomic variable can only be assigned to a %select{compile time constant|" + "variable in global adress space}0">; def err_opencl_implicit_vector_conversion : Error< "implicit conversions between vector types (%0 and %1) are not permitted">; def err_opencl_invalid_type_array : Error< Index: test/SemaOpenCL/atomic-init.cl === --- /dev/null +++ test/SemaOpenCL/atomic-init.cl @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -O0 -cl-std=CL2.0 -fsyntax-only -verify %s + +global atomic_int a1 = 0; + +kernel void test_atomic_initialization() { + a1 = 1; // expected-error {{atomic variable can only be assigned to a
[PATCH] D31321: [OpenCL] Do not generate "kernel_arg_type_qual" metadata for non-pointer args
echuraev updated this revision to Diff 93596. https://reviews.llvm.org/D31321 Files: lib/CodeGen/CodeGenFunction.cpp test/CodeGenOpenCL/kernel-arg-info.cl Index: test/CodeGenOpenCL/kernel-arg-info.cl === --- test/CodeGenOpenCL/kernel-arg-info.cl +++ test/CodeGenOpenCL/kernel-arg-info.cl @@ -2,7 +2,8 @@ // RUN: %clang_cc1 %s -cl-std=CL2.0 -emit-llvm -o - -triple spir-unknown-unknown -cl-kernel-arg-info | FileCheck %s -check-prefix ARGINFO kernel void foo(__global int * restrict X, const int Y, -volatile int anotherArg, __constant float * restrict Z) { +volatile int anotherArg, __constant float * restrict Z, +__global volatile int * V, __global const int * C) { *X = Y + anotherArg; } // CHECK: define spir_kernel void @foo{{[^!]+}} @@ -60,11 +61,11 @@ // CHECK-NOT: !kernel_arg_name // ARGINFO: !kernel_arg_name ![[MD54:[0-9]+]] -// CHECK: ![[MD11]] = !{i32 1, i32 0, i32 0, i32 2} -// CHECK: ![[MD12]] = !{!"none", !"none", !"none", !"none"} -// CHECK: ![[MD13]] = !{!"int*", !"int", !"int", !"float*"} -// CHECK: ![[MD14]] = !{!"restrict", !"const", !"volatile", !"restrict const"} -// ARGINFO: ![[MD15]] = !{!"X", !"Y", !"anotherArg", !"Z"} +// CHECK: ![[MD11]] = !{i32 1, i32 0, i32 0, i32 2, i32 1, i32 1} +// CHECK: ![[MD12]] = !{!"none", !"none", !"none", !"none", !"none", !"none"} +// CHECK: ![[MD13]] = !{!"int*", !"int", !"int", !"float*", !"int*", !"int*"} +// CHECK: ![[MD14]] = !{!"restrict", !"", !"", !"restrict const", !"volatile", !"const"} +// ARGINFO: ![[MD15]] = !{!"X", !"Y", !"anotherArg", !"Z", !"V", !"C"} // CHECK: ![[MD21]] = !{i32 1, i32 1, i32 1, i32 1} // CHECK: ![[MD22]] = !{!"read_only", !"read_only", !"write_only", !"read_write"} // CHECK: ![[MD23]] = !{!"image1d_t", !"image2d_t", !"image2d_array_t", !"image1d_t"} Index: lib/CodeGen/CodeGenFunction.cpp === --- lib/CodeGen/CodeGenFunction.cpp +++ lib/CodeGen/CodeGenFunction.cpp @@ -610,11 +610,6 @@ argBaseTypeNames.push_back(llvm::MDString::get(Context, baseTypeName)); - // Get argument type qualifiers: - if (ty.isConstQualified()) -typeQuals = "const"; - if (ty.isVolatileQualified()) -typeQuals += typeQuals.empty() ? "volatile" : " volatile"; if (isPipe) typeQuals = "pipe"; } Index: test/CodeGenOpenCL/kernel-arg-info.cl === --- test/CodeGenOpenCL/kernel-arg-info.cl +++ test/CodeGenOpenCL/kernel-arg-info.cl @@ -2,7 +2,8 @@ // RUN: %clang_cc1 %s -cl-std=CL2.0 -emit-llvm -o - -triple spir-unknown-unknown -cl-kernel-arg-info | FileCheck %s -check-prefix ARGINFO kernel void foo(__global int * restrict X, const int Y, -volatile int anotherArg, __constant float * restrict Z) { +volatile int anotherArg, __constant float * restrict Z, +__global volatile int * V, __global const int * C) { *X = Y + anotherArg; } // CHECK: define spir_kernel void @foo{{[^!]+}} @@ -60,11 +61,11 @@ // CHECK-NOT: !kernel_arg_name // ARGINFO: !kernel_arg_name ![[MD54:[0-9]+]] -// CHECK: ![[MD11]] = !{i32 1, i32 0, i32 0, i32 2} -// CHECK: ![[MD12]] = !{!"none", !"none", !"none", !"none"} -// CHECK: ![[MD13]] = !{!"int*", !"int", !"int", !"float*"} -// CHECK: ![[MD14]] = !{!"restrict", !"const", !"volatile", !"restrict const"} -// ARGINFO: ![[MD15]] = !{!"X", !"Y", !"anotherArg", !"Z"} +// CHECK: ![[MD11]] = !{i32 1, i32 0, i32 0, i32 2, i32 1, i32 1} +// CHECK: ![[MD12]] = !{!"none", !"none", !"none", !"none", !"none", !"none"} +// CHECK: ![[MD13]] = !{!"int*", !"int", !"int", !"float*", !"int*", !"int*"} +// CHECK: ![[MD14]] = !{!"restrict", !"", !"", !"restrict const", !"volatile", !"const"} +// ARGINFO: ![[MD15]] = !{!"X", !"Y", !"anotherArg", !"Z", !"V", !"C"} // CHECK: ![[MD21]] = !{i32 1, i32 1, i32 1, i32 1} // CHECK: ![[MD22]] = !{!"read_only", !"read_only", !"write_only", !"read_write"} // CHECK: ![[MD23]] = !{!"image1d_t", !"image2d_t", !"image2d_array_t", !"image1d_t"} Index: lib/CodeGen/CodeGenFunction.cpp === --- lib/CodeGen/CodeGenFunction.cpp +++ lib/CodeGen/CodeGenFunction.cpp @@ -610,11 +610,6 @@ argBaseTypeNames.push_back(llvm::MDString::get(Context, baseTypeName)); - // Get argument type qualifiers: - if (ty.isConstQualified()) -typeQuals = "const"; - if (ty.isVolatileQualified()) -typeQuals += typeQuals.empty() ? "volatile" : " volatile"; if (isPipe) typeQuals = "pipe"; } ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30643: [OpenCL] Extended diagnostics for atomic initialization
echuraev updated this revision to Diff 93602. echuraev marked an inline comment as done. https://reviews.llvm.org/D30643 Files: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaExpr.cpp lib/Sema/SemaInit.cpp test/Parser/opencl-atomics-cl20.cl test/SemaOpenCL/atomic-init.cl Index: test/SemaOpenCL/atomic-init.cl === --- /dev/null +++ test/SemaOpenCL/atomic-init.cl @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -O0 -cl-std=CL2.0 -fsyntax-only -verify %s + +global atomic_int a1 = 0; + +kernel void test_atomic_initialization() { + a1 = 1; // expected-error {{atomic variable can only be assigned to a compile time constant}} + atomic_int a2 = 0; // expected-error {{atomic variable can be initialized to a variable only in global address space}} + private atomic_int a3 = 0; // expected-error {{atomic variable can be initialized to a variable only in global address space}} + local atomic_int a4 = 0; // expected-error {{'__local' variable cannot have an initializer}} + global atomic_int a5 = 0; // expected-error {{function scope variable cannot be declared in global address space}} + static global atomic_int a6 = 0; +} Index: test/Parser/opencl-atomics-cl20.cl === --- test/Parser/opencl-atomics-cl20.cl +++ test/Parser/opencl-atomics-cl20.cl @@ -67,7 +67,7 @@ foo(&i); // OpenCL v2.0 s6.13.11.8, arithemtic operations are not permitted on atomic types. i++; // expected-error {{invalid argument type 'atomic_int' (aka '_Atomic(int)') to unary expression}} - i = 1; // expected-error {{atomic variable can only be assigned to a compile time constant in the declaration statement in the program scope}} + i = 1; // expected-error {{atomic variable can only be assigned to a compile time constant}} i += 1; // expected-error {{invalid operands to binary expression ('atomic_int' (aka '_Atomic(int)') and 'int')}} i = i + i; // expected-error {{invalid operands to binary expression ('atomic_int' (aka '_Atomic(int)') and 'atomic_int')}} } Index: lib/Sema/SemaInit.cpp === --- lib/Sema/SemaInit.cpp +++ lib/Sema/SemaInit.cpp @@ -6502,6 +6502,20 @@ << Init->getSourceRange(); } + // OpenCL v2.0 s6.13.11.1. atomic variables can be initialized in global scope + QualType ETy = Entity.getType(); + Qualifiers TyQualifiers = ETy.getQualifiers(); + bool HasGlobalAS = TyQualifiers.hasAddressSpace() && + TyQualifiers.getAddressSpace() == LangAS::opencl_global; + + if (S.getLangOpts().OpenCLVersion >= 200 && + ETy->isAtomicType() && !HasGlobalAS && + Entity.getKind() == InitializedEntity::EK_Variable && Args.size() > 0) { +S.Diag(Args[0]->getLocStart(), diag::err_opencl_atomic_init) << 1 << +SourceRange(Entity.getDecl()->getLocStart(), Args[0]->getLocEnd()); +return ExprError(); + } + // Diagnose cases where we initialize a pointer to an array temporary, and the // pointer obviously outlives the temporary. if (Args.size() == 1 && Args[0]->getType()->isArrayType() && Index: lib/Sema/SemaExpr.cpp === --- lib/Sema/SemaExpr.cpp +++ lib/Sema/SemaExpr.cpp @@ -2,7 +2,7 @@ if (LHSTy->isAtomicType() || RHSTy->isAtomicType()) { SourceRange SR(LHSExpr->getLocStart(), RHSExpr->getLocEnd()); if (BO_Assign == Opc) -Diag(OpLoc, diag::err_atomic_init_constant) << SR; +Diag(OpLoc, diag::err_opencl_atomic_init) << 0 << SR; else ResultTy = InvalidOperands(OpLoc, LHS, RHS); return ExprError(); Index: include/clang/Basic/DiagnosticSemaKinds.td === --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -8284,9 +8284,9 @@ "return value cannot be qualified with address space">; def err_opencl_constant_no_init : Error< "variable in constant address space must be initialized">; -def err_atomic_init_constant : Error< - "atomic variable can only be assigned to a compile time constant" - " in the declaration statement in the program scope">; +def err_opencl_atomic_init: Error< + "atomic variable can %select{only be assigned to a compile time constant|" + "be initialized to a variable only in global address space}0">; def err_opencl_implicit_vector_conversion : Error< "implicit conversions between vector types (%0 and %1) are not permitted">; def err_opencl_invalid_type_array : Error< Index: test/SemaOpenCL/atomic-init.cl === --- /dev/null +++ test/SemaOpenCL/atomic-init.cl @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -O0 -cl-std=CL2.0 -fsyntax-only -verify %s + +global atomic_int a1 = 0; + +kernel void test_atomic_initialization() { + a1 = 1; // expected-error {{atomic
[PATCH] D30643: [OpenCL] Extended diagnostics for atomic initialization
echuraev updated this revision to Diff 93837. echuraev marked an inline comment as done. https://reviews.llvm.org/D30643 Files: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaExpr.cpp lib/Sema/SemaInit.cpp test/Parser/opencl-atomics-cl20.cl test/SemaOpenCL/atomic-init.cl Index: test/SemaOpenCL/atomic-init.cl === --- /dev/null +++ test/SemaOpenCL/atomic-init.cl @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -O0 -cl-std=CL2.0 -fsyntax-only -verify %s + +global atomic_int a1 = 0; + +kernel void test_atomic_initialization() { + a1 = 1; // expected-error {{atomic variable can be assigned to a variable only in global address space}} + atomic_int a2 = 0; // expected-error {{atomic variable can be initialized to a variable only in global address space}} + private atomic_int a3 = 0; // expected-error {{atomic variable can be initialized to a variable only in global address space}} + local atomic_int a4 = 0; // expected-error {{'__local' variable cannot have an initializer}} + global atomic_int a5 = 0; // expected-error {{function scope variable cannot be declared in global address space}} + static global atomic_int a6 = 0; +} Index: test/Parser/opencl-atomics-cl20.cl === --- test/Parser/opencl-atomics-cl20.cl +++ test/Parser/opencl-atomics-cl20.cl @@ -67,7 +67,7 @@ foo(&i); // OpenCL v2.0 s6.13.11.8, arithemtic operations are not permitted on atomic types. i++; // expected-error {{invalid argument type 'atomic_int' (aka '_Atomic(int)') to unary expression}} - i = 1; // expected-error {{atomic variable can only be assigned to a compile time constant in the declaration statement in the program scope}} + i = 1; // expected-error {{atomic variable can be assigned to a variable only in global address space}} i += 1; // expected-error {{invalid operands to binary expression ('atomic_int' (aka '_Atomic(int)') and 'int')}} i = i + i; // expected-error {{invalid operands to binary expression ('atomic_int' (aka '_Atomic(int)') and 'atomic_int')}} } Index: lib/Sema/SemaInit.cpp === --- lib/Sema/SemaInit.cpp +++ lib/Sema/SemaInit.cpp @@ -6502,6 +6502,20 @@ << Init->getSourceRange(); } + // OpenCL v2.0 s6.13.11.1. atomic variables can be initialized in global scope + QualType ETy = Entity.getType(); + Qualifiers TyQualifiers = ETy.getQualifiers(); + bool HasGlobalAS = TyQualifiers.hasAddressSpace() && + TyQualifiers.getAddressSpace() == LangAS::opencl_global; + + if (S.getLangOpts().OpenCLVersion >= 200 && + ETy->isAtomicType() && !HasGlobalAS && + Entity.getKind() == InitializedEntity::EK_Variable && Args.size() > 0) { +S.Diag(Args[0]->getLocStart(), diag::err_opencl_atomic_init) << 1 << +SourceRange(Entity.getDecl()->getLocStart(), Args[0]->getLocEnd()); +return ExprError(); + } + // Diagnose cases where we initialize a pointer to an array temporary, and the // pointer obviously outlives the temporary. if (Args.size() == 1 && Args[0]->getType()->isArrayType() && Index: lib/Sema/SemaExpr.cpp === --- lib/Sema/SemaExpr.cpp +++ lib/Sema/SemaExpr.cpp @@ -11121,7 +11121,7 @@ if (LHSTy->isAtomicType() || RHSTy->isAtomicType()) { SourceRange SR(LHSExpr->getLocStart(), RHSExpr->getLocEnd()); if (BO_Assign == Opc) -Diag(OpLoc, diag::err_atomic_init_constant) << SR; +Diag(OpLoc, diag::err_opencl_atomic_init) << 0 << SR; else ResultTy = InvalidOperands(OpLoc, LHS, RHS); return ExprError(); Index: include/clang/Basic/DiagnosticSemaKinds.td === --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -8284,9 +8284,9 @@ "return value cannot be qualified with address space">; def err_opencl_constant_no_init : Error< "variable in constant address space must be initialized">; -def err_atomic_init_constant : Error< - "atomic variable can only be assigned to a compile time constant" - " in the declaration statement in the program scope">; +def err_opencl_atomic_init: Error< + "atomic variable can be %select{assigned|initialized}0 to a variable only " + "in global address space">; def err_opencl_implicit_vector_conversion : Error< "implicit conversions between vector types (%0 and %1) are not permitted">; def err_opencl_invalid_type_array : Error< Index: test/SemaOpenCL/atomic-init.cl === --- /dev/null +++ test/SemaOpenCL/atomic-init.cl @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -O0 -cl-std=CL2.0 -fsyntax-only -verify %s + +global atomic_int a1 = 0; + +kernel void test_atomic_initialization() { + a1 = 1; // expected-error {{atomic variable can
[PATCH] D31594: [OpenCL] Enables passing sampler initializer to function argument
echuraev created this revision. Herald added a subscriber: yaxunl. https://reviews.llvm.org/D31594 Files: lib/Sema/SemaInit.cpp test/SemaOpenCL/sampler_t.cl Index: test/SemaOpenCL/sampler_t.cl === --- test/SemaOpenCL/sampler_t.cl +++ test/SemaOpenCL/sampler_t.cl @@ -65,7 +65,7 @@ foo(const_smp5); foo(const_smp6); foo(argsmp); - foo(5); // expected-error{{sampler_t variable required - got 'int'}} + foo(CLK_ADDRESS_CLAMP_TO_EDGE | CLK_NORMALIZED_COORDS_TRUE | CLK_FILTER_LINEAR); sampler_t sa[] = {argsmp, const_smp}; // expected-error {{array of 'sampler_t' type is invalid in OpenCL}} foo(sa[0]); foo(bad()); Index: lib/Sema/SemaInit.cpp === --- lib/Sema/SemaInit.cpp +++ lib/Sema/SemaInit.cpp @@ -7174,7 +7174,7 @@ QualType SourceType = Init->getType(); // Case 1 if (Entity.isParameterKind()) { -if (!SourceType->isSamplerT()) { +if (!SourceType->isSamplerT() && !SourceType->isIntegerType()) { S.Diag(Kind.getLocation(), diag::err_sampler_argument_required) << SourceType; break; Index: test/SemaOpenCL/sampler_t.cl === --- test/SemaOpenCL/sampler_t.cl +++ test/SemaOpenCL/sampler_t.cl @@ -65,7 +65,7 @@ foo(const_smp5); foo(const_smp6); foo(argsmp); - foo(5); // expected-error{{sampler_t variable required - got 'int'}} + foo(CLK_ADDRESS_CLAMP_TO_EDGE | CLK_NORMALIZED_COORDS_TRUE | CLK_FILTER_LINEAR); sampler_t sa[] = {argsmp, const_smp}; // expected-error {{array of 'sampler_t' type is invalid in OpenCL}} foo(sa[0]); foo(bad()); Index: lib/Sema/SemaInit.cpp === --- lib/Sema/SemaInit.cpp +++ lib/Sema/SemaInit.cpp @@ -7174,7 +7174,7 @@ QualType SourceType = Init->getType(); // Case 1 if (Entity.isParameterKind()) { -if (!SourceType->isSamplerT()) { +if (!SourceType->isSamplerT() && !SourceType->isIntegerType()) { S.Diag(Kind.getLocation(), diag::err_sampler_argument_required) << SourceType; break; ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31594: [OpenCL] Enables passing sampler initializer to function argument
echuraev updated this revision to Diff 94032. echuraev marked an inline comment as done. https://reviews.llvm.org/D31594 Files: lib/Sema/SemaInit.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 @@ -30,7 +30,7 @@ constant sampler_t glb_smp9 = 0x1LL; // expected-error{{sampler_t initialization requires 32-bit integer, not 'long long'}} -void foo(sampler_t); +void foo(sampler_t); // expected-note{{passing argument to parameter here}} constant struct sampler_s { sampler_t smp; // expected-error{{the 'sampler_t' type cannot be used to declare a structure or union field}} @@ -65,7 +65,8 @@ foo(const_smp5); foo(const_smp6); foo(argsmp); - foo(5); // expected-error{{sampler_t variable required - got 'int'}} + 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()); Index: test/CodeGenOpenCL/sampler.cl === --- test/CodeGenOpenCL/sampler.cl +++ test/CodeGenOpenCL/sampler.cl @@ -54,4 +54,8 @@ fnc4smp(smp_par); // 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) + // CHECK: call spir_func void @fnc4smp(%opencl.sampler_t addrspace(2)* [[SAMP]]) } Index: lib/Sema/SemaInit.cpp === --- lib/Sema/SemaInit.cpp +++ lib/Sema/SemaInit.cpp @@ -7174,7 +7174,7 @@ QualType SourceType = Init->getType(); // Case 1 if (Entity.isParameterKind()) { -if (!SourceType->isSamplerT()) { +if (!SourceType->isSamplerT() && !SourceType->isIntegerType()) { S.Diag(Kind.getLocation(), diag::err_sampler_argument_required) << SourceType; break; Index: test/SemaOpenCL/sampler_t.cl === --- test/SemaOpenCL/sampler_t.cl +++ test/SemaOpenCL/sampler_t.cl @@ -30,7 +30,7 @@ constant sampler_t glb_smp9 = 0x1LL; // expected-error{{sampler_t initialization requires 32-bit integer, not 'long long'}} -void foo(sampler_t); +void foo(sampler_t); // expected-note{{passing argument to parameter here}} constant struct sampler_s { sampler_t smp; // expected-error{{the 'sampler_t' type cannot be used to declare a structure or union field}} @@ -65,7 +65,8 @@ foo(const_smp5); foo(const_smp6); foo(argsmp); - foo(5); // expected-error{{sampler_t variable required - got 'int'}} + 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()); Index: test/CodeGenOpenCL/sampler.cl === --- test/CodeGenOpenCL/sampler.cl +++ test/CodeGenOpenCL/sampler.cl @@ -54,4 +54,8 @@ fnc4smp(smp_par); // 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) + // CHECK: call spir_func void @fnc4smp(%opencl.sampler_t addrspace(2)* [[SAMP]]) } Index: lib/Sema/SemaInit.cpp === --- lib/Sema/SemaInit.cpp +++ lib/Sema/SemaInit.cpp @@ -7174,7 +7174,7 @@ QualType SourceType = Init->getType(); // Case 1 if (Entity.isParameterKind()) { -if (!SourceType->isSamplerT()) { +if (!SourceType->isSamplerT() && !SourceType->isIntegerType()) { S.Diag(Kind.getLocation(), diag::err_sampler_argument_required) << SourceType; break; ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D27334: [OpenCL] Ambiguous function call.
echuraev added a comment. In https://reviews.llvm.org/D27334#700521, @Anastasia wrote: > I don't actually. But remembering the follow up discussion: > http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20161205/178846.html > and since we have to deviate from the standard C/C++ implementation anyways > I am wondering whether modifying overloading resolution is a better way to go? Yes, I remember this discussion. But we saw this problem in the real OpenCL code and this warning is able to help developer to understand where his code could be ambiguous. Actually, I don't know the modifying overloading resolution is a better way to go or not. Do you have any suggestions how could we notify developer about this potential problem in better way? https://reviews.llvm.org/D27334 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31745: [OpenCL] Added diagnostic for implicit declaration of function in OpenCL
echuraev created this revision. Herald added a subscriber: yaxunl. https://reviews.llvm.org/D31745 Files: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaDecl.cpp test/SemaOpenCL/clang-builtin-version.cl test/SemaOpenCL/to_addr_builtin.cl Index: test/SemaOpenCL/to_addr_builtin.cl === --- test/SemaOpenCL/to_addr_builtin.cl +++ test/SemaOpenCL/to_addr_builtin.cl @@ -10,7 +10,7 @@ glob = to_global(glob, loc); #if __OPENCL_C_VERSION__ < CL_VERSION_2_0 - // expected-warning@-2{{implicit declaration of function 'to_global' is invalid in C99}} + // expected-error@-2{{implicit declaration of function 'to_global' is invalid in OpenCL}} // expected-warning@-3{{incompatible integer to pointer conversion assigning to '__global int *' from 'int'}} #else // expected-error@-5{{invalid number of arguments to function: 'to_global'}} Index: test/SemaOpenCL/clang-builtin-version.cl === --- test/SemaOpenCL/clang-builtin-version.cl +++ test/SemaOpenCL/clang-builtin-version.cl @@ -4,41 +4,56 @@ kernel void dse_builtins() { int tmp; - enqueue_kernel(tmp, tmp, tmp, ^(void) { // expected-warning{{implicit declaration of function 'enqueue_kernel' is invalid in C99}} + enqueue_kernel(tmp, tmp, tmp, ^(void) { // expected-error{{implicit declaration of function 'enqueue_kernel' is invalid in OpenCL}} return; }); - unsigned size = get_kernel_work_group_size(^(void) { // expected-warning{{implicit declaration of function 'get_kernel_work_group_size' is invalid in C99}} + unsigned size = get_kernel_work_group_size(^(void) { // expected-error{{implicit declaration of function 'get_kernel_work_group_size' is invalid in OpenCL}} return; }); - size = get_kernel_preferred_work_group_size_multiple(^(void) { // expected-warning{{implicit declaration of function 'get_kernel_preferred_work_group_size_multiple' is invalid in C99}} + size = get_kernel_preferred_work_group_size_multiple(^(void) { // expected-error{{implicit declaration of function 'get_kernel_preferred_work_group_size_multiple' is invalid in OpenCL}} return; }); } void pipe_builtins() { int tmp; - read_pipe(tmp, tmp); // expected-warning{{implicit declaration of function 'read_pipe' is invalid in C99}} - write_pipe(tmp, tmp); // expected-warning{{implicit declaration of function 'write_pipe' is invalid in C99}} - - reserve_read_pipe(tmp, tmp); // expected-warning{{implicit declaration of function 'reserve_read_pipe' is invalid in C99}} - reserve_write_pipe(tmp, tmp); // expected-warning{{implicit declaration of function 'reserve_write_pipe' is invalid in C99}} - - work_group_reserve_read_pipe(tmp, tmp); // expected-warning{{implicit declaration of function 'work_group_reserve_read_pipe' is invalid in C99}} - work_group_reserve_write_pipe(tmp, tmp); // expected-warning{{implicit declaration of function 'work_group_reserve_write_pipe' is invalid in C99}} - - sub_group_reserve_write_pipe(tmp, tmp); // expected-warning{{implicit declaration of function 'sub_group_reserve_write_pipe' is invalid in C99}} - sub_group_reserve_read_pipe(tmp, tmp); // expected-warning{{implicit declaration of function 'sub_group_reserve_read_pipe' is invalid in C99}} - - commit_read_pipe(tmp, tmp); // expected-warning{{implicit declaration of function 'commit_read_pipe' is invalid in C99}} - commit_write_pipe(tmp, tmp); // expected-warning{{implicit declaration of function 'commit_write_pipe' is invalid in C99}} - - work_group_commit_read_pipe(tmp, tmp); // expected-warning{{implicit declaration of function 'work_group_commit_read_pipe' is invalid in C99}} - work_group_commit_write_pipe(tmp, tmp); // expected-warning{{implicit declaration of function 'work_group_commit_write_pipe' is invalid in C99}} - - sub_group_commit_write_pipe(tmp, tmp); // expected-warning{{implicit declaration of function 'sub_group_commit_write_pipe' is invalid in C99}} - sub_group_commit_read_pipe(tmp, tmp); // expected-warning{{implicit declaration of function 'sub_group_commit_read_pipe' is invalid in C99}} - - get_pipe_num_packets(tmp); // expected-warning{{implicit declaration of function 'get_pipe_num_packets' is invalid in C99}} - get_pipe_max_packets(tmp); // expected-warning{{implicit declaration of function 'get_pipe_max_packets' is invalid in C99}} + read_pipe(tmp, tmp); // expected-error{{implicit declaration of function 'read_pipe' is invalid in OpenCL}} + write_pipe(tmp, tmp); // expected-error{{implicit declaration of function 'write_pipe' is invalid in OpenCL}} + + reserve_read_pipe(tmp, tmp); // expected-error{{implicit declaration of function 'reserve_read_pipe' is invalid in OpenCL}} + // expected-note@-1{{'reserve_read_pipe' declared here}} + reserve_write_pipe(tmp, tmp); // expected-error{{implicit declaration of function 'reserve_write_pipe' is invalid in OpenCL}} + // expected-n
[PATCH] D26794: [OpenCL] Blocks are allowed to capture arrays in OpenCL 2.0 and higher.
echuraev added a comment. Yes, I have an access to the new revision and I have read it. https://reviews.llvm.org/D26794 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D26794: [OpenCL] Blocks are allowed to capture arrays in OpenCL 2.0 and higher.
echuraev updated this revision to Diff 94503. echuraev marked an inline comment as done. https://reviews.llvm.org/D26794 Files: lib/Sema/SemaExpr.cpp test/SemaOpenCL/blocks_with_array.cl Index: test/SemaOpenCL/blocks_with_array.cl === --- /dev/null +++ test/SemaOpenCL/blocks_with_array.cl @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 -O0 -fblocks -triple spir64-unkown-unkown -emit-llvm %s -o -| FileCheck %s +// RUN: %clang_cc1 -O0 -cl-std=CL2.0 -triple spir64-unkown-unkown -emit-llvm %s -o -| FileCheck %s + +typedef int (^block_t)(); + +int block_typedef_kernel(global int* res) { + int a[3] = {1, 2, 3}; + block_t b = ^() { +// CHECK: %{{.*}} = getelementptr inbounds [3 x i32], [3 x i32] addrspace(4)* %{{.*}}, i64 0, i64 0 +return a[0]; + }; + return b(); +} + +// CHECK: define spir_func void @foo() +void foo() { + struct v { +int arr[2]; + } s = {0, 1}; + block_t bl1 = ^(){return s.arr[1];}; +// CHECK: define internal spir_func i32 @__foo_block_invoke(i8 addrspace(4)* %.block_descriptor) +// CHECK: %{{.*}} = getelementptr inbounds %struct.v, %struct.v addrspace(4)* %{{.*}}, i32 0, i32 0 +// CHECK: %{{.*}} = getelementptr inbounds [2 x i32], [2 x i32] addrspace(4)* %{{.*}}, i64 0, i64 1 + // array content copied into captured struct location + int arr[2] = {0, 1}; + block_t bl2 = ^(){return arr[1];}; +// CHECK: define internal spir_func i32 @__foo_block_invoke_2(i8 addrspace(4)* %.block_descriptor) +// CHECK: %{{.*}} = getelementptr inbounds [2 x i32], [2 x i32] addrspace(4)* %{{.*}}, i64 0, i64 1 + // array decayed to pointer while captured + s.arr[1] = arr[1] = 877; +} Index: lib/Sema/SemaExpr.cpp === --- lib/Sema/SemaExpr.cpp +++ lib/Sema/SemaExpr.cpp @@ -13643,7 +13643,7 @@ bool ByRef = false; // Blocks are not allowed to capture arrays. - if (CaptureType->isArrayType()) { + if (!S.getLangOpts().OpenCL && CaptureType->isArrayType()) { if (BuildAndDiagnose) { S.Diag(Loc, diag::err_ref_array_type); S.Diag(Var->getLocation(), diag::note_previous_decl) Index: test/SemaOpenCL/blocks_with_array.cl === --- /dev/null +++ test/SemaOpenCL/blocks_with_array.cl @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 -O0 -fblocks -triple spir64-unkown-unkown -emit-llvm %s -o -| FileCheck %s +// RUN: %clang_cc1 -O0 -cl-std=CL2.0 -triple spir64-unkown-unkown -emit-llvm %s -o -| FileCheck %s + +typedef int (^block_t)(); + +int block_typedef_kernel(global int* res) { + int a[3] = {1, 2, 3}; + block_t b = ^() { +// CHECK: %{{.*}} = getelementptr inbounds [3 x i32], [3 x i32] addrspace(4)* %{{.*}}, i64 0, i64 0 +return a[0]; + }; + return b(); +} + +// CHECK: define spir_func void @foo() +void foo() { + struct v { +int arr[2]; + } s = {0, 1}; + block_t bl1 = ^(){return s.arr[1];}; +// CHECK: define internal spir_func i32 @__foo_block_invoke(i8 addrspace(4)* %.block_descriptor) +// CHECK: %{{.*}} = getelementptr inbounds %struct.v, %struct.v addrspace(4)* %{{.*}}, i32 0, i32 0 +// CHECK: %{{.*}} = getelementptr inbounds [2 x i32], [2 x i32] addrspace(4)* %{{.*}}, i64 0, i64 1 + // array content copied into captured struct location + int arr[2] = {0, 1}; + block_t bl2 = ^(){return arr[1];}; +// CHECK: define internal spir_func i32 @__foo_block_invoke_2(i8 addrspace(4)* %.block_descriptor) +// CHECK: %{{.*}} = getelementptr inbounds [2 x i32], [2 x i32] addrspace(4)* %{{.*}}, i64 0, i64 1 + // array decayed to pointer while captured + s.arr[1] = arr[1] = 877; +} Index: lib/Sema/SemaExpr.cpp === --- lib/Sema/SemaExpr.cpp +++ lib/Sema/SemaExpr.cpp @@ -13643,7 +13643,7 @@ bool ByRef = false; // Blocks are not allowed to capture arrays. - if (CaptureType->isArrayType()) { + if (!S.getLangOpts().OpenCL && CaptureType->isArrayType()) { if (BuildAndDiagnose) { S.Diag(Loc, diag::err_ref_array_type); S.Diag(Var->getLocation(), diag::note_previous_decl) ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31745: [OpenCL] Added diagnostic for implicit declaration of function in OpenCL
echuraev updated this revision to Diff 94537. https://reviews.llvm.org/D31745 Files: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaDecl.cpp test/SemaOpenCL/clang-builtin-version.cl test/SemaOpenCL/to_addr_builtin.cl Index: test/SemaOpenCL/to_addr_builtin.cl === --- test/SemaOpenCL/to_addr_builtin.cl +++ test/SemaOpenCL/to_addr_builtin.cl @@ -10,7 +10,7 @@ glob = to_global(glob, loc); #if __OPENCL_C_VERSION__ < CL_VERSION_2_0 - // expected-warning@-2{{implicit declaration of function 'to_global' is invalid in C99}} + // expected-error@-2{{implicit declaration of function 'to_global' is invalid in OpenCL}} // expected-warning@-3{{incompatible integer to pointer conversion assigning to '__global int *' from 'int'}} #else // expected-error@-5{{invalid number of arguments to function: 'to_global'}} Index: test/SemaOpenCL/clang-builtin-version.cl === --- test/SemaOpenCL/clang-builtin-version.cl +++ test/SemaOpenCL/clang-builtin-version.cl @@ -4,41 +4,62 @@ kernel void dse_builtins() { int tmp; - enqueue_kernel(tmp, tmp, tmp, ^(void) { // expected-warning{{implicit declaration of function 'enqueue_kernel' is invalid in C99}} + enqueue_kernel(tmp, tmp, tmp, ^(void) { // expected-error{{implicit declaration of function 'enqueue_kernel' is invalid in OpenCL}} return; }); - unsigned size = get_kernel_work_group_size(^(void) { // expected-warning{{implicit declaration of function 'get_kernel_work_group_size' is invalid in C99}} + unsigned size = get_kernel_work_group_size(^(void) { // expected-error{{implicit declaration of function 'get_kernel_work_group_size' is invalid in OpenCL}} return; }); - size = get_kernel_preferred_work_group_size_multiple(^(void) { // expected-warning{{implicit declaration of function 'get_kernel_preferred_work_group_size_multiple' is invalid in C99}} + size = get_kernel_preferred_work_group_size_multiple(^(void) { // expected-error{{implicit declaration of function 'get_kernel_preferred_work_group_size_multiple' is invalid in OpenCL}} return; }); } void pipe_builtins() { int tmp; - read_pipe(tmp, tmp); // expected-warning{{implicit declaration of function 'read_pipe' is invalid in C99}} - write_pipe(tmp, tmp); // expected-warning{{implicit declaration of function 'write_pipe' is invalid in C99}} + foo(void); // expected-error{{implicit declaration of function 'foo' is invalid in OpenCL}} + // expected-note@-1{{'foo' declared here}} + // expected-error@-2{{expected expression}} + boo(); // expected-error{{implicit declaration of function 'boo' is invalid in OpenCL}} + // expected-note@-1{{did you mean 'foo'?}} - reserve_read_pipe(tmp, tmp); // expected-warning{{implicit declaration of function 'reserve_read_pipe' is invalid in C99}} - reserve_write_pipe(tmp, tmp); // expected-warning{{implicit declaration of function 'reserve_write_pipe' is invalid in C99}} + read_pipe(tmp, tmp); // expected-error{{implicit declaration of function 'read_pipe' is invalid in OpenCL}} + write_pipe(tmp, tmp); // expected-error{{implicit declaration of function 'write_pipe' is invalid in OpenCL}} - work_group_reserve_read_pipe(tmp, tmp); // expected-warning{{implicit declaration of function 'work_group_reserve_read_pipe' is invalid in C99}} - work_group_reserve_write_pipe(tmp, tmp); // expected-warning{{implicit declaration of function 'work_group_reserve_write_pipe' is invalid in C99}} + reserve_read_pipe(tmp, tmp); // expected-error{{implicit declaration of function 'reserve_read_pipe' is invalid in OpenCL}} + // expected-note@-1{{'reserve_read_pipe' declared here}} + reserve_write_pipe(tmp, tmp); // expected-error{{implicit declaration of function 'reserve_write_pipe' is invalid in OpenCL}} + // expected-note@-1{{did you mean 'reserve_read_pipe'?}} - sub_group_reserve_write_pipe(tmp, tmp); // expected-warning{{implicit declaration of function 'sub_group_reserve_write_pipe' is invalid in C99}} - sub_group_reserve_read_pipe(tmp, tmp); // expected-warning{{implicit declaration of function 'sub_group_reserve_read_pipe' is invalid in C99}} + work_group_reserve_read_pipe(tmp, tmp); // expected-error{{implicit declaration of function 'work_group_reserve_read_pipe' is invalid in OpenCL}} + // expected-note@-1 2{{'work_group_reserve_read_pipe' declared here}} + work_group_reserve_write_pipe(tmp, tmp); // expected-error{{implicit declaration of function 'work_group_reserve_write_pipe' is invalid in OpenCL}} + // expected-note@-1{{did you mean 'work_group_reserve_read_pipe'?}} + // expected-note@-2{{'work_group_reserve_write_pipe' declared here}} - commit_read_pipe(tmp, tmp); // expected-warning{{implicit declaration of function 'commit_read_pipe' is invalid in C99}} - commit_write_pipe(tmp, tmp); // expected-warning{{implicit declaration of function 'commit_write_pipe' is
[PATCH] D31745: [OpenCL] Added diagnostic for implicit declaration of function in OpenCL
echuraev added inline comments. Comment at: include/clang/Basic/DiagnosticSemaKinds.td:8254 "%0 cannot be used as the type of a kernel parameter">; +def err_opencl_implicit_function_decl : Error< + "implicit declaration of function %0 is invalid in OpenCL">; Anastasia wrote: > Could this be in OpenCL group please? But this is already in OpenCL group. Please, see line 8232. In this line is a comment that OpenCL warnings and errors are below. Comment at: test/SemaOpenCL/clang-builtin-version.cl:32 + work_group_reserve_write_pipe(tmp, tmp); // expected-error{{implicit declaration of function 'work_group_reserve_write_pipe' is invalid in OpenCL}} + // expected-note@-1{{did you mean 'work_group_reserve_read_pipe'?}} + // expected-note@-2{{'work_group_reserve_write_pipe' declared here}} Anastasia wrote: > Why do we get this note now? I believe work_group_reserve_read_pipe shouldn't > be available either? May be I don't understand something but I think that it is the right diagnostic message. We called work_group_reserve_read_pipe in line 29. So for this case we will get the following message: //clang-builtin-version.cl: 31 error: implicit declaration of function 'work_group_reserve_write_pipe' is invalid in OpenCL clang-builtin-version.cl: 31 note: did you mean 'work_group_reserve_read_pipe'? clang-builtin-version.cl: 29 note: 'work_group_reserve_read_pipe' declared here// https://reviews.llvm.org/D31745 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31745: [OpenCL] Added diagnostic for implicit declaration of function in OpenCL
echuraev added inline comments. Comment at: test/SemaOpenCL/clang-builtin-version.cl:32 + work_group_reserve_write_pipe(tmp, tmp); // expected-error{{implicit declaration of function 'work_group_reserve_write_pipe' is invalid in OpenCL}} + // expected-note@-1{{did you mean 'work_group_reserve_read_pipe'?}} + // expected-note@-2{{'work_group_reserve_write_pipe' declared here}} Anastasia wrote: > Anastasia wrote: > > echuraev wrote: > > > Anastasia wrote: > > > > Why do we get this note now? I believe work_group_reserve_read_pipe > > > > shouldn't be available either? > > > May be I don't understand something but I think that it is the right > > > diagnostic message. We called work_group_reserve_read_pipe in line 29. So > > > for this case we will get the following message: > > > //clang-builtin-version.cl: 31 error: implicit declaration of function > > > 'work_group_reserve_write_pipe' is invalid in OpenCL > > > clang-builtin-version.cl: 31 note: did you mean > > > 'work_group_reserve_read_pipe'? > > > clang-builtin-version.cl: 29 note: 'work_group_reserve_read_pipe' > > > declared here// > > But there is an error now given for the call to > > 'work_group_reserve_read_pipe'. Why is it still added to the declarations? > > I think we should prevent this. > Also do you know why we didn't have these notes before? I don't see anything > related in your change. I run this test and got a log with errors. The full log you can find in the end of the message. I think that the diagnostic messages are right. First error we get for implicit declaration of **//work_group_reserve_read_pipe//**. After that we call function **//work_group_reserve_write_pipe//** and get the same error about implicit declaration of function. But also we get two diagnostic messages. Compiler already know about **//work_group_reserve_read_pipe//** and make a hypothesis: "//note: did you mean 'work_group_reserve_read_pipe'?//" and "//note: 'work_group_reserve_read_pipe' declared here//". As well, next we have declaration of **//work_group_commit_read_pipe//**. And we get an error about implicit declaration of this function and also get a note messages: "//note: did you mean 'work_group_reserve_read_pipe'?//" and "//note: 'work_group_reserve_read_pipe' declared here//". > Also do you know why we didn't have these notes before? I don't see anything > related in your change. Unfortunately, I don't know why we get these notes. They have appeared when I changed the status of diagnostic message for implicit declaration from warning to error. If we had only warning messages then we wouldn't have these notes. ``` clang-builtin-version.cl:35:3: error: implicit declaration of function 'work_group_reserve_read_pipe' is invalid in OpenCL work_group_reserve_read_pipe(tmp, tmp); ^ clang-builtin-version.cl:37:3: error: implicit declaration of function 'work_group_reserve_write_pipe' is invalid in OpenCL work_group_reserve_write_pipe(tmp, tmp); ^ clang-builtin-version.cl:37:3: note: did you mean 'work_group_reserve_read_pipe'? clang-builtin-version.cl:35:3: note: 'work_group_reserve_read_pipe' declared here work_group_reserve_read_pipe(tmp, tmp); ^ clang-builtin-version.cl:50:3: error: implicit declaration of function 'work_group_commit_read_pipe' is invalid in OpenCL work_group_commit_read_pipe(tmp, tmp); ^ clang-builtin-version.cl:50:3: note: did you mean 'work_group_reserve_read_pipe'? clang-builtin-version.cl:35:3: note: 'work_group_reserve_read_pipe' declared here work_group_reserve_read_pipe(tmp, tmp); ^ ``` https://reviews.llvm.org/D31745 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D27917: [OpenCL] Improve diagnostics for double type
echuraev added a comment. This diagnostic was added in this commit: https://reviews.llvm.org/rL289979 It is something like that: "use of undeclared identifier 'double2'; did you mean 'double'?" This message isn't clear enough and it is difficult to understand that I forgot to enable cl_khr_fp64 extension. May be it will be better to change this diagnostic message to something like that: "use of type 'double2' (vector of 2 'double' values) requires cl_khr_fp64 extension to be enabled" https://reviews.llvm.org/D27917 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34980: [OpenCL] Test on image access modifiers and image type can only be a type of a function argument.
echuraev created this revision. Herald added a subscriber: yaxunl. https://reviews.llvm.org/D34980 Files: test/SemaOpenCL/images.cl Index: test/SemaOpenCL/images.cl === --- test/SemaOpenCL/images.cl +++ test/SemaOpenCL/images.cl @@ -1,9 +1,43 @@ -// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only +// RUN: %clang_cc1 %s -cl-std=CL2.0 -verify -pedantic -fsyntax-only -void img2d_ro(__read_only image2d_t img) {} // expected-note{{passing argument to parameter 'img' here}} expected-note{{passing argument to parameter 'img' here}} +void img2d_ro(__read_only image2d_t img) {} // expected-note 2{{passing argument to parameter 'img' here}} void imgage_access_test(image2d_t img2dro, write_only image2d_t img2dwo, image3d_t img3dro) { img2d_ro(img2dro); img2d_ro(img2dwo); // expected-error{{passing '__write_only image2d_t' to parameter of incompatible type '__read_only image2d_t'}} img2d_ro(img3dro); // expected-error{{passing '__read_only image3d_t' to parameter of incompatible type '__read_only image2d_t'}} } + +void myWrite(write_only image2d_t); // expected-note 2{{passing argument to parameter here}} +void myRead (read_only image2d_t); // expected-note 2{{passing argument to parameter here}} +void myReadWrite (read_write image2d_t); +void myIndifferent (image2d_t); // expected-note 2{{passing argument to parameter here}} + + +kernel void k1 (read_only image2d_t img) { + myWrite(img); // expected-error {{passing '__read_only image2d_t' to parameter of incompatible type '__write_only image2d_t'}} +} + +kernel void k2 (write_only image2d_t img) { + myRead(img); // expected-error {{passing '__write_only image2d_t' to parameter of incompatible type '__read_only image2d_t'}} +} + +// Should be all OK. +kernel void k3 (read_write image2d_t img) { + myRead(img); // expected-error {{passing '__read_write image2d_t' to parameter of incompatible type '__read_only image2d_t'}} + myWrite(img); // expected-error {{passing '__read_write image2d_t' to parameter of incompatible type '__write_only image2d_t'}} + myReadWrite(img); //read_write = read_write +} + +// Legal to path everything to an 'indifferent' function. +kernel void k4(read_write image2d_t i1, read_only image2d_t i2, + write_only image2d_t i3) { + myIndifferent(i1); // expected-error {{passing '__read_write image2d_t' to parameter of incompatible type '__read_only image2d_t'}} + myIndifferent(i2); + myIndifferent(i3); // expected-error {{passing '__write_only image2d_t' to parameter of incompatible type '__read_only image2d_t'}} +} + +kernel void k5(read_only image2d_t srcimg) +{ + read_only image2d_t tmp = srcimg; // expected-error {{type '__read_only image2d_t' can only be used as a function parameter in OpenCL}} +} Index: test/SemaOpenCL/images.cl === --- test/SemaOpenCL/images.cl +++ test/SemaOpenCL/images.cl @@ -1,9 +1,43 @@ -// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only +// RUN: %clang_cc1 %s -cl-std=CL2.0 -verify -pedantic -fsyntax-only -void img2d_ro(__read_only image2d_t img) {} // expected-note{{passing argument to parameter 'img' here}} expected-note{{passing argument to parameter 'img' here}} +void img2d_ro(__read_only image2d_t img) {} // expected-note 2{{passing argument to parameter 'img' here}} void imgage_access_test(image2d_t img2dro, write_only image2d_t img2dwo, image3d_t img3dro) { img2d_ro(img2dro); img2d_ro(img2dwo); // expected-error{{passing '__write_only image2d_t' to parameter of incompatible type '__read_only image2d_t'}} img2d_ro(img3dro); // expected-error{{passing '__read_only image3d_t' to parameter of incompatible type '__read_only image2d_t'}} } + +void myWrite(write_only image2d_t); // expected-note 2{{passing argument to parameter here}} +void myRead (read_only image2d_t); // expected-note 2{{passing argument to parameter here}} +void myReadWrite (read_write image2d_t); +void myIndifferent (image2d_t); // expected-note 2{{passing argument to parameter here}} + + +kernel void k1 (read_only image2d_t img) { + myWrite(img); // expected-error {{passing '__read_only image2d_t' to parameter of incompatible type '__write_only image2d_t'}} +} + +kernel void k2 (write_only image2d_t img) { + myRead(img); // expected-error {{passing '__write_only image2d_t' to parameter of incompatible type '__read_only image2d_t'}} +} + +// Should be all OK. +kernel void k3 (read_write image2d_t img) { + myRead(img); // expected-error {{passing '__read_write image2d_t' to parameter of incompatible type '__read_only image2d_t'}} + myWrite(img); // expected-error {{passing '__read_write image2d_t' to parameter of incompatible type '__write_only image2d_t'}} + myReadWrite(img); //read_write = read_write +} + +// Legal to path everything to an 'indifferent' function. +kernel void k4(read_write image2d_t i1, read_only image2d_t i2, +
[PATCH] D34980: [OpenCL] Test on image access modifiers and image type can only be a type of a function argument.
echuraev updated this revision to Diff 105218. echuraev marked 6 inline comments as done. https://reviews.llvm.org/D34980 Files: test/SemaOpenCL/images.cl Index: test/SemaOpenCL/images.cl === --- test/SemaOpenCL/images.cl +++ test/SemaOpenCL/images.cl @@ -1,9 +1,32 @@ -// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only +// RUN: %clang_cc1 %s -cl-std=CL2.0 -verify -pedantic -fsyntax-only -void img2d_ro(__read_only image2d_t img) {} // expected-note{{passing argument to parameter 'img' here}} expected-note{{passing argument to parameter 'img' here}} +void img2d_ro(read_only image2d_t); // expected-note 3{{passing argument to parameter here}} +void img2d_wo(write_only image2d_t); // expected-note 2{{passing argument to parameter here}} +void img2d_rw(read_write image2d_t); // expected-note 2{{passing argument to parameter here}} +void img2d_default(image2d_t); // expected-note 2{{passing argument to parameter here}} -void imgage_access_test(image2d_t img2dro, write_only image2d_t img2dwo, image3d_t img3dro) { - img2d_ro(img2dro); - img2d_ro(img2dwo); // expected-error{{passing '__write_only image2d_t' to parameter of incompatible type '__read_only image2d_t'}} +void imgage_access_test(image2d_t img2dro, image3d_t img3dro) { + img2d_ro(img2dro); // read_only = read_only img2d_ro(img3dro); // expected-error{{passing '__read_only image3d_t' to parameter of incompatible type '__read_only image2d_t'}} } + +kernel void read_only_access_test(read_only image2d_t img) { + img2d_ro(img); // read_only = read_only + img2d_wo(img); // expected-error {{passing '__read_only image2d_t' to parameter of incompatible type '__write_only image2d_t'}} + img2d_rw(img); // expected-error {{passing '__read_only image2d_t' to parameter of incompatible type '__read_write image2d_t'}} + img2d_default(img); // read_only = read_only +} + +kernel void write_only_access_test(write_only image2d_t img) { + img2d_ro(img); // expected-error {{passing '__write_only image2d_t' to parameter of incompatible type '__read_only image2d_t'}} + img2d_wo(img); // write_only = write_only + img2d_rw(img); // expected-error {{passing '__write_only image2d_t' to parameter of incompatible type '__read_write image2d_t'}} + img2d_default(img); // expected-error {{passing '__write_only image2d_t' to parameter of incompatible type '__read_only image2d_t'}} +} + +kernel void read_write_access_test(read_write image2d_t img) { + img2d_ro(img); // expected-error {{passing '__read_write image2d_t' to parameter of incompatible type '__read_only image2d_t'}} + img2d_wo(img); // expected-error {{passing '__read_write image2d_t' to parameter of incompatible type '__write_only image2d_t'}} + img2d_rw(img); //read_write = read_write + img2d_default(img); // expected-error {{passing '__read_write image2d_t' to parameter of incompatible type '__read_only image2d_t'}} +} Index: test/SemaOpenCL/images.cl === --- test/SemaOpenCL/images.cl +++ test/SemaOpenCL/images.cl @@ -1,9 +1,32 @@ -// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only +// RUN: %clang_cc1 %s -cl-std=CL2.0 -verify -pedantic -fsyntax-only -void img2d_ro(__read_only image2d_t img) {} // expected-note{{passing argument to parameter 'img' here}} expected-note{{passing argument to parameter 'img' here}} +void img2d_ro(read_only image2d_t); // expected-note 3{{passing argument to parameter here}} +void img2d_wo(write_only image2d_t); // expected-note 2{{passing argument to parameter here}} +void img2d_rw(read_write image2d_t); // expected-note 2{{passing argument to parameter here}} +void img2d_default(image2d_t); // expected-note 2{{passing argument to parameter here}} -void imgage_access_test(image2d_t img2dro, write_only image2d_t img2dwo, image3d_t img3dro) { - img2d_ro(img2dro); - img2d_ro(img2dwo); // expected-error{{passing '__write_only image2d_t' to parameter of incompatible type '__read_only image2d_t'}} +void imgage_access_test(image2d_t img2dro, image3d_t img3dro) { + img2d_ro(img2dro); // read_only = read_only img2d_ro(img3dro); // expected-error{{passing '__read_only image3d_t' to parameter of incompatible type '__read_only image2d_t'}} } + +kernel void read_only_access_test(read_only image2d_t img) { + img2d_ro(img); // read_only = read_only + img2d_wo(img); // expected-error {{passing '__read_only image2d_t' to parameter of incompatible type '__write_only image2d_t'}} + img2d_rw(img); // expected-error {{passing '__read_only image2d_t' to parameter of incompatible type '__read_write image2d_t'}} + img2d_default(img); // read_only = read_only +} + +kernel void write_only_access_test(write_only image2d_t img) { + img2d_ro(img); // expected-error {{passing '__write_only image2d_t' to parameter of incompatible type '__read_only image2d_t'}} + img2d_wo(img); // write_only = write_only + img2d_rw(img); // expect
[PATCH] D35000: [OpenCL] Added extended tests on metadata generation for half data type and arrays.
echuraev created this revision. Herald added a subscriber: yaxunl. https://reviews.llvm.org/D35000 Files: test/CodeGenOpenCL/kernel-arg-info.cl Index: test/CodeGenOpenCL/kernel-arg-info.cl === --- test/CodeGenOpenCL/kernel-arg-info.cl +++ test/CodeGenOpenCL/kernel-arg-info.cl @@ -61,6 +61,37 @@ // CHECK-NOT: !kernel_arg_name // ARGINFO: !kernel_arg_name ![[MD54:[0-9]+]] +kernel void foo6(constant half*constanthalfp, + constant half *restrict constanthalfrestrictp, + global half*globalhalfp, + global half *restrict globalhalfrestrictp, + global const half* globalconsthalfp, + global const half * restrict globalconsthalfrestrictp, + + global volatile half*globalvolatilehalfp, + global volatile half *restrict globalvolatilehalfrestrictp, + global const volatile half* globalconstvolatilehalfp) +{} +// CHECK: !kernel_arg_type ![[MD61:[0-9]+]] +// CHECK: !kernel_arg_base_type ![[MD61]] + +kernel void foo6_2(global const volatile half * restrict globalconstvolatilehalfrestrictp, + local half*localhalfp, + local half *restrict localhalfrestrictp, + local const half* localconsthalfp, + local const half * restrict localconsthalfrestrictp, + local volatile half*localvolatilehalfp, + local volatile half *restrict localvolatilehalfrestrictp, + local const volatile half* localconstvolatilehalfp, + local const volatile half * restrict localconstvolatilehalfrestrictp) +{} +// CHECK: !kernel_arg_type ![[MD61]] +// CHECK: !kernel_arg_base_type ![[MD61]] + +typedef char char16 __attribute__((ext_vector_type(16))); +__kernel void foo7(__global char16 arg[]) {} +// CHECK: !kernel_arg_type ![[MD71:[0-9]+]] + // CHECK: ![[MD11]] = !{i32 1, i32 0, i32 0, i32 2, i32 1, i32 1} // CHECK: ![[MD12]] = !{!"none", !"none", !"none", !"none", !"none", !"none"} // CHECK: ![[MD13]] = !{!"int*", !"int", !"int", !"float*", !"int*", !"int*"} @@ -86,4 +117,6 @@ // CHECK: ![[MD52]] = !{!"myImage", !"image1d_t"} // CHECK: ![[MD53]] = !{!"image1d_t", !"image1d_t"} // ARGINFO: ![[MD54]] = !{!"img1", !"img2"} +// CHECK: ![[MD61]] = !{!"half*", !"half*", !"half*", !"half*", !"half*", !"half*", !"half*", !"half*", !"half*"} +// CHECK: ![[MD71]] = !{!"char16*"} Index: test/CodeGenOpenCL/kernel-arg-info.cl === --- test/CodeGenOpenCL/kernel-arg-info.cl +++ test/CodeGenOpenCL/kernel-arg-info.cl @@ -61,6 +61,37 @@ // CHECK-NOT: !kernel_arg_name // ARGINFO: !kernel_arg_name ![[MD54:[0-9]+]] +kernel void foo6(constant half*constanthalfp, + constant half *restrict constanthalfrestrictp, + global half*globalhalfp, + global half *restrict globalhalfrestrictp, + global const half* globalconsthalfp, + global const half * restrict globalconsthalfrestrictp, + + global volatile half*globalvolatilehalfp, + global volatile half *restrict globalvolatilehalfrestrictp, + global const volatile half* globalconstvolatilehalfp) +{} +// CHECK: !kernel_arg_type ![[MD61:[0-9]+]] +// CHECK: !kernel_arg_base_type ![[MD61]] + +kernel void foo6_2(global const volatile half * restrict globalconstvolatilehalfrestrictp, + local half*localhalfp, + local half *restrict localhalfrestrictp, + local const half* localconsthalfp, + local const half * restrict localconsthalfrestrictp, + local volatile half*localvolatilehalfp, + local volatile half *restrict localvolatilehalfrestrictp, + local const volatile half* localconstvolatilehalfp, + local const volatile half * restrict localconstvolatilehalfrestrictp) +{} +// CHECK: !kernel_arg_type ![[MD61]] +// CHECK: !kernel_arg_base_type ![[MD61]] + +typedef char char16 __attribute__((ext_vector_type(16))); +__kernel void foo7(__global char16 arg[]) {} +// CHECK: !kernel_arg_type ![[MD71:[0-9]+]] + // CHECK: ![[MD11]] = !{i32 1, i32 0, i32 0, i32 2, i32 1, i32 1} // CHECK: ![[MD12]] = !{!"none", !"none", !"none", !"none", !"none", !"none"} // CHECK: ![[MD13]] = !{!"int*", !"int", !"int", !"float*", !"int*", !"int*"} @@ -86,4 +117,6 @@ // CHECK: ![[MD52]] = !{!"myImage", !"image1d_t"} // CHECK: ![[MD53]] = !{!"image1d_t", !"image1d_t"} // ARGINFO: ![[MD54]] = !{!"img1", !"img2"} +// CHECK: ![[MD61]] = !{!"half*", !"half*", !"half*", !"half*", !"half*", !"half*", !"half*", !"half*", !"half*"} +// CHECK: ![[MD71]] = !{!"char16*"} ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/
[PATCH] D35000: [OpenCL] Added extended tests on metadata generation for half data type and arrays.
echuraev updated this revision to Diff 105375. echuraev marked an inline comment as done. https://reviews.llvm.org/D35000 Files: test/CodeGenOpenCL/kernel-arg-info.cl Index: test/CodeGenOpenCL/kernel-arg-info.cl === --- test/CodeGenOpenCL/kernel-arg-info.cl +++ test/CodeGenOpenCL/kernel-arg-info.cl @@ -61,6 +61,37 @@ // CHECK-NOT: !kernel_arg_name // ARGINFO: !kernel_arg_name ![[MD54:[0-9]+]] +kernel void foo6(constant half * constanthalfp, + constant half * restrict constanthalfrestrictp, + global half * globalhalfp, + global half * restrict globalhalfrestrictp, + global const half * globalconsthalfp, + global const half * restrict globalconsthalfrestrictp, + + global volatile half * globalvolatilehalfp, + global volatile half * restrict globalvolatilehalfrestrictp, + global const volatile half * globalconstvolatilehalfp) +{} +// CHECK: !kernel_arg_type ![[MD61:[0-9]+]] +// CHECK: !kernel_arg_base_type ![[MD61]] + +kernel void foo6_2(global const volatile half * restrict globalconstvolatilehalfrestrictp, + local half * localhalfp, + local half * restrict localhalfrestrictp, + local const half * localconsthalfp, + local const half * restrict localconsthalfrestrictp, + local volatile half * localvolatilehalfp, + local volatile half * restrict localvolatilehalfrestrictp, + local const volatile half * localconstvolatilehalfp, + local const volatile half * restrict localconstvolatilehalfrestrictp) +{} +// CHECK: !kernel_arg_type ![[MD61]] +// CHECK: !kernel_arg_base_type ![[MD61]] + +typedef char char16 __attribute__((ext_vector_type(16))); +__kernel void foo7(__global char16 arg[]) {} +// CHECK: !kernel_arg_type ![[MD71:[0-9]+]] + // CHECK: ![[MD11]] = !{i32 1, i32 0, i32 0, i32 2, i32 1, i32 1} // CHECK: ![[MD12]] = !{!"none", !"none", !"none", !"none", !"none", !"none"} // CHECK: ![[MD13]] = !{!"int*", !"int", !"int", !"float*", !"int*", !"int*"} @@ -86,4 +117,6 @@ // CHECK: ![[MD52]] = !{!"myImage", !"image1d_t"} // CHECK: ![[MD53]] = !{!"image1d_t", !"image1d_t"} // ARGINFO: ![[MD54]] = !{!"img1", !"img2"} +// CHECK: ![[MD61]] = !{!"half*", !"half*", !"half*", !"half*", !"half*", !"half*", !"half*", !"half*", !"half*"} +// CHECK: ![[MD71]] = !{!"char16*"} Index: test/CodeGenOpenCL/kernel-arg-info.cl === --- test/CodeGenOpenCL/kernel-arg-info.cl +++ test/CodeGenOpenCL/kernel-arg-info.cl @@ -61,6 +61,37 @@ // CHECK-NOT: !kernel_arg_name // ARGINFO: !kernel_arg_name ![[MD54:[0-9]+]] +kernel void foo6(constant half * constanthalfp, + constant half * restrict constanthalfrestrictp, + global half * globalhalfp, + global half * restrict globalhalfrestrictp, + global const half * globalconsthalfp, + global const half * restrict globalconsthalfrestrictp, + + global volatile half * globalvolatilehalfp, + global volatile half * restrict globalvolatilehalfrestrictp, + global const volatile half * globalconstvolatilehalfp) +{} +// CHECK: !kernel_arg_type ![[MD61:[0-9]+]] +// CHECK: !kernel_arg_base_type ![[MD61]] + +kernel void foo6_2(global const volatile half * restrict globalconstvolatilehalfrestrictp, + local half * localhalfp, + local half * restrict localhalfrestrictp, + local const half * localconsthalfp, + local const half * restrict localconsthalfrestrictp, + local volatile half * localvolatilehalfp, + local volatile half * restrict localvolatilehalfrestrictp, + local const volatile half * localconstvolatilehalfp, + local const volatile half * restrict localconstvolatilehalfrestrictp) +{} +// CHECK: !kernel_arg_type ![[MD61]] +// CHECK: !kernel_arg_base_type ![[MD61]] + +typedef char char16 __attribute__((ext_vector_type(16))); +__kernel void foo7(__global char16 arg[]) {} +// CHECK: !kernel_arg_type ![[MD71:[0-9]+]] + // CHECK: ![[MD11]] = !{i32 1, i32 0, i32 0, i32 2, i32 1, i32 1} // CHECK: ![[MD12]] = !{!"none", !"none", !"none", !"none", !"none", !"none"} // CHECK: ![[MD13]] = !{!"int*", !"int", !"int", !"float*", !"int*", !"int*"} @@ -86,4 +117,6 @@ // CHECK: ![[MD52]] = !{!"myImage", !"image1d_t"} // CHECK: ![[MD53]] = !{!"image1d_t", !"image1d_t"} // ARGINFO: ![[MD54]] = !{!"img1", !"img2"} +// CHECK: ![[MD61]] = !{!"half*", !"half*", !"half*", !"half*", !"half*", !"half*", !"half*", !"half*", !"half*"} +// CHECK: ![[MD71]] = !{!"char16*"} ___ cfe-commits mailing l
[PATCH] D35000: [OpenCL] Added extended tests on metadata generation for half data type and arrays.
echuraev added a comment. In https://reviews.llvm.org/D35000#801132, @Anastasia wrote: > In https://reviews.llvm.org/D35000#799705, @Anastasia wrote: > > > Btw, is there any reason to add testing specifically for half? Is there > > anything specific to half in the implementation of this? > > > Trying to understand the reason for this change though... Sorry for a delay in response. No it is not any reason to add testing specifically for half. We can also do the same tests for other data types. Here we just check that it is no any qualifiers in metadata. https://reviews.llvm.org/D35000 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D35000: [OpenCL] Added extended tests on metadata generation for half data type and arrays.
echuraev updated this revision to Diff 106851. https://reviews.llvm.org/D35000 Files: test/CodeGenOpenCL/kernel-arg-info.cl Index: test/CodeGenOpenCL/kernel-arg-info.cl === --- test/CodeGenOpenCL/kernel-arg-info.cl +++ test/CodeGenOpenCL/kernel-arg-info.cl @@ -1,10 +1,24 @@ // RUN: %clang_cc1 %s -cl-std=CL2.0 -emit-llvm -o - -triple spir-unknown-unknown | FileCheck %s // RUN: %clang_cc1 %s -cl-std=CL2.0 -emit-llvm -o - -triple spir-unknown-unknown -cl-kernel-arg-info | FileCheck %s -check-prefix ARGINFO -kernel void foo(__global int * restrict X, const int Y, -volatile int anotherArg, __constant float * restrict Z, -__global volatile int * V, __global const int * C) { - *X = Y + anotherArg; +kernel void foo(global int * globalintp, global int * restrict globalintrestrictp, +global const int * globalconstintp, +global const int * restrict globalconstintrestrictp, +constant int * constantintp, constant int * restrict constantintrestrictp, +global const volatile int * globalconstvolatileintp, +global const volatile int * restrict globalconstvolatileintrestrictp, +global volatile int * globalvolatileintp, +global volatile int * restrict globalvolatileintrestrictp, +local int * localintp, local int * restrict localintrestrictp, +local const int * localconstintp, +local const int * restrict localconstintrestrictp, +local const volatile int * localconstvolatileintp, +local const volatile int * restrict localconstvolatileintrestrictp, +local volatile int * localvolatileintp, +local volatile int * restrict localvolatileintrestrictp, +int X, const int constint, const volatile int constvolatileint, +volatile int volatileint) { + *globalintrestrictp = constint + volatileint; } // CHECK: define spir_kernel void @foo{{[^!]+}} // CHECK: !kernel_arg_addr_space ![[MD11:[0-9]+]] @@ -61,11 +75,15 @@ // CHECK-NOT: !kernel_arg_name // ARGINFO: !kernel_arg_name ![[MD54:[0-9]+]] -// CHECK: ![[MD11]] = !{i32 1, i32 0, i32 0, i32 2, i32 1, i32 1} -// CHECK: ![[MD12]] = !{!"none", !"none", !"none", !"none", !"none", !"none"} -// CHECK: ![[MD13]] = !{!"int*", !"int", !"int", !"float*", !"int*", !"int*"} -// CHECK: ![[MD14]] = !{!"restrict", !"", !"", !"restrict const", !"volatile", !"const"} -// ARGINFO: ![[MD15]] = !{!"X", !"Y", !"anotherArg", !"Z", !"V", !"C"} +typedef char char16 __attribute__((ext_vector_type(16))); +__kernel void foo6(__global char16 arg[]) {} +// CHECK: !kernel_arg_type ![[MD61:[0-9]+]] + +// CHECK: ![[MD11]] = !{i32 1, i32 1, i32 1, i32 1, i32 2, i32 2, i32 1, i32 1, i32 1, i32 1, i32 3, i32 3, i32 3, i32 3, i32 3, i32 3, i32 3, i32 3, i32 0, i32 0, i32 0, i32 0} +// CHECK: ![[MD12]] = !{!"none", !"none", !"none", !"none", !"none", !"none", !"none", !"none", !"none", !"none", !"none", !"none", !"none", !"none", !"none", !"none", !"none", !"none", !"none", !"none", !"none", !"none"} +// CHECK: ![[MD13]] = !{!"int*", !"int*", !"int*", !"int*", !"int*", !"int*", !"int*", !"int*", !"int*", !"int*", !"int*", !"int*", !"int*", !"int*", !"int*", !"int*", !"int*", !"int*", !"int", !"int", !"int", !"int"} +// CHECK: ![[MD14]] = !{!"", !"restrict", !"const", !"restrict const", !"const", !"restrict const", !"const volatile", !"restrict const volatile", !"volatile", !"restrict volatile", !"", !"restrict", !"const", !"restrict const", !"const volatile", !"restrict const volatile", !"volatile", !"restrict volatile", !"", !"", !"", !""} +// ARGINFO: ![[MD15]] = !{!"globalintp", !"globalintrestrictp", !"globalconstintp", !"globalconstintrestrictp", !"constantintp", !"constantintrestrictp", !"globalconstvolatileintp", !"globalconstvolatileintrestrictp", !"globalvolatileintp", !"globalvolatileintrestrictp", !"localintp", !"localintrestrictp", !"localconstintp", !"localconstintrestrictp", !"localconstvolatileintp", !"localconstvolatileintrestrictp", !"localvolatileintp", !"localvolatileintrestrictp", !"X", !"constint", !"constvolatileint", !"volatileint"} // CHECK: ![[MD21]] = !{i32 1, i32 1, i32 1, i32 1} // CHECK: ![[MD22]] = !{!"read_only", !"read_only", !"write_only", !"read_write"} // CHECK: ![[MD23]] = !{!"image1d_t", !"image2d_t", !"image2d_array_t", !"image1d_t"} @@ -86,4 +104,5 @@ // CHECK: ![[MD52]] = !{!"myImage", !"image1d_t"} // CHECK: ![[MD53]] = !{!"image1d_t", !"image1d_t"} // ARGINFO: ![[MD54]] = !{!"img1", !"img2"} +// CHECK: ![[MD61]] = !{!"char16*"} Index: test/CodeGenOpenCL/kernel-arg-info.cl === --- test/CodeGenOpenCL/kernel-arg-info.cl +++ test/CodeGenOpenCL/kernel-arg-info.cl @@ -1,10 +1,24 @@ // RUN: %clang_cc1 %s -cl-std=CL2.0 -emit-llvm
[PATCH] D30643: [OpenCL] Extended diagnostics for atomic initialization
echuraev created this revision. Herald added a subscriber: yaxunl. I saw the same changes in the following review: https://reviews.llvm.org/D17438 I don't know in that way I could determine that atomic variable was initialized by macro ATOMIC_VAR_INIT. Anyway I added check that atomic variables can be initialize only in global scope. I think that we can discuss this change. https://reviews.llvm.org/D30643 Files: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaInit.cpp test/SemaOpenCL/atomic-init.cl Index: test/SemaOpenCL/atomic-init.cl === --- /dev/null +++ test/SemaOpenCL/atomic-init.cl @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -O0 -cl-std=CL2.0 -fsyntax-only -verify %s + +global atomic_int a1 = 0; + +kernel void test_atomic_initialization() { + atomic_int a2 = 0; // expected-error {{initialization of atomic variables is restricted to variables in global address space}} + private atomic_int a3 = 0; // expected-error {{initialization of atomic variables is restricted to variables in global address space}} + local atomic_int a4 = 0; // expected-error {{'__local' variable cannot have an initializer}} + global atomic_int a5 = 0; // expected-error {{function scope variable cannot be declared in global address space}} +} Index: lib/Sema/SemaInit.cpp === --- lib/Sema/SemaInit.cpp +++ lib/Sema/SemaInit.cpp @@ -6489,6 +6489,21 @@ << Init->getSourceRange(); } + // OpenCL v2.0 s6.13.11.1. atomic variables can be initialized in global scope + QualType ETy = Entity.getType(); + Qualifiers TyQualifiers = ETy.getQualifiers(); + bool HasGlobalAS = TyQualifiers.hasAddressSpace() && + TyQualifiers.getAddressSpace() == LangAS::opencl_global; + + if (S.getLangOpts().OpenCL && S.getLangOpts().OpenCLVersion >= 200 && + ETy->isAtomicType() && !HasGlobalAS && + Entity.getKind() == InitializedEntity::EK_Variable && Args.size() > 0) { +const Expr *Init = Args[0]; +S.Diag(Init->getLocStart(), diag::err_atomic_init_addressspace) << +SourceRange(Entity.getDecl()->getLocStart(), Init->getLocEnd()); +return ExprError(); + } + // Diagnose cases where we initialize a pointer to an array temporary, and the // pointer obviously outlives the temporary. if (Args.size() == 1 && Args[0]->getType()->isArrayType() && Index: include/clang/Basic/DiagnosticSemaKinds.td === --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -8258,6 +8258,9 @@ "return value cannot be qualified with address space">; def err_opencl_constant_no_init : Error< "variable in constant address space must be initialized">; +// Atomics +def err_atomic_init_addressspace : Error< + "initialization of atomic variables is restricted to variables in global address space">; def err_atomic_init_constant : Error< "atomic variable can only be assigned to a compile time constant" " in the declaration statement in the program scope">; Index: test/SemaOpenCL/atomic-init.cl === --- /dev/null +++ test/SemaOpenCL/atomic-init.cl @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -O0 -cl-std=CL2.0 -fsyntax-only -verify %s + +global atomic_int a1 = 0; + +kernel void test_atomic_initialization() { + atomic_int a2 = 0; // expected-error {{initialization of atomic variables is restricted to variables in global address space}} + private atomic_int a3 = 0; // expected-error {{initialization of atomic variables is restricted to variables in global address space}} + local atomic_int a4 = 0; // expected-error {{'__local' variable cannot have an initializer}} + global atomic_int a5 = 0; // expected-error {{function scope variable cannot be declared in global address space}} +} Index: lib/Sema/SemaInit.cpp === --- lib/Sema/SemaInit.cpp +++ lib/Sema/SemaInit.cpp @@ -6489,6 +6489,21 @@ << Init->getSourceRange(); } + // OpenCL v2.0 s6.13.11.1. atomic variables can be initialized in global scope + QualType ETy = Entity.getType(); + Qualifiers TyQualifiers = ETy.getQualifiers(); + bool HasGlobalAS = TyQualifiers.hasAddressSpace() && + TyQualifiers.getAddressSpace() == LangAS::opencl_global; + + if (S.getLangOpts().OpenCL && S.getLangOpts().OpenCLVersion >= 200 && + ETy->isAtomicType() && !HasGlobalAS && + Entity.getKind() == InitializedEntity::EK_Variable && Args.size() > 0) { +const Expr *Init = Args[0]; +S.Diag(Init->getLocStart(), diag::err_atomic_init_addressspace) << +SourceRange(Entity.getDecl()->getLocStart(), Init->getLocEnd()); +return ExprError(); + } + // Diagnose cases where we initialize a pointer to an array temporary, and the // pointer obviously outlives the
[PATCH] D27334: [OpenCL] Ambiguous function call.
echuraev added a comment. In https://reviews.llvm.org/D27334#614826, @Anastasia wrote: > In https://reviews.llvm.org/D27334#614389, @bader wrote: > > > In https://reviews.llvm.org/D27334#613504, @Anastasia wrote: > > > > > In https://reviews.llvm.org/D27334#612858, @bader wrote: > > > > > > > In https://reviews.llvm.org/D27334#611703, @Anastasia wrote: > > > > > > > > > This change seems to modify normal C behavior again. Is there any > > > > > strong motivation for doing this and if yes could it be done > > > > > generically with C? > > > > > > > > > > > > Motivation: > > > > > > > > // Non-portable OpenCL 1.2 code > > > > __kernel void foo(global float* out) { > > > > out[get_global_id(0)] = sin(get_global_id(0)); > > > > } > > > > > > > > > > > > This program compiles fine on OpenCL platform w/o doubles support and > > > > fails otherwise. > > > > If OpenCL driver supports doubles it provides at least two versions of > > > > 'sin' built-in math function and compiler will not be able to choose > > > > the right one for 'size_t' argument. > > > > The goal of this warning is to let OpenCL developer know about > > > > potential issues with code portability. > > > > > > > > > I would argue this improves the portability much as it can also be > > > misleading in some situations (because it refers to a potentially > > > hypothetical problem). For example there can be builtin functions that > > > only have a float parameter (without a double version of it). This is for > > > example the case with read_image functions that take a float coordinate > > > value between 0 and 1. Unfortunately this warning won't be triggered on > > > read_image functions because there is an overload candidate with an int > > > type of the same parameter too. But we can't exclude this situations to > > > appear in the future or from some vendor extensions or even custom OpenCL > > > code. > > > > > > As much as any other warning it's not always means that there is an error > > in the code. It just means that developer should inspect the construction > > triggering a warning. > > Passing integer value to a function with floating point parameters is not > > always an error, but some times it might be so. > > Do you suggest dropping the diagnostics at all or changing the diagnostics > > message? > > > I agree warnings don't always signal a definite issue (even thought it's good > to make them as precise as we can). We could try to reword the diagnostic > message. However, the biggest issue I have here is that the message can be > given in the situations that are unrelated to the problem (i.e. the overload > candidates that don't have anything to do with the parameter being diagnosed > or don't overload with the double precision). Therefore, it feels like the > diagnostic can be confusing in some cases even though they are not very > probable ones. @Anastasia, do you have any suggestions how is it better to reword the diagnostic message? Yes, this message can be given in some situations that are unrelated to the problem but in this case it will be a notification for developer that this function call can be potential ambiguous. Comment at: lib/Sema/SemaChecking.cpp:2479 +// integer values. +if (FDecl->hasAttr()) { + for (const auto* Arg : Args) { Anastasia wrote: > How does it check that this is a built-in function? In OpenCL we can overload only built-in functions. So, I think that we can recognize that the function is built-in by checking that the language is OpenCL and the function has Overloadable attribute. https://reviews.llvm.org/D27334 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30643: [OpenCL] Extended diagnostics for atomic initialization
echuraev updated this revision to Diff 91305. echuraev marked 2 inline comments as done. https://reviews.llvm.org/D30643 Files: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaInit.cpp test/SemaOpenCL/atomic-init.cl Index: test/SemaOpenCL/atomic-init.cl === --- /dev/null +++ test/SemaOpenCL/atomic-init.cl @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -O0 -cl-std=CL2.0 -fsyntax-only -verify %s + +global atomic_int a1 = 0; + +kernel void test_atomic_initialization() { + atomic_int a2 = 0; // expected-error {{initialization of atomic variables is restricted to variables in global address space}} + private atomic_int a3 = 0; // expected-error {{initialization of atomic variables is restricted to variables in global address space}} + local atomic_int a4 = 0; // expected-error {{'__local' variable cannot have an initializer}} + global atomic_int a5 = 0; // expected-error {{function scope variable cannot be declared in global address space}} +} Index: lib/Sema/SemaInit.cpp === --- lib/Sema/SemaInit.cpp +++ lib/Sema/SemaInit.cpp @@ -6489,6 +6489,20 @@ << Init->getSourceRange(); } + // OpenCL v2.0 s6.13.11.1. atomic variables can be initialized in global scope + QualType ETy = Entity.getType(); + Qualifiers TyQualifiers = ETy.getQualifiers(); + bool HasGlobalAS = TyQualifiers.hasAddressSpace() && + TyQualifiers.getAddressSpace() == LangAS::opencl_global; + + if (S.getLangOpts().OpenCLVersion >= 200 && + ETy->isAtomicType() && !HasGlobalAS && + Entity.getKind() == InitializedEntity::EK_Variable && Args.size() > 0) { +S.Diag(Args[0]->getLocStart(), diag::err_atomic_init_addressspace) << +SourceRange(Entity.getDecl()->getLocStart(), Args[0]->getLocEnd()); +return ExprError(); + } + // Diagnose cases where we initialize a pointer to an array temporary, and the // pointer obviously outlives the temporary. if (Args.size() == 1 && Args[0]->getType()->isArrayType() && Index: include/clang/Basic/DiagnosticSemaKinds.td === --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -8264,6 +8264,9 @@ "return value cannot be qualified with address space">; def err_opencl_constant_no_init : Error< "variable in constant address space must be initialized">; +// Atomics +def err_atomic_init_addressspace : Error< + "initialization of atomic variables is restricted to variables in global address space">; def err_atomic_init_constant : Error< "atomic variable can only be assigned to a compile time constant" " in the declaration statement in the program scope">; Index: test/SemaOpenCL/atomic-init.cl === --- /dev/null +++ test/SemaOpenCL/atomic-init.cl @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -O0 -cl-std=CL2.0 -fsyntax-only -verify %s + +global atomic_int a1 = 0; + +kernel void test_atomic_initialization() { + atomic_int a2 = 0; // expected-error {{initialization of atomic variables is restricted to variables in global address space}} + private atomic_int a3 = 0; // expected-error {{initialization of atomic variables is restricted to variables in global address space}} + local atomic_int a4 = 0; // expected-error {{'__local' variable cannot have an initializer}} + global atomic_int a5 = 0; // expected-error {{function scope variable cannot be declared in global address space}} +} Index: lib/Sema/SemaInit.cpp === --- lib/Sema/SemaInit.cpp +++ lib/Sema/SemaInit.cpp @@ -6489,6 +6489,20 @@ << Init->getSourceRange(); } + // OpenCL v2.0 s6.13.11.1. atomic variables can be initialized in global scope + QualType ETy = Entity.getType(); + Qualifiers TyQualifiers = ETy.getQualifiers(); + bool HasGlobalAS = TyQualifiers.hasAddressSpace() && + TyQualifiers.getAddressSpace() == LangAS::opencl_global; + + if (S.getLangOpts().OpenCLVersion >= 200 && + ETy->isAtomicType() && !HasGlobalAS && + Entity.getKind() == InitializedEntity::EK_Variable && Args.size() > 0) { +S.Diag(Args[0]->getLocStart(), diag::err_atomic_init_addressspace) << +SourceRange(Entity.getDecl()->getLocStart(), Args[0]->getLocEnd()); +return ExprError(); + } + // Diagnose cases where we initialize a pointer to an array temporary, and the // pointer obviously outlives the temporary. if (Args.size() == 1 && Args[0]->getType()->isArrayType() && Index: include/clang/Basic/DiagnosticSemaKinds.td === --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -8264,6 +8264,9 @@ "return value cannot be qualified with address space">; def err_opencl_constant_no_in
[PATCH] D30643: [OpenCL] Extended diagnostics for atomic initialization
echuraev added inline comments. Comment at: include/clang/Basic/DiagnosticSemaKinds.td:8263 +def err_atomic_init_addressspace : Error< + "initialization of atomic variables is restricted to variables in global address space">; def err_atomic_init_constant : Error< Anastasia wrote: > Could we combine this error diag with the one below? I guess they are > semantically very similar apart from one is about initialization and another > is about assignment? I'm not sure that it is a good idea to combine these errors. For example, if developer had declared a variable non-constant and not in global address space he would have got the same message for both errors. And it can be difficult to determine what the exact problem is. He can fix one of the problems but he will still get the same error. https://reviews.llvm.org/D30643 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30816: [OpenCL] Added implicit conversion rank for overloading functions with vector data type in OpenCL
echuraev created this revision. Herald added a subscriber: yaxunl. I added a new rank to ImplicitConversionRank enum to resolve the function overload ambiguity with vector types. Rank of scalar types conversion is lower than vector splat. So, we can choose which function should we call. See test for more details. https://reviews.llvm.org/D30816 Files: include/clang/Sema/Overload.h lib/Sema/SemaOverload.cpp test/SemaOpenCL/overload-scalar-widening.cl Index: test/SemaOpenCL/overload-scalar-widening.cl === --- /dev/null +++ test/SemaOpenCL/overload-scalar-widening.cl @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL2.0 +// expected-no-diagnostics + +typedef short short4 __attribute__((ext_vector_type(4))); + +short4 __attribute__ ((overloadable)) clamp(short4 x, short4 minval, short4 maxval); +short4 __attribute__ ((overloadable)) clamp(short4 x, short minval, short maxval); + +void foo() +{ +short4 e0=0; +clamp(e0, 0, 255); +} Index: lib/Sema/SemaOverload.cpp === --- lib/Sema/SemaOverload.cpp +++ lib/Sema/SemaOverload.cpp @@ -131,7 +131,7 @@ ICR_Conversion, ICR_Conversion, ICR_Conversion, -ICR_Conversion, +ICR_OCL_Scalar_Widening, ICR_Complex_Real_Conversion, ICR_Conversion, ICR_Conversion, Index: include/clang/Sema/Overload.h === --- include/clang/Sema/Overload.h +++ include/clang/Sema/Overload.h @@ -98,6 +98,7 @@ ICR_Exact_Match = 0, ///< Exact Match ICR_Promotion, ///< Promotion ICR_Conversion, ///< Conversion +ICR_OCL_Scalar_Widening, ///< OpenCL Scalar Widening ICR_Complex_Real_Conversion, ///< Complex <-> Real conversion ICR_Writeback_Conversion,///< ObjC ARC writeback conversion ICR_C_Conversion,///< Conversion only allowed in the C standard. Index: test/SemaOpenCL/overload-scalar-widening.cl === --- /dev/null +++ test/SemaOpenCL/overload-scalar-widening.cl @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL2.0 +// expected-no-diagnostics + +typedef short short4 __attribute__((ext_vector_type(4))); + +short4 __attribute__ ((overloadable)) clamp(short4 x, short4 minval, short4 maxval); +short4 __attribute__ ((overloadable)) clamp(short4 x, short minval, short maxval); + +void foo() +{ +short4 e0=0; +clamp(e0, 0, 255); +} Index: lib/Sema/SemaOverload.cpp === --- lib/Sema/SemaOverload.cpp +++ lib/Sema/SemaOverload.cpp @@ -131,7 +131,7 @@ ICR_Conversion, ICR_Conversion, ICR_Conversion, -ICR_Conversion, +ICR_OCL_Scalar_Widening, ICR_Complex_Real_Conversion, ICR_Conversion, ICR_Conversion, Index: include/clang/Sema/Overload.h === --- include/clang/Sema/Overload.h +++ include/clang/Sema/Overload.h @@ -98,6 +98,7 @@ ICR_Exact_Match = 0, ///< Exact Match ICR_Promotion, ///< Promotion ICR_Conversion, ///< Conversion +ICR_OCL_Scalar_Widening, ///< OpenCL Scalar Widening ICR_Complex_Real_Conversion, ///< Complex <-> Real conversion ICR_Writeback_Conversion,///< ObjC ARC writeback conversion ICR_C_Conversion,///< Conversion only allowed in the C standard. ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D28136: [OpenCL] Implement as_type operator as alias of __builtin_astype.
echuraev updated this revision to Diff 91327. https://reviews.llvm.org/D28136 Files: lib/Headers/opencl-c.h test/SemaOpenCL/as_type.cl Index: test/SemaOpenCL/as_type.cl === --- test/SemaOpenCL/as_type.cl +++ test/SemaOpenCL/as_type.cl @@ -1,7 +1,4 @@ -// RUN: %clang_cc1 %s -emit-llvm -triple spir-unknown-unknown -o - -verify -fsyntax-only - -typedef __attribute__(( ext_vector_type(3) )) char char3; -typedef __attribute__(( ext_vector_type(16) )) char char16; +// RUN: %clang_cc1 %s -emit-llvm -triple spir-unknown-unknown -finclude-default-header -o - -verify -fsyntax-only char3 f1(char16 x) { return __builtin_astype(x, char3); // expected-error{{invalid reinterpretation: sizes of 'char3' (vector of 3 'char' values) and 'char16' (vector of 16 'char' values) must match}} @@ -11,3 +8,7 @@ return __builtin_astype(x, char16); // expected-error{{invalid reinterpretation: sizes of 'char16' (vector of 16 'char' values) and 'int' must match}} } +void foo() { +char src = 1; +int dst = as_int(src); // expected-error{{invalid reinterpretation: sizes of 'int' and 'char' must match}} +} Index: lib/Headers/opencl-c.h === --- lib/Headers/opencl-c.h +++ lib/Headers/opencl-c.h @@ -6584,777 +6584,85 @@ * OpenCL v1.1/1.2/2.0 s6.2.4.2 - as_type operators * Reinterprets a data type as another data type of the same size */ -char __ovld __cnfn as_char(char); -char __ovld __cnfn as_char(uchar); - -char2 __ovld __cnfn as_char2(char2); -char2 __ovld __cnfn as_char2(uchar2); -char2 __ovld __cnfn as_char2(short); -char2 __ovld __cnfn as_char2(ushort); - -char3 __ovld __cnfn as_char3(char3); -char3 __ovld __cnfn as_char3(char4); -char3 __ovld __cnfn as_char3(uchar3); -char3 __ovld __cnfn as_char3(uchar4); -char3 __ovld __cnfn as_char3(short2); -char3 __ovld __cnfn as_char3(ushort2); -char3 __ovld __cnfn as_char3(int); -char3 __ovld __cnfn as_char3(uint); -char3 __ovld __cnfn as_char3(float); - -char4 __ovld __cnfn as_char4(char3); -char4 __ovld __cnfn as_char4(char4); -char4 __ovld __cnfn as_char4(uchar3); -char4 __ovld __cnfn as_char4(uchar4); -char4 __ovld __cnfn as_char4(short2); -char4 __ovld __cnfn as_char4(ushort2); -char4 __ovld __cnfn as_char4(int); -char4 __ovld __cnfn as_char4(uint); -char4 __ovld __cnfn as_char4(float); - -char8 __ovld __cnfn as_char8(char8); -char8 __ovld __cnfn as_char8(uchar8); -char8 __ovld __cnfn as_char8(short3); -char8 __ovld __cnfn as_char8(short4); -char8 __ovld __cnfn as_char8(ushort3); -char8 __ovld __cnfn as_char8(ushort4); -char8 __ovld __cnfn as_char8(int2); -char8 __ovld __cnfn as_char8(uint2); -char8 __ovld __cnfn as_char8(long); -char8 __ovld __cnfn as_char8(ulong); -char8 __ovld __cnfn as_char8(float2); - -char16 __ovld __cnfn as_char16(char16); -char16 __ovld __cnfn as_char16(uchar16); -char16 __ovld __cnfn as_char16(short8); -char16 __ovld __cnfn as_char16(ushort8); -char16 __ovld __cnfn as_char16(int3); -char16 __ovld __cnfn as_char16(int4); -char16 __ovld __cnfn as_char16(uint3); -char16 __ovld __cnfn as_char16(uint4); -char16 __ovld __cnfn as_char16(long2); -char16 __ovld __cnfn as_char16(ulong2); -char16 __ovld __cnfn as_char16(float3); -char16 __ovld __cnfn as_char16(float4); - -uchar __ovld __cnfn as_uchar(char); -uchar __ovld __cnfn as_uchar(uchar); - -uchar2 __ovld __cnfn as_uchar2(char2); -uchar2 __ovld __cnfn as_uchar2(uchar2); -uchar2 __ovld __cnfn as_uchar2(short); -uchar2 __ovld __cnfn as_uchar2(ushort); - -uchar3 __ovld __cnfn as_uchar3(char3); -uchar3 __ovld __cnfn as_uchar3(char4); -uchar3 __ovld __cnfn as_uchar3(uchar3); -uchar3 __ovld __cnfn as_uchar3(uchar4); -uchar3 __ovld __cnfn as_uchar3(short2); -uchar3 __ovld __cnfn as_uchar3(ushort2); -uchar3 __ovld __cnfn as_uchar3(int); -uchar3 __ovld __cnfn as_uchar3(uint); -uchar3 __ovld __cnfn as_uchar3(float); - -uchar4 __ovld __cnfn as_uchar4(char3); -uchar4 __ovld __cnfn as_uchar4(char4); -uchar4 __ovld __cnfn as_uchar4(uchar3); -uchar4 __ovld __cnfn as_uchar4(uchar4); -uchar4 __ovld __cnfn as_uchar4(short2); -uchar4 __ovld __cnfn as_uchar4(ushort2); -uchar4 __ovld __cnfn as_uchar4(int); -uchar4 __ovld __cnfn as_uchar4(uint); -uchar4 __ovld __cnfn as_uchar4(float); - -uchar8 __ovld __cnfn as_uchar8(char8); -uchar8 __ovld __cnfn as_uchar8(uchar8); -uchar8 __ovld __cnfn as_uchar8(short3); -uchar8 __ovld __cnfn as_uchar8(short4); -uchar8 __ovld __cnfn as_uchar8(ushort3); -uchar8 __ovld __cnfn as_uchar8(ushort4); -uchar8 __ovld __cnfn as_uchar8(int2); -uchar8 __ovld __cnfn as_uchar8(uint2); -uchar8 __ovld __cnfn as_uchar8(long); -uchar8 __ovld __cnfn as_uchar8(ulong); -uchar8 __ovld __cnfn as_uchar8(float2); - -uchar16 __ovld __cnfn as_uchar16(char16); -uchar16 __ovld __cnfn as_uchar16(uchar16); -uchar16 __ovld __cnfn as_uchar16(short8); -uchar16 __ovld __cnfn as_uchar16(ushort8); -uchar16 __ovld __cnfn as_uchar16(int3); -uchar16 __ovld __cnfn as_uchar16(int4); -uchar1
[PATCH] D28136: [OpenCL] Implement as_type operator as alias of __builtin_astype.
echuraev added a comment. In https://reviews.llvm.org/D28136#634356, @Anastasia wrote: > This has been discussed during the initial review for the header: > http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20160425/157187.html > > The main issue is after preprocessing the header the original function name > is no longer available in diagnostics reported. The spec defines as_type as a > builtin function and not a macro. Additionally your patch would allow as_type > to be used with extra type (not only those defined in spec). Also I don't see > the problem to implement as_type with just simply calling a builtin. It > should be inlined later anyways. I think that this patch is really necessary because in some cases previous implementation doesn't give a diagnostic. Please see test case that I have added to this review. With current implementation //char// variable will be cast to //int//. You can see the following part of llvm ir: %0 = load i8, i8* %src, align 1 %conv = sext i8 %0 to i32 %call = call i32 @_Z6as_inti(i32 %conv) #2 So there is a bug and we didn't get error that the size of char isn't equal to size of int. Program is compiled without any problems. If as_type functions will be defined in macro then we will have the following message: error: invalid reinterpretation: sizes of 'float' and 'char' must match int dst = as_int( src ); ^~~ ././llvm/tools/clang/lib/Headers/opencl-c-common.h:6615:21: note: expanded from macro 'as_int' #define as_int(x) __builtin_astype((x), int) ^~~~ https://reviews.llvm.org/D28136 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30643: [OpenCL] Extended diagnostics for atomic initialization
echuraev updated this revision to Diff 91536. https://reviews.llvm.org/D30643 Files: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaExpr.cpp lib/Sema/SemaInit.cpp test/Parser/opencl-atomics-cl20.cl test/SemaOpenCL/atomic-init.cl Index: test/SemaOpenCL/atomic-init.cl === --- /dev/null +++ test/SemaOpenCL/atomic-init.cl @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -O0 -cl-std=CL2.0 -fsyntax-only -verify %s + +global atomic_int a1 = 0; + +kernel void test_atomic_initialization() { + a1 = 1; // expected-error {{atomic variable can only be assigned to a compile time constant or to variables in global adress space}} + atomic_int a2 = 0; // expected-error {{atomic variable can only be assigned to a compile time constant or to variables in global adress space}} + private atomic_int a3 = 0; // expected-error {{atomic variable can only be assigned to a compile time constant or to variables in global adress space}} + local atomic_int a4 = 0; // expected-error {{'__local' variable cannot have an initializer}} + global atomic_int a5 = 0; // expected-error {{function scope variable cannot be declared in global address space}} +} Index: test/Parser/opencl-atomics-cl20.cl === --- test/Parser/opencl-atomics-cl20.cl +++ test/Parser/opencl-atomics-cl20.cl @@ -67,7 +67,7 @@ foo(&i); // OpenCL v2.0 s6.13.11.8, arithemtic operations are not permitted on atomic types. i++; // expected-error {{invalid argument type 'atomic_int' (aka '_Atomic(int)') to unary expression}} - i = 1; // expected-error {{atomic variable can only be assigned to a compile time constant in the declaration statement in the program scope}} + i = 1; // expected-error {{atomic variable can only be assigned to a compile time constant or to variables in global adress space}} i += 1; // expected-error {{invalid operands to binary expression ('atomic_int' (aka '_Atomic(int)') and 'int')}} i = i + i; // expected-error {{invalid operands to binary expression ('atomic_int' (aka '_Atomic(int)') and 'atomic_int')}} } Index: lib/Sema/SemaInit.cpp === --- lib/Sema/SemaInit.cpp +++ lib/Sema/SemaInit.cpp @@ -6489,6 +6489,20 @@ << Init->getSourceRange(); } + // OpenCL v2.0 s6.13.11.1. atomic variables can be initialized in global scope + QualType ETy = Entity.getType(); + Qualifiers TyQualifiers = ETy.getQualifiers(); + bool HasGlobalAS = TyQualifiers.hasAddressSpace() && + TyQualifiers.getAddressSpace() == LangAS::opencl_global; + + if (S.getLangOpts().OpenCLVersion >= 200 && + ETy->isAtomicType() && !HasGlobalAS && + Entity.getKind() == InitializedEntity::EK_Variable && Args.size() > 0) { +S.Diag(Args[0]->getLocStart(), diag::err_atomic_init) << +SourceRange(Entity.getDecl()->getLocStart(), Args[0]->getLocEnd()); +return ExprError(); + } + // Diagnose cases where we initialize a pointer to an array temporary, and the // pointer obviously outlives the temporary. if (Args.size() == 1 && Args[0]->getType()->isArrayType() && Index: lib/Sema/SemaExpr.cpp === --- lib/Sema/SemaExpr.cpp +++ lib/Sema/SemaExpr.cpp @@ -11091,7 +11091,7 @@ if (LHSTy->isAtomicType() || RHSTy->isAtomicType()) { SourceRange SR(LHSExpr->getLocStart(), RHSExpr->getLocEnd()); if (BO_Assign == Opc) -Diag(OpLoc, diag::err_atomic_init_constant) << SR; +Diag(OpLoc, diag::err_atomic_init) << SR; else ResultTy = InvalidOperands(OpLoc, LHS, RHS); return ExprError(); Index: include/clang/Basic/DiagnosticSemaKinds.td === --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -8264,9 +8264,9 @@ "return value cannot be qualified with address space">; def err_opencl_constant_no_init : Error< "variable in constant address space must be initialized">; -def err_atomic_init_constant : Error< - "atomic variable can only be assigned to a compile time constant" - " in the declaration statement in the program scope">; +// Atomics +def err_atomic_init: Error< + "atomic variable can only be assigned to a compile time constant or to variables in global adress space">; def err_opencl_implicit_vector_conversion : Error< "implicit conversions between vector types (%0 and %1) are not permitted">; def err_opencl_invalid_type_array : Error< Index: test/SemaOpenCL/atomic-init.cl === --- /dev/null +++ test/SemaOpenCL/atomic-init.cl @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -O0 -cl-std=CL2.0 -fsyntax-only -verify %s + +global atomic_int a1 = 0; + +kernel void test_atomic_initialization() { + a1 = 1; // expected-error {{atomic vari
[PATCH] D30816: [OpenCL] Added implicit conversion rank for overloading functions with vector data type in OpenCL
echuraev updated this revision to Diff 91691. echuraev marked an inline comment as done. https://reviews.llvm.org/D30816 Files: include/clang/Sema/Overload.h lib/Sema/SemaOverload.cpp test/SemaOpenCL/overload_addrspace_resolution.cl Index: test/SemaOpenCL/overload_addrspace_resolution.cl === --- test/SemaOpenCL/overload_addrspace_resolution.cl +++ test/SemaOpenCL/overload_addrspace_resolution.cl @@ -1,5 +1,11 @@ -// RUN: %clang_cc1 -cl-std=CL2.0 -emit-llvm -o - -triple x86_64-unknown-unknown %s | FileCheck %s +// RUN: %clang_cc1 -cl-std=CL2.0 -emit-llvm -o - -triple spir-unknown-unknown %s | FileCheck %s +typedef short short4 __attribute__((ext_vector_type(4))); + +// CHECK-DAG: declare spir_func <4 x i16> @_Z5clampDv4_sS_S_(<4 x i16>, <4 x i16>, <4 x i16>) +short4 __attribute__ ((overloadable)) clamp(short4 x, short4 minval, short4 maxval); +// CHECK-DAG: declare spir_func <4 x i16> @_Z5clampDv4_sss(<4 x i16>, i16 signext, i16 signext) +short4 __attribute__ ((overloadable)) clamp(short4 x, short minval, short maxval); void __attribute__((overloadable)) foo(global int *a, global int *b); void __attribute__((overloadable)) foo(generic int *a, generic int *b); void __attribute__((overloadable)) bar(generic int *global *a, generic int *global *b); @@ -10,20 +16,25 @@ global int *b; generic int *c; local int *d; + short4 e0=0; generic int *generic *gengen; generic int *local *genloc; generic int *global *genglob; - // CHECK: call void @_Z3fooPU8CLglobaliS0_(i32* undef, i32* undef) + // CHECK-DAG: call spir_func void @_Z3fooPU3AS1iS0_(i32 addrspace(1)* undef, i32 addrspace(1)* undef) foo(a, b); - // CHECK: call void @_Z3fooPU9CLgenericiS0_(i32* undef, i32* undef) + // CHECK-DAG: call spir_func void @_Z3fooPU3AS4iS0_(i32 addrspace(4)* undef, i32 addrspace(4)* undef) foo(b, c); - // CHECK: call void @_Z3fooPU9CLgenericiS0_(i32* undef, i32* undef) + // CHECK-DAG: call spir_func void @_Z3fooPU3AS4iS0_(i32 addrspace(4)* undef, i32 addrspace(4)* undef) foo(a, d); - // CHECK: call void @_Z3barPU9CLgenericPU9CLgenericiS2_(i32** undef, i32** undef) + // CHECK-DAG: call spir_func void @_Z3barPU3AS4PU3AS4iS2_(i32 addrspace(4)* addrspace(4)* undef, i32 addrspace(4)* addrspace(4)* undef) bar(gengen, genloc); - // CHECK: call void @_Z3barPU9CLgenericPU9CLgenericiS2_(i32** undef, i32** undef) + // CHECK-DAG: call spir_func void @_Z3barPU3AS4PU3AS4iS2_(i32 addrspace(4)* addrspace(4)* undef, i32 addrspace(4)* addrspace(4)* undef) bar(gengen, genglob); - // CHECK: call void @_Z3barPU8CLglobalPU9CLgenericiS2_(i32** undef, i32** undef) + // CHECK-DAG: call spir_func void @_Z3barPU3AS1PU3AS4iS2_(i32 addrspace(4)* addrspace(1)* undef, i32 addrspace(4)* addrspace(1)* undef) bar(genglob, genglob); + // CHECK-DAG: call spir_func <4 x i16> @_Z5clampDv4_sss(<4 x i16> zeroinitializer, i16 signext 0, i16 signext 255) + clamp(e0, 0, 255); + // CHECK-DAG: call spir_func <4 x i16> @_Z5clampDv4_sS_S_(<4 x i16> zeroinitializer, <4 x i16> zeroinitializer, <4 x i16> zeroinitializer) + clamp(e0, e0, e0); } Index: lib/Sema/SemaOverload.cpp === --- lib/Sema/SemaOverload.cpp +++ lib/Sema/SemaOverload.cpp @@ -131,7 +131,7 @@ ICR_Conversion, ICR_Conversion, ICR_Conversion, -ICR_Conversion, +ICR_OCL_Scalar_Widening, ICR_Complex_Real_Conversion, ICR_Conversion, ICR_Conversion, Index: include/clang/Sema/Overload.h === --- include/clang/Sema/Overload.h +++ include/clang/Sema/Overload.h @@ -98,6 +98,7 @@ ICR_Exact_Match = 0, ///< Exact Match ICR_Promotion, ///< Promotion ICR_Conversion, ///< Conversion +ICR_OCL_Scalar_Widening, ///< OpenCL Scalar Widening ICR_Complex_Real_Conversion, ///< Complex <-> Real conversion ICR_Writeback_Conversion,///< ObjC ARC writeback conversion ICR_C_Conversion,///< Conversion only allowed in the C standard. Index: test/SemaOpenCL/overload_addrspace_resolution.cl === --- test/SemaOpenCL/overload_addrspace_resolution.cl +++ test/SemaOpenCL/overload_addrspace_resolution.cl @@ -1,5 +1,11 @@ -// RUN: %clang_cc1 -cl-std=CL2.0 -emit-llvm -o - -triple x86_64-unknown-unknown %s | FileCheck %s +// RUN: %clang_cc1 -cl-std=CL2.0 -emit-llvm -o - -triple spir-unknown-unknown %s | FileCheck %s +typedef short short4 __attribute__((ext_vector_type(4))); + +// CHECK-DAG: declare spir_func <4 x i16> @_Z5clampDv4_sS_S_(<4 x i16>, <4 x i16>, <4 x i16>) +short4 __attribute__ ((overloadable)) clamp(short4 x, short4 minval, short4 maxval); +// CHECK-DAG: declare spir_func <4 x i16> @_Z5clampDv4_sss(<4 x i16>, i16 signext, i16 signext) +short4 __attribute__ ((overloadable)) clamp(sh
[PATCH] D30937: Added diagnostic for checking length of vector
echuraev created this revision. https://reviews.llvm.org/D30937 Files: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaExprMember.cpp test/SemaOpenCL/vector_swizzle_length.cl Index: test/SemaOpenCL/vector_swizzle_length.cl === --- /dev/null +++ test/SemaOpenCL/vector_swizzle_length.cl @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only + +typedef float float8 __attribute__((ext_vector_type(8))); + +void foo() { +float8 f2 = (float8)(0, 0, 0, 0, 0, 0, 0, 0); + +f2.s01234; // expected-error {{vector component access has invalid length 5. Supported: 1,2,3,4,8,16}} +} Index: lib/Sema/SemaExprMember.cpp === --- lib/Sema/SemaExprMember.cpp +++ lib/Sema/SemaExprMember.cpp @@ -284,6 +284,16 @@ } } +// OpenCL spec (Section 6.1.7 Vector Components): +// The component group notation can occur on the left hand side of an expression. To form an lvalue, +// swizzling must be applied to an l-value of vector type, contain no duplicate components, +// and it results in an l-value of scalar or vector type, depending on number of components +// specified. Each component must be a supported scalar or vector type. +static bool IsValidSwizzleLength(unsigned len) +{ + return (len >= 1 && len <= 4) || len == 8 || len == 16; +} + /// Check an ext-vector component access expression. /// /// VK should be set in advance to the value kind of the base @@ -376,6 +386,20 @@ } } + if (S.getLangOpts().OpenCL && !HalvingSwizzle) { +compStr = CompName->getNameStart(); + +if (HexSwizzle) + compStr++; + +unsigned swizzleLength = StringRef(compStr).size(); +if (IsValidSwizzleLength(swizzleLength) == false) { + S.Diag(OpLoc, diag::err_opencl_ext_vector_component_invalid_length) +<< swizzleLength << SourceRange(CompLoc); + return QualType(); +} + } + // The component accessor looks fine - now we need to compute the actual type. // The vector type is implied by the component accessor. For example, // vec4.b is a float, vec4.xy is a vec2, vec4.rgb is a vec3, etc. Index: include/clang/Basic/DiagnosticSemaKinds.td === --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -8219,6 +8219,8 @@ def err_kernel_arg_address_space : Error< "pointer arguments to kernel functions must reside in '__global', " "'__constant' or '__local' address space">; +def err_opencl_ext_vector_component_invalid_length : Error< + "vector component access has invalid length %0. Supported: 1,2,3,4,8,16.">; def err_opencl_function_variable : Error< "%select{non-kernel function|function scope}0 variable cannot be declared in %1 address space">; def err_static_function_scope : Error< Index: test/SemaOpenCL/vector_swizzle_length.cl === --- /dev/null +++ test/SemaOpenCL/vector_swizzle_length.cl @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only + +typedef float float8 __attribute__((ext_vector_type(8))); + +void foo() { +float8 f2 = (float8)(0, 0, 0, 0, 0, 0, 0, 0); + +f2.s01234; // expected-error {{vector component access has invalid length 5. Supported: 1,2,3,4,8,16}} +} Index: lib/Sema/SemaExprMember.cpp === --- lib/Sema/SemaExprMember.cpp +++ lib/Sema/SemaExprMember.cpp @@ -284,6 +284,16 @@ } } +// OpenCL spec (Section 6.1.7 Vector Components): +// The component group notation can occur on the left hand side of an expression. To form an lvalue, +// swizzling must be applied to an l-value of vector type, contain no duplicate components, +// and it results in an l-value of scalar or vector type, depending on number of components +// specified. Each component must be a supported scalar or vector type. +static bool IsValidSwizzleLength(unsigned len) +{ + return (len >= 1 && len <= 4) || len == 8 || len == 16; +} + /// Check an ext-vector component access expression. /// /// VK should be set in advance to the value kind of the base @@ -376,6 +386,20 @@ } } + if (S.getLangOpts().OpenCL && !HalvingSwizzle) { +compStr = CompName->getNameStart(); + +if (HexSwizzle) + compStr++; + +unsigned swizzleLength = StringRef(compStr).size(); +if (IsValidSwizzleLength(swizzleLength) == false) { + S.Diag(OpLoc, diag::err_opencl_ext_vector_component_invalid_length) +<< swizzleLength << SourceRange(CompLoc); + return QualType(); +} + } + // The component accessor looks fine - now we need to compute the actual type. // The vector type is implied by the component accessor. For example, // vec4.b is a float, vec4.xy is a vec2, vec4.rgb is a vec3, etc. Index: include/clang/Basic/DiagnosticSemaKinds.td =
[PATCH] D30816: [OpenCL] Added implicit conversion rank for overloading functions with vector data type in OpenCL
echuraev updated this revision to Diff 91713. echuraev marked 2 inline comments as done. https://reviews.llvm.org/D30816 Files: include/clang/Sema/Overload.h lib/Sema/SemaOverload.cpp test/CodeGenOpenCL/overload.cl test/SemaOpenCL/overload_addrspace_resolution.cl Index: test/SemaOpenCL/overload_addrspace_resolution.cl === --- test/SemaOpenCL/overload_addrspace_resolution.cl +++ /dev/null @@ -1,29 +0,0 @@ -// RUN: %clang_cc1 -cl-std=CL2.0 -emit-llvm -o - -triple x86_64-unknown-unknown %s | FileCheck %s - -void __attribute__((overloadable)) foo(global int *a, global int *b); -void __attribute__((overloadable)) foo(generic int *a, generic int *b); -void __attribute__((overloadable)) bar(generic int *global *a, generic int *global *b); -void __attribute__((overloadable)) bar(generic int *generic *a, generic int *generic *b); - -void kernel ker() { - global int *a; - global int *b; - generic int *c; - local int *d; - generic int *generic *gengen; - generic int *local *genloc; - generic int *global *genglob; - // CHECK: call void @_Z3fooPU8CLglobaliS0_(i32* undef, i32* undef) - foo(a, b); - // CHECK: call void @_Z3fooPU9CLgenericiS0_(i32* undef, i32* undef) - foo(b, c); - // CHECK: call void @_Z3fooPU9CLgenericiS0_(i32* undef, i32* undef) - foo(a, d); - - // CHECK: call void @_Z3barPU9CLgenericPU9CLgenericiS2_(i32** undef, i32** undef) - bar(gengen, genloc); - // CHECK: call void @_Z3barPU9CLgenericPU9CLgenericiS2_(i32** undef, i32** undef) - bar(gengen, genglob); - // CHECK: call void @_Z3barPU8CLglobalPU9CLgenericiS2_(i32** undef, i32** undef) - bar(genglob, genglob); -} Index: test/CodeGenOpenCL/overload.cl === --- /dev/null +++ test/CodeGenOpenCL/overload.cl @@ -0,0 +1,46 @@ +// RUN: %clang_cc1 -cl-std=CL2.0 -emit-llvm -o - -triple spir-unknown-unknown %s | FileCheck %s + +typedef short short4 __attribute__((ext_vector_type(4))); + +// CHECK-DAG: declare spir_func <4 x i16> @_Z5clampDv4_sS_S_(<4 x i16>, <4 x i16>, <4 x i16>) +short4 __attribute__ ((overloadable)) clamp(short4 x, short4 minval, short4 maxval); +// CHECK-DAG: declare spir_func <4 x i16> @_Z5clampDv4_sss(<4 x i16>, i16 signext, i16 signext) +short4 __attribute__ ((overloadable)) clamp(short4 x, short minval, short maxval); +void __attribute__((overloadable)) foo(global int *a, global int *b); +void __attribute__((overloadable)) foo(generic int *a, generic int *b); +void __attribute__((overloadable)) bar(generic int *global *a, generic int *global *b); +void __attribute__((overloadable)) bar(generic int *generic *a, generic int *generic *b); + +// Checking address space resolution +void kernel test1() { + global int *a; + global int *b; + generic int *c; + local int *d; + generic int *generic *gengen; + generic int *local *genloc; + generic int *global *genglob; + // CHECK-DAG: call spir_func void @_Z3fooPU3AS1iS0_(i32 addrspace(1)* undef, i32 addrspace(1)* undef) + foo(a, b); + // CHECK-DAG: call spir_func void @_Z3fooPU3AS4iS0_(i32 addrspace(4)* undef, i32 addrspace(4)* undef) + foo(b, c); + // CHECK-DAG: call spir_func void @_Z3fooPU3AS4iS0_(i32 addrspace(4)* undef, i32 addrspace(4)* undef) + foo(a, d); + + // CHECK-DAG: call spir_func void @_Z3barPU3AS4PU3AS4iS2_(i32 addrspace(4)* addrspace(4)* undef, i32 addrspace(4)* addrspace(4)* undef) + bar(gengen, genloc); + // CHECK-DAG: call spir_func void @_Z3barPU3AS4PU3AS4iS2_(i32 addrspace(4)* addrspace(4)* undef, i32 addrspace(4)* addrspace(4)* undef) + bar(gengen, genglob); + // CHECK-DAG: call spir_func void @_Z3barPU3AS1PU3AS4iS2_(i32 addrspace(4)* addrspace(1)* undef, i32 addrspace(4)* addrspace(1)* undef) + bar(genglob, genglob); +} + +// Checking vector vs scalar resolution +void kernel test2() { + short4 e0=0; + + // CHECK-DAG: call spir_func <4 x i16> @_Z5clampDv4_sss(<4 x i16> zeroinitializer, i16 signext 0, i16 signext 255) + clamp(e0, 0, 255); + // CHECK-DAG: call spir_func <4 x i16> @_Z5clampDv4_sS_S_(<4 x i16> zeroinitializer, <4 x i16> zeroinitializer, <4 x i16> zeroinitializer) + clamp(e0, e0, e0); +} Index: lib/Sema/SemaOverload.cpp === --- lib/Sema/SemaOverload.cpp +++ lib/Sema/SemaOverload.cpp @@ -131,7 +131,7 @@ ICR_Conversion, ICR_Conversion, ICR_Conversion, -ICR_Conversion, +ICR_OCL_Scalar_Widening, ICR_Complex_Real_Conversion, ICR_Conversion, ICR_Conversion, Index: include/clang/Sema/Overload.h === --- include/clang/Sema/Overload.h +++ include/clang/Sema/Overload.h @@ -98,6 +98,7 @@ ICR_Exact_Match = 0, ///< Exact Match ICR_Promotion, ///< Promotion ICR_Conversion, ///< Conversion +ICR_OCL_Scalar_Widening, ///< OpenCL Scalar Widening ICR_Complex_Real_Conversion, ///< Com
[PATCH] D27099: [OpenCL] Prohibit using reserve_id_t in program scope.
echuraev updated this revision to Diff 79292. echuraev marked 3 inline comments as done. https://reviews.llvm.org/D27099 Files: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaDecl.cpp test/SemaOpenCL/event_t.cl test/SemaOpenCL/invalid-clk-events-cl2.0.cl test/SemaOpenCL/invalid-pipes-cl2.0.cl Index: test/SemaOpenCL/invalid-pipes-cl2.0.cl === --- test/SemaOpenCL/invalid-pipes-cl2.0.cl +++ test/SemaOpenCL/invalid-pipes-cl2.0.cl @@ -1,5 +1,8 @@ // RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL2.0 +global pipe int gp;// expected-error {{type '__global read_only pipe int' can only be used as a function parameter in OpenCL}} +global reserve_id_t rid; // expected-error {{the '__global reserve_id_t' type cannot be used to declare a program scope variable}} + void test1(pipe int *p) {// expected-error {{pipes packet types cannot be of reference type}} } void test2(pipe p) {// expected-error {{missing actual type specifier for pipe}} @@ -20,3 +23,8 @@ typedef pipe int pipe_int_t; pipe_int_t test6() {} // expected-error{{declaring function return value of type 'pipe_int_t' (aka 'read_only pipe int') is not allowed}} + +bool test_id_comprision(void) { + reserve_id_t id1, id2; + return (id1 == id2); // expected-error {{invalid operands to binary expression ('reserve_id_t' and 'reserve_id_t')}} +} Index: test/SemaOpenCL/invalid-clk-events-cl2.0.cl === --- /dev/null +++ test/SemaOpenCL/invalid-clk-events-cl2.0.cl @@ -0,0 +1,3 @@ +// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL2.0 + +global clk_event_t ce; // expected-error {{the '__global clk_event_t' type cannot be used to declare a program scope variable}} Index: test/SemaOpenCL/event_t.cl === --- test/SemaOpenCL/event_t.cl +++ test/SemaOpenCL/event_t.cl @@ -1,6 +1,6 @@ // RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -event_t glb_evt; // expected-error {{the event_t type cannot be used to declare a program scope variable}} +event_t glb_evt; // expected-error {{the 'event_t' type cannot be used to declare a program scope variable}} constant struct evt_s { event_t evt; // expected-error {{the 'event_t' type cannot be used to declare a structure or union field}} Index: lib/Sema/SemaDecl.cpp === --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -5909,32 +5909,30 @@ return nullptr; } - // OpenCL v2.0 s6.9.b - Image type can only be used as a function argument. - // OpenCL v2.0 s6.13.16.1 - Pipe type can only be used as a function - // argument. - if (getLangOpts().OpenCL && (R->isImageType() || R->isPipeType())) { -Diag(D.getIdentifierLoc(), - diag::err_opencl_type_can_only_be_used_as_function_parameter) -<< R; -D.setInvalidType(); -return nullptr; - } - - DeclSpec::SCS SCSpec = D.getDeclSpec().getStorageClassSpec(); - StorageClass SC = StorageClassSpecToVarDeclStorageClass(D.getDeclSpec()); - - // dllimport globals without explicit storage class are treated as extern. We - // have to change the storage class this early to get the right DeclContext. - if (SC == SC_None && !DC->isRecord() && - hasParsedAttr(S, D, AttributeList::AT_DLLImport) && - !hasParsedAttr(S, D, AttributeList::AT_DLLExport)) -SC = SC_Extern; + if (getLangOpts().OpenCL) { +// OpenCL v2.0 s6.9.b - Image type can only be used as a function argument. +// OpenCL v2.0 s6.13.16.1 - Pipe type can only be used as a function +// argument. +if (R->isImageType() || R->isPipeType()) { + Diag(D.getIdentifierLoc(), + diag::err_opencl_type_can_only_be_used_as_function_parameter) + << R; + D.setInvalidType(); + return nullptr; +} - DeclContext *OriginalDC = DC; - bool IsLocalExternDecl = SC == SC_Extern && - adjustContextForLocalExternDecl(DC); +// OpenCL 1.2 spec, p6.9 r: +// The event type cannot be used to declare a program scope variable. +// OpenCL v2.0 s6.9.q The clk_event_t and reserve_id_t types cannot be declared in program scope. +if (NULL == S->getParent()) { + if (R->isReserveIDT() || R->isClkEventT() || R->isEventT()) { +Diag(D.getIdentifierLoc(), + diag::err_invalid_type_for_program_scope_var) << R; +D.setInvalidType(); +return nullptr; + } +} - if (getLangOpts().OpenCL) { // OpenCL v1.0 s6.8.a.3: Pointers to functions are not allowed. QualType NR = R; while (NR->isPointerType()) { @@ -5954,8 +5952,40 @@ D.setInvalidType(); } } + +// OpenCL v1.2 s6.9.b p4: +// The sampler type cannot be used with the __local and __global address +// space qualifiers. +if (R->isSamplerT() && (R.g
[PATCH] D27099: [OpenCL] Prohibit using reserve_id_t in program scope.
echuraev updated this revision to Diff 79372. echuraev marked 2 inline comments as done. https://reviews.llvm.org/D27099 Files: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaDecl.cpp test/SemaOpenCL/event_t.cl test/SemaOpenCL/invalid-clk-events-cl2.0.cl test/SemaOpenCL/invalid-pipes-cl2.0.cl Index: test/SemaOpenCL/invalid-pipes-cl2.0.cl === --- test/SemaOpenCL/invalid-pipes-cl2.0.cl +++ test/SemaOpenCL/invalid-pipes-cl2.0.cl @@ -1,5 +1,8 @@ // RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL2.0 +global pipe int gp;// expected-error {{type '__global read_only pipe int' can only be used as a function parameter in OpenCL}} +global reserve_id_t rid; // expected-error {{the '__global reserve_id_t' type cannot be used to declare a program scope variable}} + void test1(pipe int *p) {// expected-error {{pipes packet types cannot be of reference type}} } void test2(pipe p) {// expected-error {{missing actual type specifier for pipe}} @@ -20,3 +23,8 @@ typedef pipe int pipe_int_t; pipe_int_t test6() {} // expected-error{{declaring function return value of type 'pipe_int_t' (aka 'read_only pipe int') is not allowed}} + +bool test_id_comprision(void) { + reserve_id_t id1, id2; + return (id1 == id2); // expected-error {{invalid operands to binary expression ('reserve_id_t' and 'reserve_id_t')}} +} Index: test/SemaOpenCL/invalid-clk-events-cl2.0.cl === --- /dev/null +++ test/SemaOpenCL/invalid-clk-events-cl2.0.cl @@ -0,0 +1,3 @@ +// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL2.0 + +global clk_event_t ce; // expected-error {{the '__global clk_event_t' type cannot be used to declare a program scope variable}} Index: test/SemaOpenCL/event_t.cl === --- test/SemaOpenCL/event_t.cl +++ test/SemaOpenCL/event_t.cl @@ -1,6 +1,6 @@ // RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -event_t glb_evt; // expected-error {{the event_t type cannot be used to declare a program scope variable}} +event_t glb_evt; // expected-error {{the 'event_t' type cannot be used to declare a program scope variable}} constant struct evt_s { event_t evt; // expected-error {{the 'event_t' type cannot be used to declare a structure or union field}} Index: lib/Sema/SemaDecl.cpp === --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -5909,32 +5909,31 @@ return nullptr; } - // OpenCL v2.0 s6.9.b - Image type can only be used as a function argument. - // OpenCL v2.0 s6.13.16.1 - Pipe type can only be used as a function - // argument. - if (getLangOpts().OpenCL && (R->isImageType() || R->isPipeType())) { -Diag(D.getIdentifierLoc(), - diag::err_opencl_type_can_only_be_used_as_function_parameter) -<< R; -D.setInvalidType(); -return nullptr; - } - - DeclSpec::SCS SCSpec = D.getDeclSpec().getStorageClassSpec(); - StorageClass SC = StorageClassSpecToVarDeclStorageClass(D.getDeclSpec()); - - // dllimport globals without explicit storage class are treated as extern. We - // have to change the storage class this early to get the right DeclContext. - if (SC == SC_None && !DC->isRecord() && - hasParsedAttr(S, D, AttributeList::AT_DLLImport) && - !hasParsedAttr(S, D, AttributeList::AT_DLLExport)) -SC = SC_Extern; + if (getLangOpts().OpenCL) { +// OpenCL v2.0 s6.9.b - Image type can only be used as a function argument. +// OpenCL v2.0 s6.13.16.1 - Pipe type can only be used as a function +// argument. +if (R->isImageType() || R->isPipeType()) { + Diag(D.getIdentifierLoc(), + diag::err_opencl_type_can_only_be_used_as_function_parameter) + << R; + D.setInvalidType(); + return nullptr; +} - DeclContext *OriginalDC = DC; - bool IsLocalExternDecl = SC == SC_Extern && - adjustContextForLocalExternDecl(DC); +// OpenCL v1.2 s6.9.r: +// The event type cannot be used to declare a program scope variable. +// OpenCL v2.0 s6.9.q: +// The clk_event_t and reserve_id_t types cannot be declared in program scope. +if (NULL == S->getParent()) { + if (R->isReserveIDT() || R->isClkEventT() || R->isEventT()) { +Diag(D.getIdentifierLoc(), + diag::err_invalid_type_for_program_scope_var) << R; +D.setInvalidType(); +return nullptr; + } +} - if (getLangOpts().OpenCL) { // OpenCL v1.0 s6.8.a.3: Pointers to functions are not allowed. QualType NR = R; while (NR->isPointerType()) { @@ -5954,8 +5953,40 @@ D.setInvalidType(); } } + +// OpenCL v1.2 s6.9.b p4: +// The sampler type cannot be used with the __local and __global address +// space qualifiers. +if (R->isSamplerT() &&
[PATCH] D27099: [OpenCL] Prohibit using reserve_id_t in program scope.
echuraev updated this revision to Diff 79508. https://reviews.llvm.org/D27099 Files: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaDecl.cpp test/SemaOpenCL/event_t.cl test/SemaOpenCL/invalid-clk-events-cl2.0.cl test/SemaOpenCL/invalid-pipes-cl2.0.cl Index: test/SemaOpenCL/invalid-pipes-cl2.0.cl === --- test/SemaOpenCL/invalid-pipes-cl2.0.cl +++ test/SemaOpenCL/invalid-pipes-cl2.0.cl @@ -1,5 +1,8 @@ // RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL2.0 +global pipe int gp;// expected-error {{type '__global read_only pipe int' can only be used as a function parameter in OpenCL}} +global reserve_id_t rid; // expected-error {{the '__global reserve_id_t' type cannot be used to declare a program scope variable}} + void test1(pipe int *p) {// expected-error {{pipes packet types cannot be of reference type}} } void test2(pipe p) {// expected-error {{missing actual type specifier for pipe}} @@ -20,3 +23,8 @@ typedef pipe int pipe_int_t; pipe_int_t test6() {} // expected-error{{declaring function return value of type 'pipe_int_t' (aka 'read_only pipe int') is not allowed}} + +bool test_id_comprision(void) { + reserve_id_t id1, id2; + return (id1 == id2); // expected-error {{invalid operands to binary expression ('reserve_id_t' and 'reserve_id_t')}} +} Index: test/SemaOpenCL/invalid-clk-events-cl2.0.cl === --- /dev/null +++ test/SemaOpenCL/invalid-clk-events-cl2.0.cl @@ -0,0 +1,3 @@ +// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL2.0 + +global clk_event_t ce; // expected-error {{the '__global clk_event_t' type cannot be used to declare a program scope variable}} Index: test/SemaOpenCL/event_t.cl === --- test/SemaOpenCL/event_t.cl +++ test/SemaOpenCL/event_t.cl @@ -1,6 +1,6 @@ // RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -event_t glb_evt; // expected-error {{the event_t type cannot be used to declare a program scope variable}} +event_t glb_evt; // expected-error {{the 'event_t' type cannot be used to declare a program scope variable}} constant struct evt_s { event_t evt; // expected-error {{the 'event_t' type cannot be used to declare a structure or union field}} Index: lib/Sema/SemaDecl.cpp === --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -5909,32 +5909,31 @@ return nullptr; } - // OpenCL v2.0 s6.9.b - Image type can only be used as a function argument. - // OpenCL v2.0 s6.13.16.1 - Pipe type can only be used as a function - // argument. - if (getLangOpts().OpenCL && (R->isImageType() || R->isPipeType())) { -Diag(D.getIdentifierLoc(), - diag::err_opencl_type_can_only_be_used_as_function_parameter) -<< R; -D.setInvalidType(); -return nullptr; - } - - DeclSpec::SCS SCSpec = D.getDeclSpec().getStorageClassSpec(); - StorageClass SC = StorageClassSpecToVarDeclStorageClass(D.getDeclSpec()); - - // dllimport globals without explicit storage class are treated as extern. We - // have to change the storage class this early to get the right DeclContext. - if (SC == SC_None && !DC->isRecord() && - hasParsedAttr(S, D, AttributeList::AT_DLLImport) && - !hasParsedAttr(S, D, AttributeList::AT_DLLExport)) -SC = SC_Extern; + if (getLangOpts().OpenCL) { +// OpenCL v2.0 s6.9.b - Image type can only be used as a function argument. +// OpenCL v2.0 s6.13.16.1 - Pipe type can only be used as a function +// argument. +if (R->isImageType() || R->isPipeType()) { + Diag(D.getIdentifierLoc(), + diag::err_opencl_type_can_only_be_used_as_function_parameter) + << R; + D.setInvalidType(); + return nullptr; +} - DeclContext *OriginalDC = DC; - bool IsLocalExternDecl = SC == SC_Extern && - adjustContextForLocalExternDecl(DC); +// OpenCL v1.2 s6.9.r: +// The event type cannot be used to declare a program scope variable. +// OpenCL v2.0 s6.9.q: +// The clk_event_t and reserve_id_t types cannot be declared in program scope. +if (NULL == S->getParent()) { + if (R->isReserveIDT() || R->isClkEventT() || R->isEventT()) { +Diag(D.getIdentifierLoc(), + diag::err_invalid_type_for_program_scope_var) << R; +D.setInvalidType(); +return nullptr; + } +} - if (getLangOpts().OpenCL) { // OpenCL v1.0 s6.8.a.3: Pointers to functions are not allowed. QualType NR = R; while (NR->isPointerType()) { @@ -5954,8 +5953,40 @@ D.setInvalidType(); } } + +// OpenCL v1.2 s6.9.b p4: +// The sampler type cannot be used with the __local and __global address +// space qualifiers. +if (R->isSamplerT() && (R.getAddressSpace() == LangAS::opencl_loca
[PATCH] D27300: [OpenCL] Fix SPIR version generation.
echuraev created this revision. echuraev added a reviewer: Anastasia. echuraev added subscribers: cfe-commits, yaxunl, bader. https://reviews.llvm.org/D27300 Files: lib/CodeGen/TargetInfo.cpp test/CodeGenOpenCL/spir_version.cl Index: test/CodeGenOpenCL/spir_version.cl === --- test/CodeGenOpenCL/spir_version.cl +++ test/CodeGenOpenCL/spir_version.cl @@ -13,12 +13,12 @@ // CHECK-SPIR-CL10: !opencl.spir.version = !{[[SPIR:![0-9]+]]} // CHECK-SPIR-CL10: !opencl.ocl.version = !{[[OCL:![0-9]+]]} -// CHECK-SPIR-CL10: [[SPIR]] = !{i32 2, i32 0} +// CHECK-SPIR-CL10: [[SPIR]] = !{i32 1, i32 2} // CHECK-SPIR-CL10: [[OCL]] = !{i32 1, i32 0} // CHECK-SPIR-CL12: !opencl.spir.version = !{[[SPIR:![0-9]+]]} // CHECK-SPIR-CL12: !opencl.ocl.version = !{[[OCL:![0-9]+]]} -// CHECK-SPIR-CL12: [[SPIR]] = !{i32 2, i32 0} -// CHECK-SPIR-CL12: [[OCL]] = !{i32 1, i32 2} +// CHECK-SPIR-CL12: [[SPIR]] = !{i32 1, i32 2} + // CHECK-SPIR-CL20: !opencl.spir.version = !{[[SPIR:![0-9]+]]} // CHECK-SPIR-CL20: !opencl.ocl.version = !{[[SPIR:![0-9]+]]} // CHECK-SPIR-CL20: [[SPIR]] = !{i32 2, i32 0} @@ -28,4 +28,4 @@ // CHECK-AMDGCN-CL12: !opencl.ocl.version = !{[[OCL:![0-9]+]]} // CHECK-AMDGCN-CL12: [[OCL]] = !{i32 1, i32 2} // CHECK-AMDGCN-CL20: !opencl.ocl.version = !{[[OCL:![0-9]+]]} -// CHECK-AMDGCN-CL20: [[OCL]] = !{i32 2, i32 0} \ No newline at end of file +// CHECK-AMDGCN-CL20: [[OCL]] = !{i32 2, i32 0} Index: lib/CodeGen/TargetInfo.cpp === --- lib/CodeGen/TargetInfo.cpp +++ lib/CodeGen/TargetInfo.cpp @@ -7778,8 +7778,10 @@ // SPIR v2.0 s2.12 - The SPIR version used by the module is stored in the // opencl.spir.version named metadata. llvm::Metadata *SPIRVerElts[] = { - llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(Int32Ty, 2)), - llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(Int32Ty, 0))}; + llvm::ConstantAsMetadata::get( + llvm::ConstantInt::get(Int32Ty, CGM.getLangOpts().OpenCLVersion / 100)), + llvm::ConstantAsMetadata::get(llvm::ConstantInt::get( + Int32Ty, (CGM.getLangOpts().OpenCLVersion / 100 > 1) ? 0 : 2))}; llvm::NamedMDNode *SPIRVerMD = M.getOrInsertNamedMetadata("opencl.spir.version"); SPIRVerMD->addOperand(llvm::MDNode::get(Ctx, SPIRVerElts)); Index: test/CodeGenOpenCL/spir_version.cl === --- test/CodeGenOpenCL/spir_version.cl +++ test/CodeGenOpenCL/spir_version.cl @@ -13,12 +13,12 @@ // CHECK-SPIR-CL10: !opencl.spir.version = !{[[SPIR:![0-9]+]]} // CHECK-SPIR-CL10: !opencl.ocl.version = !{[[OCL:![0-9]+]]} -// CHECK-SPIR-CL10: [[SPIR]] = !{i32 2, i32 0} +// CHECK-SPIR-CL10: [[SPIR]] = !{i32 1, i32 2} // CHECK-SPIR-CL10: [[OCL]] = !{i32 1, i32 0} // CHECK-SPIR-CL12: !opencl.spir.version = !{[[SPIR:![0-9]+]]} // CHECK-SPIR-CL12: !opencl.ocl.version = !{[[OCL:![0-9]+]]} -// CHECK-SPIR-CL12: [[SPIR]] = !{i32 2, i32 0} -// CHECK-SPIR-CL12: [[OCL]] = !{i32 1, i32 2} +// CHECK-SPIR-CL12: [[SPIR]] = !{i32 1, i32 2} + // CHECK-SPIR-CL20: !opencl.spir.version = !{[[SPIR:![0-9]+]]} // CHECK-SPIR-CL20: !opencl.ocl.version = !{[[SPIR:![0-9]+]]} // CHECK-SPIR-CL20: [[SPIR]] = !{i32 2, i32 0} @@ -28,4 +28,4 @@ // CHECK-AMDGCN-CL12: !opencl.ocl.version = !{[[OCL:![0-9]+]]} // CHECK-AMDGCN-CL12: [[OCL]] = !{i32 1, i32 2} // CHECK-AMDGCN-CL20: !opencl.ocl.version = !{[[OCL:![0-9]+]]} -// CHECK-AMDGCN-CL20: [[OCL]] = !{i32 2, i32 0} \ No newline at end of file +// CHECK-AMDGCN-CL20: [[OCL]] = !{i32 2, i32 0} Index: lib/CodeGen/TargetInfo.cpp === --- lib/CodeGen/TargetInfo.cpp +++ lib/CodeGen/TargetInfo.cpp @@ -7778,8 +7778,10 @@ // SPIR v2.0 s2.12 - The SPIR version used by the module is stored in the // opencl.spir.version named metadata. llvm::Metadata *SPIRVerElts[] = { - llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(Int32Ty, 2)), - llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(Int32Ty, 0))}; + llvm::ConstantAsMetadata::get( + llvm::ConstantInt::get(Int32Ty, CGM.getLangOpts().OpenCLVersion / 100)), + llvm::ConstantAsMetadata::get(llvm::ConstantInt::get( + Int32Ty, (CGM.getLangOpts().OpenCLVersion / 100 > 1) ? 0 : 2))}; llvm::NamedMDNode *SPIRVerMD = M.getOrInsertNamedMetadata("opencl.spir.version"); SPIRVerMD->addOperand(llvm::MDNode::get(Ctx, SPIRVerElts)); ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D27300: [OpenCL] Fix SPIR version generation.
echuraev added inline comments. Comment at: test/CodeGenOpenCL/spir_version.cl:21 -// CHECK-SPIR-CL12: [[SPIR]] = !{i32 2, i32 0} -// CHECK-SPIR-CL12: [[OCL]] = !{i32 1, i32 2} // CHECK-SPIR-CL20: !opencl.spir.version = !{[[SPIR:![0-9]+]]} yaxunl wrote: > why this is removed? After my changes, value of SPIR version and OCL will be the same and so, it will be generate only one metadata (e.g. !1 = !{i32 1, i32 2}). The same situation is for checking CL20 below. https://reviews.llvm.org/D27300 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D27300: [OpenCL] Fix SPIR version generation.
echuraev updated this revision to Diff 80034. echuraev marked 3 inline comments as done. https://reviews.llvm.org/D27300 Files: lib/CodeGen/TargetInfo.cpp test/CodeGenOpenCL/spir_version.cl Index: test/CodeGenOpenCL/spir_version.cl === --- test/CodeGenOpenCL/spir_version.cl +++ test/CodeGenOpenCL/spir_version.cl @@ -13,12 +13,12 @@ // CHECK-SPIR-CL10: !opencl.spir.version = !{[[SPIR:![0-9]+]]} // CHECK-SPIR-CL10: !opencl.ocl.version = !{[[OCL:![0-9]+]]} -// CHECK-SPIR-CL10: [[SPIR]] = !{i32 2, i32 0} +// CHECK-SPIR-CL10: [[SPIR]] = !{i32 1, i32 2} // CHECK-SPIR-CL10: [[OCL]] = !{i32 1, i32 0} -// CHECK-SPIR-CL12: !opencl.spir.version = !{[[SPIR:![0-9]+]]} -// CHECK-SPIR-CL12: !opencl.ocl.version = !{[[OCL:![0-9]+]]} -// CHECK-SPIR-CL12: [[SPIR]] = !{i32 2, i32 0} -// CHECK-SPIR-CL12: [[OCL]] = !{i32 1, i32 2} +// CHECK-SPIR-CL12: !opencl.spir.version = !{[[VER:![0-9]+]]} +// CHECK-SPIR-CL12: !opencl.ocl.version = !{[[VER]]} +// CHECK-SPIR-CL12: [[VER]] = !{i32 1, i32 2} + // CHECK-SPIR-CL20: !opencl.spir.version = !{[[SPIR:![0-9]+]]} // CHECK-SPIR-CL20: !opencl.ocl.version = !{[[SPIR:![0-9]+]]} // CHECK-SPIR-CL20: [[SPIR]] = !{i32 2, i32 0} @@ -28,4 +28,4 @@ // CHECK-AMDGCN-CL12: !opencl.ocl.version = !{[[OCL:![0-9]+]]} // CHECK-AMDGCN-CL12: [[OCL]] = !{i32 1, i32 2} // CHECK-AMDGCN-CL20: !opencl.ocl.version = !{[[OCL:![0-9]+]]} -// CHECK-AMDGCN-CL20: [[OCL]] = !{i32 2, i32 0} \ No newline at end of file +// CHECK-AMDGCN-CL20: [[OCL]] = !{i32 2, i32 0} Index: lib/CodeGen/TargetInfo.cpp === --- lib/CodeGen/TargetInfo.cpp +++ lib/CodeGen/TargetInfo.cpp @@ -7778,8 +7778,10 @@ // SPIR v2.0 s2.12 - The SPIR version used by the module is stored in the // opencl.spir.version named metadata. llvm::Metadata *SPIRVerElts[] = { - llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(Int32Ty, 2)), - llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(Int32Ty, 0))}; + llvm::ConstantAsMetadata::get( + llvm::ConstantInt::get(Int32Ty, CGM.getLangOpts().OpenCLVersion / 100)), + llvm::ConstantAsMetadata::get(llvm::ConstantInt::get( + Int32Ty, (CGM.getLangOpts().OpenCLVersion / 100 > 1) ? 0 : 2))}; llvm::NamedMDNode *SPIRVerMD = M.getOrInsertNamedMetadata("opencl.spir.version"); SPIRVerMD->addOperand(llvm::MDNode::get(Ctx, SPIRVerElts)); Index: test/CodeGenOpenCL/spir_version.cl === --- test/CodeGenOpenCL/spir_version.cl +++ test/CodeGenOpenCL/spir_version.cl @@ -13,12 +13,12 @@ // CHECK-SPIR-CL10: !opencl.spir.version = !{[[SPIR:![0-9]+]]} // CHECK-SPIR-CL10: !opencl.ocl.version = !{[[OCL:![0-9]+]]} -// CHECK-SPIR-CL10: [[SPIR]] = !{i32 2, i32 0} +// CHECK-SPIR-CL10: [[SPIR]] = !{i32 1, i32 2} // CHECK-SPIR-CL10: [[OCL]] = !{i32 1, i32 0} -// CHECK-SPIR-CL12: !opencl.spir.version = !{[[SPIR:![0-9]+]]} -// CHECK-SPIR-CL12: !opencl.ocl.version = !{[[OCL:![0-9]+]]} -// CHECK-SPIR-CL12: [[SPIR]] = !{i32 2, i32 0} -// CHECK-SPIR-CL12: [[OCL]] = !{i32 1, i32 2} +// CHECK-SPIR-CL12: !opencl.spir.version = !{[[VER:![0-9]+]]} +// CHECK-SPIR-CL12: !opencl.ocl.version = !{[[VER]]} +// CHECK-SPIR-CL12: [[VER]] = !{i32 1, i32 2} + // CHECK-SPIR-CL20: !opencl.spir.version = !{[[SPIR:![0-9]+]]} // CHECK-SPIR-CL20: !opencl.ocl.version = !{[[SPIR:![0-9]+]]} // CHECK-SPIR-CL20: [[SPIR]] = !{i32 2, i32 0} @@ -28,4 +28,4 @@ // CHECK-AMDGCN-CL12: !opencl.ocl.version = !{[[OCL:![0-9]+]]} // CHECK-AMDGCN-CL12: [[OCL]] = !{i32 1, i32 2} // CHECK-AMDGCN-CL20: !opencl.ocl.version = !{[[OCL:![0-9]+]]} -// CHECK-AMDGCN-CL20: [[OCL]] = !{i32 2, i32 0} \ No newline at end of file +// CHECK-AMDGCN-CL20: [[OCL]] = !{i32 2, i32 0} Index: lib/CodeGen/TargetInfo.cpp === --- lib/CodeGen/TargetInfo.cpp +++ lib/CodeGen/TargetInfo.cpp @@ -7778,8 +7778,10 @@ // SPIR v2.0 s2.12 - The SPIR version used by the module is stored in the // opencl.spir.version named metadata. llvm::Metadata *SPIRVerElts[] = { - llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(Int32Ty, 2)), - llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(Int32Ty, 0))}; + llvm::ConstantAsMetadata::get( + llvm::ConstantInt::get(Int32Ty, CGM.getLangOpts().OpenCLVersion / 100)), + llvm::ConstantAsMetadata::get(llvm::ConstantInt::get( + Int32Ty, (CGM.getLangOpts().OpenCLVersion / 100 > 1) ? 0 : 2))}; llvm::NamedMDNode *SPIRVerMD = M.getOrInsertNamedMetadata("opencl.spir.version"); SPIRVerMD->addOperand(llvm::MDNode::get(Ctx, SPIRVerElts)); ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D27334: [OpenCL] Ambiguous function call.
echuraev created this revision. echuraev added a reviewer: Anastasia. echuraev added subscribers: bader, cfe-commits, yaxunl. Added warning about potential ambiguity error with built-in overloading. Patch by Alexey Bader https://reviews.llvm.org/D27334 Files: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaChecking.cpp test/SemaOpenCL/warn-potential-abiguity.cl Index: test/SemaOpenCL/warn-potential-abiguity.cl === --- /dev/null +++ test/SemaOpenCL/warn-potential-abiguity.cl @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -pedantic -Wconversion-might-lead-to-ambiguity %s + +float __attribute__((overloadable)) ocl_builtin_func(float f) { return f; } +float __attribute__((overloadable)) ocl_builtin_func_2args(float arg1, float arg2) { return arg1 + arg2; } + +__kernel void test() { + int p = ocl_builtin_func(3); // expected-warning {{implicit conversion from integral type to floating point type for overloadable function might lead to ambiguity}} + int q = ocl_builtin_func_2args(3.f, 3); // expected-warning {{implicit conversion from integral type to floating point type for overloadable function might lead to ambiguity}} +} Index: lib/Sema/SemaChecking.cpp === --- lib/Sema/SemaChecking.cpp +++ lib/Sema/SemaChecking.cpp @@ -2472,6 +2472,19 @@ if (FDecl) { for (const auto *I : FDecl->specific_attrs()) CheckArgumentWithTypeTag(I, Args.data()); + + if (getLangOpts().OpenCL) { +// Check if overloadble built-in function with floating point arguments takes +// integer values. +if (FDecl->hasAttr()) { + for (const auto* Arg : Args) { +const ImplicitCastExpr *ICE = dyn_cast(Arg); +if (!ICE || ICE->getCastKind() != CK_IntegralToFloating) + continue; +Diag(Loc, diag::warn_ocl_bultin_potential_ambiguity) << Range; + } +} + } } } } Index: include/clang/Basic/DiagnosticSemaKinds.td === --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -8099,6 +8099,10 @@ "missing actual type specifier for pipe">; def err_reference_pipe_type : Error < "pipes packet types cannot be of reference type">; +def warn_ocl_bultin_potential_ambiguity : Warning< +"implicit conversion from integral type to floating point type for" +" overloadable function might lead to ambiguity">, + InGroup>, DefaultIgnore; def err_opencl_no_main : Error<"%select{function|kernel}0 cannot be called 'main'">; def err_opencl_kernel_attr : Error<"attribute %0 can only be applied to a kernel function">; Index: test/SemaOpenCL/warn-potential-abiguity.cl === --- /dev/null +++ test/SemaOpenCL/warn-potential-abiguity.cl @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -pedantic -Wconversion-might-lead-to-ambiguity %s + +float __attribute__((overloadable)) ocl_builtin_func(float f) { return f; } +float __attribute__((overloadable)) ocl_builtin_func_2args(float arg1, float arg2) { return arg1 + arg2; } + +__kernel void test() { + int p = ocl_builtin_func(3); // expected-warning {{implicit conversion from integral type to floating point type for overloadable function might lead to ambiguity}} + int q = ocl_builtin_func_2args(3.f, 3); // expected-warning {{implicit conversion from integral type to floating point type for overloadable function might lead to ambiguity}} +} Index: lib/Sema/SemaChecking.cpp === --- lib/Sema/SemaChecking.cpp +++ lib/Sema/SemaChecking.cpp @@ -2472,6 +2472,19 @@ if (FDecl) { for (const auto *I : FDecl->specific_attrs()) CheckArgumentWithTypeTag(I, Args.data()); + + if (getLangOpts().OpenCL) { +// Check if overloadble built-in function with floating point arguments takes +// integer values. +if (FDecl->hasAttr()) { + for (const auto* Arg : Args) { +const ImplicitCastExpr *ICE = dyn_cast(Arg); +if (!ICE || ICE->getCastKind() != CK_IntegralToFloating) + continue; +Diag(Loc, diag::warn_ocl_bultin_potential_ambiguity) << Range; + } +} + } } } } Index: include/clang/Basic/DiagnosticSemaKinds.td === --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -8099,6 +8099,10 @@ "missing actual type specifier for pipe">; def err_reference_pipe_type : Error < "pipes packet types cannot be of reference type">; +def warn_ocl_bultin_potential_ambiguity : Warning< +"implicit conversion from integral type to floating point type for" +" overloadable
[PATCH] D27300: [OpenCL] Fix SPIR version generation.
echuraev updated this revision to Diff 80229. echuraev marked 2 inline comments as done. https://reviews.llvm.org/D27300 Files: lib/CodeGen/TargetInfo.cpp test/CodeGenOpenCL/spir_version.cl Index: test/CodeGenOpenCL/spir_version.cl === --- test/CodeGenOpenCL/spir_version.cl +++ test/CodeGenOpenCL/spir_version.cl @@ -13,19 +13,22 @@ // CHECK-SPIR-CL10: !opencl.spir.version = !{[[SPIR:![0-9]+]]} // CHECK-SPIR-CL10: !opencl.ocl.version = !{[[OCL:![0-9]+]]} -// CHECK-SPIR-CL10: [[SPIR]] = !{i32 2, i32 0} +// CHECK-SPIR-CL10: [[SPIR]] = !{i32 1, i32 2} // CHECK-SPIR-CL10: [[OCL]] = !{i32 1, i32 0} -// CHECK-SPIR-CL12: !opencl.spir.version = !{[[SPIR:![0-9]+]]} -// CHECK-SPIR-CL12: !opencl.ocl.version = !{[[OCL:![0-9]+]]} -// CHECK-SPIR-CL12: [[SPIR]] = !{i32 2, i32 0} -// CHECK-SPIR-CL12: [[OCL]] = !{i32 1, i32 2} -// CHECK-SPIR-CL20: !opencl.spir.version = !{[[SPIR:![0-9]+]]} -// CHECK-SPIR-CL20: !opencl.ocl.version = !{[[SPIR:![0-9]+]]} -// CHECK-SPIR-CL20: [[SPIR]] = !{i32 2, i32 0} +// CHECK-SPIR-CL12: !opencl.spir.version = !{[[VER:![0-9]+]]} +// CHECK-SPIR-CL12: !opencl.ocl.version = !{[[VER]]} +// CHECK-SPIR-CL12: [[VER]] = !{i32 1, i32 2} +// CHECK-SPIR-CL20: !opencl.spir.version = !{[[VER:![0-9]+]]} +// CHECK-SPIR-CL20: !opencl.ocl.version = !{[[VER]]} +// CHECK-SPIR-CL20: [[VER]] = !{i32 2, i32 0} + +// CHECK-AMDGCN-CL10-NOT: !opencl.spir.version // CHECK-AMDGCN-CL10: !opencl.ocl.version = !{[[OCL:![0-9]+]]} // CHECK-AMDGCN-CL10: [[OCL]] = !{i32 1, i32 0} +// CHECK-AMDGCN-CL12-NOT: !opencl.spir.version // CHECK-AMDGCN-CL12: !opencl.ocl.version = !{[[OCL:![0-9]+]]} // CHECK-AMDGCN-CL12: [[OCL]] = !{i32 1, i32 2} +// CHECK-AMDGCN-CL20-NOT: !opencl.spir.version // CHECK-AMDGCN-CL20: !opencl.ocl.version = !{[[OCL:![0-9]+]]} -// CHECK-AMDGCN-CL20: [[OCL]] = !{i32 2, i32 0} \ No newline at end of file +// CHECK-AMDGCN-CL20: [[OCL]] = !{i32 2, i32 0} Index: lib/CodeGen/TargetInfo.cpp === --- lib/CodeGen/TargetInfo.cpp +++ lib/CodeGen/TargetInfo.cpp @@ -7778,8 +7778,10 @@ // SPIR v2.0 s2.12 - The SPIR version used by the module is stored in the // opencl.spir.version named metadata. llvm::Metadata *SPIRVerElts[] = { - llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(Int32Ty, 2)), - llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(Int32Ty, 0))}; + llvm::ConstantAsMetadata::get( + llvm::ConstantInt::get(Int32Ty, CGM.getLangOpts().OpenCLVersion / 100)), + llvm::ConstantAsMetadata::get(llvm::ConstantInt::get( + Int32Ty, (CGM.getLangOpts().OpenCLVersion / 100 > 1) ? 0 : 2))}; llvm::NamedMDNode *SPIRVerMD = M.getOrInsertNamedMetadata("opencl.spir.version"); SPIRVerMD->addOperand(llvm::MDNode::get(Ctx, SPIRVerElts)); Index: test/CodeGenOpenCL/spir_version.cl === --- test/CodeGenOpenCL/spir_version.cl +++ test/CodeGenOpenCL/spir_version.cl @@ -13,19 +13,22 @@ // CHECK-SPIR-CL10: !opencl.spir.version = !{[[SPIR:![0-9]+]]} // CHECK-SPIR-CL10: !opencl.ocl.version = !{[[OCL:![0-9]+]]} -// CHECK-SPIR-CL10: [[SPIR]] = !{i32 2, i32 0} +// CHECK-SPIR-CL10: [[SPIR]] = !{i32 1, i32 2} // CHECK-SPIR-CL10: [[OCL]] = !{i32 1, i32 0} -// CHECK-SPIR-CL12: !opencl.spir.version = !{[[SPIR:![0-9]+]]} -// CHECK-SPIR-CL12: !opencl.ocl.version = !{[[OCL:![0-9]+]]} -// CHECK-SPIR-CL12: [[SPIR]] = !{i32 2, i32 0} -// CHECK-SPIR-CL12: [[OCL]] = !{i32 1, i32 2} -// CHECK-SPIR-CL20: !opencl.spir.version = !{[[SPIR:![0-9]+]]} -// CHECK-SPIR-CL20: !opencl.ocl.version = !{[[SPIR:![0-9]+]]} -// CHECK-SPIR-CL20: [[SPIR]] = !{i32 2, i32 0} +// CHECK-SPIR-CL12: !opencl.spir.version = !{[[VER:![0-9]+]]} +// CHECK-SPIR-CL12: !opencl.ocl.version = !{[[VER]]} +// CHECK-SPIR-CL12: [[VER]] = !{i32 1, i32 2} +// CHECK-SPIR-CL20: !opencl.spir.version = !{[[VER:![0-9]+]]} +// CHECK-SPIR-CL20: !opencl.ocl.version = !{[[VER]]} +// CHECK-SPIR-CL20: [[VER]] = !{i32 2, i32 0} + +// CHECK-AMDGCN-CL10-NOT: !opencl.spir.version // CHECK-AMDGCN-CL10: !opencl.ocl.version = !{[[OCL:![0-9]+]]} // CHECK-AMDGCN-CL10: [[OCL]] = !{i32 1, i32 0} +// CHECK-AMDGCN-CL12-NOT: !opencl.spir.version // CHECK-AMDGCN-CL12: !opencl.ocl.version = !{[[OCL:![0-9]+]]} // CHECK-AMDGCN-CL12: [[OCL]] = !{i32 1, i32 2} +// CHECK-AMDGCN-CL20-NOT: !opencl.spir.version // CHECK-AMDGCN-CL20: !opencl.ocl.version = !{[[OCL:![0-9]+]]} -// CHECK-AMDGCN-CL20: [[OCL]] = !{i32 2, i32 0} \ No newline at end of file +// CHECK-AMDGCN-CL20: [[OCL]] = !{i32 2, i32 0} Index: lib/CodeGen/TargetInfo.cpp === --- lib/CodeGen/TargetInfo.cpp +++ lib/CodeGen/TargetInfo.cpp @@ -7778,8 +7778,10 @@ // SPIR v2.0 s2.12 - The SPIR version used by the module is stored in the // opencl.spir.version named metadata. llvm::Metadata *SPIRVerElts[] = { - llvm::Co
[PATCH] D27403: [OpenCL] Added a LIT test for ensuring address space mangling is done the same both in OpenCL1.2 and OpenCL2.0.
echuraev created this revision. echuraev added a reviewer: Anastasia. echuraev added subscribers: bader, cfe-commits, yaxunl. https://reviews.llvm.org/D27403 Files: test/CodeGenOpenCL/address-spaces-mangling.cl Index: test/CodeGenOpenCL/address-spaces-mangling.cl === --- test/CodeGenOpenCL/address-spaces-mangling.cl +++ test/CodeGenOpenCL/address-spaces-mangling.cl @@ -1,6 +1,10 @@ // RUN: %clang_cc1 %s -ffake-address-space-map -faddress-space-map-mangling=yes -triple %itanium_abi_triple -emit-llvm -o - | FileCheck -check-prefix=ASMANG %s // RUN: %clang_cc1 %s -ffake-address-space-map -faddress-space-map-mangling=no -triple %itanium_abi_triple -emit-llvm -o - | FileCheck -check-prefix=NOASMANG %s +// We check that the address spaces are mangled the same in both version of OpenCL +// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=CL2.0 -emit-llvm -o - | FileCheck -check-prefix=OCL %s +// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=CL1.2 -emit-llvm -o - | FileCheck -check-prefix=OCL %s + // We can't name this f as private is equivalent to default // no specifier given address space so we get multiple definition // warnings, but we do want it for comparison purposes. @@ -28,3 +32,20 @@ void f(constant int *arg) { } // ASMANG: @_Z1fPU3AS3i // NOASMANG: @_Z1fPU10CLconstanti + +__attribute__((overloadable)) void foo(private char *); +__attribute__((overloadable)) void foo(global char *); +__attribute__((overloadable)) void foo(constant char *); +__attribute__((overloadable)) void foo(local char *); + +void bar(global char *gp, constant char *cp, local char *lp) { + private char* pp; + // OCL: call spir_func void @_Z3fooPc + foo(pp); + // OCL: call spir_func void @_Z3fooPU3AS1c + foo(gp); + // OCL: call spir_func void @_Z3fooPU3AS2c + foo(cp); + // OCL: call spir_func void @_Z3fooPU3AS3c + foo(lp); +} Index: test/CodeGenOpenCL/address-spaces-mangling.cl === --- test/CodeGenOpenCL/address-spaces-mangling.cl +++ test/CodeGenOpenCL/address-spaces-mangling.cl @@ -1,6 +1,10 @@ // RUN: %clang_cc1 %s -ffake-address-space-map -faddress-space-map-mangling=yes -triple %itanium_abi_triple -emit-llvm -o - | FileCheck -check-prefix=ASMANG %s // RUN: %clang_cc1 %s -ffake-address-space-map -faddress-space-map-mangling=no -triple %itanium_abi_triple -emit-llvm -o - | FileCheck -check-prefix=NOASMANG %s +// We check that the address spaces are mangled the same in both version of OpenCL +// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=CL2.0 -emit-llvm -o - | FileCheck -check-prefix=OCL %s +// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=CL1.2 -emit-llvm -o - | FileCheck -check-prefix=OCL %s + // We can't name this f as private is equivalent to default // no specifier given address space so we get multiple definition // warnings, but we do want it for comparison purposes. @@ -28,3 +32,20 @@ void f(constant int *arg) { } // ASMANG: @_Z1fPU3AS3i // NOASMANG: @_Z1fPU10CLconstanti + +__attribute__((overloadable)) void foo(private char *); +__attribute__((overloadable)) void foo(global char *); +__attribute__((overloadable)) void foo(constant char *); +__attribute__((overloadable)) void foo(local char *); + +void bar(global char *gp, constant char *cp, local char *lp) { + private char* pp; + // OCL: call spir_func void @_Z3fooPc + foo(pp); + // OCL: call spir_func void @_Z3fooPU3AS1c + foo(gp); + // OCL: call spir_func void @_Z3fooPU3AS2c + foo(cp); + // OCL: call spir_func void @_Z3fooPU3AS3c + foo(lp); +} ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D27403: [OpenCL] Added a LIT test for ensuring address space mangling is done the same both in OpenCL1.2 and OpenCL2.0.
echuraev updated this revision to Diff 80401. echuraev marked an inline comment as done. https://reviews.llvm.org/D27403 Files: test/CodeGenOpenCL/address-spaces-mangling.cl Index: test/CodeGenOpenCL/address-spaces-mangling.cl === --- test/CodeGenOpenCL/address-spaces-mangling.cl +++ test/CodeGenOpenCL/address-spaces-mangling.cl @@ -1,30 +1,44 @@ // RUN: %clang_cc1 %s -ffake-address-space-map -faddress-space-map-mangling=yes -triple %itanium_abi_triple -emit-llvm -o - | FileCheck -check-prefix=ASMANG %s // RUN: %clang_cc1 %s -ffake-address-space-map -faddress-space-map-mangling=no -triple %itanium_abi_triple -emit-llvm -o - | FileCheck -check-prefix=NOASMANG %s +// We check that the address spaces are mangled the same in both version of OpenCL +// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=CL2.0 -emit-llvm -o - | FileCheck -check-prefix=OCL-20 %s +// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=CL1.2 -emit-llvm -o - | FileCheck -check-prefix=OCL-12 %s + // We can't name this f as private is equivalent to default // no specifier given address space so we get multiple definition // warnings, but we do want it for comparison purposes. __attribute__((overloadable)) void ff(int *arg) { } // ASMANG: @_Z2ffPi // NOASMANG: @_Z2ffPi +// OCL-20-DAG: @_Z2ffPU3AS4i +// OCL-12-DAG: @_Z2ffPi __attribute__((overloadable)) void f(private int *arg) { } // ASMANG: @_Z1fPi // NOASMANG: @_Z1fPi +// OCL-20-DAG: @_Z1fPi +// OCL-12-DAG: @_Z1fPi __attribute__((overloadable)) void f(global int *arg) { } // ASMANG: @_Z1fPU3AS1i // NOASMANG: @_Z1fPU8CLglobali +// OCL-20-DAG: @_Z1fPU3AS1i +// OCL-12-DAG: @_Z1fPU3AS1i __attribute__((overloadable)) void f(local int *arg) { } // ASMANG: @_Z1fPU3AS2i // NOASMANG: @_Z1fPU7CLlocali +// OCL-20-DAG: @_Z1fPU3AS2i +// OCL-12-DAG: @_Z1fPU3AS2i __attribute__((overloadable)) void f(constant int *arg) { } // ASMANG: @_Z1fPU3AS3i // NOASMANG: @_Z1fPU10CLconstanti +// OCL-20-DAG: @_Z1fPU3AS3i +// OCL-12-DAG: @_Z1fPU3AS3i Index: test/CodeGenOpenCL/address-spaces-mangling.cl === --- test/CodeGenOpenCL/address-spaces-mangling.cl +++ test/CodeGenOpenCL/address-spaces-mangling.cl @@ -1,30 +1,44 @@ // RUN: %clang_cc1 %s -ffake-address-space-map -faddress-space-map-mangling=yes -triple %itanium_abi_triple -emit-llvm -o - | FileCheck -check-prefix=ASMANG %s // RUN: %clang_cc1 %s -ffake-address-space-map -faddress-space-map-mangling=no -triple %itanium_abi_triple -emit-llvm -o - | FileCheck -check-prefix=NOASMANG %s +// We check that the address spaces are mangled the same in both version of OpenCL +// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=CL2.0 -emit-llvm -o - | FileCheck -check-prefix=OCL-20 %s +// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=CL1.2 -emit-llvm -o - | FileCheck -check-prefix=OCL-12 %s + // We can't name this f as private is equivalent to default // no specifier given address space so we get multiple definition // warnings, but we do want it for comparison purposes. __attribute__((overloadable)) void ff(int *arg) { } // ASMANG: @_Z2ffPi // NOASMANG: @_Z2ffPi +// OCL-20-DAG: @_Z2ffPU3AS4i +// OCL-12-DAG: @_Z2ffPi __attribute__((overloadable)) void f(private int *arg) { } // ASMANG: @_Z1fPi // NOASMANG: @_Z1fPi +// OCL-20-DAG: @_Z1fPi +// OCL-12-DAG: @_Z1fPi __attribute__((overloadable)) void f(global int *arg) { } // ASMANG: @_Z1fPU3AS1i // NOASMANG: @_Z1fPU8CLglobali +// OCL-20-DAG: @_Z1fPU3AS1i +// OCL-12-DAG: @_Z1fPU3AS1i __attribute__((overloadable)) void f(local int *arg) { } // ASMANG: @_Z1fPU3AS2i // NOASMANG: @_Z1fPU7CLlocali +// OCL-20-DAG: @_Z1fPU3AS2i +// OCL-12-DAG: @_Z1fPU3AS2i __attribute__((overloadable)) void f(constant int *arg) { } // ASMANG: @_Z1fPU3AS3i // NOASMANG: @_Z1fPU10CLconstanti +// OCL-20-DAG: @_Z1fPU3AS3i +// OCL-12-DAG: @_Z1fPU3AS3i ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D27453: [OpenCL] Enable unroll hint for OpenCL 1.x.
echuraev created this revision. echuraev added a reviewer: Anastasia. echuraev added subscribers: bader, cfe-commits, yaxunl. Although the feature was introduced only in OpenCL C v2.0 spec., it's useful for OpenCL 1.x too and doesn't require HW support. https://reviews.llvm.org/D27453 Files: lib/Sema/SemaStmtAttr.cpp test/CodeGenOpenCL/unroll-hint.cl test/SemaOpenCL/unroll-hint.cl Index: test/SemaOpenCL/unroll-hint.cl === --- test/SemaOpenCL/unroll-hint.cl +++ test/SemaOpenCL/unroll-hint.cl @@ -1,17 +1,5 @@ -//RUN: %clang_cc1 -O0 -fsyntax-only -verify %s -//RUN: %clang_cc1 -O0 -cl-std=CL2.0 -fsyntax-only -verify -DCL20 %s +//RUN: %clang_cc1 -O0 -cl-std=CL2.0 -fsyntax-only -verify %s -kernel void D (global int *x) { - int i = 10; -#ifndef CL20 - // expected-error@+2 {{'opencl_unroll_hint' attribute requires OpenCL version 2.0 or above}} -#endif - __attribute__((opencl_unroll_hint)) - do { - } while(i--); -} - -#ifdef CL20 kernel void C (global int *x) { int I = 3; __attribute__((opencl_unroll_hint(I))) // expected-error {{'opencl_unroll_hint' attribute requires an integer constant}} @@ -27,4 +15,3 @@ __attribute__((opencl_unroll_hint(-1))) // expected-error {{'opencl_unroll_hint' attribute requires a positive integral compile time constant expression}} for(int i=0; i<100; i++); } -#endif Index: test/CodeGenOpenCL/unroll-hint.cl === --- test/CodeGenOpenCL/unroll-hint.cl +++ test/CodeGenOpenCL/unroll-hint.cl @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -emit-llvm -O0 -cl-std=CL2.0 -o - %s | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -O0 -cl-std=CL1.2 -o - %s | FileCheck %s /*** for ***/ void for_count() Index: lib/Sema/SemaStmtAttr.cpp === --- lib/Sema/SemaStmtAttr.cpp +++ lib/Sema/SemaStmtAttr.cpp @@ -229,12 +229,6 @@ // determines unrolling factor) or 1 argument (the unroll factor provided // by the user). - if (S.getLangOpts().OpenCLVersion < 200) { -S.Diag(A.getLoc(), diag::err_attribute_requires_opencl_version) -<< A.getName() << "2.0" << 1; -return nullptr; - } - unsigned NumArgs = A.getNumArgs(); if (NumArgs > 1) { Index: test/SemaOpenCL/unroll-hint.cl === --- test/SemaOpenCL/unroll-hint.cl +++ test/SemaOpenCL/unroll-hint.cl @@ -1,17 +1,5 @@ -//RUN: %clang_cc1 -O0 -fsyntax-only -verify %s -//RUN: %clang_cc1 -O0 -cl-std=CL2.0 -fsyntax-only -verify -DCL20 %s +//RUN: %clang_cc1 -O0 -cl-std=CL2.0 -fsyntax-only -verify %s -kernel void D (global int *x) { - int i = 10; -#ifndef CL20 - // expected-error@+2 {{'opencl_unroll_hint' attribute requires OpenCL version 2.0 or above}} -#endif - __attribute__((opencl_unroll_hint)) - do { - } while(i--); -} - -#ifdef CL20 kernel void C (global int *x) { int I = 3; __attribute__((opencl_unroll_hint(I))) // expected-error {{'opencl_unroll_hint' attribute requires an integer constant}} @@ -27,4 +15,3 @@ __attribute__((opencl_unroll_hint(-1))) // expected-error {{'opencl_unroll_hint' attribute requires a positive integral compile time constant expression}} for(int i=0; i<100; i++); } -#endif Index: test/CodeGenOpenCL/unroll-hint.cl === --- test/CodeGenOpenCL/unroll-hint.cl +++ test/CodeGenOpenCL/unroll-hint.cl @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -emit-llvm -O0 -cl-std=CL2.0 -o - %s | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -O0 -cl-std=CL1.2 -o - %s | FileCheck %s /*** for ***/ void for_count() Index: lib/Sema/SemaStmtAttr.cpp === --- lib/Sema/SemaStmtAttr.cpp +++ lib/Sema/SemaStmtAttr.cpp @@ -229,12 +229,6 @@ // determines unrolling factor) or 1 argument (the unroll factor provided // by the user). - if (S.getLangOpts().OpenCLVersion < 200) { -S.Diag(A.getLoc(), diag::err_attribute_requires_opencl_version) -<< A.getName() << "2.0" << 1; -return nullptr; - } - unsigned NumArgs = A.getNumArgs(); if (NumArgs > 1) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D27453: [OpenCL] Enable unroll hint for OpenCL 1.x.
echuraev updated this revision to Diff 80547. echuraev marked an inline comment as done. https://reviews.llvm.org/D27453 Files: lib/Sema/SemaStmtAttr.cpp test/CodeGenOpenCL/unroll-hint.cl test/SemaOpenCL/unroll-hint.cl Index: test/SemaOpenCL/unroll-hint.cl === --- test/SemaOpenCL/unroll-hint.cl +++ test/SemaOpenCL/unroll-hint.cl @@ -1,17 +1,5 @@ -//RUN: %clang_cc1 -O0 -fsyntax-only -verify %s -//RUN: %clang_cc1 -O0 -cl-std=CL2.0 -fsyntax-only -verify -DCL20 %s +//RUN: %clang_cc1 -O0 -cl-std=CL2.0 -fsyntax-only -verify %s -kernel void D (global int *x) { - int i = 10; -#ifndef CL20 - // expected-error@+2 {{'opencl_unroll_hint' attribute requires OpenCL version 2.0 or above}} -#endif - __attribute__((opencl_unroll_hint)) - do { - } while(i--); -} - -#ifdef CL20 kernel void C (global int *x) { int I = 3; __attribute__((opencl_unroll_hint(I))) // expected-error {{'opencl_unroll_hint' attribute requires an integer constant}} @@ -27,4 +15,3 @@ __attribute__((opencl_unroll_hint(-1))) // expected-error {{'opencl_unroll_hint' attribute requires a positive integral compile time constant expression}} for(int i=0; i<100; i++); } -#endif Index: test/CodeGenOpenCL/unroll-hint.cl === --- test/CodeGenOpenCL/unroll-hint.cl +++ test/CodeGenOpenCL/unroll-hint.cl @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -emit-llvm -O0 -cl-std=CL2.0 -o - %s | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -O0 -cl-std=CL1.2 -o - %s | FileCheck %s /*** for ***/ void for_count() Index: lib/Sema/SemaStmtAttr.cpp === --- lib/Sema/SemaStmtAttr.cpp +++ lib/Sema/SemaStmtAttr.cpp @@ -225,16 +225,12 @@ static Attr *handleOpenCLUnrollHint(Sema &S, Stmt *St, const AttributeList &A, SourceRange Range) { - // OpenCL v2.0 s6.11.5 - opencl_unroll_hint can have 0 arguments (compiler + // Although the feature was introduced only in OpenCL C v2.0 s6.11.5, it's + // useful for OpenCL 1.x too and doesn't require HW support. + // opencl_unroll_hint can have 0 arguments (compiler // determines unrolling factor) or 1 argument (the unroll factor provided // by the user). - if (S.getLangOpts().OpenCLVersion < 200) { -S.Diag(A.getLoc(), diag::err_attribute_requires_opencl_version) -<< A.getName() << "2.0" << 1; -return nullptr; - } - unsigned NumArgs = A.getNumArgs(); if (NumArgs > 1) { Index: test/SemaOpenCL/unroll-hint.cl === --- test/SemaOpenCL/unroll-hint.cl +++ test/SemaOpenCL/unroll-hint.cl @@ -1,17 +1,5 @@ -//RUN: %clang_cc1 -O0 -fsyntax-only -verify %s -//RUN: %clang_cc1 -O0 -cl-std=CL2.0 -fsyntax-only -verify -DCL20 %s +//RUN: %clang_cc1 -O0 -cl-std=CL2.0 -fsyntax-only -verify %s -kernel void D (global int *x) { - int i = 10; -#ifndef CL20 - // expected-error@+2 {{'opencl_unroll_hint' attribute requires OpenCL version 2.0 or above}} -#endif - __attribute__((opencl_unroll_hint)) - do { - } while(i--); -} - -#ifdef CL20 kernel void C (global int *x) { int I = 3; __attribute__((opencl_unroll_hint(I))) // expected-error {{'opencl_unroll_hint' attribute requires an integer constant}} @@ -27,4 +15,3 @@ __attribute__((opencl_unroll_hint(-1))) // expected-error {{'opencl_unroll_hint' attribute requires a positive integral compile time constant expression}} for(int i=0; i<100; i++); } -#endif Index: test/CodeGenOpenCL/unroll-hint.cl === --- test/CodeGenOpenCL/unroll-hint.cl +++ test/CodeGenOpenCL/unroll-hint.cl @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -emit-llvm -O0 -cl-std=CL2.0 -o - %s | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -O0 -cl-std=CL1.2 -o - %s | FileCheck %s /*** for ***/ void for_count() Index: lib/Sema/SemaStmtAttr.cpp === --- lib/Sema/SemaStmtAttr.cpp +++ lib/Sema/SemaStmtAttr.cpp @@ -225,16 +225,12 @@ static Attr *handleOpenCLUnrollHint(Sema &S, Stmt *St, const AttributeList &A, SourceRange Range) { - // OpenCL v2.0 s6.11.5 - opencl_unroll_hint can have 0 arguments (compiler + // Although the feature was introduced only in OpenCL C v2.0 s6.11.5, it's + // useful for OpenCL 1.x too and doesn't require HW support. + // opencl_unroll_hint can have 0 arguments (compiler // determines unrolling factor) or 1 argument (the unroll factor provided // by the user). - if (S.getLangOpts().OpenCLVersion < 200) { -S.Diag(A.getLoc(), diag::err_attribute_requires_opencl_version) -<< A.getName() << "2.0" << 1; -return nullptr; - } - unsigned NumArgs = A.getNumArgs(); if (NumArgs > 1) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org ht
[PATCH] D27569: [OpenCL] Enabling the usage of CLK_NULL_QUEUE as compare operand.
echuraev created this revision. echuraev added a reviewer: Anastasia. echuraev added subscribers: bader, yaxunl, cfe-commits. Enabling the compression of CLK_NULL_QUEUE to variable of type queue_t. https://reviews.llvm.org/D27569 Files: lib/Sema/SemaExpr.cpp test/CodeGenOpenCL/null_queue.cl Index: test/CodeGenOpenCL/null_queue.cl === --- /dev/null +++ test/CodeGenOpenCL/null_queue.cl @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -O0 -cl-std=CL2.0 -emit-llvm %s -o - | FileCheck %s +extern queue_t get_default_queue(); + +#define CLK_NULL_QUEUE 0 + +bool f() { + return CLK_NULL_QUEUE == get_default_queue() && + get_default_queue() == CLK_NULL_QUEUE; + // CHECK: icmp eq %opencl.queue_t* null, %{{.*}} +} + Index: lib/Sema/SemaExpr.cpp === --- lib/Sema/SemaExpr.cpp +++ lib/Sema/SemaExpr.cpp @@ -9621,6 +9621,18 @@ return ResultTy; } + if (getLangOpts().OpenCL && getLangOpts().OpenCLVersion >= 200) { +if (LHSIsNull && RHSType->isQueueT()) { + LHS = ImpCastExprToType(LHS.get(), RHSType, CK_NullToPointer); + return ResultTy; +} + +if (LHSType->isQueueT() && RHSIsNull) { + RHS = ImpCastExprToType(RHS.get(), LHSType, CK_NullToPointer); + return ResultTy; +} + } + return InvalidOperands(Loc, LHS, RHS); } Index: test/CodeGenOpenCL/null_queue.cl === --- /dev/null +++ test/CodeGenOpenCL/null_queue.cl @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -O0 -cl-std=CL2.0 -emit-llvm %s -o - | FileCheck %s +extern queue_t get_default_queue(); + +#define CLK_NULL_QUEUE 0 + +bool f() { + return CLK_NULL_QUEUE == get_default_queue() && + get_default_queue() == CLK_NULL_QUEUE; + // CHECK: icmp eq %opencl.queue_t* null, %{{.*}} +} + Index: lib/Sema/SemaExpr.cpp === --- lib/Sema/SemaExpr.cpp +++ lib/Sema/SemaExpr.cpp @@ -9621,6 +9621,18 @@ return ResultTy; } + if (getLangOpts().OpenCL && getLangOpts().OpenCLVersion >= 200) { +if (LHSIsNull && RHSType->isQueueT()) { + LHS = ImpCastExprToType(LHS.get(), RHSType, CK_NullToPointer); + return ResultTy; +} + +if (LHSType->isQueueT() && RHSIsNull) { + RHS = ImpCastExprToType(RHS.get(), LHSType, CK_NullToPointer); + return ResultTy; +} + } + return InvalidOperands(Loc, LHS, RHS); } ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D27671: [OpenCL] Improve address space diagnostics.
echuraev created this revision. echuraev added a reviewer: Anastasia. echuraev added subscribers: cfe-commits, yaxunl, bader. https://reviews.llvm.org/D27671 Files: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaDecl.cpp test/SemaOpenCL/invalid-kernel.cl Index: test/SemaOpenCL/invalid-kernel.cl === --- test/SemaOpenCL/invalid-kernel.cl +++ test/SemaOpenCL/invalid-kernel.cl @@ -1,10 +1,11 @@ // RUN: %clang_cc1 -verify %s +// RUN: %clang_cc1 -cl-std=CL2.0 -verify %s -kernel void no_ptrptr(global int **i) { } // expected-error{{kernel parameter cannot be declared as a pointer to a pointer}} +kernel void no_ptrptr(global int * global *i) { } // expected-error{{kernel parameter cannot be declared as a pointer to a pointer}} -__kernel void no_privateptr(__private int *i) { } // expected-error {{kernel parameter cannot be declared as a pointer to the __private address space}} +__kernel void no_privateptr(__private int *i) { } // expected-error {{pointer arguments to kernel functions must reside in '__global', '__constant' or '__local' address space}} -__kernel void no_privatearray(__private int i[]) { } // expected-error {{kernel parameter cannot be declared as a pointer to the __private address space}} +__kernel void no_privatearray(__private int i[]) { } // expected-error {{pointer arguments to kernel functions must reside in '__global', '__constant' or '__local' address space}} kernel int bar() { // expected-error {{kernel must have void return type}} return 6; @@ -29,3 +30,6 @@ int* constant x(int* x) { // expected-error {{return value cannot be qualified with address space}} return x + 1; } + +__kernel void testKernel(int *ptr) { // expected-error {{pointer arguments to kernel functions must reside in '__global', '__constant' or '__local' address space}} +} Index: lib/Sema/SemaDecl.cpp === --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -7586,7 +7586,7 @@ ValidKernelParam, PtrPtrKernelParam, PtrKernelParam, - PrivatePtrKernelParam, + InvalidAddrSpacePtrKernelParam, InvalidKernelParam, RecordKernelParam }; @@ -7596,8 +7596,10 @@ QualType PointeeType = PT->getPointeeType(); if (PointeeType->isPointerType()) return PtrPtrKernelParam; -return PointeeType.getAddressSpace() == 0 ? PrivatePtrKernelParam - : PtrKernelParam; +if (PointeeType.getAddressSpace() == LangAS::opencl_generic || +PointeeType.getAddressSpace() == 0) + return InvalidAddrSpacePtrKernelParam; +return PtrKernelParam; } // TODO: Forbid the other integer types (size_t, ptrdiff_t...) when they can @@ -7645,11 +7647,12 @@ D.setInvalidType(); return; - case PrivatePtrKernelParam: -// OpenCL v1.2 s6.9.a: -// A kernel function argument cannot be declared as a -// pointer to the private address space. -S.Diag(Param->getLocation(), diag::err_opencl_private_ptr_kernel_param); + case InvalidAddrSpacePtrKernelParam: +// OpenCL v1.0 s6.5: +// __kernel function arguments declared to be a pointer of a type can point +// to one of the following address spaces only : __global, __local or +// __constant. +S.Diag(Param->getLocation(), diag::err_kernel_arg_address_space); D.setInvalidType(); return; @@ -7736,7 +7739,7 @@ // do not allow OpenCL objects to be passed as elements of the struct or // union. if (ParamType == PtrKernelParam || ParamType == PtrPtrKernelParam || - ParamType == PrivatePtrKernelParam) { + ParamType == InvalidAddrSpacePtrKernelParam) { S.Diag(Param->getLocation(), diag::err_record_with_pointers_kernel_param) << PT->isUnionType() Index: include/clang/Basic/DiagnosticSemaKinds.td === --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -8076,8 +8076,9 @@ "kernel functions cannot be declared static">; def err_opencl_ptrptr_kernel_param : Error< "kernel parameter cannot be declared as a pointer to a pointer">; -def err_opencl_private_ptr_kernel_param : Error< - "kernel parameter cannot be declared as a pointer to the __private address space">; +def err_kernel_arg_address_space : Error< + "pointer arguments to kernel functions must reside in '__global', " + "'__constant' or '__local' address space">; def err_opencl_function_variable : Error< "%select{non-kernel function|function scope}0 variable cannot be declared in %1 address space">; def err_static_function_scope : Error< Index: test/SemaOpenCL/invalid-kernel.cl === --- test/SemaOpenCL/invalid-kernel.cl +++ test/SemaOpenCL/invalid-kernel.cl @@ -1,10 +1,11 @@ // RUN: %clang_cc1 -ver
[PATCH] D27453: [OpenCL] Enable unroll hint for OpenCL 1.x.
This revision was automatically updated to reflect the committed changes. Closed by commit rL289535: [OpenCL] Enable unroll hint for OpenCL 1.x. (authored by echuraev). Changed prior to commit: https://reviews.llvm.org/D27453?vs=80547&id=81223#toc Repository: rL LLVM https://reviews.llvm.org/D27453 Files: cfe/trunk/lib/Sema/SemaStmtAttr.cpp cfe/trunk/test/CodeGenOpenCL/unroll-hint.cl cfe/trunk/test/SemaOpenCL/unroll-hint.cl Index: cfe/trunk/test/CodeGenOpenCL/unroll-hint.cl === --- cfe/trunk/test/CodeGenOpenCL/unroll-hint.cl +++ cfe/trunk/test/CodeGenOpenCL/unroll-hint.cl @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -emit-llvm -O0 -cl-std=CL2.0 -o - %s | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -O0 -cl-std=CL1.2 -o - %s | FileCheck %s /*** for ***/ void for_count() Index: cfe/trunk/test/SemaOpenCL/unroll-hint.cl === --- cfe/trunk/test/SemaOpenCL/unroll-hint.cl +++ cfe/trunk/test/SemaOpenCL/unroll-hint.cl @@ -1,17 +1,5 @@ -//RUN: %clang_cc1 -O0 -fsyntax-only -verify %s -//RUN: %clang_cc1 -O0 -cl-std=CL2.0 -fsyntax-only -verify -DCL20 %s +//RUN: %clang_cc1 -O0 -cl-std=CL2.0 -fsyntax-only -verify %s -kernel void D (global int *x) { - int i = 10; -#ifndef CL20 - // expected-error@+2 {{'opencl_unroll_hint' attribute requires OpenCL version 2.0 or above}} -#endif - __attribute__((opencl_unroll_hint)) - do { - } while(i--); -} - -#ifdef CL20 kernel void C (global int *x) { int I = 3; __attribute__((opencl_unroll_hint(I))) // expected-error {{'opencl_unroll_hint' attribute requires an integer constant}} @@ -27,4 +15,3 @@ __attribute__((opencl_unroll_hint(-1))) // expected-error {{'opencl_unroll_hint' attribute requires a positive integral compile time constant expression}} for(int i=0; i<100; i++); } -#endif Index: cfe/trunk/lib/Sema/SemaStmtAttr.cpp === --- cfe/trunk/lib/Sema/SemaStmtAttr.cpp +++ cfe/trunk/lib/Sema/SemaStmtAttr.cpp @@ -225,16 +225,12 @@ static Attr *handleOpenCLUnrollHint(Sema &S, Stmt *St, const AttributeList &A, SourceRange Range) { - // OpenCL v2.0 s6.11.5 - opencl_unroll_hint can have 0 arguments (compiler + // Although the feature was introduced only in OpenCL C v2.0 s6.11.5, it's + // useful for OpenCL 1.x too and doesn't require HW support. + // opencl_unroll_hint can have 0 arguments (compiler // determines unrolling factor) or 1 argument (the unroll factor provided // by the user). - if (S.getLangOpts().OpenCLVersion < 200) { -S.Diag(A.getLoc(), diag::err_attribute_requires_opencl_version) -<< A.getName() << "2.0" << 1; -return nullptr; - } - unsigned NumArgs = A.getNumArgs(); if (NumArgs > 1) { Index: cfe/trunk/test/CodeGenOpenCL/unroll-hint.cl === --- cfe/trunk/test/CodeGenOpenCL/unroll-hint.cl +++ cfe/trunk/test/CodeGenOpenCL/unroll-hint.cl @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -emit-llvm -O0 -cl-std=CL2.0 -o - %s | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -O0 -cl-std=CL1.2 -o - %s | FileCheck %s /*** for ***/ void for_count() Index: cfe/trunk/test/SemaOpenCL/unroll-hint.cl === --- cfe/trunk/test/SemaOpenCL/unroll-hint.cl +++ cfe/trunk/test/SemaOpenCL/unroll-hint.cl @@ -1,17 +1,5 @@ -//RUN: %clang_cc1 -O0 -fsyntax-only -verify %s -//RUN: %clang_cc1 -O0 -cl-std=CL2.0 -fsyntax-only -verify -DCL20 %s +//RUN: %clang_cc1 -O0 -cl-std=CL2.0 -fsyntax-only -verify %s -kernel void D (global int *x) { - int i = 10; -#ifndef CL20 - // expected-error@+2 {{'opencl_unroll_hint' attribute requires OpenCL version 2.0 or above}} -#endif - __attribute__((opencl_unroll_hint)) - do { - } while(i--); -} - -#ifdef CL20 kernel void C (global int *x) { int I = 3; __attribute__((opencl_unroll_hint(I))) // expected-error {{'opencl_unroll_hint' attribute requires an integer constant}} @@ -27,4 +15,3 @@ __attribute__((opencl_unroll_hint(-1))) // expected-error {{'opencl_unroll_hint' attribute requires a positive integral compile time constant expression}} for(int i=0; i<100; i++); } -#endif Index: cfe/trunk/lib/Sema/SemaStmtAttr.cpp === --- cfe/trunk/lib/Sema/SemaStmtAttr.cpp +++ cfe/trunk/lib/Sema/SemaStmtAttr.cpp @@ -225,16 +225,12 @@ static Attr *handleOpenCLUnrollHint(Sema &S, Stmt *St, const AttributeList &A, SourceRange Range) { - // OpenCL v2.0 s6.11.5 - opencl_unroll_hint can have 0 arguments (compiler + // Although the feature was introduced only in OpenCL C v2.0 s6.11.5, it's + // useful for OpenCL 1.x too and doesn't require HW support. + // opencl_unroll_hint can have 0 arguments (compiler // determines unrolling factor) or 1 argument
[PATCH] D27569: [OpenCL] Enabling the usage of CLK_NULL_QUEUE as compare operand.
echuraev updated this revision to Diff 81372. echuraev marked 4 inline comments as done. https://reviews.llvm.org/D27569 Files: include/clang/AST/OperationKinds.def include/clang/Sema/Initialization.h include/clang/Sema/Overload.h lib/AST/ExprConstant.cpp lib/CodeGen/CGExprAgg.cpp lib/CodeGen/CGExprComplex.cpp lib/CodeGen/CGExprScalar.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaExprCXX.cpp lib/Sema/SemaInit.cpp lib/Sema/SemaOverload.cpp test/CodeGenOpenCL/null_queue.cl Index: test/CodeGenOpenCL/null_queue.cl === --- /dev/null +++ test/CodeGenOpenCL/null_queue.cl @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -O0 -cl-std=CL2.0 -emit-llvm %s -o - | FileCheck %s +extern queue_t get_default_queue(); + +bool compare() { + return 0 == get_default_queue() && + get_default_queue() == 0; + // CHECK: icmp eq %opencl.queue_t* null, %{{.*}} + // CHECK: icmp eq %opencl.queue_t* %{{.*}}, null +} + +void init() { + queue_t q = 0; + // CHECK: store %opencl.queue_t* null, %opencl.queue_t** %q +} Index: lib/Sema/SemaOverload.cpp === --- lib/Sema/SemaOverload.cpp +++ lib/Sema/SemaOverload.cpp @@ -1781,6 +1781,11 @@ From->EvaluateKnownConstInt(S.getASTContext()) == 0) { SCS.Second = ICK_Zero_Event_Conversion; FromType = ToType; + } else if (ToType->isQueueT() && + From->isIntegerConstantExpr(S.getASTContext()) && + (From->EvaluateKnownConstInt(S.getASTContext()) == 0)) { +SCS.Second = ICK_Zero_Queue_Conversion; +FromType = ToType; } else { // No second conversion required. SCS.Second = ICK_Identity; @@ -5155,6 +5160,7 @@ case ICK_Function_Conversion: case ICK_Integral_Promotion: case ICK_Integral_Conversion: // Narrowing conversions are checked elsewhere. + case ICK_Zero_Queue_Conversion: return true; case ICK_Boolean_Conversion: Index: lib/Sema/SemaInit.cpp === --- lib/Sema/SemaInit.cpp +++ lib/Sema/SemaInit.cpp @@ -3073,6 +3073,7 @@ case SK_StdInitializerListConstructorCall: case SK_OCLSamplerInit: case SK_OCLZeroEvent: + case SK_OCLZeroQueue: break; case SK_ConversionSequence: @@ -3334,6 +3335,13 @@ Steps.push_back(S); } +void InitializationSequence::AddOCLZeroQueueStep(QualType T) { + Step S; + S.Kind = SK_OCLZeroQueue; + S.Type = T; + Steps.push_back(S); +} + void InitializationSequence::RewrapReferenceInitList(QualType T, InitListExpr *Syntactic) { assert(Syntactic->getNumInits() == 1 && @@ -4981,6 +4989,20 @@ return true; } +static bool TryOCLZeroQueueInitialization(Sema &S, + InitializationSequence &Sequence, + QualType DestType, + Expr *Initializer) { + if (!S.getLangOpts().OpenCL || S.getLangOpts().OpenCLVersion < 200 || + !DestType->isQueueT() || + !Initializer->isIntegerConstantExpr(S.getASTContext()) || + (Initializer->EvaluateKnownConstInt(S.getASTContext()) != 0)) +return false; + + Sequence.AddOCLZeroQueueStep(DestType); + return true; +} + InitializationSequence::InitializationSequence(Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind, @@ -5179,6 +5201,9 @@ if (TryOCLZeroEventInitialization(S, *this, DestType, Initializer)) return; +if (TryOCLZeroQueueInitialization(S, *this, DestType, Initializer)) + return; + // Handle initialization in C AddCAssignmentStep(DestType); MaybeProduceObjCObject(S, *this, Entity); @@ -6414,7 +6439,8 @@ case SK_ProduceObjCObject: case SK_StdInitializerList: case SK_OCLSamplerInit: - case SK_OCLZeroEvent: { + case SK_OCLZeroEvent: + case SK_OCLZeroQueue: { assert(Args.size() == 1); CurInit = Args[0]; if (!CurInit.get()) return ExprError(); @@ -7088,6 +7114,15 @@ CurInit.get()->getValueKind()); break; } +case SK_OCLZeroQueue: { + assert(Step->Type->isQueueT() && + "Event initialization on non queue type."); + + CurInit = S.ImpCastExprToType(CurInit.get(), Step->Type, +CK_ZeroToOCLQueue, +CurInit.get()->getValueKind()); + break; +} } } @@ -7873,6 +7908,10 @@ case SK_OCLZeroEvent: OS << "OpenCL event_t from zero"; break; + +case SK_OCLZeroQueue: + OS << "OpenCL queue_t from zero"; + break; } OS << " [" << S->Type.getAsString() << ']'; Index: lib/Sema/SemaExprCXX.cpp === --- lib/Sema/SemaExprCXX.
[PATCH] D32896: [OpenCL] Make CLK_NULL_RESERVE_ID invalid reserve id.
echuraev created this revision. Herald added a subscriber: yaxunl. Make CLK_NULL_RESERVE_ID invalid reserve id. Rename PIPE_RESERVE_ID_VALID_BIT to avoid user name space pollution. Current implementation reserve_id_t type assumes that it's a pointer type whose most significant bit is set to one and the rest of the bits keep the id value. This patch increase reserve id size by one bit on 32-bit platforms and by 33 bits on 64-bit platforms. https://reviews.llvm.org/D32896 Files: lib/Headers/opencl-c.h Index: lib/Headers/opencl-c.h === --- lib/Headers/opencl-c.h +++ lib/Headers/opencl-c.h @@ -16014,8 +16014,10 @@ // OpenCL v2.0 s6.13.16 - Pipe Functions #if __OPENCL_C_VERSION__ >= CL_VERSION_2_0 -#define PIPE_RESERVE_ID_VALID_BIT (1U << 30) -#define CLK_NULL_RESERVE_ID (__builtin_astype(((void*)(__SIZE_MAX__)), reserve_id_t)) +// The most significant bit of valid reserve_id must be set to one. +#define __PIPE_RESERVE_ID_VALID_BIT ((size_t)1 << (sizeof(size_t) * 8 - 1)) +// The macro CLK_NULL_RESERVE_ID refers to an invalid reservation ID. +#define CLK_NULL_RESERVE_ID (__builtin_astype((void *)0, reserve_id_t)) bool __ovld is_valid_reserve_id(reserve_id_t reserve_id); #endif //__OPENCL_C_VERSION__ >= CL_VERSION_2_0 Index: lib/Headers/opencl-c.h === --- lib/Headers/opencl-c.h +++ lib/Headers/opencl-c.h @@ -16014,8 +16014,10 @@ // OpenCL v2.0 s6.13.16 - Pipe Functions #if __OPENCL_C_VERSION__ >= CL_VERSION_2_0 -#define PIPE_RESERVE_ID_VALID_BIT (1U << 30) -#define CLK_NULL_RESERVE_ID (__builtin_astype(((void*)(__SIZE_MAX__)), reserve_id_t)) +// The most significant bit of valid reserve_id must be set to one. +#define __PIPE_RESERVE_ID_VALID_BIT ((size_t)1 << (sizeof(size_t) * 8 - 1)) +// The macro CLK_NULL_RESERVE_ID refers to an invalid reservation ID. +#define CLK_NULL_RESERVE_ID (__builtin_astype((void *)0, reserve_id_t)) bool __ovld is_valid_reserve_id(reserve_id_t reserve_id); #endif //__OPENCL_C_VERSION__ >= CL_VERSION_2_0 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D32897: [OpenCL] Added checking OpenCL version for cl_khr_mipmap_image built-ins
echuraev created this revision. Herald added a subscriber: yaxunl. https://reviews.llvm.org/D32897 Files: lib/Headers/opencl-c.h Index: lib/Headers/opencl-c.h === --- lib/Headers/opencl-c.h +++ lib/Headers/opencl-c.h @@ -14962,6 +14962,7 @@ #endif //cl_khr_gl_msaa_sharing // OpenCL Extension v2.0 s9.18 - Mipmaps +#if __OPENCL_C_VERSION__ >= CL_VERSION_2_0 #ifdef cl_khr_mipmap_image float4 __purefn __ovld read_imagef(read_only image1d_t image, sampler_t sampler, float coord, float lod); @@ -15037,6 +15038,7 @@ uint4 __purefn __ovld read_imageui(read_only image3d_t image, sampler_t sampler, float4 coord, float lod); #endif //cl_khr_mipmap_image +#endif //__OPENCL_C_VERSION__ >= CL_VERSION_2_0 /** * Sampler-less Image Access @@ -15135,6 +15137,7 @@ float __purefn __ovld read_imagef(read_write image2d_array_msaa_depth_t image, int4 coord, int sample); #endif //cl_khr_gl_msaa_sharing +#if __OPENCL_C_VERSION__ >= CL_VERSION_2_0 #ifdef cl_khr_mipmap_image float4 __purefn __ovld read_imagef(read_write image1d_t image, sampler_t sampler, float coord, float lod); int4 __purefn __ovld read_imagei(read_write image1d_t image, sampler_t sampler, float coord, float lod); @@ -15208,6 +15211,7 @@ int4 __purefn __ovld read_imagei(read_write image3d_t image, sampler_t sampler, float4 coord, float lod); uint4 __purefn __ovld read_imageui(read_write image3d_t image, sampler_t sampler, float4 coord, float lod); #endif //cl_khr_mipmap_image +#endif //__OPENCL_C_VERSION__ >= CL_VERSION_2_0 // Image read functions returning half4 type #ifdef cl_khr_fp16 @@ -15319,6 +15323,7 @@ #endif //cl_khr_depth_images // OpenCL Extension v2.0 s9.18 - Mipmaps +#if __OPENCL_C_VERSION__ >= CL_VERSION_2_0 #ifdef cl_khr_mipmap_image void __ovld write_imagef(write_only image1d_t image, int coord, int lod, float4 color); void __ovld write_imagei(write_only image1d_t image, int coord, int lod, int4 color); @@ -15345,6 +15350,7 @@ void __ovld write_imageui(write_only image3d_t image, int4 coord, int lod, uint4 color); #endif #endif //cl_khr_mipmap_image +#endif //__OPENCL_C_VERSION__ >= CL_VERSION_2_0 // Image write functions for half4 type #ifdef cl_khr_fp16 @@ -15391,6 +15397,7 @@ void __ovld write_imagef(read_write image2d_array_depth_t image, int4 coord, float color); #endif //cl_khr_depth_images +#if __OPENCL_C_VERSION__ >= CL_VERSION_2_0 #ifdef cl_khr_mipmap_image void __ovld write_imagef(read_write image1d_t image, int coord, int lod, float4 color); void __ovld write_imagei(read_write image1d_t image, int coord, int lod, int4 color); @@ -15417,6 +15424,7 @@ void __ovld write_imageui(read_write image3d_t image, int4 coord, int lod, uint4 color); #endif #endif //cl_khr_mipmap_image +#endif //__OPENCL_C_VERSION__ >= CL_VERSION_2_0 // Image write functions for half4 type #ifdef cl_khr_fp16 @@ -15559,6 +15567,7 @@ #endif //__OPENCL_C_VERSION__ >= CL_VERSION_2_0 // OpenCL Extension v2.0 s9.18 - Mipmaps +#if __OPENCL_C_VERSION__ >= CL_VERSION_2_0 #ifdef cl_khr_mipmap_image /** * Return the image miplevels. @@ -15574,11 +15583,9 @@ int __ovld get_image_num_mip_levels(write_only image3d_t image); #endif -#if __OPENCL_C_VERSION__ >= CL_VERSION_2_0 int __ovld get_image_num_mip_levels(read_write image1d_t image); int __ovld get_image_num_mip_levels(read_write image2d_t image); int __ovld get_image_num_mip_levels(read_write image3d_t image); -#endif //__OPENCL_C_VERSION__ >= CL_VERSION_2_0 int __ovld get_image_num_mip_levels(read_only image1d_array_t image); int __ovld get_image_num_mip_levels(read_only image2d_array_t image); @@ -15590,14 +15597,13 @@ int __ovld get_image_num_mip_levels(write_only image2d_array_depth_t image); int __ovld get_image_num_mip_levels(write_only image2d_depth_t image); -#if __OPENCL_C_VERSION__ >= CL_VERSION_2_0 int __ovld get_image_num_mip_levels(read_write image1d_array_t image); int __ovld get_image_num_mip_levels(read_write image2d_array_t image); int __ovld get_image_num_mip_levels(read_write image2d_array_depth_t image); int __ovld get_image_num_mip_levels(read_write image2d_depth_t image); -#endif //__OPENCL_C_VERSION__ >= CL_VERSION_2_0 #endif //cl_khr_mipmap_image +#endif //__OPENCL_C_VERSION__ >= CL_VERSION_2_0 /** * Return the channel data type. Valid values are: ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D32898: [OpenCL] Handle OpenCL specific subelement types
echuraev created this revision. Herald added a subscriber: yaxunl. https://reviews.llvm.org/D32898 Files: lib/Sema/SemaInit.cpp test/SemaOpenCL/array-init.cl Index: test/SemaOpenCL/array-init.cl === --- /dev/null +++ test/SemaOpenCL/array-init.cl @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL2.0 +// expected-no-diagnostics + +__kernel void k2(queue_t q1, queue_t q2) { + queue_t q[] = {q1, q2}; +} + +__kernel void k3(read_only pipe int p) { + reserve_id_t i1 = reserve_read_pipe(p, 1); + reserve_id_t i2 = reserve_read_pipe(p, 1); + reserve_id_t i[] = {i1, i2}; +} + +event_t create_event(); +__kernel void k5() { + event_t e1 = create_event(); + event_t e2 = create_event(); + event_t e[] = {e1, e2}; +} + Index: lib/Sema/SemaInit.cpp === --- lib/Sema/SemaInit.cpp +++ lib/Sema/SemaInit.cpp @@ -1209,7 +1209,7 @@ } else { assert((ElemType->isRecordType() || ElemType->isVectorType() || -ElemType->isClkEventT()) && "Unexpected type"); +ElemType->isOpenCLSpecificType()) && "Unexpected type"); // C99 6.7.8p13: // Index: test/SemaOpenCL/array-init.cl === --- /dev/null +++ test/SemaOpenCL/array-init.cl @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL2.0 +// expected-no-diagnostics + +__kernel void k2(queue_t q1, queue_t q2) { + queue_t q[] = {q1, q2}; +} + +__kernel void k3(read_only pipe int p) { + reserve_id_t i1 = reserve_read_pipe(p, 1); + reserve_id_t i2 = reserve_read_pipe(p, 1); + reserve_id_t i[] = {i1, i2}; +} + +event_t create_event(); +__kernel void k5() { + event_t e1 = create_event(); + event_t e2 = create_event(); + event_t e[] = {e1, e2}; +} + Index: lib/Sema/SemaInit.cpp === --- lib/Sema/SemaInit.cpp +++ lib/Sema/SemaInit.cpp @@ -1209,7 +1209,7 @@ } else { assert((ElemType->isRecordType() || ElemType->isVectorType() || -ElemType->isClkEventT()) && "Unexpected type"); +ElemType->isOpenCLSpecificType()) && "Unexpected type"); // C99 6.7.8p13: // ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D32898: [OpenCL] Handle OpenCL specific subelement types
echuraev updated this revision to Diff 98416. https://reviews.llvm.org/D32898 Files: lib/Sema/SemaInit.cpp test/SemaOpenCL/array-init.cl Index: test/SemaOpenCL/array-init.cl === --- /dev/null +++ test/SemaOpenCL/array-init.cl @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL2.0 +// expected-no-diagnostics + +__kernel void k1(queue_t q1, queue_t q2) { + queue_t q[] = {q1, q2}; +} + +__kernel void k2(read_only pipe int p) { + reserve_id_t i1 = reserve_read_pipe(p, 1); + reserve_id_t i2 = reserve_read_pipe(p, 1); + reserve_id_t i[] = {i1, i2}; +} + +event_t create_event(); +__kernel void k3() { + event_t e1 = create_event(); + event_t e2 = create_event(); + event_t e[] = {e1, e2}; +} + Index: lib/Sema/SemaInit.cpp === --- lib/Sema/SemaInit.cpp +++ lib/Sema/SemaInit.cpp @@ -1209,7 +1209,7 @@ } else { assert((ElemType->isRecordType() || ElemType->isVectorType() || -ElemType->isClkEventT()) && "Unexpected type"); +ElemType->isOpenCLSpecificType()) && "Unexpected type"); // C99 6.7.8p13: // Index: test/SemaOpenCL/array-init.cl === --- /dev/null +++ test/SemaOpenCL/array-init.cl @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL2.0 +// expected-no-diagnostics + +__kernel void k1(queue_t q1, queue_t q2) { + queue_t q[] = {q1, q2}; +} + +__kernel void k2(read_only pipe int p) { + reserve_id_t i1 = reserve_read_pipe(p, 1); + reserve_id_t i2 = reserve_read_pipe(p, 1); + reserve_id_t i[] = {i1, i2}; +} + +event_t create_event(); +__kernel void k3() { + event_t e1 = create_event(); + event_t e2 = create_event(); + event_t e[] = {e1, e2}; +} + Index: lib/Sema/SemaInit.cpp === --- lib/Sema/SemaInit.cpp +++ lib/Sema/SemaInit.cpp @@ -1209,7 +1209,7 @@ } else { assert((ElemType->isRecordType() || ElemType->isVectorType() || -ElemType->isClkEventT()) && "Unexpected type"); +ElemType->isOpenCLSpecificType()) && "Unexpected type"); // C99 6.7.8p13: // ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D27334: [OpenCL] Ambiguous function call.
echuraev added a comment. So, I think that we have to do some decision about this patch. @Anastasia, What do you think about it? Please see my commentary above. What should we do with this patch? https://reviews.llvm.org/D27334 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31745: [OpenCL] Added diagnostic for implicit declaration of function in OpenCL
echuraev updated this revision to Diff 98958. echuraev added a comment. I disabled adding note diagnostic for OpenCL. Addition function to dictionary occurs in function CurrectTypo. In this function take place creation of consumer by calling function makeTypoCorrectionConsumer. The function do some checks and next create consumer by the following code: auto Consumer = llvm::make_unique( *this, TypoName, LookupKind, S, SS, std::move(CCC), MemberContext, EnteringContext); In constructor TypoCorrectionConsumer occurs adding correction to dictionary (ValidatedCorrections). https://reviews.llvm.org/D31745 Files: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaDecl.cpp test/SemaOpenCL/clang-builtin-version.cl test/SemaOpenCL/to_addr_builtin.cl Index: test/SemaOpenCL/to_addr_builtin.cl === --- test/SemaOpenCL/to_addr_builtin.cl +++ test/SemaOpenCL/to_addr_builtin.cl @@ -10,7 +10,7 @@ glob = to_global(glob, loc); #if __OPENCL_C_VERSION__ < CL_VERSION_2_0 - // expected-warning@-2{{implicit declaration of function 'to_global' is invalid in C99}} + // expected-error@-2{{implicit declaration of function 'to_global' is invalid in OpenCL}} // expected-warning@-3{{incompatible integer to pointer conversion assigning to '__global int *' from 'int'}} #else // expected-error@-5{{invalid number of arguments to function: 'to_global'}} Index: test/SemaOpenCL/clang-builtin-version.cl === --- test/SemaOpenCL/clang-builtin-version.cl +++ test/SemaOpenCL/clang-builtin-version.cl @@ -4,41 +4,45 @@ kernel void dse_builtins() { int tmp; - enqueue_kernel(tmp, tmp, tmp, ^(void) { // expected-warning{{implicit declaration of function 'enqueue_kernel' is invalid in C99}} + enqueue_kernel(tmp, tmp, tmp, ^(void) { // expected-error{{implicit declaration of function 'enqueue_kernel' is invalid in OpenCL}} return; }); - unsigned size = get_kernel_work_group_size(^(void) { // expected-warning{{implicit declaration of function 'get_kernel_work_group_size' is invalid in C99}} + unsigned size = get_kernel_work_group_size(^(void) { // expected-error{{implicit declaration of function 'get_kernel_work_group_size' is invalid in OpenCL}} return; }); - size = get_kernel_preferred_work_group_size_multiple(^(void) { // expected-warning{{implicit declaration of function 'get_kernel_preferred_work_group_size_multiple' is invalid in C99}} + size = get_kernel_preferred_work_group_size_multiple(^(void) { // expected-error{{implicit declaration of function 'get_kernel_preferred_work_group_size_multiple' is invalid in OpenCL}} return; }); } void pipe_builtins() { int tmp; - read_pipe(tmp, tmp); // expected-warning{{implicit declaration of function 'read_pipe' is invalid in C99}} - write_pipe(tmp, tmp); // expected-warning{{implicit declaration of function 'write_pipe' is invalid in C99}} + foo(void); // expected-error{{implicit declaration of function 'foo' is invalid in OpenCL}} + // expected-error@-1{{expected expression}} + boo(); // expected-error{{implicit declaration of function 'boo' is invalid in OpenCL}} - reserve_read_pipe(tmp, tmp); // expected-warning{{implicit declaration of function 'reserve_read_pipe' is invalid in C99}} - reserve_write_pipe(tmp, tmp); // expected-warning{{implicit declaration of function 'reserve_write_pipe' is invalid in C99}} + read_pipe(tmp, tmp); // expected-error{{implicit declaration of function 'read_pipe' is invalid in OpenCL}} + write_pipe(tmp, tmp); // expected-error{{implicit declaration of function 'write_pipe' is invalid in OpenCL}} - work_group_reserve_read_pipe(tmp, tmp); // expected-warning{{implicit declaration of function 'work_group_reserve_read_pipe' is invalid in C99}} - work_group_reserve_write_pipe(tmp, tmp); // expected-warning{{implicit declaration of function 'work_group_reserve_write_pipe' is invalid in C99}} + reserve_read_pipe(tmp, tmp); // expected-error{{implicit declaration of function 'reserve_read_pipe' is invalid in OpenCL}} + reserve_write_pipe(tmp, tmp); // expected-error{{implicit declaration of function 'reserve_write_pipe' is invalid in OpenCL}} - sub_group_reserve_write_pipe(tmp, tmp); // expected-warning{{implicit declaration of function 'sub_group_reserve_write_pipe' is invalid in C99}} - sub_group_reserve_read_pipe(tmp, tmp); // expected-warning{{implicit declaration of function 'sub_group_reserve_read_pipe' is invalid in C99}} + work_group_reserve_read_pipe(tmp, tmp); // expected-error{{implicit declaration of function 'work_group_reserve_read_pipe' is invalid in OpenCL}} + work_group_reserve_write_pipe(tmp, tmp); // expected-error{{implicit declaration of function 'work_group_reserve_write_pipe' is invalid in OpenCL}} - commit_read_pipe(tmp, tmp); // expected-warning{{implicit declaration of function 'commit_read_pipe' is
[PATCH] D32896: [OpenCL] Make CLK_NULL_RESERVE_ID invalid reserve id.
echuraev added inline comments. Comment at: lib/Headers/opencl-c.h:16020 +// The macro CLK_NULL_RESERVE_ID refers to an invalid reservation ID. +#define CLK_NULL_RESERVE_ID (__builtin_astype((void *)0, reserve_id_t)) bool __ovld is_valid_reserve_id(reserve_id_t reserve_id); yaxunl wrote: > Anastasia wrote: > > yaxunl wrote: > > > Anastasia wrote: > > > > Looks good from my side. > > > > > > > > @yaxunl , since you originally committed this. Could you please verify > > > > that changing from `SIZE_MAX` to `0` would be fine. > > > > > > > > Btw, we have a similar definition for `CLK_NULL_EVENT`. > > > `__PIPE_RESERVE_ID_VALID_BIT` is implementation detail and not part of > > > the spec. I would suggest to remove it from this header file. > > > > > > The spec only requires CLK_NULL_RESERVE_ID to be defined but does not > > > define its value. Naturally a valid id starts from 0 and increases. I > > > don't see significant advantage to change CLK_NULL_RESERVE_ID from > > > __SIZE_MAX to 0. > > > > > > Is there any reason that this change is needed? > > I don't see issues to commit things outside of spec as soon as they > > prefixed properly with "__". But I agree it would be nice to see if it's > > any useful and what the motivation is for having different implementation. > For `__PIPE_RESERVE_ID_VALID_BIT`, it assumes that the implementation uses > one specific bit of a reserve id to indicate that the reserve id is valid. > Not all implementations assume that. Actually I am curious why that is needed > too. About `CLK_NULL_RESERVE_ID`: we check that reserve id is valid if significant bit equal to one. `CLK_NULL_RESERVE_ID refers to an invalid reservation, so if `CLK_NULL_RESERVE_ID equal to 0, we can be sure that significant bit doesn't equal to 1 and it is invalid reserve id. Also it is more obviously if CLK_**NULL**_RESERVE_ID is equal to 0. What about `__PIPE_RESERVE_ID_VALID_BIT`: As I understand previous implementation also assumes that one specific bit was of a reverse id was used to indicate that the reserve id is valid. So, we just increased reserve id size by one bit on 32-bit platforms and by 33 bits on 64-bit platforms. https://reviews.llvm.org/D32896 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D33353: [OpenCL] An error shall occur if any scalar operand has greater rank than the type of the vector element
echuraev created this revision. Herald added a subscriber: yaxunl. https://reviews.llvm.org/D33353 Files: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaExpr.cpp test/SemaOpenCL/arithmetic-conversions.cl test/SemaOpenCL/cond.cl Index: test/SemaOpenCL/cond.cl === --- test/SemaOpenCL/cond.cl +++ test/SemaOpenCL/cond.cl @@ -89,7 +89,7 @@ float2 ntest05(int2 C, int2 X, float Y) { - return C ? X : Y; // expected-error {{cannot convert between vector values of different size ('int2' (vector of 2 'int' values) and 'float')}} + return C ? X : Y; // expected-error {{scalar operand type has greater rank than the type of the vector element. ('int2' (vector of 2 'int' values) and 'float'}} } char2 ntest06(int2 C, char2 X, char2 Y) Index: test/SemaOpenCL/arithmetic-conversions.cl === --- /dev/null +++ test/SemaOpenCL/arithmetic-conversions.cl @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL1.2 + +typedef float float2 __attribute__((ext_vector_type(2))); +typedef long long2 __attribute__((ext_vector_type(2))); +typedef int int2 __attribute__((ext_vector_type(2))); + +kernel void foo1(float2 in, global float2 *out) { *out = in + 0.5;} // expected-error {{scalar operand type has greater rank than the type of the vector element. ('float2' (vector of 2 'float' values) and 'double')}} + +kernel void foo2(float2 in, global float2 *out) { *out = 0.5 + in;} // expected-error {{scalar operand type has greater rank than the type of the vector element. ('double' and 'float2' (vector of 2 'float' values))}} + +kernel void foo3(float2 in, global float2 *out) { *out = 0.5f + in;} + +kernel void foo4(long2 in, global long2 *out) { *out = 5 + in;} + +kernel void foo5(float2 in, global float2 *out) { +float* f; +*out = f + in; // expected-error{{cannot convert between vector and non-scalar values ('float *' and 'float2' (vector of 2 'float' values))}} +} + +kernel void foo6(int2 in, global int2 *out) { +int* f; +*out = f + in; // expected-error{{cannot convert between vector and non-scalar values ('int *' and 'int2' (vector of 2 'int' values))}} +} Index: lib/Sema/SemaExpr.cpp === --- lib/Sema/SemaExpr.cpp +++ lib/Sema/SemaExpr.cpp @@ -8064,28 +8064,38 @@ /// rank; for C, Obj-C, and C++ we allow any real scalar conversion except /// for float->int. /// +/// OpenCL V2.0 6.2.6.p2: +/// An error shall occur if any scalar operand type has greater rank +/// than the type of the vector element. +/// /// \param scalar - if non-null, actually perform the conversions /// \return true if the operation fails (but without diagnosing the failure) static bool tryVectorConvertAndSplat(Sema &S, ExprResult *scalar, QualType scalarTy, QualType vectorEltTy, - QualType vectorTy) { + QualType vectorTy, + unsigned &DiagID) { // The conversion to apply to the scalar before splatting it, // if necessary. CastKind scalarCast = CK_Invalid; if (vectorEltTy->isIntegralType(S.Context)) { -if (!scalarTy->isIntegralType(S.Context)) +if (S.getLangOpts().OpenCL && (scalarTy->isRealFloatingType() || +(scalarTy->isIntegerType() && + S.Context.getIntegerTypeOrder(vectorEltTy, scalarTy) < 0))) { + DiagID = diag::err_scalar_type_rank_greater_than_vector_type; return true; -if (S.getLangOpts().OpenCL && -S.Context.getIntegerTypeOrder(vectorEltTy, scalarTy) < 0) +} +if (!scalarTy->isIntegralType(S.Context)) return true; scalarCast = CK_IntegralCast; } else if (vectorEltTy->isRealFloatingType()) { if (scalarTy->isRealFloatingType()) { if (S.getLangOpts().OpenCL && - S.Context.getFloatingTypeOrder(vectorEltTy, scalarTy) < 0) + S.Context.getFloatingTypeOrder(vectorEltTy, scalarTy) < 0) { +DiagID = diag::err_scalar_type_rank_greater_than_vector_type; return true; + } scalarCast = CK_FloatingCast; } else if (scalarTy->isIntegralType(S.Context)) @@ -8331,10 +8341,12 @@ // If there's a vector type and a scalar, try to convert the scalar to // the vector element type and splat. + unsigned DeclID = 0; if (!RHSVecType) { if (isa(LHSVecType)) { if (!tryVectorConvertAndSplat(*this, &RHS, RHSType, -LHSVecType->getElementType(), LHSType)) +LHSVecType->getElementType(), LHSType, +DeclID)) return LHSType; } else { if (!tryGCCVectorConvertAndSplat(*this, &RHS, &LHS)) @@ -8345,15 +8357,22 @@ if (isa(RHSVecType)) { if (!tryVec
[PATCH] D31745: [OpenCL] Added diagnostic for implicit declaration of function in OpenCL
echuraev added inline comments. Comment at: lib/Sema/SemaDecl.cpp:12449 // function declaration is going to be treated as an error. - if (Diags.getDiagnosticLevel(diag_id, Loc) >= DiagnosticsEngine::Error) { + if (!getLangOpts().OpenCL && + Diags.getDiagnosticLevel(diag_id, Loc) >= DiagnosticsEngine::Error) { Anastasia wrote: > This way prevents the typo corrections completely for OpenCL which is not > very desirable. I was just wondering could we prevent adding the invalid > builtin function identifiers instead to the correction candidate list. > > Like when `work_group_reserve_read_pipe` was first parsed it shouldn't have > been added to the list of valid function identifiers to appear in the > corrections of 'work_group_reserve_write_pipe'. I am guessing the identifier > might be added when builtins are initialized... Yes, sorry, I didn't think about it. I investigated the question how can I remove invalid functions from correction candidate list. But I have a problem and I hope that you will be able to help me. I found that the correction is added in function `void TypoCorrectionConsumer::addName` (in file //SemaLookup.cpp//) which called from loop in function `std::unique_ptr Sema::makeTypoCorrectionConsumer`. The loop you can see below: ``` // For unqualified lookup, look through all of the names that we have // seen in this translation unit. // FIXME: Re-add the ability to skip very unlikely potential corrections. for (const auto &I : Context.Idents) Consumer->FoundName(I.getKey()); ``` But the map `Context.Idents` already contains names of implicit functions. So, I found that names of functions were added to this dictionary during parsing AST. After calling `ConsumeToken()` function in `void Parser::ParseDeclarationSpecifiers` (in file //ParseDecl.cpp//) implicit functions were added to the dictionary. But in this function I'm not able to check is the OpenCL function implicit declared or not. As a result I tried to remove names of implicit functions before calling `CorrectTypo`. But unfortunately, we don't have an API for removing items from `Context.Idents`. So, I don't know the good way for fixing these diagnostic messages. Could you help me please? Do you have any suggestions? Thank you in advance! https://reviews.llvm.org/D31745 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits