https://github.com/erichkeane created 
https://github.com/llvm/llvm-project/pull/230536

This ends up being basically just a copy/paste from the 'add' patch I just did, 
otherthan not having to modify the 'splat' work (as that is already done!).

>From 6d9296330ac224239928c7e1cd7a70b5f75e22a2 Mon Sep 17 00:00:00 2001
From: erichkeane <[email protected]>
Date: Fri, 9 Oct 2026 07:46:24 -0700
Subject: [PATCH] [CIR] Implement 'matrix-subtraction' lowering.

This ends up being basically just a copy/paste from the 'add' patch I
just did, otherthan not having to modify the 'splat' work (as that is
already done!).
---
 clang/include/clang/CIR/Dialect/IR/CIROps.td |  13 +-
 clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp   |  12 +-
 clang/test/CIR/CodeGen/matrix-sub.c          | 207 +++++++++++++++++++
 clang/test/CIR/IR/matrix.cir                 |  16 ++
 clang/test/CIR/Lowering/matrix-sub.cir       |  70 +++++++
 5 files changed, 310 insertions(+), 8 deletions(-)
 create mode 100644 clang/test/CIR/CodeGen/matrix-sub.c
 create mode 100644 clang/test/CIR/Lowering/matrix-sub.cir

diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index c0de90183c255..3a09ea42416af 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -2831,12 +2831,12 @@ def CIR_AddOp
 
//===----------------------------------------------------------------------===//
 
 def CIR_SubOp
