[PATCH] D76793: [Matrix] Implement + and - operators for MatrixType.

2020-05-29 Thread Florian Hahn via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG6f6e91d19337: [Matrix] Implement + and - operators for 
MatrixType. (authored by fhahn).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D76793

Files:
  clang/include/clang/AST/Type.h
  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
@@ -127,6 +127,16 @@
   /// 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");
+
 return cast(LHS->getType())
->getElementType()
->isFloatingPointTy()
@@ -137,6 +147,16 @@
   /// 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");
+
 return cast(LHS->getType())
->getElementType()
->isFloatingPointTy()
Index: clang/test/SemaCXX/matrix-type-operators.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/matrix-type-operators.cpp
@@ -0,0 +1,93 @@
+// RUN: %clang_cc1 %s -fenable-matrix -pedantic -std=c++11 -verify -triple=x86_64-apple-darwin9
+
+typedef float sx5x10_t __attribute__((matrix_type(5, 10)));
+
+template 
+struct MyMatrix {
+  using matrix_t = EltTy __attribute__((matrix_type(Rows, Columns)));
+
+  matrix_t value;
+};
+
+template 
+typename MyMatrix::matrix_t add(MyMatrix , MyMatrix ) {
+  char *v1 = A.value + B.value;
+  // expected-error@-1 {{cannot initialize a variable of type 'char *' with an rvalue of type 'MyMatrix::matrix_t' (aka '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, 3)))') and 'MyMatrix::matrix_t' (aka 'float __attribute__((matrix_type(2, 2)))'))}}
+  // expected-error@-3 {{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(3, 3)))') and 'MyMatrix::matrix_t' (aka 'float __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)))'))}}
+}
+
+void test_add_template(unsigned *Ptr1, float *Ptr2) {
+  MyMatrix Mat1;
+  MyMatrix Mat2;
+  MyMatrix Mat3;
+  Mat1.value = *((decltype(Mat1)::matrix_t *)Ptr1);
+  unsigned v1 = add(Mat1, Mat1);
+  // expected-error@-1 {{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)))')}}
+  // expected-note@-2 {{in instantiation of function template specialization 'add' requested here}}
+
+  Mat1.value = add(Mat1, Mat2);
+  // expected-note@-1 {{in instantiation of function template specialization 'add' requested here}}
+
+  Mat1.value = add(Mat2, Mat3);
+  // expected-note@-1 {{in instantiation of function template specialization 'add' requested here}}
+}
+
+template 
+typename MyMatrix::matrix_t subtract(MyMatrix , MyMatrix ) {
+  char *v1 = A.value - B.value;
+  // expected-error@-1 {{cannot 

[PATCH] D76793: [Matrix] Implement + and - operators for MatrixType.

2020-05-29 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.

LGTM.




Comment at: clang/lib/Sema/SemaExpr.cpp:12112
+return InvalidOperands(Loc, OriginalLHS, OriginalRHS);
+  }
+

fhahn wrote:
> rjmccall wrote:
> > You need to not actually apply this conversion to the LHS if this is a 
> > compound assignment.  You can handle that in a follow-up patch, I think, 
> > since this patch isn't doing those yet.
> I am planning on adding support for compound assignment as follow-on patch 
> and include the change there.
WFM



Comment at: clang/test/CodeGenCXX/matrix-type-operators.cpp:374
+  // CHECK-NEXT:%1 = bitcast [90 x double]* %value to <90 x double>*
+  // CHECK-NEXT:%2 = load <90 x double>, <90 x double>* %1, align 8
+  // CHECK-NEXT:%call = call double 
@_ZN14DoubleWrapper1cvdEv(%struct.DoubleWrapper1* %w1)

fhahn wrote:
> rjmccall wrote:
> > Please don't test for exact value numbers; it makes updating the test 
> > really painful for relatively minor IR changes.  Use FileCheck variables 
> > instead.
> > 
> > More generally, can you make these tests a little more targeted instead of 
> > testing the entire function body?  You might find it easier to do so if you 
> > do a single operation per function.
> I've split up the tests more and updated the check lines to only check the 
> bits relevant for the operator (loading operands, computation, storing 
> result). The general matrix-type tests should cover checking loading the 
> correct value. Was that what you had in mind?
Yes, this looks great, thanks!


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D76793



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


[PATCH] D76793: [Matrix] Implement + and - operators for MatrixType.

2020-05-28 Thread Florian Hahn via Phabricator via cfe-commits
fhahn updated this revision to Diff 267061.
fhahn marked 7 inline comments as done.
fhahn added a comment.

