[clang] db210bc - [Matrix] Implement C-style explicit type conversions in CXX for matrix types

Florian Hahn via cfe-commits cfe-commits at lists.llvm.org
Tue May 4 07:28:19 PDT 2021


Author: Saurabh Jha
Date: 2021-05-04T15:27:57+01:00
New Revision: db210bc69bb50979fb843b68fcb71a9c905e971b

URL: https://github.com/llvm/llvm-project/commit/db210bc69bb50979fb843b68fcb71a9c905e971b
DIFF: https://github.com/llvm/llvm-project/commit/db210bc69bb50979fb843b68fcb71a9c905e971b.diff

LOG: [Matrix] Implement C-style explicit type conversions in CXX for matrix types

This patch implements C-style explicit type conversions in CXX for matrix types. It is part of fixing https://bugs.llvm.org/show_bug.cgi?id=47141

Reviewed By: fhahn

Differential Revision: https://reviews.llvm.org/D101696

Added: 
    clang/test/CodeGenCXX/matrix-casts.cpp

Modified: 
    clang/lib/Sema/SemaCast.cpp
    clang/test/SemaCXX/matrix-casts.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp
index d347975e1341b..8a9ee1a309941 100644
--- a/clang/lib/Sema/SemaCast.cpp
+++ b/clang/lib/Sema/SemaCast.cpp
@@ -2648,6 +2648,13 @@ void CastOperation::CheckCXXCStyleCast(bool FunctionalStyle,
       return;
   }
 
