[PATCH] D76794: [Matrix] Implement * binary operator for MatrixType.

2020-06-07 Thread Florian Hahn via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG4affc444b499: [Matrix] Implement * binary operator for 
MatrixType. (authored by fhahn).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D76794

Files:
  clang/include/clang/Sema/Sema.h
  clang/lib/CodeGen/CGExprScalar.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/test/CodeGen/matrix-type-operators.c
  clang/test/CodeGenCXX/matrix-type-operators.cpp
  clang/test/Sema/matrix-type-operators.c
  clang/test/SemaCXX/matrix-type-operators.cpp
  llvm/include/llvm/IR/MatrixBuilder.h

Index: llvm/include/llvm/IR/MatrixBuilder.h
===
--- llvm/include/llvm/IR/MatrixBuilder.h
+++ llvm/include/llvm/IR/MatrixBuilder.h
@@ -33,6 +33,21 @@
   IRBuilderTy 
   Module *getModule() { return B.GetInsertBlock()->getParent()->getParent(); }
 
+  std::pair splatScalarOperandIfNeeded(Value *LHS,
+ Value *RHS) {
+assert((LHS->getType()->isVectorTy() || RHS->getType()->isVectorTy()) &&
+   "One of the operands must be a matrix (embedded in a vector)");
+if (LHS->getType()->isVectorTy() && !RHS->getType()->isVectorTy())
+  RHS = B.CreateVectorSplat(
+  cast(LHS->getType())->getNumElements(), RHS,
+  "scalar.splat");
+else if (!LHS->getType()->isVectorTy() && RHS->getType()->isVectorTy())
+  LHS = B.CreateVectorSplat(
+  cast(RHS->getType())->getNumElements(), LHS,
+  "scalar.splat");
+return {LHS, RHS};
+  }
+
 public:
   MatrixBuilder(IRBuilderTy ) : B(Builder) {}
 
@@ -164,15 +179,13 @@
: B.CreateSub(LHS, RHS);
   }
 
-  /// Multiply matrix \p LHS with scalar \p RHS.
+  /// Multiply matrix \p LHS with scalar \p RHS or scalar \p LHS with matrix \p
+  /// RHS.
   Value *CreateScalarMultiply(Value *LHS, Value *RHS) {
-Value *ScalarVector =
-B.CreateVectorSplat(cast(LHS->getType())->getNumElements(),
-RHS, "scalar.splat");
-if (RHS->getType()->isFloatingPointTy())
-  return B.CreateFMul(LHS, ScalarVector);
-
-return B.CreateMul(LHS, ScalarVector);
+std::tie(LHS, RHS) = splatScalarOperandIfNeeded(LHS, RHS);
+if (LHS->getType()->getScalarType()->isFloatingPointTy())
+  return B.CreateFMul(LHS, RHS);
+return B.CreateMul(LHS, RHS);
   }
 
   /// Extracts the element at (\p RowIdx, \p ColumnIdx) from \p Matrix.
Index: clang/test/SemaCXX/matrix-type-operators.cpp
===
--- clang/test/SemaCXX/matrix-type-operators.cpp
+++ clang/test/SemaCXX/matrix-type-operators.cpp
@@ -65,6 +65,45 @@
   // expected-note@-1 {{in instantiation of function template specialization 'subtract' requested here}}
 }
 