Updated tests to use more targeted checks, fix typo and rebased on top of 
master (so this change can be applied before D76791 
.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D76793

Files:
  clang/include/clang/AST/Type.h
  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
@@ -127,6 +127,16 @@
   /// 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");
+
 return cast(LHS->getType())
->getElementType()
->isFloatingPointTy()
@@ -137,6 +147,16 @@
   /// 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");
+
 return cast(LHS->getType())
->getElementType()
->isFloatingPointTy()
Index: clang/test/SemaCXX/matrix-type-operators.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/matrix-type-operators.cpp
@@ -0,0 +1,93 @@
+// RUN: %clang_cc1 %s -fenable-matrix -pedantic -std=c++11 -verify -triple=x86_64-apple-darwin9
+
+typedef float sx5x10_t __attribute__((matrix_type(5, 10)));
+
+template 
+struct MyMatrix {
+  using matrix_t = EltTy __attribute__((matrix_type(Rows, Columns)));
+
+  matrix_t value;
+};
+
+template 
+typename MyMatrix::matrix_t add(MyMatrix , MyMatrix ) {
+  char *v1 = A.value + B.value;
+  // expected-error@-1 {{cannot initialize a variable of type 'char *' with an rvalue of type 'MyMatrix::matrix_t' (aka '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, 3)))') and 'MyMatrix::matrix_t' (aka 'float __attribute__((matrix_type(2, 2)))'))}}
+  // expected-error@-3 {{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(3, 3)))') and 'MyMatrix::matrix_t' (aka 'float __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)))'))}}
+}
+
+void test_add_template(unsigned *Ptr1, float *Ptr2) {
+  MyMatrix Mat1;
+  MyMatrix Mat2;
+  MyMatrix Mat3;
+  Mat1.value = *((decltype(Mat1)::matrix_t *)Ptr1);
+  unsigned v1 = add(Mat1, Mat1);
+  // expected-error@-1 {{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)))')}}
+  // expected-note@-2 {{in instantiation of function template specialization 'add' requested here}}
+
+  Mat1.value = add(Mat1, Mat2);
+  // expected-note@-1 {{in instantiation of function template specialization 'add' requested here}}
+
+  Mat1.value = add(Mat2, Mat3);
+  // expected-note@-1 {{in instantiation of function template specialization 'add' requested here}}
+}
+
+template 
+typename MyMatrix::matrix_t subtract(MyMatrix 

[PATCH] D76793: [Matrix] Implement + and - operators for MatrixType.

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



Comment at: clang/lib/Sema/SemaExpr.cpp:12112
+return InvalidOperands(Loc, OriginalLHS, OriginalRHS);
+  }
+

rjmccall wrote:
> You need to not actually apply this conversion to the LHS if this is a 
> compound assignment.  You can handle that in a follow-up patch, I think, 
> since this patch isn't doing those yet.
I am planning on adding support for compound assignment as follow-on patch and 
include the change there.



Comment at: clang/test/CodeGenCXX/matrix-type-operators.cpp:374
+  // CHECK-NEXT:%1 = bitcast [90 x double]* %value to <90 x double>*
+  // CHECK-NEXT:%2 = load <90 x double>, <90 x double>* %1, align 8
+  // CHECK-NEXT:%call = call double 
@_ZN14DoubleWrapper1cvdEv(%struct.DoubleWrapper1* %w1)

rjmccall wrote:
> Please don't test for exact value numbers; it makes updating the test really 
> painful for relatively minor IR changes.  Use FileCheck variables instead.
> 
> More generally, can you make these tests a little more targeted instead of 
> testing the entire function body?  You might find it easier to do so if you 
> do a single operation per function.
I've split up the tests more and updated the check lines to only check the bits 
relevant for the operator (loading operands, computation, storing result). The 
general matrix-type tests should cover checking loading the correct value. Was 
that what you had in mind?



Comment at: clang/test/SemaCXX/matrix-type-operators.cpp:188
+// expected-note@-3 {{candidate function}}
+// expected-note@-4 {{candidate function}}
+return {};

rjmccall wrote:
> `expected-note` can take a repeat count
Ah that's great, thanks!


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D76793



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


[PATCH] D76793: [Matrix] Implement + and - operators for MatrixType.

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

Thanks, functionality is looking good for the non-assignment operators.




Comment at: clang/lib/Sema/SemaExpr.cpp:12112
+return InvalidOperands(Loc, OriginalLHS, OriginalRHS);
+  }
+

You need to not actually apply this conversion to the LHS if this is a compound 
assignment.  You can handle that in a follow-up patch, I think, since this 
patch isn't doing those yet.



