SaurabhJha updated this revision to Diff 342261.
SaurabhJha added a comment.

Updating D101696 <https://reviews.llvm.org/D101696>: [Matrix] Implement C-style 
explicit type conversions in CXX for matrix types

1. Remove bitcast when types are of the same size.
2. Make int conversion depend on whether both input and output are signed.
3. Add a test case of assigning to an incorrect type.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D101696/new/

https://reviews.llvm.org/D101696

Files:
  clang/lib/CodeGen/CGExprScalar.cpp
  clang/lib/Sema/SemaCast.cpp
  clang/test/CodeGen/matrix-cast.c
  clang/test/CodeGenCXX/matrix-casts.cpp
  clang/test/SemaCXX/matrix-casts.cpp

Index: clang/test/SemaCXX/matrix-casts.cpp
===================================================================
--- clang/test/SemaCXX/matrix-casts.cpp
+++ clang/test/SemaCXX/matrix-casts.cpp
@@ -14,7 +14,6 @@
 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 @@
   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 different 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 different\
+ 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;
 }
Index: clang/test/CodeGenCXX/matrix-casts.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGenCXX/matrix-casts.cpp
@@ -0,0 +1,137 @@
+// 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:%.*]] = zext <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 @_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;
+}
+
+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;
+}
\ No newline at end of file
Index: clang/test/CodeGen/matrix-cast.c
===================================================================
--- clang/test/CodeGen/matrix-cast.c
+++ clang/test/CodeGen/matrix-cast.c
@@ -22,7 +22,7 @@
 void cast_char_matrix_to_unsigned_int(cx5x5 c, unsigned_int_5x5 u) {
   // CHECK-LABEL: define{{.*}} void @cast_char_matrix_to_unsigned_int(<25 x i8> %c, <25 x i32> %u)
   // 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:  [[CONV:%.*]] = zext <25 x i8> [[C]] to <25 x i32>
   // CHECK-NEXT:  store <25 x i32> [[CONV]], <25 x i32>* {{.*}}, align 4
   // CHECK-NEXT:  ret void
 
@@ -52,7 +52,7 @@
 void cast_int_matrix_to_float(ix5x5 i, fx5x5 f) {
   // CHECK-LABEL: define{{.*}} void @cast_int_matrix_to_float(<25 x i32> %i, <25 x float> %f)
   // CHECK:       [[I:%.*]] = load <25 x i32>, <25 x i32>* {{.*}}, align 4
-  // CHECK-NEXT:  [[CONV:%.*]] = bitcast <25 x i32> [[I]] to <25 x float>
+  // CHECK-NEXT:  [[CONV:%.*]] = sitofp <25 x i32> [[I]] to <25 x float>
   // CHECK-NEXT:  store <25 x float> [[CONV]], <25 x float>* {{.*}}, align 4
   // CHECK-NEXT:  ret void
 
Index: clang/lib/Sema/SemaCast.cpp
===================================================================
--- clang/lib/Sema/SemaCast.cpp
+++ clang/lib/Sema/SemaCast.cpp
@@ -2648,6 +2648,13 @@
       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
Index: clang/lib/CodeGen/CGExprScalar.cpp
===================================================================
--- clang/lib/CodeGen/CGExprScalar.cpp
+++ clang/lib/CodeGen/CGExprScalar.cpp
@@ -1205,10 +1205,6 @@
   QualType SrcElementType;
   QualType DstElementType;
   if (SrcType->isMatrixType() && DstType->isMatrixType()) {
-    // Allow bitcast between matrixes of the same size.
-    if (SrcTy->getPrimitiveSizeInBits() == DstTy->getPrimitiveSizeInBits())
-      return Builder.CreateBitCast(Src, DstTy, "conv");
-
     SrcElementTy = cast<llvm::VectorType>(SrcTy)->getElementType();
     DstElementTy = cast<llvm::VectorType>(DstTy)->getElementType();
     SrcElementType = SrcType->castAs<MatrixType>()->getElementType();
@@ -1228,8 +1224,16 @@
       InputSigned = true;
     }
 
-    if (isa<llvm::IntegerType>(DstElementTy))
-      return Builder.CreateIntCast(Src, DstTy, InputSigned, "conv");
+    bool OutputSigned = DstElementType->isSignedIntegerOrEnumerationType();
+    if (DstElementType->isBooleanType() && Opts.TreatBooleanAsSigned) {
+      OutputSigned = true;
+    }
+
+    if (isa<llvm::IntegerType>(DstElementTy)) {
+
+      return Builder.CreateIntCast(Src, DstTy, InputSigned && OutputSigned,
+                                   "conv");
+    }
     if (InputSigned)
       return Builder.CreateSIToFP(Src, DstTy, "conv");
     return Builder.CreateUIToFP(Src, DstTy, "conv");
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to