+template 
+typename MyMatrix::matrix_t multiply(MyMatrix , MyMatrix ) {
+  char *v1 = A.value * B.value;
+  // expected-error@-1 {{cannot initialize a variable of type 'char *' with an rvalue of type 'unsigned int __attribute__((matrix_type(2, 2)))'}}
+  // expected-error@-2 {{invalid operands to binary expression ('MyMatrix::matrix_t' (aka 'unsigned int __attribute__((matrix_type(3, 2)))') and 'MyMatrix::matrix_t' (aka 'unsigned int __attribute__((matrix_type(3, 3)))'))}}
+  // expected-error@-3 {{invalid operands to binary expression ('MyMatrix::matrix_t' (aka 'float __attribute__((matrix_type(2, 2)))') and 'MyMatrix::matrix_t' (aka 'unsigned int __attribute__((matrix_type(2, 2)))'))}}
+
+  MyMatrix m;
+  B.value = m.value * A.value;
+  // expected-error@-1 {{invalid operands to binary expression ('MyMatrix::matrix_t' (aka 'int __attribute__((matrix_type(5, 6)))') and 'MyMatrix::matrix_t' (aka 'unsigned int __attribute__((matrix_type(2, 2)))'))}}
+  // expected-error@-2 {{invalid operands to binary expression ('MyMatrix::matrix_t' (aka 'int __attribute__((matrix_type(5, 6)))') and 'MyMatrix::matrix_t' (aka 'unsigned int __attribute__((matrix_type(3, 2)))'))}}
+  // expected-error@-3 {{invalid operands to binary expression ('MyMatrix::matrix_t' (aka 'int __attribute__((matrix_type(5, 6)))') and 'MyMatrix::matrix_t' (aka 'float __attribute__((matrix_type(2, 2)))'))}}
+
+  return A.value * B.value;
+  // expected-error@-1 {{invalid operands to binary expression ('MyMatrix::matrix_t' (aka 'unsigned int __attribute__((matrix_type(3, 2)))') and 'MyMatrix::matrix_t' (aka 'unsigned int __attribute__((matrix_type(3, 3)))'))}}
+  // expected-error@-2 {{invalid operands to binary expression ('MyMatrix::matrix_t' (aka 'float __attribute__((matrix_type(2, 2)))') and 'MyMatrix::matrix_t' (aka 'unsigned int __attribute__((matrix_type(2, 2)))'))}}
+}
+
+void test_multiply_template(unsigned *Ptr1, float *Ptr2) {
+  MyMatrix Mat1;
+  MyMatrix Mat2;
+  MyMatrix Mat3;
+  Mat1.value = *((decltype(Mat1)::matrix_t *)Ptr1);
+  unsigned v1 = 

[PATCH] D76794: [Matrix] Implement * binary operator for MatrixType.

2020-06-06 Thread John McCall via Phabricator via cfe-commits
rjmccall accepted this revision.
rjmccall added a comment.
This revision is now accepted and ready to land.

Thanks, LGTM!


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D76794



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D76794: [Matrix] Implement * binary operator for MatrixType.

2020-06-06 Thread Florian Hahn via Phabricator via cfe-commits
fhahn updated this revision to Diff 269027.
fhahn marked 2 inline comments as done.
fhahn added a comment.

In D76794#2078232 , @rjmccall wrote:

> Your IRGen test cases cover a lot of ground, but please add more Sema test 
> cases that go over the basics: element types matching, column/row counts 
> matching, multiplication by inappropriate scalars, etc.  Otherwise LGTM!


Oh, of course! I think some of those might have been accidentally dropped when 
moving patches around. I've added the additional Sema tests.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D76794

Files:
  clang/include/clang/Sema/Sema.h
  clang/lib/CodeGen/CGExprScalar.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/test/CodeGen/matrix-type-operators.c
  clang/test/CodeGenCXX/matrix-type-operators.cpp
  clang/test/Sema/matrix-type-operators.c
  clang/test/SemaCXX/matrix-type-operators.cpp
  llvm/include/llvm/IR/MatrixBuilder.h

Index: llvm/include/llvm/IR/MatrixBuilder.h
===
--- llvm/include/llvm/IR/MatrixBuilder.h
+++ llvm/include/llvm/IR/MatrixBuilder.h
@@ -33,6 +33,21 @@
   IRBuilderTy 
   Module *getModule() { return B.GetInsertBlock()->getParent()->getParent(); }
 
+  std::pair splatScalarOperandIfNeeded(Value *LHS,
+ Value *RHS) {
+assert((LHS->getType()->isVectorTy() || RHS->getType()->isVectorTy()) &&
+   "One of the operands must be a matrix (embedded in a vector)");
+if (LHS->getType()->isVectorTy() && !RHS->getType()->isVectorTy())
+  RHS = B.CreateVectorSplat(
+  cast(LHS->getType())->getNumElements(), RHS,
+  "scalar.splat");
+else if (!LHS->getType()->isVectorTy() && RHS->getType()->isVectorTy())
+  LHS = B.CreateVectorSplat(
+  cast(RHS->getType())->getNumElements(), LHS,
+  "scalar.splat");
+return {LHS, RHS};
+  }
+
 public:
   MatrixBuilder(IRBuilderTy ) : B(Builder) {}
 
@@ -164,15 +179,13 @@
: B.CreateSub(LHS, RHS);
   }
 
-  /// Multiply matrix \p LHS with scalar \p RHS.
+  /// Multiply matrix \p LHS with scalar \p RHS or scalar \p LHS with matrix \p
+  /// RHS.
   Value *CreateScalarMultiply(Value *LHS, Value *RHS) {
-Value *ScalarVector =
-B.CreateVectorSplat(cast(LHS->getType())->getNumElements(),
-RHS, "scalar.splat");
-if (RHS->getType()->isFloatingPointTy())
-  return B.CreateFMul(LHS, ScalarVector);
-
-return B.CreateMul(LHS, ScalarVector);
+std::tie(LHS, RHS) = splatScalarOperandIfNeeded(LHS, RHS);
+if (LHS->getType()->getScalarType()->isFloatingPointTy())
+  return B.CreateFMul(LHS, RHS);
+return B.CreateMul(LHS, RHS);
   }
 
   /// Extracts the element at (\p RowIdx, \p ColumnIdx) from \p Matrix.
