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

llvmlistbot at llvm.org llvmlistbot at llvm.org
Mon Jun 17 04:53:59 PDT 2024


Author: Corentin Ferry
Date: 2024-06-17T13:53:55+02:00
New Revision: 3cead572e91d3de5f8cb458f09ab39302e289d22

URL: https://github.com/llvm/llvm-project/commit/3cead572e91d3de5f8cb458f09ab39302e289d22
DIFF: https://github.com/llvm/llvm-project/commit/3cead572e91d3de5f8cb458f09ab39302e289d22.diff

LOG: [mlir][emitc] Add EmitC index types (#93155)

This commit adds `emitc.size_t`, `emitc.ssize_t` and `emitc.ptrdiff_t`
types to the EmitC dialect. These are used to map `index` types to C/C++
types with an explicit signedness, and are emitted in C/C++ as `size_t`,
`ssize_t` and `ptrdiff_t`.

Added: 
    mlir/include/mlir/Dialect/EmitC/Transforms/TypeConversions.h
    mlir/lib/Dialect/EmitC/Transforms/TypeConversions.cpp

Modified: 
    mlir/docs/Dialects/emitc.md
    mlir/include/mlir/Dialect/EmitC/IR/EmitC.h
    mlir/include/mlir/Dialect/EmitC/IR/EmitC.td
    mlir/include/mlir/Dialect/EmitC/IR/EmitCTypes.td
    mlir/lib/Dialect/EmitC/IR/EmitC.cpp
    mlir/lib/Dialect/EmitC/Transforms/CMakeLists.txt
    mlir/lib/Target/Cpp/TranslateToCpp.cpp
    mlir/test/Dialect/EmitC/invalid_ops.mlir
    mlir/test/Dialect/EmitC/invalid_types.mlir
    mlir/test/Dialect/EmitC/ops.mlir
    mlir/test/Dialect/EmitC/types.mlir
    mlir/test/Target/Cpp/types.mlir

Removed: 
    


################################################################################
diff  --git a/mlir/docs/Dialects/emitc.md b/mlir/docs/Dialects/emitc.md
index 1158bc683af06..4b0394606e4a2 100644
--- a/mlir/docs/Dialects/emitc.md
+++ b/mlir/docs/Dialects/emitc.md
@@ -10,11 +10,18 @@ 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`
+    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
 Cpp emitter and therefore need to be considered while implementing conversions.
 
+Type conversions are provided for the MLIR type `index` into the unsigned `size_t`
+type and its signed counterpart `ptr
diff _t`. Conversions between these two types
+are only valid if the `index`-typed values are within 
+`[PTRDIFF_MIN, PTRDIFF_MAX]`.
+
 After the conversion, C/C++ code can be emitted with `mlir-translate`. The tool
 supports translating MLIR to C/C++ by passing `-mlir-to-cpp`. Furthermore, code
 with variables declared at top can be generated by passing the additional

diff  --git a/mlir/include/mlir/Dialect/EmitC/IR/EmitC.h b/mlir/include/mlir/Dialect/EmitC/IR/EmitC.h
index 5d9531cd12415..87a4078f280f6 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 isPointerWideType(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..452302c565139 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 : 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]> {
@@ -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..79f6d34fc91b1 100644
--- a/mlir/include/mlir/Dialect/EmitC/IR/EmitCTypes.td
+++ b/mlir/include/mlir/Dialect/EmitC/IR/EmitCTypes.td
@@ -75,8 +75,9 @@ def EmitC_ArrayType : EmitC_Type<"Array", "array", [ShapedTypeInterface]> {
                         Type elementType) const;
 
     static bool isValidElementType(Type type) {
-      return type.isIntOrIndexOrFloat() ||
-         llvm::isa<PointerType, OpaqueType>(type);
+      return emitc::isSupportedFloatType(type) ||
+         emitc::isIntegerIndexOrOpaqueType(type) ||
+         llvm::isa<PointerType>(type);
     }
   }];
   let genVerifyDecl = 1;
@@ -130,4 +131,31 @@ 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";
+  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", "ptr
diff _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 `ptr
diff _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
new file mode 100644
index 0000000000000..a03419f8ac0f7
--- /dev/null
+++ b/mlir/include/mlir/Dialect/EmitC/Transforms/TypeConversions.h
@@ -0,0 +1,26 @@
+//===- 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
+
+#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 20f47574b25ad..b2556bb6065d8 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())
+  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);
+         isSupportedIntegerType(type) || isPointerWideType(type);
 }
 
 bool mlir::emitc::isSupportedFloatType(Type type) {
@@ -126,6 +126,11 @@ bool mlir::emitc::isSupportedFloatType(Type type) {
   return false;
 }
 
+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
 /// result type.
 static LogicalResult verifyInitializationAttribute(Operation *op,
@@ -142,6 +147,9 @@ static LogicalResult verifyInitializationAttribute(Operation *op,
   Type resultType = op->getResult(0).getType();
   Type attrType = cast<TypedAttr>(value).getType();
 
+  if (isPointerWideType(resultType) && attrType.isIndex())
+    return success();
+
   if (resultType != attrType)
     return op->emitOpError()
            << "requires attribute to either be an #emitc.opaque attribute or "
@@ -226,10 +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>(input)) &&
-          (llvm::isa<IntegerType, FloatType, IndexType, emitc::OpaqueType,
-                     emitc::PointerType>(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/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..83de9b37974f6
--- /dev/null
+++ b/mlir/lib/Dialect/EmitC/Transforms/TypeConversions.cpp
@@ -0,0 +1,64 @@
+//===- 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::populateEmitCSizeTTypeConversions(TypeConverter &converter) {
+  converter.addConversion(
+      [](IndexType type) { return emitc::SizeTType::get(type.getContext()); });
+
+  converter.addSourceMaterialization(materializeAsUnrealizedCast);
+  converter.addTargetMaterialization(materializeAsUnrealizedCast);
+  converter.addArgumentMaterialization(materializeAsUnrealizedCast);
+}
+
+/// 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(),
+                            IntegerType::SignednessSemantics::Unsigned);
+  if (isa<PtrDiffTType, SignedSizeTType>(ty))
+    return SizeTType::get(ty.getContext());
+  if (isa<SizeTType>(ty))
+    return ty;
+  return {};
+}
+
+/// 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(),
+                            IntegerType::SignednessSemantics::Signed);
+  if (isa<SizeTType, SignedSizeTType>(ty))
+    return PtrDiffTType::get(ty.getContext());
+  if (isa<PtrDiffTType>(ty))
+    return ty;
+  return {};
+}

