[Mlir-commits] [mlir] [mlir][llvmir][reland] expose Type(To/From)LLVMIRTranslator C API (PR #125110)

Maksim Levental llvmlistbot at llvm.org
Thu Jan 30 11:51:26 PST 2025


https://github.com/makslevental created https://github.com/llvm/llvm-project/pull/125110

Reland https://github.com/llvm/llvm-project/pull/124864

>From 473dd7a95a31bf9bc388879b272d2a69b328f9ff Mon Sep 17 00:00:00 2001
From: max <maksim.levental at gmail.com>
Date: Tue, 28 Jan 2025 19:37:34 -0500
Subject: [PATCH 1/8] [mlir][llvmir] expose TypeFromLLVMIRTranslator

---
 mlir/include/mlir-c/Target/LLVMIR.h | 20 ++++++++++++++++++++
 mlir/lib/CAPI/Target/LLVMIR.cpp     | 19 ++++++++++++++++---
 mlir/test/CAPI/translation.c        | 17 +++++++++++++++++
 3 files changed, 53 insertions(+), 3 deletions(-)

diff --git a/mlir/include/mlir-c/Target/LLVMIR.h b/mlir/include/mlir-c/Target/LLVMIR.h
index effa74b905ce66..28b497f5d8d832 100644
--- a/mlir/include/mlir-c/Target/LLVMIR.h
+++ b/mlir/include/mlir-c/Target/LLVMIR.h
@@ -16,6 +16,8 @@
 
 #include "mlir-c/IR.h"
 #include "mlir-c/Support.h"
+#include "mlir/CAPI/Wrap.h"
+#include "mlir/Target/LLVMIR/TypeFromLLVM.h"
 #include "llvm-c/Support.h"
 
 #ifdef __cplusplus
@@ -32,6 +34,24 @@ extern "C" {
 MLIR_CAPI_EXPORTED LLVMModuleRef
 mlirTranslateModuleToLLVMIR(MlirOperation module, LLVMContextRef context);
 
+struct MlirTypeFromLLVMIRTranslator {
+  void *ptr;
+};
+
+typedef struct MlirTypeFromLLVMIRTranslator MlirTypeFromLLVMIRTranslator;
+
+DEFINE_C_API_PTR_METHODS(MlirTypeFromLLVMIRTranslator,
+                         mlir::LLVM::TypeFromLLVMIRTranslator);
+
+MLIR_CAPI_EXPORTED MlirTypeFromLLVMIRTranslator
+mlirTypeFromLLVMIRTranslatorCreate(MlirContext ctx);
+
+MLIR_CAPI_EXPORTED MlirTypeFromLLVMIRTranslator
+mlirTypeFromLLVMIRTranslatorCreate(MlirContext ctx);
+
+MLIR_CAPI_EXPORTED MlirType mlirTypeFromLLVMIRTranslatorTranslateType(
+    MlirTypeFromLLVMIRTranslator translator, LLVMTypeRef llvmType);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/mlir/lib/CAPI/Target/LLVMIR.cpp b/mlir/lib/CAPI/Target/LLVMIR.cpp
index dc798372be7467..6606e2376e0d1e 100644
--- a/mlir/lib/CAPI/Target/LLVMIR.cpp
+++ b/mlir/lib/CAPI/Target/LLVMIR.cpp
@@ -8,16 +8,15 @@
 //===----------------------------------------------------------------------===//
 
 #include "mlir-c/Target/LLVMIR.h"
-#include "llvm-c/Support.h"
 
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/Module.h"
-#include <memory>
+#include "llvm/IR/Type.h"
 
 #include "mlir/CAPI/IR.h"
-#include "mlir/CAPI/Support.h"
 #include "mlir/CAPI/Wrap.h"
 #include "mlir/Target/LLVMIR/ModuleTranslation.h"
+#include "mlir/Target/LLVMIR/TypeFromLLVM.h"
 
 using namespace mlir;
 
@@ -34,3 +33,17 @@ LLVMModuleRef mlirTranslateModuleToLLVMIR(MlirOperation module,
 
   return moduleRef;
 }
+
+MlirTypeFromLLVMIRTranslator
+mlirTypeFromLLVMIRTranslatorCreate(MlirContext ctx) {
+  MLIRContext *context = unwrap(ctx);
+  auto *translator = new LLVM::TypeFromLLVMIRTranslator(*context);
+  return wrap(translator);
+}
+
+MlirType mlirTypeFromLLVMIRTranslatorTranslateType(
+    MlirTypeFromLLVMIRTranslator translator, LLVMTypeRef llvmType) {
+  LLVM::TypeFromLLVMIRTranslator *translator_ = unwrap(translator);
+  mlir::Type type = translator_->translateType(llvm::unwrap(llvmType));
+  return wrap(type);
+}
\ No newline at end of file
diff --git a/mlir/test/CAPI/translation.c b/mlir/test/CAPI/translation.c
index c9233d95fd5120..ddbf217c1d9862 100644
--- a/mlir/test/CAPI/translation.c
+++ b/mlir/test/CAPI/translation.c
@@ -58,11 +58,28 @@ static void testToLLVMIR(MlirContext ctx) {
   LLVMContextDispose(llvmCtx);
 }
 
+// CHECK-LABEL: testTypeFromLLVMIRTranslator
+static void testTypeFromLLVMIRTranslator(MlirContext ctx) {
+  fprintf(stderr, "testTypeFromLLVMIRTranslator\n");
+  LLVMContextRef llvmCtx = LLVMContextCreate();
+
+  LLVMTypeRef llvmTy = LLVMInt32TypeInContext(llvmCtx);
+  MlirTypeFromLLVMIRTranslator translator =
+      mlirTypeFromLLVMIRTranslatorCreate(ctx);
+  MlirType mlirTy =
+      mlirTypeFromLLVMIRTranslatorTranslateType(translator, llvmTy);
+  // CHECK: i32
+  mlirTypeDump(mlirTy);
+
+  LLVMContextDispose(llvmCtx);
+}
+
 int main(void) {
   MlirContext ctx = mlirContextCreate();
   mlirDialectHandleRegisterDialect(mlirGetDialectHandle__llvm__(), ctx);
   mlirContextGetOrLoadDialect(ctx, mlirStringRefCreateFromCString("llvm"));
   testToLLVMIR(ctx);
+  testTypeFromLLVMIRTranslator(ctx);
   mlirContextDestroy(ctx);
   return 0;
 }

>From d2eab6ee70235a4837fcbc2f2de1519a03050827 Mon Sep 17 00:00:00 2001
From: max <maksim.levental at gmail.com>
Date: Tue, 28 Jan 2025 20:00:40 -0500
Subject: [PATCH 2/8] [mlir][llvmir] expose TypeFromLLVMIRTranslator

---
 mlir/include/mlir-c/Target/LLVMIR.h | 5 -----
 mlir/lib/CAPI/Target/LLVMIR.cpp     | 3 +++
 2 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/mlir/include/mlir-c/Target/LLVMIR.h b/mlir/include/mlir-c/Target/LLVMIR.h
index 28b497f5d8d832..90204626013952 100644
--- a/mlir/include/mlir-c/Target/LLVMIR.h
+++ b/mlir/include/mlir-c/Target/LLVMIR.h
@@ -16,8 +16,6 @@
 
 #include "mlir-c/IR.h"
 #include "mlir-c/Support.h"
-#include "mlir/CAPI/Wrap.h"
-#include "mlir/Target/LLVMIR/TypeFromLLVM.h"
 #include "llvm-c/Support.h"
 
 #ifdef __cplusplus
@@ -40,9 +38,6 @@ struct MlirTypeFromLLVMIRTranslator {
 
 typedef struct MlirTypeFromLLVMIRTranslator MlirTypeFromLLVMIRTranslator;
 
-DEFINE_C_API_PTR_METHODS(MlirTypeFromLLVMIRTranslator,
-                         mlir::LLVM::TypeFromLLVMIRTranslator);
-
 MLIR_CAPI_EXPORTED MlirTypeFromLLVMIRTranslator
 mlirTypeFromLLVMIRTranslatorCreate(MlirContext ctx);
 
diff --git a/mlir/lib/CAPI/Target/LLVMIR.cpp b/mlir/lib/CAPI/Target/LLVMIR.cpp
index 6606e2376e0d1e..7d81b490ed0c7b 100644
--- a/mlir/lib/CAPI/Target/LLVMIR.cpp
+++ b/mlir/lib/CAPI/Target/LLVMIR.cpp
@@ -34,6 +34,9 @@ LLVMModuleRef mlirTranslateModuleToLLVMIR(MlirOperation module,
   return moduleRef;
 }
 
+DEFINE_C_API_PTR_METHODS(MlirTypeFromLLVMIRTranslator,
+                         mlir::LLVM::TypeFromLLVMIRTranslator);
+
 MlirTypeFromLLVMIRTranslator
 mlirTypeFromLLVMIRTranslatorCreate(MlirContext ctx) {
   MLIRContext *context = unwrap(ctx);

>From 1c51d3ffbdcea07e04b90b428897def71bd17eec Mon Sep 17 00:00:00 2001
From: max <maksim.levental at gmail.com>
Date: Wed, 29 Jan 2025 20:14:03 -0500
Subject: [PATCH 3/8] comments

---
 mlir/include/mlir-c/Target/LLVMIR.h | 10 ++++++++--
 mlir/lib/CAPI/Target/LLVMIR.cpp     |  7 ++++++-
 2 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/mlir/include/mlir-c/Target/LLVMIR.h b/mlir/include/mlir-c/Target/LLVMIR.h
index 90204626013952..94663574eac038 100644
--- a/mlir/include/mlir-c/Target/LLVMIR.h
+++ b/mlir/include/mlir-c/Target/LLVMIR.h
@@ -38,12 +38,18 @@ struct MlirTypeFromLLVMIRTranslator {
 
 typedef struct MlirTypeFromLLVMIRTranslator MlirTypeFromLLVMIRTranslator;
 
+/// Create an LLVM::TypeFromLLVMIRTranslator and transfer ownership to the
+/// caller.
 MLIR_CAPI_EXPORTED MlirTypeFromLLVMIRTranslator
 mlirTypeFromLLVMIRTranslatorCreate(MlirContext ctx);
 
-MLIR_CAPI_EXPORTED MlirTypeFromLLVMIRTranslator
-mlirTypeFromLLVMIRTranslatorCreate(MlirContext ctx);
+/// Takes an LLVM::TypeFromLLVMIRTranslator owned by the caller and destroys it.
+/// It is the responsibility of the user to only pass an
+/// LLVM::TypeFromLLVMIRTranslator class.
+MLIR_CAPI_EXPORTED void
+mlirTypeFromLLVMIRTranslatorDestroy(MlirTypeFromLLVMIRTranslator translator);
 
+/// Translates the given LLVM IR type to the MLIR LLVM dialect.
 MLIR_CAPI_EXPORTED MlirType mlirTypeFromLLVMIRTranslatorTranslateType(
     MlirTypeFromLLVMIRTranslator translator, LLVMTypeRef llvmType);
 
diff --git a/mlir/lib/CAPI/Target/LLVMIR.cpp b/mlir/lib/CAPI/Target/LLVMIR.cpp
index 7d81b490ed0c7b..5261c8773faf7d 100644
--- a/mlir/lib/CAPI/Target/LLVMIR.cpp
+++ b/mlir/lib/CAPI/Target/LLVMIR.cpp
@@ -44,9 +44,14 @@ mlirTypeFromLLVMIRTranslatorCreate(MlirContext ctx) {
   return wrap(translator);
 }
 
+void mlirTypeFromLLVMIRTranslatorDestroy(
+    MlirTypeFromLLVMIRTranslator translator) {
+  delete static_cast<LLVM::TypeFromLLVMIRTranslator *>(unwrap(translator));
+}
+
 MlirType mlirTypeFromLLVMIRTranslatorTranslateType(
     MlirTypeFromLLVMIRTranslator translator, LLVMTypeRef llvmType) {
   LLVM::TypeFromLLVMIRTranslator *translator_ = unwrap(translator);
   mlir::Type type = translator_->translateType(llvm::unwrap(llvmType));
   return wrap(type);
-}
\ No newline at end of file
+}

>From 4a32519e4a8773c838e86ab419bf06f6ff8d49e9 Mon Sep 17 00:00:00 2001
From: max <maksim.levental at gmail.com>
Date: Wed, 29 Jan 2025 20:27:37 -0500
Subject: [PATCH 4/8] add ToLLVMIR

---
 mlir/include/mlir-c/Target/LLVMIR.h | 21 +++++++++++++++++++++
 mlir/lib/CAPI/Target/LLVMIR.cpp     | 22 ++++++++++++++++++++++
 mlir/test/CAPI/translation.c        | 13 +++++++++++--
 3 files changed, 54 insertions(+), 2 deletions(-)

diff --git a/mlir/include/mlir-c/Target/LLVMIR.h b/mlir/include/mlir-c/Target/LLVMIR.h
index 94663574eac038..6a026c31d05117 100644
--- a/mlir/include/mlir-c/Target/LLVMIR.h
+++ b/mlir/include/mlir-c/Target/LLVMIR.h
@@ -53,6 +53,27 @@ mlirTypeFromLLVMIRTranslatorDestroy(MlirTypeFromLLVMIRTranslator translator);
 MLIR_CAPI_EXPORTED MlirType mlirTypeFromLLVMIRTranslatorTranslateType(
     MlirTypeFromLLVMIRTranslator translator, LLVMTypeRef llvmType);
 
+struct MlirTypeToLLVMIRTranslator {
+  void *ptr;
+};
+
+typedef struct MlirTypeToLLVMIRTranslator MlirTypeToLLVMIRTranslator;
+
+/// Create an LLVM::TypeToLLVMIRTranslator and transfer ownership to the
+/// caller.
+MLIR_CAPI_EXPORTED MlirTypeToLLVMIRTranslator
+mlirTypeToLLVMIRTranslatorCreate(LLVMContextRef ctx);
+
+/// Takes an LLVM::TypeToLLVMIRTranslator owned by the caller and destroys it.
+/// It is the responsibility of the user to only pass an
+/// LLVM::TypeToLLVMIRTranslator class.
+MLIR_CAPI_EXPORTED void
+mlirTypeToLLVMIRTranslatorDestroy(MlirTypeToLLVMIRTranslator translator);
+
+/// Translates the given MLIR LLVM dialect to the LLVM IR type.
+MLIR_CAPI_EXPORTED LLVMTypeRef mlirTypeToLLVMIRTranslatorTranslateType(
+    MlirTypeToLLVMIRTranslator translator, MlirType mlirType);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/mlir/lib/CAPI/Target/LLVMIR.cpp b/mlir/lib/CAPI/Target/LLVMIR.cpp
index 5261c8773faf7d..5e2bba8be45624 100644
--- a/mlir/lib/CAPI/Target/LLVMIR.cpp
+++ b/mlir/lib/CAPI/Target/LLVMIR.cpp
@@ -55,3 +55,25 @@ MlirType mlirTypeFromLLVMIRTranslatorTranslateType(
   mlir::Type type = translator_->translateType(llvm::unwrap(llvmType));
   return wrap(type);
 }
+
+DEFINE_C_API_PTR_METHODS(MlirTypeToLLVMIRTranslator,
+                         mlir::LLVM::TypeToLLVMIRTranslator);
+
+MlirTypeToLLVMIRTranslator
+mlirTypeToLLVMIRTranslatorCreate(LLVMContextRef ctx) {
+  llvm::LLVMContext *context = llvm::unwrap(ctx);
+  auto *translator = new LLVM::TypeToLLVMIRTranslator(*context);
+  return wrap(translator);
+}
+
+void mlirTypeToLLVMIRTranslatorDestroy(MlirTypeToLLVMIRTranslator translator) {
+  delete static_cast<LLVM::TypeToLLVMIRTranslator *>(unwrap(translator));
+}
+
+LLVMTypeRef
+mlirTypeToLLVMIRTranslatorTranslateType(MlirTypeToLLVMIRTranslator translator,
+                                        MlirType mlirType) {
+  LLVM::TypeToLLVMIRTranslator *translator_ = unwrap(translator);
+  llvm::Type *type = translator_->translateType(unwrap(mlirType));
+  return llvm::wrap(type);
+}
diff --git a/mlir/test/CAPI/translation.c b/mlir/test/CAPI/translation.c
index ddbf217c1d9862..a1284bbc95b3d5 100644
--- a/mlir/test/CAPI/translation.c
+++ b/mlir/test/CAPI/translation.c
@@ -64,13 +64,22 @@ static void testTypeFromLLVMIRTranslator(MlirContext ctx) {
   LLVMContextRef llvmCtx = LLVMContextCreate();
 
   LLVMTypeRef llvmTy = LLVMInt32TypeInContext(llvmCtx);
-  MlirTypeFromLLVMIRTranslator translator =
+  MlirTypeFromLLVMIRTranslator fromLLVMTranslator =
       mlirTypeFromLLVMIRTranslatorCreate(ctx);
   MlirType mlirTy =
-      mlirTypeFromLLVMIRTranslatorTranslateType(translator, llvmTy);
+      mlirTypeFromLLVMIRTranslatorTranslateType(fromLLVMTranslator, llvmTy);
   // CHECK: i32
   mlirTypeDump(mlirTy);
 
+  MlirTypeToLLVMIRTranslator toLLVMTranslator =
+      mlirTypeToLLVMIRTranslatorCreate(llvmCtx);
+  LLVMTypeRef llvmTy2 =
+      mlirTypeToLLVMIRTranslatorTranslateType(toLLVMTranslator, mlirTy);
+  // CHECK: i32
+  LLVMDumpType(llvmTy2);
+
+  mlirTypeFromLLVMIRTranslatorDestroy(fromLLVMTranslator);
+  mlirTypeToLLVMIRTranslatorDestroy(toLLVMTranslator);
   LLVMContextDispose(llvmCtx);
 }
 

>From 24f81e4ec76a572d4e2f4b673a51c7806af84ace Mon Sep 17 00:00:00 2001
From: max <maksim.levental at gmail.com>
Date: Wed, 29 Jan 2025 21:48:20 -0500
Subject: [PATCH 5/8] add uncheckedGetIntrinsicSignature and
 mlirLLVMFunctionTypeGetReturnType

---
 mlir/include/mlir-c/Dialect/LLVM.h           |  3 ++
 mlir/include/mlir-c/Target/LLVMIR.h          |  8 ++++
 mlir/include/mlir/Target/LLVMIR/TypeToLLVM.h |  9 +++++
 mlir/lib/CAPI/Dialect/LLVM.cpp               |  4 ++
 mlir/lib/CAPI/Target/LLVMIR.cpp              | 13 +++++++
 mlir/lib/Target/LLVMIR/TypeToLLVM.cpp        | 16 ++++++++
 mlir/test/CAPI/translation.c                 | 39 ++++++++++++++++++--
 7 files changed, 88 insertions(+), 4 deletions(-)

diff --git a/mlir/include/mlir-c/Dialect/LLVM.h b/mlir/include/mlir-c/Dialect/LLVM.h
index 26c4140757c3c9..65b14254e44925 100644
--- a/mlir/include/mlir-c/Dialect/LLVM.h
+++ b/mlir/include/mlir-c/Dialect/LLVM.h
@@ -52,6 +52,9 @@ MLIR_CAPI_EXPORTED intptr_t mlirLLVMFunctionTypeGetNumInputs(MlirType type);
 MLIR_CAPI_EXPORTED MlirType mlirLLVMFunctionTypeGetInput(MlirType type,
                                                          intptr_t pos);
 
+/// Returns the return type of the function type.
+MLIR_CAPI_EXPORTED MlirType mlirLLVMFunctionTypeGetReturnType(MlirType type);
+
 /// Returns `true` if the type is an LLVM dialect struct type.
 MLIR_CAPI_EXPORTED bool mlirTypeIsALLVMStructType(MlirType type);
 
diff --git a/mlir/include/mlir-c/Target/LLVMIR.h b/mlir/include/mlir-c/Target/LLVMIR.h
index 6a026c31d05117..5898a82c640e06 100644
--- a/mlir/include/mlir-c/Target/LLVMIR.h
+++ b/mlir/include/mlir-c/Target/LLVMIR.h
@@ -74,6 +74,14 @@ mlirTypeToLLVMIRTranslatorDestroy(MlirTypeToLLVMIRTranslator translator);
 MLIR_CAPI_EXPORTED LLVMTypeRef mlirTypeToLLVMIRTranslatorTranslateType(
     MlirTypeToLLVMIRTranslator translator, MlirType mlirType);
 
+/// Attempts to look up the LLVM intrinsic matching `id` with parameter types
+/// `mlirParamTypes`. Note, since no return type is required, no check is
+/// performed to verify the found intrinsic.
+MLIR_CAPI_EXPORTED LLVMTypeRef
+mlirTypeToLLVMIRTranslatorUncheckedGetIntrinsicSignature(
+    MlirTypeToLLVMIRTranslator translator, unsigned id,
+    MlirType *mlirParamTypes, unsigned numParams);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/mlir/include/mlir/Target/LLVMIR/TypeToLLVM.h b/mlir/include/mlir/Target/LLVMIR/TypeToLLVM.h
index 1d852676525ad0..29c3d0cadac13a 100644
--- a/mlir/include/mlir/Target/LLVMIR/TypeToLLVM.h
+++ b/mlir/include/mlir/Target/LLVMIR/TypeToLLVM.h
@@ -14,9 +14,12 @@
 #ifndef MLIR_TARGET_LLVMIR_TYPETOLLVM_H
 #define MLIR_TARGET_LLVMIR_TYPETOLLVM_H
 
+#include "llvm/ADT/ArrayRef.h"
+
 #include <memory>
 
 namespace llvm {
+class FunctionType;
 class DataLayout;
 class LLVMContext;
 class Type;
@@ -50,6 +53,12 @@ class TypeToLLVMIRTranslator {
   /// Translates the given MLIR LLVM dialect type to LLVM IR.
   llvm::Type *translateType(Type type);
 
+  /// Attempts to look up the LLVM intrinsic matching `id` with parameter types
+  /// `types`. Note, since no return type is required, no check is performed to
+  /// verify the found intrinsic.
+  llvm::FunctionType *
+  uncheckedGetIntrinsicSignature(unsigned id, llvm::ArrayRef<Type> types);
+
 private:
   /// Private implementation.
   std::unique_ptr<detail::TypeToLLVMIRTranslatorImpl> impl;
diff --git a/mlir/lib/CAPI/Dialect/LLVM.cpp b/mlir/lib/CAPI/Dialect/LLVM.cpp
index da450dd3fd8a3b..69c804b7667f3a 100644
--- a/mlir/lib/CAPI/Dialect/LLVM.cpp
+++ b/mlir/lib/CAPI/Dialect/LLVM.cpp
@@ -65,6 +65,10 @@ MlirType mlirLLVMFunctionTypeGetInput(MlirType type, intptr_t pos) {
                   .getParamType(static_cast<unsigned>(pos)));
 }
 
+MlirType mlirLLVMFunctionTypeGetReturnType(MlirType type) {
+  return wrap(llvm::cast<LLVM::LLVMFunctionType>(unwrap(type)).getReturnType());
+}
+
 bool mlirTypeIsALLVMStructType(MlirType type) {
   return isa<LLVM::LLVMStructType>(unwrap(type));
 }
diff --git a/mlir/lib/CAPI/Target/LLVMIR.cpp b/mlir/lib/CAPI/Target/LLVMIR.cpp
index 5e2bba8be45624..453a59624198aa 100644
--- a/mlir/lib/CAPI/Target/LLVMIR.cpp
+++ b/mlir/lib/CAPI/Target/LLVMIR.cpp
@@ -9,6 +9,7 @@
 
 #include "mlir-c/Target/LLVMIR.h"
 
+#include "llvm/IR/Intrinsics.h"
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/Module.h"
 #include "llvm/IR/Type.h"
@@ -77,3 +78,15 @@ mlirTypeToLLVMIRTranslatorTranslateType(MlirTypeToLLVMIRTranslator translator,
   llvm::Type *type = translator_->translateType(unwrap(mlirType));
   return llvm::wrap(type);
 }
+
+LLVMTypeRef mlirTypeToLLVMIRTranslatorUncheckedGetIntrinsicSignature(
+    MlirTypeToLLVMIRTranslator translator, unsigned id,
+    MlirType *mlirParamTypes, unsigned numParams) {
+  SmallVector<mlir::Type, 4> paramTypes;
+  for (unsigned i = 0; i < numParams; i++)
+    paramTypes.emplace_back(unwrap(mlirParamTypes[i]));
+  LLVM::TypeToLLVMIRTranslator *translator_ = unwrap(translator);
+  llvm::Type *functionType =
+      translator_->uncheckedGetIntrinsicSignature(id, paramTypes);
+  return llvm::wrap(functionType);
+}
diff --git a/mlir/lib/Target/LLVMIR/TypeToLLVM.cpp b/mlir/lib/Target/LLVMIR/TypeToLLVM.cpp
index c7a533eddce84b..d47c8bfc1687e4 100644
--- a/mlir/lib/Target/LLVMIR/TypeToLLVM.cpp
+++ b/mlir/lib/Target/LLVMIR/TypeToLLVM.cpp
@@ -14,6 +14,7 @@
 #include "llvm/ADT/TypeSwitch.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Intrinsics.h"
 #include "llvm/IR/Type.h"
 
 using namespace mlir;
@@ -84,6 +85,15 @@ class TypeToLLVMIRTranslatorImpl {
     return translated;
   }
 
+  llvm::FunctionType *
+  uncheckedGetIntrinsicSignature(unsigned id, llvm::ArrayRef<Type> types) {
+    SmallVector<llvm::Type *, 8> paramTypes;
+    if (llvm::Intrinsic::isOverloaded(id)) {
+      translateTypes(types, paramTypes);
+    }
+    return llvm::Intrinsic::getType(context, id, paramTypes);
+  }
+
 private:
   /// Translates the given array type.
   llvm::Type *translate(LLVM::LLVMArrayType type) {
@@ -193,6 +203,12 @@ llvm::Type *LLVM::TypeToLLVMIRTranslator::translateType(Type type) {
   return impl->translateType(type);
 }
 
+llvm::FunctionType *
+LLVM::TypeToLLVMIRTranslator::uncheckedGetIntrinsicSignature(
+    unsigned id, llvm::ArrayRef<Type> types) {
+  return impl->uncheckedGetIntrinsicSignature(id, types);
+}
+
 unsigned LLVM::TypeToLLVMIRTranslator::getPreferredAlignment(
     Type type, const llvm::DataLayout &layout) {
   return layout.getPrefTypeAlign(translateType(type)).value();
diff --git a/mlir/test/CAPI/translation.c b/mlir/test/CAPI/translation.c
index a1284bbc95b3d5..3aff3ae6bc8536 100644
--- a/mlir/test/CAPI/translation.c
+++ b/mlir/test/CAPI/translation.c
@@ -58,9 +58,9 @@ static void testToLLVMIR(MlirContext ctx) {
   LLVMContextDispose(llvmCtx);
 }
 
-// CHECK-LABEL: testTypeFromLLVMIRTranslator
-static void testTypeFromLLVMIRTranslator(MlirContext ctx) {
-  fprintf(stderr, "testTypeFromLLVMIRTranslator\n");
+// CHECK-LABEL: testTypeToFromLLVMIRTranslator
+static void testTypeToFromLLVMIRTranslator(MlirContext ctx) {
+  fprintf(stderr, "testTypeToFromLLVMIRTranslator\n");
   LLVMContextRef llvmCtx = LLVMContextCreate();
 
   LLVMTypeRef llvmTy = LLVMInt32TypeInContext(llvmCtx);
@@ -77,6 +77,37 @@ static void testTypeFromLLVMIRTranslator(MlirContext ctx) {
       mlirTypeToLLVMIRTranslatorTranslateType(toLLVMTranslator, mlirTy);
   // CHECK: i32
   LLVMDumpType(llvmTy2);
+  fprintf(stderr, "\n");
+
+  // check "not overloaded" path
+  MlirType i32 = mlirIntegerTypeGet(ctx, 32);
+  MlirType nonOverloadeTys[] = {i32};
+  unsigned returnAddressIID = LLVMLookupIntrinsicID("llvm.returnaddress", 18);
+  LLVMTypeRef returnAddressIntrinsicTy =
+      mlirTypeToLLVMIRTranslatorUncheckedGetIntrinsicSignature(
+          toLLVMTranslator, returnAddressIID, nonOverloadeTys, 1);
+  // CHECK: ptr (i32)
+  LLVMDumpType(returnAddressIntrinsicTy);
+  fprintf(stderr, "\n");
+
+  // check "overloaded" path
+  MlirType overloadeTys[] = {i32, i32};
+  unsigned sMaxIID = LLVMLookupIntrinsicID("llvm.smax", 9);
+  LLVMTypeRef llvmSMaxIntrinsicTy =
+      mlirTypeToLLVMIRTranslatorUncheckedGetIntrinsicSignature(
+          toLLVMTranslator, sMaxIID, overloadeTys, 2);
+  // CHECK: i32 (i32, i32)
+  LLVMDumpType(llvmSMaxIntrinsicTy);
+  fprintf(stderr, "\n");
+
+  MlirType mlirSMaxIntrinsicTy = mlirTypeFromLLVMIRTranslatorTranslateType(
+      fromLLVMTranslator, llvmSMaxIntrinsicTy);
+  // CHECK: !llvm.func<i32 (i32, i32)>
+  mlirTypeDump(mlirSMaxIntrinsicTy);
+
+  MlirType retType = mlirLLVMFunctionTypeGetReturnType(mlirSMaxIntrinsicTy);
+  // CHECK: i32
+  mlirTypeDump(retType);
 
   mlirTypeFromLLVMIRTranslatorDestroy(fromLLVMTranslator);
   mlirTypeToLLVMIRTranslatorDestroy(toLLVMTranslator);
@@ -88,7 +119,7 @@ int main(void) {
   mlirDialectHandleRegisterDialect(mlirGetDialectHandle__llvm__(), ctx);
   mlirContextGetOrLoadDialect(ctx, mlirStringRefCreateFromCString("llvm"));
   testToLLVMIR(ctx);
-  testTypeFromLLVMIRTranslator(ctx);
+  testTypeToFromLLVMIRTranslator(ctx);
   mlirContextDestroy(ctx);
   return 0;
 }

>From cdf3d98e5c327355a473eac7fde8a74fe4ea9f81 Mon Sep 17 00:00:00 2001
From: Maksim Levental <maksim.levental at gmail.com>
Date: Thu, 30 Jan 2025 09:22:11 -0500
Subject: [PATCH 6/8] remove uncheckedGetInstrincSource, add llvm-c/Core.h

---
 mlir/include/mlir-c/Target/LLVMIR.h          |  9 +-----
 mlir/include/mlir/Target/LLVMIR/TypeToLLVM.h |  6 ----
 mlir/lib/CAPI/Target/LLVMIR.cpp              | 13 ---------
 mlir/lib/Target/LLVMIR/TypeToLLVM.cpp        | 15 ----------
 mlir/test/CAPI/translation.c                 | 30 --------------------
 5 files changed, 1 insertion(+), 72 deletions(-)

diff --git a/mlir/include/mlir-c/Target/LLVMIR.h b/mlir/include/mlir-c/Target/LLVMIR.h
index 5898a82c640e06..b5f948961e898b 100644
--- a/mlir/include/mlir-c/Target/LLVMIR.h
+++ b/mlir/include/mlir-c/Target/LLVMIR.h
@@ -16,6 +16,7 @@
 
 #include "mlir-c/IR.h"
 #include "mlir-c/Support.h"
+#include "llvm-c/Core.h"
 #include "llvm-c/Support.h"
 
 #ifdef __cplusplus
@@ -74,14 +75,6 @@ mlirTypeToLLVMIRTranslatorDestroy(MlirTypeToLLVMIRTranslator translator);
 MLIR_CAPI_EXPORTED LLVMTypeRef mlirTypeToLLVMIRTranslatorTranslateType(
     MlirTypeToLLVMIRTranslator translator, MlirType mlirType);
 
-/// Attempts to look up the LLVM intrinsic matching `id` with parameter types
-/// `mlirParamTypes`. Note, since no return type is required, no check is
-/// performed to verify the found intrinsic.
-MLIR_CAPI_EXPORTED LLVMTypeRef
-mlirTypeToLLVMIRTranslatorUncheckedGetIntrinsicSignature(
-    MlirTypeToLLVMIRTranslator translator, unsigned id,
-    MlirType *mlirParamTypes, unsigned numParams);
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/mlir/include/mlir/Target/LLVMIR/TypeToLLVM.h b/mlir/include/mlir/Target/LLVMIR/TypeToLLVM.h
index 29c3d0cadac13a..2d9da8cf877084 100644
--- a/mlir/include/mlir/Target/LLVMIR/TypeToLLVM.h
+++ b/mlir/include/mlir/Target/LLVMIR/TypeToLLVM.h
@@ -53,12 +53,6 @@ class TypeToLLVMIRTranslator {
   /// Translates the given MLIR LLVM dialect type to LLVM IR.
   llvm::Type *translateType(Type type);
 
-  /// Attempts to look up the LLVM intrinsic matching `id` with parameter types
-  /// `types`. Note, since no return type is required, no check is performed to
-  /// verify the found intrinsic.
-  llvm::FunctionType *
-  uncheckedGetIntrinsicSignature(unsigned id, llvm::ArrayRef<Type> types);
-
 private:
   /// Private implementation.
   std::unique_ptr<detail::TypeToLLVMIRTranslatorImpl> impl;
diff --git a/mlir/lib/CAPI/Target/LLVMIR.cpp b/mlir/lib/CAPI/Target/LLVMIR.cpp
index 453a59624198aa..5e2bba8be45624 100644
--- a/mlir/lib/CAPI/Target/LLVMIR.cpp
+++ b/mlir/lib/CAPI/Target/LLVMIR.cpp
@@ -9,7 +9,6 @@
 
 #include "mlir-c/Target/LLVMIR.h"
 
-#include "llvm/IR/Intrinsics.h"
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/Module.h"
 #include "llvm/IR/Type.h"
@@ -78,15 +77,3 @@ mlirTypeToLLVMIRTranslatorTranslateType(MlirTypeToLLVMIRTranslator translator,
   llvm::Type *type = translator_->translateType(unwrap(mlirType));
   return llvm::wrap(type);
 }
-
-LLVMTypeRef mlirTypeToLLVMIRTranslatorUncheckedGetIntrinsicSignature(
-    MlirTypeToLLVMIRTranslator translator, unsigned id,
-    MlirType *mlirParamTypes, unsigned numParams) {
-  SmallVector<mlir::Type, 4> paramTypes;
-  for (unsigned i = 0; i < numParams; i++)
-    paramTypes.emplace_back(unwrap(mlirParamTypes[i]));
-  LLVM::TypeToLLVMIRTranslator *translator_ = unwrap(translator);
-  llvm::Type *functionType =
-      translator_->uncheckedGetIntrinsicSignature(id, paramTypes);
-  return llvm::wrap(functionType);
-}
diff --git a/mlir/lib/Target/LLVMIR/TypeToLLVM.cpp b/mlir/lib/Target/LLVMIR/TypeToLLVM.cpp
index d47c8bfc1687e4..26c64a34c72688 100644
--- a/mlir/lib/Target/LLVMIR/TypeToLLVM.cpp
+++ b/mlir/lib/Target/LLVMIR/TypeToLLVM.cpp
@@ -85,15 +85,6 @@ class TypeToLLVMIRTranslatorImpl {
     return translated;
   }
 
-  llvm::FunctionType *
-  uncheckedGetIntrinsicSignature(unsigned id, llvm::ArrayRef<Type> types) {
-    SmallVector<llvm::Type *, 8> paramTypes;
-    if (llvm::Intrinsic::isOverloaded(id)) {
-      translateTypes(types, paramTypes);
-    }
-    return llvm::Intrinsic::getType(context, id, paramTypes);
-  }
-
 private:
   /// Translates the given array type.
   llvm::Type *translate(LLVM::LLVMArrayType type) {
@@ -203,12 +194,6 @@ llvm::Type *LLVM::TypeToLLVMIRTranslator::translateType(Type type) {
   return impl->translateType(type);
 }
 
-llvm::FunctionType *
-LLVM::TypeToLLVMIRTranslator::uncheckedGetIntrinsicSignature(
-    unsigned id, llvm::ArrayRef<Type> types) {
-  return impl->uncheckedGetIntrinsicSignature(id, types);
-}
-
 unsigned LLVM::TypeToLLVMIRTranslator::getPreferredAlignment(
     Type type, const llvm::DataLayout &layout) {
   return layout.getPrefTypeAlign(translateType(type)).value();
diff --git a/mlir/test/CAPI/translation.c b/mlir/test/CAPI/translation.c
index 3aff3ae6bc8536..8891c2a559b7e8 100644
--- a/mlir/test/CAPI/translation.c
+++ b/mlir/test/CAPI/translation.c
@@ -79,36 +79,6 @@ static void testTypeToFromLLVMIRTranslator(MlirContext ctx) {
   LLVMDumpType(llvmTy2);
   fprintf(stderr, "\n");
 
-  // check "not overloaded" path
-  MlirType i32 = mlirIntegerTypeGet(ctx, 32);
-  MlirType nonOverloadeTys[] = {i32};
-  unsigned returnAddressIID = LLVMLookupIntrinsicID("llvm.returnaddress", 18);
-  LLVMTypeRef returnAddressIntrinsicTy =
-      mlirTypeToLLVMIRTranslatorUncheckedGetIntrinsicSignature(
-          toLLVMTranslator, returnAddressIID, nonOverloadeTys, 1);
-  // CHECK: ptr (i32)
-  LLVMDumpType(returnAddressIntrinsicTy);
-  fprintf(stderr, "\n");
-
-  // check "overloaded" path
-  MlirType overloadeTys[] = {i32, i32};
-  unsigned sMaxIID = LLVMLookupIntrinsicID("llvm.smax", 9);
-  LLVMTypeRef llvmSMaxIntrinsicTy =
-      mlirTypeToLLVMIRTranslatorUncheckedGetIntrinsicSignature(
-          toLLVMTranslator, sMaxIID, overloadeTys, 2);
-  // CHECK: i32 (i32, i32)
-  LLVMDumpType(llvmSMaxIntrinsicTy);
-  fprintf(stderr, "\n");
-
-  MlirType mlirSMaxIntrinsicTy = mlirTypeFromLLVMIRTranslatorTranslateType(
-      fromLLVMTranslator, llvmSMaxIntrinsicTy);
-  // CHECK: !llvm.func<i32 (i32, i32)>
-  mlirTypeDump(mlirSMaxIntrinsicTy);
-
-  MlirType retType = mlirLLVMFunctionTypeGetReturnType(mlirSMaxIntrinsicTy);
-  // CHECK: i32
-  mlirTypeDump(retType);
-
   mlirTypeFromLLVMIRTranslatorDestroy(fromLLVMTranslator);
   mlirTypeToLLVMIRTranslatorDestroy(toLLVMTranslator);
   LLVMContextDispose(llvmCtx);

>From 7d22af157cdc5f4d39f9dc7a85e5aec5bc06740f Mon Sep 17 00:00:00 2001
From: Maksim Levental <maksim.levental at gmail.com>
Date: Thu, 30 Jan 2025 12:07:41 -0500
Subject: [PATCH 7/8] revert TypeToLLVM.h

---
 mlir/include/mlir/Target/LLVMIR/TypeToLLVM.h | 3 ---
 mlir/lib/Target/LLVMIR/TypeToLLVM.cpp        | 1 -
 2 files changed, 4 deletions(-)

diff --git a/mlir/include/mlir/Target/LLVMIR/TypeToLLVM.h b/mlir/include/mlir/Target/LLVMIR/TypeToLLVM.h
index 2d9da8cf877084..1d852676525ad0 100644
--- a/mlir/include/mlir/Target/LLVMIR/TypeToLLVM.h
+++ b/mlir/include/mlir/Target/LLVMIR/TypeToLLVM.h
@@ -14,12 +14,9 @@
 #ifndef MLIR_TARGET_LLVMIR_TYPETOLLVM_H
 #define MLIR_TARGET_LLVMIR_TYPETOLLVM_H
 
-#include "llvm/ADT/ArrayRef.h"
-
 #include <memory>
 
 namespace llvm {
-class FunctionType;
 class DataLayout;
 class LLVMContext;
 class Type;
diff --git a/mlir/lib/Target/LLVMIR/TypeToLLVM.cpp b/mlir/lib/Target/LLVMIR/TypeToLLVM.cpp
index 26c64a34c72688..c7a533eddce84b 100644
--- a/mlir/lib/Target/LLVMIR/TypeToLLVM.cpp
+++ b/mlir/lib/Target/LLVMIR/TypeToLLVM.cpp
@@ -14,7 +14,6 @@
 #include "llvm/ADT/TypeSwitch.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/DerivedTypes.h"
-#include "llvm/IR/Intrinsics.h"
 #include "llvm/IR/Type.h"
 
 using namespace mlir;

>From 157af9b822b850b42a46d7c7e821d5d66fe216eb Mon Sep 17 00:00:00 2001
From: Maksim Levental <maksim.levental at gmail.com>
Date: Thu, 30 Jan 2025 14:50:33 -0500
Subject: [PATCH 8/8] [mlir][llvmir][reland] expose
 Type(To/From)LLVMIRTranslator C API

---
 mlir/lib/CAPI/Target/CMakeLists.txt | 1 +
 mlir/lib/CAPI/Target/LLVMIR.cpp     | 7 +++----
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/mlir/lib/CAPI/Target/CMakeLists.txt b/mlir/lib/CAPI/Target/CMakeLists.txt
index ce86fd3def964c..ea617da72261bc 100644
--- a/mlir/lib/CAPI/Target/CMakeLists.txt
+++ b/mlir/lib/CAPI/Target/CMakeLists.txt
@@ -8,5 +8,6 @@ add_mlir_upstream_c_api_library(MLIRCAPITarget
   MLIRToLLVMIRTranslationRegistration
   MLIRCAPIIR
   MLIRLLVMToLLVMIRTranslation
+  MLIRLLVMIRToLLVMTranslation
   MLIRSupport
 )
diff --git a/mlir/lib/CAPI/Target/LLVMIR.cpp b/mlir/lib/CAPI/Target/LLVMIR.cpp
index 5e2bba8be45624..0bb2903fc300f2 100644
--- a/mlir/lib/CAPI/Target/LLVMIR.cpp
+++ b/mlir/lib/CAPI/Target/LLVMIR.cpp
@@ -35,7 +35,7 @@ LLVMModuleRef mlirTranslateModuleToLLVMIR(MlirOperation module,
 }
 
 DEFINE_C_API_PTR_METHODS(MlirTypeFromLLVMIRTranslator,
-                         mlir::LLVM::TypeFromLLVMIRTranslator);
+                         mlir::LLVM::TypeFromLLVMIRTranslator)
 
 MlirTypeFromLLVMIRTranslator
 mlirTypeFromLLVMIRTranslatorCreate(MlirContext ctx) {
@@ -45,9 +45,8 @@ mlirTypeFromLLVMIRTranslatorCreate(MlirContext ctx) {
 }
 
 void mlirTypeFromLLVMIRTranslatorDestroy(
-    MlirTypeFromLLVMIRTranslator translator) {
-  delete static_cast<LLVM::TypeFromLLVMIRTranslator *>(unwrap(translator));
-}
+    MlirTypeFromLLVMIRTranslator translator){
+    delete static_cast<LLVM::TypeFromLLVMIRTranslator *>(unwrap(translator))}
 
 MlirType mlirTypeFromLLVMIRTranslatorTranslateType(
     MlirTypeFromLLVMIRTranslator translator, LLVMTypeRef llvmType) {



More information about the Mlir-commits mailing list