[Mlir-commits] [mlir] 84fe39a - [mlir][emitc] Add a cast op
Marius Brehler
llvmlistbot at llvm.org
Thu Apr 28 08:51:37 PDT 2022
Author: Marius Brehler
Date: 2022-04-28T15:50:59Z
New Revision: 84fe39a45b7340d468378f58836c8559fda3959b
URL: https://github.com/llvm/llvm-project/commit/84fe39a45b7340d468378f58836c8559fda3959b
DIFF: https://github.com/llvm/llvm-project/commit/84fe39a45b7340d468378f58836c8559fda3959b.diff
LOG: [mlir][emitc] Add a cast op
This adds a cast operation that allows to perform an explicit type
conversion. The cast op is emitted as a C-style cast. It can be applied
to integer, float, index and EmitC types.
Reviewed By: jpienaar
Differential Revision: https://reviews.llvm.org/D123514
Added:
mlir/test/Target/Cpp/cast.mlir
Modified:
mlir/include/mlir/Dialect/EmitC/IR/EmitC.td
mlir/lib/Dialect/EmitC/IR/CMakeLists.txt
mlir/lib/Dialect/EmitC/IR/EmitC.cpp
mlir/lib/Target/Cpp/TranslateToCpp.cpp
mlir/test/Dialect/EmitC/invalid_ops.mlir
mlir/test/Dialect/EmitC/ops.mlir
Removed:
################################################################################
diff --git a/mlir/include/mlir/Dialect/EmitC/IR/EmitC.td b/mlir/include/mlir/Dialect/EmitC/IR/EmitC.td
index e67ac05ebaf20..6ddf10e7935dd 100644
--- a/mlir/include/mlir/Dialect/EmitC/IR/EmitC.td
+++ b/mlir/include/mlir/Dialect/EmitC/IR/EmitC.td
@@ -16,6 +16,7 @@
include "mlir/Dialect/EmitC/IR/EmitCAttributes.td"
include "mlir/Dialect/EmitC/IR/EmitCTypes.td"
+include "mlir/Interfaces/CastInterfaces.td"
include "mlir/Interfaces/SideEffectInterfaces.td"
//===----------------------------------------------------------------------===//
@@ -88,6 +89,33 @@ def EmitC_CallOp : EmitC_Op<"call", []> {
let hasVerifier = 1;
}
+def EmitC_CastOp : EmitC_Op<"cast", [
+ DeclareOpInterfaceMethods<CastOpInterface>,
+ SameOperandsAndResultShape
+ ]> {
+ let summary = "Cast operation";
+ let description = [{
+ The `cast` operation performs an explicit type conversion and is emitted
+ as a C-style cast expression. It can be applied to integer, float, index
+ and EmitC types.
+
+ Example:
+
+ ```mlir
+ // Cast from `int32_t` to `float`
+ %0 = emitc.cast %arg0: i32 to f32
+
+ // Cast from `void` to `int32_t` pointer
+ %1 = emitc.cast %arg1 :
+ !emitc.ptr<!emitc.opaque<"void">> to !emitc.ptr<i32>
+ ```
+ }];
+
+ let arguments = (ins AnyType:$source);
+ let results = (outs AnyType:$dest);
+ let assemblyFormat = "$source attr-dict `:` type($source) `to` type($dest)";
+}
+
def EmitC_ConstantOp : EmitC_Op<"constant", [ConstantLike]> {
let summary = "Constant operation";
let description = [{
diff --git a/mlir/lib/Dialect/EmitC/IR/CMakeLists.txt b/mlir/lib/Dialect/EmitC/IR/CMakeLists.txt
index 6283441fdadff..1eaa8ce68ce58 100644
--- a/mlir/lib/Dialect/EmitC/IR/CMakeLists.txt
+++ b/mlir/lib/Dialect/EmitC/IR/CMakeLists.txt
@@ -9,6 +9,7 @@ add_mlir_dialect_library(MLIREmitC
MLIREmitCAttributesIncGen
LINK_LIBS PUBLIC
+ MLIRCastInterfaces
MLIRIR
MLIRSideEffectInterfaces
)
diff --git a/mlir/lib/Dialect/EmitC/IR/EmitC.cpp b/mlir/lib/Dialect/EmitC/IR/EmitC.cpp
index a1e6db238f607..a310495bffc71 100644
--- a/mlir/lib/Dialect/EmitC/IR/EmitC.cpp
+++ b/mlir/lib/Dialect/EmitC/IR/EmitC.cpp
@@ -62,6 +62,19 @@ LogicalResult ApplyOp::verify() {
return success();
}
+//===----------------------------------------------------------------------===//
+// CastOp
+//===----------------------------------------------------------------------===//
+
+bool CastOp::areCastCompatible(TypeRange inputs, TypeRange outputs) {
+ Type input = inputs.front(), output = outputs.front();
+
+ return ((input.isa<IntegerType, FloatType, IndexType, emitc::OpaqueType,
+ emitc::PointerType>()) &&
+ (output.isa<IntegerType, FloatType, IndexType, emitc::OpaqueType,
+ emitc::PointerType>()));
+}
+
//===----------------------------------------------------------------------===//
// CallOp
//===----------------------------------------------------------------------===//
diff --git a/mlir/lib/Target/Cpp/TranslateToCpp.cpp b/mlir/lib/Target/Cpp/TranslateToCpp.cpp
index dc3336f67b409..4eaa686e56d8f 100644
--- a/mlir/lib/Target/Cpp/TranslateToCpp.cpp
+++ b/mlir/lib/Target/Cpp/TranslateToCpp.cpp
@@ -383,6 +383,21 @@ static LogicalResult printOperation(CppEmitter &emitter,
return success();
}
+static LogicalResult printOperation(CppEmitter &emitter, emitc::CastOp castOp) {
+ raw_ostream &os = emitter.ostream();
+ Operation &op = *castOp.getOperation();
+
+ if (failed(emitter.emitAssignPrefix(op)))
+ return failure();
+ os << "(";
+ if (failed(emitter.emitType(op.getLoc(), op.getResult(0).getType())))
+ return failure();
+ os << ") ";
+ os << emitter.getOrCreateName(castOp.getOperand());
+
+ return success();
+}
+
static LogicalResult printOperation(CppEmitter &emitter,
emitc::IncludeOp includeOp) {
raw_ostream &os = emitter.ostream();
@@ -918,7 +933,7 @@ LogicalResult CppEmitter::emitOperation(Operation &op, bool trailingSemicolon) {
.Case<cf::BranchOp, cf::CondBranchOp>(
[&](auto op) { return printOperation(*this, op); })
// EmitC ops.
- .Case<emitc::ApplyOp, emitc::CallOp, emitc::ConstantOp,
+ .Case<emitc::ApplyOp, emitc::CallOp, emitc::CastOp, emitc::ConstantOp,
emitc::IncludeOp, emitc::VariableOp>(
[&](auto op) { return printOperation(*this, op); })
// Func ops.
diff --git a/mlir/test/Dialect/EmitC/invalid_ops.mlir b/mlir/test/Dialect/EmitC/invalid_ops.mlir
index f6e4701d24466..64753b8096fe0 100644
--- a/mlir/test/Dialect/EmitC/invalid_ops.mlir
+++ b/mlir/test/Dialect/EmitC/invalid_ops.mlir
@@ -93,3 +93,11 @@ func.func @var_attribute_return_type_2() {
%c0 = "emitc.variable"(){value = "nullptr" : !emitc.ptr<i64>} : () -> !emitc.ptr<i32>
return
}
+
+// -----
+
+func.func @cast_tensor(%arg : tensor<f32>) {
+ // expected-error @+1 {{'emitc.cast' op operand type 'tensor<f32>' and result type 'tensor<f32>' are cast incompatible}}
+ %1 = emitc.cast %arg: tensor<f32> to tensor<f32>
+ return
+}
diff --git a/mlir/test/Dialect/EmitC/ops.mlir b/mlir/test/Dialect/EmitC/ops.mlir
index cce9c281b0265..08b2845ff5d9d 100644
--- a/mlir/test/Dialect/EmitC/ops.mlir
+++ b/mlir/test/Dialect/EmitC/ops.mlir
@@ -12,6 +12,11 @@ func.func @f(%arg0: i32, %f: !emitc.opaque<"int32_t">) {
return
}
+func.func @cast(%arg0: i32) {
+ %1 = emitc.cast %arg0: i32 to f32
+ return
+}
+
func.func @c() {
%1 = "emitc.constant"(){value = 42 : i32} : () -> i32
return
diff --git a/mlir/test/Target/Cpp/cast.mlir b/mlir/test/Target/Cpp/cast.mlir
new file mode 100644
index 0000000000000..7254f84e237f4
--- /dev/null
+++ b/mlir/test/Target/Cpp/cast.mlir
@@ -0,0 +1,30 @@
+// RUN: mlir-translate -mlir-to-cpp %s | FileCheck %s
+// CHECK-LABEL: void cast
+func.func @cast(%arg0 : i32) {
+ // CHECK-NEXT: uint32_t [[V1:[^ ]*]] = (uint32_t) [[V0:[^ ]*]]
+ %1 = emitc.cast %arg0: i32 to ui32
+
+ // CHECK-NEXT: int64_t [[V4:[^ ]*]] = (int64_t) [[V0:[^ ]*]]
+ %2 = emitc.cast %arg0: i32 to i64
+ // CHECK-NEXT: int64_t [[V5:[^ ]*]] = (uint64_t) [[V0:[^ ]*]]
+ %3 = emitc.cast %arg0: i32 to ui64
+
+ // CHECK-NEXT: float [[V4:[^ ]*]] = (float) [[V0:[^ ]*]]
+ %4 = emitc.cast %arg0: i32 to f32
+ // CHECK-NEXT: double [[V5:[^ ]*]] = (double) [[V0:[^ ]*]]
+ %5 = emitc.cast %arg0: i32 to f64
+
+ // CHECK-NEXT: bool [[V6:[^ ]*]] = (bool) [[V0:[^ ]*]]
+ %6 = emitc.cast %arg0: i32 to i1
+
+ // CHECK-NEXT: mytype [[V7:[^ ]*]] = (mytype) [[V0:[^ ]*]]
+ %7 = emitc.cast %arg0: i32 to !emitc.opaque<"mytype">
+ return
+}
+
+// CHECK-LABEL: void cast_ptr
+func.func @cast_ptr(%arg0 : !emitc.ptr<!emitc.opaque<"void">>) {
+ // CHECK-NEXT: int32_t* [[V1:[^ ]*]] = (int32_t*) [[V0:[^ ]*]]
+ %1 = emitc.cast %arg0 : !emitc.ptr<!emitc.opaque<"void">> to !emitc.ptr<i32>
+ return
+}
More information about the Mlir-commits
mailing list