Comment at: clang/lib/Sema/SemaOverload.cpp:8591
 
+  /// Add binary operators overloads for each candidate matrix type M1, M2:
+  ///  * (M1, M1) -> M1

"operator overloads"



Comment at: clang/test/CodeGenCXX/matrix-type-operators.cpp:374
+  // CHECK-NEXT:%1 = bitcast [90 x double]* %value to <90 x double>*
+  // CHECK-NEXT:%2 = load <90 x double>, <90 x double>* %1, align 8
+  // CHECK-NEXT:%call = call double 
@_ZN14DoubleWrapper1cvdEv(%struct.DoubleWrapper1* %w1)

Please don't test for exact value numbers; it makes updating the test really 
painful for relatively minor IR changes.  Use FileCheck variables instead.

More generally, can you make these tests a little more targeted instead of 
testing the entire function body?  You might find it easier to do so if you do 
a single operation per function.



Comment at: clang/test/SemaCXX/matrix-type-operators.cpp:188
+// expected-note@-3 {{candidate function}}
+// expected-note@-4 {{candidate function}}
+return {};

`expected-note` can take a repeat count


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D76793



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


[PATCH] D76793: [Matrix] Implement + and - operators for MatrixType.

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



Comment at: clang/lib/Sema/SemaExpr.cpp:11989
+  else
+return false;
+

rjmccall wrote:
> fhahn wrote:
> > rjmccall wrote:
> > > I would suggest checking some preconditions and then just calling 
> > > `PrepareScalarCast`.
> > > 
> > > You should allow implicit conversions from class types, which somewhat 
> > > surprisingly I'm not sure we have a convenient method for, but which you 
> > > can find workable code for in `ConvertForConditional` in SemaExprCXX.cpp. 
> > >  Test case is `struct DoubleWrapper { operator double(); };`, and you 
> > > should test using that even when the element type isn't a double.
> > > 
> > > In SemaOverload, you should add builtin candidates for these operators if 
> > > one operand or the other is a matrix type.  Basically:
> > > 
> > > 1. Collect matrix types in `AddTypesConvertedFrom`
> > > 2. For each matrix type `M` on the LHS, add candidates for `(M, M) -> M` 
> > > and `(M, E) -> M`, and then analogously on the RHS.  Although you might 
> > > need to avoid adding redundant candidates if the same type shows up on 
> > > both sides.
> > Thank you very much John, I hope I managed to update the patch properly 
> > according to your comments!
> Does it work to just do the initialization step instead of separately 
> checking for an arithmetic type?  That code is definitely capable of doing 
> arithmetic conversions.
Yes it does. Much simpler, thanks!



Comment at: clang/lib/Sema/SemaOverload.cpp:9173
   OpBuilder.addBinaryPlusOrMinusPointerOverloads(Op);
-  OpBuilder.addGenericBinaryArithmeticOverloads();
+  OpBuilder.addGenericBinaryArithmeticOverloads(Op);
 }

rjmccall wrote:
> Maybe you should just extract your new code into its own method and call it 
> here.  That might fit in a bit cleaner to the design, since unlike the vector 
> case you're not planning on uniformly having element-wise versions of all of 
> the operators.
Sounds good, thanks!


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D76793



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


[PATCH] D76793: [Matrix] Implement + and - operators for MatrixType.

2020-05-28 Thread Florian Hahn via Phabricator via cfe-commits
fhahn updated this revision to Diff 266842.
fhahn marked 4 inline comments as done.
fhahn added a comment.

Use initialization step for all conversions (including for arithemtic types), 
add & call separate addMatrixBinaryArithmeticOverloads


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D76793

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
@@ -127,6 +127,16 @@
   /// 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");
+
 return cast(LHS->getType())
->getElementType()
->isFloatingPointTy()
@@ -137,6 +147,16 @@
   /// 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");
+
 return cast(LHS->getType())
->getElementType()
->isFloatingPointTy()
Index: clang/test/SemaCXX/matrix-type-operators.cpp
===
--- clang/test/SemaCXX/matrix-type-operators.cpp
+++ clang/test/SemaCXX/matrix-type-operators.cpp
@@ -114,3 +114,96 @@
   a[2] = f;
   // expected-error@-1 {{single subscript expressions are not allowed for matrix values}}
 }