+  if (DestType->getAs<MatrixType>() ||
+      SrcExpr.get()->getType()->getAs<MatrixType>()) {
+    if (Self.CheckMatrixCast(OpRange, DestType, SrcExpr.get()->getType(), Kind))
+      SrcExpr = ExprError();
+    return;
+  }
+
   // AltiVec vector initialization with a single literal.
   if (const VectorType *vecTy = DestType->getAs<VectorType>())
     if (vecTy->getVectorKind() == VectorType::AltiVecVector

diff  --git a/clang/test/CodeGenCXX/matrix-casts.cpp b/clang/test/CodeGenCXX/matrix-casts.cpp
new file mode 100644
index 0000000000000..26fd77fd26f60
--- /dev/null
+++ b/clang/test/CodeGenCXX/matrix-casts.cpp
@@ -0,0 +1,175 @@
+// RUN: %clang_cc1 -std=c++11 -fenable-matrix -triple x86_64-apple-darwin %s -emit-llvm -disable-llvm-passes -o - | FileCheck %s
+
+template <typename X>
+using matrix_4_4 = X __attribute__((matrix_type(4, 4)));
+
+template <typename Y>
+using matrix_5_5 = Y __attribute__((matrix_type(5, 5)));
+
+// CHECK-LABEL: define{{.*}} void @_Z19CastCharMatrixToIntv
+void CastCharMatrixToInt() {
+  // CHECK: [[C:%.*]] = load <25 x i8>, <25 x i8>* {{.*}}, align 1
+  // CHECK-NEXT: [[CONV:%.*]] = sext <25 x i8> [[C]] to <25 x i32>
+  // CHECK-NEXT: [[CONV1:%.*]] = bitcast [25 x i32]* {{.*}} to <25 x i32>*
+  // CHECK-NEXT: store <25 x i32> [[CONV]], <25 x i32>* [[CONV1]], align 4
+
+  matrix_5_5<char> c;
+  matrix_5_5<int> i;
+  i = (matrix_5_5<int>)c;
+}
+
+// CHECK-LABEL: define{{.*}} void @_Z27CastCharMatrixToUnsignedIntv
+void CastCharMatrixToUnsignedInt() {
+  // CHECK:       [[C:%.*]] = load <25 x i8>, <25 x i8>* {{.*}}, align 1
+  // CHECK-NEXT:  [[CONV:%.*]] = sext <25 x i8> [[C]] to <25 x i32>
+  // CHECK-NEXT:  [[CONV1:%.*]] = bitcast [25 x i32]* {{.*}} to <25 x i32>*
+  // CHECK-NEXT:  store <25 x i32> [[CONV]], <25 x i32>* [[CONV1]], align 4
+  // CHECK-NEXT:  ret void
+
+  matrix_5_5<char> c;
+  matrix_5_5<unsigned int> u;
+  u = (matrix_5_5<unsigned int>)c;
+}
+
+// CHECK-LABEL: define{{.*}} void @_Z32CastUnsignedLongIntMatrixToShortv
+void CastUnsignedLongIntMatrixToShort() {
+  // CHECK:      [[U:%.*]] = load <25 x i64>, <25 x i64>* {{.*}}, align 8
+  // CHECK-NEXT: [[CONV:%.*]] = trunc <25 x i64> {{.*}} to <25 x i16>
+  // CHECK-NEXT: [[CONV1:%.*]] = bitcast [25 x i16]* {{.*}} to <25 x i16>*
+  // CHECK-NEXT: store <25 x i16> [[CONV]], <25 x i16>* [[CONV1]], align 2
+  // CHECK-NEXT: ret void
+
+  matrix_5_5<unsigned long int> u;
+  matrix_5_5<short int> s;
+  s = (matrix_5_5<short int>)u;
+}
+
+// CHECK-LABEL: define{{.*}} void @_Z20CastIntMatrixToShortv()
+void CastIntMatrixToShort() {
+  // CHECK:       [[I:%.*]] = load <25 x i32>, <25 x i32>* {{.*}}, align 4
+  // CHECK-NEXT:  [[CONV:%.*]] = trunc <25 x i32> [[I]] to <25 x i16>
+  // CHECK-NEXT:  [[CONV1:%.*]] = bitcast [25 x i16]* {{.*}} to <25 x i16>*
+  // CHECK-NEXT:  store <25 x i16> [[CONV]], <25 x i16>* [[CONV1]], align 2
+  // CHECK-NEXT:  ret void
+
+  matrix_5_5<int> i;
+  matrix_5_5<short int> s;
+  s = (matrix_5_5<short int>)i;
+}
+
+// CHECK-LABEL: define{{.*}} void @_Z20CastIntMatrixToFloatv()
+void CastIntMatrixToFloat() {
+  // CHECK:       [[I:%.*]] = load <25 x i32>, <25 x i32>* {{.*}}, align 4
+  // CHECK-NEXT:  [[CONV]] = sitofp <25 x i32> {{.*}} to <25 x float>
+  // CHECK-NEXT:  [[CONV1]] = bitcast [25 x float]* {{.*}} to <25 x float>*
+  // CHECK-NEXT:  store <25 x float> [[CONV]], <25 x float>* [[CONV1]], align 4
+  // CHECK-NEXT:  ret void
+
+  matrix_5_5<int> i;
+  matrix_5_5<float> f;
+  f = (matrix_5_5<float>)i;
+}
+
+// CHECK-LABEL: define{{.*}} void @_Z28CastUnsignedIntMatrixToFloatv()
+void CastUnsignedIntMatrixToFloat() {
+  // CHECK:       [[U:%.*]] = load <25 x i16>, <25 x i16>* {{.*}}, align 2
+  // CHECK-NEXT:  [[CONV:%.*]] = uitofp <25 x i16> [[U]] to <25 x float>
+  // CHECK-NEXT:  [[CONV1:%.*]] = bitcast [25 x float]* {{.*}} to <25 x float>*
+  // CHECK-NEXT:  store <25 x float> [[CONV]], <25 x float>* {{.*}}, align 4
+  // CHECK-NEXT:  ret void
+
+  matrix_5_5<unsigned short int> u;
+  matrix_5_5<float> f;
+  f = (matrix_5_5<float>)u;
+}
+
+// CHECK-LABEL: define{{.*}} void @_Z21CastDoubleMatrixToIntv()
+void CastDoubleMatrixToInt() {
+  // CHECK:       [[D:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 8
+  // CHECK-NEXT:  [[CONV:%.*]] = fptosi <25 x double> [[D]] to <25 x i32>
+  // CHECK-NEXT:  [[CONV1:%.*]] = bitcast [25 x i32]* %i to <25 x i32>*
+  // CHECK-NEXT:  store <25 x i32> [[CONV]], <25 x i32>* {{.*}}, align 4
+  // CHECK-NEXT:  ret void
+
+  matrix_5_5<double> d;
+  matrix_5_5<int> i;
+  i = (matrix_5_5<int>)d;
+}
+
+// CHECK-LABEL: define{{.*}} void @_Z33CastFloatMatrixToUnsignedShortIntv()
+void CastFloatMatrixToUnsignedShortInt() {
+  // CHECK:       [[F:%.*]] = load <25 x float>, <25 x float>* {{.*}}, align 4
+  // CHECK-NEXT:  [[CONV:%.*]] = fptoui <25 x float> [[F]] to <25 x i16>
+  // CHECK-NEXT:  [[CONV1:%.*]] = bitcast [25 x i16]* {{.*}} to <25 x i16>*
+  // CHECK-NEXT:  store <25 x i16> [[CONV]], <25 x i16>* [[CONV1]], align 2
+  // CHECK-NEXT:  ret void
+
+  matrix_5_5<float> f;
+  matrix_5_5<unsigned short int> i;
+  i = (matrix_5_5<unsigned short int>)f;
+}
+
+// CHECK-LABEL: define{{.*}} void @_Z23CastDoubleMatrixToFloatv()
+void CastDoubleMatrixToFloat() {
+  // CHECK:       [[D:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 8
+  // CHECK-NEXT:  [[CONV:%.*]] = fptrunc <25 x double> [[D]] to <25 x float>
+  // CHECK-NEXT:  [[CONV1:%.*]] = bitcast [25 x float]* {{.*}} to <25 x float>*
+  // CHECK-NEXT:  store <25 x float> [[CONV]], <25 x float>* [[CONV1]], align 4
+  // CHECK-NEXT:  ret void
+
+  matrix_5_5<double> d;
+  matrix_5_5<float> f;
+  f = (matrix_5_5<float>)d;
+}
+
+// CHECK-LABEL: define{{.*}} void @_Z33CastUnsignedShortIntToUnsignedIntv()
+void CastUnsignedShortIntToUnsignedInt() {
+  // CHECK:       [[S:%.*]] = load <25 x i16>, <25 x i16>* {{.*}}, align 2
+  // CHECK-NEXT:  [[CONV:%.*]] = zext <25 x i16> [[S]] to <25 x i32>
+  // CHECK-NEXT:  [[CONV1:%.*]] = bitcast [25 x i32]* {{.*}} to <25 x i32>*
+  // CHECK-NEXT:  store <25 x i32> [[CONV]], <25 x i32>* [[CONV1]], align 4
+  // CHECK-NEXT:  ret void
+
+  matrix_5_5<unsigned short int> s;
+  matrix_5_5<unsigned int> i;
+  i = (matrix_5_5<unsigned int>)s;
+}
+
+// CHECK-LABEL: define{{.*}} void @_Z37CastUnsignedLongIntToUnsignedShortIntv()
+void CastUnsignedLongIntToUnsignedShortInt() {
+  // CHECK:       [[L:%.*]] = load <25 x i64>, <25 x i64>* %0, align 8
+  // CHECK-NEXT:  [[CONV:%.*]] = trunc <25 x i64> [[L]] to <25 x i16>
+  // CHECK-NEXT:  [[CONV1:%.*]] = bitcast [25 x i16]* {{.*}} to <25 x i16>*
+  // CHECK-NEXT:  store <25 x i16> [[CONV]], <25 x i16>* [[CONV1]], align 2
+  // CHECK-NEXT:  ret void
+
+  matrix_5_5<unsigned long int> l;
+  matrix_5_5<unsigned short int> s;
+  s = (matrix_5_5<unsigned short int>)l;
+}
+
+// CHECK-LABEL: define{{.*}} void @_Z25CastUnsignedShortIntToIntv()
+void CastUnsignedShortIntToInt() {
+  // CHECK:       [[U:%.*]] = load <25 x i16>, <25 x i16>* %0, align 2
+  // CHECK-NEXT:  [[CONV:%.*]] = zext <25 x i16> [[U]] to <25 x i32>
+  // CHECK-NEXT:  [[CONV1:%.*]] = bitcast [25 x i32]* {{.*}} to <25 x i32>*
+  // CHECK-NEXT:  store <25 x i32> [[CONV]], <25 x i32>* {{.*}}, align 4
+  // CHECK-NEXT:  ret void
+
+  matrix_5_5<unsigned short int> u;
+  matrix_5_5<int> i;
+  i = (matrix_5_5<int>)u;
+}
+
+// CHECK-LABEL: define{{.*}} void @_Z24CastIntToUnsignedLongIntv()
+void CastIntToUnsignedLongInt() {
+  // CHECK:       [[I:%.*]] = load <25 x i32>, <25 x i32>* %0, align 4
+  // CHECK-NEXT:  [[CONV:%.*]] = sext <25 x i32> [[I]] to <25 x i64>
+  // CHECK-NEXT:  [[CONV1:%.*]] = bitcast [25 x i64]* {{.*}} to <25 x i64>*
+  // CHECK-NEXT:  store <25 x i64> [[CONV]], <25 x i64>* {{.*}}, align 8
+  // CHECK-NEXT:  ret void
+
+  matrix_5_5<int> i;
+  matrix_5_5<unsigned long int> u;
+  u = (matrix_5_5<unsigned long int>)i;
+}

diff  --git a/clang/test/SemaCXX/matrix-casts.cpp b/clang/test/SemaCXX/matrix-casts.cpp
index bb03f3ab8d239..5593f269a4202 100644
--- a/clang/test/SemaCXX/matrix-casts.cpp
+++ b/clang/test/SemaCXX/matrix-casts.cpp
@@ -14,7 +14,6 @@ typedef struct test_struct {
 typedef int vec __attribute__((vector_size(4)));
 
 void f1() {
-  // TODO: Update this test once the support of C-style casts for C++ is implemented.
   matrix_4_4<char> m1;
   matrix_4_4<int> m2;
   matrix_4_4<short> m3;
@@ -23,45 +22,46 @@ void f1() {
   vec v;
   test_struct *s;
 
-  (matrix_4_4<int>)m1;   // expected-error {{C-style cast from 'matrix_4_4<char>' (aka 'char __attribute__((matrix_type(4, \
-4)))') to 'matrix_4_4<int>' (aka 'int __attribute__((matrix_type(4, 4)))') is not allowed}}
-  (matrix_4_4<short>)m2; // expected-error {{C-style cast from 'matrix_4_4<int>' (aka 'int __attribute__((matrix_type(4, \
-4)))') to 'matrix_4_4<short>' (aka 'short __attribute__((matrix_type(4, 4)))') is not allowed}}
-  (matrix_5_5<int>)m3;   // expected-error {{C-style cast from 'matrix_4_4<short>' (aka 'short __attribute__((matrix_type(4, \
-4)))') to 'matrix_5_5<int>' (aka 'int __attribute__((matrix_type(5, 5)))') is not allowed}}
+  m2 = (matrix_4_4<int>)m1;
+  m2 = m1; // expected-error {{assigning to 'matrix_4_4<int>' from incompatible type 'matrix_4_4<char>'}}
+  m3 = (matrix_4_4<short>)m2;
+  (matrix_5_5<int>)m3; // expected-error {{conversion between matrix types 'matrix_5_5<int>' (aka 'int __attribute__\
+((matrix_type(5, 5)))') and 'matrix_4_4<short>' (aka 'short __attribute__((matrix_type(4, 4)))') of 
diff erent size is not\
+ allowed}}
 
