llvm-project
2488 строк · 96.4 Кб
1//===- ir.c - Simple test of C 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-ir-test 2>&1 | FileCheck %s
11*/
12
13#include "mlir-c/IR.h"
14#include "mlir-c/AffineExpr.h"
15#include "mlir-c/AffineMap.h"
16#include "mlir-c/BuiltinAttributes.h"
17#include "mlir-c/BuiltinTypes.h"
18#include "mlir-c/Diagnostics.h"
19#include "mlir-c/Dialect/Func.h"
20#include "mlir-c/IntegerSet.h"
21#include "mlir-c/RegisterEverything.h"
22#include "mlir-c/Support.h"
23
24#include <assert.h>
25#include <inttypes.h>
26#include <math.h>
27#include <stdio.h>
28#include <stdlib.h>
29#include <string.h>
30
31static void registerAllUpstreamDialects(MlirContext ctx) {
32MlirDialectRegistry registry = mlirDialectRegistryCreate();
33mlirRegisterAllDialects(registry);
34mlirContextAppendDialectRegistry(ctx, registry);
35mlirDialectRegistryDestroy(registry);
36}
37
38struct ResourceDeleteUserData {
39const char *name;
40};
41static struct ResourceDeleteUserData resourceI64BlobUserData = {
42"resource_i64_blob"};
43static void reportResourceDelete(void *userData, const void *data, size_t size,
44size_t align) {
45fprintf(stderr, "reportResourceDelete: %s\n",
46((struct ResourceDeleteUserData *)userData)->name);
47}
48
49void populateLoopBody(MlirContext ctx, MlirBlock loopBody,
50MlirLocation location, MlirBlock funcBody) {
51MlirValue iv = mlirBlockGetArgument(loopBody, 0);
52MlirValue funcArg0 = mlirBlockGetArgument(funcBody, 0);
53MlirValue funcArg1 = mlirBlockGetArgument(funcBody, 1);
54MlirType f32Type =
55mlirTypeParseGet(ctx, mlirStringRefCreateFromCString("f32"));
56
57MlirOperationState loadLHSState = mlirOperationStateGet(
58mlirStringRefCreateFromCString("memref.load"), location);
59MlirValue loadLHSOperands[] = {funcArg0, iv};
60mlirOperationStateAddOperands(&loadLHSState, 2, loadLHSOperands);
61mlirOperationStateAddResults(&loadLHSState, 1, &f32Type);
62MlirOperation loadLHS = mlirOperationCreate(&loadLHSState);
63mlirBlockAppendOwnedOperation(loopBody, loadLHS);
64
65MlirOperationState loadRHSState = mlirOperationStateGet(
66mlirStringRefCreateFromCString("memref.load"), location);
67MlirValue loadRHSOperands[] = {funcArg1, iv};
68mlirOperationStateAddOperands(&loadRHSState, 2, loadRHSOperands);
69mlirOperationStateAddResults(&loadRHSState, 1, &f32Type);
70MlirOperation loadRHS = mlirOperationCreate(&loadRHSState);
71mlirBlockAppendOwnedOperation(loopBody, loadRHS);
72
73MlirOperationState addState = mlirOperationStateGet(
74mlirStringRefCreateFromCString("arith.addf"), location);
75MlirValue addOperands[] = {mlirOperationGetResult(loadLHS, 0),
76mlirOperationGetResult(loadRHS, 0)};
77mlirOperationStateAddOperands(&addState, 2, addOperands);
78mlirOperationStateAddResults(&addState, 1, &f32Type);
79MlirOperation add = mlirOperationCreate(&addState);
80mlirBlockAppendOwnedOperation(loopBody, add);
81
82MlirOperationState storeState = mlirOperationStateGet(
83mlirStringRefCreateFromCString("memref.store"), location);
84MlirValue storeOperands[] = {mlirOperationGetResult(add, 0), funcArg0, iv};
85mlirOperationStateAddOperands(&storeState, 3, storeOperands);
86MlirOperation store = mlirOperationCreate(&storeState);
87mlirBlockAppendOwnedOperation(loopBody, store);
88
89MlirOperationState yieldState = mlirOperationStateGet(
90mlirStringRefCreateFromCString("scf.yield"), location);
91MlirOperation yield = mlirOperationCreate(&yieldState);
92mlirBlockAppendOwnedOperation(loopBody, yield);
93}
94
95MlirModule makeAndDumpAdd(MlirContext ctx, MlirLocation location) {
96MlirModule moduleOp = mlirModuleCreateEmpty(location);
97MlirBlock moduleBody = mlirModuleGetBody(moduleOp);
98
99MlirType memrefType =
100mlirTypeParseGet(ctx, mlirStringRefCreateFromCString("memref<?xf32>"));
101MlirType funcBodyArgTypes[] = {memrefType, memrefType};
102MlirLocation funcBodyArgLocs[] = {location, location};
103MlirRegion funcBodyRegion = mlirRegionCreate();
104MlirBlock funcBody =
105mlirBlockCreate(sizeof(funcBodyArgTypes) / sizeof(MlirType),
106funcBodyArgTypes, funcBodyArgLocs);
107mlirRegionAppendOwnedBlock(funcBodyRegion, funcBody);
108
109MlirAttribute funcTypeAttr = mlirAttributeParseGet(
110ctx,
111mlirStringRefCreateFromCString("(memref<?xf32>, memref<?xf32>) -> ()"));
112MlirAttribute funcNameAttr =
113mlirAttributeParseGet(ctx, mlirStringRefCreateFromCString("\"add\""));
114MlirNamedAttribute funcAttrs[] = {
115mlirNamedAttributeGet(
116mlirIdentifierGet(ctx,
117mlirStringRefCreateFromCString("function_type")),
118funcTypeAttr),
119mlirNamedAttributeGet(
120mlirIdentifierGet(ctx, mlirStringRefCreateFromCString("sym_name")),
121funcNameAttr)};
122MlirOperationState funcState = mlirOperationStateGet(
123mlirStringRefCreateFromCString("func.func"), location);
124mlirOperationStateAddAttributes(&funcState, 2, funcAttrs);
125mlirOperationStateAddOwnedRegions(&funcState, 1, &funcBodyRegion);
126MlirOperation func = mlirOperationCreate(&funcState);
127mlirBlockInsertOwnedOperation(moduleBody, 0, func);
128
129MlirType indexType =
130mlirTypeParseGet(ctx, mlirStringRefCreateFromCString("index"));
131MlirAttribute indexZeroLiteral =
132mlirAttributeParseGet(ctx, mlirStringRefCreateFromCString("0 : index"));
133MlirNamedAttribute indexZeroValueAttr = mlirNamedAttributeGet(
134mlirIdentifierGet(ctx, mlirStringRefCreateFromCString("value")),
135indexZeroLiteral);
136MlirOperationState constZeroState = mlirOperationStateGet(
137mlirStringRefCreateFromCString("arith.constant"), location);
138mlirOperationStateAddResults(&constZeroState, 1, &indexType);
139mlirOperationStateAddAttributes(&constZeroState, 1, &indexZeroValueAttr);
140MlirOperation constZero = mlirOperationCreate(&constZeroState);
141mlirBlockAppendOwnedOperation(funcBody, constZero);
142
143MlirValue funcArg0 = mlirBlockGetArgument(funcBody, 0);
144MlirValue constZeroValue = mlirOperationGetResult(constZero, 0);
145MlirValue dimOperands[] = {funcArg0, constZeroValue};
146MlirOperationState dimState = mlirOperationStateGet(
147mlirStringRefCreateFromCString("memref.dim"), location);
148mlirOperationStateAddOperands(&dimState, 2, dimOperands);
149mlirOperationStateAddResults(&dimState, 1, &indexType);
150MlirOperation dim = mlirOperationCreate(&dimState);
151mlirBlockAppendOwnedOperation(funcBody, dim);
152
153MlirRegion loopBodyRegion = mlirRegionCreate();
154MlirBlock loopBody = mlirBlockCreate(0, NULL, NULL);
155mlirBlockAddArgument(loopBody, indexType, location);
156mlirRegionAppendOwnedBlock(loopBodyRegion, loopBody);
157
158MlirAttribute indexOneLiteral =
159mlirAttributeParseGet(ctx, mlirStringRefCreateFromCString("1 : index"));
160MlirNamedAttribute indexOneValueAttr = mlirNamedAttributeGet(
161mlirIdentifierGet(ctx, mlirStringRefCreateFromCString("value")),
162indexOneLiteral);
163MlirOperationState constOneState = mlirOperationStateGet(
164mlirStringRefCreateFromCString("arith.constant"), location);
165mlirOperationStateAddResults(&constOneState, 1, &indexType);
166mlirOperationStateAddAttributes(&constOneState, 1, &indexOneValueAttr);
167MlirOperation constOne = mlirOperationCreate(&constOneState);
168mlirBlockAppendOwnedOperation(funcBody, constOne);
169
170MlirValue dimValue = mlirOperationGetResult(dim, 0);
171MlirValue constOneValue = mlirOperationGetResult(constOne, 0);
172MlirValue loopOperands[] = {constZeroValue, dimValue, constOneValue};
173MlirOperationState loopState = mlirOperationStateGet(
174mlirStringRefCreateFromCString("scf.for"), location);
175mlirOperationStateAddOperands(&loopState, 3, loopOperands);
176mlirOperationStateAddOwnedRegions(&loopState, 1, &loopBodyRegion);
177MlirOperation loop = mlirOperationCreate(&loopState);
178mlirBlockAppendOwnedOperation(funcBody, loop);
179
180populateLoopBody(ctx, loopBody, location, funcBody);
181
182MlirOperationState retState = mlirOperationStateGet(
183mlirStringRefCreateFromCString("func.return"), location);
184MlirOperation ret = mlirOperationCreate(&retState);
185mlirBlockAppendOwnedOperation(funcBody, ret);
186
187MlirOperation module = mlirModuleGetOperation(moduleOp);
188mlirOperationDump(module);
189// clang-format off
190// CHECK: module {
191// CHECK: func @add(%[[ARG0:.*]]: memref<?xf32>, %[[ARG1:.*]]: memref<?xf32>) {
192// CHECK: %[[C0:.*]] = arith.constant 0 : index
193// CHECK: %[[DIM:.*]] = memref.dim %[[ARG0]], %[[C0]] : memref<?xf32>
194// CHECK: %[[C1:.*]] = arith.constant 1 : index
195// CHECK: scf.for %[[I:.*]] = %[[C0]] to %[[DIM]] step %[[C1]] {
196// CHECK: %[[LHS:.*]] = memref.load %[[ARG0]][%[[I]]] : memref<?xf32>
197// CHECK: %[[RHS:.*]] = memref.load %[[ARG1]][%[[I]]] : memref<?xf32>
198// CHECK: %[[SUM:.*]] = arith.addf %[[LHS]], %[[RHS]] : f32
199// CHECK: memref.store %[[SUM]], %[[ARG0]][%[[I]]] : memref<?xf32>
200// CHECK: }
201// CHECK: return
202// CHECK: }
203// CHECK: }
204// clang-format on
205
206return moduleOp;
207}
208
209struct OpListNode {
210MlirOperation op;
211struct OpListNode *next;
212};
213typedef struct OpListNode OpListNode;
214
215struct ModuleStats {
216unsigned numOperations;
217unsigned numAttributes;
218unsigned numBlocks;
219unsigned numRegions;
220unsigned numValues;
221unsigned numBlockArguments;
222unsigned numOpResults;
223};
224typedef struct ModuleStats ModuleStats;
225
226int collectStatsSingle(OpListNode *head, ModuleStats *stats) {
227MlirOperation operation = head->op;
228stats->numOperations += 1;
229stats->numValues += mlirOperationGetNumResults(operation);
230stats->numAttributes += mlirOperationGetNumAttributes(operation);
231
232unsigned numRegions = mlirOperationGetNumRegions(operation);
233
234stats->numRegions += numRegions;
235
236intptr_t numResults = mlirOperationGetNumResults(operation);
237for (intptr_t i = 0; i < numResults; ++i) {
238MlirValue result = mlirOperationGetResult(operation, i);
239if (!mlirValueIsAOpResult(result))
240return 1;
241if (mlirValueIsABlockArgument(result))
242return 2;
243if (!mlirOperationEqual(operation, mlirOpResultGetOwner(result)))
244return 3;
245if (i != mlirOpResultGetResultNumber(result))
246return 4;
247++stats->numOpResults;
248}
249
250MlirRegion region = mlirOperationGetFirstRegion(operation);
251while (!mlirRegionIsNull(region)) {
252for (MlirBlock block = mlirRegionGetFirstBlock(region);
253!mlirBlockIsNull(block); block = mlirBlockGetNextInRegion(block)) {
254++stats->numBlocks;
255intptr_t numArgs = mlirBlockGetNumArguments(block);
256stats->numValues += numArgs;
257for (intptr_t j = 0; j < numArgs; ++j) {
258MlirValue arg = mlirBlockGetArgument(block, j);
259if (!mlirValueIsABlockArgument(arg))
260return 5;
261if (mlirValueIsAOpResult(arg))
262return 6;
263if (!mlirBlockEqual(block, mlirBlockArgumentGetOwner(arg)))
264return 7;
265if (j != mlirBlockArgumentGetArgNumber(arg))
266return 8;
267++stats->numBlockArguments;
268}
269
270for (MlirOperation child = mlirBlockGetFirstOperation(block);
271!mlirOperationIsNull(child);
272child = mlirOperationGetNextInBlock(child)) {
273OpListNode *node = malloc(sizeof(OpListNode));
274node->op = child;
275node->next = head->next;
276head->next = node;
277}
278}
279region = mlirRegionGetNextInOperation(region);
280}
281return 0;
282}
283
284int collectStats(MlirOperation operation) {
285OpListNode *head = malloc(sizeof(OpListNode));
286head->op = operation;
287head->next = NULL;
288
289ModuleStats stats;
290stats.numOperations = 0;
291stats.numAttributes = 0;
292stats.numBlocks = 0;
293stats.numRegions = 0;
294stats.numValues = 0;
295stats.numBlockArguments = 0;
296stats.numOpResults = 0;
297
298do {
299int retval = collectStatsSingle(head, &stats);
300if (retval) {
301free(head);
302return retval;
303}
304OpListNode *next = head->next;
305free(head);
306head = next;
307} while (head);
308
309if (stats.numValues != stats.numBlockArguments + stats.numOpResults)
310return 100;
311
312fprintf(stderr, "@stats\n");
313fprintf(stderr, "Number of operations: %u\n", stats.numOperations);
314fprintf(stderr, "Number of attributes: %u\n", stats.numAttributes);
315fprintf(stderr, "Number of blocks: %u\n", stats.numBlocks);
316fprintf(stderr, "Number of regions: %u\n", stats.numRegions);
317fprintf(stderr, "Number of values: %u\n", stats.numValues);
318fprintf(stderr, "Number of block arguments: %u\n", stats.numBlockArguments);
319fprintf(stderr, "Number of op results: %u\n", stats.numOpResults);
320// clang-format off
321// CHECK-LABEL: @stats
322// CHECK: Number of operations: 12
323// CHECK: Number of attributes: 5
324// CHECK: Number of blocks: 3
325// CHECK: Number of regions: 3
326// CHECK: Number of values: 9
327// CHECK: Number of block arguments: 3
328// CHECK: Number of op results: 6
329// clang-format on
330return 0;
331}
332
333static void printToStderr(MlirStringRef str, void *userData) {
334(void)userData;
335fwrite(str.data, 1, str.length, stderr);
336}
337
338static void printFirstOfEach(MlirContext ctx, MlirOperation operation) {
339// Assuming we are given a module, go to the first operation of the first
340// function.
341MlirRegion region = mlirOperationGetRegion(operation, 0);
342MlirBlock block = mlirRegionGetFirstBlock(region);
343MlirOperation function = mlirBlockGetFirstOperation(block);
344region = mlirOperationGetRegion(function, 0);
345MlirOperation parentOperation = function;
346block = mlirRegionGetFirstBlock(region);
347operation = mlirBlockGetFirstOperation(block);
348assert(mlirModuleIsNull(mlirModuleFromOperation(operation)));
349
350// Verify that parent operation and block report correctly.
351// CHECK: Parent operation eq: 1
352fprintf(stderr, "Parent operation eq: %d\n",
353mlirOperationEqual(mlirOperationGetParentOperation(operation),
354parentOperation));
355// CHECK: Block eq: 1
356fprintf(stderr, "Block eq: %d\n",
357mlirBlockEqual(mlirOperationGetBlock(operation), block));
358// CHECK: Block parent operation eq: 1
359fprintf(
360stderr, "Block parent operation eq: %d\n",
361mlirOperationEqual(mlirBlockGetParentOperation(block), parentOperation));
362// CHECK: Block parent region eq: 1
363fprintf(stderr, "Block parent region eq: %d\n",
364mlirRegionEqual(mlirBlockGetParentRegion(block), region));
365
366// In the module we created, the first operation of the first function is
367// an "memref.dim", which has an attribute and a single result that we can
368// use to test the printing mechanism.
369mlirBlockPrint(block, printToStderr, NULL);
370fprintf(stderr, "\n");
371fprintf(stderr, "First operation: ");
372mlirOperationPrint(operation, printToStderr, NULL);
373fprintf(stderr, "\n");
374// clang-format off
375// CHECK: %[[C0:.*]] = arith.constant 0 : index
376// CHECK: %[[DIM:.*]] = memref.dim %{{.*}}, %[[C0]] : memref<?xf32>
377// CHECK: %[[C1:.*]] = arith.constant 1 : index
378// CHECK: scf.for %[[I:.*]] = %[[C0]] to %[[DIM]] step %[[C1]] {
379// CHECK: %[[LHS:.*]] = memref.load %{{.*}}[%[[I]]] : memref<?xf32>
380// CHECK: %[[RHS:.*]] = memref.load %{{.*}}[%[[I]]] : memref<?xf32>
381// CHECK: %[[SUM:.*]] = arith.addf %[[LHS]], %[[RHS]] : f32
382// CHECK: memref.store %[[SUM]], %{{.*}}[%[[I]]] : memref<?xf32>
383// CHECK: }
384// CHECK: return
385// CHECK: First operation: {{.*}} = arith.constant 0 : index
386// clang-format on
387
388// Get the operation name and print it.
389MlirIdentifier ident = mlirOperationGetName(operation);
390MlirStringRef identStr = mlirIdentifierStr(ident);
391fprintf(stderr, "Operation name: '");
392for (size_t i = 0; i < identStr.length; ++i)
393fputc(identStr.data[i], stderr);
394fprintf(stderr, "'\n");
395// CHECK: Operation name: 'arith.constant'
396
397// Get the identifier again and verify equal.
398MlirIdentifier identAgain = mlirIdentifierGet(ctx, identStr);
399fprintf(stderr, "Identifier equal: %d\n",
400mlirIdentifierEqual(ident, identAgain));
401// CHECK: Identifier equal: 1
402
403// Get the block terminator and print it.
404MlirOperation terminator = mlirBlockGetTerminator(block);
405fprintf(stderr, "Terminator: ");
406mlirOperationPrint(terminator, printToStderr, NULL);
407fprintf(stderr, "\n");
408// CHECK: Terminator: func.return
409
410// Get the attribute by name.
411bool hasValueAttr = mlirOperationHasInherentAttributeByName(
412operation, mlirStringRefCreateFromCString("value"));
413if (hasValueAttr)
414// CHECK: Has attr "value"
415fprintf(stderr, "Has attr \"value\"");
416
417MlirAttribute valueAttr0 = mlirOperationGetInherentAttributeByName(
418operation, mlirStringRefCreateFromCString("value"));
419fprintf(stderr, "Get attr \"value\": ");
420mlirAttributePrint(valueAttr0, printToStderr, NULL);
421fprintf(stderr, "\n");
422// CHECK: Get attr "value": 0 : index
423
424// Get a non-existing attribute and assert that it is null (sanity).
425fprintf(stderr, "does_not_exist is null: %d\n",
426mlirAttributeIsNull(mlirOperationGetDiscardableAttributeByName(
427operation, mlirStringRefCreateFromCString("does_not_exist"))));
428// CHECK: does_not_exist is null: 1
429
430// Get result 0 and its type.
431MlirValue value = mlirOperationGetResult(operation, 0);
432fprintf(stderr, "Result 0: ");
433mlirValuePrint(value, printToStderr, NULL);
434fprintf(stderr, "\n");
435fprintf(stderr, "Value is null: %d\n", mlirValueIsNull(value));
436// CHECK: Result 0: {{.*}} = arith.constant 0 : index
437// CHECK: Value is null: 0
438
439MlirType type = mlirValueGetType(value);
440fprintf(stderr, "Result 0 type: ");
441mlirTypePrint(type, printToStderr, NULL);
442fprintf(stderr, "\n");
443// CHECK: Result 0 type: index
444
445// Set a discardable attribute.
446mlirOperationSetDiscardableAttributeByName(
447operation, mlirStringRefCreateFromCString("custom_attr"),
448mlirBoolAttrGet(ctx, 1));
449fprintf(stderr, "Op with set attr: ");
450mlirOperationPrint(operation, printToStderr, NULL);
451fprintf(stderr, "\n");
452// CHECK: Op with set attr: {{.*}} {custom_attr = true}
453
454// Remove the attribute.
455fprintf(stderr, "Remove attr: %d\n",
456mlirOperationRemoveDiscardableAttributeByName(
457operation, mlirStringRefCreateFromCString("custom_attr")));
458fprintf(stderr, "Remove attr again: %d\n",
459mlirOperationRemoveDiscardableAttributeByName(
460operation, mlirStringRefCreateFromCString("custom_attr")));
461fprintf(stderr, "Removed attr is null: %d\n",
462mlirAttributeIsNull(mlirOperationGetDiscardableAttributeByName(
463operation, mlirStringRefCreateFromCString("custom_attr"))));
464// CHECK: Remove attr: 1
465// CHECK: Remove attr again: 0
466// CHECK: Removed attr is null: 1
467
468// Add a large attribute to verify printing flags.
469int64_t eltsShape[] = {4};
470int32_t eltsData[] = {1, 2, 3, 4};
471mlirOperationSetDiscardableAttributeByName(
472operation, mlirStringRefCreateFromCString("elts"),
473mlirDenseElementsAttrInt32Get(
474mlirRankedTensorTypeGet(1, eltsShape, mlirIntegerTypeGet(ctx, 32),
475mlirAttributeGetNull()),
4764, eltsData));
477MlirOpPrintingFlags flags = mlirOpPrintingFlagsCreate();
478mlirOpPrintingFlagsElideLargeElementsAttrs(flags, 2);
479mlirOpPrintingFlagsPrintGenericOpForm(flags);
480mlirOpPrintingFlagsEnableDebugInfo(flags, /*enable=*/1, /*prettyForm=*/0);
481mlirOpPrintingFlagsUseLocalScope(flags);
482fprintf(stderr, "Op print with all flags: ");
483mlirOperationPrintWithFlags(operation, flags, printToStderr, NULL);
484fprintf(stderr, "\n");
485fprintf(stderr, "Op print with state: ");
486MlirAsmState state = mlirAsmStateCreateForOperation(parentOperation, flags);
487mlirOperationPrintWithState(operation, state, printToStderr, NULL);
488fprintf(stderr, "\n");
489// clang-format off
490// CHECK: Op print with all flags: %{{.*}} = "arith.constant"() <{value = 0 : index}> {elts = dense_resource<__elided__> : tensor<4xi32>} : () -> index loc(unknown)
491// clang-format on
492
493mlirOpPrintingFlagsDestroy(flags);
494flags = mlirOpPrintingFlagsCreate();
495mlirOpPrintingFlagsSkipRegions(flags);
496fprintf(stderr, "Op print with skip regions flag: ");
497mlirOperationPrintWithFlags(function, flags, printToStderr, NULL);
498fprintf(stderr, "\n");
499// clang-format off
500// CHECK: Op print with skip regions flag: func.func @add(%[[ARG0:.*]]: memref<?xf32>, %[[ARG1:.*]]: memref<?xf32>)
501// CHECK-NOT: constant
502// CHECK-NOT: return
503// clang-format on
504
505fprintf(stderr, "With state: |");
506mlirValuePrintAsOperand(value, state, printToStderr, NULL);
507// CHECK: With state: |%0|
508fprintf(stderr, "|\n");
509mlirAsmStateDestroy(state);
510
511mlirOpPrintingFlagsDestroy(flags);
512}
513
514static int constructAndTraverseIr(MlirContext ctx) {
515MlirLocation location = mlirLocationUnknownGet(ctx);
516
517MlirModule moduleOp = makeAndDumpAdd(ctx, location);
518MlirOperation module = mlirModuleGetOperation(moduleOp);
519assert(!mlirModuleIsNull(mlirModuleFromOperation(module)));
520
521int errcode = collectStats(module);
522if (errcode)
523return errcode;
524
525printFirstOfEach(ctx, module);
526
527mlirModuleDestroy(moduleOp);
528return 0;
529}
530
531/// Creates an operation with a region containing multiple blocks with
532/// operations and dumps it. The blocks and operations are inserted using
533/// block/operation-relative API and their final order is checked.
534static void buildWithInsertionsAndPrint(MlirContext ctx) {
535MlirLocation loc = mlirLocationUnknownGet(ctx);
536mlirContextSetAllowUnregisteredDialects(ctx, true);
537
538MlirRegion owningRegion = mlirRegionCreate();
539MlirBlock nullBlock = mlirRegionGetFirstBlock(owningRegion);
540MlirOperationState state = mlirOperationStateGet(
541mlirStringRefCreateFromCString("insertion.order.test"), loc);
542mlirOperationStateAddOwnedRegions(&state, 1, &owningRegion);
543MlirOperation op = mlirOperationCreate(&state);
544MlirRegion region = mlirOperationGetRegion(op, 0);
545
546// Use integer types of different bitwidth as block arguments in order to
547// differentiate blocks.
548MlirType i1 = mlirIntegerTypeGet(ctx, 1);
549MlirType i2 = mlirIntegerTypeGet(ctx, 2);
550MlirType i3 = mlirIntegerTypeGet(ctx, 3);
551MlirType i4 = mlirIntegerTypeGet(ctx, 4);
552MlirType i5 = mlirIntegerTypeGet(ctx, 5);
553MlirBlock block1 = mlirBlockCreate(1, &i1, &loc);
554MlirBlock block2 = mlirBlockCreate(1, &i2, &loc);
555MlirBlock block3 = mlirBlockCreate(1, &i3, &loc);
556MlirBlock block4 = mlirBlockCreate(1, &i4, &loc);
557MlirBlock block5 = mlirBlockCreate(1, &i5, &loc);
558// Insert blocks so as to obtain the 1-2-3-4 order,
559mlirRegionInsertOwnedBlockBefore(region, nullBlock, block3);
560mlirRegionInsertOwnedBlockBefore(region, block3, block2);
561mlirRegionInsertOwnedBlockAfter(region, nullBlock, block1);
562mlirRegionInsertOwnedBlockAfter(region, block3, block4);
563mlirRegionInsertOwnedBlockBefore(region, block3, block5);
564
565MlirOperationState op1State =
566mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op1"), loc);
567MlirOperationState op2State =
568mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op2"), loc);
569MlirOperationState op3State =
570mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op3"), loc);
571MlirOperationState op4State =
572mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op4"), loc);
573MlirOperationState op5State =
574mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op5"), loc);
575MlirOperationState op6State =
576mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op6"), loc);
577MlirOperationState op7State =
578mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op7"), loc);
579MlirOperationState op8State =
580mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op8"), loc);
581MlirOperation op1 = mlirOperationCreate(&op1State);
582MlirOperation op2 = mlirOperationCreate(&op2State);
583MlirOperation op3 = mlirOperationCreate(&op3State);
584MlirOperation op4 = mlirOperationCreate(&op4State);
585MlirOperation op5 = mlirOperationCreate(&op5State);
586MlirOperation op6 = mlirOperationCreate(&op6State);
587MlirOperation op7 = mlirOperationCreate(&op7State);
588MlirOperation op8 = mlirOperationCreate(&op8State);
589
590// Insert operations in the first block so as to obtain the 1-2-3-4 order.
591MlirOperation nullOperation = mlirBlockGetFirstOperation(block1);
592assert(mlirOperationIsNull(nullOperation));
593mlirBlockInsertOwnedOperationBefore(block1, nullOperation, op3);
594mlirBlockInsertOwnedOperationBefore(block1, op3, op2);
595mlirBlockInsertOwnedOperationAfter(block1, nullOperation, op1);
596mlirBlockInsertOwnedOperationAfter(block1, op3, op4);
597
598// Append operations to the rest of blocks to make them non-empty and thus
599// printable.
600mlirBlockAppendOwnedOperation(block2, op5);
601mlirBlockAppendOwnedOperation(block3, op6);
602mlirBlockAppendOwnedOperation(block4, op7);
603mlirBlockAppendOwnedOperation(block5, op8);
604
605// Remove block5.
606mlirBlockDetach(block5);
607mlirBlockDestroy(block5);
608
609mlirOperationDump(op);
610mlirOperationDestroy(op);
611mlirContextSetAllowUnregisteredDialects(ctx, false);
612// clang-format off
613// CHECK-LABEL: "insertion.order.test"
614// CHECK: ^{{.*}}(%{{.*}}: i1
615// CHECK: "dummy.op1"
616// CHECK-NEXT: "dummy.op2"
617// CHECK-NEXT: "dummy.op3"
618// CHECK-NEXT: "dummy.op4"
619// CHECK: ^{{.*}}(%{{.*}}: i2
620// CHECK: "dummy.op5"
621// CHECK-NOT: ^{{.*}}(%{{.*}}: i5
622// CHECK-NOT: "dummy.op8"
623// CHECK: ^{{.*}}(%{{.*}}: i3
624// CHECK: "dummy.op6"
625// CHECK: ^{{.*}}(%{{.*}}: i4
626// CHECK: "dummy.op7"
627// clang-format on
628}
629
630/// Creates operations with type inference and tests various failure modes.
631static int createOperationWithTypeInference(MlirContext ctx) {
632MlirLocation loc = mlirLocationUnknownGet(ctx);
633MlirAttribute iAttr = mlirIntegerAttrGet(mlirIntegerTypeGet(ctx, 32), 4);
634
635// The shape.const_size op implements result type inference and is only used
636// for that reason.
637MlirOperationState state = mlirOperationStateGet(
638mlirStringRefCreateFromCString("shape.const_size"), loc);
639MlirNamedAttribute valueAttr = mlirNamedAttributeGet(
640mlirIdentifierGet(ctx, mlirStringRefCreateFromCString("value")), iAttr);
641mlirOperationStateAddAttributes(&state, 1, &valueAttr);
642mlirOperationStateEnableResultTypeInference(&state);
643
644// Expect result type inference to succeed.
645MlirOperation op = mlirOperationCreate(&state);
646if (mlirOperationIsNull(op)) {
647fprintf(stderr, "ERROR: Result type inference unexpectedly failed");
648return 1;
649}
650
651// CHECK: RESULT_TYPE_INFERENCE: !shape.size
652fprintf(stderr, "RESULT_TYPE_INFERENCE: ");
653mlirTypeDump(mlirValueGetType(mlirOperationGetResult(op, 0)));
654fprintf(stderr, "\n");
655mlirOperationDestroy(op);
656return 0;
657}
658
659/// Dumps instances of all builtin types to check that C API works correctly.
660/// Additionally, performs simple identity checks that a builtin type
661/// constructed with C API can be inspected and has the expected type. The
662/// latter achieves full coverage of C API for builtin types. Returns 0 on
663/// success and a non-zero error code on failure.
664static int printBuiltinTypes(MlirContext ctx) {
665// Integer types.
666MlirType i32 = mlirIntegerTypeGet(ctx, 32);
667MlirType si32 = mlirIntegerTypeSignedGet(ctx, 32);
668MlirType ui32 = mlirIntegerTypeUnsignedGet(ctx, 32);
669if (!mlirTypeIsAInteger(i32) || mlirTypeIsAF32(i32))
670return 1;
671if (!mlirTypeIsAInteger(si32) || !mlirIntegerTypeIsSigned(si32))
672return 2;
673if (!mlirTypeIsAInteger(ui32) || !mlirIntegerTypeIsUnsigned(ui32))
674return 3;
675if (mlirTypeEqual(i32, ui32) || mlirTypeEqual(i32, si32))
676return 4;
677if (mlirIntegerTypeGetWidth(i32) != mlirIntegerTypeGetWidth(si32))
678return 5;
679fprintf(stderr, "@types\n");
680mlirTypeDump(i32);
681fprintf(stderr, "\n");
682mlirTypeDump(si32);
683fprintf(stderr, "\n");
684mlirTypeDump(ui32);
685fprintf(stderr, "\n");
686// CHECK-LABEL: @types
687// CHECK: i32
688// CHECK: si32
689// CHECK: ui32
690
691// Index type.
692MlirType index = mlirIndexTypeGet(ctx);
693if (!mlirTypeIsAIndex(index))
694return 6;
695mlirTypeDump(index);
696fprintf(stderr, "\n");
697// CHECK: index
698
699// Floating-point types.
700MlirType bf16 = mlirBF16TypeGet(ctx);
701MlirType f16 = mlirF16TypeGet(ctx);
702MlirType f32 = mlirF32TypeGet(ctx);
703MlirType f64 = mlirF64TypeGet(ctx);
704if (!mlirTypeIsABF16(bf16))
705return 7;
706if (!mlirTypeIsAF16(f16))
707return 9;
708if (!mlirTypeIsAF32(f32))
709return 10;
710if (!mlirTypeIsAF64(f64))
711return 11;
712mlirTypeDump(bf16);
713fprintf(stderr, "\n");
714mlirTypeDump(f16);
715fprintf(stderr, "\n");
716mlirTypeDump(f32);
717fprintf(stderr, "\n");
718mlirTypeDump(f64);
719fprintf(stderr, "\n");
720// CHECK: bf16
721// CHECK: f16
722// CHECK: f32
723// CHECK: f64
724
725// None type.
726MlirType none = mlirNoneTypeGet(ctx);
727if (!mlirTypeIsANone(none))
728return 12;
729mlirTypeDump(none);
730fprintf(stderr, "\n");
731// CHECK: none
732
733// Complex type.
734MlirType cplx = mlirComplexTypeGet(f32);
735if (!mlirTypeIsAComplex(cplx) ||
736!mlirTypeEqual(mlirComplexTypeGetElementType(cplx), f32))
737return 13;
738mlirTypeDump(cplx);
739fprintf(stderr, "\n");
740// CHECK: complex<f32>
741
742// Vector (and Shaped) type. ShapedType is a common base class for vectors,
743// memrefs and tensors, one cannot create instances of this class so it is
744// tested on an instance of vector type.
745int64_t shape[] = {2, 3};
746MlirType vector =
747mlirVectorTypeGet(sizeof(shape) / sizeof(int64_t), shape, f32);
748if (!mlirTypeIsAVector(vector) || !mlirTypeIsAShaped(vector))
749return 14;
750if (!mlirTypeEqual(mlirShapedTypeGetElementType(vector), f32) ||
751!mlirShapedTypeHasRank(vector) || mlirShapedTypeGetRank(vector) != 2 ||
752mlirShapedTypeGetDimSize(vector, 0) != 2 ||
753mlirShapedTypeIsDynamicDim(vector, 0) ||
754mlirShapedTypeGetDimSize(vector, 1) != 3 ||
755!mlirShapedTypeHasStaticShape(vector))
756return 15;
757mlirTypeDump(vector);
758fprintf(stderr, "\n");
759// CHECK: vector<2x3xf32>
760
761// Scalable vector type.
762bool scalable[] = {false, true};
763MlirType scalableVector = mlirVectorTypeGetScalable(
764sizeof(shape) / sizeof(int64_t), shape, scalable, f32);
765if (!mlirTypeIsAVector(scalableVector))
766return 16;
767if (!mlirVectorTypeIsScalable(scalableVector) ||
768mlirVectorTypeIsDimScalable(scalableVector, 0) ||
769!mlirVectorTypeIsDimScalable(scalableVector, 1))
770return 17;
771mlirTypeDump(scalableVector);
772fprintf(stderr, "\n");
773// CHECK: vector<2x[3]xf32>
774
775// Ranked tensor type.
776MlirType rankedTensor = mlirRankedTensorTypeGet(
777sizeof(shape) / sizeof(int64_t), shape, f32, mlirAttributeGetNull());
778if (!mlirTypeIsATensor(rankedTensor) ||
779!mlirTypeIsARankedTensor(rankedTensor) ||
780!mlirAttributeIsNull(mlirRankedTensorTypeGetEncoding(rankedTensor)))
781return 18;
782mlirTypeDump(rankedTensor);
783fprintf(stderr, "\n");
784// CHECK: tensor<2x3xf32>
785
786// Unranked tensor type.
787MlirType unrankedTensor = mlirUnrankedTensorTypeGet(f32);
788if (!mlirTypeIsATensor(unrankedTensor) ||
789!mlirTypeIsAUnrankedTensor(unrankedTensor) ||
790mlirShapedTypeHasRank(unrankedTensor))
791return 19;
792mlirTypeDump(unrankedTensor);
793fprintf(stderr, "\n");
794// CHECK: tensor<*xf32>
795
796// MemRef type.
797MlirAttribute memSpace2 = mlirIntegerAttrGet(mlirIntegerTypeGet(ctx, 64), 2);
798MlirType memRef = mlirMemRefTypeContiguousGet(
799f32, sizeof(shape) / sizeof(int64_t), shape, memSpace2);
800if (!mlirTypeIsAMemRef(memRef) ||
801!mlirAttributeEqual(mlirMemRefTypeGetMemorySpace(memRef), memSpace2))
802return 20;
803mlirTypeDump(memRef);
804fprintf(stderr, "\n");
805// CHECK: memref<2x3xf32, 2>
806
807// Unranked MemRef type.
808MlirAttribute memSpace4 = mlirIntegerAttrGet(mlirIntegerTypeGet(ctx, 64), 4);
809MlirType unrankedMemRef = mlirUnrankedMemRefTypeGet(f32, memSpace4);
810if (!mlirTypeIsAUnrankedMemRef(unrankedMemRef) ||
811mlirTypeIsAMemRef(unrankedMemRef) ||
812!mlirAttributeEqual(mlirUnrankedMemrefGetMemorySpace(unrankedMemRef),
813memSpace4))
814return 21;
815mlirTypeDump(unrankedMemRef);
816fprintf(stderr, "\n");
817// CHECK: memref<*xf32, 4>
818
819// Tuple type.
820MlirType types[] = {unrankedMemRef, f32};
821MlirType tuple = mlirTupleTypeGet(ctx, 2, types);
822if (!mlirTypeIsATuple(tuple) || mlirTupleTypeGetNumTypes(tuple) != 2 ||
823!mlirTypeEqual(mlirTupleTypeGetType(tuple, 0), unrankedMemRef) ||
824!mlirTypeEqual(mlirTupleTypeGetType(tuple, 1), f32))
825return 22;
826mlirTypeDump(tuple);
827fprintf(stderr, "\n");
828// CHECK: tuple<memref<*xf32, 4>, f32>
829
830// Function type.
831MlirType funcInputs[2] = {mlirIndexTypeGet(ctx), mlirIntegerTypeGet(ctx, 1)};
832MlirType funcResults[3] = {mlirIntegerTypeGet(ctx, 16),
833mlirIntegerTypeGet(ctx, 32),
834mlirIntegerTypeGet(ctx, 64)};
835MlirType funcType = mlirFunctionTypeGet(ctx, 2, funcInputs, 3, funcResults);
836if (mlirFunctionTypeGetNumInputs(funcType) != 2)
837return 23;
838if (mlirFunctionTypeGetNumResults(funcType) != 3)
839return 24;
840if (!mlirTypeEqual(funcInputs[0], mlirFunctionTypeGetInput(funcType, 0)) ||
841!mlirTypeEqual(funcInputs[1], mlirFunctionTypeGetInput(funcType, 1)))
842return 25;
843if (!mlirTypeEqual(funcResults[0], mlirFunctionTypeGetResult(funcType, 0)) ||
844!mlirTypeEqual(funcResults[1], mlirFunctionTypeGetResult(funcType, 1)) ||
845!mlirTypeEqual(funcResults[2], mlirFunctionTypeGetResult(funcType, 2)))
846return 26;
847mlirTypeDump(funcType);
848fprintf(stderr, "\n");
849// CHECK: (index, i1) -> (i16, i32, i64)
850
851// Opaque type.
852MlirStringRef namespace = mlirStringRefCreate("dialect", 7);
853MlirStringRef data = mlirStringRefCreate("type", 4);
854mlirContextSetAllowUnregisteredDialects(ctx, true);
855MlirType opaque = mlirOpaqueTypeGet(ctx, namespace, data);
856mlirContextSetAllowUnregisteredDialects(ctx, false);
857if (!mlirTypeIsAOpaque(opaque) ||
858!mlirStringRefEqual(mlirOpaqueTypeGetDialectNamespace(opaque),
859namespace) ||
860!mlirStringRefEqual(mlirOpaqueTypeGetData(opaque), data))
861return 27;
862mlirTypeDump(opaque);
863fprintf(stderr, "\n");
864// CHECK: !dialect.type
865
866return 0;
867}
868
869void callbackSetFixedLengthString(const char *data, intptr_t len,
870void *userData) {
871strncpy(userData, data, len);
872}
873
874bool stringIsEqual(const char *lhs, MlirStringRef rhs) {
875if (strlen(lhs) != rhs.length) {
876return false;
877}
878return !strncmp(lhs, rhs.data, rhs.length);
879}
880
881int printBuiltinAttributes(MlirContext ctx) {
882MlirAttribute floating =
883mlirFloatAttrDoubleGet(ctx, mlirF64TypeGet(ctx), 2.0);
884if (!mlirAttributeIsAFloat(floating) ||
885fabs(mlirFloatAttrGetValueDouble(floating) - 2.0) > 1E-6)
886return 1;
887fprintf(stderr, "@attrs\n");
888mlirAttributeDump(floating);
889// CHECK-LABEL: @attrs
890// CHECK: 2.000000e+00 : f64
891
892// Exercise mlirAttributeGetType() just for the first one.
893MlirType floatingType = mlirAttributeGetType(floating);
894mlirTypeDump(floatingType);
895// CHECK: f64
896
897MlirAttribute integer = mlirIntegerAttrGet(mlirIntegerTypeGet(ctx, 32), 42);
898MlirAttribute signedInteger =
899mlirIntegerAttrGet(mlirIntegerTypeSignedGet(ctx, 8), -1);
900MlirAttribute unsignedInteger =
901mlirIntegerAttrGet(mlirIntegerTypeUnsignedGet(ctx, 8), 255);
902if (!mlirAttributeIsAInteger(integer) ||
903mlirIntegerAttrGetValueInt(integer) != 42 ||
904mlirIntegerAttrGetValueSInt(signedInteger) != -1 ||
905mlirIntegerAttrGetValueUInt(unsignedInteger) != 255)
906return 2;
907mlirAttributeDump(integer);
908mlirAttributeDump(signedInteger);
909mlirAttributeDump(unsignedInteger);
910// CHECK: 42 : i32
911// CHECK: -1 : si8
912// CHECK: 255 : ui8
913
914MlirAttribute boolean = mlirBoolAttrGet(ctx, 1);
915if (!mlirAttributeIsABool(boolean) || !mlirBoolAttrGetValue(boolean))
916return 3;
917mlirAttributeDump(boolean);
918// CHECK: true
919
920const char data[] = "abcdefghijklmnopqestuvwxyz";
921MlirAttribute opaque =
922mlirOpaqueAttrGet(ctx, mlirStringRefCreateFromCString("func"), 3, data,
923mlirNoneTypeGet(ctx));
924if (!mlirAttributeIsAOpaque(opaque) ||
925!stringIsEqual("func", mlirOpaqueAttrGetDialectNamespace(opaque)))
926return 4;
927
928MlirStringRef opaqueData = mlirOpaqueAttrGetData(opaque);
929if (opaqueData.length != 3 ||
930strncmp(data, opaqueData.data, opaqueData.length))
931return 5;
932mlirAttributeDump(opaque);
933// CHECK: #func.abc
934
935MlirAttribute string =
936mlirStringAttrGet(ctx, mlirStringRefCreate(data + 3, 2));
937if (!mlirAttributeIsAString(string))
938return 6;
939
940MlirStringRef stringValue = mlirStringAttrGetValue(string);
941if (stringValue.length != 2 ||
942strncmp(data + 3, stringValue.data, stringValue.length))
943return 7;
944mlirAttributeDump(string);
945// CHECK: "de"
946
947MlirAttribute flatSymbolRef =
948mlirFlatSymbolRefAttrGet(ctx, mlirStringRefCreate(data + 5, 3));
949if (!mlirAttributeIsAFlatSymbolRef(flatSymbolRef))
950return 8;
951
952MlirStringRef flatSymbolRefValue =
953mlirFlatSymbolRefAttrGetValue(flatSymbolRef);
954if (flatSymbolRefValue.length != 3 ||
955strncmp(data + 5, flatSymbolRefValue.data, flatSymbolRefValue.length))
956return 9;
957mlirAttributeDump(flatSymbolRef);
958// CHECK: @fgh
959
960MlirAttribute symbols[] = {flatSymbolRef, flatSymbolRef};
961MlirAttribute symbolRef =
962mlirSymbolRefAttrGet(ctx, mlirStringRefCreate(data + 8, 2), 2, symbols);
963if (!mlirAttributeIsASymbolRef(symbolRef) ||
964mlirSymbolRefAttrGetNumNestedReferences(symbolRef) != 2 ||
965!mlirAttributeEqual(mlirSymbolRefAttrGetNestedReference(symbolRef, 0),
966flatSymbolRef) ||
967!mlirAttributeEqual(mlirSymbolRefAttrGetNestedReference(symbolRef, 1),
968flatSymbolRef))
969return 10;
970
971MlirStringRef symbolRefLeaf = mlirSymbolRefAttrGetLeafReference(symbolRef);
972MlirStringRef symbolRefRoot = mlirSymbolRefAttrGetRootReference(symbolRef);
973if (symbolRefLeaf.length != 3 ||
974strncmp(data + 5, symbolRefLeaf.data, symbolRefLeaf.length) ||
975symbolRefRoot.length != 2 ||
976strncmp(data + 8, symbolRefRoot.data, symbolRefRoot.length))
977return 11;
978mlirAttributeDump(symbolRef);
979// CHECK: @ij::@fgh::@fgh
980
981MlirAttribute type = mlirTypeAttrGet(mlirF32TypeGet(ctx));
982if (!mlirAttributeIsAType(type) ||
983!mlirTypeEqual(mlirF32TypeGet(ctx), mlirTypeAttrGetValue(type)))
984return 12;
985mlirAttributeDump(type);
986// CHECK: f32
987
988MlirAttribute unit = mlirUnitAttrGet(ctx);
989if (!mlirAttributeIsAUnit(unit))
990return 13;
991mlirAttributeDump(unit);
992// CHECK: unit
993
994int64_t shape[] = {1, 2};
995
996int bools[] = {0, 1};
997uint8_t uints8[] = {0u, 1u};
998int8_t ints8[] = {0, 1};
999uint16_t uints16[] = {0u, 1u};
1000int16_t ints16[] = {0, 1};
1001uint32_t uints32[] = {0u, 1u};
1002int32_t ints32[] = {0, 1};
1003uint64_t uints64[] = {0u, 1u};
1004int64_t ints64[] = {0, 1};
1005float floats[] = {0.0f, 1.0f};
1006double doubles[] = {0.0, 1.0};
1007uint16_t bf16s[] = {0x0, 0x3f80};
1008uint16_t f16s[] = {0x0, 0x3c00};
1009MlirAttribute encoding = mlirAttributeGetNull();
1010MlirAttribute boolElements = mlirDenseElementsAttrBoolGet(
1011mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 1), encoding),
10122, bools);
1013MlirAttribute uint8Elements = mlirDenseElementsAttrUInt8Get(
1014mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeUnsignedGet(ctx, 8),
1015encoding),
10162, uints8);
1017MlirAttribute int8Elements = mlirDenseElementsAttrInt8Get(
1018mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 8), encoding),
10192, ints8);
1020MlirAttribute uint16Elements = mlirDenseElementsAttrUInt16Get(
1021mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeUnsignedGet(ctx, 16),
1022encoding),
10232, uints16);
1024MlirAttribute int16Elements = mlirDenseElementsAttrInt16Get(
1025mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 16), encoding),
10262, ints16);
1027MlirAttribute uint32Elements = mlirDenseElementsAttrUInt32Get(
1028mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeUnsignedGet(ctx, 32),
1029encoding),
10302, uints32);
1031MlirAttribute int32Elements = mlirDenseElementsAttrInt32Get(
1032mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 32), encoding),
10332, ints32);
1034MlirAttribute uint64Elements = mlirDenseElementsAttrUInt64Get(
1035mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeUnsignedGet(ctx, 64),
1036encoding),
10372, uints64);
1038MlirAttribute int64Elements = mlirDenseElementsAttrInt64Get(
1039mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 64), encoding),
10402, ints64);
1041MlirAttribute floatElements = mlirDenseElementsAttrFloatGet(
1042mlirRankedTensorTypeGet(2, shape, mlirF32TypeGet(ctx), encoding), 2,
1043floats);
1044MlirAttribute doubleElements = mlirDenseElementsAttrDoubleGet(
1045mlirRankedTensorTypeGet(2, shape, mlirF64TypeGet(ctx), encoding), 2,
1046doubles);
1047MlirAttribute bf16Elements = mlirDenseElementsAttrBFloat16Get(
1048mlirRankedTensorTypeGet(2, shape, mlirBF16TypeGet(ctx), encoding), 2,
1049bf16s);
1050MlirAttribute f16Elements = mlirDenseElementsAttrFloat16Get(
1051mlirRankedTensorTypeGet(2, shape, mlirF16TypeGet(ctx), encoding), 2,
1052f16s);
1053
1054if (!mlirAttributeIsADenseElements(boolElements) ||
1055!mlirAttributeIsADenseElements(uint8Elements) ||
1056!mlirAttributeIsADenseElements(int8Elements) ||
1057!mlirAttributeIsADenseElements(uint32Elements) ||
1058!mlirAttributeIsADenseElements(int32Elements) ||
1059!mlirAttributeIsADenseElements(uint64Elements) ||
1060!mlirAttributeIsADenseElements(int64Elements) ||
1061!mlirAttributeIsADenseElements(floatElements) ||
1062!mlirAttributeIsADenseElements(doubleElements) ||
1063!mlirAttributeIsADenseElements(bf16Elements) ||
1064!mlirAttributeIsADenseElements(f16Elements))
1065return 14;
1066
1067if (mlirDenseElementsAttrGetBoolValue(boolElements, 1) != 1 ||
1068mlirDenseElementsAttrGetUInt8Value(uint8Elements, 1) != 1 ||
1069mlirDenseElementsAttrGetInt8Value(int8Elements, 1) != 1 ||
1070mlirDenseElementsAttrGetUInt16Value(uint16Elements, 1) != 1 ||
1071mlirDenseElementsAttrGetInt16Value(int16Elements, 1) != 1 ||
1072mlirDenseElementsAttrGetUInt32Value(uint32Elements, 1) != 1 ||
1073mlirDenseElementsAttrGetInt32Value(int32Elements, 1) != 1 ||
1074mlirDenseElementsAttrGetUInt64Value(uint64Elements, 1) != 1 ||
1075mlirDenseElementsAttrGetInt64Value(int64Elements, 1) != 1 ||
1076fabsf(mlirDenseElementsAttrGetFloatValue(floatElements, 1) - 1.0f) >
10771E-6f ||
1078fabs(mlirDenseElementsAttrGetDoubleValue(doubleElements, 1) - 1.0) > 1E-6)
1079return 15;
1080
1081mlirAttributeDump(boolElements);
1082mlirAttributeDump(uint8Elements);
1083mlirAttributeDump(int8Elements);
1084mlirAttributeDump(uint32Elements);
1085mlirAttributeDump(int32Elements);
1086mlirAttributeDump(uint64Elements);
1087mlirAttributeDump(int64Elements);
1088mlirAttributeDump(floatElements);
1089mlirAttributeDump(doubleElements);
1090mlirAttributeDump(bf16Elements);
1091mlirAttributeDump(f16Elements);
1092// CHECK: dense<{{\[}}[false, true]]> : tensor<1x2xi1>
1093// CHECK: dense<{{\[}}[0, 1]]> : tensor<1x2xui8>
1094// CHECK: dense<{{\[}}[0, 1]]> : tensor<1x2xi8>
1095// CHECK: dense<{{\[}}[0, 1]]> : tensor<1x2xui32>
1096// CHECK: dense<{{\[}}[0, 1]]> : tensor<1x2xi32>
1097// CHECK: dense<{{\[}}[0, 1]]> : tensor<1x2xui64>
1098// CHECK: dense<{{\[}}[0, 1]]> : tensor<1x2xi64>
1099// CHECK: dense<{{\[}}[0.000000e+00, 1.000000e+00]]> : tensor<1x2xf32>
1100// CHECK: dense<{{\[}}[0.000000e+00, 1.000000e+00]]> : tensor<1x2xf64>
1101// CHECK: dense<{{\[}}[0.000000e+00, 1.000000e+00]]> : tensor<1x2xbf16>
1102// CHECK: dense<{{\[}}[0.000000e+00, 1.000000e+00]]> : tensor<1x2xf16>
1103
1104MlirAttribute splatBool = mlirDenseElementsAttrBoolSplatGet(
1105mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 1), encoding),
11061);
1107MlirAttribute splatUInt8 = mlirDenseElementsAttrUInt8SplatGet(
1108mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeUnsignedGet(ctx, 8),
1109encoding),
11101);
1111MlirAttribute splatInt8 = mlirDenseElementsAttrInt8SplatGet(
1112mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 8), encoding),
11131);
1114MlirAttribute splatUInt32 = mlirDenseElementsAttrUInt32SplatGet(
1115mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeUnsignedGet(ctx, 32),
1116encoding),
11171);
1118MlirAttribute splatInt32 = mlirDenseElementsAttrInt32SplatGet(
1119mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 32), encoding),
11201);
1121MlirAttribute splatUInt64 = mlirDenseElementsAttrUInt64SplatGet(
1122mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeUnsignedGet(ctx, 64),
1123encoding),
11241);
1125MlirAttribute splatInt64 = mlirDenseElementsAttrInt64SplatGet(
1126mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 64), encoding),
11271);
1128MlirAttribute splatFloat = mlirDenseElementsAttrFloatSplatGet(
1129mlirRankedTensorTypeGet(2, shape, mlirF32TypeGet(ctx), encoding), 1.0f);
1130MlirAttribute splatDouble = mlirDenseElementsAttrDoubleSplatGet(
1131mlirRankedTensorTypeGet(2, shape, mlirF64TypeGet(ctx), encoding), 1.0);
1132
1133if (!mlirAttributeIsADenseElements(splatBool) ||
1134!mlirDenseElementsAttrIsSplat(splatBool) ||
1135!mlirAttributeIsADenseElements(splatUInt8) ||
1136!mlirDenseElementsAttrIsSplat(splatUInt8) ||
1137!mlirAttributeIsADenseElements(splatInt8) ||
1138!mlirDenseElementsAttrIsSplat(splatInt8) ||
1139!mlirAttributeIsADenseElements(splatUInt32) ||
1140!mlirDenseElementsAttrIsSplat(splatUInt32) ||
1141!mlirAttributeIsADenseElements(splatInt32) ||
1142!mlirDenseElementsAttrIsSplat(splatInt32) ||
1143!mlirAttributeIsADenseElements(splatUInt64) ||
1144!mlirDenseElementsAttrIsSplat(splatUInt64) ||
1145!mlirAttributeIsADenseElements(splatInt64) ||
1146!mlirDenseElementsAttrIsSplat(splatInt64) ||
1147!mlirAttributeIsADenseElements(splatFloat) ||
1148!mlirDenseElementsAttrIsSplat(splatFloat) ||
1149!mlirAttributeIsADenseElements(splatDouble) ||
1150!mlirDenseElementsAttrIsSplat(splatDouble))
1151return 16;
1152
1153if (mlirDenseElementsAttrGetBoolSplatValue(splatBool) != 1 ||
1154mlirDenseElementsAttrGetUInt8SplatValue(splatUInt8) != 1 ||
1155mlirDenseElementsAttrGetInt8SplatValue(splatInt8) != 1 ||
1156mlirDenseElementsAttrGetUInt32SplatValue(splatUInt32) != 1 ||
1157mlirDenseElementsAttrGetInt32SplatValue(splatInt32) != 1 ||
1158mlirDenseElementsAttrGetUInt64SplatValue(splatUInt64) != 1 ||
1159mlirDenseElementsAttrGetInt64SplatValue(splatInt64) != 1 ||
1160fabsf(mlirDenseElementsAttrGetFloatSplatValue(splatFloat) - 1.0f) >
11611E-6f ||
1162fabs(mlirDenseElementsAttrGetDoubleSplatValue(splatDouble) - 1.0) > 1E-6)
1163return 17;
1164
1165const uint8_t *uint8RawData =
1166(const uint8_t *)mlirDenseElementsAttrGetRawData(uint8Elements);
1167const int8_t *int8RawData =
1168(const int8_t *)mlirDenseElementsAttrGetRawData(int8Elements);
1169const uint32_t *uint32RawData =
1170(const uint32_t *)mlirDenseElementsAttrGetRawData(uint32Elements);
1171const int32_t *int32RawData =
1172(const int32_t *)mlirDenseElementsAttrGetRawData(int32Elements);
1173const uint64_t *uint64RawData =
1174(const uint64_t *)mlirDenseElementsAttrGetRawData(uint64Elements);
1175const int64_t *int64RawData =
1176(const int64_t *)mlirDenseElementsAttrGetRawData(int64Elements);
1177const float *floatRawData =
1178(const float *)mlirDenseElementsAttrGetRawData(floatElements);
1179const double *doubleRawData =
1180(const double *)mlirDenseElementsAttrGetRawData(doubleElements);
1181const uint16_t *bf16RawData =
1182(const uint16_t *)mlirDenseElementsAttrGetRawData(bf16Elements);
1183const uint16_t *f16RawData =
1184(const uint16_t *)mlirDenseElementsAttrGetRawData(f16Elements);
1185if (uint8RawData[0] != 0u || uint8RawData[1] != 1u || int8RawData[0] != 0 ||
1186int8RawData[1] != 1 || uint32RawData[0] != 0u || uint32RawData[1] != 1u ||
1187int32RawData[0] != 0 || int32RawData[1] != 1 || uint64RawData[0] != 0u ||
1188uint64RawData[1] != 1u || int64RawData[0] != 0 || int64RawData[1] != 1 ||
1189floatRawData[0] != 0.0f || floatRawData[1] != 1.0f ||
1190doubleRawData[0] != 0.0 || doubleRawData[1] != 1.0 ||
1191bf16RawData[0] != 0 || bf16RawData[1] != 0x3f80 || f16RawData[0] != 0 ||
1192f16RawData[1] != 0x3c00)
1193return 18;
1194
1195mlirAttributeDump(splatBool);
1196mlirAttributeDump(splatUInt8);
1197mlirAttributeDump(splatInt8);
1198mlirAttributeDump(splatUInt32);
1199mlirAttributeDump(splatInt32);
1200mlirAttributeDump(splatUInt64);
1201mlirAttributeDump(splatInt64);
1202mlirAttributeDump(splatFloat);
1203mlirAttributeDump(splatDouble);
1204// CHECK: dense<true> : tensor<1x2xi1>
1205// CHECK: dense<1> : tensor<1x2xui8>
1206// CHECK: dense<1> : tensor<1x2xi8>
1207// CHECK: dense<1> : tensor<1x2xui32>
1208// CHECK: dense<1> : tensor<1x2xi32>
1209// CHECK: dense<1> : tensor<1x2xui64>
1210// CHECK: dense<1> : tensor<1x2xi64>
1211// CHECK: dense<1.000000e+00> : tensor<1x2xf32>
1212// CHECK: dense<1.000000e+00> : tensor<1x2xf64>
1213
1214mlirAttributeDump(mlirElementsAttrGetValue(floatElements, 2, uints64));
1215mlirAttributeDump(mlirElementsAttrGetValue(doubleElements, 2, uints64));
1216mlirAttributeDump(mlirElementsAttrGetValue(bf16Elements, 2, uints64));
1217mlirAttributeDump(mlirElementsAttrGetValue(f16Elements, 2, uints64));
1218// CHECK: 1.000000e+00 : f32
1219// CHECK: 1.000000e+00 : f64
1220// CHECK: 1.000000e+00 : bf16
1221// CHECK: 1.000000e+00 : f16
1222
1223int64_t indices[] = {0, 1};
1224int64_t one = 1;
1225MlirAttribute indicesAttr = mlirDenseElementsAttrInt64Get(
1226mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 64), encoding),
12272, indices);
1228MlirAttribute valuesAttr = mlirDenseElementsAttrFloatGet(
1229mlirRankedTensorTypeGet(1, &one, mlirF32TypeGet(ctx), encoding), 1,
1230floats);
1231MlirAttribute sparseAttr = mlirSparseElementsAttribute(
1232mlirRankedTensorTypeGet(2, shape, mlirF32TypeGet(ctx), encoding),
1233indicesAttr, valuesAttr);
1234mlirAttributeDump(sparseAttr);
1235// CHECK: sparse<{{\[}}[0, 1]], 0.000000e+00> : tensor<1x2xf32>
1236
1237MlirAttribute boolArray = mlirDenseBoolArrayGet(ctx, 2, bools);
1238MlirAttribute int8Array = mlirDenseI8ArrayGet(ctx, 2, ints8);
1239MlirAttribute int16Array = mlirDenseI16ArrayGet(ctx, 2, ints16);
1240MlirAttribute int32Array = mlirDenseI32ArrayGet(ctx, 2, ints32);
1241MlirAttribute int64Array = mlirDenseI64ArrayGet(ctx, 2, ints64);
1242MlirAttribute floatArray = mlirDenseF32ArrayGet(ctx, 2, floats);
1243MlirAttribute doubleArray = mlirDenseF64ArrayGet(ctx, 2, doubles);
1244if (!mlirAttributeIsADenseBoolArray(boolArray) ||
1245!mlirAttributeIsADenseI8Array(int8Array) ||
1246!mlirAttributeIsADenseI16Array(int16Array) ||
1247!mlirAttributeIsADenseI32Array(int32Array) ||
1248!mlirAttributeIsADenseI64Array(int64Array) ||
1249!mlirAttributeIsADenseF32Array(floatArray) ||
1250!mlirAttributeIsADenseF64Array(doubleArray))
1251return 19;
1252
1253if (mlirDenseArrayGetNumElements(boolArray) != 2 ||
1254mlirDenseArrayGetNumElements(int8Array) != 2 ||
1255mlirDenseArrayGetNumElements(int16Array) != 2 ||
1256mlirDenseArrayGetNumElements(int32Array) != 2 ||
1257mlirDenseArrayGetNumElements(int64Array) != 2 ||
1258mlirDenseArrayGetNumElements(floatArray) != 2 ||
1259mlirDenseArrayGetNumElements(doubleArray) != 2)
1260return 20;
1261
1262if (mlirDenseBoolArrayGetElement(boolArray, 1) != 1 ||
1263mlirDenseI8ArrayGetElement(int8Array, 1) != 1 ||
1264mlirDenseI16ArrayGetElement(int16Array, 1) != 1 ||
1265mlirDenseI32ArrayGetElement(int32Array, 1) != 1 ||
1266mlirDenseI64ArrayGetElement(int64Array, 1) != 1 ||
1267fabsf(mlirDenseF32ArrayGetElement(floatArray, 1) - 1.0f) > 1E-6f ||
1268fabs(mlirDenseF64ArrayGetElement(doubleArray, 1) - 1.0) > 1E-6)
1269return 21;
1270
1271int64_t layoutStrides[3] = {5, 7, 13};
1272MlirAttribute stridedLayoutAttr =
1273mlirStridedLayoutAttrGet(ctx, 42, 3, &layoutStrides[0]);
1274
1275// CHECK: strided<[5, 7, 13], offset: 42>
1276mlirAttributeDump(stridedLayoutAttr);
1277
1278if (mlirStridedLayoutAttrGetOffset(stridedLayoutAttr) != 42 ||
1279mlirStridedLayoutAttrGetNumStrides(stridedLayoutAttr) != 3 ||
1280mlirStridedLayoutAttrGetStride(stridedLayoutAttr, 0) != 5 ||
1281mlirStridedLayoutAttrGetStride(stridedLayoutAttr, 1) != 7 ||
1282mlirStridedLayoutAttrGetStride(stridedLayoutAttr, 2) != 13)
1283return 22;
1284
1285MlirAttribute uint8Blob = mlirUnmanagedDenseUInt8ResourceElementsAttrGet(
1286mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeUnsignedGet(ctx, 8),
1287encoding),
1288mlirStringRefCreateFromCString("resource_ui8"), 2, uints8);
1289MlirAttribute uint16Blob = mlirUnmanagedDenseUInt16ResourceElementsAttrGet(
1290mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeUnsignedGet(ctx, 16),
1291encoding),
1292mlirStringRefCreateFromCString("resource_ui16"), 2, uints16);
1293MlirAttribute uint32Blob = mlirUnmanagedDenseUInt32ResourceElementsAttrGet(
1294mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeUnsignedGet(ctx, 32),
1295encoding),
1296mlirStringRefCreateFromCString("resource_ui32"), 2, uints32);
1297MlirAttribute uint64Blob = mlirUnmanagedDenseUInt64ResourceElementsAttrGet(
1298mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeUnsignedGet(ctx, 64),
1299encoding),
1300mlirStringRefCreateFromCString("resource_ui64"), 2, uints64);
1301MlirAttribute int8Blob = mlirUnmanagedDenseInt8ResourceElementsAttrGet(
1302mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 8), encoding),
1303mlirStringRefCreateFromCString("resource_i8"), 2, ints8);
1304MlirAttribute int16Blob = mlirUnmanagedDenseInt16ResourceElementsAttrGet(
1305mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 16), encoding),
1306mlirStringRefCreateFromCString("resource_i16"), 2, ints16);
1307MlirAttribute int32Blob = mlirUnmanagedDenseInt32ResourceElementsAttrGet(
1308mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 32), encoding),
1309mlirStringRefCreateFromCString("resource_i32"), 2, ints32);
1310MlirAttribute int64Blob = mlirUnmanagedDenseInt64ResourceElementsAttrGet(
1311mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 64), encoding),
1312mlirStringRefCreateFromCString("resource_i64"), 2, ints64);
1313MlirAttribute floatsBlob = mlirUnmanagedDenseFloatResourceElementsAttrGet(
1314mlirRankedTensorTypeGet(2, shape, mlirF32TypeGet(ctx), encoding),
1315mlirStringRefCreateFromCString("resource_f32"), 2, floats);
1316MlirAttribute doublesBlob = mlirUnmanagedDenseDoubleResourceElementsAttrGet(
1317mlirRankedTensorTypeGet(2, shape, mlirF64TypeGet(ctx), encoding),
1318mlirStringRefCreateFromCString("resource_f64"), 2, doubles);
1319MlirAttribute blobBlob = mlirUnmanagedDenseResourceElementsAttrGet(
1320mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 64), encoding),
1321mlirStringRefCreateFromCString("resource_i64_blob"), /*data=*/uints64,
1322/*dataLength=*/sizeof(uints64),
1323/*dataAlignment=*/_Alignof(uint64_t),
1324/*dataIsMutable=*/false,
1325/*deleter=*/reportResourceDelete,
1326/*userData=*/(void *)&resourceI64BlobUserData);
1327
1328mlirAttributeDump(uint8Blob);
1329mlirAttributeDump(uint16Blob);
1330mlirAttributeDump(uint32Blob);
1331mlirAttributeDump(uint64Blob);
1332mlirAttributeDump(int8Blob);
1333mlirAttributeDump(int16Blob);
1334mlirAttributeDump(int32Blob);
1335mlirAttributeDump(int64Blob);
1336mlirAttributeDump(floatsBlob);
1337mlirAttributeDump(doublesBlob);
1338mlirAttributeDump(blobBlob);
1339// CHECK: dense_resource<resource_ui8> : tensor<1x2xui8>
1340// CHECK: dense_resource<resource_ui16> : tensor<1x2xui16>
1341// CHECK: dense_resource<resource_ui32> : tensor<1x2xui32>
1342// CHECK: dense_resource<resource_ui64> : tensor<1x2xui64>
1343// CHECK: dense_resource<resource_i8> : tensor<1x2xi8>
1344// CHECK: dense_resource<resource_i16> : tensor<1x2xi16>
1345// CHECK: dense_resource<resource_i32> : tensor<1x2xi32>
1346// CHECK: dense_resource<resource_i64> : tensor<1x2xi64>
1347// CHECK: dense_resource<resource_f32> : tensor<1x2xf32>
1348// CHECK: dense_resource<resource_f64> : tensor<1x2xf64>
1349// CHECK: dense_resource<resource_i64_blob> : tensor<1x2xi64>
1350
1351if (mlirDenseUInt8ResourceElementsAttrGetValue(uint8Blob, 1) != 1 ||
1352mlirDenseUInt16ResourceElementsAttrGetValue(uint16Blob, 1) != 1 ||
1353mlirDenseUInt32ResourceElementsAttrGetValue(uint32Blob, 1) != 1 ||
1354mlirDenseUInt64ResourceElementsAttrGetValue(uint64Blob, 1) != 1 ||
1355mlirDenseInt8ResourceElementsAttrGetValue(int8Blob, 1) != 1 ||
1356mlirDenseInt16ResourceElementsAttrGetValue(int16Blob, 1) != 1 ||
1357mlirDenseInt32ResourceElementsAttrGetValue(int32Blob, 1) != 1 ||
1358mlirDenseInt64ResourceElementsAttrGetValue(int64Blob, 1) != 1 ||
1359fabsf(mlirDenseF32ArrayGetElement(floatArray, 1) - 1.0f) > 1E-6f ||
1360fabsf(mlirDenseFloatResourceElementsAttrGetValue(floatsBlob, 1) - 1.0f) >
13611e-6 ||
1362fabs(mlirDenseDoubleResourceElementsAttrGetValue(doublesBlob, 1) - 1.0f) >
13631e-6 ||
1364mlirDenseUInt64ResourceElementsAttrGetValue(blobBlob, 1) != 1)
1365return 23;
1366
1367MlirLocation loc = mlirLocationUnknownGet(ctx);
1368MlirAttribute locAttr = mlirLocationGetAttribute(loc);
1369if (!mlirAttributeIsALocation(locAttr))
1370return 24;
1371
1372return 0;
1373}
1374
1375int printAffineMap(MlirContext ctx) {
1376MlirAffineMap emptyAffineMap = mlirAffineMapEmptyGet(ctx);
1377MlirAffineMap affineMap = mlirAffineMapZeroResultGet(ctx, 3, 2);
1378MlirAffineMap constAffineMap = mlirAffineMapConstantGet(ctx, 2);
1379MlirAffineMap multiDimIdentityAffineMap =
1380mlirAffineMapMultiDimIdentityGet(ctx, 3);
1381MlirAffineMap minorIdentityAffineMap =
1382mlirAffineMapMinorIdentityGet(ctx, 3, 2);
1383unsigned permutation[] = {1, 2, 0};
1384MlirAffineMap permutationAffineMap = mlirAffineMapPermutationGet(
1385ctx, sizeof(permutation) / sizeof(unsigned), permutation);
1386
1387fprintf(stderr, "@affineMap\n");
1388mlirAffineMapDump(emptyAffineMap);
1389mlirAffineMapDump(affineMap);
1390mlirAffineMapDump(constAffineMap);
1391mlirAffineMapDump(multiDimIdentityAffineMap);
1392mlirAffineMapDump(minorIdentityAffineMap);
1393mlirAffineMapDump(permutationAffineMap);
1394// CHECK-LABEL: @affineMap
1395// CHECK: () -> ()
1396// CHECK: (d0, d1, d2)[s0, s1] -> ()
1397// CHECK: () -> (2)
1398// CHECK: (d0, d1, d2) -> (d0, d1, d2)
1399// CHECK: (d0, d1, d2) -> (d1, d2)
1400// CHECK: (d0, d1, d2) -> (d1, d2, d0)
1401
1402if (!mlirAffineMapIsIdentity(emptyAffineMap) ||
1403mlirAffineMapIsIdentity(affineMap) ||
1404mlirAffineMapIsIdentity(constAffineMap) ||
1405!mlirAffineMapIsIdentity(multiDimIdentityAffineMap) ||
1406mlirAffineMapIsIdentity(minorIdentityAffineMap) ||
1407mlirAffineMapIsIdentity(permutationAffineMap))
1408return 1;
1409
1410if (!mlirAffineMapIsMinorIdentity(emptyAffineMap) ||
1411mlirAffineMapIsMinorIdentity(affineMap) ||
1412!mlirAffineMapIsMinorIdentity(multiDimIdentityAffineMap) ||
1413!mlirAffineMapIsMinorIdentity(minorIdentityAffineMap) ||
1414mlirAffineMapIsMinorIdentity(permutationAffineMap))
1415return 2;
1416
1417if (!mlirAffineMapIsEmpty(emptyAffineMap) ||
1418mlirAffineMapIsEmpty(affineMap) || mlirAffineMapIsEmpty(constAffineMap) ||
1419mlirAffineMapIsEmpty(multiDimIdentityAffineMap) ||
1420mlirAffineMapIsEmpty(minorIdentityAffineMap) ||
1421mlirAffineMapIsEmpty(permutationAffineMap))
1422return 3;
1423
1424if (mlirAffineMapIsSingleConstant(emptyAffineMap) ||
1425mlirAffineMapIsSingleConstant(affineMap) ||
1426!mlirAffineMapIsSingleConstant(constAffineMap) ||
1427mlirAffineMapIsSingleConstant(multiDimIdentityAffineMap) ||
1428mlirAffineMapIsSingleConstant(minorIdentityAffineMap) ||
1429mlirAffineMapIsSingleConstant(permutationAffineMap))
1430return 4;
1431
1432if (mlirAffineMapGetSingleConstantResult(constAffineMap) != 2)
1433return 5;
1434
1435if (mlirAffineMapGetNumDims(emptyAffineMap) != 0 ||
1436mlirAffineMapGetNumDims(affineMap) != 3 ||
1437mlirAffineMapGetNumDims(constAffineMap) != 0 ||
1438mlirAffineMapGetNumDims(multiDimIdentityAffineMap) != 3 ||
1439mlirAffineMapGetNumDims(minorIdentityAffineMap) != 3 ||
1440mlirAffineMapGetNumDims(permutationAffineMap) != 3)
1441return 6;
1442
1443if (mlirAffineMapGetNumSymbols(emptyAffineMap) != 0 ||
1444mlirAffineMapGetNumSymbols(affineMap) != 2 ||
1445mlirAffineMapGetNumSymbols(constAffineMap) != 0 ||
1446mlirAffineMapGetNumSymbols(multiDimIdentityAffineMap) != 0 ||
1447mlirAffineMapGetNumSymbols(minorIdentityAffineMap) != 0 ||
1448mlirAffineMapGetNumSymbols(permutationAffineMap) != 0)
1449return 7;
1450
1451if (mlirAffineMapGetNumResults(emptyAffineMap) != 0 ||
1452mlirAffineMapGetNumResults(affineMap) != 0 ||
1453mlirAffineMapGetNumResults(constAffineMap) != 1 ||
1454mlirAffineMapGetNumResults(multiDimIdentityAffineMap) != 3 ||
1455mlirAffineMapGetNumResults(minorIdentityAffineMap) != 2 ||
1456mlirAffineMapGetNumResults(permutationAffineMap) != 3)
1457return 8;
1458
1459if (mlirAffineMapGetNumInputs(emptyAffineMap) != 0 ||
1460mlirAffineMapGetNumInputs(affineMap) != 5 ||
1461mlirAffineMapGetNumInputs(constAffineMap) != 0 ||
1462mlirAffineMapGetNumInputs(multiDimIdentityAffineMap) != 3 ||
1463mlirAffineMapGetNumInputs(minorIdentityAffineMap) != 3 ||
1464mlirAffineMapGetNumInputs(permutationAffineMap) != 3)
1465return 9;
1466
1467if (!mlirAffineMapIsProjectedPermutation(emptyAffineMap) ||
1468!mlirAffineMapIsPermutation(emptyAffineMap) ||
1469mlirAffineMapIsProjectedPermutation(affineMap) ||
1470mlirAffineMapIsPermutation(affineMap) ||
1471mlirAffineMapIsProjectedPermutation(constAffineMap) ||
1472mlirAffineMapIsPermutation(constAffineMap) ||
1473!mlirAffineMapIsProjectedPermutation(multiDimIdentityAffineMap) ||
1474!mlirAffineMapIsPermutation(multiDimIdentityAffineMap) ||
1475!mlirAffineMapIsProjectedPermutation(minorIdentityAffineMap) ||
1476mlirAffineMapIsPermutation(minorIdentityAffineMap) ||
1477!mlirAffineMapIsProjectedPermutation(permutationAffineMap) ||
1478!mlirAffineMapIsPermutation(permutationAffineMap))
1479return 10;
1480
1481intptr_t sub[] = {1};
1482
1483MlirAffineMap subMap = mlirAffineMapGetSubMap(
1484multiDimIdentityAffineMap, sizeof(sub) / sizeof(intptr_t), sub);
1485MlirAffineMap majorSubMap =
1486mlirAffineMapGetMajorSubMap(multiDimIdentityAffineMap, 1);
1487MlirAffineMap minorSubMap =
1488mlirAffineMapGetMinorSubMap(multiDimIdentityAffineMap, 1);
1489
1490mlirAffineMapDump(subMap);
1491mlirAffineMapDump(majorSubMap);
1492mlirAffineMapDump(minorSubMap);
1493// CHECK: (d0, d1, d2) -> (d1)
1494// CHECK: (d0, d1, d2) -> (d0)
1495// CHECK: (d0, d1, d2) -> (d2)
1496
1497// CHECK: distinct[0]<"foo">
1498mlirAttributeDump(mlirDisctinctAttrCreate(
1499mlirStringAttrGet(ctx, mlirStringRefCreateFromCString("foo"))));
1500
1501return 0;
1502}
1503
1504int printAffineExpr(MlirContext ctx) {
1505MlirAffineExpr affineDimExpr = mlirAffineDimExprGet(ctx, 5);
1506MlirAffineExpr affineSymbolExpr = mlirAffineSymbolExprGet(ctx, 5);
1507MlirAffineExpr affineConstantExpr = mlirAffineConstantExprGet(ctx, 5);
1508MlirAffineExpr affineAddExpr =
1509mlirAffineAddExprGet(affineDimExpr, affineSymbolExpr);
1510MlirAffineExpr affineMulExpr =
1511mlirAffineMulExprGet(affineDimExpr, affineSymbolExpr);
1512MlirAffineExpr affineModExpr =
1513mlirAffineModExprGet(affineDimExpr, affineSymbolExpr);
1514MlirAffineExpr affineFloorDivExpr =
1515mlirAffineFloorDivExprGet(affineDimExpr, affineSymbolExpr);
1516MlirAffineExpr affineCeilDivExpr =
1517mlirAffineCeilDivExprGet(affineDimExpr, affineSymbolExpr);
1518
1519// Tests mlirAffineExprDump.
1520fprintf(stderr, "@affineExpr\n");
1521mlirAffineExprDump(affineDimExpr);
1522mlirAffineExprDump(affineSymbolExpr);
1523mlirAffineExprDump(affineConstantExpr);
1524mlirAffineExprDump(affineAddExpr);
1525mlirAffineExprDump(affineMulExpr);
1526mlirAffineExprDump(affineModExpr);
1527mlirAffineExprDump(affineFloorDivExpr);
1528mlirAffineExprDump(affineCeilDivExpr);
1529// CHECK-LABEL: @affineExpr
1530// CHECK: d5
1531// CHECK: s5
1532// CHECK: 5
1533// CHECK: d5 + s5
1534// CHECK: d5 * s5
1535// CHECK: d5 mod s5
1536// CHECK: d5 floordiv s5
1537// CHECK: d5 ceildiv s5
1538
1539// Tests methods of affine binary operation expression, takes add expression
1540// as an example.
1541mlirAffineExprDump(mlirAffineBinaryOpExprGetLHS(affineAddExpr));
1542mlirAffineExprDump(mlirAffineBinaryOpExprGetRHS(affineAddExpr));
1543// CHECK: d5
1544// CHECK: s5
1545
1546// Tests methods of affine dimension expression.
1547if (mlirAffineDimExprGetPosition(affineDimExpr) != 5)
1548return 1;
1549
1550// Tests methods of affine symbol expression.
1551if (mlirAffineSymbolExprGetPosition(affineSymbolExpr) != 5)
1552return 2;
1553
1554// Tests methods of affine constant expression.
1555if (mlirAffineConstantExprGetValue(affineConstantExpr) != 5)
1556return 3;
1557
1558// Tests methods of affine expression.
1559if (mlirAffineExprIsSymbolicOrConstant(affineDimExpr) ||
1560!mlirAffineExprIsSymbolicOrConstant(affineSymbolExpr) ||
1561!mlirAffineExprIsSymbolicOrConstant(affineConstantExpr) ||
1562mlirAffineExprIsSymbolicOrConstant(affineAddExpr) ||
1563mlirAffineExprIsSymbolicOrConstant(affineMulExpr) ||
1564mlirAffineExprIsSymbolicOrConstant(affineModExpr) ||
1565mlirAffineExprIsSymbolicOrConstant(affineFloorDivExpr) ||
1566mlirAffineExprIsSymbolicOrConstant(affineCeilDivExpr))
1567return 4;
1568
1569if (!mlirAffineExprIsPureAffine(affineDimExpr) ||
1570!mlirAffineExprIsPureAffine(affineSymbolExpr) ||
1571!mlirAffineExprIsPureAffine(affineConstantExpr) ||
1572!mlirAffineExprIsPureAffine(affineAddExpr) ||
1573mlirAffineExprIsPureAffine(affineMulExpr) ||
1574mlirAffineExprIsPureAffine(affineModExpr) ||
1575mlirAffineExprIsPureAffine(affineFloorDivExpr) ||
1576mlirAffineExprIsPureAffine(affineCeilDivExpr))
1577return 5;
1578
1579if (mlirAffineExprGetLargestKnownDivisor(affineDimExpr) != 1 ||
1580mlirAffineExprGetLargestKnownDivisor(affineSymbolExpr) != 1 ||
1581mlirAffineExprGetLargestKnownDivisor(affineConstantExpr) != 5 ||
1582mlirAffineExprGetLargestKnownDivisor(affineAddExpr) != 1 ||
1583mlirAffineExprGetLargestKnownDivisor(affineMulExpr) != 1 ||
1584mlirAffineExprGetLargestKnownDivisor(affineModExpr) != 1 ||
1585mlirAffineExprGetLargestKnownDivisor(affineFloorDivExpr) != 1 ||
1586mlirAffineExprGetLargestKnownDivisor(affineCeilDivExpr) != 1)
1587return 6;
1588
1589if (!mlirAffineExprIsMultipleOf(affineDimExpr, 1) ||
1590!mlirAffineExprIsMultipleOf(affineSymbolExpr, 1) ||
1591!mlirAffineExprIsMultipleOf(affineConstantExpr, 5) ||
1592!mlirAffineExprIsMultipleOf(affineAddExpr, 1) ||
1593!mlirAffineExprIsMultipleOf(affineMulExpr, 1) ||
1594!mlirAffineExprIsMultipleOf(affineModExpr, 1) ||
1595!mlirAffineExprIsMultipleOf(affineFloorDivExpr, 1) ||
1596!mlirAffineExprIsMultipleOf(affineCeilDivExpr, 1))
1597return 7;
1598
1599if (!mlirAffineExprIsFunctionOfDim(affineDimExpr, 5) ||
1600mlirAffineExprIsFunctionOfDim(affineSymbolExpr, 5) ||
1601mlirAffineExprIsFunctionOfDim(affineConstantExpr, 5) ||
1602!mlirAffineExprIsFunctionOfDim(affineAddExpr, 5) ||
1603!mlirAffineExprIsFunctionOfDim(affineMulExpr, 5) ||
1604!mlirAffineExprIsFunctionOfDim(affineModExpr, 5) ||
1605!mlirAffineExprIsFunctionOfDim(affineFloorDivExpr, 5) ||
1606!mlirAffineExprIsFunctionOfDim(affineCeilDivExpr, 5))
1607return 8;
1608
1609// Tests 'IsA' methods of affine binary operation expression.
1610if (!mlirAffineExprIsAAdd(affineAddExpr))
1611return 9;
1612
1613if (!mlirAffineExprIsAMul(affineMulExpr))
1614return 10;
1615
1616if (!mlirAffineExprIsAMod(affineModExpr))
1617return 11;
1618
1619if (!mlirAffineExprIsAFloorDiv(affineFloorDivExpr))
1620return 12;
1621
1622if (!mlirAffineExprIsACeilDiv(affineCeilDivExpr))
1623return 13;
1624
1625if (!mlirAffineExprIsABinary(affineAddExpr))
1626return 14;
1627
1628// Test other 'IsA' method on affine expressions.
1629if (!mlirAffineExprIsAConstant(affineConstantExpr))
1630return 15;
1631
1632if (!mlirAffineExprIsADim(affineDimExpr))
1633return 16;
1634
1635if (!mlirAffineExprIsASymbol(affineSymbolExpr))
1636return 17;
1637
1638// Test equality and nullity.
1639MlirAffineExpr otherDimExpr = mlirAffineDimExprGet(ctx, 5);
1640if (!mlirAffineExprEqual(affineDimExpr, otherDimExpr))
1641return 18;
1642
1643if (mlirAffineExprIsNull(affineDimExpr))
1644return 19;
1645
1646return 0;
1647}
1648
1649int affineMapFromExprs(MlirContext ctx) {
1650MlirAffineExpr affineDimExpr = mlirAffineDimExprGet(ctx, 0);
1651MlirAffineExpr affineSymbolExpr = mlirAffineSymbolExprGet(ctx, 1);
1652MlirAffineExpr exprs[] = {affineDimExpr, affineSymbolExpr};
1653MlirAffineMap map = mlirAffineMapGet(ctx, 3, 3, 2, exprs);
1654
1655// CHECK-LABEL: @affineMapFromExprs
1656fprintf(stderr, "@affineMapFromExprs");
1657// CHECK: (d0, d1, d2)[s0, s1, s2] -> (d0, s1)
1658mlirAffineMapDump(map);
1659
1660if (mlirAffineMapGetNumResults(map) != 2)
1661return 1;
1662
1663if (!mlirAffineExprEqual(mlirAffineMapGetResult(map, 0), affineDimExpr))
1664return 2;
1665
1666if (!mlirAffineExprEqual(mlirAffineMapGetResult(map, 1), affineSymbolExpr))
1667return 3;
1668
1669MlirAffineExpr affineDim2Expr = mlirAffineDimExprGet(ctx, 1);
1670MlirAffineExpr composed = mlirAffineExprCompose(affineDim2Expr, map);
1671// CHECK: s1
1672mlirAffineExprDump(composed);
1673if (!mlirAffineExprEqual(composed, affineSymbolExpr))
1674return 4;
1675
1676return 0;
1677}
1678
1679int printIntegerSet(MlirContext ctx) {
1680MlirIntegerSet emptySet = mlirIntegerSetEmptyGet(ctx, 2, 1);
1681
1682// CHECK-LABEL: @printIntegerSet
1683fprintf(stderr, "@printIntegerSet");
1684
1685// CHECK: (d0, d1)[s0] : (1 == 0)
1686mlirIntegerSetDump(emptySet);
1687
1688if (!mlirIntegerSetIsCanonicalEmpty(emptySet))
1689return 1;
1690
1691MlirIntegerSet anotherEmptySet = mlirIntegerSetEmptyGet(ctx, 2, 1);
1692if (!mlirIntegerSetEqual(emptySet, anotherEmptySet))
1693return 2;
1694
1695// Construct a set constrained by:
1696// d0 - s0 == 0,
1697// d1 - 42 >= 0.
1698MlirAffineExpr negOne = mlirAffineConstantExprGet(ctx, -1);
1699MlirAffineExpr negFortyTwo = mlirAffineConstantExprGet(ctx, -42);
1700MlirAffineExpr d0 = mlirAffineDimExprGet(ctx, 0);
1701MlirAffineExpr d1 = mlirAffineDimExprGet(ctx, 1);
1702MlirAffineExpr s0 = mlirAffineSymbolExprGet(ctx, 0);
1703MlirAffineExpr negS0 = mlirAffineMulExprGet(negOne, s0);
1704MlirAffineExpr d0minusS0 = mlirAffineAddExprGet(d0, negS0);
1705MlirAffineExpr d1minus42 = mlirAffineAddExprGet(d1, negFortyTwo);
1706MlirAffineExpr constraints[] = {d0minusS0, d1minus42};
1707bool flags[] = {true, false};
1708
1709MlirIntegerSet set = mlirIntegerSetGet(ctx, 2, 1, 2, constraints, flags);
1710// CHECK: (d0, d1)[s0] : (
1711// CHECK-DAG: d0 - s0 == 0
1712// CHECK-DAG: d1 - 42 >= 0
1713mlirIntegerSetDump(set);
1714
1715// Transform d1 into s0.
1716MlirAffineExpr s1 = mlirAffineSymbolExprGet(ctx, 1);
1717MlirAffineExpr repl[] = {d0, s1};
1718MlirIntegerSet replaced = mlirIntegerSetReplaceGet(set, repl, &s0, 1, 2);
1719// CHECK: (d0)[s0, s1] : (
1720// CHECK-DAG: d0 - s0 == 0
1721// CHECK-DAG: s1 - 42 >= 0
1722mlirIntegerSetDump(replaced);
1723
1724if (mlirIntegerSetGetNumDims(set) != 2)
1725return 3;
1726if (mlirIntegerSetGetNumDims(replaced) != 1)
1727return 4;
1728
1729if (mlirIntegerSetGetNumSymbols(set) != 1)
1730return 5;
1731if (mlirIntegerSetGetNumSymbols(replaced) != 2)
1732return 6;
1733
1734if (mlirIntegerSetGetNumInputs(set) != 3)
1735return 7;
1736
1737if (mlirIntegerSetGetNumConstraints(set) != 2)
1738return 8;
1739
1740if (mlirIntegerSetGetNumEqualities(set) != 1)
1741return 9;
1742
1743if (mlirIntegerSetGetNumInequalities(set) != 1)
1744return 10;
1745
1746MlirAffineExpr cstr1 = mlirIntegerSetGetConstraint(set, 0);
1747MlirAffineExpr cstr2 = mlirIntegerSetGetConstraint(set, 1);
1748bool isEq1 = mlirIntegerSetIsConstraintEq(set, 0);
1749bool isEq2 = mlirIntegerSetIsConstraintEq(set, 1);
1750if (!mlirAffineExprEqual(cstr1, isEq1 ? d0minusS0 : d1minus42))
1751return 11;
1752if (!mlirAffineExprEqual(cstr2, isEq2 ? d0minusS0 : d1minus42))
1753return 12;
1754
1755return 0;
1756}
1757
1758int registerOnlyStd(void) {
1759MlirContext ctx = mlirContextCreate();
1760// The built-in dialect is always loaded.
1761if (mlirContextGetNumLoadedDialects(ctx) != 1)
1762return 1;
1763
1764MlirDialectHandle stdHandle = mlirGetDialectHandle__func__();
1765
1766MlirDialect std = mlirContextGetOrLoadDialect(
1767ctx, mlirDialectHandleGetNamespace(stdHandle));
1768if (!mlirDialectIsNull(std))
1769return 2;
1770
1771mlirDialectHandleRegisterDialect(stdHandle, ctx);
1772
1773std = mlirContextGetOrLoadDialect(ctx,
1774mlirDialectHandleGetNamespace(stdHandle));
1775if (mlirDialectIsNull(std))
1776return 3;
1777
1778MlirDialect alsoStd = mlirDialectHandleLoadDialect(stdHandle, ctx);
1779if (!mlirDialectEqual(std, alsoStd))
1780return 4;
1781
1782MlirStringRef stdNs = mlirDialectGetNamespace(std);
1783MlirStringRef alsoStdNs = mlirDialectHandleGetNamespace(stdHandle);
1784if (stdNs.length != alsoStdNs.length ||
1785strncmp(stdNs.data, alsoStdNs.data, stdNs.length))
1786return 5;
1787
1788fprintf(stderr, "@registration\n");
1789// CHECK-LABEL: @registration
1790
1791// CHECK: func.call is_registered: 1
1792fprintf(stderr, "func.call is_registered: %d\n",
1793mlirContextIsRegisteredOperation(
1794ctx, mlirStringRefCreateFromCString("func.call")));
1795
1796// CHECK: func.not_existing_op is_registered: 0
1797fprintf(stderr, "func.not_existing_op is_registered: %d\n",
1798mlirContextIsRegisteredOperation(
1799ctx, mlirStringRefCreateFromCString("func.not_existing_op")));
1800
1801// CHECK: not_existing_dialect.not_existing_op is_registered: 0
1802fprintf(stderr, "not_existing_dialect.not_existing_op is_registered: %d\n",
1803mlirContextIsRegisteredOperation(
1804ctx, mlirStringRefCreateFromCString(
1805"not_existing_dialect.not_existing_op")));
1806
1807mlirContextDestroy(ctx);
1808return 0;
1809}
1810
1811/// Tests backreference APIs
1812static int testBackreferences(void) {
1813fprintf(stderr, "@test_backreferences\n");
1814
1815MlirContext ctx = mlirContextCreate();
1816mlirContextSetAllowUnregisteredDialects(ctx, true);
1817MlirLocation loc = mlirLocationUnknownGet(ctx);
1818
1819MlirOperationState opState =
1820mlirOperationStateGet(mlirStringRefCreateFromCString("invalid.op"), loc);
1821MlirRegion region = mlirRegionCreate();
1822MlirBlock block = mlirBlockCreate(0, NULL, NULL);
1823mlirRegionAppendOwnedBlock(region, block);
1824mlirOperationStateAddOwnedRegions(&opState, 1, ®ion);
1825MlirOperation op = mlirOperationCreate(&opState);
1826MlirIdentifier ident =
1827mlirIdentifierGet(ctx, mlirStringRefCreateFromCString("identifier"));
1828
1829if (!mlirContextEqual(ctx, mlirOperationGetContext(op))) {
1830fprintf(stderr, "ERROR: Getting context from operation failed\n");
1831return 1;
1832}
1833if (!mlirOperationEqual(op, mlirBlockGetParentOperation(block))) {
1834fprintf(stderr, "ERROR: Getting parent operation from block failed\n");
1835return 2;
1836}
1837if (!mlirContextEqual(ctx, mlirIdentifierGetContext(ident))) {
1838fprintf(stderr, "ERROR: Getting context from identifier failed\n");
1839return 3;
1840}
1841
1842mlirOperationDestroy(op);
1843mlirContextDestroy(ctx);
1844
1845// CHECK-LABEL: @test_backreferences
1846return 0;
1847}
1848
1849/// Tests operand APIs.
1850int testOperands(void) {
1851fprintf(stderr, "@testOperands\n");
1852// CHECK-LABEL: @testOperands
1853
1854MlirContext ctx = mlirContextCreate();
1855registerAllUpstreamDialects(ctx);
1856
1857mlirContextGetOrLoadDialect(ctx, mlirStringRefCreateFromCString("arith"));
1858mlirContextGetOrLoadDialect(ctx, mlirStringRefCreateFromCString("test"));
1859MlirLocation loc = mlirLocationUnknownGet(ctx);
1860MlirType indexType = mlirIndexTypeGet(ctx);
1861
1862// Create some constants to use as operands.
1863MlirAttribute indexZeroLiteral =
1864mlirAttributeParseGet(ctx, mlirStringRefCreateFromCString("0 : index"));
1865MlirNamedAttribute indexZeroValueAttr = mlirNamedAttributeGet(
1866mlirIdentifierGet(ctx, mlirStringRefCreateFromCString("value")),
1867indexZeroLiteral);
1868MlirOperationState constZeroState = mlirOperationStateGet(
1869mlirStringRefCreateFromCString("arith.constant"), loc);
1870mlirOperationStateAddResults(&constZeroState, 1, &indexType);
1871mlirOperationStateAddAttributes(&constZeroState, 1, &indexZeroValueAttr);
1872MlirOperation constZero = mlirOperationCreate(&constZeroState);
1873MlirValue constZeroValue = mlirOperationGetResult(constZero, 0);
1874
1875MlirAttribute indexOneLiteral =
1876mlirAttributeParseGet(ctx, mlirStringRefCreateFromCString("1 : index"));
1877MlirNamedAttribute indexOneValueAttr = mlirNamedAttributeGet(
1878mlirIdentifierGet(ctx, mlirStringRefCreateFromCString("value")),
1879indexOneLiteral);
1880MlirOperationState constOneState = mlirOperationStateGet(
1881mlirStringRefCreateFromCString("arith.constant"), loc);
1882mlirOperationStateAddResults(&constOneState, 1, &indexType);
1883mlirOperationStateAddAttributes(&constOneState, 1, &indexOneValueAttr);
1884MlirOperation constOne = mlirOperationCreate(&constOneState);
1885MlirValue constOneValue = mlirOperationGetResult(constOne, 0);
1886
1887// Create the operation under test.
1888mlirContextSetAllowUnregisteredDialects(ctx, true);
1889MlirOperationState opState =
1890mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op"), loc);
1891MlirValue initialOperands[] = {constZeroValue};
1892mlirOperationStateAddOperands(&opState, 1, initialOperands);
1893MlirOperation op = mlirOperationCreate(&opState);
1894
1895// Test operand APIs.
1896intptr_t numOperands = mlirOperationGetNumOperands(op);
1897fprintf(stderr, "Num Operands: %" PRIdPTR "\n", numOperands);
1898// CHECK: Num Operands: 1
1899
1900MlirValue opOperand1 = mlirOperationGetOperand(op, 0);
1901fprintf(stderr, "Original operand: ");
1902mlirValuePrint(opOperand1, printToStderr, NULL);
1903// CHECK: Original operand: {{.+}} arith.constant 0 : index
1904
1905mlirOperationSetOperand(op, 0, constOneValue);
1906MlirValue opOperand2 = mlirOperationGetOperand(op, 0);
1907fprintf(stderr, "Updated operand: ");
1908mlirValuePrint(opOperand2, printToStderr, NULL);
1909// CHECK: Updated operand: {{.+}} arith.constant 1 : index
1910
1911// Test op operand APIs.
1912MlirOpOperand use1 = mlirValueGetFirstUse(opOperand1);
1913if (!mlirOpOperandIsNull(use1)) {
1914fprintf(stderr, "ERROR: Use should be null\n");
1915return 1;
1916}
1917
1918MlirOpOperand use2 = mlirValueGetFirstUse(opOperand2);
1919if (mlirOpOperandIsNull(use2)) {
1920fprintf(stderr, "ERROR: Use should not be null\n");
1921return 2;
1922}
1923
1924fprintf(stderr, "Use owner: ");
1925mlirOperationPrint(mlirOpOperandGetOwner(use2), printToStderr, NULL);
1926fprintf(stderr, "\n");
1927// CHECK: Use owner: "dummy.op"
1928
1929fprintf(stderr, "Use operandNumber: %d\n",
1930mlirOpOperandGetOperandNumber(use2));
1931// CHECK: Use operandNumber: 0
1932
1933use2 = mlirOpOperandGetNextUse(use2);
1934if (!mlirOpOperandIsNull(use2)) {
1935fprintf(stderr, "ERROR: Next use should be null\n");
1936return 3;
1937}
1938
1939MlirOperationState op2State =
1940mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op2"), loc);
1941MlirValue initialOperands2[] = {constOneValue};
1942mlirOperationStateAddOperands(&op2State, 1, initialOperands2);
1943MlirOperation op2 = mlirOperationCreate(&op2State);
1944
1945MlirOpOperand use3 = mlirValueGetFirstUse(constOneValue);
1946fprintf(stderr, "First use owner: ");
1947mlirOperationPrint(mlirOpOperandGetOwner(use3), printToStderr, NULL);
1948fprintf(stderr, "\n");
1949// CHECK: First use owner: "dummy.op2"
1950
1951use3 = mlirOpOperandGetNextUse(mlirValueGetFirstUse(constOneValue));
1952fprintf(stderr, "Second use owner: ");
1953mlirOperationPrint(mlirOpOperandGetOwner(use3), printToStderr, NULL);
1954fprintf(stderr, "\n");
1955// CHECK: Second use owner: "dummy.op"
1956
1957MlirAttribute indexTwoLiteral =
1958mlirAttributeParseGet(ctx, mlirStringRefCreateFromCString("2 : index"));
1959MlirNamedAttribute indexTwoValueAttr = mlirNamedAttributeGet(
1960mlirIdentifierGet(ctx, mlirStringRefCreateFromCString("value")),
1961indexTwoLiteral);
1962MlirOperationState constTwoState = mlirOperationStateGet(
1963mlirStringRefCreateFromCString("arith.constant"), loc);
1964mlirOperationStateAddResults(&constTwoState, 1, &indexType);
1965mlirOperationStateAddAttributes(&constTwoState, 1, &indexTwoValueAttr);
1966MlirOperation constTwo = mlirOperationCreate(&constTwoState);
1967MlirValue constTwoValue = mlirOperationGetResult(constTwo, 0);
1968
1969mlirValueReplaceAllUsesOfWith(constOneValue, constTwoValue);
1970
1971use3 = mlirValueGetFirstUse(constOneValue);
1972if (!mlirOpOperandIsNull(use3)) {
1973fprintf(stderr, "ERROR: Use should be null\n");
1974return 4;
1975}
1976
1977MlirOpOperand use4 = mlirValueGetFirstUse(constTwoValue);
1978fprintf(stderr, "First replacement use owner: ");
1979mlirOperationPrint(mlirOpOperandGetOwner(use4), printToStderr, NULL);
1980fprintf(stderr, "\n");
1981// CHECK: First replacement use owner: "dummy.op"
1982
1983use4 = mlirOpOperandGetNextUse(mlirValueGetFirstUse(constTwoValue));
1984fprintf(stderr, "Second replacement use owner: ");
1985mlirOperationPrint(mlirOpOperandGetOwner(use4), printToStderr, NULL);
1986fprintf(stderr, "\n");
1987// CHECK: Second replacement use owner: "dummy.op2"
1988
1989MlirOpOperand use5 = mlirValueGetFirstUse(constTwoValue);
1990MlirOpOperand use6 = mlirOpOperandGetNextUse(use5);
1991if (!mlirValueEqual(mlirOpOperandGetValue(use5),
1992mlirOpOperandGetValue(use6))) {
1993fprintf(stderr,
1994"ERROR: First and second operand should share the same value\n");
1995return 5;
1996}
1997
1998mlirOperationDestroy(op);
1999mlirOperationDestroy(op2);
2000mlirOperationDestroy(constZero);
2001mlirOperationDestroy(constOne);
2002mlirOperationDestroy(constTwo);
2003mlirContextDestroy(ctx);
2004
2005return 0;
2006}
2007
2008/// Tests clone APIs.
2009int testClone(void) {
2010fprintf(stderr, "@testClone\n");
2011// CHECK-LABEL: @testClone
2012
2013MlirContext ctx = mlirContextCreate();
2014registerAllUpstreamDialects(ctx);
2015
2016mlirContextGetOrLoadDialect(ctx, mlirStringRefCreateFromCString("func"));
2017mlirContextGetOrLoadDialect(ctx, mlirStringRefCreateFromCString("arith"));
2018MlirLocation loc = mlirLocationUnknownGet(ctx);
2019MlirType indexType = mlirIndexTypeGet(ctx);
2020MlirStringRef valueStringRef = mlirStringRefCreateFromCString("value");
2021
2022MlirAttribute indexZeroLiteral =
2023mlirAttributeParseGet(ctx, mlirStringRefCreateFromCString("0 : index"));
2024MlirNamedAttribute indexZeroValueAttr = mlirNamedAttributeGet(
2025mlirIdentifierGet(ctx, valueStringRef), indexZeroLiteral);
2026MlirOperationState constZeroState = mlirOperationStateGet(
2027mlirStringRefCreateFromCString("arith.constant"), loc);
2028mlirOperationStateAddResults(&constZeroState, 1, &indexType);
2029mlirOperationStateAddAttributes(&constZeroState, 1, &indexZeroValueAttr);
2030MlirOperation constZero = mlirOperationCreate(&constZeroState);
2031
2032MlirAttribute indexOneLiteral =
2033mlirAttributeParseGet(ctx, mlirStringRefCreateFromCString("1 : index"));
2034MlirOperation constOne = mlirOperationClone(constZero);
2035mlirOperationSetAttributeByName(constOne, valueStringRef, indexOneLiteral);
2036
2037mlirOperationPrint(constZero, printToStderr, NULL);
2038mlirOperationPrint(constOne, printToStderr, NULL);
2039// CHECK: arith.constant 0 : index
2040// CHECK: arith.constant 1 : index
2041
2042mlirOperationDestroy(constZero);
2043mlirOperationDestroy(constOne);
2044mlirContextDestroy(ctx);
2045return 0;
2046}
2047
2048// Wraps a diagnostic into additional text we can match against.
2049MlirLogicalResult errorHandler(MlirDiagnostic diagnostic, void *userData) {
2050fprintf(stderr, "processing diagnostic (userData: %" PRIdPTR ") <<\n",
2051(intptr_t)userData);
2052mlirDiagnosticPrint(diagnostic, printToStderr, NULL);
2053fprintf(stderr, "\n");
2054MlirLocation loc = mlirDiagnosticGetLocation(diagnostic);
2055mlirLocationPrint(loc, printToStderr, NULL);
2056assert(mlirDiagnosticGetNumNotes(diagnostic) == 0);
2057fprintf(stderr, "\n>> end of diagnostic (userData: %" PRIdPTR ")\n",
2058(intptr_t)userData);
2059return mlirLogicalResultSuccess();
2060}
2061
2062// Logs when the delete user data callback is called
2063static void deleteUserData(void *userData) {
2064fprintf(stderr, "deleting user data (userData: %" PRIdPTR ")\n",
2065(intptr_t)userData);
2066}
2067
2068int testTypeID(MlirContext ctx) {
2069fprintf(stderr, "@testTypeID\n");
2070
2071// Test getting and comparing type and attribute type ids.
2072MlirType i32 = mlirIntegerTypeGet(ctx, 32);
2073MlirTypeID i32ID = mlirTypeGetTypeID(i32);
2074MlirType ui32 = mlirIntegerTypeUnsignedGet(ctx, 32);
2075MlirTypeID ui32ID = mlirTypeGetTypeID(ui32);
2076MlirType f32 = mlirF32TypeGet(ctx);
2077MlirTypeID f32ID = mlirTypeGetTypeID(f32);
2078MlirAttribute i32Attr = mlirIntegerAttrGet(i32, 1);
2079MlirTypeID i32AttrID = mlirAttributeGetTypeID(i32Attr);
2080
2081if (mlirTypeIDIsNull(i32ID) || mlirTypeIDIsNull(ui32ID) ||
2082mlirTypeIDIsNull(f32ID) || mlirTypeIDIsNull(i32AttrID)) {
2083fprintf(stderr, "ERROR: Expected type ids to be present\n");
2084return 1;
2085}
2086
2087if (!mlirTypeIDEqual(i32ID, ui32ID) ||
2088mlirTypeIDHashValue(i32ID) != mlirTypeIDHashValue(ui32ID)) {
2089fprintf(
2090stderr,
2091"ERROR: Expected different integer types to have the same type id\n");
2092return 2;
2093}
2094
2095if (mlirTypeIDEqual(i32ID, f32ID)) {
2096fprintf(stderr,
2097"ERROR: Expected integer type id to not equal float type id\n");
2098return 3;
2099}
2100
2101if (mlirTypeIDEqual(i32ID, i32AttrID)) {
2102fprintf(stderr, "ERROR: Expected integer type id to not equal integer "
2103"attribute type id\n");
2104return 4;
2105}
2106
2107MlirLocation loc = mlirLocationUnknownGet(ctx);
2108MlirType indexType = mlirIndexTypeGet(ctx);
2109MlirStringRef valueStringRef = mlirStringRefCreateFromCString("value");
2110
2111// Create a registered operation, which should have a type id.
2112MlirAttribute indexZeroLiteral =
2113mlirAttributeParseGet(ctx, mlirStringRefCreateFromCString("0 : index"));
2114MlirNamedAttribute indexZeroValueAttr = mlirNamedAttributeGet(
2115mlirIdentifierGet(ctx, valueStringRef), indexZeroLiteral);
2116MlirOperationState constZeroState = mlirOperationStateGet(
2117mlirStringRefCreateFromCString("arith.constant"), loc);
2118mlirOperationStateAddResults(&constZeroState, 1, &indexType);
2119mlirOperationStateAddAttributes(&constZeroState, 1, &indexZeroValueAttr);
2120MlirOperation constZero = mlirOperationCreate(&constZeroState);
2121
2122if (!mlirOperationVerify(constZero)) {
2123fprintf(stderr, "ERROR: Expected operation to verify correctly\n");
2124return 5;
2125}
2126
2127if (mlirOperationIsNull(constZero)) {
2128fprintf(stderr, "ERROR: Expected registered operation to be present\n");
2129return 6;
2130}
2131
2132MlirTypeID registeredOpID = mlirOperationGetTypeID(constZero);
2133
2134if (mlirTypeIDIsNull(registeredOpID)) {
2135fprintf(stderr,
2136"ERROR: Expected registered operation type id to be present\n");
2137return 7;
2138}
2139
2140// Create an unregistered operation, which should not have a type id.
2141mlirContextSetAllowUnregisteredDialects(ctx, true);
2142MlirOperationState opState =
2143mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op"), loc);
2144MlirOperation unregisteredOp = mlirOperationCreate(&opState);
2145if (mlirOperationIsNull(unregisteredOp)) {
2146fprintf(stderr, "ERROR: Expected unregistered operation to be present\n");
2147return 8;
2148}
2149
2150MlirTypeID unregisteredOpID = mlirOperationGetTypeID(unregisteredOp);
2151
2152if (!mlirTypeIDIsNull(unregisteredOpID)) {
2153fprintf(stderr,
2154"ERROR: Expected unregistered operation type id to be null\n");
2155return 9;
2156}
2157
2158mlirOperationDestroy(constZero);
2159mlirOperationDestroy(unregisteredOp);
2160
2161return 0;
2162}
2163
2164int testSymbolTable(MlirContext ctx) {
2165fprintf(stderr, "@testSymbolTable\n");
2166
2167const char *moduleString = "func.func private @foo()"
2168"func.func private @bar()";
2169const char *otherModuleString = "func.func private @qux()"
2170"func.func private @foo()";
2171
2172MlirModule module =
2173mlirModuleCreateParse(ctx, mlirStringRefCreateFromCString(moduleString));
2174MlirModule otherModule = mlirModuleCreateParse(
2175ctx, mlirStringRefCreateFromCString(otherModuleString));
2176
2177MlirSymbolTable symbolTable =
2178mlirSymbolTableCreate(mlirModuleGetOperation(module));
2179
2180MlirOperation funcFoo =
2181mlirSymbolTableLookup(symbolTable, mlirStringRefCreateFromCString("foo"));
2182if (mlirOperationIsNull(funcFoo))
2183return 1;
2184
2185MlirOperation funcBar =
2186mlirSymbolTableLookup(symbolTable, mlirStringRefCreateFromCString("bar"));
2187if (mlirOperationEqual(funcFoo, funcBar))
2188return 2;
2189
2190MlirOperation missing =
2191mlirSymbolTableLookup(symbolTable, mlirStringRefCreateFromCString("qux"));
2192if (!mlirOperationIsNull(missing))
2193return 3;
2194
2195MlirBlock moduleBody = mlirModuleGetBody(module);
2196MlirBlock otherModuleBody = mlirModuleGetBody(otherModule);
2197MlirOperation operation = mlirBlockGetFirstOperation(otherModuleBody);
2198mlirOperationRemoveFromParent(operation);
2199mlirBlockAppendOwnedOperation(moduleBody, operation);
2200
2201// At this moment, the operation is still missing from the symbol table.
2202MlirOperation stillMissing =
2203mlirSymbolTableLookup(symbolTable, mlirStringRefCreateFromCString("qux"));
2204if (!mlirOperationIsNull(stillMissing))
2205return 4;
2206
2207// After it is added to the symbol table, and not only the operation with
2208// which the table is associated, it can be looked up.
2209mlirSymbolTableInsert(symbolTable, operation);
2210MlirOperation funcQux =
2211mlirSymbolTableLookup(symbolTable, mlirStringRefCreateFromCString("qux"));
2212if (!mlirOperationEqual(operation, funcQux))
2213return 5;
2214
2215// Erasing from the symbol table also removes the operation.
2216mlirSymbolTableErase(symbolTable, funcBar);
2217MlirOperation nowMissing =
2218mlirSymbolTableLookup(symbolTable, mlirStringRefCreateFromCString("bar"));
2219if (!mlirOperationIsNull(nowMissing))
2220return 6;
2221
2222// Adding a symbol with the same name to the table should rename.
2223MlirOperation duplicateNameOp = mlirBlockGetFirstOperation(otherModuleBody);
2224mlirOperationRemoveFromParent(duplicateNameOp);
2225mlirBlockAppendOwnedOperation(moduleBody, duplicateNameOp);
2226MlirAttribute newName = mlirSymbolTableInsert(symbolTable, duplicateNameOp);
2227MlirStringRef newNameStr = mlirStringAttrGetValue(newName);
2228if (mlirStringRefEqual(newNameStr, mlirStringRefCreateFromCString("foo")))
2229return 7;
2230MlirAttribute updatedName = mlirOperationGetAttributeByName(
2231duplicateNameOp, mlirSymbolTableGetSymbolAttributeName());
2232if (!mlirAttributeEqual(updatedName, newName))
2233return 8;
2234
2235mlirOperationDump(mlirModuleGetOperation(module));
2236mlirOperationDump(mlirModuleGetOperation(otherModule));
2237// clang-format off
2238// CHECK-LABEL: @testSymbolTable
2239// CHECK: module
2240// CHECK: func private @foo
2241// CHECK: func private @qux
2242// CHECK: func private @foo{{.+}}
2243// CHECK: module
2244// CHECK-NOT: @qux
2245// CHECK-NOT: @foo
2246// clang-format on
2247
2248mlirSymbolTableDestroy(symbolTable);
2249mlirModuleDestroy(module);
2250mlirModuleDestroy(otherModule);
2251
2252return 0;
2253}
2254
2255typedef struct {
2256const char *x;
2257} callBackData;
2258
2259MlirWalkResult walkCallBack(MlirOperation op, void *rootOpVoid) {
2260fprintf(stderr, "%s: %s\n", ((callBackData *)(rootOpVoid))->x,
2261mlirIdentifierStr(mlirOperationGetName(op)).data);
2262return MlirWalkResultAdvance;
2263}
2264
2265MlirWalkResult walkCallBackTestWalkResult(MlirOperation op, void *rootOpVoid) {
2266fprintf(stderr, "%s: %s\n", ((callBackData *)(rootOpVoid))->x,
2267mlirIdentifierStr(mlirOperationGetName(op)).data);
2268if (strcmp(mlirIdentifierStr(mlirOperationGetName(op)).data, "func.func") ==
22690)
2270return MlirWalkResultSkip;
2271if (strcmp(mlirIdentifierStr(mlirOperationGetName(op)).data, "arith.addi") ==
22720)
2273return MlirWalkResultInterrupt;
2274return MlirWalkResultAdvance;
2275}
2276
2277int testOperationWalk(MlirContext ctx) {
2278// CHECK-LABEL: @testOperationWalk
2279fprintf(stderr, "@testOperationWalk\n");
2280
2281const char *moduleString = "module {\n"
2282" func.func @foo() {\n"
2283" %1 = arith.constant 10: i32\n"
2284" arith.addi %1, %1: i32\n"
2285" return\n"
2286" }\n"
2287" func.func @bar() {\n"
2288" return\n"
2289" }\n"
2290"}";
2291MlirModule module =
2292mlirModuleCreateParse(ctx, mlirStringRefCreateFromCString(moduleString));
2293
2294callBackData data;
2295data.x = "i love you";
2296
2297// CHECK-NEXT: i love you: arith.constant
2298// CHECK-NEXT: i love you: arith.addi
2299// CHECK-NEXT: i love you: func.return
2300// CHECK-NEXT: i love you: func.func
2301// CHECK-NEXT: i love you: func.return
2302// CHECK-NEXT: i love you: func.func
2303// CHECK-NEXT: i love you: builtin.module
2304mlirOperationWalk(mlirModuleGetOperation(module), walkCallBack,
2305(void *)(&data), MlirWalkPostOrder);
2306
2307data.x = "i don't love you";
2308// CHECK-NEXT: i don't love you: builtin.module
2309// CHECK-NEXT: i don't love you: func.func
2310// CHECK-NEXT: i don't love you: arith.constant
2311// CHECK-NEXT: i don't love you: arith.addi
2312// CHECK-NEXT: i don't love you: func.return
2313// CHECK-NEXT: i don't love you: func.func
2314// CHECK-NEXT: i don't love you: func.return
2315mlirOperationWalk(mlirModuleGetOperation(module), walkCallBack,
2316(void *)(&data), MlirWalkPreOrder);
2317
2318data.x = "interrupt";
2319// Interrupted at `arith.addi`
2320// CHECK-NEXT: interrupt: arith.constant
2321// CHECK-NEXT: interrupt: arith.addi
2322mlirOperationWalk(mlirModuleGetOperation(module), walkCallBackTestWalkResult,
2323(void *)(&data), MlirWalkPostOrder);
2324
2325data.x = "skip";
2326// Skip at `func.func`
2327// CHECK-NEXT: skip: builtin.module
2328// CHECK-NEXT: skip: func.func
2329// CHECK-NEXT: skip: func.func
2330mlirOperationWalk(mlirModuleGetOperation(module), walkCallBackTestWalkResult,
2331(void *)(&data), MlirWalkPreOrder);
2332
2333mlirModuleDestroy(module);
2334return 0;
2335}
2336
2337int testDialectRegistry(void) {
2338fprintf(stderr, "@testDialectRegistry\n");
2339
2340MlirDialectRegistry registry = mlirDialectRegistryCreate();
2341if (mlirDialectRegistryIsNull(registry)) {
2342fprintf(stderr, "ERROR: Expected registry to be present\n");
2343return 1;
2344}
2345
2346MlirDialectHandle stdHandle = mlirGetDialectHandle__func__();
2347mlirDialectHandleInsertDialect(stdHandle, registry);
2348
2349MlirContext ctx = mlirContextCreate();
2350if (mlirContextGetNumRegisteredDialects(ctx) != 0) {
2351fprintf(stderr,
2352"ERROR: Expected no dialects to be registered to new context\n");
2353}
2354
2355mlirContextAppendDialectRegistry(ctx, registry);
2356if (mlirContextGetNumRegisteredDialects(ctx) != 1) {
2357fprintf(stderr, "ERROR: Expected the dialect in the registry to be "
2358"registered to the context\n");
2359}
2360
2361mlirContextDestroy(ctx);
2362mlirDialectRegistryDestroy(registry);
2363
2364return 0;
2365}
2366
2367void testExplicitThreadPools(void) {
2368MlirLlvmThreadPool threadPool = mlirLlvmThreadPoolCreate();
2369MlirDialectRegistry registry = mlirDialectRegistryCreate();
2370mlirRegisterAllDialects(registry);
2371MlirContext context =
2372mlirContextCreateWithRegistry(registry, /*threadingEnabled=*/false);
2373mlirContextSetThreadPool(context, threadPool);
2374mlirContextDestroy(context);
2375mlirDialectRegistryDestroy(registry);
2376mlirLlvmThreadPoolDestroy(threadPool);
2377}
2378
2379void testDiagnostics(void) {
2380MlirContext ctx = mlirContextCreate();
2381MlirDiagnosticHandlerID id = mlirContextAttachDiagnosticHandler(
2382ctx, errorHandler, (void *)42, deleteUserData);
2383fprintf(stderr, "@test_diagnostics\n");
2384MlirLocation unknownLoc = mlirLocationUnknownGet(ctx);
2385mlirEmitError(unknownLoc, "test diagnostics");
2386MlirAttribute unknownAttr = mlirLocationGetAttribute(unknownLoc);
2387MlirLocation unknownClone = mlirLocationFromAttribute(unknownAttr);
2388mlirEmitError(unknownClone, "test clone");
2389MlirLocation fileLineColLoc = mlirLocationFileLineColGet(
2390ctx, mlirStringRefCreateFromCString("file.c"), 1, 2);
2391mlirEmitError(fileLineColLoc, "test diagnostics");
2392MlirLocation callSiteLoc = mlirLocationCallSiteGet(
2393mlirLocationFileLineColGet(
2394ctx, mlirStringRefCreateFromCString("other-file.c"), 2, 3),
2395fileLineColLoc);
2396mlirEmitError(callSiteLoc, "test diagnostics");
2397MlirLocation null = {0};
2398MlirLocation nameLoc =
2399mlirLocationNameGet(ctx, mlirStringRefCreateFromCString("named"), null);
2400mlirEmitError(nameLoc, "test diagnostics");
2401MlirLocation locs[2] = {nameLoc, callSiteLoc};
2402MlirAttribute nullAttr = {0};
2403MlirLocation fusedLoc = mlirLocationFusedGet(ctx, 2, locs, nullAttr);
2404mlirEmitError(fusedLoc, "test diagnostics");
2405mlirContextDetachDiagnosticHandler(ctx, id);
2406mlirEmitError(unknownLoc, "more test diagnostics");
2407// CHECK-LABEL: @test_diagnostics
2408// CHECK: processing diagnostic (userData: 42) <<
2409// CHECK: test diagnostics
2410// CHECK: loc(unknown)
2411// CHECK: processing diagnostic (userData: 42) <<
2412// CHECK: test clone
2413// CHECK: loc(unknown)
2414// CHECK: >> end of diagnostic (userData: 42)
2415// CHECK: processing diagnostic (userData: 42) <<
2416// CHECK: test diagnostics
2417// CHECK: loc("file.c":1:2)
2418// CHECK: >> end of diagnostic (userData: 42)
2419// CHECK: processing diagnostic (userData: 42) <<
2420// CHECK: test diagnostics
2421// CHECK: loc(callsite("other-file.c":2:3 at "file.c":1:2))
2422// CHECK: >> end of diagnostic (userData: 42)
2423// CHECK: processing diagnostic (userData: 42) <<
2424// CHECK: test diagnostics
2425// CHECK: loc("named")
2426// CHECK: >> end of diagnostic (userData: 42)
2427// CHECK: processing diagnostic (userData: 42) <<
2428// CHECK: test diagnostics
2429// CHECK: loc(fused["named", callsite("other-file.c":2:3 at "file.c":1:2)])
2430// CHECK: deleting user data (userData: 42)
2431// CHECK-NOT: processing diagnostic
2432// CHECK: more test diagnostics
2433mlirContextDestroy(ctx);
2434}
2435
2436int main(void) {
2437MlirContext ctx = mlirContextCreate();
2438registerAllUpstreamDialects(ctx);
2439mlirContextGetOrLoadDialect(ctx, mlirStringRefCreateFromCString("func"));
2440mlirContextGetOrLoadDialect(ctx, mlirStringRefCreateFromCString("memref"));
2441mlirContextGetOrLoadDialect(ctx, mlirStringRefCreateFromCString("shape"));
2442mlirContextGetOrLoadDialect(ctx, mlirStringRefCreateFromCString("scf"));
2443
2444if (constructAndTraverseIr(ctx))
2445return 1;
2446buildWithInsertionsAndPrint(ctx);
2447if (createOperationWithTypeInference(ctx))
2448return 2;
2449
2450if (printBuiltinTypes(ctx))
2451return 3;
2452if (printBuiltinAttributes(ctx))
2453return 4;
2454if (printAffineMap(ctx))
2455return 5;
2456if (printAffineExpr(ctx))
2457return 6;
2458if (affineMapFromExprs(ctx))
2459return 7;
2460if (printIntegerSet(ctx))
2461return 8;
2462if (registerOnlyStd())
2463return 9;
2464if (testBackreferences())
2465return 10;
2466if (testOperands())
2467return 11;
2468if (testClone())
2469return 12;
2470if (testTypeID(ctx))
2471return 13;
2472if (testSymbolTable(ctx))
2473return 14;
2474if (testDialectRegistry())
2475return 15;
2476if (testOperationWalk(ctx))
2477return 16;
2478
2479testExplicitThreadPools();
2480testDiagnostics();
2481
2482// CHECK: DESTROY MAIN CONTEXT
2483// CHECK: reportResourceDelete: resource_i64_blob
2484fprintf(stderr, "DESTROY MAIN CONTEXT\n");
2485mlirContextDestroy(ctx);
2486
2487return 0;
2488}
2489