wuzish updated this revision to Diff 173276.
wuzish added a comment.

Extend the scope to all vector type as one comment suggested.

> a conversion sequence that bitcasts a vector should be ranked worse than one 
> that does not, regardless of the kind of vector in use.

Which is also made code clearly and consistently, the effect is to update some 
tests expected behavior.


https://reviews.llvm.org/D53417

Files:
  clang/lib/Sema/SemaOverload.cpp
  clang/test/CodeGen/altivec-generic-overload.c
  clang/test/Sema/altivec-generic-overload.c
  clang/test/SemaCXX/vector.cpp

Index: clang/test/SemaCXX/vector.cpp
===================================================================
--- clang/test/SemaCXX/vector.cpp
+++ clang/test/SemaCXX/vector.cpp
@@ -17,14 +17,14 @@
   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}}
+  f1(c16e);
+  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}} \
Index: clang/test/Sema/altivec-generic-overload.c
===================================================================
--- /dev/null
+++ clang/test/Sema/altivec-generic-overload.c
@@ -0,0 +1,101 @@
+// 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)));
+
+void __attribute__((__overloadable__)) convert1(vector signed char);
+void __attribute__((__overloadable__)) convert1(vector unsigned char);
+void __attribute__((__overloadable__)) convert1(vector signed short);
+void __attribute__((__overloadable__)) convert1(vector unsigned short);
+void __attribute__((__overloadable__)) convert1(vector signed int);
+void __attribute__((__overloadable__)) convert1(vector unsigned int);
+void __attribute__((__overloadable__)) convert1(vector signed long long);
+void __attribute__((__overloadable__)) convert1(vector unsigned long long);
+void __attribute__((__overloadable__)) convert1(vector signed __int128);
+void __attribute__((__overloadable__)) convert1(vector unsigned __int128);
+void __attribute__((__overloadable__)) convert1(vector float);
+void __attribute__((__overloadable__)) convert1(vector double);
+void __attribute__((__overloadable__)) convert1(vector bool int);
+void __attribute__((__overloadable__)) convert1(vector pixel short);
+void __attribute__((__overloadable__)) convert2(__v16sc);
+void __attribute__((__overloadable__)) convert2(__v16uc);
+void __attribute__((__overloadable__)) convert2(__v8ss);
+void __attribute__((__overloadable__)) convert2(__v8us);
+void __attribute__((__overloadable__)) convert2(__v4si);
+void __attribute__((__overloadable__)) convert2(__v4ui);
+void __attribute__((__overloadable__)) convert2(__v2sll);
+void __attribute__((__overloadable__)) convert2(__v2ull);
+void __attribute__((__overloadable__)) convert2(__v1slll);
+void __attribute__((__overloadable__)) convert2(__v1ulll);
+void __attribute__((__overloadable__)) convert2(__v4f);
+void __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;
+
+  convert1(gv1);
+  convert1(gv2);
+  convert1(gv3);
+  convert1(gv4);
+  convert1(gv5);
+  convert1(gv6);
+  convert1(gv7);
+  convert1(gv8);
+  convert1(gv9);
+  convert1(gv10);
+  convert1(gv11);
+  convert1(gv12);
+
+  convert2(av1);
+  convert2(av2);
+  convert2(av3);
+  convert2(av4);
+  convert2(av5);
+  convert2(av6);
+  convert2(av7);
+  convert2(av8);
+  convert2(av9);
+  convert2(av10);
+  convert2(av11);
+  convert2(av12);
+  convert2(av13); // expected-error {{call to 'convert2' is ambiguous}}
+  convert2(av14); // expected-error {{call to 'convert2' is ambiguous}}
+
+}
Index: clang/test/CodeGen/altivec-generic-overload.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/altivec-generic-overload.c
@@ -0,0 +1,122 @@
+// RUN: %clang_cc1 %s -triple=powerpc64le-unknown-linux -target-feature +altivec -target-feature +vsx -S -emit-llvm -o - | FileCheck %s --check-prefix=CHECK
+
+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)));
+
+void __attribute__((__overloadable__)) convert1(vector signed char);
+void __attribute__((__overloadable__)) convert1(vector unsigned char);
+void __attribute__((__overloadable__)) convert1(vector signed short);
+void __attribute__((__overloadable__)) convert1(vector unsigned short);
+void __attribute__((__overloadable__)) convert1(vector signed int);
+void __attribute__((__overloadable__)) convert1(vector unsigned int);
+void __attribute__((__overloadable__)) convert1(vector signed long long);
+void __attribute__((__overloadable__)) convert1(vector unsigned long long);
+void __attribute__((__overloadable__)) convert1(vector signed __int128);
+void __attribute__((__overloadable__)) convert1(vector unsigned __int128);
+void __attribute__((__overloadable__)) convert1(vector float);
+void __attribute__((__overloadable__)) convert1(vector double);
+void __attribute__((__overloadable__)) convert1(vector bool int);
+void __attribute__((__overloadable__)) convert1(vector pixel short);
+void __attribute__((__overloadable__)) convert2(__v16sc);
+void __attribute__((__overloadable__)) convert2(__v16uc);
+void __attribute__((__overloadable__)) convert2(__v8ss);
+void __attribute__((__overloadable__)) convert2(__v8us);
+void __attribute__((__overloadable__)) convert2(__v4si);
+void __attribute__((__overloadable__)) convert2(__v4ui);
+void __attribute__((__overloadable__)) convert2(__v2sll);
+void __attribute__((__overloadable__)) convert2(__v2ull);
+void __attribute__((__overloadable__)) convert2(__v1slll);
+void __attribute__((__overloadable__)) convert2(__v1ulll);
+void __attribute__((__overloadable__)) convert2(__v4f);
+void __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;
+
+  convert1(gv1);
+  // CHECK: call void @_Z8convert1Dv16_a(<16 x i8> %{{[0-9]+}})
+  convert1(gv2);
+  // CHECK: call void @_Z8convert1Dv16_h(<16 x i8> %{{[0-9]+}})
+  convert1(gv3);
+  // CHECK: call void @_Z8convert1Dv8_s(<8 x i16> %{{[0-9]+}})
+  convert1(gv4);
+  // CHECK: call void @_Z8convert1Dv8_t(<8 x i16> %{{[0-9]+}})
+  convert1(gv5);
+  // CHECK: call void @_Z8convert1Dv4_i(<4 x i32> %{{[0-9]+}})
+  convert1(gv6);
+  // CHECK: call void @_Z8convert1Dv4_j(<4 x i32> %{{[0-9]+}})
+  convert1(gv7);
+  // CHECK: call void @_Z8convert1Dv2_x(<2 x i64> %{{[0-9]+}})
+  convert1(gv8);
+  // CHECK: call void @_Z8convert1Dv2_y(<2 x i64> %{{[0-9]+}})
+  convert1(gv9);
+  // CHECK: call void @_Z8convert1Dv1_n(<1 x i128> %{{[0-9]+}})
+  convert1(gv10);
+  // CHECK: call void @_Z8convert1Dv1_o(<1 x i128> %{{[0-9]+}})
+  convert1(gv11);
+  // CHECK: call void @_Z8convert1Dv4_f(<4 x float> %{{[0-9]+}})
+  convert1(gv12);
+  // CHECK: call void @_Z8convert1Dv2_d(<2 x double> %{{[0-9]+}})
+
+  convert2(av1);
+  // CHECK: call void @_Z8convert2Dv16_a(<16 x i8> %{{[0-9]+}})
+  convert2(av2);
+  // CHECK: call void @_Z8convert2Dv16_h(<16 x i8> %{{[0-9]+}})
+  convert2(av3);
+  // CHECK: call void @_Z8convert2Dv8_s(<8 x i16> %{{[0-9]+}})
+  convert2(av4);
+  // CHECK: call void @_Z8convert2Dv8_t(<8 x i16> %{{[0-9]+}})
+  convert2(av5);
+  // CHECK: call void @_Z8convert2Dv4_i(<4 x i32> %{{[0-9]+}})
+  convert2(av6);
+  // CHECK: call void @_Z8convert2Dv4_j(<4 x i32> %{{[0-9]+}})
+  convert2(av7);
+  // CHECK: call void @_Z8convert2Dv2_x(<2 x i64> %{{[0-9]+}})
+  convert2(av8);
+  // CHECK: call void @_Z8convert2Dv2_y(<2 x i64> %{{[0-9]+}})
+  convert2(av9);
+  // CHECK: call void @_Z8convert2Dv1_n(<1 x i128> %{{[0-9]+}})
+  convert2(av10);
+  // CHECK: call void @_Z8convert2Dv1_o(<1 x i128> %{{[0-9]+}})
+  convert2(av11);
+  // CHECK: call void @_Z8convert2Dv4_f(<4 x float> %{{[0-9]+}})
+  convert2(av12);
+  // CHECK: call void @_Z8convert2Dv2_d(<2 x double> %{{[0-9]+}})
+}
Index: clang/lib/Sema/SemaOverload.cpp
===================================================================
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -3900,6 +3900,31 @@
           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;
 }
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to