-  (int)m3;            // expected-error {{C-style cast from 'matrix_4_4<short>' (aka 'short __attribute__((matrix_type(4, \
-4)))') to 'int'}}
-  (matrix_4_4<int>)i; // expected-error {{C-style cast from 'int' to 'matrix_4_4<int>' (aka 'int __attribute__((\
-matrix_type(4, 4)))') is not allowed}}
+  (int)m3;            // expected-error {{conversion between matrix type 'matrix_4_4<short>' (aka 'short __attribute__\
+((matrix_type(4, 4)))') and incompatible type 'int' is not allowed}}
+  (matrix_4_4<int>)i; // expected-error {{conversion between matrix type 'matrix_4_4<int>' (aka 'int __attribute__\
+((matrix_type(4, 4)))') and incompatible type 'int' is not allowed}}
 
-  (vec) m2;            // expected-error {{C-style cast from 'matrix_4_4<int>' (aka 'int __attribute__((matrix_type(4, 4)))') \
-to 'vec' (vector of 1 'int' value) is not allowed}}
-  (matrix_4_4<char>)v; // expected-error {{C-style cast from 'vec' (vector of 1 'int' value) to 'matrix_4_4<char>' \
-(aka 'char __attribute__((matrix_type(4, 4)))') is not allowed}}
+  (vec) m2;            // expected-error {{conversion between matrix type 'matrix_4_4<int>' (aka 'int __attribute__\
+((matrix_type(4, 4)))') and incompatible type 'vec' (vector of 1 'int' value) is not allowed}}
+  (matrix_4_4<char>)v; // expected-error {{conversion between matrix type 'matrix_4_4<char>' (aka 'char __attribute__\
+((matrix_type(4, 4)))') and incompatible type 'vec' (vector of 1 'int' value) is not allowed}}
 