-    : CIR_BinaryOpWithOverflowFlags<"sub", CIR_AnyIntOrVecOfIntType> {
+    : CIR_BinaryOpWithOverflowFlags<"sub", CIR_AnyIntOrVecOrMatrixOfIntType> {
   let summary = "Integer subtraction";
   let description = [{
     The `cir.sub` operation performs subtraction on integer operands. Both
-    operands and the result must have the same integer or vector-of-integer
-    type.
+    operands and the result must have the same integer, vector-of-integer or
+    matrix-of-integer type.
 
     The optional `nsw` (no signed wrap) and `nuw` (no unsigned wrap) unit
     attributes indicate that the result is poison if signed or unsigned
@@ -2851,6 +2851,7 @@ def CIR_SubOp
     %1 = cir.sub nsw %a, %b : !s32i
     %2 = cir.sub sat %a, %b : !s32i
     %3 = cir.sub %va, %vb : !cir.vector<4 x !s32i>
+    %4 = cir.sub %ma, %mb : !cir.matrix<3 x 3 x !s32i>
     ```
   }];
 }
@@ -2992,12 +2993,13 @@ def CIR_FAddOp
 // FSubOp
 
//===----------------------------------------------------------------------===//
 
-def CIR_FSubOp : CIR_FPBinaryOp<"fsub"> {
+def CIR_FSubOp
+    : CIR_FPBinaryOp<"fsub", [], CIR_AnyFloatOrVecOrMatrixOfFloatType> {
   let summary = "Floating-point subtraction";
   let description = [{
     The `cir.fsub` operation performs floating-point subtraction on its
     operands. Both operands and the result must have the same floating-point
-    scalar or vector-of-float type.
+    scalar vector-of-float or matrix-of-float type.
 
     Example:
 
@@ -3005,6 +3007,7 @@ def CIR_FSubOp : CIR_FPBinaryOp<"fsub"> {
     %0 = cir.fsub %a, %b : !cir.float
     %1 = cir.fsub %a, %b : !cir.double
     %2 = cir.fsub %va, %vb : !cir.vector<4 x !cir.float>
+    %3 = cir.fsub %ma, %mb : !cir.matrix<3 x 3 x !cir.float>
     ```
   }];
 
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index 8ae0be29d6d2b..4469da94327de 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
@@ -2467,9 +2467,15 @@ mlir::Value ScalarExprEmitter::emitSub(const BinOpInfo 
&ops) {
     }
 
     if (ops.fullType->isConstantMatrixType()) {
-      assert(!cir::MissingFeatures::matrixType());
-      cgf.cgm.errorNYI("ScalarExprEmitter::emitSub: matrix types");
-      return {};
+      // Like llvm::MatrixBuilder::CreateSub, splat a scalar operand to the
+      // matrix type before adding.
+      auto [lhs, rhs] =
+          builder.splatMatrixOpOperandsIfNecessary(loc, ops.lhs, ops.rhs);
+
+      CIRGenFunction::CIRGenFPOptionsRAII fpOptsRAII(cgf, ops.fpFeatures);
+      if (cir::isFPOrVectorOrMatrixOfFPType(lhs.getType()))
+        return builder.createFSub(loc, lhs, rhs);
+      return builder.createSub(loc, lhs, rhs);
     }
 
     if (ops.compType->isUnsignedIntegerType() &&
diff --git a/clang/test/CIR/CodeGen/matrix-sub.c 
b/clang/test/CIR/CodeGen/matrix-sub.c
new file mode 100644
index 0000000000000..eda6e3d64f68f
--- /dev/null
+++ b/clang/test/CIR/CodeGen/matrix-sub.c
@@ -0,0 +1,207 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fenable-matrix -fclangir 
-emit-cir %s -o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fenable-matrix -fclangir 
-emit-llvm %s -o %t-cir.ll
+// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fenable-matrix -emit-llvm 
%s -o %t.ll
+// RUN: FileCheck --input-file=%t.ll %s -check-prefix=LLVM
+
+typedef double dx5x5_t __attribute__((matrix_type(5, 5)));
+typedef float fx2x3_t __attribute__((matrix_type(2, 3)));
+typedef int ix9x3_t __attribute__((matrix_type(9, 3)));
+typedef unsigned long long ullx4x2_t __attribute__((matrix_type(4, 2)));
+
+void sub_matrix_matrix_double() {
+  dx5x5_t a;
+  dx5x5_t b;
+  dx5x5_t c;
+  a = b - c;
+}
+
+// CIR-LABEL: cir.func {{.*}}@sub_matrix_matrix_double
+// CIR: %[[B:.*]] = cir.load {{.*}} : !cir.ptr<!cir.matrix<5 x 5 x 
!cir.double>>, !cir.matrix<5 x 5 x !cir.double>
+// CIR: %[[C:.*]] = cir.load {{.*}} : !cir.ptr<!cir.matrix<5 x 5 x 
!cir.double>>, !cir.matrix<5 x 5 x !cir.double>
+// CIR: %[[RES:.*]] = cir.fsub %[[B]], %[[C]] : !cir.matrix<5 x 5 x 
!cir.double>
+// CIR: cir.store {{.*}} %[[RES]], {{.*}} : !cir.matrix<5 x 5 x !cir.double>, 
!cir.ptr<!cir.matrix<5 x 5 x !cir.double>>
+
+// LLVM-LABEL: define {{.*}}void @sub_matrix_matrix_double(
+// LLVM: %[[B:.*]] = load <25 x double>, ptr {{.*}}, align 8
+// LLVM: %[[C:.*]] = load <25 x double>, ptr {{.*}}, align 8
+// LLVM: %[[RES:.*]] = fsub <25 x double> %[[B]], %[[C]]
+// LLVM: store <25 x double> %[[RES]], ptr {{.*}}, align 8
+
+void sub_compound_assign_matrix_double() {
+  dx5x5_t a;
+  dx5x5_t b;
+  a -= b;
+}
+
+// CIR-LABEL: cir.func {{.*}}@sub_compound_assign_matrix_double
+// CIR: %[[B:.*]] = cir.load {{.*}} : !cir.ptr<!cir.matrix<5 x 5 x 
!cir.double>>, !cir.matrix<5 x 5 x !cir.double>
+// CIR: %[[A:.*]] = cir.load {{.*}} : !cir.ptr<!cir.matrix<5 x 5 x 
!cir.double>>, !cir.matrix<5 x 5 x !cir.double>
+// CIR: %[[RES:.*]] = cir.fsub %[[A]], %[[B]] : !cir.matrix<5 x 5 x 
!cir.double>
+// CIR: cir.store {{.*}} %[[RES]], {{.*}} : !cir.matrix<5 x 5 x !cir.double>, 
!cir.ptr<!cir.matrix<5 x 5 x !cir.double>>
+
+// LLVM-LABEL: define {{.*}}void @sub_compound_assign_matrix_double(
+// LLVM: %[[B:.*]] = load <25 x double>, ptr {{.*}}, align 8
+// LLVM: %[[A:.*]] = load <25 x double>, ptr {{.*}}, align 8
+// LLVM: %[[RES:.*]] = fsub <25 x double> %[[A]], %[[B]]
+// LLVM: store <25 x double> %[[RES]], ptr {{.*}}, align 8
+
+void sub_matrix_matrix_float() {
+  fx2x3_t a;
+  fx2x3_t b;
+  fx2x3_t c;
+  a = b - c;
+}
+
+// CIR-LABEL: cir.func {{.*}}@sub_matrix_matrix_float
+// CIR: %[[B:.*]] = cir.load {{.*}} : !cir.ptr<!cir.matrix<2 x 3 x 
!cir.float>>, !cir.matrix<2 x 3 x !cir.float>
+// CIR: %[[C:.*]] = cir.load {{.*}} : !cir.ptr<!cir.matrix<2 x 3 x 
!cir.float>>, !cir.matrix<2 x 3 x !cir.float>
+// CIR: %[[RES:.*]] = cir.fsub %[[B]], %[[C]] : !cir.matrix<2 x 3 x !cir.float>
+
+// LLVM-LABEL: define {{.*}}void @sub_matrix_matrix_float(
+// LLVM: %[[B:.*]] = load <6 x float>, ptr {{.*}}, align 4
+// LLVM: %[[C:.*]] = load <6 x float>, ptr {{.*}}, align 4
+// LLVM: %[[RES:.*]] = fsub <6 x float> %[[B]], %[[C]]
+// LLVM: store <6 x float> %[[RES]], ptr {{.*}}, align 4
+
+void sub_matrix_matrix_int() {
+  ix9x3_t a;
+  ix9x3_t b;
+  ix9x3_t c;
+  a = b - c;
+}
+
+// CIR-LABEL: cir.func {{.*}}@sub_matrix_matrix_int
+// CIR: %[[B:.*]] = cir.load {{.*}} : !cir.ptr<!cir.matrix<9 x 3 x !s32i>>, 
!cir.matrix<9 x 3 x !s32i>
+// CIR: %[[C:.*]] = cir.load {{.*}} : !cir.ptr<!cir.matrix<9 x 3 x !s32i>>, 
!cir.matrix<9 x 3 x !s32i>
+// CIR: %[[RES:.*]] = cir.sub %[[B]], %[[C]] : !cir.matrix<9 x 3 x !s32i>
+// CIR: cir.store {{.*}} %[[RES]], {{.*}} : !cir.matrix<9 x 3 x !s32i>, 
!cir.ptr<!cir.matrix<9 x 3 x !s32i>>
+
+// LLVM-LABEL: define {{.*}}void @sub_matrix_matrix_int(
+// LLVM: %[[B:.*]] = load <27 x i32>, ptr {{.*}}, align 4
+// LLVM: %[[C:.*]] = load <27 x i32>, ptr {{.*}}, align 4
+// LLVM: %[[RES:.*]] = sub <27 x i32> %[[B]], %[[C]]
+// LLVM: store <27 x i32> %[[RES]], ptr {{.*}}, align 4
+
+void sub_compound_assign_matrix_int() {
+  ix9x3_t a;
+  ix9x3_t b;
+  a -= b;
+}
+
+// CIR-LABEL: cir.func {{.*}}@sub_compound_assign_matrix_int
+// CIR: %[[B:.*]] = cir.load {{.*}} : !cir.ptr<!cir.matrix<9 x 3 x !s32i>>, 
!cir.matrix<9 x 3 x !s32i>
+// CIR: %[[A:.*]] = cir.load {{.*}} : !cir.ptr<!cir.matrix<9 x 3 x !s32i>>, 
!cir.matrix<9 x 3 x !s32i>
+// CIR: %[[RES:.*]] = cir.sub %[[A]], %[[B]] : !cir.matrix<9 x 3 x !s32i>
+
+// LLVM-LABEL: define {{.*}}void @sub_compound_assign_matrix_int(
+// LLVM: %[[B:.*]] = load <27 x i32>, ptr {{.*}}, align 4
+// LLVM: %[[A:.*]] = load <27 x i32>, ptr {{.*}}, align 4
+// LLVM: %[[RES:.*]] = sub <27 x i32> %[[A]], %[[B]]
+// LLVM: store <27 x i32> %[[RES]], ptr {{.*}}, align 4
+
+void sub_matrix_matrix_unsigned() {
+  ullx4x2_t a;
+  ullx4x2_t b;
+  ullx4x2_t c;
+  a = b - c;
+}
+
+// CIR-LABEL: cir.func {{.*}}@sub_matrix_matrix_unsigned
+// CIR: %[[RES:.*]] = cir.sub %{{.*}}, %{{.*}} : !cir.matrix<4 x 2 x !u64i>
+
+// LLVM-LABEL: define {{.*}}void @sub_matrix_matrix_unsigned(
+// LLVM: %[[RES:.*]] = sub <8 x i64> %{{.*}}, %{{.*}}
+
+void sub_matrix_scalar_double_double() {
+  dx5x5_t a;
+  double vd;
+  a = a - vd;
+}
+
+// CIR-LABEL: cir.func {{.*}}@sub_matrix_scalar_double_double
+// CIR: %[[MAT:.*]] = cir.load {{.*}} : !cir.ptr<!cir.matrix<5 x 5 x 
!cir.double>>, !cir.matrix<5 x 5 x !cir.double>
+// CIR: %[[SCALAR:.*]] = cir.load {{.*}} : !cir.ptr<!cir.double>, !cir.double
+// CIR: %[[SPLAT:.*]] = cir.vec.splat %[[SCALAR]] : !cir.double, !cir.matrix<5 
x 5 x !cir.double>
+// CIR: %[[RES:.*]] = cir.fsub %[[MAT]], %[[SPLAT]] : !cir.matrix<5 x 5 x 
!cir.double>
+
+// LLVM-LABEL: define {{.*}}void @sub_matrix_scalar_double_double(
+// LLVM: %[[MAT:.*]] = load <25 x double>, ptr {{.*}}, align 8
+// LLVM: %[[SCALAR:.*]] = load double, ptr {{.*}}, align 8
+// LLVM: %[[EMBED:.*]] = insertelement <25 x double> poison, double 
%[[SCALAR]], i64 0
+// LLVM: %[[SPLAT:.*]] = shufflevector <25 x double> %[[EMBED]], <25 x double> 
poison, <25 x i32> zeroinitializer
+// LLVM: %[[RES:.*]] = fsub <25 x double> %[[MAT]], %[[SPLAT]]
+// LLVM: store <25 x double> %[[RES]], ptr {{.*}}, align 8
+
+void sub_scalar_matrix_double_double() {
+  dx5x5_t a;
+  double vd;
+  a = vd - a;
+}
+
+// CIR-LABEL: cir.func {{.*}}@sub_scalar_matrix_double_double
+// CIR: %[[SCALAR:.*]] = cir.load {{.*}} : !cir.ptr<!cir.double>, !cir.double
+// CIR: %[[MAT:.*]] = cir.load {{.*}} : !cir.ptr<!cir.matrix<5 x 5 x 
!cir.double>>, !cir.matrix<5 x 5 x !cir.double>
+// CIR: %[[SPLAT:.*]] = cir.vec.splat %[[SCALAR]] : !cir.double, !cir.matrix<5 
x 5 x !cir.double>
+// CIR: %[[RES:.*]] = cir.fsub %[[SPLAT]], %[[MAT]] : !cir.matrix<5 x 5 x 
!cir.double>
+
+// LLVM-LABEL: define {{.*}}void @sub_scalar_matrix_double_double(
+// LLVM: %[[SCALAR:.*]] = load double, ptr {{.*}}, align 8
+// LLVM: %[[MAT:.*]] = load <25 x double>, ptr {{.*}}, align 8
+// LLVM: %[[EMBED:.*]] = insertelement <25 x double> poison, double 
%[[SCALAR]], i64 0
+// LLVM: %[[SPLAT:.*]] = shufflevector <25 x double> %[[EMBED]], <25 x double> 
poison, <25 x i32> zeroinitializer
+// LLVM: %[[RES:.*]] = fsub <25 x double> %[[SPLAT]], %[[MAT]]
+
+void sub_matrix_scalar_double_float() {
+  dx5x5_t a;
+  float vf;
+  a = a - vf;
+}
+
+// CIR-LABEL: cir.func {{.*}}@sub_matrix_scalar_double_float
+// CIR: %[[SCALAR:.*]] = cir.load {{.*}} : !cir.ptr<!cir.float>, !cir.float
+// CIR: %[[EXT:.*]] = cir.cast floating %[[SCALAR]] : !cir.float -> !cir.double
+// CIR: %[[SPLAT:.*]] = cir.vec.splat %[[EXT]] : !cir.double, !cir.matrix<5 x 
5 x !cir.double>
+// CIR: cir.fsub %{{.*}}, %[[SPLAT]] : !cir.matrix<5 x 5 x !cir.double>
+
+// LLVM-LABEL: define {{.*}}void @sub_matrix_scalar_double_float(
+// LLVM: %[[SCALAR:.*]] = load float, ptr {{.*}}, align 4
+// LLVM: %[[EXT:.*]] = fpext float %[[SCALAR]] to double
+// LLVM: %[[EMBED:.*]] = insertelement <25 x double> poison, double %[[EXT]], 
i64 0
+// LLVM: %[[SPLAT:.*]] = shufflevector <25 x double> %[[EMBED]], <25 x double> 
poison, <25 x i32> zeroinitializer
+// LLVM: fsub <25 x double> %{{.*}}, %[[SPLAT]]
+
+void sub_matrix_scalar_int_long() {
+  ix9x3_t a;
+  long vl;
+  a = a - vl;
+}
+
+// CIR-LABEL: cir.func {{.*}}@sub_matrix_scalar_int_long
+// CIR: %[[SCALAR:.*]] = cir.load {{.*}} : !cir.ptr<!s64i>, !s64i
+// CIR: %[[TRUNC:.*]] = cir.cast integral %[[SCALAR]] : !s64i -> !s32i
+// CIR: %[[SPLAT:.*]] = cir.vec.splat %[[TRUNC]] : !s32i, !cir.matrix<9 x 3 x 
!s32i>
+// CIR: cir.sub %{{.*}}, %[[SPLAT]] : !cir.matrix<9 x 3 x !s32i>
+
+// LLVM-LABEL: define {{.*}}void @sub_matrix_scalar_int_long(
+// LLVM: %[[SCALAR:.*]] = load i64, ptr {{.*}}, align 8
+// LLVM: %[[TRUNC:.*]] = trunc i64 %[[SCALAR]] to i32
+// LLVM: %[[EMBED:.*]] = insertelement <27 x i32> poison, i32 %[[TRUNC]], i64 0
+// LLVM: %[[SPLAT:.*]] = shufflevector <27 x i32> %[[EMBED]], <27 x i32> 
poison, <27 x i32> zeroinitializer
+// LLVM: sub <27 x i32> %{{.*}}, %[[SPLAT]]
+
+void sub_compound_matrix_scalar_float_float() {
+  fx2x3_t b;
+  float vf;
+  b -= vf;
+}
+
+// CIR-LABEL: cir.func {{.*}}@sub_compound_matrix_scalar_float_float
+// CIR: %[[SPLAT:.*]] = cir.vec.splat %{{.*}} : !cir.float, !cir.matrix<2 x 3 
x !cir.float>
+// CIR: cir.fsub %{{.*}}, %[[SPLAT]] : !cir.matrix<2 x 3 x !cir.float>
+
+// LLVM-LABEL: define {{.*}}void @sub_compound_matrix_scalar_float_float(
+// LLVM: %[[EMBED:.*]] = insertelement <6 x float> poison, float %{{.*}}, i64 0
+// LLVM: %[[SPLAT:.*]] = shufflevector <6 x float> %[[EMBED]], <6 x float> 
poison, <6 x i32> zeroinitializer
+// LLVM: fsub <6 x float> %{{.*}}, %[[SPLAT]]
diff --git a/clang/test/CIR/IR/matrix.cir b/clang/test/CIR/IR/matrix.cir
index ea4f239a13146..1a5e1cc387601 100644
--- a/clang/test/CIR/IR/matrix.cir
+++ b/clang/test/CIR/IR/matrix.cir
@@ -33,6 +33,22 @@ cir.func @matrix_add(%arg0: !cir.matrix<2 x 3 x !s32i>, 
%arg1: !cir.matrix<2 x 3
 // CHECK:   cir.return
 // CHECK: }
 
+cir.func @matrix_sub(%arg0: !cir.matrix<2 x 3 x !s32i>, %arg1: !cir.matrix<2 x 
3 x !s32i>,
+                     %arg2: !cir.matrix<3 x 3 x !cir.float>, %arg3: 
!cir.matrix<3 x 3 x !cir.float>) {
+  %0 = cir.sub %arg0, %arg1 : !cir.matrix<2 x 3 x !s32i>
+  %1 = cir.sub nsw %arg0, %arg1 : !cir.matrix<2 x 3 x !s32i>
+  %2 = cir.fsub %arg2, %arg3 : !cir.matrix<3 x 3 x !cir.float>
+  cir.return
+}
+
+// CHECK: cir.func @matrix_sub(%[[A:.*]]: !cir.matrix<2 x 3 x !s32i>, 
%[[B:.*]]: !cir.matrix<2 x 3 x !s32i>,
+// CHECK-SAME: %[[C:.*]]: !cir.matrix<3 x 3 x !cir.float>, %[[D:.*]]: 
!cir.matrix<3 x 3 x !cir.float>) {
+// CHECK:   %{{.*}} = cir.sub %[[A]], %[[B]] : !cir.matrix<2 x 3 x !s32i>
+// CHECK:   %{{.*}} = cir.sub nsw %[[A]], %[[B]] : !cir.matrix<2 x 3 x !s32i>
+// CHECK:   %{{.*}} = cir.fsub %[[C]], %[[D]] : !cir.matrix<3 x 3 x !cir.float>
+// CHECK:   cir.return
+// CHECK: }
+
 cir.func @matrix_splat(%arg0: !s32i, %arg1: !cir.float) {
   %0 = cir.vec.splat %arg0 : !s32i, !cir.matrix<2 x 3 x !s32i>
   %1 = cir.vec.splat %arg1 : !cir.float, !cir.matrix<3 x 3 x !cir.float>
diff --git a/clang/test/CIR/Lowering/matrix-sub.cir 
b/clang/test/CIR/Lowering/matrix-sub.cir
new file mode 100644
index 0000000000000..8b2b7684365a5
--- /dev/null
+++ b/clang/test/CIR/Lowering/matrix-sub.cir
@@ -0,0 +1,70 @@
+// RUN: cir-opt %s -cir-to-llvm -o - | FileCheck %s -check-prefix=MLIR
+// RUN: cir-translate %s -cir-to-llvmir --target x86_64-unknown-linux-gnu 
--disable-cc-lowering | FileCheck %s -check-prefix=LLVM
+
+!s32i = !cir.int<s, 32>
+
+module {
+  cir.func @int_matrix_sub(%arg0: !cir.matrix<2 x 3 x !s32i>,
+                           %arg1: !cir.matrix<2 x 3 x !s32i>) -> !cir.matrix<2 
x 3 x !s32i> {
+    %0 = cir.sub %arg0, %arg1 : !cir.matrix<2 x 3 x !s32i>
+    cir.return %0 : !cir.matrix<2 x 3 x !s32i>
+  }
+
+  // MLIR-LABEL: llvm.func @int_matrix_sub
+  // MLIR: llvm.sub %{{.*}}, %{{.*}} : vector<6xi32>
+  // LLVM-LABEL: define {{.*}}@int_matrix_sub(
+  // LLVM: sub <6 x i32> %{{.*}}, %{{.*}}
+
+  cir.func @int_matrix_sub_nsw(%arg0: !cir.matrix<2 x 3 x !s32i>,
+                               %arg1: !cir.matrix<2 x 3 x !s32i>) -> 
!cir.matrix<2 x 3 x !s32i> {
+    %0 = cir.sub nsw %arg0, %arg1 : !cir.matrix<2 x 3 x !s32i>
+    cir.return %0 : !cir.matrix<2 x 3 x !s32i>
+  }
+
+  // MLIR-LABEL: llvm.func @int_matrix_sub_nsw
+  // MLIR: llvm.sub %{{.*}}, %{{.*}} overflow<nsw> : vector<6xi32>
+  // LLVM-LABEL: define {{.*}}@int_matrix_sub_nsw(
+  // LLVM: sub nsw <6 x i32> %{{.*}}, %{{.*}}
+
+  cir.func @fp_matrix_sub(%arg0: !cir.matrix<3 x 3 x !cir.float>,
+                          %arg1: !cir.matrix<3 x 3 x !cir.float>) -> 
!cir.matrix<3 x 3 x !cir.float> {
+    %0 = cir.fsub %arg0, %arg1 : !cir.matrix<3 x 3 x !cir.float>
+    cir.return %0 : !cir.matrix<3 x 3 x !cir.float>
+  }
+
+  // MLIR-LABEL: llvm.func @fp_matrix_sub
+  // MLIR: llvm.fsub %{{.*}}, %{{.*}} : vector<9xf32>
+  // LLVM-LABEL: define {{.*}}@fp_matrix_sub(
+  // LLVM: fsub <9 x float> %{{.*}}, %{{.*}}
+
+  cir.func @matrix_splat_sub(%arg0: !cir.matrix<3 x 3 x !cir.float>,
+                             %arg1: !cir.float) -> !cir.matrix<3 x 3 x 
!cir.float> {
+    %0 = cir.vec.splat %arg1 : !cir.float, !cir.matrix<3 x 3 x !cir.float>
+    %1 = cir.fsub %arg0, %0 : !cir.matrix<3 x 3 x !cir.float>
+    cir.return %1 : !cir.matrix<3 x 3 x !cir.float>
+  }
+
+  // MLIR-LABEL: llvm.func @matrix_splat_sub
+  // MLIR: %[[POISON:.*]] = llvm.mlir.poison : vector<9xf32>
+  // MLIR: %[[IDX:.*]] = llvm.mlir.constant(0 : i64) : i64
+  // MLIR: %[[INS:.*]] = llvm.insertelement %{{.*}}, %[[POISON]][%[[IDX]] : 
i64] : vector<9xf32>
+  // MLIR: %[[SPLAT:.*]] = llvm.shufflevector %[[INS]], %[[POISON]] [0, 0, 0, 
0, 0, 0, 0, 0, 0] : vector<9xf32>
+  // MLIR: llvm.fsub %{{.*}}, %[[SPLAT]] : vector<9xf32>
+  // LLVM-LABEL: define {{.*}}@matrix_splat_sub(
+  // LLVM: %[[INS:.*]] = insertelement <9 x float> poison, float %{{.*}}, i64 0
+  // LLVM: %[[SPLAT:.*]] = shufflevector <9 x float> %[[INS]], <9 x float> 
poison, <9 x i32> zeroinitializer
+  // LLVM: fsub <9 x float> %{{.*}}, %[[SPLAT]]
+
+  // A splat of a constant lowers to a dense constant vector.
+  cir.func @matrix_const_splat() -> !cir.matrix<2 x 3 x !s32i> {
+    %0 = cir.const #cir.int<7> : !s32i
+    %1 = cir.vec.splat %0 : !s32i, !cir.matrix<2 x 3 x !s32i>
+    cir.return %1 : !cir.matrix<2 x 3 x !s32i>
+  }
+
+  // MLIR-LABEL: llvm.func @matrix_const_splat
+  // MLIR: %[[C:.*]] = llvm.mlir.constant(dense<7> : vector<6xi32>) : 
vector<6xi32>
+  // MLIR: llvm.return %[[C]]
+  // LLVM-LABEL: define {{.*}}@matrix_const_splat(
+  // LLVM: ret <6 x i32> splat (i32 7)
+}

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to