+
+template 
+struct MyMatrix {
+  using matrix_t = EltTy __attribute__((matrix_type(Rows, Columns)));
+
+  matrix_t value;
+};
+
+template 
+typename MyMatrix::matrix_t add(MyMatrix , MyMatrix ) {
+  char *v1 = A.value + B.value;
+  // expected-error@-1 {{cannot initialize a variable of type 'char *' with an rvalue of type 'MyMatrix::matrix_t' (aka '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, 3)))') and 'MyMatrix::matrix_t' (aka 'float __attribute__((matrix_type(2, 2)))'))}}
+  // expected-error@-3 {{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(3, 3)))') and 'MyMatrix::matrix_t' (aka 'float __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)))'))}}
+}
+
+void test_add_template(unsigned *Ptr1, float *Ptr2) {
+  MyMatrix Mat1;
+  MyMatrix Mat2;
+  MyMatrix Mat3;
+  Mat1.value = *((decltype(Mat1)::matrix_t *)Ptr1);
+  unsigned v1 = add(Mat1, Mat1);
+  // expected-error@-1 {{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)))')}}
+  // expected-note@-2 {{in instantiation of function template specialization 'add' requested here}}
+
+  Mat1.value = add(Mat1, Mat2);
+  // expected-note@-1 {{in instantiation of function template specialization 'add' requested here}}
+
+  Mat1.value = add(Mat2, Mat3);
+  // expected-note@-1 {{in instantiation of function template specialization 'add' requested here}}
+}
+
+template 
+typename MyMatrix::matrix_t subtract(MyMatrix , MyMatrix ) {
+  char *v1 = A.value - B.value;
+  // expected-error@-1 

[PATCH] D76793: [Matrix] Implement + and - operators for MatrixType.

2020-05-27 Thread John McCall via Phabricator via cfe-commits
rjmccall added inline comments.



Comment at: clang/lib/Sema/SemaExpr.cpp:11989
+  else
+return false;
+

fhahn wrote:
> rjmccall wrote:
> > I would suggest checking some preconditions and then just calling 
> > `PrepareScalarCast`.
> > 
> > You should allow implicit conversions from class types, which somewhat 
> > surprisingly I'm not sure we have a convenient method for, but which you 
> > can find workable code for in `ConvertForConditional` in SemaExprCXX.cpp.  
> > Test case is `struct DoubleWrapper { operator double(); };`, and you should 
> > test using that even when the element type isn't a double.
> > 
> > In SemaOverload, you should add builtin candidates for these operators if 
> > one operand or the other is a matrix type.  Basically:
> > 
> > 1. Collect matrix types in `AddTypesConvertedFrom`
> > 2. For each matrix type `M` on the LHS, add candidates for `(M, M) -> M` 
> > and `(M, E) -> M`, and then analogously on the RHS.  Although you might 
> > need to avoid adding redundant candidates if the same type shows up on both 
> > sides.
> Thank you very much John, I hope I managed to update the patch properly 
> according to your comments!
Does it work to just do the initialization step instead of separately checking 
for an arithmetic type?  That code is definitely capable of doing arithmetic 
conversions.



Comment at: clang/lib/Sema/SemaOverload.cpp:9173
   OpBuilder.addBinaryPlusOrMinusPointerOverloads(Op);
-  OpBuilder.addGenericBinaryArithmeticOverloads();
+  OpBuilder.addGenericBinaryArithmeticOverloads(Op);
 }

Maybe you should just extract your new code into its own method and call it 
here.  That might fit in a bit cleaner to the design, since unlike the vector 
case you're not planning on uniformly having element-wise versions of all of 
the operators.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D76793



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


[PATCH] D76793: [Matrix] Implement + and - operators for MatrixType.

2020-05-27 Thread Florian Hahn via Phabricator via cfe-commits
fhahn updated this revision to Diff 266675.
fhahn added a comment.

Fixed overload candidates, use copy instead of const reference, thanks!


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D76793

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
@@ -127,6 +127,16 @@
   /// 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");
+
 return cast(LHS->getType())
->getElementType()
->isFloatingPointTy()
@@ -137,6 +147,16 @@
   /// 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");
+
 return cast(LHS->getType())
->getElementType()
->isFloatingPointTy()
Index: clang/test/SemaCXX/matrix-type-operators.cpp
===
--- clang/test/SemaCXX/matrix-type-operators.cpp
+++ clang/test/SemaCXX/matrix-type-operators.cpp
@@ -114,3 +114,96 @@
   a[2] = f;
   // expected-error@-1 {{single subscript expressions are not allowed for matrix values}}
 }
