summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEgor Churaev <egor.churaev@gmail.com>2017-03-21 12:55:55 +0000
committerEgor Churaev <egor.churaev@gmail.com>2017-03-21 12:55:55 +0000
commit40cf0c36256645a229357c029ef83f6a324c818b (patch)
tree87440dbacc986ec61e9714c3d33e0a19b083a9ba
parent62fafdbf9ce3f19b233a72f64d5523491d9a7d6c (diff)
[OpenCL] Added implicit conversion rank for overloading functions with vector data type in OpenCL
Summary: 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. Reviewers: Anastasia, cfe-commits Reviewed By: Anastasia Subscribers: bader, yaxunl Differential Revision: https://reviews.llvm.org/D30816 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@298366 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Sema/Overload.h1
-rw-r--r--lib/Sema/SemaOverload.cpp2
-rw-r--r--test/CodeGenOpenCL/overload.cl46
-rw-r--r--test/SemaOpenCL/overload_addrspace_resolution.cl29
4 files changed, 48 insertions, 30 deletions
diff --git a/include/clang/Sema/Overload.h b/include/clang/Sema/Overload.h
index 5220d98730..941b772b78 100644
--- a/include/clang/Sema/Overload.h
+++ b/include/clang/Sema/Overload.h
@@ -98,6 +98,7 @@ namespace clang {
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.
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 8b53258803..7f94bf26d8 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -131,7 +131,7 @@ ImplicitConversionRank clang::GetConversionRank(ImplicitConversionKind Kind) {
ICR_Conversion,
ICR_Conversion,
ICR_Conversion,
- ICR_Conversion,
+ ICR_OCL_Scalar_Widening,
ICR_Complex_Real_Conversion,
ICR_Conversion,
ICR_Conversion,
diff --git a/test/CodeGenOpenCL/overload.cl b/test/CodeGenOpenCL/overload.cl
new file mode 100644
index 0000000000..f182cb5fd2
--- /dev/null
+++ b/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);
+}
diff --git a/test/SemaOpenCL/overload_addrspace_resolution.cl b/test/SemaOpenCL/overload_addrspace_resolution.cl
deleted file mode 100644
index c7cf5fcb8d..0000000000
--- a/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);
-}