diff  --git a/mlir/lib/Target/Cpp/TranslateToCpp.cpp b/mlir/lib/Target/Cpp/TranslateToCpp.cpp
index 202df89025f26..626638282efe1 100644
--- a/mlir/lib/Target/Cpp/TranslateToCpp.cpp
+++ b/mlir/lib/Target/Cpp/TranslateToCpp.cpp
@@ -1574,6 +1574,12 @@ LogicalResult CppEmitter::emitType(Location loc, Type type) {
   }
   if (auto iType = dyn_cast<IndexType>(type))
     return (os << "size_t"), success();
+  if (auto sType = dyn_cast<emitc::SizeTType>(type))
+    return (os << "size_t"), success();
+  if (auto sType = dyn_cast<emitc::SignedSizeTType>(type))
+    return (os << "ssize_t"), success();
+  if (auto pType = dyn_cast<emitc::PtrDiffTType>(type))
+    return (os << "ptr
diff _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..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 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 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 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 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 0ad8d4eabe6b8..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 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 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..51c484a633eec 100644
--- a/mlir/test/Dialect/EmitC/ops.mlir
+++ b/mlir/test/Dialect/EmitC/ops.mlir
@@ -41,6 +41,9 @@ 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
+  %4 = "emitc.constant"(){value = 42 : index} : () -> !emitc.ptr
diff _t
   return
 }
 

diff  --git a/mlir/test/Dialect/EmitC/types.mlir b/mlir/test/Dialect/EmitC/types.mlir
index 752f2c10c17be..66947a97e1f9f 100644
--- a/mlir/test/Dialect/EmitC/types.mlir
+++ b/mlir/test/Dialect/EmitC/types.mlir
@@ -11,7 +11,13 @@ 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>,
+  // CHECK-SAME: !emitc.array<30x!emitc.ptr
diff _t>
+  %arg6: !emitc.array<30x!emitc.ptr
diff _t>
 ) {
   return
 }
@@ -53,3 +59,15 @@ func.func @pointer_types() {
 
   return
 }
+
+// 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
+  emitc.call_opaque "f"() {template_args = [!emitc.size_t]} : () -> ()
+  // CHECK-NEXT: !emitc.ptr
diff _t
+  emitc.call_opaque "f"() {template_args = [!emitc.ptr
diff _t]} : () -> ()
+
+  return
+}

diff  --git a/mlir/test/Target/Cpp/types.mlir b/mlir/test/Target/Cpp/types.mlir
index 0585b27eb6c22..deda383b3b0a7 100644
--- a/mlir/test/Target/Cpp/types.mlir
+++ b/mlir/test/Target/Cpp/types.mlir
@@ -35,3 +35,15 @@ 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]} : () -> ()
+  // CHECK-NEXT: f<ptr
diff _t>();
+  emitc.call_opaque "f"() {template_args = [!emitc.ptr
diff _t]} : () -> ()
+
+  return
+}


        


More information about the Mlir-commits mailing list