1 //===- llvm.c - Test of llvm APIs -----------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
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"
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);
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
);
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);
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,
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)>
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));
106 mlirLLVMStructTypeLiteralGet(ctx
, sizeof(i8_i32_i64
) / sizeof(MlirType
),
107 i8_i32_i64
, /*isPacked=*/false);
108 // CHECK: num elements: 3
112 fprintf(stderr
, "num elements: %" PRIdPTR
"\n",
113 mlirLLVMStructTypeGetNumElementTypes(literal
));
114 for (intptr_t i
= 0; i
< 3; ++i
) {
115 mlirTypeDump(mlirLLVMStructTypeGetElementType(literal
, i
));
119 mlirLLVMStructTypeLiteralGet(ctx
, 1, &i32
, /*isPacked=*/false),
120 mlirLLVMStructTypeLiteralGet(ctx
, 1, &i32
, /*isPacked=*/false))) {
124 mlirLLVMStructTypeLiteralGet(ctx
, 1, &i32
, /*isPacked=*/false),
125 mlirLLVMStructTypeLiteralGet(ctx
, 1, &i64
, /*isPacked=*/false))) {
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")))) {
142 if (mlirTypeEqual(mlirLLVMStructTypeIdentifiedGet(
143 ctx
, mlirStringRefCreateFromCString("foo")),
144 mlirLLVMStructTypeIdentifiedGet(
145 ctx
, mlirStringRefCreateFromCString("bar")))) {
149 MlirType fooStruct
= mlirLLVMStructTypeIdentifiedGet(
150 ctx
, mlirStringRefCreateFromCString("foo"));
151 MlirStringRef name
= mlirLLVMStructTypeGetIdentifier(fooStruct
);
152 if (memcmp(name
.data
, "foo", name
.length
))
154 if (!mlirLLVMStructTypeIsOpaque(fooStruct
))
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
))
164 // CHECK: !llvm.struct<"foo", (i32, i64)>
165 mlirTypeDump(fooStruct
);
166 if (mlirLLVMStructTypeIsOpaque(fooStruct
))
168 if (mlirLLVMStructTypeIsPacked(fooStruct
))
170 if (!mlirTypeEqual(mlirLLVMStructTypeIdentifiedGet(
171 ctx
, mlirStringRefCreateFromCString("foo")),
176 MlirType barStruct
= mlirLLVMStructTypeIdentifiedGet(
177 ctx
, mlirStringRefCreateFromCString("bar"));
178 result
= mlirLLVMStructTypeSetBody(barStruct
, 1, &i32
, /*isPacked=*/true);
179 if (!mlirLogicalResultIsSuccess(result
))
182 // CHECK: !llvm.struct<"bar", packed (i32)>
183 mlirTypeDump(barStruct
);
184 if (!mlirLLVMStructTypeIsPacked(barStruct
))
187 // Same body, should succeed.
189 mlirLLVMStructTypeSetBody(fooStruct
, sizeof(i32_i64
) / sizeof(MlirType
),
190 i32_i64
, /*isPacked=*/false);
191 if (!mlirLogicalResultIsSuccess(result
))
194 // Different body, should fail.
195 result
= mlirLLVMStructTypeSetBody(fooStruct
, 1, &i32
, /*isPacked=*/false);
196 if (mlirLogicalResultIsSuccess(result
))
199 // Packed flag differs, should fail.
200 result
= mlirLLVMStructTypeSetBody(barStruct
, 1, &i32
, /*isPacked=*/false);
201 if (mlirLogicalResultIsSuccess(result
))
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.
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))) {
221 MlirType opaque
= mlirLLVMStructTypeOpaqueGet(
222 ctx
, mlirStringRefCreateFromCString("opaque"));
223 // CHECK: !llvm.struct<"opaque", opaque>
224 mlirTypeDump(opaque
);
225 if (!mlirLLVMStructTypeIsOpaque(opaque
))
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");
248 mlirStringAttrGet(ctx
, mlirStringRefCreateFromCString("foo"));
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
));
289 mlirAttributeDump(mlirLLVMDIFlagsAttrGet(ctx
, 0x1));
291 // CHECK: #llvm.di_lexical_block<{{.*}}>
293 mlirLLVMDILexicalBlockAttrGet(ctx
, compile_unit
, file
, 1, 2));
295 // CHECK: #llvm.di_lexical_block_file<{{.*}}>
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
,
309 // CHECK: #llvm.di_derived_type<{{.*}} dwarfAddressSpace = 3{{.*}}>
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
));
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
);
385 fprintf(stderr
, "FAILED: code %d", result
);