+
+template 
+struct MyMatrix {
+  using matrix_t = EltTy __attribute__((matrix_type(Rows, Columns)));
+
+  matrix_t value;
+};
+
+template 
+typename MyMatrix::matrix_t add(MyMatrix , MyMatrix ) {
+  char *v1 = A.value + B.value;
+  // expected-error@-1 {{cannot initialize a variable of type 'char *' with an rvalue of type 'MyMatrix::matrix_t' (aka '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, 3)))') and 'MyMatrix::matrix_t' (aka 'float __attribute__((matrix_type(2, 2)))'))}}
+  // expected-error@-3 {{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(3, 3)))') and 'MyMatrix::matrix_t' (aka 'float __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)))'))}}
+}
+
+void test_add_template(unsigned *Ptr1, float *Ptr2) {
+  MyMatrix Mat1;
+  MyMatrix Mat2;
+  MyMatrix Mat3;
+  Mat1.value = *((decltype(Mat1)::matrix_t *)Ptr1);
+  unsigned v1 = add(Mat1, Mat1);
+  // expected-error@-1 {{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)))')}}
+  // expected-note@-2 {{in instantiation of function template specialization 'add' requested here}}
+
+  Mat1.value = add(Mat1, Mat2);
+  // expected-note@-1 {{in instantiation of function template specialization 'add' requested here}}
+
+  Mat1.value = add(Mat2, Mat3);
+  // expected-note@-1 {{in instantiation of function template specialization 'add' requested here}}
+}
+
+template 
+typename MyMatrix::matrix_t subtract(MyMatrix , MyMatrix ) {
+  char *v1 = A.value - B.value;
+  // expected-error@-1 {{cannot initialize a variable of type 'char *' with an rvalue of type 'MyMatrix::matrix_t' (aka 

[PATCH] D76793: [Matrix] Implement + and - operators for MatrixType.

2020-05-27 Thread Florian Hahn via Phabricator via cfe-commits
fhahn marked 2 inline comments as done.
fhahn added inline comments.



Comment at: clang/lib/Sema/SemaOverload.cpp:8587
+if (S.Context.hasSameType(M1, M2))
+  AddCandidate(M1, M2);
+

rjmccall wrote:
> I don't think this works if one side or the other has e.g. a templated 
> conversion to a matrix type.  You need to add:
> 
> ```
>(M1, M1) -> M1
>(M1, M1.ElementType) -> M1
>(M2, M2) -> M2// but don't introduce the same candidate twice if the 
> same type is also in the LHS set)
>(M2.ElementType, M2) -> M2
> ```
> 
> Test case is something like:
> 
> ```
> struct identmatrix_t {
>   template 
>   operator matrix_type() const {
> matrix_type result = {};
> for (unsigned i = 0; i != N; ++i) result[i][i] = 1;
> return result;
>   }
> };
> constexpr identmatrix_t identmatrix = identmatrix();
> 
> ...
> m + identmatrix
> ```
> 
> Also, these operator candidates are only for specific operators, right?  I 
> think you can check what the operator is.
Oh I see, I've updated the code to add the versions as suggested.

> Also, these operator candidates are only for specific operators, right? I 
> think you can check what the operator is.

Yes they are. I had to update addGenericBinaryArithmeticOverloads to pass the 
Op kind.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D76793



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


[PATCH] D76793: [Matrix] Implement + and - operators for MatrixType.

2020-05-27 Thread John McCall via Phabricator via cfe-commits
rjmccall added inline comments.



Comment at: clang/lib/Sema/SemaOverload.cpp:8587
+if (S.Context.hasSameType(M1, M2))
+  AddCandidate(M1, M2);
+

I don't think this works if one side or the other has e.g. a templated 
conversion to a matrix type.  You need to add:

```
   (M1, M1) -> M1
   (M1, M1.ElementType) -> M1
   (M2, M2) -> M2// but don't introduce the same candidate twice if the 
same type is also in the LHS set)
   (M2.ElementType, M2) -> M2
```

Test case is something like:

```
struct identmatrix_t {
  template 
  operator matrix_type() const {
matrix_type result = {};
for (unsigned i = 0; i != N; ++i) result[i][i] = 1;
return result;
  }
};
constexpr identmatrix_t identmatrix = identmatrix();

...
m + identmatrix
```

Also, these operator candidates are only for specific operators, right?  I 
think you can check what the operator is.



Comment at: clang/lib/Sema/SemaOverload.cpp:8593
+  AddCandidate(cast(M2)->getElementType(), M2);
   }
 

Idiomatically, we just copy `QualType` instead of binding references to it.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D76793



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


[PATCH] D76793: [Matrix] Implement + and - operators for MatrixType.

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



Comment at: clang/lib/Sema/SemaExpr.cpp:11989
+  else
+return false;
+

