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 MlirAttribute id = mlirDisctinctAttrCreate(referencedAttr: foo);
252
253 // CHECK: #llvm.di_null_type
254 mlirAttributeDump(attr: mlirLLVMDINullTypeAttrGet(ctx));
255
256 // CHECK: #llvm.di_basic_type<tag = DW_TAG_null, name = "foo", sizeInBits =
257 // CHECK-SAME: 64, encoding = DW_ATE_signed>
258 MlirAttribute di_type =
259 mlirLLVMDIBasicTypeAttrGet(ctx, tag: 0, name: foo, sizeInBits: 64, encoding: MlirLLVMTypeEncodingSigned);
260 mlirAttributeDump(attr: di_type);
261
262 MlirAttribute file = mlirLLVMDIFileAttrGet(ctx, name: foo, directory: bar);
263
264 // CHECK: #llvm.di_file<"foo" in "bar">
265 mlirAttributeDump(attr: file);
266
267 MlirAttribute compile_unit = mlirLLVMDICompileUnitAttrGet(
268 ctx, id, sourceLanguage: LLVMDWARFSourceLanguageC99, file, producer: foo, false,
269 emissionKind: MlirLLVMDIEmissionKindFull, nameTableKind: MlirLLVMDINameTableKindDefault);
270
271 // CHECK: #llvm.di_compile_unit<{{.*}}>
272 mlirAttributeDump(attr: compile_unit);
273
274 MlirAttribute di_module = mlirLLVMDIModuleAttrGet(
275 ctx, file, scope: compile_unit, name: foo,
276 configMacros: mlirStringAttrGet(ctx, str: mlirStringRefCreateFromCString(str: "")), includePath: bar, apinotes: foo, line: 1,
277 isDecl: 0);
278 // CHECK: #llvm.di_module<{{.*}}>
279 mlirAttributeDump(attr: di_module);
280
281 // CHECK: #llvm.di_compile_unit<{{.*}}>
282 mlirAttributeDump(attr: mlirLLVMDIModuleAttrGetScope(diModule: di_module));
283
284 // CHECK: 1 : i32
285 mlirAttributeDump(attr: mlirLLVMDIFlagsAttrGet(ctx, value: 0x1));
286
287 // CHECK: #llvm.di_lexical_block<{{.*}}>
288 mlirAttributeDump(
289 attr: mlirLLVMDILexicalBlockAttrGet(ctx, scope: compile_unit, file, line: 1, column: 2));
290
291 // CHECK: #llvm.di_lexical_block_file<{{.*}}>
292 mlirAttributeDump(
293 attr: mlirLLVMDILexicalBlockFileAttrGet(ctx, scope: compile_unit, file, discriminator: 3));
294
295 // CHECK: #llvm.di_local_variable<{{.*}}>
296 mlirAttributeDump(attr: mlirLLVMDILocalVariableAttrGet(ctx, scope: compile_unit, name: foo, diFile: file,
297 line: 1, arg: 0, alignInBits: 8, diType: di_type));
298 // CHECK: #llvm.di_derived_type<{{.*}}>
299 mlirAttributeDump(
300 attr: mlirLLVMDIDerivedTypeAttrGet(ctx, tag: 0, name: bar, baseType: di_type, sizeInBits: 64, alignInBits: 8, offsetInBits: 0, extraData: di_type));
301
302 // CHECK: #llvm.di_composite_type<{{.*}}>
303 mlirAttributeDump(attr: mlirLLVMDICompositeTypeAttrGet(
304 ctx, tag: 0, recId: id, name: foo, file, line: 1, scope: compile_unit, baseType: di_type, flags: 0, sizeInBits: 64, alignInBits: 8, nElements: 1, elements: &di_type));
305
306 MlirAttribute subroutine_type =
307 mlirLLVMDISubroutineTypeAttrGet(ctx, callingConvention: 0x0, nTypes: 1, types: &di_type);
308
309 // CHECK: #llvm.di_subroutine_type<{{.*}}>
310 mlirAttributeDump(attr: subroutine_type);
311
312 MlirAttribute di_subprogram =
313 mlirLLVMDISubprogramAttrGet(ctx, id, compileUnit: compile_unit, scope: compile_unit, name: foo, linkageName: bar,
314 file, line: 1, scopeLine: 2, subprogramFlags: 0, type: subroutine_type);
315 // CHECK: #llvm.di_subprogram<{{.*}}>
316 mlirAttributeDump(attr: di_subprogram);
317
318 // CHECK: #llvm.di_compile_unit<{{.*}}>
319 mlirAttributeDump(attr: mlirLLVMDISubprogramAttrGetScope(diSubprogram: di_subprogram));
320
321 // CHECK: #llvm.di_file<{{.*}}>
322 mlirAttributeDump(attr: mlirLLVMDISubprogramAttrGetFile(diSubprogram: di_subprogram));
323
324 // CHECK: #llvm.di_subroutine_type<{{.*}}>
325 mlirAttributeDump(attr: mlirLLVMDISubprogramAttrGetType(diSubprogram: di_subprogram));
326
327 MlirAttribute expression_elem =
328 mlirLLVMDIExpressionElemAttrGet(ctx, opcode: 1, nArguments: 1, arguments: &(uint64_t){1});
329
330 // CHECK: #llvm<di_expression_elem(1)>
331 mlirAttributeDump(attr: expression_elem);
332
333 // CHECK: #llvm.di_expression<[(1)]>
334 mlirAttributeDump(attr: mlirLLVMDIExpressionAttrGet(ctx, nOperations: 1, operations: &expression_elem));
335}
336
337int main(void) {
338 MlirContext ctx = mlirContextCreate();
339 mlirDialectHandleRegisterDialect(mlirGetDialectHandle__llvm__(), ctx);
340 mlirContextGetOrLoadDialect(context: ctx, name: mlirStringRefCreateFromCString(str: "llvm"));
341 testTypeCreation(ctx);
342 int result = testStructTypeCreation(ctx);
343 testLLVMAttributes(ctx);
344 testDebugInfoAttributes(ctx);
345 mlirContextDestroy(context: ctx);
346 if (result)
347 fprintf(stderr, format: "FAILED: code %d", result);
348 return result;
349}
350

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