[flang] Fix crash in HLFIR generation (#118399)
[llvm-project.git] / mlir / test / CAPI / execution_engine.c
blob4751288c3ee4bd18fb0c96892f77a5dbf8d223dd
1 //===- execution_engine.c - Test for the C bindings for the MLIR JIT-------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM
4 // Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //
8 //===----------------------------------------------------------------------===//
10 /* RUN: mlir-capi-execution-engine-test 2>&1 | FileCheck %s
12 /* REQUIRES: host-supports-jit
15 #include "mlir-c/Conversion.h"
16 #include "mlir-c/ExecutionEngine.h"
17 #include "mlir-c/IR.h"
18 #include "mlir-c/RegisterEverything.h"
20 #include <assert.h>
21 #include <math.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
26 static void registerAllUpstreamDialects(MlirContext ctx) {
27 MlirDialectRegistry registry = mlirDialectRegistryCreate();
28 mlirRegisterAllDialects(registry);
29 mlirContextAppendDialectRegistry(ctx, registry);
30 mlirDialectRegistryDestroy(registry);
33 void lowerModuleToLLVM(MlirContext ctx, MlirModule module) {
34 MlirPassManager pm = mlirPassManagerCreate(ctx);
35 MlirOpPassManager opm = mlirPassManagerGetNestedUnder(
36 pm, mlirStringRefCreateFromCString("func.func"));
37 mlirPassManagerAddOwnedPass(pm, mlirCreateConversionConvertFuncToLLVMPass());
38 mlirOpPassManagerAddOwnedPass(
39 opm, mlirCreateConversionArithToLLVMConversionPass());
40 MlirLogicalResult status =
41 mlirPassManagerRunOnOp(pm, mlirModuleGetOperation(module));
42 if (mlirLogicalResultIsFailure(status)) {
43 fprintf(stderr, "Unexpected failure running pass pipeline\n");
44 exit(2);
46 mlirPassManagerDestroy(pm);
49 // CHECK-LABEL: Running test 'testSimpleExecution'
50 void testSimpleExecution(void) {
51 MlirContext ctx = mlirContextCreate();
52 registerAllUpstreamDialects(ctx);
54 MlirModule module = mlirModuleCreateParse(
55 ctx, mlirStringRefCreateFromCString(
56 // clang-format off
57 "module { \n"
58 #ifdef __s390__
59 " func.func @add(%arg0 : i32) -> (i32 {llvm.signext}) attributes { llvm.emit_c_interface } { \n"
60 #else
61 " func.func @add(%arg0 : i32) -> i32 attributes { llvm.emit_c_interface } { \n"
62 #endif
63 " %res = arith.addi %arg0, %arg0 : i32 \n"
64 " return %res : i32 \n"
65 " } \n"
66 "}"));
67 // clang-format on
68 lowerModuleToLLVM(ctx, module);
69 mlirRegisterAllLLVMTranslations(ctx);
70 MlirExecutionEngine jit = mlirExecutionEngineCreate(
71 module, /*optLevel=*/2, /*numPaths=*/0, /*sharedLibPaths=*/NULL,
72 /*enableObjectDump=*/false);
73 if (mlirExecutionEngineIsNull(jit)) {
74 fprintf(stderr, "Execution engine creation failed");
75 exit(2);
77 int input = 42;
78 int result = -1;
79 void *args[2] = {&input, &result};
80 if (mlirLogicalResultIsFailure(mlirExecutionEngineInvokePacked(
81 jit, mlirStringRefCreateFromCString("add"), args))) {
82 fprintf(stderr, "Execution engine creation failed");
83 abort();
85 // CHECK: Input: 42 Result: 84
86 printf("Input: %d Result: %d\n", input, result);
87 mlirExecutionEngineDestroy(jit);
88 mlirModuleDestroy(module);
89 mlirContextDestroy(ctx);
92 // CHECK-LABEL: Running test 'testOmpCreation'
93 void testOmpCreation(void) {
94 MlirContext ctx = mlirContextCreate();
95 registerAllUpstreamDialects(ctx);
97 MlirModule module = mlirModuleCreateParse(
98 ctx, mlirStringRefCreateFromCString(
99 // clang-format off
100 "module { \n"
101 " func.func @main() attributes { llvm.emit_c_interface } { \n"
102 " %0 = arith.constant 0 : i32 \n"
103 " %1 = arith.constant 1 : i32 \n"
104 " %2 = arith.constant 2 : i32 \n"
105 " omp.parallel { \n"
106 " omp.wsloop { \n"
107 " omp.loop_nest (%3) : i32 = (%0) to (%2) step (%1) { \n"
108 " omp.yield \n"
109 " } \n"
110 " } \n"
111 " omp.terminator \n"
112 " } \n"
113 " llvm.return \n"
114 " } \n"
115 "} \n"
117 // clang-format on
118 lowerModuleToLLVM(ctx, module);
120 // At this point all operations in the MLIR module have been lowered to the
121 // 'llvm' dialect except 'omp' operations. The goal of this test is
122 // guaranteeing that the execution engine C binding has registered OpenMP
123 // translations and therefore does not fail when it encounters 'omp' ops.
124 // We don't attempt to run the engine, since that would force us to link
125 // against the OpenMP library.
126 MlirExecutionEngine jit = mlirExecutionEngineCreate(
127 module, /*optLevel=*/2, /*numPaths=*/0, /*sharedLibPaths=*/NULL,
128 /*enableObjectDump=*/false);
129 if (mlirExecutionEngineIsNull(jit)) {
130 fprintf(stderr, "Engine creation failed with OpenMP");
131 exit(2);
133 // CHECK: Engine creation succeeded with OpenMP
134 printf("Engine creation succeeded with OpenMP\n");
135 mlirExecutionEngineDestroy(jit);
136 mlirModuleDestroy(module);
137 mlirContextDestroy(ctx);
140 int main(void) {
142 #define _STRINGIFY(x) #x
143 #define STRINGIFY(x) _STRINGIFY(x)
144 #define TEST(test) \
145 printf("Running test '" STRINGIFY(test) "'\n"); \
146 test();
148 TEST(testSimpleExecution);
149 TEST(testOmpCreation);
150 return 0;