wuzish updated this revision to Diff 170871.
wuzish marked 2 inline comments as done.
wuzish added a comment.

Updated the diff.

fix some points from comments.


https://reviews.llvm.org/D53417

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

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/lib/Sema/SemaOverload.cpp
===================================================================
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -3900,6 +3900,56 @@
           S.Context.getTypeSize(SCS1.getToType(2)))
     return ImplicitConversionSequence::Better;
 
+  // For now only conversions with altivec-related kind and generic kind
+  // prefer to choose a compatible vector conversion
+  // FIXME: Can remove this constraint and extend to other vector kind?
+  auto IsPreferCompatibleConversionVectorKind =
+      [&S](const StandardConversionSequence &SCS1,
+           const StandardConversionSequence &SCS2) {
+        QualType Types[] = {SCS1.getFromType(), SCS1.getToType(2),
+                            SCS2.getFromType(), SCS2.getToType(2)};
+
+        for (auto Type : Types) {
+          if (S.Context.getCanonicalType(Type)->getTypeClass() != Type::Vector)
+            return false;
+          VectorType::VectorKind Kind =
+              Type->castAs<VectorType>()->getVectorKind();
+          if (Kind != VectorType::AltiVecVector &&
+              Kind != VectorType::AltiVecPixel &&
+              Kind != VectorType::AltiVecBool &&
+              Kind != VectorType::GenericVector)
+            return false;
+        }
+
+        return true;
+      };
+
+  // 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 &&
+      IsPreferCompatibleConversionVectorKind(SCS1, SCS2)) {
+    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