[PATCH] D35000: [OpenCL] Added extended tests on metadata generation for half data type and arrays.

2017-07-17 Thread Egor Churaev via Phabricator via cfe-commits
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 

[PATCH] D35000: [OpenCL] Added extended tests on metadata generation for half data type and arrays.

2017-07-13 Thread Egor Churaev via Phabricator via cfe-commits
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.

2017-07-06 Thread Egor Churaev via Phabricator via cfe-commits
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 

[PATCH] D35000: [OpenCL] Added extended tests on metadata generation for half data type and arrays.

2017-07-05 Thread Egor Churaev via Phabricator via cfe-commits
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

[PATCH] D34980: [OpenCL] Test on image access modifiers and image type can only be a type of a function argument.

2017-07-05 Thread Egor Churaev via Phabricator via cfe-commits
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); // 

[PATCH] D34980: [OpenCL] Test on image access modifiers and image type can only be a type of a function argument.

2017-07-05 Thread Egor Churaev via Phabricator via cfe-commits
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] D33648: [OpenCL] An error shall occur if any scalar operand has greater rank than the type of the vector element

2017-05-29 Thread Egor Churaev via Phabricator via cfe-commits
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 , ExprResult *scalar,
  QualType scalarTy,
  QualType vectorEltTy,
- QualType vectorTy) {
+ QualType vectorTy,
+ unsigned ) {
   // 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, , RHSType,
-LHSVecType->getElementType(), LHSType))
+

[PATCH] D33353: [OpenCL] An error shall occur if any scalar operand has greater rank than the type of the vector element

2017-05-29 Thread Egor Churaev via Phabricator via cfe-commits
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] D33592: [OpenCL] Test on half immediate support.

2017-05-26 Thread Egor Churaev via Phabricator via cfe-commits
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

2017-05-25 Thread Egor Churaev via Phabricator via cfe-commits
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 , ExprResult *scalar,
  QualType scalarTy,
  QualType vectorEltTy,
- QualType vectorTy) {
+ QualType vectorTy,
+ unsigned ) {
   // 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, , RHSType,
-LHSVecType->getElementType(), LHSType))
+LHSVecType->getElementType(), LHSType,
+DiagID))
 return LHSType;
 } else {
   if (!tryGCCVectorConvertAndSplat(*this, , ))
@@ -8345,7 

[PATCH] D31745: [OpenCL] Added diagnostic for implicit declaration of function in OpenCL

2017-05-25 Thread Egor Churaev via Phabricator via cfe-commits
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' 

[PATCH] D31745: [OpenCL] Added diagnostic for implicit declaration of function in OpenCL

2017-05-22 Thread Egor Churaev via Phabricator via cfe-commits
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  : 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


[PATCH] D33353: [OpenCL] An error shall occur if any scalar operand has greater rank than the type of the vector element

2017-05-19 Thread Egor Churaev via Phabricator via cfe-commits
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 , ExprResult *scalar,
  QualType scalarTy,
  QualType vectorEltTy,
- QualType vectorTy) {
+ QualType vectorTy,
+ unsigned ) {
   // 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, , RHSType,
-LHSVecType->getElementType(), LHSType))
+LHSVecType->getElementType(), LHSType,
+DeclID))
 return LHSType;
 } else {
   if (!tryGCCVectorConvertAndSplat(*this, , ))
@@ -8345,15 +8357,22 @@
 if (isa(RHSVecType)) {
   if 

[PATCH] D32896: [OpenCL] Make CLK_NULL_RESERVE_ID invalid reserve id.

2017-05-15 Thread Egor Churaev via Phabricator via cfe-commits
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] D31745: [OpenCL] Added diagnostic for implicit declaration of function in OpenCL

2017-05-15 Thread Egor Churaev via Phabricator via cfe-commits
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] D27334: [OpenCL] Ambiguous function call.

2017-05-11 Thread Egor Churaev via Phabricator via cfe-commits
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] D32898: [OpenCL] Handle OpenCL specific subelement types

2017-05-10 Thread Egor Churaev via Phabricator via cfe-commits
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] D32898: [OpenCL] Handle OpenCL specific subelement types

2017-05-05 Thread Egor Churaev via Phabricator via cfe-commits
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] D32897: [OpenCL] Added checking OpenCL version for cl_khr_mipmap_image built-ins

2017-05-05 Thread Egor Churaev via Phabricator via cfe-commits
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] D32896: [OpenCL] Make CLK_NULL_RESERVE_ID invalid reserve id.

2017-05-05 Thread Egor Churaev via Phabricator via cfe-commits
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] D31745: [OpenCL] Added diagnostic for implicit declaration of function in OpenCL

2017-04-14 Thread Egor Churaev via Phabricator via cfe-commits
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] D31745: [OpenCL] Added diagnostic for implicit declaration of function in OpenCL

2017-04-10 Thread Egor Churaev via Phabricator via cfe-commits
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

