[Mlir-commits] [mlir] [mlir][emitc] Add EmitC index types (PR #93155)

Corentin Ferry llvmlistbot at llvm.org
Wed Jun 12 05:52:46 PDT 2024


https://github.com/cferry-AMD updated https://github.com/llvm/llvm-project/pull/93155

>From 150501bc0643b92410b70078e9d69ed54c12d47a Mon Sep 17 00:00:00 2001
From: Corentin Ferry <corentin.ferry at amd.com>
Date: Thu, 16 May 2024 15:25:40 +0200
Subject: [PATCH 01/11] Add EmitC index types

---
 mlir/include/mlir/Dialect/EmitC/IR/EmitC.h    |  4 ++
 mlir/include/mlir/Dialect/EmitC/IR/EmitC.td   |  5 ++-
 .../mlir/Dialect/EmitC/IR/EmitCTypes.td       |  9 +++++
 .../EmitC/Transforms/TypeConversions.h        | 17 ++++++++
 mlir/lib/Dialect/EmitC/IR/EmitC.cpp           | 25 +++++++++---
 .../Dialect/EmitC/Transforms/CMakeLists.txt   |  1 +
 .../EmitC/Transforms/TypeConversions.cpp      | 39 +++++++++++++++++++
 mlir/lib/Target/Cpp/TranslateToCpp.cpp        |  4 ++
 mlir/test/Dialect/EmitC/invalid_ops.mlir      |  8 ++--
 mlir/test/Dialect/EmitC/invalid_types.mlir    |  4 +-
 mlir/test/Dialect/EmitC/types.mlir            | 10 +++++
 mlir/test/Target/Cpp/types.mlir               | 10 +++++
 12 files changed, 122 insertions(+), 14 deletions(-)
 create mode 100644 mlir/include/mlir/Dialect/EmitC/Transforms/TypeConversions.h
 create mode 100644 mlir/lib/Dialect/EmitC/Transforms/TypeConversions.cpp

diff --git a/mlir/include/mlir/Dialect/EmitC/IR/EmitC.h b/mlir/include/mlir/Dialect/EmitC/IR/EmitC.h
index 5d9531cd12415..575b91516b919 100644
--- a/mlir/include/mlir/Dialect/EmitC/IR/EmitC.h
+++ b/mlir/include/mlir/Dialect/EmitC/IR/EmitC.h
@@ -43,6 +43,10 @@ bool isIntegerIndexOrOpaqueType(Type type);
 
 /// Determines whether \p type is a valid floating-point type in EmitC.
 bool isSupportedFloatType(mlir::Type type);
+
+/// Determines whether \p type is a emitc.size_t/ssize_t type.
+bool isAnySizeTType(mlir::Type type);
+
 } // namespace emitc
 } // namespace mlir
 
diff --git a/mlir/include/mlir/Dialect/EmitC/IR/EmitC.td b/mlir/include/mlir/Dialect/EmitC/IR/EmitC.td
index 5da8593f59563..071c4bc6bdc8a 100644
--- a/mlir/include/mlir/Dialect/EmitC/IR/EmitC.td
+++ b/mlir/include/mlir/Dialect/EmitC/IR/EmitC.td
@@ -51,7 +51,8 @@ class EmitC_BinaryOp<string mnemonic, list<Trait> traits = []> :
 def CExpression : NativeOpTrait<"emitc::CExpression">;
 
 // Types only used in binary arithmetic operations.
-def IntegerIndexOrOpaqueType : AnyTypeOf<[EmitCIntegerType, Index, EmitC_OpaqueType]>;
+def IntegerIndexOrOpaqueType : AnyTypeOf<[EmitCIntegerType, Index,
+  EmitC_SignedSizeT, EmitC_SizeT, EmitC_OpaqueType]>;
 def FloatIntegerIndexOrOpaqueType : AnyTypeOf<[EmitCFloatType, IntegerIndexOrOpaqueType]>;
 
 def EmitC_AddOp : EmitC_BinaryOp<"add", [CExpression]> {
@@ -470,7 +471,7 @@ def EmitC_ForOp : EmitC_Op<"for",
     upper bound and step respectively, and defines an SSA value for its
     induction variable. It has one region capturing the loop body. The induction
     variable is represented as an argument of this region. This SSA value is a
-    signless integer or index. The step is a value of same type.
+    signless integer, or an index. The step is a value of same type.
 
     This operation has no result. The body region must contain exactly one block
     that terminates with `emitc.yield`. Calling ForOp::build will create such a
diff --git a/mlir/include/mlir/Dialect/EmitC/IR/EmitCTypes.td b/mlir/include/mlir/Dialect/EmitC/IR/EmitCTypes.td
index 444395b915e25..f6a8bd4ef59e1 100644
--- a/mlir/include/mlir/Dialect/EmitC/IR/EmitCTypes.td
+++ b/mlir/include/mlir/Dialect/EmitC/IR/EmitCTypes.td
@@ -76,6 +76,7 @@ def EmitC_ArrayType : EmitC_Type<"Array", "array", [ShapedTypeInterface]> {
 
     static bool isValidElementType(Type type) {
       return type.isIntOrIndexOrFloat() ||
+         emitc::isAnySizeTType(type) ||
          llvm::isa<PointerType, OpaqueType>(type);
     }
   }];
@@ -130,4 +131,12 @@ def EmitC_PointerType : EmitC_Type<"Pointer", "ptr"> {
   let assemblyFormat = "`<` qualified($pointee) `>`";
 }
 
+def EmitC_SignedSizeT : EmitC_Type<"SignedSizeT", "ssize_t"> {
+  let summary = "EmitC signed size type";
+}
+
+def EmitC_SizeT : EmitC_Type<"SizeT", "size_t"> {
+  let summary = "EmitC unsigned size type";
+}
+
 #endif // MLIR_DIALECT_EMITC_IR_EMITCTYPES
diff --git a/mlir/include/mlir/Dialect/EmitC/Transforms/TypeConversions.h b/mlir/include/mlir/Dialect/EmitC/Transforms/TypeConversions.h
new file mode 100644
index 0000000000000..1c05a927e948a
--- /dev/null
+++ b/mlir/include/mlir/Dialect/EmitC/Transforms/TypeConversions.h
@@ -0,0 +1,17 @@
+//===- TypeConversions.h - Convert signless types into C/C++ types -------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_DIALECT_EMITC_TRANSFORMS_TYPECONVERSIONS_H
+#define MLIR_DIALECT_EMITC_TRANSFORMS_TYPECONVERSIONS_H
+
+namespace mlir {
+class TypeConverter;
+void populateEmitCSizeTypeConversions(TypeConverter &converter);
+} // namespace mlir
+
+#endif // MLIR_DIALECT_EMITC_TRANSFORMS_TYPECONVERSIONS_H
diff --git a/mlir/lib/Dialect/EmitC/IR/EmitC.cpp b/mlir/lib/Dialect/EmitC/IR/EmitC.cpp
index ef7b7a19489d4..e855f2119abb3 100644
--- a/mlir/lib/Dialect/EmitC/IR/EmitC.cpp
+++ b/mlir/lib/Dialect/EmitC/IR/EmitC.cpp
@@ -68,7 +68,8 @@ bool mlir::emitc::isSupportedEmitCType(Type type) {
     return !llvm::isa<emitc::ArrayType>(elemType) &&
            isSupportedEmitCType(elemType);
   }
-  if (type.isIndex())
+  if (type.isIndex() ||
+      llvm::isa<emitc::SignedSizeTType, emitc::SizeTType>(type))
     return true;
   if (llvm::isa<IntegerType>(type))
     return isSupportedIntegerType(type);
@@ -109,7 +110,8 @@ bool mlir::emitc::isSupportedIntegerType(Type type) {
 }
 
 bool mlir::emitc::isIntegerIndexOrOpaqueType(Type type) {
-  return llvm::isa<IndexType, emitc::OpaqueType>(type) ||
+  return llvm::isa<IndexType, emitc::SignedSizeTType, emitc::SizeTType,
+                   emitc::OpaqueType>(type) ||
          isSupportedIntegerType(type);
 }
 