-  (test_struct *)m1;    // expected-error {{cannot cast from type 'matrix_4_4<char>' (aka 'char __attribute__\
-((matrix_type(4, 4)))') to pointer type 'test_struct *}}'
-  (matrix_5_5<float>)s; // expected-error {{C-style cast from 'test_struct *' to 'matrix_5_5<float>' (aka 'float __attribute__\
-((matrix_type(5, 5)))') is not allowed}}'
+  (test_struct *)m1;    // expected-error {{conversion between matrix type 'matrix_4_4<char>' (aka 'char __attribute__\
+((matrix_type(4, 4)))') and incompatible type 'test_struct *' is not allowed}}'
+  (matrix_5_5<float>)s; // expected-error {{conversion between matrix type 'matrix_5_5<float>' (aka 'float __attribute__\
+((matrix_type(5, 5)))') and incompatible type 'test_struct *' is not allowed}}'
 }
 
 void f2() {
-  // TODO: Update this test once the support of C-style casts for C++ is implemented.
   matrix_4_4<float> m1;
-  matrix_5_5<double> m2;
-  matrix_5_5<signed int> m3;
-  matrix_4_4<unsigned int> m4;
+  matrix_4_4<double> m2;
+  matrix_5_5<double> m3;
+  matrix_5_5<signed int> m4;
+  matrix_4_4<unsigned int> m5;
+  matrix_5_5<unsigned int> m6;
   float f;
 
-  (matrix_4_4<double>)m1;       // expected-error {{C-style cast from 'matrix_4_4<float>' (aka 'float __attribute__\
-((matrix_type(4, 4)))') to 'matrix_4_4<double>' (aka 'double __attribute__((matrix_type(4, 4)))') is not allowed}}
-  (matrix_5_5<float>)m2;        // expected-error {{C-style cast from 'matrix_5_5<double>' (aka 'double __attribute__\
-((matrix_type(5, 5)))') to 'matrix_5_5<float>' (aka 'float __attribute__((matrix_type(5, 5)))') is not allowed}}
-  (matrix_5_5<unsigned int>)m3; // expected-error {{C-style cast from 'matrix_5_5<int>' (aka 'int __attribute__\
-((matrix_type(5, 5)))') to 'matrix_5_5<unsigned int>' (aka 'unsigned int __attribute__((matrix_type(5, 5)))') \
-is not allowed}}
-  (matrix_4_4<int>)m4;          // expected-error {{C-style cast from 'matrix_4_4<unsigned int>' (aka 'unsigned int \
-__attribute__((matrix_type(4, 4)))') to 'matrix_4_4<int>' (aka 'int __attribute__((matrix_type(4, 4)))') is not \
-allowed}}
+  m2 = (matrix_4_4<double>)m1;
+  (matrix_5_5<double>)m1; // expected-error {{conversion between matrix types 'matrix_5_5<double>' (aka 'double __\
+attribute__((matrix_type(5, 5)))') and 'matrix_4_4<float>' (aka 'float __attribute__((matrix_type(4, 4)))') of 
diff erent\
+ size is not allowed}}
+  m4 = (matrix_5_5<signed int>)m3;
+  m5 = (matrix_5_5<unsigned int>)m4; // expected-error {{assigning to 'matrix_4_4<unsigned int>' (aka 'unsigned int \
+__attribute__((matrix_type(4, 4)))') from incompatible type 'matrix_5_5<unsigned int>' (aka 'unsigned int __attribute__\
+((matrix_type(5, 5)))')}}
+  m6 = (matrix_5_5<unsigned int>)m4;
+  m4 = (matrix_5_5<signed int>)m6;
 }


        


More information about the cfe-commits mailing list