Index: clang/test/SemaCXX/matrix-type-operators.cpp
===
--- clang/test/SemaCXX/matrix-type-operators.cpp
+++ clang/test/SemaCXX/matrix-type-operators.cpp
@@ -65,6 +65,45 @@
   // expected-note@-1 {{in instantiation of function template specialization 'subtract' requested here}}
 }
 
+template 
+typename MyMatrix::matrix_t multiply(MyMatrix , MyMatrix ) {
+  char *v1 = A.value * B.value;
+  // expected-error@-1 {{cannot initialize a variable of type 'char *' with an rvalue of type 'unsigned int __attribute__((matrix_type(2, 2)))'}}
+  // expected-error@-2 {{invalid operands to binary expression ('MyMatrix::matrix_t' (aka 'unsigned int __attribute__((matrix_type(3, 2)))') and 'MyMatrix::matrix_t' (aka 'unsigned int __attribute__((matrix_type(3, 3)))'))}}
+  // expected-error@-3 {{invalid operands to binary expression ('MyMatrix::matrix_t' (aka 'float __attribute__((matrix_type(2, 2)))') and 'MyMatrix::matrix_t' (aka 'unsigned int __attribute__((matrix_type(2, 2)))'))}}
+
+  MyMatrix m;
+  B.value = m.value * A.value;
+  // expected-error@-1 {{invalid operands to binary expression ('MyMatrix::matrix_t' (aka 'int __attribute__((matrix_type(5, 6)))') and 'MyMatrix::matrix_t' (aka 'unsigned int __attribute__((matrix_type(2, 2)))'))}}
+  // expected-error@-2 {{invalid operands to binary expression ('MyMatrix::matrix_t' (aka 'int __attribute__((matrix_type(5, 6)))') and 'MyMatrix::matrix_t' (aka 'unsigned int __attribute__((matrix_type(3, 2)))'))}}
+  // expected-error@-3 {{invalid operands to binary expression ('MyMatrix::matrix_t' (aka 'int __attribute__((matrix_type(5, 6)))') and 'MyMatrix::matrix_t' (aka 'float __attribute__((matrix_type(2, 2)))'))}}
+
+  return A.value * B.value;
+  // expected-error@-1 {{invalid operands to binary expression ('MyMatrix::matrix_t' (aka 'unsigned int __attribute__((matrix_type(3, 2)))') and 'MyMatrix::matrix_t' (aka 'unsigned int __attribute__((matrix_type(3, 3)))'))}}
+  // expected-error@-2 {{invalid 

[PATCH] D76794: [Matrix] Implement * binary operator for MatrixType.

2020-06-06 Thread Florian Hahn via Phabricator via cfe-commits
fhahn added inline comments.



Comment at: clang/lib/Sema/SemaExpr.cpp:12130
+  QualType LHSType = LHS.get()->getType().getUnqualifiedType();
+  QualType RHSType = RHS.get()->getType().getUnqualifiedType();
+

rjmccall wrote:
> You never actually do anything with these that cares about having gotten the 
> unqualified type.
Ah right! I think that was still a left-over from the manual conversion code. 
Dropped!


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D76794



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D76794: [Matrix] Implement * binary operator for MatrixType.

2020-06-06 Thread John McCall via Phabricator via cfe-commits
rjmccall added a comment.

Your IRGen test cases cover a lot of ground, but please add more Sema test 
cases that go over the basics: element types matching, column/row counts 
matching, multiplication by inappropriate scalars, etc.  Otherwise LGTM!




Comment at: clang/lib/Sema/SemaExpr.cpp:12130
+  QualType LHSType = LHS.get()->getType().getUnqualifiedType();
+  QualType RHSType = RHS.get()->getType().getUnqualifiedType();
+

You never actually do anything with these that cares about having gotten the 
unqualified type.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D76794



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D76794: [Matrix] Implement * binary operator for MatrixType.

2020-06-01 Thread Florian Hahn via Phabricator via cfe-commits
fhahn updated this revision to Diff 267627.
fhahn added a comment.

Ping :)

Updated the patch to include the feedback from D76793 
 (adding overloads, conversions, more targeted 
tests)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D76794

