r347019 - [Clang][Sema]Choose a better candidate in overload function call if there is a compatible vector conversion instead of ambiguous call error

Zi Xuan Wu via cfe-commits cfe-commits at lists.llvm.org
Thu Nov 15 19:00:00 PST 2018


Author: wuzish
Date: Thu Nov 15 19:00:00 2018
New Revision: 347019

URL: http://llvm.org/viewvc/llvm-project?rev=347019&view=rev
Log:
[Clang][Sema]Choose a better candidate in overload function call if there is a compatible vector conversion instead of ambiguous call error

There are 2 function variations with vector type parameter. When we call them with argument of different vector type we would prefer to 
choose the variation with implicit argument conversion of compatible vector type instead of incompatible vector type. For example,

typedef float __v4sf __attribute__((__vector_size__(16)));
void f(vector float);
void f(vector signed int);

int main {
   __v4sf a;
   f(a);
}

Here, we'd like to choose f(vector float) but not report an ambiguous call error.

Differential revision: https://reviews.llvm.org/D53417


Added:
    cfe/trunk/test/Sema/altivec-generic-overload.c
Modified:
    cfe/trunk/lib/Sema/SemaOverload.cpp
    cfe/trunk/test/SemaCXX/vector.cpp

Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=347019&r1=347018&r2=347019&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Thu Nov 15 19:00:00 2018
@@ -3900,6 +3900,31 @@ CompareStandardConversionSequences(Sema
           S.Context.getTypeSize(SCS1.getToType(2)))
     return ImplicitConversionSequence::Better;
 
+  // Prefer a compatible vector conversion over a lax vector conversion
+  // For example:
+  //
+  // typedef float __v4sf __attribute__((__vector_size__(16)));
+  // void f(vector float);
+  // void f(vector signed int);
+  // int main() {
+  //   __v4sf a;
+  //   f(a);
+  // }
+  // Here, we'd like to choose f(vector float) and not
+  // report an ambiguous call error
+  if (SCS1.Second == ICK_Vector_Conversion &&
+      SCS2.Second == ICK_Vector_Conversion) {
+    bool SCS1IsCompatibleVectorConversion = S.Context.areCompatibleVectorTypes(
+        SCS1.getFromType(), SCS1.getToType(2));
+    bool SCS2IsCompatibleVectorConversion = S.Context.areCompatibleVectorTypes(
+        SCS2.getFromType(), SCS2.getToType(2));
+
+    if (SCS1IsCompatibleVectorConversion != SCS2IsCompatibleVectorConversion)
+      return SCS1IsCompatibleVectorConversion
+                 ? ImplicitConversionSequence::Better
+                 : ImplicitConversionSequence::Worse;
+  }
+
   return ImplicitConversionSequence::Indistinguishable;
 }
 