rjmccall wrote:
> I would suggest checking some preconditions and then just calling 
> `PrepareScalarCast`.
> 
> You should allow implicit conversions from class types, which somewhat 
> surprisingly I'm not sure we have a convenient method for, but which you can 
> find workable code for in `ConvertForConditional` in SemaExprCXX.cpp.  Test 
> case is `struct DoubleWrapper { operator double(); };`, and you should test 
> using that even when the element type isn't a double.
> 
> In SemaOverload, you should add builtin candidates for these operators if one 
> operand or the other is a matrix type.  Basically:
> 
> 1. Collect matrix types in `AddTypesConvertedFrom`
> 2. For each matrix type `M` on the LHS, add candidates for `(M, M) -> M` and 
> `(M, E) -> M`, and then analogously on the RHS.  Although you might need to 
> avoid adding redundant candidates if the same type shows up on both sides.
Thank you very much John, I hope I managed to update the patch properly 
according to your comments!


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D76793



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


[PATCH] D76793: [Matrix] Implement + and - operators for MatrixType.

2020-05-26 Thread Florian Hahn via Phabricator via cfe-commits
fhahn updated this revision to Diff 266303.
fhahn marked an inline comment as done.
fhahn added a comment.

Add support for user-defined conversion function, use PrepareScalarCast and add 
overloads for matrix +/- operators.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D76793

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
@@ -127,6 +127,16 @@
   /// 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");
+
 return cast(LHS->getType())
->getElementType()
->isFloatingPointTy()
@@ -137,6 +147,16 @@
   /// 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");
+
 return cast(LHS->getType())
->getElementType()
->isFloatingPointTy()
Index: clang/test/SemaCXX/matrix-type-operators.cpp
===
--- clang/test/SemaCXX/matrix-type-operators.cpp
+++ clang/test/SemaCXX/matrix-type-operators.cpp
@@ -84,3 +84,96 @@
   a[2] = f;
   // expected-error@-1 {{single subscript expressions are not allowed for matrix values}}
 }
+
+template 
+struct MyMatrix {
+  using matrix_t = EltTy __attribute__((matrix_type(Rows, Columns)));
+
+  matrix_t value;
+};
+
+template 
+typename MyMatrix::matrix_t add(MyMatrix , MyMatrix ) {
+  char *v1 = A.value + B.value;
+  // expected-error@-1 {{cannot initialize a variable of type 'char *' with an rvalue of type 'MyMatrix::matrix_t' (aka '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, 3)))') and 'MyMatrix::matrix_t' (aka 'float __attribute__((matrix_type(2, 2)))'))}}
+  // expected-error@-3 {{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(3, 3)))') and 'MyMatrix::matrix_t' (aka 'float __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)))'))}}
+}
+
+void test_add_template(unsigned *Ptr1, float *Ptr2) {
+  MyMatrix Mat1;
+  MyMatrix Mat2;
+  MyMatrix Mat3;
+  Mat1.value = *((decltype(Mat1)::matrix_t *)Ptr1);
+  unsigned v1 = add(Mat1, Mat1);
+  // expected-error@-1 {{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)))')}}
+  // expected-note@-2 {{in instantiation of function template specialization 'add' requested here}}
+
+  Mat1.value = add(Mat1, Mat2);
+  // expected-note@-1 {{in instantiation of function template specialization 'add' requested here}}
+
+  Mat1.value = add(Mat2, Mat3);
+  // expected-note@-1 {{in instantiation of function template specialization 'add' requested here}}
+}
+
+template 
+typename MyMatrix::matrix_t subtract(MyMatrix , MyMatrix ) {
+  char *v1 = A.value - B.value;
+  // expected-error@-1 {{cannot initialize a 

[PATCH] D76793: [Matrix] Implement + and - operators for MatrixType.

2020-05-22 Thread John McCall via Phabricator via cfe-commits
rjmccall added inline comments.



Comment at: clang/lib/Sema/SemaExpr.cpp:11989
+  else
+return false;
+

I would suggest checking some preconditions and then just calling 
`PrepareScalarCast`.

You should allow implicit conversions from class types, which somewhat 
surprisingly I'm not sure we have a convenient method for, but which you can 
find workable code for in `ConvertForConditional` in SemaExprCXX.cpp.  Test 
case is `struct DoubleWrapper { operator double(); };`, and you should test 
using that even when the element type isn't a double.

In SemaOverload, you should add builtin candidates for these operators if one 
operand or the other is a matrix type.  Basically:

1. Collect matrix types in `AddTypesConvertedFrom`
2. For each matrix type `M` on the LHS, add candidates for `(M, M) -> M` and 
`(M, E) -> M`, and then analogously on the RHS.  Although you might need to 
avoid adding redundant candidates if the same type shows up on both sides.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D76793



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


[PATCH] D76793: [Matrix] Implement + and - operators for MatrixType.

2020-05-18 Thread Florian Hahn via Phabricator via cfe-commits
fhahn added a comment.

ping :)

