[clang] [CIR] Implement 'matrix-subtraction' lowering. (PR #230536)
Erich Keane via cfe-commits
cfe-commits at lists.llvm.org
Fri Oct 9 13:06:22 PDT 2026
https://github.com/erichkeane updated https://github.com/llvm/llvm-project/pull/230536
>From 6d9296330ac224239928c7e1cd7a70b5f75e22a2 Mon Sep 17 00:00:00 2001
From: erichkeane <ekeane at nvidia.com>
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)
+}
More information about the cfe-commits
mailing list