2017-04-10 Thread Egor Churaev via Phabricator via cfe-commits
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] D26794: [OpenCL] Blocks are allowed to capture arrays in OpenCL 2.0 and higher.

2017-04-07 Thread Egor Churaev via Phabricator via cfe-commits
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] D26794: [OpenCL] Blocks are allowed to capture arrays in OpenCL 2.0 and higher.

2017-04-07 Thread Egor Churaev via Phabricator via cfe-commits
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] D31745: [OpenCL] Added diagnostic for implicit declaration of function in OpenCL

2017-04-06 Thread Egor Churaev via Phabricator via cfe-commits
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}}
+  // 

[PATCH] D27334: [OpenCL] Ambiguous function call.

2017-04-06 Thread Egor Churaev via Phabricator via cfe-commits
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] D31594: [OpenCL] Enables passing sampler initializer to function argument

2017-04-04 Thread Egor Churaev via Phabricator via cfe-commits
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] D31594: [OpenCL] Enables passing sampler initializer to function argument

2017-04-03 Thread Egor Churaev via Phabricator via cfe-commits
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] D30643: [OpenCL] Extended diagnostics for atomic initialization

2017-04-03 Thread Egor Churaev via Phabricator via cfe-commits
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();
 // 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] D30643: [OpenCL] Extended diagnostics for atomic initialization

2017-03-31 Thread Egor Churaev via Phabricator via cfe-commits
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();
 // 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] D31321: [OpenCL] Do not generate "kernel_arg_type_qual" metadata for non-pointer args

2017-03-31 Thread Egor Churaev via Phabricator via cfe-commits
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

2017-03-29 Thread Egor Churaev via Phabricator via cfe-commits
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();
 // 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

2017-03-29 Thread Egor Churaev via Phabricator via cfe-commits
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] D31321: [OpenCL] Do not generate "kernel_arg_type_qual" metadata for non-pointer args

2017-03-29 Thread Egor Churaev via Phabricator via cfe-commits
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] D31183: [OpenCL] Added parsing for OpenCL vector types.

2017-03-27 Thread Egor Churaev via Phabricator via cfe-commits
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 ,
-   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: 

[PATCH] D30643: [OpenCL] Extended diagnostics for atomic initialization

2017-03-27 Thread Egor Churaev via Phabricator via cfe-commits
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();
 // 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.

2017-03-27 Thread Egor Churaev via Phabricator via cfe-commits
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] D31324: [OpenCL] Extended mapping of parcing CodeGen arguments

2017-03-24 Thread Egor Churaev via Phabricator via cfe-commits
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] D31321: [OpenCL] Do not generate "kernel_arg_type_qual" metadata for non-pointer args

2017-03-24 Thread Egor Churaev via Phabricator via cfe-commits
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] D31183: [OpenCL] Added parsing for OpenCL vector types.

2017-03-23 Thread Egor Churaev via Phabricator via cfe-commits
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] D31183: [OpenCL] Added parsing for OpenCL vector types.

2017-03-21 Thread Egor Churaev via Phabricator via cfe-commits
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 ,
-   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, 

[PATCH] D30937: [OpenCL] Added diagnostic for checking length of vector

2017-03-15 Thread Egor Churaev via Phabricator via cfe-commits
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 

[PATCH] D30816: [OpenCL] Added implicit conversion rank for overloading functions with vector data type in OpenCL

2017-03-14 Thread Egor Churaev via Phabricator via cfe-commits
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, ///< 

[PATCH] D30937: Added diagnostic for checking length of vector

2017-03-14 Thread Egor Churaev via Phabricator via cfe-commits
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

2017-03-14 Thread Egor Churaev via Phabricator via cfe-commits
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)) 

[PATCH] D30643: [OpenCL] Extended diagnostics for atomic initialization

2017-03-13 Thread Egor Churaev via Phabricator via cfe-commits
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();
 // 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 

[PATCH] D28136: [OpenCL] Implement as_type operator as alias of __builtin_astype.

2017-03-10 Thread Egor Churaev via Phabricator via cfe-commits
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] D28136: [OpenCL] Implement as_type operator as alias of __builtin_astype.

2017-03-10 Thread Egor Churaev via Phabricator via cfe-commits
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);

[PATCH] D30816: [OpenCL] Added implicit conversion rank for overloading functions with vector data type in OpenCL

2017-03-10 Thread Egor Churaev via Phabricator via cfe-commits
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] D30643: [OpenCL] Extended diagnostics for atomic initialization

2017-03-10 Thread Egor Churaev via Phabricator via cfe-commits
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] D30643: [OpenCL] Extended diagnostics for atomic initialization

2017-03-10 Thread Egor Churaev via Phabricator via cfe-commits
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 

[PATCH] D27334: [OpenCL] Ambiguous function call.

2017-03-09 Thread Egor Churaev via Phabricator via cfe-commits
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