this patch should be ready to be reviewed independently (it's marked as 
dependent on D76791  in Phab, but it can be 
applied independently and changing the relationship in Phab will trigger a 
bunch of unnecessary emails)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D76793



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


[PATCH] D76793: [Matrix] Implement + and - operators for MatrixType.

2020-05-08 Thread Florian Hahn via Phabricator via cfe-commits
fhahn updated this revision to Diff 262901.
fhahn added a comment.

Rebase on top of the final version of D72281 .

I think this patch is now ready for review.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D76793

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
@@ -127,6 +127,16 @@
   /// 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");
+
 return cast(LHS->getType())
->getElementType()
->isFloatingPointTy()
@@ -137,6 +147,16 @@
   /// 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");
+
 return cast(LHS->getType())
->getElementType()
->isFloatingPointTy()
Index: clang/test/SemaCXX/matrix-type-operators.cpp
===
--- clang/test/SemaCXX/matrix-type-operators.cpp
+++ clang/test/SemaCXX/matrix-type-operators.cpp
@@ -66,3 +66,66 @@
   a[2] = f;
   // expected-error@-1 {{single subscript expressions are not allowed for matrix values}}
 }
+
+template 
+struct MyMatrix {
+  using matrix_t = EltTy __attribute__((matrix_type(Rows, Columns)));
+
+  matrix_t value;
+};
+
+template 
+typename MyMatrix::matrix_t add(MyMatrix , MyMatrix ) {
+  char *v1 = A.value + B.value;
+  // expected-error@-1 {{cannot initialize a variable of type 'char *' with an rvalue of type 'MyMatrix::matrix_t' (aka '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, 3)))') and 'MyMatrix::matrix_t' (aka 'float __attribute__((matrix_type(2, 2)))'))}}
+  // expected-error@-3 {{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(3, 3)))') and 'MyMatrix::matrix_t' (aka 'float __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)))'))}}
+}
+
+void test_add_template(unsigned *Ptr1, float *Ptr2) {
+  MyMatrix Mat1;
+  MyMatrix Mat2;
+  MyMatrix Mat3;
+  Mat1.value = *((decltype(Mat1)::matrix_t *)Ptr1);
+  unsigned v1 = add(Mat1, Mat1);
+  // expected-error@-1 {{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)))')}}
+  // expected-note@-2 {{in instantiation of function template specialization 'add' requested here}}
+
+  Mat1.value = add(Mat1, Mat2);
+  // expected-note@-1 {{in instantiation of function template specialization 'add' requested here}}
+
+  Mat1.value = add(Mat2, Mat3);
+  // expected-note@-1 {{in instantiation of function template specialization 'add' requested here}}
+}
+
+template 
+typename MyMatrix::matrix_t subtract(MyMatrix , MyMatrix ) {
+  char *v1 = A.value - B.value;
+  // expected-error@-1 {{cannot initialize a variable of type 'char *' with an rvalue of type 

[PATCH] D76793: [Matrix] Implement + and - operators for MatrixType.

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

Implement conversions for matrix/scalar variants.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D76793

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
@@ -127,6 +127,16 @@
   /// 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");
+
 return cast(LHS->getType())
->getElementType()
->isFloatingPointTy()
@@ -137,6 +147,16 @@
   /// 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");
+
 return cast(LHS->getType())
->getElementType()
->isFloatingPointTy()
Index: clang/test/SemaCXX/matrix-type-operators.cpp
===
--- clang/test/SemaCXX/matrix-type-operators.cpp
+++ clang/test/SemaCXX/matrix-type-operators.cpp
@@ -66,3 +66,66 @@
   a[2] = f;
   // expected-error@-1 {{single subscript expressions are not allowed for matrix values}}
 }
