[flang] Fix crash in HLFIR generation (#118399)
[llvm-project.git] / mlir / test / CAPI / llvm.c
blob12a436ad12fc4c609a6c3ff70407aa762fa3bdd0
1 //===- llvm.c - Test of llvm APIs -----------------------------------------===//
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-llvm-test 2>&1 | FileCheck %s
12 #include "mlir-c/Dialect/LLVM.h"
13 #include "mlir-c/BuiltinAttributes.h"
14 #include "mlir-c/BuiltinTypes.h"
15 #include "mlir-c/IR.h"
16 #include "mlir-c/Support.h"
17 #include "llvm-c/Core.h"
18 #include "llvm-c/DebugInfo.h"
20 #include <assert.h>
21 #include <inttypes.h>
22 #include <math.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
27 // CHECK-LABEL: testTypeCreation()
28 static void testTypeCreation(MlirContext ctx) {
29 fprintf(stderr, "testTypeCreation()\n");
30 MlirType i8 = mlirIntegerTypeGet(ctx, 8);
31 MlirType i32 = mlirIntegerTypeGet(ctx, 32);
32 MlirType i64 = mlirIntegerTypeGet(ctx, 64);
34 const char *ptr_text = "!llvm.ptr";
35 MlirType ptr = mlirLLVMPointerTypeGet(ctx, 0);
36 MlirType ptr_ref =
37 mlirTypeParseGet(ctx, mlirStringRefCreateFromCString(ptr_text));
38 // CHECK: !llvm.ptr: 1
39 fprintf(stderr, "%s: %d\n", ptr_text, mlirTypeEqual(ptr, ptr_ref));
41 const char *ptr_addr_text = "!llvm.ptr<42>";
42 MlirType ptr_addr = mlirLLVMPointerTypeGet(ctx, 42);
43 MlirType ptr_addr_ref =
44 mlirTypeParseGet(ctx, mlirStringRefCreateFromCString(ptr_addr_text));
45 // CHECK: !llvm.ptr<42>: 1
46 fprintf(stderr, "%s: %d\n", ptr_addr_text,
47 mlirTypeEqual(ptr_addr, ptr_addr_ref));
49 const char *voidt_text = "!llvm.void";
50 MlirType voidt = mlirLLVMVoidTypeGet(ctx);
51 MlirType voidt_ref =
52 mlirTypeParseGet(ctx, mlirStringRefCreateFromCString(voidt_text));
53 // CHECK: !llvm.void: 1
54 fprintf(stderr, "%s: %d\n", voidt_text, mlirTypeEqual(voidt, voidt_ref));
56 const char *i32_4_text = "!llvm.array<4 x i32>";
57 MlirType i32_4 = mlirLLVMArrayTypeGet(i32, 4);
58 MlirType i32_4_ref =
59 mlirTypeParseGet(ctx, mlirStringRefCreateFromCString(i32_4_text));
60 // CHECK: !llvm.array<4 x i32>: 1
61 fprintf(stderr, "%s: %d\n", i32_4_text, mlirTypeEqual(i32_4, i32_4_ref));
63 const char *i8_i32_i64_text = "!llvm.func<i8 (i32, i64)>";
64 const MlirType i32_i64_arr[] = {i32, i64};
65 MlirType i8_i32_i64 = mlirLLVMFunctionTypeGet(i8, 2, i32_i64_arr, false);
66 MlirType i8_i32_i64_ref =
67 mlirTypeParseGet(ctx, mlirStringRefCreateFromCString(i8_i32_i64_text));
68 // CHECK: !llvm.func<i8 (i32, i64)>: 1
69 fprintf(stderr, "%s: %d\n", i8_i32_i64_text,
70 mlirTypeEqual(i8_i32_i64, i8_i32_i64_ref));
72 const char *i32_i64_s_text = "!llvm.struct<(i32, i64)>";
73 MlirType i32_i64_s = mlirLLVMStructTypeLiteralGet(ctx, 2, i32_i64_arr, false);
74 MlirType i32_i64_s_ref =
75 mlirTypeParseGet(ctx, mlirStringRefCreateFromCString(i32_i64_s_text));
76 // CHECK: !llvm.struct<(i32, i64)>: 1
77 fprintf(stderr, "%s: %d\n", i32_i64_s_text,
78 mlirTypeEqual(i32_i64_s, i32_i64_s_ref));
81 // CHECK-LABEL: testStructTypeCreation
82 static int testStructTypeCreation(MlirContext ctx) {
83 fprintf(stderr, "testStructTypeCreation\n");
85 // CHECK: !llvm.struct<()>
86 mlirTypeDump(mlirLLVMStructTypeLiteralGet(ctx, /*nFieldTypes=*/0,
87 /*fieldTypes=*/NULL,
88 /*isPacked=*/false));
90 MlirType i8 = mlirIntegerTypeGet(ctx, 8);
91 MlirType i32 = mlirIntegerTypeGet(ctx, 32);
92 MlirType i64 = mlirIntegerTypeGet(ctx, 64);
93 MlirType i8_i32_i64[] = {i8, i32, i64};
94 // CHECK: !llvm.struct<(i8, i32, i64)>
95 mlirTypeDump(
96 mlirLLVMStructTypeLiteralGet(ctx, sizeof(i8_i32_i64) / sizeof(MlirType),
97 i8_i32_i64, /*isPacked=*/false));
98 // CHECK: !llvm.struct<(i32)>
99 mlirTypeDump(mlirLLVMStructTypeLiteralGet(ctx, 1, &i32, /*isPacked=*/false));
100 MlirType i32_i32[] = {i32, i32};
101 // CHECK: !llvm.struct<packed (i32, i32)>
102 mlirTypeDump(mlirLLVMStructTypeLiteralGet(
103 ctx, sizeof(i32_i32) / sizeof(MlirType), i32_i32, /*isPacked=*/true));
105 MlirType literal =
106 mlirLLVMStructTypeLiteralGet(ctx, sizeof(i8_i32_i64) / sizeof(MlirType),
107 i8_i32_i64, /*isPacked=*/false);
108 // CHECK: num elements: 3
109 // CHECK: i8
110 // CHECK: i32
111 // CHECK: i64
112 fprintf(stderr, "num elements: %" PRIdPTR "\n",
113 mlirLLVMStructTypeGetNumElementTypes(literal));
114 for (intptr_t i = 0; i < 3; ++i) {
115 mlirTypeDump(mlirLLVMStructTypeGetElementType(literal, i));
118 if (!mlirTypeEqual(
119 mlirLLVMStructTypeLiteralGet(ctx, 1, &i32, /*isPacked=*/false),
120 mlirLLVMStructTypeLiteralGet(ctx, 1, &i32, /*isPacked=*/false))) {
121 return 1;
123 if (mlirTypeEqual(
124 mlirLLVMStructTypeLiteralGet(ctx, 1, &i32, /*isPacked=*/false),
125 mlirLLVMStructTypeLiteralGet(ctx, 1, &i64, /*isPacked=*/false))) {
126 return 2;
129 // CHECK: !llvm.struct<"foo", opaque>
130 // CHECK: !llvm.struct<"bar", opaque>
131 mlirTypeDump(mlirLLVMStructTypeIdentifiedGet(
132 ctx, mlirStringRefCreateFromCString("foo")));
133 mlirTypeDump(mlirLLVMStructTypeIdentifiedGet(
134 ctx, mlirStringRefCreateFromCString("bar")));
136 if (!mlirTypeEqual(mlirLLVMStructTypeIdentifiedGet(
137 ctx, mlirStringRefCreateFromCString("foo")),
138 mlirLLVMStructTypeIdentifiedGet(
139 ctx, mlirStringRefCreateFromCString("foo")))) {
140 return 3;
142 if (mlirTypeEqual(mlirLLVMStructTypeIdentifiedGet(
143 ctx, mlirStringRefCreateFromCString("foo")),
144 mlirLLVMStructTypeIdentifiedGet(
145 ctx, mlirStringRefCreateFromCString("bar")))) {
146 return 4;
149 MlirType fooStruct = mlirLLVMStructTypeIdentifiedGet(
150 ctx, mlirStringRefCreateFromCString("foo"));
151 MlirStringRef name = mlirLLVMStructTypeGetIdentifier(fooStruct);
152 if (memcmp(name.data, "foo", name.length))
153 return 5;
154 if (!mlirLLVMStructTypeIsOpaque(fooStruct))
155 return 6;
157 MlirType i32_i64[] = {i32, i64};
158 MlirLogicalResult result =
159 mlirLLVMStructTypeSetBody(fooStruct, sizeof(i32_i64) / sizeof(MlirType),
160 i32_i64, /*isPacked=*/false);
161 if (!mlirLogicalResultIsSuccess(result))
162 return 7;
164 // CHECK: !llvm.struct<"foo", (i32, i64)>
165 mlirTypeDump(fooStruct);
166 if (mlirLLVMStructTypeIsOpaque(fooStruct))
167 return 8;
168 if (mlirLLVMStructTypeIsPacked(fooStruct))
169 return 9;
170 if (!mlirTypeEqual(mlirLLVMStructTypeIdentifiedGet(
171 ctx, mlirStringRefCreateFromCString("foo")),
172 fooStruct)) {
173 return 10;
176 MlirType barStruct = mlirLLVMStructTypeIdentifiedGet(
177 ctx, mlirStringRefCreateFromCString("bar"));
178 result = mlirLLVMStructTypeSetBody(barStruct, 1, &i32, /*isPacked=*/true);
179 if (!mlirLogicalResultIsSuccess(result))
180 return 11;
182 // CHECK: !llvm.struct<"bar", packed (i32)>
183 mlirTypeDump(barStruct);
184 if (!mlirLLVMStructTypeIsPacked(barStruct))
185 return 12;
187 // Same body, should succeed.
188 result =
189 mlirLLVMStructTypeSetBody(fooStruct, sizeof(i32_i64) / sizeof(MlirType),
190 i32_i64, /*isPacked=*/false);
191 if (!mlirLogicalResultIsSuccess(result))
192 return 13;
194 // Different body, should fail.
195 result = mlirLLVMStructTypeSetBody(fooStruct, 1, &i32, /*isPacked=*/false);
196 if (mlirLogicalResultIsSuccess(result))
197 return 14;
199 // Packed flag differs, should fail.
200 result = mlirLLVMStructTypeSetBody(barStruct, 1, &i32, /*isPacked=*/false);
201 if (mlirLogicalResultIsSuccess(result))
202 return 15;
204 // Should have a different name.
205 // CHECK: !llvm.struct<"foo{{[^"]+}}
206 mlirTypeDump(mlirLLVMStructTypeIdentifiedNewGet(
207 ctx, mlirStringRefCreateFromCString("foo"), /*nFieldTypes=*/0,
208 /*fieldTypes=*/NULL, /*isPacked=*/false));
210 // Two freshly created "new" types must differ.
211 if (mlirTypeEqual(
212 mlirLLVMStructTypeIdentifiedNewGet(
213 ctx, mlirStringRefCreateFromCString("foo"), /*nFieldTypes=*/0,
214 /*fieldTypes=*/NULL, /*isPacked=*/false),
215 mlirLLVMStructTypeIdentifiedNewGet(
216 ctx, mlirStringRefCreateFromCString("foo"), /*nFieldTypes=*/0,
217 /*fieldTypes=*/NULL, /*isPacked=*/false))) {
218 return 16;
221 MlirType opaque = mlirLLVMStructTypeOpaqueGet(
222 ctx, mlirStringRefCreateFromCString("opaque"));
223 // CHECK: !llvm.struct<"opaque", opaque>
224 mlirTypeDump(opaque);
225 if (!mlirLLVMStructTypeIsOpaque(opaque))
226 return 17;
228 return 0;
231 // CHECK-LABEL: testLLVMAttributes
232 static void testLLVMAttributes(MlirContext ctx) {
233 fprintf(stderr, "testLLVMAttributes\n");
235 // CHECK: #llvm.linkage<internal>
236 mlirAttributeDump(mlirLLVMLinkageAttrGet(ctx, MlirLLVMLinkageInternal));
237 // CHECK: #llvm.cconv<ccc>
238 mlirAttributeDump(mlirLLVMCConvAttrGet(ctx, MlirLLVMCConvC));
239 // CHECK: #llvm<comdat any>
240 mlirAttributeDump(mlirLLVMComdatAttrGet(ctx, MlirLLVMComdatAny));
243 // CHECK-LABEL: testDebugInfoAttributes
244 static void testDebugInfoAttributes(MlirContext ctx) {
245 fprintf(stderr, "testDebugInfoAttributes\n");
247 MlirAttribute foo =
248 mlirStringAttrGet(ctx, mlirStringRefCreateFromCString("foo"));
249 MlirAttribute bar =
250 mlirStringAttrGet(ctx, mlirStringRefCreateFromCString("bar"));
252 MlirAttribute none = mlirUnitAttrGet(ctx);
253 MlirAttribute id = mlirDisctinctAttrCreate(none);
254 MlirAttribute recId0 = mlirDisctinctAttrCreate(none);
255 MlirAttribute recId1 = mlirDisctinctAttrCreate(none);
257 // CHECK: #llvm.di_null_type
258 mlirAttributeDump(mlirLLVMDINullTypeAttrGet(ctx));
260 // CHECK: #llvm.di_basic_type<name = "foo", sizeInBits =
261 // CHECK-SAME: 64, encoding = DW_ATE_signed>
262 MlirAttribute di_type =
263 mlirLLVMDIBasicTypeAttrGet(ctx, 0, foo, 64, MlirLLVMTypeEncodingSigned);
264 mlirAttributeDump(di_type);
266 MlirAttribute file = mlirLLVMDIFileAttrGet(ctx, foo, bar);
268 // CHECK: #llvm.di_file<"foo" in "bar">
269 mlirAttributeDump(file);
271 MlirAttribute compile_unit = mlirLLVMDICompileUnitAttrGet(
272 ctx, id, LLVMDWARFSourceLanguageC99, file, foo, false,
273 MlirLLVMDIEmissionKindFull, MlirLLVMDINameTableKindDefault);
275 // CHECK: #llvm.di_compile_unit<{{.*}}>
276 mlirAttributeDump(compile_unit);
278 MlirAttribute di_module = mlirLLVMDIModuleAttrGet(
279 ctx, file, compile_unit, foo,
280 mlirStringAttrGet(ctx, mlirStringRefCreateFromCString("")), bar, foo, 1,
282 // CHECK: #llvm.di_module<{{.*}}>
283 mlirAttributeDump(di_module);
285 // CHECK: #llvm.di_compile_unit<{{.*}}>
286 mlirAttributeDump(mlirLLVMDIModuleAttrGetScope(di_module));
288 // CHECK: 1 : i32
289 mlirAttributeDump(mlirLLVMDIFlagsAttrGet(ctx, 0x1));
291 // CHECK: #llvm.di_lexical_block<{{.*}}>
292 mlirAttributeDump(
293 mlirLLVMDILexicalBlockAttrGet(ctx, compile_unit, file, 1, 2));
295 // CHECK: #llvm.di_lexical_block_file<{{.*}}>
296 mlirAttributeDump(
297 mlirLLVMDILexicalBlockFileAttrGet(ctx, compile_unit, file, 3));
299 // CHECK: #llvm.di_local_variable<{{.*}}>
300 MlirAttribute local_var = mlirLLVMDILocalVariableAttrGet(
301 ctx, compile_unit, foo, file, 1, 0, 8, di_type, 0);
302 mlirAttributeDump(local_var);
303 // CHECK: #llvm.di_derived_type<{{.*}}>
304 // CHECK-NOT: dwarfAddressSpace
305 mlirAttributeDump(mlirLLVMDIDerivedTypeAttrGet(
306 ctx, 0, bar, di_type, 64, 8, 0, MLIR_CAPI_DWARF_ADDRESS_SPACE_NULL,
307 di_type));
309 // CHECK: #llvm.di_derived_type<{{.*}} dwarfAddressSpace = 3{{.*}}>
310 mlirAttributeDump(
311 mlirLLVMDIDerivedTypeAttrGet(ctx, 0, bar, di_type, 64, 8, 0, 3, di_type));
313 MlirAttribute subroutine_type =
314 mlirLLVMDISubroutineTypeAttrGet(ctx, 0x0, 1, &di_type);
316 // CHECK: #llvm.di_subroutine_type<{{.*}}>
317 mlirAttributeDump(subroutine_type);
319 MlirAttribute di_subprogram_self_rec =
320 mlirLLVMDISubprogramAttrGetRecSelf(recId0);
321 MlirAttribute di_imported_entity = mlirLLVMDIImportedEntityAttrGet(
322 ctx, 0, di_subprogram_self_rec, di_module, file, 1, foo, 1, &local_var);
324 mlirAttributeDump(di_imported_entity);
325 // CHECK: #llvm.di_imported_entity<{{.*}}>
327 MlirAttribute di_annotation = mlirLLVMDIAnnotationAttrGet(
328 ctx, mlirStringAttrGet(ctx, mlirStringRefCreateFromCString("foo")),
329 mlirStringAttrGet(ctx, mlirStringRefCreateFromCString("bar")));
331 mlirAttributeDump(di_annotation);
332 // CHECK: #llvm.di_annotation<{{.*}}>
334 MlirAttribute di_subprogram = mlirLLVMDISubprogramAttrGet(
335 ctx, recId0, false, id, compile_unit, compile_unit, foo, bar, file, 1, 2,
336 0, subroutine_type, 1, &di_imported_entity, 1, &di_annotation);
337 // CHECK: #llvm.di_subprogram<{{.*}}>
338 mlirAttributeDump(di_subprogram);
340 // CHECK: #llvm.di_compile_unit<{{.*}}>
341 mlirAttributeDump(mlirLLVMDISubprogramAttrGetScope(di_subprogram));
343 // CHECK: #llvm.di_file<{{.*}}>
344 mlirAttributeDump(mlirLLVMDISubprogramAttrGetFile(di_subprogram));
346 // CHECK: #llvm.di_subroutine_type<{{.*}}>
347 mlirAttributeDump(mlirLLVMDISubprogramAttrGetType(di_subprogram));
349 MlirAttribute expression_elem =
350 mlirLLVMDIExpressionElemAttrGet(ctx, 1, 1, &(uint64_t){1});
352 // CHECK: #llvm<di_expression_elem(1)>
353 mlirAttributeDump(expression_elem);
355 MlirAttribute expression =
356 mlirLLVMDIExpressionAttrGet(ctx, 1, &expression_elem);
357 // CHECK: #llvm.di_expression<[(1)]>
358 mlirAttributeDump(expression);
360 MlirAttribute string_type =
361 mlirLLVMDIStringTypeAttrGet(ctx, 0x0, foo, 16, 0, local_var, expression,
362 expression, MlirLLVMTypeEncodingSigned);
363 // CHECK: #llvm.di_string_type<{{.*}}>
364 mlirAttributeDump(string_type);
366 // CHECK: #llvm.di_composite_type<recId = {{.*}}, isRecSelf = true>
367 mlirAttributeDump(mlirLLVMDICompositeTypeAttrGetRecSelf(recId1));
369 // CHECK: #llvm.di_composite_type<{{.*}}>
370 mlirAttributeDump(mlirLLVMDICompositeTypeAttrGet(
371 ctx, recId1, false, 0, foo, file, 1, compile_unit, di_type, 0, 64, 8, 1,
372 &di_type, expression, expression, expression, expression));
375 int main(void) {
376 MlirContext ctx = mlirContextCreate();
377 mlirDialectHandleRegisterDialect(mlirGetDialectHandle__llvm__(), ctx);
378 mlirContextGetOrLoadDialect(ctx, mlirStringRefCreateFromCString("llvm"));
379 testTypeCreation(ctx);
380 int result = testStructTypeCreation(ctx);
381 testLLVMAttributes(ctx);
382 testDebugInfoAttributes(ctx);
383 mlirContextDestroy(ctx);
384 if (result)
385 fprintf(stderr, "FAILED: code %d", result);
386 return result;