2017-03-06 Thread Egor Churaev via Phabricator via cfe-commits
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 

[PATCH] D27917: [OpenCL] Improve diagnostics for double type

2017-01-26 Thread Egor Churaev via Phabricator via cfe-commits
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] D28136: [OpenCL] Implement as_type operator as alias of __builtin_astype.

2016-12-28 Thread Egor Churaev via Phabricator via cfe-commits
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 

[PATCH] D28048: [OpenCL] Align fake address space map with the SPIR target maps.

2016-12-22 Thread Egor Churaev via Phabricator via cfe-commits
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();
 }
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 = 

[PATCH] D27917: [OpenCL] Improve diagnostics for double type

2016-12-20 Thread Egor Churaev via Phabricator via cfe-commits
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] D27981: Fix problems in "[OpenCL] Enabling the usage of CLK_NULL_QUEUE as compare operand."

2016-12-20 Thread Egor Churaev via Phabricator via cfe-commits
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) {
+  

[PATCH] D27917: [OpenCL] Improve diagnostics for double type

2016-12-19 Thread Egor Churaev via Phabricator via cfe-commits
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] D27569: [OpenCL] Enabling the usage of CLK_NULL_QUEUE as compare operand.

2016-12-18 Thread Egor Churaev via Phabricator via cfe-commits
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 ,
+  InitializationSequence ,
+  QualType DestType,
+  Expr *Initializer) {
+  if (!S.getLangOpts().OpenCL || S.getLangOpts().OpenCLVersion < 200 ||
+  !DestType->isQueueT() ||
+  !Initializer->isIntegerConstantExpr(S.getASTContext()) ||
+  

[PATCH] D27569: [OpenCL] Enabling the usage of CLK_NULL_QUEUE as compare operand.

2016-12-16 Thread Egor Churaev via Phabricator via cfe-commits
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 ,
+  InitializationSequence ,
+  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 ,
const InitializedEntity ,
 

[PATCH] D27569: [OpenCL] Enabling the usage of CLK_NULL_QUEUE as compare operand.

2016-12-14 Thread Egor Churaev via Phabricator via cfe-commits
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 ,
+  InitializationSequence ,
+  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 ,
const InitializedEntity ,
const InitializationKind ,
@@ -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.cpp
+++ 

[PATCH] D27453: [OpenCL] Enable unroll hint for OpenCL 1.x.

2016-12-13 Thread Egor Churaev via Phabricator via cfe-commits
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=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 , Stmt *St, const AttributeList ,
 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 , Stmt *St, const AttributeList ,
 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 

[PATCH] D27671: [OpenCL] Improve address space diagnostics.

2016-12-12 Thread Egor Churaev via Phabricator via cfe-commits
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 

[PATCH] D27569: [OpenCL] Enabling the usage of CLK_NULL_QUEUE as compare operand.

2016-12-08 Thread Egor Churaev via Phabricator via cfe-commits
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] D27453: [OpenCL] Enable unroll hint for OpenCL 1.x.

2016-12-07 Thread Egor Churaev via Phabricator via cfe-commits
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 , Stmt *St, const AttributeList ,
 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 , Stmt *St, const AttributeList ,
 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

[PATCH] D27453: [OpenCL] Enable unroll hint for OpenCL 1.x.

2016-12-06 Thread Egor Churaev via Phabricator via cfe-commits
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] D27403: [OpenCL] Added a LIT test for ensuring address space mangling is done the same both in OpenCL1.2 and OpenCL2.0.

2016-12-06 Thread Egor Churaev via Phabricator via cfe-commits
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] D27403: [OpenCL] Added a LIT test for ensuring address space mangling is done the same both in OpenCL1.2 and OpenCL2.0.

2016-12-05 Thread Egor Churaev via Phabricator via cfe-commits
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] D27300: [OpenCL] Fix SPIR version generation.

2016-12-04 Thread Egor Churaev via Phabricator via cfe-commits
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[] = {
-  

[PATCH] D27334: [OpenCL] Ambiguous function call.

2016-12-02 Thread Egor Churaev via Phabricator via cfe-commits
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 

[PATCH] D27300: [OpenCL] Fix SPIR version generation.

2016-12-02 Thread Egor Churaev via Phabricator via cfe-commits
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] D27300: [OpenCL] Fix SPIR version generation.

2016-12-01 Thread Egor Churaev via Phabricator via cfe-commits
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.

2016-12-01 Thread Egor Churaev via Phabricator via cfe-commits
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] D27099: [OpenCL] Prohibit using reserve_id_t in program scope.

2016-11-28 Thread Egor Churaev via Phabricator via cfe-commits
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() == 

[PATCH] D27099: [OpenCL] Prohibit using reserve_id_t in program scope.

2016-11-27 Thread Egor Churaev via Phabricator via cfe-commits
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.

2016-11-25 Thread Egor Churaev via Phabricator via cfe-commits
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() &&