+
+template 
+struct MyMatrix {
+  using matrix_t = EltTy __attribute__((matrix_type(Rows, Columns)));
+
+  matrix_t value;
+};
+
+template 
+typename MyMatrix::matrix_t add(MyMatrix , MyMatrix ) {
+  char *v1 = A.value + B.value;
+  // expected-error@-1 {{cannot initialize a variable of type 'char *' with an rvalue of type 'MyMatrix::matrix_t' (aka '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, 3)))') and 'MyMatrix::matrix_t' (aka 'float __attribute__((matrix_type(2, 2)))'))}}
+  // expected-error@-3 {{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(3, 3)))') and 'MyMatrix::matrix_t' (aka 'float __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)))'))}}
+}
+
+void test_add_template(unsigned *Ptr1, float *Ptr2) {
+  MyMatrix Mat1;
+  MyMatrix Mat2;
+  MyMatrix Mat3;
+  Mat1.value = *((decltype(Mat1)::matrix_t *)Ptr1);
+  unsigned v1 = add(Mat1, Mat1);
+  // expected-error@-1 {{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)))')}}
+  // expected-note@-2 {{in instantiation of function template specialization 'add' requested here}}
+
+  Mat1.value = add(Mat1, Mat2);
+  // expected-note@-1 {{in instantiation of function template specialization 'add' requested here}}
+
+  Mat1.value = add(Mat2, Mat3);
+  // expected-note@-1 {{in instantiation of function template specialization 'add' requested here}}
+}
+
+template 
+typename MyMatrix::matrix_t subtract(MyMatrix , MyMatrix ) {
+  char *v1 = A.value - B.value;
+  // expected-error@-1 {{cannot initialize a variable of type 'char *' with an rvalue of type 'MyMatrix::matrix_t' (aka 'unsigned int __attribute__((matrix_type(2, 2)))')}}
+  // 

[PATCH] D76793: [Matrix] Implement + and - operators 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 + and - binary operators for values of
MatrixType. It adds support for matrix +/- matrix, scalar +/- matrix and
matrix +/- scalar.

For the matrix, matrix case, the types must initially be structurally
equivalent. 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/D76793

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

Index: clang/test/SemaCXX/matrix-type-operators.cpp
===
--- clang/test/SemaCXX/matrix-type-operators.cpp
+++ clang/test/SemaCXX/matrix-type-operators.cpp
@@ -59,3 +59,66 @@
   float v11 = a[5][10.0];
   // expected-error@-1 {{matrix row index is outside the allowed range [0, 5)}}
 }
+
+template 
+struct MyMatrix {
+  using matrix_t = EltTy __attribute__((matrix_type(Rows, Columns)));
+
+  matrix_t value;
+};
+
+template 
+typename MyMatrix::matrix_t add(MyMatrix , MyMatrix ) {
+  char *v1 = A.value + B.value;
+  // expected-error@-1 {{cannot initialize a variable of type 'char *' with an rvalue of type 'MyMatrix::matrix_t' (aka '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, 3)))') and 'MyMatrix::matrix_t' (aka 'float __attribute__((matrix_type(2, 2)))'))}}
+  // expected-error@-3 {{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(3, 3)))') and 'MyMatrix::matrix_t' (aka 'float __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)))'))}}
+}
+
+void test_add_template(unsigned *Ptr1, float *Ptr2) {
+  MyMatrix Mat1;
+  MyMatrix Mat2;
+  MyMatrix Mat3;
+  Mat1.value = *((decltype(Mat1)::matrix_t *)Ptr1);
+  unsigned v1 = add(Mat1, Mat1);
+  // expected-error@-1 {{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)))')}}
+  // expected-note@-2 {{in instantiation of function template specialization 'add' requested here}}
+
+  Mat1.value = add(Mat1, Mat2);
+  // expected-note@-1 {{in instantiation of function template specialization 'add' requested here}}
+
+  Mat1.value = add(Mat2, Mat3);
+  // expected-note@-1 {{in instantiation of function template specialization 'add' requested here}}
+}
+
+template 
+typename MyMatrix::matrix_t subtract(MyMatrix , MyMatrix ) {
+  char *v1 = A.value - B.value;
+  // expected-error@-1 {{cannot initialize a variable of type 'char *' with an rvalue of type 'MyMatrix::matrix_t' (aka '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, 3)))') and 'MyMatrix::matrix_t' (aka 'float __attribute__((matrix_type(2, 2)))')}}
+  // expected-error@-3 {{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(3, 3)))') and 'MyMatrix::matrix_t' (aka 'float __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)))')}}
+}
+
+void test_subtract_template(unsigned *Ptr1, float *Ptr2) {
+  MyMatrix Mat1;
+  MyMatrix Mat2;
+  MyMatrix Mat3;
+  Mat1.value = *((decltype(Mat1)::matrix_t *)Ptr1);
+  unsigned v1 = subtract(Mat1, Mat1);
+  // expected-error@-1 {{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)))')}}
+  // expected-note@-2 {{in instantiation of function template