Added: cfe/trunk/test/Sema/altivec-generic-overload.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/altivec-generic-overload.c?rev=347019&view=auto
==============================================================================
--- cfe/trunk/test/Sema/altivec-generic-overload.c (added)
+++ cfe/trunk/test/Sema/altivec-generic-overload.c Thu Nov 15 19:00:00 2018
@@ -0,0 +1,100 @@
+// RUN: %clang_cc1 %s -triple=powerpc64le-unknown-linux -target-feature +altivec -target-feature +vsx -verify -verify-ignore-unexpected=note -pedantic -fsyntax-only
+
+typedef signed char __v16sc __attribute__((__vector_size__(16)));
+typedef unsigned char __v16uc __attribute__((__vector_size__(16)));
+typedef signed short __v8ss __attribute__((__vector_size__(16)));
+typedef unsigned short __v8us __attribute__((__vector_size__(16)));
+typedef signed int __v4si __attribute__((__vector_size__(16)));
+typedef unsigned int __v4ui __attribute__((__vector_size__(16)));
+typedef signed long long __v2sll __attribute__((__vector_size__(16)));
+typedef unsigned long long __v2ull __attribute__((__vector_size__(16)));
+typedef signed __int128 __v1slll __attribute__((__vector_size__(16)));
+typedef unsigned __int128 __v1ulll __attribute__((__vector_size__(16)));
+typedef float __v4f __attribute__((__vector_size__(16)));
+typedef double __v2d __attribute__((__vector_size__(16)));
+
+__v16sc *__attribute__((__overloadable__)) convert1(vector signed char);
+__v16uc *__attribute__((__overloadable__)) convert1(vector unsigned char);
+__v8ss *__attribute__((__overloadable__)) convert1(vector signed short);
+__v8us *__attribute__((__overloadable__)) convert1(vector unsigned short);
+__v4si *__attribute__((__overloadable__)) convert1(vector signed int);
+__v4ui *__attribute__((__overloadable__)) convert1(vector unsigned int);
+__v2sll *__attribute__((__overloadable__)) convert1(vector signed long long);
+__v2ull *__attribute__((__overloadable__)) convert1(vector unsigned long long);
+__v1slll *__attribute__((__overloadable__)) convert1(vector signed __int128);
+__v1ulll *__attribute__((__overloadable__)) convert1(vector unsigned __int128);
+__v4f *__attribute__((__overloadable__)) convert1(vector float);
+__v2d *__attribute__((__overloadable__)) convert1(vector double);
+void __attribute__((__overloadable__)) convert1(vector bool int);
+void __attribute__((__overloadable__)) convert1(vector pixel short);
+
+vector signed char *__attribute__((__overloadable__)) convert2(__v16sc);
+vector unsigned char *__attribute__((__overloadable__)) convert2(__v16uc);
+vector signed short *__attribute__((__overloadable__)) convert2(__v8ss);
+vector unsigned short *__attribute__((__overloadable__)) convert2(__v8us);
+vector signed int *__attribute__((__overloadable__)) convert2(__v4si);
+vector unsigned int *__attribute__((__overloadable__)) convert2(__v4ui);
+vector signed long long *__attribute__((__overloadable__)) convert2(__v2sll);
+vector unsigned long long *__attribute__((__overloadable__)) convert2(__v2ull);
+vector signed __int128 *__attribute__((__overloadable__)) convert2(__v1slll);
+vector unsigned __int128 *__attribute__((__overloadable__)) convert2(__v1ulll);
+vector float *__attribute__((__overloadable__)) convert2(__v4f);
+vector double *__attribute__((__overloadable__)) convert2(__v2d);
+
+void test() {
+  __v16sc gv1;
+  __v16uc gv2;
+  __v8ss gv3;
+  __v8us gv4;
+  __v4si gv5;
+  __v4ui gv6;
+  __v2sll gv7;
+  __v2ull gv8;
+  __v1slll gv9;
+  __v1ulll gv10;
+  __v4f gv11;
+  __v2d gv12;
+
+  vector signed char av1;
+  vector unsigned char av2;
+  vector signed short av3;
+  vector unsigned short av4;
+  vector signed int av5;
+  vector unsigned int av6;
+  vector signed long long av7;
+  vector unsigned long long av8;
+  vector signed __int128 av9;
+  vector unsigned __int128 av10;
+  vector float av11;
+  vector double av12;
+  vector bool int av13;
+  vector pixel short av14;
+
+  __v16sc *gv1_p = convert1(gv1);
+  __v16uc *gv2_p = convert1(gv2);
+  __v8ss *gv3_p = convert1(gv3);
+  __v8us *gv4_p = convert1(gv4);
+  __v4si *gv5_p = convert1(gv5);
+  __v4ui *gv6_p = convert1(gv6);
+  __v2sll *gv7_p = convert1(gv7);
+  __v2ull *gv8_p = convert1(gv8);
+  __v1slll *gv9_p = convert1(gv9);
+  __v1ulll *gv10_p = convert1(gv10);
+  __v4f *gv11_p = convert1(gv11);
+  __v2d *gv12_p = convert1(gv12);
+
+  vector signed char *av1_p = convert2(av1);
+  vector unsigned char *av2_p = convert2(av2);
+  vector signed short *av3_p = convert2(av3);
+  vector unsigned short *av4_p = convert2(av4);
+  vector signed int *av5_p = convert2(av5);
+  vector unsigned int *av6_p = convert2(av6);
+  vector signed long long *av7_p = convert2(av7);
+  vector unsigned long long *av8_p = convert2(av8);
+  vector signed __int128 *av9_p = convert2(av9);
+  vector unsigned __int128 *av10_p = convert2(av10);
+  vector float *av11_p = convert2(av11);
+  vector double *av12_p = convert2(av12);
+  convert2(av13); // expected-error {{call to 'convert2' is ambiguous}}
+  convert2(av14); // expected-error {{call to 'convert2' is ambiguous}}
+}

Modified: cfe/trunk/test/SemaCXX/vector.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/vector.cpp?rev=347019&r1=347018&r2=347019&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/vector.cpp (original)
+++ cfe/trunk/test/SemaCXX/vector.cpp Thu Nov 15 19:00:00 2018
@@ -17,14 +17,14 @@ void f0_test(char16 c16, longlong16 ll16
   f0(ll16e);
 }
 
-int &f1(char16); // expected-note 2{{candidate function}}
-float &f1(longlong16); // expected-note 2{{candidate function}}
+int &f1(char16);
+float &f1(longlong16);
 
 void f1_test(char16 c16, longlong16 ll16, char16_e c16e, longlong16_e ll16e) {
   int &ir1 = f1(c16);
   float &fr1 = f1(ll16);
-  f1(c16e); // expected-error{{call to 'f1' is ambiguous}}
-  f1(ll16e); // expected-error{{call to 'f1' is ambiguous}}
+  int &ir2 = f1(c16e);
+  float &fr2 = f1(ll16e);
 }
 
 void f2(char16_e); // expected-note{{no known conversion from 'longlong16_e' (vector of 2 'long long' values) to 'char16_e' (vector of 16 'char' values) for 1st argument}} \




More information about the cfe-commits mailing list