https://github.com/AmrDeveloper updated https://github.com/llvm/llvm-project/pull/230808
>From 360e09c290d9af6cd3c38d6828ae263ccb0728fb Mon Sep 17 00:00:00 2001 From: Amr Hesham <[email protected]> Date: Sat, 10 Oct 2026 16:07:36 +0200 Subject: [PATCH 1/2] [CIR] Implement matrix scalar division support --- clang/include/clang/CIR/Dialect/IR/CIROps.td | 10 ++-- clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp | 18 +++++-- clang/test/CIR/CodeGen/matrix.cpp | 56 ++++++++++++++++++++ 3 files changed, 77 insertions(+), 7 deletions(-) diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index b0b3d03cefa59..56526bd11839a 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -2900,12 +2900,12 @@ def CIR_MulOp : CIR_BinaryOp<"mul", CIR_AnyIntOrVecOrMatrixOfIntType> { // DivOp //===----------------------------------------------------------------------===// -def CIR_DivOp : CIR_BinaryOp<"div", CIR_AnyIntOrVecOfIntType> { +def CIR_DivOp : CIR_BinaryOp<"div", CIR_AnyIntOrVecOrMatrixOfIntType> { let summary = "Integer division"; let description = [{ The `cir.div` operation performs division on integer operands. Both operands and the result must have the same integer or vector-of-integer - type. + or matrix-of-integer type. Example: @@ -2913,6 +2913,7 @@ def CIR_DivOp : CIR_BinaryOp<"div", CIR_AnyIntOrVecOfIntType> { %0 = cir.div %a, %b : !s32i %1 = cir.div %a, %b : !u32i %2 = cir.div %va, %vb : !cir.vector<4 x !s32i> + %3 = cir.div %ma, %mb : !cir.matrix<3 x 3 x !s32i> ``` }]; } @@ -3044,12 +3045,12 @@ def CIR_FMulOp : CIR_FPBinaryOp<"fmul", [], CIR_AnyFloatOrVecOrMatrixOfFloatType // FDivOp //===----------------------------------------------------------------------===// -def CIR_FDivOp : CIR_FPBinaryOp<"fdiv"> { +def CIR_FDivOp : CIR_FPBinaryOp<"fdiv", [], CIR_AnyFloatOrVecOrMatrixOfFloatType> { let summary = "Floating-point division"; let description = [{ The `cir.fdiv` operation performs floating-point division on its operands. Both operands and the result must have the same floating-point scalar or - vector-of-float type. + ector-of-float or matrix-of-float type. Example: @@ -3057,6 +3058,7 @@ def CIR_FDivOp : CIR_FPBinaryOp<"fdiv"> { %0 = cir.fdiv %a, %b : !cir.float %1 = cir.fdiv %a, %b : !cir.double %2 = cir.fdiv %va, %vb : !cir.vector<4 x !cir.float> + %3 = cir.fdiv %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 fbf3e90d14369..0cb4bc9b620c1 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp @@ -2290,9 +2290,21 @@ mlir::Value ScalarExprEmitter::emitDiv(const BinOpInfo &ops) { } if (ops.fullType->isConstantMatrixType()) { - assert(!cir::MissingFeatures::matrixType()); - cgf.cgm.errorNYI("ScalarExprEmitter::emitDiv: matrix types"); - return {}; + auto *bo = cast<BinaryOperator>(ops.e); + (void)bo; + assert( + isa<ConstantMatrixType>(bo->getLHS()->getType().getCanonicalType()) && + "first operand must be a matrix"); + assert(bo->getRHS()->getType().getCanonicalType()->isArithmeticType() && + "second operand must be an arithmetic type"); + + auto [lhs, rhs] = + builder.splatMatrixOpOperandsIfNecessary(loc, ops.lhs, ops.rhs); + + CIRGenFunction::CIRGenFPOptionsRAII fpOptsRAII(cgf, ops.fpFeatures); + if (cir::isFPOrVectorOrMatrixOfFPType(lhs.getType())) + return builder.createFDiv(loc, lhs, rhs); + return builder.createDiv(loc, lhs, rhs); } if (ops.isFixedPointOp()) diff --git a/clang/test/CIR/CodeGen/matrix.cpp b/clang/test/CIR/CodeGen/matrix.cpp index 8ef99b87dc68e..0f1ddc743299a 100644 --- a/clang/test/CIR/CodeGen/matrix.cpp +++ b/clang/test/CIR/CodeGen/matrix.cpp @@ -308,3 +308,59 @@ void int_matrix_scalar_mul() { // LLVM: %[[SPLAT_SCALAR:.*]] = shufflevector <9 x i32> %[[SPLAT_SCALAR_INSERT]], <9 x i32> poison, <9 x i32> zeroinitializer // LLVM: %[[RESULT:.*]] = mul <9 x i32> %[[TMP_MATRIX]], %[[SPLAT_SCALAR]] // LLVM: store <9 x i32> %[[RESULT]], ptr %[[RESULT_ADDR]], align 4 + +void fp_matrix_scalar_div() { + matrix3x3 matrix; + float scalar = 3.0f; + matrix3x3 result = matrix / scalar; +} + +// CIR: %[[MATRIX_ADDR:.*]] = cir.alloca "matrix" {{.*}} : !cir.ptr<!cir.matrix<3 x 3 x !cir.float>> +// CIR: %[[SCALAR_ADDR:.*]] = cir.alloca "scalar" {{.*}} init : !cir.ptr<!cir.float> +// CIR: %[[RESULT_ADDR:.*]] = cir.alloca "result" {{.*}} init : !cir.ptr<!cir.matrix<3 x 3 x !cir.float>> +// CIR: %[[CONST_3:.*]] = cir.const #cir.fp<3.000000e+00> : !cir.float +// CIR: cir.store {{.*}} %[[CONST_3]], %[[SCALAR_ADDR]] : !cir.float, !cir.ptr<!cir.float> +// CIR: %[[TMP_MATRIX:.*]] = cir.load {{.*}} %[[MATRIX_ADDR]] : !cir.ptr<!cir.matrix<3 x 3 x !cir.float>>, !cir.matrix<3 x 3 x !cir.float> +// CIR: %[[TMP_SCALAR:.*]] = cir.load {{.*}} %[[SCALAR_ADDR]] : !cir.ptr<!cir.float>, !cir.float +// CIR: %[[SPLAT_SCALAR:.*]] = cir.vec.splat %[[TMP_SCALAR]] : !cir.float, !cir.matrix<3 x 3 x !cir.float> +// CIR: %[[RESULT:.*]] = cir.fdiv %[[TMP_MATRIX]], %[[SPLAT_SCALAR]] : !cir.matrix<3 x 3 x !cir.float> +// CIR: cir.store {{.*}} %[[RESULT]], %[[RESULT_ADDR]] : !cir.matrix<3 x 3 x !cir.float>, !cir.ptr<!cir.matrix<3 x 3 x !cir.float>> + +// LLVM: %[[MATRIX_ADDR:.*]] = alloca [9 x float], align 4 +// LLVM: %[[SCALAR_ADDR:.*]] = alloca float, align 4 +// LLVM: %[[RESULT_ADDR:.*]] = alloca [9 x float], align 4 +// LLVM: store float 3.000000e+00, ptr %[[SCALAR_ADDR]], align 4 +// LLVM: %[[TMP_MATRIX:.*]] = load <9 x float>, ptr %[[MATRIX_ADDR]], align 4 +// LLVM: %[[TMP_SCALAR:.*]] = load float, ptr %[[SCALAR_ADDR]], align 4 +// LLVM: %[[SPLAT_SCALAR_INSERT:.*]] = insertelement <9 x float> poison, float %[[TMP_SCALAR]], i64 0 +// LLVM: %[[SPLAT_SCALAR:.*]] = shufflevector <9 x float> %[[SPLAT_SCALAR_INSERT]], <9 x float> poison, <9 x i32> zeroinitializer +// LLVM: %[[RESULT:.*]] = fdiv <9 x float> %[[TMP_MATRIX]], %[[SPLAT_SCALAR]] +// LLVM: store <9 x float> %[[RESULT]], ptr %[[RESULT_ADDR]], align 4 + +void int_matrix_scalar_div() { + matrixi3x3 matrix; + int scalar = 3; + matrixi3x3 result = matrix / scalar; +} + +// CIR: %[[MATRIX_ADDR:.*]] = cir.alloca "matrix" {{.*}} : !cir.ptr<!cir.matrix<3 x 3 x !s32i>> +// CIR: %[[SCALAR_ADDR:.*]] = cir.alloca "scalar" {{.*}} init : !cir.ptr<!s32i> +// CIR: %[[RESULT_ADDR:.*]] = cir.alloca "result" {{.*}} init : !cir.ptr<!cir.matrix<3 x 3 x !s32i>> +// CIR: %[[CONST_3:.*]] = cir.const #cir.int<3> : !s32i +// CIR: cir.store {{.*}} %[[CONST_3]], %[[SCALAR_ADDR]] : !s32i, !cir.ptr<!s32i> +// CIR: %[[TMP_MATRIX:.*]] = cir.load {{.*}} %[[MATRIX_ADDR]] : !cir.ptr<!cir.matrix<3 x 3 x !s32i>>, !cir.matrix<3 x 3 x !s32i> +// CIR: %[[TMP_SCALAR:.*]] = cir.load {{.*}} %[[SCALAR_ADDR]] : !cir.ptr<!s32i>, !s32i +// CIR: %[[SPLAT_SCALAR:.*]] = cir.vec.splat %[[TMP_SCALAR]] : !s32i, !cir.matrix<3 x 3 x !s32i> +// CIR: %[[RESULT:.*]] = cir.div %[[TMP_MATRIX]], %[[SPLAT_SCALAR]] : !cir.matrix<3 x 3 x !s32i> +// CIR: cir.store {{.*}} %[[RESULT]], %[[RESULT_ADDR]] : !cir.matrix<3 x 3 x !s32i>, !cir.ptr<!cir.matrix<3 x 3 x !s32i>> + +// LLVM: %[[MATRIX_ADDR:.*]] = alloca [9 x i32], align 4 +// LLVM: %[[SCALAR_ADDR:.*]] = alloca i32, align 4 +// LLVM: %[[RESULT_ADDR:.*]] = alloca [9 x i32], align 4 +// LLVM: store i32 3, ptr %[[SCALAR_ADDR]], align 4 +// LLVM: %[[TMP_MATRIX:.*]] = load <9 x i32>, ptr %[[MATRIX_ADDR]], align 4 +// LLVM: %[[TMP_SCALAR:.*]] = load i32, ptr %[[SCALAR_ADDR]], align 4 +// LLVM: %[[SPLAT_SCALAR_INSERT:.*]] = insertelement <9 x i32> poison, i32 %[[TMP_SCALAR]], i64 0 +// LLVM: %[[SPLAT_SCALAR:.*]] = shufflevector <9 x i32> %[[SPLAT_SCALAR_INSERT]], <9 x i32> poison, <9 x i32> zeroinitializer +// LLVM: %[[RESULT:.*]] = sdiv <9 x i32> %[[TMP_MATRIX]], %[[SPLAT_SCALAR]] +// LLVM: store <9 x i32> %[[RESULT]], ptr %[[RESULT_ADDR]], align 4 >From b06af0bd53c1cdcc21527d95c86ae40c7905af5c Mon Sep 17 00:00:00 2001 From: Amr Hesham <[email protected]> Date: Mon, 12 Oct 2026 19:36:55 +0200 Subject: [PATCH 2/2] Address code review comments --- clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp index 0cb4bc9b620c1..ccfb54177138b 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp @@ -2290,12 +2290,9 @@ mlir::Value ScalarExprEmitter::emitDiv(const BinOpInfo &ops) { } if (ops.fullType->isConstantMatrixType()) { - auto *bo = cast<BinaryOperator>(ops.e); - (void)bo; - assert( - isa<ConstantMatrixType>(bo->getLHS()->getType().getCanonicalType()) && - "first operand must be a matrix"); - assert(bo->getRHS()->getType().getCanonicalType()->isArithmeticType() && + assert(mlir::isa<cir::MatrixType>(ops.lhs.getType()) && + "first operand must be a matrix"); + assert(cir::isAnyIntegerOrFloatingPointType(ops.rhs.getType()) && "second operand must be an arithmetic type"); auto [lhs, rhs] = _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
