[clang] [CIR] Implement matrix scalar multiplication support (PR #230815)
Amr Hesham via cfe-commits
cfe-commits at lists.llvm.org
Mon Oct 12 09:58:27 PDT 2026
https://github.com/AmrDeveloper updated https://github.com/llvm/llvm-project/pull/230815
>From 601dc568d7eb69d0895d510231f9bb01cbe4b4e3 Mon Sep 17 00:00:00 2001
From: Amr Hesham <amr96 at programmer.net>
Date: Sat, 10 Oct 2026 18:21:51 +0200
Subject: [PATCH 1/2] [CIR] Implement matrix scalar multiplication support
---
clang/include/clang/CIR/Dialect/IR/CIROps.td | 11 +++++++----
clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp | 12 +++++++++---
clang/test/CIR/CodeGen/matrix.cpp | 1 +
3 files changed, 17 insertions(+), 7 deletions(-)
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index aa32ada090f91..b0b3d03cefa59 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -2860,12 +2860,12 @@ def CIR_SubOp
// MulOp
//===----------------------------------------------------------------------===//
-def CIR_MulOp : CIR_BinaryOp<"mul", CIR_AnyIntOrVecOfIntType> {
+def CIR_MulOp : CIR_BinaryOp<"mul", CIR_AnyIntOrVecOrMatrixOfIntType> {
let summary = "Integer multiplication";
let description = [{
The `cir.mul` operation performs multiplication on integer operands. Both
operands and the result must have the same integer or vector-of-integer
- type.
+ 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
@@ -2878,11 +2878,13 @@ def CIR_MulOp : CIR_BinaryOp<"mul", CIR_AnyIntOrVecOfIntType> {
%1 = cir.mul nsw %a, %b : !s32i
%2 = cir.mul nuw %a, %b : !u32i
%3 = cir.mul %va, %vb : !cir.vector<4 x !s32i>
+ %4 = cir.mul %ma, %mb : !cir.matrix<3 x 3 x !s32i>
```
}];
let arguments = (ins
- CIR_AnyIntOrVecOfIntType:$lhs, CIR_AnyIntOrVecOfIntType:$rhs,
+ CIR_AnyIntOrVecOrMatrixOfIntType:$lhs,
+ CIR_AnyIntOrVecOrMatrixOfIntType:$rhs,
UnitProp:$no_signed_wrap,
UnitProp:$no_unsigned_wrap
);
@@ -3001,6 +3003,7 @@ def CIR_FSubOp
operands. Both operands and the result must have the same floating-point
scalar vector-of-float or matrix-of-float type.
+
Example:
```
@@ -3018,7 +3021,7 @@ def CIR_FSubOp
// FMulOp
//===----------------------------------------------------------------------===//
-def CIR_FMulOp : CIR_FPBinaryOp<"fmul"> {
+def CIR_FMulOp : CIR_FPBinaryOp<"fmul", [], CIR_AnyFloatOrVecOrMatrixOfFloatType> {
let summary = "Floating-point multiplication";
let description = [{
The `cir.fmul` operation performs floating-point multiplication on its
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index d08b686917536..fbf3e90d14369 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
@@ -2251,15 +2251,21 @@ mlir::Value ScalarExprEmitter::emitMul(const BinOpInfo &ops) {
cgf.cgm.errorNYI("sanitizers");
}
}
+
if (ops.fullType->isConstantMatrixType()) {
+ CIRGenFunction::CIRGenFPOptionsRAII fpOptsRAII(cgf, ops.fpFeatures);
+
if (isa<cir::MatrixType>(ops.lhs.getType()) &&
isa<cir::MatrixType>(ops.rhs.getType()))
return builder.createMatrixMultiply(loc, ops.lhs, ops.rhs);
- assert(!cir::MissingFeatures::matrixType());
- cgf.cgm.errorNYI("ScalarExprEmitter::emitMul: matrix scalar multiply");
- return {};
+ auto [lhs, rhs] =
+ builder.splatMatrixOpOperandsIfNecessary(loc, ops.lhs, ops.rhs);
+ if (cir::isFPOrVectorOrMatrixOfFPType(lhs.getType()))
+ return builder.createFMul(loc, lhs, rhs);
+ return builder.createMul(loc, lhs, rhs);
}
+
if (ops.compType->isUnsignedIntegerType() &&
cgf.sanOpts.has(SanitizerKind::UnsignedIntegerOverflow) &&
!canElideOverflowCheck(cgf.getContext(), ops))
diff --git a/clang/test/CIR/CodeGen/matrix.cpp b/clang/test/CIR/CodeGen/matrix.cpp
index 60196ad2f6d15..9125694f2045c 100644
--- a/clang/test/CIR/CodeGen/matrix.cpp
+++ b/clang/test/CIR/CodeGen/matrix.cpp
@@ -8,6 +8,7 @@
typedef float matrix3x3 __attribute__((matrix_type(3, 3)));
typedef float matrix3x2 __attribute__((matrix_type(3, 2)));
typedef float matrix2x3 __attribute__((matrix_type(2, 3)));
+typedef int matrixi3x3 __attribute__((matrix_type(3, 3)));
matrix3x3 a;
>From 08a4cc492bea1460fe5a19c63001308fc57cded1 Mon Sep 17 00:00:00 2001
From: Amr Hesham <amr96 at programmer.net>
Date: Sun, 11 Oct 2026 15:36:57 +0200
Subject: [PATCH 2/2] Remove old test
---
clang/test/CIR/IR/invalid-matrix.cir | 11 -----------
1 file changed, 11 deletions(-)
diff --git a/clang/test/CIR/IR/invalid-matrix.cir b/clang/test/CIR/IR/invalid-matrix.cir
index 9fe1eb5d798c0..d8d3758664463 100644
--- a/clang/test/CIR/IR/invalid-matrix.cir
+++ b/clang/test/CIR/IR/invalid-matrix.cir
@@ -103,17 +103,6 @@ cir.func @add_mismatched_matrix_types(%arg0: !cir.matrix<2 x 2 x !s32i>, %arg1:
!s32i = !cir.int<s, 32>
-// Only element-wise ops accept matrices; mul on a matrix is not element-wise.
-cir.func @mul_of_matrix(%arg0: !cir.matrix<2 x 2 x !s32i>) {
- // expected-error at +1 {{'cir.mul' op operand #0 must be integer or vector of integer type}}
- %0 = cir.mul %arg0, %arg0 : !cir.matrix<2 x 2 x !s32i>
- cir.return
-}
-
-// -----
-
-!s32i = !cir.int<s, 32>
-
cir.func @splat_element_type_mismatch(%arg0: !s32i) {
// expected-error at +1 {{type of 'value' matches element type of 'result'}}
%0 = cir.vec.splat %arg0 : !s32i, !cir.matrix<2 x 2 x !cir.float>
More information about the cfe-commits
mailing list