[Mlir-commits] [mlir] [emitc][mlir] Add an option to cast array type to ptr type (PR #126385)
Andrey Timonin
llvmlistbot at llvm.org
Sat Feb 8 13:41:52 PST 2025
https://github.com/EtoAndruwa updated https://github.com/llvm/llvm-project/pull/126385
>From e92a135823f9d7237e0451328c06e0ff2e306307 Mon Sep 17 00:00:00 2001
From: Andrey Timonin <timonina1909 at gmail.com>
Date: Sat, 8 Feb 2025 21:40:30 +0300
Subject: [PATCH 1/2] [emitc][mlir] Add an option to cast array type to ptr
type
---
mlir/include/mlir/Dialect/EmitC/IR/EmitC.td | 3 +--
mlir/lib/Dialect/EmitC/IR/EmitC.cpp | 11 ++++++-----
mlir/test/Dialect/EmitC/invalid_ops.mlir | 14 +++++++++++---
mlir/test/Dialect/EmitC/ops.mlir | 5 +++++
4 files changed, 23 insertions(+), 10 deletions(-)
diff --git a/mlir/include/mlir/Dialect/EmitC/IR/EmitC.td b/mlir/include/mlir/Dialect/EmitC/IR/EmitC.td
index 4fbce995ce5b800..360f2e843436368 100644
--- a/mlir/include/mlir/Dialect/EmitC/IR/EmitC.td
+++ b/mlir/include/mlir/Dialect/EmitC/IR/EmitC.td
@@ -266,8 +266,7 @@ def EmitC_CallOpaqueOp : EmitC_Op<"call_opaque", [CExpression]> {
def EmitC_CastOp : EmitC_Op<"cast",
[CExpression,
- DeclareOpInterfaceMethods<CastOpInterface>,
- SameOperandsAndResultShape]> {
+ DeclareOpInterfaceMethods<CastOpInterface>]> {
let summary = "Cast operation";
let description = [{
The `emitc.cast` operation performs an explicit type conversion and is emitted
diff --git a/mlir/lib/Dialect/EmitC/IR/EmitC.cpp b/mlir/lib/Dialect/EmitC/IR/EmitC.cpp
index 728a2d33f46e7f3..01effa5734caa6e 100644
--- a/mlir/lib/Dialect/EmitC/IR/EmitC.cpp
+++ b/mlir/lib/Dialect/EmitC/IR/EmitC.cpp
@@ -247,11 +247,12 @@ LogicalResult emitc::AssignOp::verify() {
bool CastOp::areCastCompatible(TypeRange inputs, TypeRange outputs) {
Type input = inputs.front(), output = outputs.front();
- return (
- (emitc::isIntegerIndexOrOpaqueType(input) ||
- emitc::isSupportedFloatType(input) || isa<emitc::PointerType>(input)) &&
- (emitc::isIntegerIndexOrOpaqueType(output) ||
- emitc::isSupportedFloatType(output) || isa<emitc::PointerType>(output)));
+ return ((emitc::isIntegerIndexOrOpaqueType(input) ||
+ emitc::isSupportedFloatType(input) ||
+ isa<emitc::PointerType>(input) || isa<emitc::ArrayType>(input)) &&
+ (emitc::isIntegerIndexOrOpaqueType(output) ||
+ emitc::isSupportedFloatType(output) ||
+ isa<emitc::PointerType>(output)));
}
//===----------------------------------------------------------------------===//
diff --git a/mlir/test/Dialect/EmitC/invalid_ops.mlir b/mlir/test/Dialect/EmitC/invalid_ops.mlir
index a0d8d7f59de1156..c40195dd3473aa7 100644
--- a/mlir/test/Dialect/EmitC/invalid_ops.mlir
+++ b/mlir/test/Dialect/EmitC/invalid_ops.mlir
@@ -130,9 +130,17 @@ func.func @cast_tensor(%arg : tensor<f32>) {
// -----
-func.func @cast_array(%arg : !emitc.array<4xf32>) {
- // expected-error @+1 {{'emitc.cast' op operand type '!emitc.array<4xf32>' and result type '!emitc.array<4xf32>' are cast incompatible}}
- %1 = emitc.cast %arg: !emitc.array<4xf32> to !emitc.array<4xf32>
+func.func @cast_to_array(%arg : f32) {
+ // expected-error @+1 {{'emitc.cast' op operand type 'f32' and result type '!emitc.array<4xf32>' are cast incompatible}}
+ %1 = emitc.cast %arg: f32 to !emitc.array<4xf32>
+ return
+}
+
+// -----
+
+func.func @cast_pointer_to_array(%arg : !emitc.ptr<i32>) {
+ // expected-error @+1 {{'emitc.cast' op operand type '!emitc.ptr<i32>' and result type '!emitc.array<3xi32>' are cast incompatible}}
+ %1 = emitc.cast %arg: !emitc.ptr<i32> to !emitc.array<3xi32>
return
}
diff --git a/mlir/test/Dialect/EmitC/ops.mlir b/mlir/test/Dialect/EmitC/ops.mlir
index 7fd0a2d020397b6..c6f90f560085559 100644
--- a/mlir/test/Dialect/EmitC/ops.mlir
+++ b/mlir/test/Dialect/EmitC/ops.mlir
@@ -39,6 +39,11 @@ func.func @cast(%arg0: i32) {
return
}
+func.func @cast_array_to_pointer(%arg0: !emitc.array<3xi32>) {
+ %1 = emitc.cast %arg0: !emitc.array<3xi32> to !emitc.ptr<i32>
+ return
+}
+
func.func @c() {
%1 = "emitc.constant"(){value = 42 : i32} : () -> i32
%2 = "emitc.constant"(){value = 42 : index} : () -> !emitc.size_t
>From 845126ecee5d690b7906ab0ae9a68eeb45530390 Mon Sep 17 00:00:00 2001
From: EtoAndruwa <timonina1909 at gmail.com>
Date: Sun, 9 Feb 2025 00:41:40 +0300
Subject: [PATCH 2/2] [emitc][mlir] Strengthen type and rank checks
---
mlir/lib/Dialect/EmitC/IR/EmitC.cpp | 29 +++++++++++++++---------
mlir/test/Dialect/EmitC/invalid_ops.mlir | 24 ++++++++++++++++++++
2 files changed, 42 insertions(+), 11 deletions(-)
diff --git a/mlir/lib/Dialect/EmitC/IR/EmitC.cpp b/mlir/lib/Dialect/EmitC/IR/EmitC.cpp
index 01effa5734caa6e..80581a9f814acfb 100644
--- a/mlir/lib/Dialect/EmitC/IR/EmitC.cpp
+++ b/mlir/lib/Dialect/EmitC/IR/EmitC.cpp
@@ -247,12 +247,19 @@ LogicalResult emitc::AssignOp::verify() {
bool CastOp::areCastCompatible(TypeRange inputs, TypeRange outputs) {
Type input = inputs.front(), output = outputs.front();
- return ((emitc::isIntegerIndexOrOpaqueType(input) ||
- emitc::isSupportedFloatType(input) ||
- isa<emitc::PointerType>(input) || isa<emitc::ArrayType>(input)) &&
- (emitc::isIntegerIndexOrOpaqueType(output) ||
- emitc::isSupportedFloatType(output) ||
- isa<emitc::PointerType>(output)));
+ if (auto arrayType = dyn_cast<emitc::ArrayType>(input)) {
+ if (auto pointerType = dyn_cast<emitc::PointerType>(output)) {
+ return (arrayType.getElementType() == pointerType.getPointee()) &&
+ arrayType.getShape().size() == 1 && arrayType.getShape()[0] >= 1;
+ }
+ return false;
+ }
+
+ return (
+ (emitc::isIntegerIndexOrOpaqueType(input) ||
+ emitc::isSupportedFloatType(input) || isa<emitc::PointerType>(input)) &&
+ (emitc::isIntegerIndexOrOpaqueType(output) ||
+ emitc::isSupportedFloatType(output) || isa<emitc::PointerType>(output)));
}
//===----------------------------------------------------------------------===//
@@ -700,9 +707,9 @@ void IfOp::print(OpAsmPrinter &p) {
/// Given the region at `index`, or the parent operation if `index` is None,
/// return the successor regions. These are the regions that may be selected
-/// during the flow of control. `operands` is a set of optional attributes that
-/// correspond to a constant value for each operand, or null if that operand is
-/// not a constant.
+/// during the flow of control. `operands` is a set of optional attributes
+/// that correspond to a constant value for each operand, or null if that
+/// operand is not a constant.
void IfOp::getSuccessorRegions(RegionBranchPoint point,
SmallVectorImpl<RegionSuccessor> ®ions) {
// The `then` and the `else` region branch back to the parent operation.
@@ -1000,8 +1007,8 @@ emitc::ArrayType::cloneWith(std::optional<ArrayRef<int64_t>> shape,
LogicalResult mlir::emitc::LValueType::verify(
llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
mlir::Type value) {
- // Check that the wrapped type is valid. This especially forbids nested lvalue
- // types.
+ // Check that the wrapped type is valid. This especially forbids nested
+ // lvalue types.
if (!isSupportedEmitCType(value))
return emitError()
<< "!emitc.lvalue must wrap supported emitc type, but got " << value;
diff --git a/mlir/test/Dialect/EmitC/invalid_ops.mlir b/mlir/test/Dialect/EmitC/invalid_ops.mlir
index c40195dd3473aa7..b58981689919b78 100644
--- a/mlir/test/Dialect/EmitC/invalid_ops.mlir
+++ b/mlir/test/Dialect/EmitC/invalid_ops.mlir
@@ -138,6 +138,30 @@ func.func @cast_to_array(%arg : f32) {
// -----
+func.func @cast_multidimensional_array(%arg : !emitc.array<1x2xi32>) {
+ // expected-error @+1 {{'emitc.cast' op operand type '!emitc.array<1x2xi32>' and result type '!emitc.ptr<i32>' are cast incompatible}}
+ %1 = emitc.cast %arg: !emitc.array<1x2xi32> to !emitc.ptr<i32>
+ return
+}
+
+// -----
+
+func.func @cast_array_zero_rank(%arg : !emitc.array<0xi32>) {
+ // expected-error @+1 {{'emitc.cast' op operand type '!emitc.array<0xi32>' and result type '!emitc.ptr<i32>' are cast incompatible}}
+ %1 = emitc.cast %arg: !emitc.array<0xi32> to !emitc.ptr<i32>
+ return
+}
+
+// -----
+
+func.func @cast_array_to_pointer_types_mismatch(%arg : !emitc.array<3xi32>) {
+ // expected-error @+1 {{'emitc.cast' op operand type '!emitc.array<3xi32>' and result type '!emitc.ptr<f16>' are cast incompatible}}
+ %1 = emitc.cast %arg: !emitc.array<3xi32> to !emitc.ptr<f16>
+ return
+}
+
+// -----
+
func.func @cast_pointer_to_array(%arg : !emitc.ptr<i32>) {
// expected-error @+1 {{'emitc.cast' op operand type '!emitc.ptr<i32>' and result type '!emitc.array<3xi32>' are cast incompatible}}
%1 = emitc.cast %arg: !emitc.ptr<i32> to !emitc.array<3xi32>
More information about the Mlir-commits
mailing list