@@ -126,6 +128,10 @@ bool mlir::emitc::isSupportedFloatType(Type type) {
   return false;
 }
 
+bool mlir::emitc::isAnySizeTType(Type type) {
+  return isa<emitc::SignedSizeTType, emitc::SizeTType>(type);
+}
+
 /// Check that the type of the initial value is compatible with the operations
 /// result type.
 static LogicalResult verifyInitializationAttribute(Operation *op,
@@ -142,6 +148,10 @@ static LogicalResult verifyInitializationAttribute(Operation *op,
   Type resultType = op->getResult(0).getType();
   Type attrType = cast<TypedAttr>(value).getType();
 
+  if (isa<emitc::SignedSizeTType, emitc::SizeTType>(resultType) &&
+      attrType.isIndex())
+    return success();
+
   if (resultType != attrType)
     return op->emitOpError()
            << "requires attribute to either be an #emitc.opaque attribute or "
@@ -226,10 +236,13 @@ LogicalResult emitc::AssignOp::verify() {
 bool CastOp::areCastCompatible(TypeRange inputs, TypeRange outputs) {
   Type input = inputs.front(), output = outputs.front();
 
-  return ((llvm::isa<IntegerType, FloatType, IndexType, emitc::OpaqueType,
-                     emitc::PointerType>(input)) &&
-          (llvm::isa<IntegerType, FloatType, IndexType, emitc::OpaqueType,
-                     emitc::PointerType>(output)));
+  return (
+      (llvm::isa<IntegerType, FloatType, IndexType, emitc::OpaqueType,
+                 emitc::PointerType, emitc::SignedSizeTType, emitc::SizeTType>(
+          input)) &&
+      (llvm::isa<IntegerType, FloatType, IndexType, emitc::OpaqueType,
+                 emitc::PointerType, emitc::SignedSizeTType, emitc::SizeTType>(
+          output)));
 }
 
 //===----------------------------------------------------------------------===//
diff --git a/mlir/lib/Dialect/EmitC/Transforms/CMakeLists.txt b/mlir/lib/Dialect/EmitC/Transforms/CMakeLists.txt
index bfcc14523f137..19b80b22bd84b 100644
--- a/mlir/lib/Dialect/EmitC/Transforms/CMakeLists.txt
+++ b/mlir/lib/Dialect/EmitC/Transforms/CMakeLists.txt
@@ -1,6 +1,7 @@
 add_mlir_dialect_library(MLIREmitCTransforms
   Transforms.cpp
   FormExpressions.cpp
+  TypeConversions.cpp
 
   ADDITIONAL_HEADER_DIRS
   ${MLIR_MAIN_INCLUDE_DIR}/mlir/Dialect/EmitC/Transforms
diff --git a/mlir/lib/Dialect/EmitC/Transforms/TypeConversions.cpp b/mlir/lib/Dialect/EmitC/Transforms/TypeConversions.cpp
new file mode 100644
index 0000000000000..02987df56f042
--- /dev/null
+++ b/mlir/lib/Dialect/EmitC/Transforms/TypeConversions.cpp
@@ -0,0 +1,39 @@
+//===- TypeConversions.cpp - Convert signless types into C/C++ types ------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/Dialect/EmitC/Transforms/TypeConversions.h"
+#include "mlir/Dialect/EmitC/IR/EmitC.h"
+#include "mlir/IR/BuiltinTypes.h"
+#include "mlir/Transforms/DialectConversion.h"
+#include <optional>
+
+using namespace mlir;
+
+namespace {
+
+std::optional<Value> materializeAsUnrealizedCast(OpBuilder &builder,
+                                                 Type resultType,
+                                                 ValueRange inputs,
+                                                 Location loc) {
+  if (inputs.size() != 1)
+    return std::nullopt;
+
+  return builder.create<UnrealizedConversionCastOp>(loc, resultType, inputs)
+      .getResult(0);
+}
+
+} // namespace
+
+void mlir::populateEmitCSizeTypeConversions(TypeConverter &converter) {
+  converter.addConversion(
+      [](IndexType type) { return emitc::SizeTType::get(type.getContext()); });
+
+  converter.addSourceMaterialization(materializeAsUnrealizedCast);
+  converter.addTargetMaterialization(materializeAsUnrealizedCast);
+  converter.addArgumentMaterialization(materializeAsUnrealizedCast);
+}
diff --git a/mlir/lib/Target/Cpp/TranslateToCpp.cpp b/mlir/lib/Target/Cpp/TranslateToCpp.cpp
index 7db7163bac4ab..d2ba57f679de2 100644
--- a/mlir/lib/Target/Cpp/TranslateToCpp.cpp
+++ b/mlir/lib/Target/Cpp/TranslateToCpp.cpp
@@ -1570,6 +1570,10 @@ LogicalResult CppEmitter::emitType(Location loc, Type type) {
   }
   if (auto iType = dyn_cast<IndexType>(type))
     return (os << "size_t"), success();
+  if (auto iType = dyn_cast<emitc::SizeTType>(type))
+    return (os << "size_t"), success();
+  if (auto iType = dyn_cast<emitc::SignedSizeTType>(type))
+    return (os << "ssize_t"), success();
   if (auto tType = dyn_cast<TensorType>(type)) {
     if (!tType.hasRank())
       return emitError(loc, "cannot emit unranked tensor type");
diff --git a/mlir/test/Dialect/EmitC/invalid_ops.mlir b/mlir/test/Dialect/EmitC/invalid_ops.mlir
index 21ea6a5df91b9..3eede2c72dca4 100644
--- a/mlir/test/Dialect/EmitC/invalid_ops.mlir
+++ b/mlir/test/Dialect/EmitC/invalid_ops.mlir
@@ -170,7 +170,7 @@ func.func @add_float_pointer(%arg0: f32, %arg1: !emitc.ptr<f32>) {
 // -----
 
 func.func @div_tensor(%arg0: tensor<i32>, %arg1: tensor<i32>) {
-    // expected-error @+1 {{'emitc.div' op operand #0 must be floating-point type supported by EmitC or integer type supported by EmitC or index or EmitC opaque type, but got 'tensor<i32>'}}
+    // expected-error @+1 {{'emitc.div' op operand #0 must be floating-point type supported by EmitC or integer type supported by EmitC or index or EmitC signed size type or EmitC unsigned size type or EmitC opaque type, but got 'tensor<i32>'}}
     %1 = "emitc.div" (%arg0, %arg1) : (tensor<i32>, tensor<i32>) -> tensor<i32>
     return
 }
@@ -178,7 +178,7 @@ func.func @div_tensor(%arg0: tensor<i32>, %arg1: tensor<i32>) {
 // -----
 
 func.func @mul_tensor(%arg0: tensor<i32>, %arg1: tensor<i32>) {
-    // expected-error @+1 {{'emitc.mul' op operand #0 must be floating-point type supported by EmitC or integer type supported by EmitC or index or EmitC opaque type, but got 'tensor<i32>'}}
+    // expected-error @+1 {{'emitc.mul' op operand #0 must be floating-point type supported by EmitC or integer type supported by EmitC or index or EmitC signed size type or EmitC unsigned size type or EmitC opaque type, but got 'tensor<i32>'}}
     %1 = "emitc.mul" (%arg0, %arg1) : (tensor<i32>, tensor<i32>) -> tensor<i32>
     return
 }
@@ -186,7 +186,7 @@ func.func @mul_tensor(%arg0: tensor<i32>, %arg1: tensor<i32>) {
 // -----
 
 func.func @rem_tensor(%arg0: tensor<i32>, %arg1: tensor<i32>) {
-    // expected-error @+1 {{'emitc.rem' op operand #0 must be integer type supported by EmitC or index or EmitC opaque type, but got 'tensor<i32>'}}
+    // expected-error @+1 {{'emitc.rem' op operand #0 must be integer type supported by EmitC or index or EmitC signed size type or EmitC unsigned size type or EmitC opaque type, but got 'tensor<i32>'}}
     %1 = "emitc.rem" (%arg0, %arg1) : (tensor<i32>, tensor<i32>) -> tensor<i32>
     return
 }
@@ -194,7 +194,7 @@ func.func @rem_tensor(%arg0: tensor<i32>, %arg1: tensor<i32>) {
 // -----
 
 func.func @rem_float(%arg0: f32, %arg1: f32) {
-    // expected-error @+1 {{'emitc.rem' op operand #0 must be integer type supported by EmitC or index or EmitC opaque type, but got 'f32'}}
+    // expected-error @+1 {{'emitc.rem' op operand #0 must be integer type supported by EmitC or index or EmitC signed size type or EmitC unsigned size type or EmitC opaque type, but got 'f32'}}
     %1 = "emitc.rem" (%arg0, %arg1) : (f32, f32) -> f32
     return
 }
diff --git a/mlir/test/Dialect/EmitC/invalid_types.mlir b/mlir/test/Dialect/EmitC/invalid_types.mlir
index 0ad8d4eabe6b8..111fbc7de640b 100644
--- a/mlir/test/Dialect/EmitC/invalid_types.mlir
+++ b/mlir/test/Dialect/EmitC/invalid_types.mlir
@@ -85,7 +85,7 @@ func.func @illegal_array_with_tensor_element_type(
 // -----
 
 func.func @illegal_integer_type(%arg0: i11, %arg1: i11) -> i11 {
-    // expected-error @+1 {{'emitc.mul' op operand #0 must be floating-point type supported by EmitC or integer type supported by EmitC or index or EmitC opaque type, but got 'i11'}}
+    // expected-error @+1 {{'emitc.mul' op operand #0 must be floating-point type supported by EmitC or integer type supported by EmitC or index or EmitC signed size type or EmitC unsigned size type or EmitC opaque type, but got 'i11'}}
     %mul = "emitc.mul" (%arg0, %arg1) : (i11, i11) -> i11
     return
 }
@@ -93,7 +93,7 @@ func.func @illegal_integer_type(%arg0: i11, %arg1: i11) -> i11 {
 // -----
 
 func.func @illegal_float_type(%arg0: f80, %arg1: f80) {
-    // expected-error @+1 {{'emitc.mul' op operand #0 must be floating-point type supported by EmitC or integer type supported by EmitC or index or EmitC opaque type, but got 'f80'}}
+    // expected-error @+1 {{'emitc.mul' op operand #0 must be floating-point type supported by EmitC or integer type supported by EmitC or index or EmitC signed size type or EmitC unsigned size type or EmitC opaque type, but got 'f80'}}
     %mul = "emitc.mul" (%arg0, %arg1) : (f80, f80) -> f80
     return
 }
diff --git a/mlir/test/Dialect/EmitC/types.mlir b/mlir/test/Dialect/EmitC/types.mlir
index 752f2c10c17be..8b630d5a320f4 100644
--- a/mlir/test/Dialect/EmitC/types.mlir
+++ b/mlir/test/Dialect/EmitC/types.mlir
@@ -53,3 +53,13 @@ func.func @pointer_types() {
 
   return
 }
+
+// CHECK-LABEL: func @index_types() 
+func.func @index_types() {
+  // CHECK-NEXT: !emitc.ssize_t
+  emitc.call_opaque "f"() {template_args = [!emitc.ssize_t]} : () -> ()
+  // CHECK-NEXT: !emitc.size_t
+  emitc.call_opaque "f"() {template_args = [!emitc.size_t]} : () -> ()
+
+  return
+}
diff --git a/mlir/test/Target/Cpp/types.mlir b/mlir/test/Target/Cpp/types.mlir
index 0585b27eb6c22..647777c8ac718 100644
--- a/mlir/test/Target/Cpp/types.mlir
+++ b/mlir/test/Target/Cpp/types.mlir
@@ -35,3 +35,13 @@ func.func @ptr_types() {
 
   return
 }
+
+// CHECK-LABEL: void size_types() {
+func.func @size_types() {
+  // CHECK-NEXT: f<ssize_t>();
+  emitc.call_opaque "f"() {template_args = [!emitc.ssize_t]} : () -> ()
+  // CHECK-NEXT: f<size_t>();
+  emitc.call_opaque "f"() {template_args = [!emitc.size_t]} : () -> ()
+
+  return
+}

>From ceb2d40667a4e3a01e3e0dbf35494e2aa6017afa Mon Sep 17 00:00:00 2001
From: Corentin Ferry <corentin.ferry at amd.com>
Date: Mon, 27 May 2024 14:36:43 +0100
Subject: [PATCH 02/11] Address review comments

---
 mlir/include/mlir/Dialect/EmitC/IR/EmitC.td |  4 ++--
 mlir/lib/Dialect/EmitC/IR/EmitC.cpp         | 11 ++++-------
 mlir/lib/Target/Cpp/TranslateToCpp.cpp      |  4 ++--
 mlir/test/Dialect/EmitC/invalid_ops.mlir    |  8 ++++----
 mlir/test/Dialect/EmitC/invalid_types.mlir  |  4 ++--
 mlir/test/Dialect/EmitC/ops.mlir            |  2 ++
 mlir/test/Dialect/EmitC/types.mlir          | 10 +++++++---
 7 files changed, 23 insertions(+), 20 deletions(-)

diff --git a/mlir/include/mlir/Dialect/EmitC/IR/EmitC.td b/mlir/include/mlir/Dialect/EmitC/IR/EmitC.td
index 071c4bc6bdc8a..452302c565139 100644
--- a/mlir/include/mlir/Dialect/EmitC/IR/EmitC.td
+++ b/mlir/include/mlir/Dialect/EmitC/IR/EmitC.td
@@ -51,8 +51,8 @@ class EmitC_BinaryOp<string mnemonic, list<Trait> traits = []> :
 def CExpression : NativeOpTrait<"emitc::CExpression">;
 
 // Types only used in binary arithmetic operations.
-def IntegerIndexOrOpaqueType : AnyTypeOf<[EmitCIntegerType, Index,
-  EmitC_SignedSizeT, EmitC_SizeT, EmitC_OpaqueType]>;
+def IntegerIndexOrOpaqueType : Type<CPred<"emitc::isIntegerIndexOrOpaqueType($_self)">,
+"integer, index or opaque type supported by EmitC">;
 def FloatIntegerIndexOrOpaqueType : AnyTypeOf<[EmitCFloatType, IntegerIndexOrOpaqueType]>;
 
 def EmitC_AddOp : EmitC_BinaryOp<"add", [CExpression]> {
diff --git a/mlir/lib/Dialect/EmitC/IR/EmitC.cpp b/mlir/lib/Dialect/EmitC/IR/EmitC.cpp
index e855f2119abb3..8a618788eb597 100644
--- a/mlir/lib/Dialect/EmitC/IR/EmitC.cpp
+++ b/mlir/lib/Dialect/EmitC/IR/EmitC.cpp
@@ -68,8 +68,7 @@ bool mlir::emitc::isSupportedEmitCType(Type type) {
     return !llvm::isa<emitc::ArrayType>(elemType) &&
            isSupportedEmitCType(elemType);
   }
-  if (type.isIndex() ||
-      llvm::isa<emitc::SignedSizeTType, emitc::SizeTType>(type))
+  if (type.isIndex() || emitc::isAnySizeTType(type))
     return true;
   if (llvm::isa<IntegerType>(type))
     return isSupportedIntegerType(type);
@@ -110,9 +109,8 @@ bool mlir::emitc::isSupportedIntegerType(Type type) {
 }
 
 bool mlir::emitc::isIntegerIndexOrOpaqueType(Type type) {
-  return llvm::isa<IndexType, emitc::SignedSizeTType, emitc::SizeTType,
-                   emitc::OpaqueType>(type) ||
-         isSupportedIntegerType(type);
+  return llvm::isa<IndexType,emitc::OpaqueType>(type) ||
+         isSupportedIntegerType(type) || isAnySizeTType(type);
 }
 
 bool mlir::emitc::isSupportedFloatType(Type type) {
@@ -148,8 +146,7 @@ static LogicalResult verifyInitializationAttribute(Operation *op,
   Type resultType = op->getResult(0).getType();
   Type attrType = cast<TypedAttr>(value).getType();
 
-  if (isa<emitc::SignedSizeTType, emitc::SizeTType>(resultType) &&
-      attrType.isIndex())
+  if (isAnySizeTType(resultType) && attrType.isIndex())
     return success();
 
   if (resultType != attrType)
diff --git a/mlir/lib/Target/Cpp/TranslateToCpp.cpp b/mlir/lib/Target/Cpp/TranslateToCpp.cpp
index d2ba57f679de2..547319632d2f6 100644
--- a/mlir/lib/Target/Cpp/TranslateToCpp.cpp
+++ b/mlir/lib/Target/Cpp/TranslateToCpp.cpp
@@ -1570,9 +1570,9 @@ LogicalResult CppEmitter::emitType(Location loc, Type type) {
   }
   if (auto iType = dyn_cast<IndexType>(type))
     return (os << "size_t"), success();
-  if (auto iType = dyn_cast<emitc::SizeTType>(type))
+  if (auto sType = dyn_cast<emitc::SizeTType>(type))
     return (os << "size_t"), success();
-  if (auto iType = dyn_cast<emitc::SignedSizeTType>(type))
+  if (auto sType = dyn_cast<emitc::SignedSizeTType>(type))
     return (os << "ssize_t"), success();
   if (auto tType = dyn_cast<TensorType>(type)) {
     if (!tType.hasRank())
diff --git a/mlir/test/Dialect/EmitC/invalid_ops.mlir b/mlir/test/Dialect/EmitC/invalid_ops.mlir
index 3eede2c72dca4..8cd8bdca4df33 100644
--- a/mlir/test/Dialect/EmitC/invalid_ops.mlir
+++ b/mlir/test/Dialect/EmitC/invalid_ops.mlir
@@ -170,7 +170,7 @@ func.func @add_float_pointer(%arg0: f32, %arg1: !emitc.ptr<f32>) {
 // -----
 
 func.func @div_tensor(%arg0: tensor<i32>, %arg1: tensor<i32>) {
-    // expected-error @+1 {{'emitc.div' op operand #0 must be floating-point type supported by EmitC or integer type supported by EmitC or index or EmitC signed size type or EmitC unsigned size type or EmitC opaque type, but got 'tensor<i32>'}}
+    // expected-error @+1 {{'emitc.div' op operand #0 must be floating-point type supported by EmitC or integer, index or opaque type supported by EmitC, but got 'tensor<i32>'}}
     %1 = "emitc.div" (%arg0, %arg1) : (tensor<i32>, tensor<i32>) -> tensor<i32>
     return
 }
@@ -178,7 +178,7 @@ func.func @div_tensor(%arg0: tensor<i32>, %arg1: tensor<i32>) {
 // -----
 
 func.func @mul_tensor(%arg0: tensor<i32>, %arg1: tensor<i32>) {
-    // expected-error @+1 {{'emitc.mul' op operand #0 must be floating-point type supported by EmitC or integer type supported by EmitC or index or EmitC signed size type or EmitC unsigned size type or EmitC opaque type, but got 'tensor<i32>'}}
+    // expected-error @+1 {{'emitc.mul' op operand #0 must be floating-point type supported by EmitC or integer, index or opaque type supported by EmitC, but got 'tensor<i32>'}}
     %1 = "emitc.mul" (%arg0, %arg1) : (tensor<i32>, tensor<i32>) -> tensor<i32>
     return
 }
@@ -186,7 +186,7 @@ func.func @mul_tensor(%arg0: tensor<i32>, %arg1: tensor<i32>) {
 // -----
 
 func.func @rem_tensor(%arg0: tensor<i32>, %arg1: tensor<i32>) {
-    // expected-error @+1 {{'emitc.rem' op operand #0 must be integer type supported by EmitC or index or EmitC signed size type or EmitC unsigned size type or EmitC opaque type, but got 'tensor<i32>'}}
+    // expected-error @+1 {{'emitc.rem' op operand #0 must be integer, index or opaque type supported by EmitC, but got 'tensor<i32>'}}
     %1 = "emitc.rem" (%arg0, %arg1) : (tensor<i32>, tensor<i32>) -> tensor<i32>
     return
 }
@@ -194,7 +194,7 @@ func.func @rem_tensor(%arg0: tensor<i32>, %arg1: tensor<i32>) {
 // -----
 
 func.func @rem_float(%arg0: f32, %arg1: f32) {
-    // expected-error @+1 {{'emitc.rem' op operand #0 must be integer type supported by EmitC or index or EmitC signed size type or EmitC unsigned size type or EmitC opaque type, but got 'f32'}}
+    // expected-error @+1 {{'emitc.rem' op operand #0 must be integer, index or opaque type supported by EmitC, but got 'f32'}}
     %1 = "emitc.rem" (%arg0, %arg1) : (f32, f32) -> f32
     return
 }
diff --git a/mlir/test/Dialect/EmitC/invalid_types.mlir b/mlir/test/Dialect/EmitC/invalid_types.mlir
index 111fbc7de640b..9bf0c49e7199a 100644
--- a/mlir/test/Dialect/EmitC/invalid_types.mlir
+++ b/mlir/test/Dialect/EmitC/invalid_types.mlir
@@ -85,7 +85,7 @@ func.func @illegal_array_with_tensor_element_type(
 // -----
 
 func.func @illegal_integer_type(%arg0: i11, %arg1: i11) -> i11 {
-    // expected-error @+1 {{'emitc.mul' op operand #0 must be floating-point type supported by EmitC or integer type supported by EmitC or index or EmitC signed size type or EmitC unsigned size type or EmitC opaque type, but got 'i11'}}
+    // expected-error @+1 {{'emitc.mul' op operand #0 must be floating-point type supported by EmitC or integer, index or opaque type supported by EmitC, but got 'i11'}}
     %mul = "emitc.mul" (%arg0, %arg1) : (i11, i11) -> i11
     return
 }
@@ -93,7 +93,7 @@ func.func @illegal_integer_type(%arg0: i11, %arg1: i11) -> i11 {
 // -----
 
 func.func @illegal_float_type(%arg0: f80, %arg1: f80) {
-    // expected-error @+1 {{'emitc.mul' op operand #0 must be floating-point type supported by EmitC or integer type supported by EmitC or index or EmitC signed size type or EmitC unsigned size type or EmitC opaque type, but got 'f80'}}
+    // expected-error @+1 {{'emitc.mul' op operand #0 must be floating-point type supported by EmitC or integer, index or opaque type supported by EmitC, but got 'f80'}}
     %mul = "emitc.mul" (%arg0, %arg1) : (f80, f80) -> f80
     return
 }
diff --git a/mlir/test/Dialect/EmitC/ops.mlir b/mlir/test/Dialect/EmitC/ops.mlir
index 05510e6dddbf5..814435e6ef8b5 100644
--- a/mlir/test/Dialect/EmitC/ops.mlir
+++ b/mlir/test/Dialect/EmitC/ops.mlir
@@ -41,6 +41,8 @@ func.func @cast(%arg0: i32) {
 
 func.func @c() {
   %1 = "emitc.constant"(){value = 42 : i32} : () -> i32
+  %2 = "emitc.constant"(){value = 42 : index} : () -> !emitc.size_t
+  %3 = "emitc.constant"(){value = 42 : index} : () -> !emitc.ssize_t
   return
 }
 
diff --git a/mlir/test/Dialect/EmitC/types.mlir b/mlir/test/Dialect/EmitC/types.mlir
index 8b630d5a320f4..5adc49e9dc2a1 100644
--- a/mlir/test/Dialect/EmitC/types.mlir
+++ b/mlir/test/Dialect/EmitC/types.mlir
@@ -11,7 +11,11 @@ func.func @array_types(
   // CHECK-SAME: !emitc.array<30x!emitc.ptr<i32>>,
   %arg2: !emitc.array<30x!emitc.ptr<i32>>,
   // CHECK-SAME: !emitc.array<30x!emitc.opaque<"int">>
-  %arg3: !emitc.array<30x!emitc.opaque<"int">>
+  %arg3: !emitc.array<30x!emitc.opaque<"int">>,
+  // CHECK-SAME: !emitc.array<30x!emitc.size_t>
+  %arg4: !emitc.array<30x!emitc.size_t>,
+  // CHECK-SAME: !emitc.array<30x!emitc.ssize_t>
+  %arg5: !emitc.array<30x!emitc.ssize_t>
 ) {
   return
 }
@@ -54,8 +58,8 @@ func.func @pointer_types() {
   return
 }
 
-// CHECK-LABEL: func @index_types() 
-func.func @index_types() {
+// CHECK-LABEL: func @size_types() 
+func.func @size_types() {
   // CHECK-NEXT: !emitc.ssize_t
   emitc.call_opaque "f"() {template_args = [!emitc.ssize_t]} : () -> ()
   // CHECK-NEXT: !emitc.size_t

>From 1edd8fbf40458b62d949525efd36eb9219e9a6f0 Mon Sep 17 00:00:00 2001
From: Corentin Ferry <corentin.ferry at amd.com>
Date: Mon, 27 May 2024 14:41:54 +0100
Subject: [PATCH 03/11] Fix code formatting

---
 mlir/lib/Dialect/EmitC/IR/EmitC.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mlir/lib/Dialect/EmitC/IR/EmitC.cpp b/mlir/lib/Dialect/EmitC/IR/EmitC.cpp
index 8a618788eb597..d410a60d64aeb 100644
--- a/mlir/lib/Dialect/EmitC/IR/EmitC.cpp
+++ b/mlir/lib/Dialect/EmitC/IR/EmitC.cpp
@@ -109,7 +109,7 @@ bool mlir::emitc::isSupportedIntegerType(Type type) {
 }
 
 bool mlir::emitc::isIntegerIndexOrOpaqueType(Type type) {
-  return llvm::isa<IndexType,emitc::OpaqueType>(type) ||
+  return llvm::isa<IndexType, emitc::OpaqueType>(type) ||
          isSupportedIntegerType(type) || isAnySizeTType(type);
 }
 

>From 5c732b1fdc9d2f8f7218de79f3740746b57ab200 Mon Sep 17 00:00:00 2001
From: Corentin Ferry <corentin.ferry at amd.com>
Date: Tue, 28 May 2024 08:17:07 +0100
Subject: [PATCH 04/11] EmitCSizeType -> EmitCSizeTType

---
 mlir/include/mlir/Dialect/EmitC/Transforms/TypeConversions.h | 2 +-
 mlir/lib/Dialect/EmitC/Transforms/TypeConversions.cpp        | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/mlir/include/mlir/Dialect/EmitC/Transforms/TypeConversions.h b/mlir/include/mlir/Dialect/EmitC/Transforms/TypeConversions.h
index 1c05a927e948a..0a2094c7d8d98 100644
--- a/mlir/include/mlir/Dialect/EmitC/Transforms/TypeConversions.h
+++ b/mlir/include/mlir/Dialect/EmitC/Transforms/TypeConversions.h
@@ -11,7 +11,7 @@
 
 namespace mlir {
 class TypeConverter;
-void populateEmitCSizeTypeConversions(TypeConverter &converter);
+void populateEmitCSizeTTypeConversions(TypeConverter &converter);
 } // namespace mlir
 
 #endif // MLIR_DIALECT_EMITC_TRANSFORMS_TYPECONVERSIONS_H
diff --git a/mlir/lib/Dialect/EmitC/Transforms/TypeConversions.cpp b/mlir/lib/Dialect/EmitC/Transforms/TypeConversions.cpp
index 02987df56f042..c31bfadc180ee 100644
--- a/mlir/lib/Dialect/EmitC/Transforms/TypeConversions.cpp
+++ b/mlir/lib/Dialect/EmitC/Transforms/TypeConversions.cpp
@@ -29,7 +29,7 @@ std::optional<Value> materializeAsUnrealizedCast(OpBuilder &builder,
 
 } // namespace
 
-void mlir::populateEmitCSizeTypeConversions(TypeConverter &converter) {
+void mlir::populateEmitCSizeTTypeConversions(TypeConverter &converter) {
   converter.addConversion(
       [](IndexType type) { return emitc::SizeTType::get(type.getContext()); });
 

>From ae8d1610f895a5d4c5b5f489aa8a4a6065244e1e Mon Sep 17 00:00:00 2001
From: Corentin Ferry <corentin.ferry at amd.com>
Date: Wed, 29 May 2024 09:16:39 +0100
Subject: [PATCH 05/11] Add ptrdiff_t

---
 mlir/include/mlir/Dialect/EmitC/IR/EmitC.h    |  2 +-
 .../mlir/Dialect/EmitC/IR/EmitCTypes.td       | 21 +++++++++++++++-
 .../EmitC/Transforms/TypeConversions.h        |  9 +++++++
 mlir/lib/Dialect/EmitC/IR/EmitC.cpp           | 11 ++++----
 .../EmitC/Transforms/TypeConversions.cpp      | 25 +++++++++++++++++++
 mlir/lib/Target/Cpp/TranslateToCpp.cpp        |  2 ++
 mlir/test/Dialect/EmitC/types.mlir            |  6 ++++-
 mlir/test/Target/Cpp/types.mlir               |  2 ++
 8 files changed, 70 insertions(+), 8 deletions(-)

diff --git a/mlir/include/mlir/Dialect/EmitC/IR/EmitC.h b/mlir/include/mlir/Dialect/EmitC/IR/EmitC.h
index 575b91516b919..87a4078f280f6 100644
--- a/mlir/include/mlir/Dialect/EmitC/IR/EmitC.h
+++ b/mlir/include/mlir/Dialect/EmitC/IR/EmitC.h
@@ -45,7 +45,7 @@ bool isIntegerIndexOrOpaqueType(Type type);
 bool isSupportedFloatType(mlir::Type type);
 
 /// Determines whether \p type is a emitc.size_t/ssize_t type.
-bool isAnySizeTType(mlir::Type type);
+bool isPointerWideType(mlir::Type type);
 
 } // namespace emitc
 } // namespace mlir
diff --git a/mlir/include/mlir/Dialect/EmitC/IR/EmitCTypes.td b/mlir/include/mlir/Dialect/EmitC/IR/EmitCTypes.td
index f6a8bd4ef59e1..6c1a22cb0730e 100644
--- a/mlir/include/mlir/Dialect/EmitC/IR/EmitCTypes.td
+++ b/mlir/include/mlir/Dialect/EmitC/IR/EmitCTypes.td
@@ -76,7 +76,7 @@ def EmitC_ArrayType : EmitC_Type<"Array", "array", [ShapedTypeInterface]> {
 
     static bool isValidElementType(Type type) {
       return type.isIntOrIndexOrFloat() ||
-         emitc::isAnySizeTType(type) ||
+         emitc::isPointerWideType(type) ||
          llvm::isa<PointerType, OpaqueType>(type);
     }
   }];
@@ -133,10 +133,29 @@ def EmitC_PointerType : EmitC_Type<"Pointer", "ptr"> {
 
 def EmitC_SignedSizeT : EmitC_Type<"SignedSizeT", "ssize_t"> {
   let summary = "EmitC signed size type";
+  let description = [{
+    Data type representing all values of `emitc.size_t`, plus -1.
+    It corresponds to `ssize_t` found in `<sys/types.h>`.
+    
+    Use of this type causes the code to be non-C99 compliant.
+  }];
+}
+
+def EmitC_PtrDiffT : EmitC_Type<"PtrDiffT", "ptrdiff_t"> {
+  let summary = "EmitC signed pointer diff type";
+  let description = [{
+    Signed data type as wide as platform-specific pointer types.
+    In particular, it is as wide as `emitc.size_t`.
+    It corresponds to `ptrdiff_t` found in `<stddef.h>`.
+  }];
 }
 
 def EmitC_SizeT : EmitC_Type<"SizeT", "size_t"> {
   let summary = "EmitC unsigned size type";
+  let description = [{
+    Unsigned data type as wide as platform-specific pointer types.
+    It corresponds to `size_t` found in `<stddef.h>`.
+  }];
 }
 
 #endif // MLIR_DIALECT_EMITC_IR_EMITCTYPES
diff --git a/mlir/include/mlir/Dialect/EmitC/Transforms/TypeConversions.h b/mlir/include/mlir/Dialect/EmitC/Transforms/TypeConversions.h
index 0a2094c7d8d98..a03419f8ac0f7 100644
--- a/mlir/include/mlir/Dialect/EmitC/Transforms/TypeConversions.h
+++ b/mlir/include/mlir/Dialect/EmitC/Transforms/TypeConversions.h
@@ -9,9 +9,18 @@
 #ifndef MLIR_DIALECT_EMITC_TRANSFORMS_TYPECONVERSIONS_H
 #define MLIR_DIALECT_EMITC_TRANSFORMS_TYPECONVERSIONS_H
 
+#include <optional>
+
 namespace mlir {
 class TypeConverter;
+class Type;
 void populateEmitCSizeTTypeConversions(TypeConverter &converter);
+
+namespace emitc {
+std::optional<Type> getUnsignedTypeFor(Type ty);
+std::optional<Type> getSignedTypeFor(Type ty);
+} // namespace emitc
+
 } // namespace mlir
 
 #endif // MLIR_DIALECT_EMITC_TRANSFORMS_TYPECONVERSIONS_H
diff --git a/mlir/lib/Dialect/EmitC/IR/EmitC.cpp b/mlir/lib/Dialect/EmitC/IR/EmitC.cpp
index d410a60d64aeb..6096f7cceba80 100644
--- a/mlir/lib/Dialect/EmitC/IR/EmitC.cpp
+++ b/mlir/lib/Dialect/EmitC/IR/EmitC.cpp
@@ -68,7 +68,7 @@ bool mlir::emitc::isSupportedEmitCType(Type type) {
     return !llvm::isa<emitc::ArrayType>(elemType) &&
            isSupportedEmitCType(elemType);
   }
-  if (type.isIndex() || emitc::isAnySizeTType(type))
+  if (type.isIndex() || emitc::isPointerWideType(type))
     return true;
   if (llvm::isa<IntegerType>(type))
     return isSupportedIntegerType(type);
@@ -110,7 +110,7 @@ bool mlir::emitc::isSupportedIntegerType(Type type) {
 
 bool mlir::emitc::isIntegerIndexOrOpaqueType(Type type) {
   return llvm::isa<IndexType, emitc::OpaqueType>(type) ||
-         isSupportedIntegerType(type) || isAnySizeTType(type);
+         isSupportedIntegerType(type) || isPointerWideType(type);
 }
 
 bool mlir::emitc::isSupportedFloatType(Type type) {
@@ -126,8 +126,9 @@ bool mlir::emitc::isSupportedFloatType(Type type) {
   return false;
 }
 
-bool mlir::emitc::isAnySizeTType(Type type) {
-  return isa<emitc::SignedSizeTType, emitc::SizeTType>(type);
+bool mlir::emitc::isPointerWideType(Type type) {
+  return isa<emitc::SignedSizeTType, emitc::SizeTType, emitc::PtrDiffTType>(
+      type);
 }
 
 /// Check that the type of the initial value is compatible with the operations
@@ -146,7 +147,7 @@ static LogicalResult verifyInitializationAttribute(Operation *op,
   Type resultType = op->getResult(0).getType();
   Type attrType = cast<TypedAttr>(value).getType();
 
-  if (isAnySizeTType(resultType) && attrType.isIndex())
+  if (isPointerWideType(resultType) && attrType.isIndex())
     return success();
 
   if (resultType != attrType)
diff --git a/mlir/lib/Dialect/EmitC/Transforms/TypeConversions.cpp b/mlir/lib/Dialect/EmitC/Transforms/TypeConversions.cpp
index c31bfadc180ee..5b8c76960793e 100644
--- a/mlir/lib/Dialect/EmitC/Transforms/TypeConversions.cpp
+++ b/mlir/lib/Dialect/EmitC/Transforms/TypeConversions.cpp
@@ -37,3 +37,28 @@ void mlir::populateEmitCSizeTTypeConversions(TypeConverter &converter) {
   converter.addTargetMaterialization(materializeAsUnrealizedCast);
   converter.addArgumentMaterialization(materializeAsUnrealizedCast);
 }
+
+/// Get an unsigned data type as wide as \p ty.
+std::optional<Type> mlir::emitc::getUnsignedTypeFor(Type ty) {
+  if (ty.isInteger())
+    return IntegerType::get(ty.getContext(), ty.getIntOrFloatBitWidth(),
+                            IntegerType::SignednessSemantics::Unsigned);
+  if (isa<emitc::PtrDiffTType, emitc::SignedSizeTType>(ty))
+    return emitc::SizeTType::get(ty.getContext());
+  if (isSupportedIntegerType(ty))
+    return ty;
+  return {};
+}
+
+/// Get a signed data type as wide as \p ty that supports arithmetic on negative
+/// values.
+std::optional<Type> mlir::emitc::getSignedTypeFor(Type ty) {
+  if (ty.isInteger())
+    return IntegerType::get(ty.getContext(), ty.getIntOrFloatBitWidth(),
+                            IntegerType::SignednessSemantics::Signed);
+  if (isa<emitc::SizeTType>(ty))
+    return emitc::PtrDiffTType::get(ty.getContext());
+  if (isSupportedIntegerType(ty))
+    return ty;
+  return {};
+}
diff --git a/mlir/lib/Target/Cpp/TranslateToCpp.cpp b/mlir/lib/Target/Cpp/TranslateToCpp.cpp
index 547319632d2f6..3c851b59bdeae 100644
--- a/mlir/lib/Target/Cpp/TranslateToCpp.cpp
+++ b/mlir/lib/Target/Cpp/TranslateToCpp.cpp
@@ -1574,6 +1574,8 @@ LogicalResult CppEmitter::emitType(Location loc, Type type) {
     return (os << "size_t"), success();
   if (auto sType = dyn_cast<emitc::SignedSizeTType>(type))
     return (os << "ssize_t"), success();
+  if (auto sType = dyn_cast<emitc::PtrDiffTType>(type))
+    return (os << "ptrdiff_t"), success();
   if (auto tType = dyn_cast<TensorType>(type)) {
     if (!tType.hasRank())
       return emitError(loc, "cannot emit unranked tensor type");
diff --git a/mlir/test/Dialect/EmitC/types.mlir b/mlir/test/Dialect/EmitC/types.mlir
index 5adc49e9dc2a1..66947a97e1f9f 100644
--- a/mlir/test/Dialect/EmitC/types.mlir
+++ b/mlir/test/Dialect/EmitC/types.mlir
@@ -15,7 +15,9 @@ func.func @array_types(
   // CHECK-SAME: !emitc.array<30x!emitc.size_t>
   %arg4: !emitc.array<30x!emitc.size_t>,
   // CHECK-SAME: !emitc.array<30x!emitc.ssize_t>
-  %arg5: !emitc.array<30x!emitc.ssize_t>
+  %arg5: !emitc.array<30x!emitc.ssize_t>,
+  // CHECK-SAME: !emitc.array<30x!emitc.ptrdiff_t>
+  %arg6: !emitc.array<30x!emitc.ptrdiff_t>
 ) {
   return
 }
@@ -64,6 +66,8 @@ func.func @size_types() {
   emitc.call_opaque "f"() {template_args = [!emitc.ssize_t]} : () -> ()
   // CHECK-NEXT: !emitc.size_t
   emitc.call_opaque "f"() {template_args = [!emitc.size_t]} : () -> ()
+  // CHECK-NEXT: !emitc.ptrdiff_t
+  emitc.call_opaque "f"() {template_args = [!emitc.ptrdiff_t]} : () -> ()
 
   return
 }
diff --git a/mlir/test/Target/Cpp/types.mlir b/mlir/test/Target/Cpp/types.mlir
index 647777c8ac718..deda383b3b0a7 100644
--- a/mlir/test/Target/Cpp/types.mlir
+++ b/mlir/test/Target/Cpp/types.mlir
@@ -42,6 +42,8 @@ func.func @size_types() {
   emitc.call_opaque "f"() {template_args = [!emitc.ssize_t]} : () -> ()
   // CHECK-NEXT: f<size_t>();
   emitc.call_opaque "f"() {template_args = [!emitc.size_t]} : () -> ()
+  // CHECK-NEXT: f<ptrdiff_t>();
+  emitc.call_opaque "f"() {template_args = [!emitc.ptrdiff_t]} : () -> ()
 
   return
 }

>From 5ef20112a77286ffd053b96ad3bee85212146eab Mon Sep 17 00:00:00 2001
From: Corentin Ferry <corentin.ferry at amd.com>
Date: Wed, 29 May 2024 09:29:11 +0100
Subject: [PATCH 06/11] Add cast compatibility from/to ptrdiff_t

---
 mlir/lib/Dialect/EmitC/IR/EmitC.cpp | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/mlir/lib/Dialect/EmitC/IR/EmitC.cpp b/mlir/lib/Dialect/EmitC/IR/EmitC.cpp
index 6096f7cceba80..45377804dbba8 100644
--- a/mlir/lib/Dialect/EmitC/IR/EmitC.cpp
+++ b/mlir/lib/Dialect/EmitC/IR/EmitC.cpp
@@ -234,13 +234,12 @@ LogicalResult emitc::AssignOp::verify() {
 bool CastOp::areCastCompatible(TypeRange inputs, TypeRange outputs) {
   Type input = inputs.front(), output = outputs.front();
 
-  return (
-      (llvm::isa<IntegerType, FloatType, IndexType, emitc::OpaqueType,
-                 emitc::PointerType, emitc::SignedSizeTType, emitc::SizeTType>(
-          input)) &&
-      (llvm::isa<IntegerType, FloatType, IndexType, emitc::OpaqueType,
-                 emitc::PointerType, emitc::SignedSizeTType, emitc::SizeTType>(
-          output)));
+  return ((llvm::isa<IntegerType, FloatType, IndexType, emitc::OpaqueType,
+                     emitc::PointerType, emitc::SignedSizeTType,
+                     emitc::SizeTType, emitc::PtrDiffTType>(input)) &&
+          (llvm::isa<IntegerType, FloatType, IndexType, emitc::OpaqueType,
+                     emitc::PointerType, emitc::SignedSizeTType,
+                     emitc::SizeTType, emitc::PtrDiffTType>(output)));
 }
 
 //===----------------------------------------------------------------------===//

>From 1cd591a7e2d65418ff451db0b567b8c49a9ea9fd Mon Sep 17 00:00:00 2001
From: Corentin Ferry <corentin.ferry at amd.com>
Date: Wed, 29 May 2024 10:12:07 +0100
Subject: [PATCH 07/11] Address review comments

---
 mlir/include/mlir/Dialect/EmitC/IR/EmitCTypes.td     |  6 +++---
 mlir/lib/Dialect/EmitC/IR/EmitC.cpp                  | 11 +++++------
 .../lib/Dialect/EmitC/Transforms/TypeConversions.cpp | 12 ++++++------
 3 files changed, 14 insertions(+), 15 deletions(-)

diff --git a/mlir/include/mlir/Dialect/EmitC/IR/EmitCTypes.td b/mlir/include/mlir/Dialect/EmitC/IR/EmitCTypes.td
index 6c1a22cb0730e..79f6d34fc91b1 100644
--- a/mlir/include/mlir/Dialect/EmitC/IR/EmitCTypes.td
+++ b/mlir/include/mlir/Dialect/EmitC/IR/EmitCTypes.td
@@ -75,9 +75,9 @@ def EmitC_ArrayType : EmitC_Type<"Array", "array", [ShapedTypeInterface]> {
                         Type elementType) const;
 
     static bool isValidElementType(Type type) {
-      return type.isIntOrIndexOrFloat() ||
-         emitc::isPointerWideType(type) ||
-         llvm::isa<PointerType, OpaqueType>(type);
+      return emitc::isSupportedFloatType(type) ||
+         emitc::isIntegerIndexOrOpaqueType(type) ||
+         llvm::isa<PointerType>(type);
     }
   }];
   let genVerifyDecl = 1;
diff --git a/mlir/lib/Dialect/EmitC/IR/EmitC.cpp b/mlir/lib/Dialect/EmitC/IR/EmitC.cpp
index 45377804dbba8..1569b6d7d702c 100644
--- a/mlir/lib/Dialect/EmitC/IR/EmitC.cpp
+++ b/mlir/lib/Dialect/EmitC/IR/EmitC.cpp
@@ -234,12 +234,11 @@ LogicalResult emitc::AssignOp::verify() {
 bool CastOp::areCastCompatible(TypeRange inputs, TypeRange outputs) {
   Type input = inputs.front(), output = outputs.front();
 
-  return ((llvm::isa<IntegerType, FloatType, IndexType, emitc::OpaqueType,
-                     emitc::PointerType, emitc::SignedSizeTType,
-                     emitc::SizeTType, emitc::PtrDiffTType>(input)) &&
-          (llvm::isa<IntegerType, FloatType, IndexType, emitc::OpaqueType,
-                     emitc::PointerType, emitc::SignedSizeTType,
-                     emitc::SizeTType, emitc::PtrDiffTType>(output)));
+  return (
+      (emitc::isIntegerIndexOrOpaqueType(input) ||
+       emitc::isSupportedFloatType(input) || isa<emitc::PointerType>(input)) &&
+      (emitc::isIntegerIndexOrOpaqueType(output) ||
+       emitc::isSupportedFloatType(output) || isa<emitc::PointerType>(output)));
 }
 
 //===----------------------------------------------------------------------===//
diff --git a/mlir/lib/Dialect/EmitC/Transforms/TypeConversions.cpp b/mlir/lib/Dialect/EmitC/Transforms/TypeConversions.cpp
index 5b8c76960793e..da2fe37c3f9c0 100644
--- a/mlir/lib/Dialect/EmitC/Transforms/TypeConversions.cpp
+++ b/mlir/lib/Dialect/EmitC/Transforms/TypeConversions.cpp
@@ -43,9 +43,9 @@ std::optional<Type> mlir::emitc::getUnsignedTypeFor(Type ty) {
   if (ty.isInteger())
     return IntegerType::get(ty.getContext(), ty.getIntOrFloatBitWidth(),
                             IntegerType::SignednessSemantics::Unsigned);
-  if (isa<emitc::PtrDiffTType, emitc::SignedSizeTType>(ty))
-    return emitc::SizeTType::get(ty.getContext());
-  if (isSupportedIntegerType(ty))
+  if (isa<PtrDiffTType, SignedSizeTType>(ty))
+    return SizeTType::get(ty.getContext());
+  if (isa<SizeTType>(ty))
     return ty;
   return {};
 }
@@ -56,9 +56,9 @@ std::optional<Type> mlir::emitc::getSignedTypeFor(Type ty) {
   if (ty.isInteger())
     return IntegerType::get(ty.getContext(), ty.getIntOrFloatBitWidth(),
                             IntegerType::SignednessSemantics::Signed);
-  if (isa<emitc::SizeTType>(ty))
-    return emitc::PtrDiffTType::get(ty.getContext());
-  if (isSupportedIntegerType(ty))
+  if (isa<SizeTType, SignedSizeTType>(ty))
+    return PtrDiffTType::get(ty.getContext());
+  if (isa<PtrDiffTType>(ty))
     return ty;
   return {};
 }

>From ac1481915f00ba2d05a8cba55b245f8b40d787a0 Mon Sep 17 00:00:00 2001
From: Corentin Ferry <corentin.ferry at amd.com>
Date: Wed, 29 May 2024 12:33:29 +0100
Subject: [PATCH 08/11] Mention ssize_t/POSIX in docs

---
 mlir/docs/Dialects/emitc.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/mlir/docs/Dialects/emitc.md b/mlir/docs/Dialects/emitc.md
index 1158bc683af06..7e320aa4992dd 100644
--- a/mlir/docs/Dialects/emitc.md
+++ b/mlir/docs/Dialects/emitc.md
@@ -10,6 +10,7 @@ The following convention is followed:
     `emitc.call_opaque` operation, C++11 is required.
 *   If floating-point type template arguments are passed to an `emitc.call_opaque`
     operation, C++20 is required.
+*   If `ssize_t` is used, then the code requires the POSIX header `sys/types.h`,
 *   Else the generated code is compatible with C99.
 
 These restrictions are neither inherent to the EmitC dialect itself nor to the

>From c9de812de6cd0a74ac49cef19a15fe5bb97b6baf Mon Sep 17 00:00:00 2001
From: Corentin Ferry <corentin.ferry at amd.com>
Date: Wed, 29 May 2024 13:36:00 +0200
Subject: [PATCH 09/11] Update mlir/docs/Dialects/emitc.md

---
 mlir/docs/Dialects/emitc.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mlir/docs/Dialects/emitc.md b/mlir/docs/Dialects/emitc.md
index 7e320aa4992dd..0b72580809c04 100644
--- a/mlir/docs/Dialects/emitc.md
+++ b/mlir/docs/Dialects/emitc.md
@@ -10,7 +10,7 @@ The following convention is followed:
     `emitc.call_opaque` operation, C++11 is required.
 *   If floating-point type template arguments are passed to an `emitc.call_opaque`
     operation, C++20 is required.
-*   If `ssize_t` is used, then the code requires the POSIX header `sys/types.h`,
+*   If `ssize_t` is used, then the code requires the POSIX header `sys/types.h`.
 *   Else the generated code is compatible with C99.
 
 These restrictions are neither inherent to the EmitC dialect itself nor to the

>From 76be5aa21084c54a219a0ce677bc36742614d021 Mon Sep 17 00:00:00 2001
From: Corentin Ferry <corentin.ferry at amd.com>
Date: Wed, 12 Jun 2024 13:30:18 +0100
Subject: [PATCH 10/11] Update comments for data types

---
 mlir/lib/Dialect/EmitC/Transforms/TypeConversions.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/mlir/lib/Dialect/EmitC/Transforms/TypeConversions.cpp b/mlir/lib/Dialect/EmitC/Transforms/TypeConversions.cpp
index da2fe37c3f9c0..83de9b37974f6 100644
--- a/mlir/lib/Dialect/EmitC/Transforms/TypeConversions.cpp
+++ b/mlir/lib/Dialect/EmitC/Transforms/TypeConversions.cpp
@@ -38,7 +38,7 @@ void mlir::populateEmitCSizeTTypeConversions(TypeConverter &converter) {
   converter.addArgumentMaterialization(materializeAsUnrealizedCast);
 }
 
-/// Get an unsigned data type as wide as \p ty.
+/// Get an unsigned integer or size data type corresponding to \p ty.
 std::optional<Type> mlir::emitc::getUnsignedTypeFor(Type ty) {
   if (ty.isInteger())
     return IntegerType::get(ty.getContext(), ty.getIntOrFloatBitWidth(),
@@ -50,8 +50,8 @@ std::optional<Type> mlir::emitc::getUnsignedTypeFor(Type ty) {
   return {};
 }
 
-/// Get a signed data type as wide as \p ty that supports arithmetic on negative
-/// values.
+/// Get a signed integer or size data type corresponding to \p ty that supports
+/// arithmetic on negative values.
 std::optional<Type> mlir::emitc::getSignedTypeFor(Type ty) {
   if (ty.isInteger())
     return IntegerType::get(ty.getContext(), ty.getIntOrFloatBitWidth(),

>From 0d31f9551379a3f3c06be7903e4560120161ed86 Mon Sep 17 00:00:00 2001
From: Corentin Ferry <corentin.ferry at amd.com>
Date: Wed, 12 Jun 2024 13:49:43 +0100
Subject: [PATCH 11/11] Address review comments

---
 mlir/docs/Dialects/emitc.md            | 3 ++-
 mlir/lib/Target/Cpp/TranslateToCpp.cpp | 2 +-
 mlir/test/Dialect/EmitC/ops.mlir       | 1 +
 3 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/mlir/docs/Dialects/emitc.md b/mlir/docs/Dialects/emitc.md
index 0b72580809c04..95fb29f3bec7c 100644
--- a/mlir/docs/Dialects/emitc.md
+++ b/mlir/docs/Dialects/emitc.md
@@ -10,7 +10,8 @@ The following convention is followed:
     `emitc.call_opaque` operation, C++11 is required.
 *   If floating-point type template arguments are passed to an `emitc.call_opaque`
     operation, C++20 is required.
-*   If `ssize_t` is used, then the code requires the POSIX header `sys/types.h`.
+*   If `ssize_t` is used, then the code requires the POSIX header `sys/types.h`
+    or any of the C++ headers in which the type is defined.
 *   Else the generated code is compatible with C99.
 
 These restrictions are neither inherent to the EmitC dialect itself nor to the
diff --git a/mlir/lib/Target/Cpp/TranslateToCpp.cpp b/mlir/lib/Target/Cpp/TranslateToCpp.cpp
index 3c851b59bdeae..f61de4a420a64 100644
--- a/mlir/lib/Target/Cpp/TranslateToCpp.cpp
+++ b/mlir/lib/Target/Cpp/TranslateToCpp.cpp
@@ -1574,7 +1574,7 @@ LogicalResult CppEmitter::emitType(Location loc, Type type) {
     return (os << "size_t"), success();
   if (auto sType = dyn_cast<emitc::SignedSizeTType>(type))
     return (os << "ssize_t"), success();
-  if (auto sType = dyn_cast<emitc::PtrDiffTType>(type))
+  if (auto pType = dyn_cast<emitc::PtrDiffTType>(type))
     return (os << "ptrdiff_t"), success();
   if (auto tType = dyn_cast<TensorType>(type)) {
     if (!tType.hasRank())
diff --git a/mlir/test/Dialect/EmitC/ops.mlir b/mlir/test/Dialect/EmitC/ops.mlir
index 814435e6ef8b5..51c484a633eec 100644
--- a/mlir/test/Dialect/EmitC/ops.mlir
+++ b/mlir/test/Dialect/EmitC/ops.mlir
@@ -43,6 +43,7 @@ func.func @c() {
   %1 = "emitc.constant"(){value = 42 : i32} : () -> i32
   %2 = "emitc.constant"(){value = 42 : index} : () -> !emitc.size_t
   %3 = "emitc.constant"(){value = 42 : index} : () -> !emitc.ssize_t
+  %4 = "emitc.constant"(){value = 42 : index} : () -> !emitc.ptrdiff_t
   return
 }
 



More information about the Mlir-commits mailing list