Files:
  clang/include/clang/Sema/Sema.h
  clang/lib/CodeGen/CGExprScalar.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/test/CodeGen/matrix-type-operators.c
  clang/test/CodeGenCXX/matrix-type-operators.cpp
  clang/test/Sema/matrix-type-operators.c
  clang/test/SemaCXX/matrix-type-operators.cpp
  llvm/include/llvm/IR/MatrixBuilder.h

Index: llvm/include/llvm/IR/MatrixBuilder.h
===
--- llvm/include/llvm/IR/MatrixBuilder.h
+++ llvm/include/llvm/IR/MatrixBuilder.h
@@ -33,6 +33,21 @@
   IRBuilderTy 
   Module *getModule() { return B.GetInsertBlock()->getParent()->getParent(); }
 
+  std::pair splatScalarOperandIfNeeded(Value *LHS,
+ Value *RHS) {
+assert((LHS->getType()->isVectorTy() || RHS->getType()->isVectorTy()) &&
+   "One of the operands must be a matrix (embedded in a vector)");
+if (LHS->getType()->isVectorTy() && !RHS->getType()->isVectorTy())
+  RHS = B.CreateVectorSplat(
+  cast(LHS->getType())->getNumElements(), RHS,
+  "scalar.splat");
+else if (!LHS->getType()->isVectorTy() && RHS->getType()->isVectorTy())
+  LHS = B.CreateVectorSplat(
+  cast(RHS->getType())->getNumElements(), LHS,
+  "scalar.splat");
+return {LHS, RHS};
+  }
+
 public:
   MatrixBuilder(IRBuilderTy ) : B(Builder) {}
 
@@ -164,15 +179,13 @@
: B.CreateSub(LHS, RHS);
   }
 
-  /// Multiply matrix \p LHS with scalar \p RHS.
+  /// Multiply matrix \p LHS with scalar \p RHS or scalar \p LHS with matrix \p
+  /// RHS.
   Value *CreateScalarMultiply(Value *LHS, Value *RHS) {
-Value *ScalarVector =
-B.CreateVectorSplat(cast(LHS->getType())->getNumElements(),
-RHS, "scalar.splat");
-if (RHS->getType()->isFloatingPointTy())
-  return B.CreateFMul(LHS, ScalarVector);
-
-return B.CreateMul(LHS, ScalarVector);
+std::tie(LHS, RHS) = splatScalarOperandIfNeeded(LHS, RHS);
+if (LHS->getType()->getScalarType()->isFloatingPointTy())
+  return B.CreateFMul(LHS, RHS);
+return B.CreateMul(LHS, RHS);
   }
 
   /// Extracts the element at (\p RowIdx, \p ColumnIdx) from \p Matrix.
Index: clang/test/SemaCXX/matrix-type-operators.cpp
===
--- clang/test/SemaCXX/matrix-type-operators.cpp
+++ clang/test/SemaCXX/matrix-type-operators.cpp
@@ -204,3 +204,26 @@
   a[2] = f;
   // expected-error@-1 {{single subscript expressions are not allowed for matrix values}}
 }
+
+template 
+typename MyMatrix::matrix_t multiply(MyMatrix , MyMatrix ) {
+  char *v1 = A.value * B.value;
+  // expected-error@-1 {{cannot initialize a variable of type 'char *' with an rvalue of type 'unsigned int __attribute__((matrix_type(2, 2)))'}}
+  // expected-error@-2 {{invalid operands to binary expression ('MyMatrix::matrix_t' (aka 'unsigned int __attribute__((matrix_type(2, 2)))') and 'MyMatrix::matrix_t' (aka 'unsigned int __attribute__((matrix_type(3, 3)))'))}}
+
+  return A.value * B.value;
+  // expected-error@-1 {{invalid operands to binary expression ('MyMatrix::matrix_t' (aka 'unsigned int __attribute__((matrix_type(2, 2)))') and 'MyMatrix::matrix_t' (aka 'unsigned int __attribute__((matrix_type(3, 3)))'))}}
+}
+
+void test_multiply_template(unsigned *Ptr1, float *Ptr2) {
+  MyMatrix Mat1;
+  MyMatrix Mat2;
+  MyMatrix Mat3;
+  Mat1.value = *((decltype(Mat1)::matrix_t *)Ptr1);
+  unsigned v1 = multiply(Mat1, Mat1);
+  // expected-note@-1 {{in instantiation of function template specialization 'multiply' requested here}}
+  // expected-error@-2 {{cannot initialize a variable of type 'unsigned int' with an rvalue of type 'typename MyMatrix::matrix_t' (aka 'unsigned int __attribute__((matrix_type(2, 2)))')}}
+
+  Mat1.value = multiply(Mat1, Mat2);
+  // expected-note@-1 {{in instantiation of function template specialization 'multiply' requested here}}
+}
Index: clang/test/Sema/matrix-type-operators.c
===
--- clang/test/Sema/matrix-type-operators.c
+++ clang/test/Sema/matrix-type-operators.c
@@ -132,3 +132,9 @@
   return &(*a)[0][1];
   // expected-error@-1 {{address of matrix element requested}}
 }
