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//===----------------------------------------------------------------------===//
9
10// RUN: mlir-capi-llvm-test 2>&1 | FileCheck %s
11
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"
19
20#include <assert.h>
21#include <inttypes.h>
22#include <math.h>
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26
27// CHECK-LABEL: testTypeCreation()
28static void testTypeCreation(MlirContext ctx) {
29 fprintf(stderr, format: "testTypeCreation()\n");
30 MlirType i8 = mlirIntegerTypeGet(ctx, bitwidth: 8);
31 MlirType i32 = mlirIntegerTypeGet(ctx, bitwidth: 32);
32 MlirType i64 = mlirIntegerTypeGet(ctx, bitwidth: 64);
33
34 const char *ptr_text = "!llvm.ptr";
35 MlirType ptr = mlirLLVMPointerTypeGet(ctx, addressSpace: 0);
36 MlirType ptr_ref =
37 mlirTypeParseGet(context: ctx, type: mlirStringRefCreateFromCString(str: ptr_text));
38 // CHECK: !llvm.ptr: 1
39 fprintf(stderr, format: "%s: %d\n", ptr_text, mlirTypeEqual(t1: ptr, t2: ptr_ref));
40
41 const char *ptr_addr_text = "!llvm.ptr<42>";
42 MlirType ptr_addr = mlirLLVMPointerTypeGet(ctx, addressSpace: 42);
43 MlirType ptr_addr_ref =
44 mlirTypeParseGet(context: ctx, type: mlirStringRefCreateFromCString(str: ptr_addr_text));
45 // CHECK: !llvm.ptr<42>: 1
46 fprintf(stderr, format: "%s: %d\n", ptr_addr_text,
47 mlirTypeEqual(t1: ptr_addr, t2: ptr_addr_ref));
48
49 const char *voidt_text = "!llvm.void";
50 MlirType voidt = mlirLLVMVoidTypeGet(ctx);
51 MlirType voidt_ref =
52 mlirTypeParseGet(context: ctx, type: mlirStringRefCreateFromCString(str: voidt_text));
53 // CHECK: !llvm.void: 1
54 fprintf(stderr, format: "%s: %d\n", voidt_text, mlirTypeEqual(t1: voidt, t2: voidt_ref));
55
56 const char *i32_4_text = "!llvm.array<4 x i32>";
57 MlirType i32_4 = mlirLLVMArrayTypeGet(elementType: i32, numElements: 4);
58 MlirType i32_4_ref =
59 mlirTypeParseGet(context: ctx, type: mlirStringRefCreateFromCString(str: i32_4_text));
60 // CHECK: !llvm.array<4 x i32>: 1
61 fprintf(stderr, format: "%s: %d\n", i32_4_text, mlirTypeEqual(t1: i32_4, t2: i32_4_ref));
62
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(resultType: i8, nArgumentTypes: 2, argumentTypes: i32_i64_arr, false);
66 MlirType i8_i32_i64_ref =
67 mlirTypeParseGet(context: ctx, type: mlirStringRefCreateFromCString(str: i8_i32_i64_text));
68 // CHECK: !llvm.func<i8 (i32, i64)>: 1
69 fprintf(stderr, format: "%s: %d\n", i8_i32_i64_text,
70 mlirTypeEqual(t1: i8_i32_i64, t2: i8_i32_i64_ref));
71
72 const char *i32_i64_s_text = "!llvm.struct<(i32, i64)>";
73 MlirType i32_i64_s = mlirLLVMStructTypeLiteralGet(ctx, nFieldTypes: 2, fieldTypes: i32_i64_arr, false);
74 MlirType i32_i64_s_ref =
75 mlirTypeParseGet(context: ctx, type: mlirStringRefCreateFromCString(str: i32_i64_s_text));
76 // CHECK: !llvm.struct<(i32, i64)>: 1
77 fprintf(stderr, format: "%s: %d\n", i32_i64_s_text,
78 mlirTypeEqual(t1: i32_i64_s, t2: i32_i64_s_ref));
79}
80
81// CHECK-LABEL: testStructTypeCreation
82static int testStructTypeCreation(MlirContext ctx) {
83 fprintf(stderr, format: "testStructTypeCreation\n");
84
85 // CHECK: !llvm.struct<()>
86 mlirTypeDump(type: mlirLLVMStructTypeLiteralGet(ctx, /*nFieldTypes=*/0,
87 /*fieldTypes=*/NULL,
88 /*isPacked=*/false));
89
90 MlirType i8 = mlirIntegerTypeGet(ctx, bitwidth: 8);
91 MlirType i32 = mlirIntegerTypeGet(ctx, bitwidth: 32);
92 MlirType i64 = mlirIntegerTypeGet(ctx, bitwidth: 64);
93 MlirType i8_i32_i64[] = {i8, i32, i64};
94 // CHECK: !llvm.struct<(i8, i32, i64)>
95 mlirTypeDump(
96 type: mlirLLVMStructTypeLiteralGet(ctx, nFieldTypes: sizeof(i8_i32_i64) / sizeof(MlirType),
97 fieldTypes: i8_i32_i64, /*isPacked=*/false));
98 // CHECK: !llvm.struct<(i32)>
99 mlirTypeDump(type: mlirLLVMStructTypeLiteralGet(ctx, nFieldTypes: 1, fieldTypes: &i32, /*isPacked=*/false));
100 MlirType i32_i32[] = {i32, i32};
101 // CHECK: !llvm.struct<packed (i32, i32)>
102 mlirTypeDump(type: mlirLLVMStructTypeLiteralGet(
103 ctx, nFieldTypes: sizeof(i32_i32) / sizeof(MlirType), fieldTypes: i32_i32, /*isPacked=*/true));
104
105 MlirType literal =
106 mlirLLVMStructTypeLiteralGet(ctx, nFieldTypes: sizeof(i8_i32_i64) / sizeof(MlirType),
107 fieldTypes: i8_i32_i64, /*isPacked=*/false);
108 // CHECK: num elements: 3
109 // CHECK: i8
110 // CHECK: i32
111 // CHECK: i64
112 fprintf(stderr, format: "num elements: %" PRIdPTR "\n",
113 mlirLLVMStructTypeGetNumElementTypes(type: literal));
114 for (intptr_t i = 0; i < 3; ++i) {
115 mlirTypeDump(type: mlirLLVMStructTypeGetElementType(type: literal, position: i));
116 }
117
118 if (!mlirTypeEqual(
119 t1: mlirLLVMStructTypeLiteralGet(ctx, nFieldTypes: 1, fieldTypes: &i32, /*isPacked=*/false),
120 t2: mlirLLVMStructTypeLiteralGet(ctx, nFieldTypes: 1, fieldTypes: &i32, /*isPacked=*/false))) {
121 return 1;
122 }
123 if (mlirTypeEqual(
124 t1: mlirLLVMStructTypeLiteralGet(ctx, nFieldTypes: 1, fieldTypes: &i32, /*isPacked=*/false),
125 t2: mlirLLVMStructTypeLiteralGet(ctx, nFieldTypes: 1, fieldTypes: &i64, /*isPacked=*/false))) {
126 return 2;
127 }
128
129 // CHECK: !llvm.struct<"foo", opaque>
130 // CHECK: !llvm.struct<"bar", opaque>
131 mlirTypeDump(type: mlirLLVMStructTypeIdentifiedGet(
132 ctx, name: mlirStringRefCreateFromCString(str: "foo")));
133 mlirTypeDump(type: mlirLLVMStructTypeIdentifiedGet(
134 ctx, name: mlirStringRefCreateFromCString(str: "bar")));
135
136 if (!mlirTypeEqual(t1: mlirLLVMStructTypeIdentifiedGet(
137 ctx, name: mlirStringRefCreateFromCString(str: "foo")),
138 t2: mlirLLVMStructTypeIdentifiedGet(
139 ctx, name: mlirStringRefCreateFromCString(str: "foo")))) {
140 return 3;
141 }
142 if (mlirTypeEqual(t1: mlirLLVMStructTypeIdentifiedGet(
143 ctx, name: mlirStringRefCreateFromCString(str: "foo")),
144 t2: mlirLLVMStructTypeIdentifiedGet(
145 ctx, name: mlirStringRefCreateFromCString(str: "bar")))) {
146 return 4;
147 }
148
149 MlirType fooStruct = mlirLLVMStructTypeIdentifiedGet(
150 ctx, name: mlirStringRefCreateFromCString(str: "foo"));
151 MlirStringRef name = mlirLLVMStructTypeGetIdentifier(type: fooStruct);
152 if (memcmp(s1: name.data, s2: "foo", n: name.length))
153 return 5;
154 if (!mlirLLVMStructTypeIsOpaque(type: fooStruct))
155 return 6;
156
157 MlirType i32_i64[] = {i32, i64};
158 MlirLogicalResult result =
159 mlirLLVMStructTypeSetBody(structType: fooStruct, nFieldTypes: sizeof(i32_i64) / sizeof(MlirType),
160 fieldTypes: i32_i64, /*isPacked=*/false);
161 if (!mlirLogicalResultIsSuccess(res: result))
162 return 7;
163
164 // CHECK: !llvm.struct<"foo", (i32, i64)>
165 mlirTypeDump(type: fooStruct);
166 if (mlirLLVMStructTypeIsOpaque(type: fooStruct))
167 return 8;
168 if (mlirLLVMStructTypeIsPacked(type: fooStruct))
169 return 9;
170 if (!mlirTypeEqual(t1: mlirLLVMStructTypeIdentifiedGet(
171 ctx, name: mlirStringRefCreateFromCString(str: "foo")),
172 t2: fooStruct)) {
173 return 10;
174 }
175
176 MlirType barStruct = mlirLLVMStructTypeIdentifiedGet(
177 ctx, name: mlirStringRefCreateFromCString(str: "bar"));
178 result = mlirLLVMStructTypeSetBody(structType: barStruct, nFieldTypes: 1, fieldTypes: &i32, /*isPacked=*/true);
179 if (!mlirLogicalResultIsSuccess(res: result))
180 return 11;
181
182 // CHECK: !llvm.struct<"bar", packed (i32)>
183 mlirTypeDump(type: barStruct);
184 if (!mlirLLVMStructTypeIsPacked(type: barStruct))
185 return 12;
186
187 // Same body, should succeed.
188 result =
189 mlirLLVMStructTypeSetBody(structType: fooStruct, nFieldTypes: sizeof(i32_i64) / sizeof(MlirType),
190 fieldTypes: i32_i64, /*isPacked=*/false);
191 if (!mlirLogicalResultIsSuccess(res: result))
192 return 13;
193
194 // Different body, should fail.
195 result = mlirLLVMStructTypeSetBody(structType: fooStruct, nFieldTypes: 1, fieldTypes: &i32, /*isPacked=*/false);
196 if (mlirLogicalResultIsSuccess(res: result))
197 return 14;
198
199 // Packed flag differs, should fail.
200 result = mlirLLVMStructTypeSetBody(structType: barStruct, nFieldTypes: 1, fieldTypes: &i32, /*isPacked=*/false);
201 if (mlirLogicalResultIsSuccess(res: result))
202 return 15;
203
204 // Should have a different name.
205 // CHECK: !llvm.struct<"foo{{[^"]+}}
206 mlirTypeDump(type: mlirLLVMStructTypeIdentifiedNewGet(
207 ctx, name: mlirStringRefCreateFromCString(str: "foo"), /*nFieldTypes=*/0,
208 /*fieldTypes=*/NULL, /*isPacked=*/false));
209
210 // Two freshly created "new" types must differ.
211 if (mlirTypeEqual(
212 t1: mlirLLVMStructTypeIdentifiedNewGet(
213 ctx, name: mlirStringRefCreateFromCString(str: "foo"), /*nFieldTypes=*/0,
214 /*fieldTypes=*/NULL, /*isPacked=*/false),
215 t2: mlirLLVMStructTypeIdentifiedNewGet(
216 ctx, name: mlirStringRefCreateFromCString(str: "foo"), /*nFieldTypes=*/0,
217 /*fieldTypes=*/NULL, /*isPacked=*/false))) {
218 return 16;
219 }
220
221 MlirType opaque = mlirLLVMStructTypeOpaqueGet(
222 ctx, name: mlirStringRefCreateFromCString(str: "opaque"));
223 // CHECK: !llvm.struct<"opaque", opaque>
224 mlirTypeDump(type: opaque);
225 if (!mlirLLVMStructTypeIsOpaque(type: opaque))
226 return 17;
227
228 return 0;
229}
230
231// CHECK-LABEL: testLLVMAttributes
232static void testLLVMAttributes(MlirContext ctx) {
233 fprintf(stderr, format: "testLLVMAttributes\n");
234
235 // CHECK: #llvm.linkage<internal>
236 mlirAttributeDump(attr: mlirLLVMLinkageAttrGet(ctx, linkage: MlirLLVMLinkageInternal));
237 // CHECK: #llvm.cconv<ccc>
238 mlirAttributeDump(attr: mlirLLVMCConvAttrGet(ctx, cconv: MlirLLVMCConvC));
239 // CHECK: #llvm<comdat any>
240 mlirAttributeDump(attr: mlirLLVMComdatAttrGet(ctx, comdat: MlirLLVMComdatAny));
241}
242
243// CHECK-LABEL: testDebugInfoAttributes
244static void testDebugInfoAttributes(MlirContext ctx) {
245 fprintf(stderr, format: "testDebugInfoAttributes\n");
246
247 MlirAttribute foo =
248 mlirStringAttrGet(ctx, str: mlirStringRefCreateFromCString(str: "foo"));
249 MlirAttribute bar =
250 mlirStringAttrGet(ctx, str: mlirStringRefCreateFromCString(str: "bar"));
251
252 MlirAttribute none = mlirUnitAttrGet(ctx);
253 MlirAttribute id = mlirDisctinctAttrCreate(referencedAttr: none);
254 MlirAttribute recId0 = mlirDisctinctAttrCreate(referencedAttr: none);
255 MlirAttribute recId1 = mlirDisctinctAttrCreate(referencedAttr: none);
256
257 // CHECK: #llvm.di_null_type
258 mlirAttributeDump(attr: mlirLLVMDINullTypeAttrGet(ctx));
259
260 // CHECK: #llvm.di_basic_type<name = "foo", sizeInBits =
261 // CHECK-SAME: 64, encoding = DW_ATE_signed>
262 MlirAttribute di_type =
263 mlirLLVMDIBasicTypeAttrGet(ctx, tag: 0, name: foo, sizeInBits: 64, encoding: MlirLLVMTypeEncodingSigned);
264 mlirAttributeDump(attr: di_type);
265
266 MlirAttribute file = mlirLLVMDIFileAttrGet(ctx, name: foo, directory: bar);
267
268 // CHECK: #llvm.di_file<"foo" in "bar">
269 mlirAttributeDump(attr: file);
270
271 MlirAttribute compile_unit = mlirLLVMDICompileUnitAttrGet(
272 ctx, id, sourceLanguage: LLVMDWARFSourceLanguageC99, file, producer: foo, false,
273 emissionKind: MlirLLVMDIEmissionKindFull, nameTableKind: MlirLLVMDINameTableKindDefault);
274
275 // CHECK: #llvm.di_compile_unit<{{.*}}>
276 mlirAttributeDump(attr: compile_unit);
277
278 MlirAttribute di_module = mlirLLVMDIModuleAttrGet(
279 ctx, file, scope: compile_unit, name: foo,
280 configMacros: mlirStringAttrGet(ctx, str: mlirStringRefCreateFromCString(str: "")), includePath: bar, apinotes: foo, line: 1,
281 isDecl: 0);
282 // CHECK: #llvm.di_module<{{.*}}>
283 mlirAttributeDump(attr: di_module);
284
285 // CHECK: #llvm.di_compile_unit<{{.*}}>
286 mlirAttributeDump(attr: mlirLLVMDIModuleAttrGetScope(diModule: di_module));
287
288 // CHECK: 1 : i32
289 mlirAttributeDump(attr: mlirLLVMDIFlagsAttrGet(ctx, value: 0x1));
290
291 // CHECK: #llvm.di_lexical_block<{{.*}}>
292 mlirAttributeDump(
293 attr: mlirLLVMDILexicalBlockAttrGet(ctx, scope: compile_unit, file, line: 1, column: 2));
294
295 // CHECK: #llvm.di_lexical_block_file<{{.*}}>
296 mlirAttributeDump(
297 attr: mlirLLVMDILexicalBlockFileAttrGet(ctx, scope: compile_unit, file, discriminator: 3));
298
299 // CHECK: #llvm.di_local_variable<{{.*}}>
300 MlirAttribute local_var = mlirLLVMDILocalVariableAttrGet(
301 ctx, scope: compile_unit, name: foo, diFile: file, line: 1, arg: 0, alignInBits: 8, diType: di_type, flags: 0);
302 mlirAttributeDump(attr: local_var);
303 // CHECK: #llvm.di_derived_type<{{.*}}>
304 // CHECK-NOT: dwarfAddressSpace
305 mlirAttributeDump(attr: mlirLLVMDIDerivedTypeAttrGet(
306 ctx, tag: 0, name: bar, baseType: di_type, sizeInBits: 64, alignInBits: 8, offsetInBits: 0, MLIR_CAPI_DWARF_ADDRESS_SPACE_NULL,
307 extraData: di_type));
308
309 // CHECK: #llvm.di_derived_type<{{.*}} dwarfAddressSpace = 3{{.*}}>
310 mlirAttributeDump(
311 attr: mlirLLVMDIDerivedTypeAttrGet(ctx, tag: 0, name: bar, baseType: di_type, sizeInBits: 64, alignInBits: 8, offsetInBits: 0, dwarfAddressSpace: 3, extraData: di_type));
312
313 MlirAttribute subroutine_type =
314 mlirLLVMDISubroutineTypeAttrGet(ctx, callingConvention: 0x0, nTypes: 1, types: &di_type);
315
316 // CHECK: #llvm.di_subroutine_type<{{.*}}>
317 mlirAttributeDump(attr: subroutine_type);
318
319 MlirAttribute di_subprogram_self_rec =
320 mlirLLVMDISubprogramAttrGetRecSelf(recId: recId0);
321 MlirAttribute di_imported_entity = mlirLLVMDIImportedEntityAttrGet(
322 ctx, tag: 0, scope: di_subprogram_self_rec, entity: di_module, file, line: 1, name: foo, nElements: 1, elements: &local_var);
323
324 mlirAttributeDump(attr: di_imported_entity);
325 // CHECK: #llvm.di_imported_entity<{{.*}}>
326
327 MlirAttribute di_annotation = mlirLLVMDIAnnotationAttrGet(
328 ctx, name: mlirStringAttrGet(ctx, str: mlirStringRefCreateFromCString(str: "foo")),
329 value: mlirStringAttrGet(ctx, str: mlirStringRefCreateFromCString(str: "bar")));
330
331 mlirAttributeDump(attr: di_annotation);
332 // CHECK: #llvm.di_annotation<{{.*}}>
333
334 MlirAttribute di_subprogram = mlirLLVMDISubprogramAttrGet(
335 ctx, recId: recId0, false, id, compileUnit: compile_unit, scope: compile_unit, name: foo, linkageName: bar, file, line: 1, scopeLine: 2,
336 subprogramFlags: 0, type: subroutine_type, nRetainedNodes: 1, retainedNodes: &di_imported_entity, nAnnotations: 1, annotations: &di_annotation);
337 // CHECK: #llvm.di_subprogram<{{.*}}>
338 mlirAttributeDump(attr: di_subprogram);
339
340 // CHECK: #llvm.di_compile_unit<{{.*}}>
341 mlirAttributeDump(attr: mlirLLVMDISubprogramAttrGetScope(diSubprogram: di_subprogram));
342
343 // CHECK: #llvm.di_file<{{.*}}>
344 mlirAttributeDump(attr: mlirLLVMDISubprogramAttrGetFile(diSubprogram: di_subprogram));
345
346 // CHECK: #llvm.di_subroutine_type<{{.*}}>
347 mlirAttributeDump(attr: mlirLLVMDISubprogramAttrGetType(diSubprogram: di_subprogram));
348
349 MlirAttribute expression_elem =
350 mlirLLVMDIExpressionElemAttrGet(ctx, opcode: 1, nArguments: 1, arguments: &(uint64_t){1});
351
352 // CHECK: #llvm<di_expression_elem(1)>
353 mlirAttributeDump(attr: expression_elem);
354
355 MlirAttribute expression =
356 mlirLLVMDIExpressionAttrGet(ctx, nOperations: 1, operations: &expression_elem);
357 // CHECK: #llvm.di_expression<[(1)]>
358 mlirAttributeDump(attr: expression);
359
360 MlirAttribute string_type =
361 mlirLLVMDIStringTypeAttrGet(ctx, tag: 0x0, name: foo, sizeInBits: 16, alignInBits: 0, stringLength: local_var, stringLengthExp: expression,
362 stringLocationExp: expression, encoding: MlirLLVMTypeEncodingSigned);
363 // CHECK: #llvm.di_string_type<{{.*}}>
364 mlirAttributeDump(attr: string_type);
365
366 // CHECK: #llvm.di_composite_type<recId = {{.*}}, isRecSelf = true>
367 mlirAttributeDump(attr: mlirLLVMDICompositeTypeAttrGetRecSelf(recId: recId1));
368
369 // CHECK: #llvm.di_composite_type<{{.*}}>
370 mlirAttributeDump(attr: mlirLLVMDICompositeTypeAttrGet(
371 ctx, recId: recId1, false, tag: 0, name: foo, file, line: 1, scope: compile_unit, baseType: di_type, flags: 0, sizeInBits: 64, alignInBits: 8, nElements: 1,
372 elements: &di_type, dataLocation: expression, rank: expression, allocated: expression, associated: expression));
373}
374
375int main(void) {
376 MlirContext ctx = mlirContextCreate();
377 mlirDialectHandleRegisterDialect(mlirGetDialectHandle__llvm__(), ctx);
378 mlirContextGetOrLoadDialect(context: ctx, name: mlirStringRefCreateFromCString(str: "llvm"));
379 testTypeCreation(ctx);
380 int result = testStructTypeCreation(ctx);
381 testLLVMAttributes(ctx);
382 testDebugInfoAttributes(ctx);
383 mlirContextDestroy(context: ctx);
384 if (result)
385 fprintf(stderr, format: "FAILED: code %d", result);
386 return result;
387}
388

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of mlir/test/CAPI/llvm.c