+
+void mat_scalar_multiply(sx10x10_t a, sx5x10_t b, float scalar) {
+  // Shape of multiplication result does not match the type of b.
+  b = a * scalar;
+  // expected-error@-1 {{assigning to 'sx5x10_t' (aka 'float __attribute__((matrix_type(5, 10)))') from incompatible type 'sx10x10_t' (aka 'float 

[PATCH] D76794: [Matrix] Implement * binary operator for MatrixType.

2020-04-02 Thread Florian Hahn via Phabricator via cfe-commits
fhahn updated this revision to Diff 254601.
fhahn added a comment.

Implement conversion for matrix/scalar variants.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D76794

Files:
  clang/include/clang/Sema/Sema.h
  clang/lib/CodeGen/CGExprScalar.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/test/CodeGen/matrix-type-operators.c
  clang/test/CodeGenCXX/matrix-type-operators.cpp
  clang/test/Sema/matrix-type-operators.c
  clang/test/SemaCXX/matrix-type-operators.cpp
  llvm/include/llvm/IR/MatrixBuilder.h

Index: llvm/include/llvm/IR/MatrixBuilder.h
===
--- llvm/include/llvm/IR/MatrixBuilder.h
+++ llvm/include/llvm/IR/MatrixBuilder.h
@@ -33,6 +33,19 @@
   IRBuilderTy 
   Module *getModule() { return B.GetInsertBlock()->getParent()->getParent(); }
 
+  std::pair splatScalarOperandIfNeeded(Value *LHS, Value *RHS) {
+assert((LHS->getType()->isVectorTy() || RHS->getType()->isVectorTy()) && "One of the operands must be a matrix (embedded in a vector)");
+if (LHS->getType()->isVectorTy() && !RHS->getType()->isVectorTy())
+  RHS = B.CreateVectorSplat(
+  cast(LHS->getType())->getNumElements(), RHS,
+  "scalar.splat");
+else if (!LHS->getType()->isVectorTy() && RHS->getType()->isVectorTy())
+  LHS = B.CreateVectorSplat(
+  cast(RHS->getType())->getNumElements(), LHS,
+  "scalar.splat");
+return {LHS, RHS};
+}
+
 public:
   MatrixBuilder(IRBuilderTy ) : B(Builder) {}
 
@@ -127,16 +140,7 @@
   /// Add matrixes \p LHS and \p RHS. Support both integer and floating point
   /// matrixes.
   Value *CreateAdd(Value *LHS, Value *RHS) {
-assert(LHS->getType()->isVectorTy() || RHS->getType()->isVectorTy());
-if (LHS->getType()->isVectorTy() && !RHS->getType()->isVectorTy())
-  RHS = B.CreateVectorSplat(
-  cast(LHS->getType())->getNumElements(), RHS,
-  "scalar.splat");
-else if (!LHS->getType()->isVectorTy() && RHS->getType()->isVectorTy())
-  LHS = B.CreateVectorSplat(
-  cast(RHS->getType())->getNumElements(), LHS,
-  "scalar.splat");
-
+std::tie(LHS, RHS) = splatScalarOperandIfNeeded(LHS, RHS);
 return cast(LHS->getType())
->getElementType()
->isFloatingPointTy()
@@ -147,16 +151,7 @@
   /// Subtract matrixes \p LHS and \p RHS. Support both integer and floating
   /// point matrixes.
   Value *CreateSub(Value *LHS, Value *RHS) {
-assert(LHS->getType()->isVectorTy() || RHS->getType()->isVectorTy());
-if (LHS->getType()->isVectorTy() && !RHS->getType()->isVectorTy())
-  RHS = B.CreateVectorSplat(
-  cast(LHS->getType())->getNumElements(), RHS,
-  "scalar.splat");
-else if (!LHS->getType()->isVectorTy() && RHS->getType()->isVectorTy())
-  LHS = B.CreateVectorSplat(
-  cast(RHS->getType())->getNumElements(), LHS,
-  "scalar.splat");
-
+std::tie(LHS, RHS) = splatScalarOperandIfNeeded(LHS, RHS);
 return cast(LHS->getType())
->getElementType()
->isFloatingPointTy()
@@ -164,15 +159,13 @@
: B.CreateSub(LHS, RHS);
   }
 
-  /// Multiply matrix \p LHS with scalar \p RHS.
+  /// Multiply matrix \p LHS with scalar \p RHS or scalar \p LHS with matrix \p
+  /// RHS.
   Value *CreateScalarMultiply(Value *LHS, Value *RHS) {
-Value *ScalarVector =
-B.CreateVectorSplat(cast(LHS->getType())->getNumElements(),
-RHS, "scalar.splat");
-if (RHS->getType()->isFloatingPointTy())
-  return B.CreateFMul(LHS, ScalarVector);
-
-return B.CreateMul(LHS, ScalarVector);
+std::tie(LHS, RHS) = splatScalarOperandIfNeeded(LHS, RHS);
+if (LHS->getType()->getScalarType()->isFloatingPointTy())
+return B.CreateFMul(LHS, RHS);
+return B.CreateMul(LHS, RHS);
   }
 
   /// Extracts the element at (\p Row, \p Column) from \p Matrix.
Index: clang/test/SemaCXX/matrix-type-operators.cpp
===
--- clang/test/SemaCXX/matrix-type-operators.cpp
+++ clang/test/SemaCXX/matrix-type-operators.cpp
@@ -129,3 +129,26 @@
   Mat1.value = subtract(Mat2, Mat3);
   // expected-note@-1 {{in instantiation of function template specialization 'subtract' requested here}}
 }
+
+template 
+typename MyMatrix::matrix_t multiply(MyMatrix , MyMatrix ) {
+  char *v1 = A.value * B.value;
+  // expected-error@-1 {{cannot initialize a variable of type 'char *' with an rvalue of type 'unsigned int __attribute__((matrix_type(2, 2)))'}}
+  // expected-error@-2 {{invalid operands to binary expression ('MyMatrix::matrix_t' (aka 'unsigned int __attribute__((matrix_type(2, 2)))') and 'MyMatrix::matrix_t' (aka 'unsigned int __attribute__((matrix_type(3, 3)))'))}}
+
+  return A.value * B.value;
+  // expected-error@-1 {{invalid operands to binary expression 

[PATCH] D76794: [Matrix] Implement * binary operator for MatrixType.

2020-04-02 Thread Florian Hahn via Phabricator via cfe-commits
fhahn updated this revision to Diff 254602.
fhahn added a comment.

clang-format


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D76794

Files:
  clang/include/clang/Sema/Sema.h
  clang/lib/CodeGen/CGExprScalar.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/test/CodeGen/matrix-type-operators.c
  clang/test/CodeGenCXX/matrix-type-operators.cpp
  clang/test/Sema/matrix-type-operators.c
  clang/test/SemaCXX/matrix-type-operators.cpp
  llvm/include/llvm/IR/MatrixBuilder.h

Index: llvm/include/llvm/IR/MatrixBuilder.h
===
--- llvm/include/llvm/IR/MatrixBuilder.h
+++ llvm/include/llvm/IR/MatrixBuilder.h
@@ -33,6 +33,21 @@
   IRBuilderTy 
   Module *getModule() { return B.GetInsertBlock()->getParent()->getParent(); }
 
+  std::pair splatScalarOperandIfNeeded(Value *LHS,
+ Value *RHS) {
+assert((LHS->getType()->isVectorTy() || RHS->getType()->isVectorTy()) &&
+   "One of the operands must be a matrix (embedded in a vector)");
+if (LHS->getType()->isVectorTy() && !RHS->getType()->isVectorTy())
+  RHS = B.CreateVectorSplat(
+  cast(LHS->getType())->getNumElements(), RHS,
+  "scalar.splat");
+else if (!LHS->getType()->isVectorTy() && RHS->getType()->isVectorTy())
+  LHS = B.CreateVectorSplat(
+  cast(RHS->getType())->getNumElements(), LHS,
+  "scalar.splat");
+return {LHS, RHS};
+  }
+
 public:
   MatrixBuilder(IRBuilderTy ) : B(Builder) {}
 
@@ -127,16 +142,7 @@
   /// Add matrixes \p LHS and \p RHS. Support both integer and floating point
   /// matrixes.
   Value *CreateAdd(Value *LHS, Value *RHS) {
-assert(LHS->getType()->isVectorTy() || RHS->getType()->isVectorTy());
-if (LHS->getType()->isVectorTy() && !RHS->getType()->isVectorTy())
-  RHS = B.CreateVectorSplat(
-  cast(LHS->getType())->getNumElements(), RHS,
-  "scalar.splat");
-else if (!LHS->getType()->isVectorTy() && RHS->getType()->isVectorTy())
-  LHS = B.CreateVectorSplat(
-  cast(RHS->getType())->getNumElements(), LHS,
-  "scalar.splat");
-
+std::tie(LHS, RHS) = splatScalarOperandIfNeeded(LHS, RHS);
 return cast(LHS->getType())
->getElementType()
->isFloatingPointTy()
@@ -147,16 +153,7 @@
   /// Subtract matrixes \p LHS and \p RHS. Support both integer and floating
   /// point matrixes.
   Value *CreateSub(Value *LHS, Value *RHS) {
-assert(LHS->getType()->isVectorTy() || RHS->getType()->isVectorTy());
-if (LHS->getType()->isVectorTy() && !RHS->getType()->isVectorTy())
-  RHS = B.CreateVectorSplat(
-  cast(LHS->getType())->getNumElements(), RHS,
-  "scalar.splat");
-else if (!LHS->getType()->isVectorTy() && RHS->getType()->isVectorTy())
-  LHS = B.CreateVectorSplat(
-  cast(RHS->getType())->getNumElements(), LHS,
-  "scalar.splat");
-
+std::tie(LHS, RHS) = splatScalarOperandIfNeeded(LHS, RHS);
 return cast(LHS->getType())
->getElementType()
->isFloatingPointTy()
@@ -164,15 +161,13 @@
: B.CreateSub(LHS, RHS);
   }
 
-  /// Multiply matrix \p LHS with scalar \p RHS.
+  /// Multiply matrix \p LHS with scalar \p RHS or scalar \p LHS with matrix \p
+  /// RHS.
   Value *CreateScalarMultiply(Value *LHS, Value *RHS) {
-Value *ScalarVector =
-B.CreateVectorSplat(cast(LHS->getType())->getNumElements(),
-RHS, "scalar.splat");
-if (RHS->getType()->isFloatingPointTy())
-  return B.CreateFMul(LHS, ScalarVector);
-
-return B.CreateMul(LHS, ScalarVector);
+std::tie(LHS, RHS) = splatScalarOperandIfNeeded(LHS, RHS);
+if (LHS->getType()->getScalarType()->isFloatingPointTy())
+  return B.CreateFMul(LHS, RHS);
+return B.CreateMul(LHS, RHS);
   }
 
   /// Extracts the element at (\p Row, \p Column) from \p Matrix.
Index: clang/test/SemaCXX/matrix-type-operators.cpp
===
--- clang/test/SemaCXX/matrix-type-operators.cpp
+++ clang/test/SemaCXX/matrix-type-operators.cpp
@@ -129,3 +129,26 @@
   Mat1.value = subtract(Mat2, Mat3);
   // expected-note@-1 {{in instantiation of function template specialization 'subtract' requested here}}
 }
+
+template 
+typename MyMatrix::matrix_t multiply(MyMatrix , MyMatrix ) {
+  char *v1 = A.value * B.value;
+  // expected-error@-1 {{cannot initialize a variable of type 'char *' with an rvalue of type 'unsigned int __attribute__((matrix_type(2, 2)))'}}
+  // expected-error@-2 {{invalid operands to binary expression ('MyMatrix::matrix_t' (aka 'unsigned int __attribute__((matrix_type(2, 2)))') and 'MyMatrix::matrix_t' (aka 'unsigned int __attribute__((matrix_type(3, 3)))'))}}
+
+  return A.value * B.value;
+  // expected-error@-1 {{invalid operands 

[PATCH] D76794: [Matrix] Implement * binary operator for MatrixType.

2020-03-25 Thread Florian Hahn via Phabricator via cfe-commits
fhahn created this revision.
fhahn added reviewers: rjmccall, anemet, Bigcheese, rsmith, martong.
Herald added subscribers: tschuett, dexonsmith, rnkovacs.
Herald added a project: clang.

This patch implements the * binary operator for values of
MatrixType. It adds support for matrix * matrix, scalar * matrix and
matrix * scalar.

For the matrix, matrix case, the number of columns of the first operand
must match the number of rows of the second. For the scalar,matrix variants,
the element type of the matrix must match the scalar type.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D76794

Files:
  clang/include/clang/Sema/Sema.h
  clang/lib/CodeGen/CGExprScalar.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/test/CodeGen/matrix-type-operators.c
  clang/test/CodeGenCXX/matrix-type-operators.cpp
  clang/test/Sema/matrix-type-operators.c
  clang/test/SemaCXX/matrix-type-operators.cpp
  llvm/include/llvm/IR/MatrixBuilder.h

Index: llvm/include/llvm/IR/MatrixBuilder.h
===
--- llvm/include/llvm/IR/MatrixBuilder.h
+++ llvm/include/llvm/IR/MatrixBuilder.h
@@ -144,15 +144,24 @@
: B.CreateSub(LHS, RHS);
   }
 
-  /// Multiply matrix \p LHS with scalar \p RHS.
+  /// Multiply matrix \p LHS with scalar \p RHS or scalar \p LHS with matrix \p
+  /// RHS.
   Value *CreateScalarMultiply(Value *LHS, Value *RHS) {
-Value *ScalarVector =
-B.CreateVectorSplat(cast(LHS->getType())->getNumElements(),
-RHS, "scalar.splat");
-if (RHS->getType()->isFloatingPointTy())
-  return B.CreateFMul(LHS, ScalarVector);
-
-return B.CreateMul(LHS, ScalarVector);
+assert(LHS->getType()->isVectorTy() ||
+   RHS->getType()->isVectorTy() &&
+   "One of the operands must be a matrix (embedded in a vector)");
+Value *ScalarVector = B.CreateVectorSplat(
+cast(LHS->getType())->getNumElements(),
+LHS->getType()->isVectorTy() ? RHS : LHS, "scalar.splat");
+if (RHS->getType()->isFloatingPointTy()) {
+  if (LHS->getType()->isVectorTy())
+return B.CreateFMul(LHS, ScalarVector);
+  return B.CreateFMul(ScalarVector, RHS);
+}
+
+if (LHS->getType()->isVectorTy())
+  return B.CreateMul(LHS, ScalarVector);
+return B.CreateMul(ScalarVector, RHS);
   }
 
   /// Extracts the element at (\p Row, \p Column) from \p Matrix.
Index: clang/test/SemaCXX/matrix-type-operators.cpp
===
--- clang/test/SemaCXX/matrix-type-operators.cpp
+++ clang/test/SemaCXX/matrix-type-operators.cpp
@@ -122,3 +122,26 @@
   Mat1.value = subtract(Mat2, Mat3);
   // expected-note@-1 {{in instantiation of function template specialization 'subtract' requested here}}
 }
+
+template 
+typename MyMatrix::matrix_t multiply(MyMatrix , MyMatrix ) {
+  char *v1 = A.value * B.value;
+  // expected-error@-1 {{cannot initialize a variable of type 'char *' with an rvalue of type 'unsigned int __attribute__((matrix_type(2, 2))) '}}
+  // expected-error@-2 {{invalid operands to binary expression ('MyMatrix::matrix_t' (aka 'unsigned int __attribute__((matrix_type(2, 2)))') and 'MyMatrix::matrix_t' (aka 'unsigned int __attribute__((matrix_type(3, 3)))'))}}
+
+  return A.value * B.value;
+  // expected-error@-1 {{invalid operands to binary expression ('MyMatrix::matrix_t' (aka 'unsigned int __attribute__((matrix_type(2, 2)))') and 'MyMatrix::matrix_t' (aka 'unsigned int __attribute__((matrix_type(3, 3)))'))}}
+}
+
+void test_multiply_template(unsigned *Ptr1, float *Ptr2) {
+  MyMatrix Mat1;
+  MyMatrix Mat2;
+  MyMatrix Mat3;
+  Mat1.value = *((decltype(Mat1)::matrix_t *)Ptr1);
+  unsigned v1 = multiply(Mat1, Mat1);
+  // expected-note@-1 {{in instantiation of function template specialization 'multiply' requested here}}
+  // expected-error@-2 {{cannot initialize a variable of type 'unsigned int' with an rvalue of type 'typename MyMatrix::matrix_t' (aka 'unsigned int __attribute__((matrix_type(2, 2)))')}}
+
+  Mat1.value = multiply(Mat1, Mat2);
+  // expected-note@-1 {{in instantiation of function template specialization 'multiply' requested here}}
+}
Index: clang/test/Sema/matrix-type-operators.c
===
--- clang/test/Sema/matrix-type-operators.c
+++ clang/test/Sema/matrix-type-operators.c
@@ -96,3 +96,22 @@
   a = b - 
   // expected-error@-1 {{invalid operands to binary expression ('sx5x10_t' (aka 'float __attribute__((matrix_type(5, 10)))') and 'sx10x5_t *' (aka 'float  __attribute__((matrix_type(10, 5)))*'))}}
 }
+
+void mat_mat_multiply(sx10x10_t a, sx5x10_t b, sx10x5_t c) {
+  // Invalid dimensions for operands.
+  a = c * c;
+  // expected-error@-1 {{invalid operands to binary expression ('sx10x5_t' (aka 'float __attribute__((matrix_type(10, 5)))') and 'sx10x5_t')}}
+
+  // Shape of multiplication result does not match the type of b.
+  b = a * a;
+  //