1 //===- ir.c - Simple test of C APIs ---------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8 //===----------------------------------------------------------------------===//
10 /* RUN: mlir-capi-ir-test 2>&1 | FileCheck %s
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"
31 static void registerAllUpstreamDialects(MlirContext ctx
) {
32 MlirDialectRegistry registry
= mlirDialectRegistryCreate();
33 mlirRegisterAllDialects(registry
);
34 mlirContextAppendDialectRegistry(ctx
, registry
);
35 mlirDialectRegistryDestroy(registry
);
38 struct ResourceDeleteUserData
{
41 static struct ResourceDeleteUserData resourceI64BlobUserData
= {
43 static void reportResourceDelete(void *userData
, const void *data
, size_t size
,
45 fprintf(stderr
, "reportResourceDelete: %s\n",
46 ((struct ResourceDeleteUserData
*)userData
)->name
);
49 void populateLoopBody(MlirContext ctx
, MlirBlock loopBody
,
50 MlirLocation location
, MlirBlock funcBody
) {
51 MlirValue iv
= mlirBlockGetArgument(loopBody
, 0);
52 MlirValue funcArg0
= mlirBlockGetArgument(funcBody
, 0);
53 MlirValue funcArg1
= mlirBlockGetArgument(funcBody
, 1);
55 mlirTypeParseGet(ctx
, mlirStringRefCreateFromCString("f32"));
57 MlirOperationState loadLHSState
= mlirOperationStateGet(
58 mlirStringRefCreateFromCString("memref.load"), location
);
59 MlirValue loadLHSOperands
[] = {funcArg0
, iv
};
60 mlirOperationStateAddOperands(&loadLHSState
, 2, loadLHSOperands
);
61 mlirOperationStateAddResults(&loadLHSState
, 1, &f32Type
);
62 MlirOperation loadLHS
= mlirOperationCreate(&loadLHSState
);
63 mlirBlockAppendOwnedOperation(loopBody
, loadLHS
);
65 MlirOperationState loadRHSState
= mlirOperationStateGet(
66 mlirStringRefCreateFromCString("memref.load"), location
);
67 MlirValue loadRHSOperands
[] = {funcArg1
, iv
};
68 mlirOperationStateAddOperands(&loadRHSState
, 2, loadRHSOperands
);
69 mlirOperationStateAddResults(&loadRHSState
, 1, &f32Type
);
70 MlirOperation loadRHS
= mlirOperationCreate(&loadRHSState
);
71 mlirBlockAppendOwnedOperation(loopBody
, loadRHS
);
73 MlirOperationState addState
= mlirOperationStateGet(
74 mlirStringRefCreateFromCString("arith.addf"), location
);
75 MlirValue addOperands
[] = {mlirOperationGetResult(loadLHS
, 0),
76 mlirOperationGetResult(loadRHS
, 0)};
77 mlirOperationStateAddOperands(&addState
, 2, addOperands
);
78 mlirOperationStateAddResults(&addState
, 1, &f32Type
);
79 MlirOperation add
= mlirOperationCreate(&addState
);
80 mlirBlockAppendOwnedOperation(loopBody
, add
);
82 MlirOperationState storeState
= mlirOperationStateGet(
83 mlirStringRefCreateFromCString("memref.store"), location
);
84 MlirValue storeOperands
[] = {mlirOperationGetResult(add
, 0), funcArg0
, iv
};
85 mlirOperationStateAddOperands(&storeState
, 3, storeOperands
);
86 MlirOperation store
= mlirOperationCreate(&storeState
);
87 mlirBlockAppendOwnedOperation(loopBody
, store
);
89 MlirOperationState yieldState
= mlirOperationStateGet(
90 mlirStringRefCreateFromCString("scf.yield"), location
);
91 MlirOperation yield
= mlirOperationCreate(&yieldState
);
92 mlirBlockAppendOwnedOperation(loopBody
, yield
);
95 MlirModule
makeAndDumpAdd(MlirContext ctx
, MlirLocation location
) {
96 MlirModule moduleOp
= mlirModuleCreateEmpty(location
);
97 MlirBlock moduleBody
= mlirModuleGetBody(moduleOp
);
100 mlirTypeParseGet(ctx
, mlirStringRefCreateFromCString("memref<?xf32>"));
101 MlirType funcBodyArgTypes
[] = {memrefType
, memrefType
};
102 MlirLocation funcBodyArgLocs
[] = {location
, location
};
103 MlirRegion funcBodyRegion
= mlirRegionCreate();
105 mlirBlockCreate(sizeof(funcBodyArgTypes
) / sizeof(MlirType
),
106 funcBodyArgTypes
, funcBodyArgLocs
);
107 mlirRegionAppendOwnedBlock(funcBodyRegion
, funcBody
);
109 MlirAttribute funcTypeAttr
= mlirAttributeParseGet(
111 mlirStringRefCreateFromCString("(memref<?xf32>, memref<?xf32>) -> ()"));
112 MlirAttribute funcNameAttr
=
113 mlirAttributeParseGet(ctx
, mlirStringRefCreateFromCString("\"add\""));
114 MlirNamedAttribute funcAttrs
[] = {
115 mlirNamedAttributeGet(
116 mlirIdentifierGet(ctx
,
117 mlirStringRefCreateFromCString("function_type")),
119 mlirNamedAttributeGet(
120 mlirIdentifierGet(ctx
, mlirStringRefCreateFromCString("sym_name")),
122 MlirOperationState funcState
= mlirOperationStateGet(
123 mlirStringRefCreateFromCString("func.func"), location
);
124 mlirOperationStateAddAttributes(&funcState
, 2, funcAttrs
);
125 mlirOperationStateAddOwnedRegions(&funcState
, 1, &funcBodyRegion
);
126 MlirOperation func
= mlirOperationCreate(&funcState
);
127 mlirBlockInsertOwnedOperation(moduleBody
, 0, func
);
130 mlirTypeParseGet(ctx
, mlirStringRefCreateFromCString("index"));
131 MlirAttribute indexZeroLiteral
=
132 mlirAttributeParseGet(ctx
, mlirStringRefCreateFromCString("0 : index"));
133 MlirNamedAttribute indexZeroValueAttr
= mlirNamedAttributeGet(
134 mlirIdentifierGet(ctx
, mlirStringRefCreateFromCString("value")),
136 MlirOperationState constZeroState
= mlirOperationStateGet(
137 mlirStringRefCreateFromCString("arith.constant"), location
);
138 mlirOperationStateAddResults(&constZeroState
, 1, &indexType
);
139 mlirOperationStateAddAttributes(&constZeroState
, 1, &indexZeroValueAttr
);
140 MlirOperation constZero
= mlirOperationCreate(&constZeroState
);
141 mlirBlockAppendOwnedOperation(funcBody
, constZero
);
143 MlirValue funcArg0
= mlirBlockGetArgument(funcBody
, 0);
144 MlirValue constZeroValue
= mlirOperationGetResult(constZero
, 0);
145 MlirValue dimOperands
[] = {funcArg0
, constZeroValue
};
146 MlirOperationState dimState
= mlirOperationStateGet(
147 mlirStringRefCreateFromCString("memref.dim"), location
);
148 mlirOperationStateAddOperands(&dimState
, 2, dimOperands
);
149 mlirOperationStateAddResults(&dimState
, 1, &indexType
);
150 MlirOperation dim
= mlirOperationCreate(&dimState
);
151 mlirBlockAppendOwnedOperation(funcBody
, dim
);
153 MlirRegion loopBodyRegion
= mlirRegionCreate();
154 MlirBlock loopBody
= mlirBlockCreate(0, NULL
, NULL
);
155 mlirBlockAddArgument(loopBody
, indexType
, location
);
156 mlirRegionAppendOwnedBlock(loopBodyRegion
, loopBody
);
158 MlirAttribute indexOneLiteral
=
159 mlirAttributeParseGet(ctx
, mlirStringRefCreateFromCString("1 : index"));
160 MlirNamedAttribute indexOneValueAttr
= mlirNamedAttributeGet(
161 mlirIdentifierGet(ctx
, mlirStringRefCreateFromCString("value")),
163 MlirOperationState constOneState
= mlirOperationStateGet(
164 mlirStringRefCreateFromCString("arith.constant"), location
);
165 mlirOperationStateAddResults(&constOneState
, 1, &indexType
);
166 mlirOperationStateAddAttributes(&constOneState
, 1, &indexOneValueAttr
);
167 MlirOperation constOne
= mlirOperationCreate(&constOneState
);
168 mlirBlockAppendOwnedOperation(funcBody
, constOne
);
170 MlirValue dimValue
= mlirOperationGetResult(dim
, 0);
171 MlirValue constOneValue
= mlirOperationGetResult(constOne
, 0);
172 MlirValue loopOperands
[] = {constZeroValue
, dimValue
, constOneValue
};
173 MlirOperationState loopState
= mlirOperationStateGet(
174 mlirStringRefCreateFromCString("scf.for"), location
);
175 mlirOperationStateAddOperands(&loopState
, 3, loopOperands
);
176 mlirOperationStateAddOwnedRegions(&loopState
, 1, &loopBodyRegion
);
177 MlirOperation loop
= mlirOperationCreate(&loopState
);
178 mlirBlockAppendOwnedOperation(funcBody
, loop
);
180 populateLoopBody(ctx
, loopBody
, location
, funcBody
);
182 MlirOperationState retState
= mlirOperationStateGet(
183 mlirStringRefCreateFromCString("func.return"), location
);
184 MlirOperation ret
= mlirOperationCreate(&retState
);
185 mlirBlockAppendOwnedOperation(funcBody
, ret
);
187 MlirOperation module
= mlirModuleGetOperation(moduleOp
);
188 mlirOperationDump(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>
211 struct OpListNode
*next
;
213 typedef struct OpListNode OpListNode
;
216 unsigned numOperations
;
217 unsigned numAttributes
;
221 unsigned numBlockArguments
;
222 unsigned numOpResults
;
224 typedef struct ModuleStats ModuleStats
;
226 int collectStatsSingle(OpListNode
*head
, ModuleStats
*stats
) {
227 MlirOperation operation
= head
->op
;
228 stats
->numOperations
+= 1;
229 stats
->numValues
+= mlirOperationGetNumResults(operation
);
230 stats
->numAttributes
+= mlirOperationGetNumAttributes(operation
);
232 unsigned numRegions
= mlirOperationGetNumRegions(operation
);
234 stats
->numRegions
+= numRegions
;
236 intptr_t numResults
= mlirOperationGetNumResults(operation
);
237 for (intptr_t i
= 0; i
< numResults
; ++i
) {
238 MlirValue result
= mlirOperationGetResult(operation
, i
);
239 if (!mlirValueIsAOpResult(result
))
241 if (mlirValueIsABlockArgument(result
))
243 if (!mlirOperationEqual(operation
, mlirOpResultGetOwner(result
)))
245 if (i
!= mlirOpResultGetResultNumber(result
))
247 ++stats
->numOpResults
;
250 MlirRegion region
= mlirOperationGetFirstRegion(operation
);
251 while (!mlirRegionIsNull(region
)) {
252 for (MlirBlock block
= mlirRegionGetFirstBlock(region
);
253 !mlirBlockIsNull(block
); block
= mlirBlockGetNextInRegion(block
)) {
255 intptr_t numArgs
= mlirBlockGetNumArguments(block
);
256 stats
->numValues
+= numArgs
;
257 for (intptr_t j
= 0; j
< numArgs
; ++j
) {
258 MlirValue arg
= mlirBlockGetArgument(block
, j
);
259 if (!mlirValueIsABlockArgument(arg
))
261 if (mlirValueIsAOpResult(arg
))
263 if (!mlirBlockEqual(block
, mlirBlockArgumentGetOwner(arg
)))
265 if (j
!= mlirBlockArgumentGetArgNumber(arg
))
267 ++stats
->numBlockArguments
;
270 for (MlirOperation child
= mlirBlockGetFirstOperation(block
);
271 !mlirOperationIsNull(child
);
272 child
= mlirOperationGetNextInBlock(child
)) {
273 OpListNode
*node
= malloc(sizeof(OpListNode
));
275 node
->next
= head
->next
;
279 region
= mlirRegionGetNextInOperation(region
);
284 int collectStats(MlirOperation operation
) {
285 OpListNode
*head
= malloc(sizeof(OpListNode
));
286 head
->op
= operation
;
290 stats
.numOperations
= 0;
291 stats
.numAttributes
= 0;
293 stats
.numRegions
= 0;
295 stats
.numBlockArguments
= 0;
296 stats
.numOpResults
= 0;
299 int retval
= collectStatsSingle(head
, &stats
);
304 OpListNode
*next
= head
->next
;
309 if (stats
.numValues
!= stats
.numBlockArguments
+ stats
.numOpResults
)
312 fprintf(stderr
, "@stats\n");
313 fprintf(stderr
, "Number of operations: %u\n", stats
.numOperations
);
314 fprintf(stderr
, "Number of attributes: %u\n", stats
.numAttributes
);
315 fprintf(stderr
, "Number of blocks: %u\n", stats
.numBlocks
);
316 fprintf(stderr
, "Number of regions: %u\n", stats
.numRegions
);
317 fprintf(stderr
, "Number of values: %u\n", stats
.numValues
);
318 fprintf(stderr
, "Number of block arguments: %u\n", stats
.numBlockArguments
);
319 fprintf(stderr
, "Number of op results: %u\n", stats
.numOpResults
);
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
333 static void printToStderr(MlirStringRef str
, void *userData
) {
335 fwrite(str
.data
, 1, str
.length
, stderr
);
338 static void printFirstOfEach(MlirContext ctx
, MlirOperation operation
) {
339 // Assuming we are given a module, go to the first operation of the first
341 MlirRegion region
= mlirOperationGetRegion(operation
, 0);
342 MlirBlock block
= mlirRegionGetFirstBlock(region
);
343 operation
= mlirBlockGetFirstOperation(block
);
344 region
= mlirOperationGetRegion(operation
, 0);
345 MlirOperation parentOperation
= operation
;
346 block
= mlirRegionGetFirstBlock(region
);
347 operation
= mlirBlockGetFirstOperation(block
);
348 assert(mlirModuleIsNull(mlirModuleFromOperation(operation
)));
350 // Verify that parent operation and block report correctly.
351 // CHECK: Parent operation eq: 1
352 fprintf(stderr
, "Parent operation eq: %d\n",
353 mlirOperationEqual(mlirOperationGetParentOperation(operation
),
355 // CHECK: Block eq: 1
356 fprintf(stderr
, "Block eq: %d\n",
357 mlirBlockEqual(mlirOperationGetBlock(operation
), block
));
358 // CHECK: Block parent operation eq: 1
360 stderr
, "Block parent operation eq: %d\n",
361 mlirOperationEqual(mlirBlockGetParentOperation(block
), parentOperation
));
362 // CHECK: Block parent region eq: 1
363 fprintf(stderr
, "Block parent region eq: %d\n",
364 mlirRegionEqual(mlirBlockGetParentRegion(block
), region
));
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.
369 mlirBlockPrint(block
, printToStderr
, NULL
);
370 fprintf(stderr
, "\n");
371 fprintf(stderr
, "First operation: ");
372 mlirOperationPrint(operation
, printToStderr
, NULL
);
373 fprintf(stderr
, "\n");
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>
385 // CHECK: First operation: {{.*}} = arith.constant 0 : index
388 // Get the operation name and print it.
389 MlirIdentifier ident
= mlirOperationGetName(operation
);
390 MlirStringRef identStr
= mlirIdentifierStr(ident
);
391 fprintf(stderr
, "Operation name: '");
392 for (size_t i
= 0; i
< identStr
.length
; ++i
)
393 fputc(identStr
.data
[i
], stderr
);
394 fprintf(stderr
, "'\n");
395 // CHECK: Operation name: 'arith.constant'
397 // Get the identifier again and verify equal.
398 MlirIdentifier identAgain
= mlirIdentifierGet(ctx
, identStr
);
399 fprintf(stderr
, "Identifier equal: %d\n",
400 mlirIdentifierEqual(ident
, identAgain
));
401 // CHECK: Identifier equal: 1
403 // Get the block terminator and print it.
404 MlirOperation terminator
= mlirBlockGetTerminator(block
);
405 fprintf(stderr
, "Terminator: ");
406 mlirOperationPrint(terminator
, printToStderr
, NULL
);
407 fprintf(stderr
, "\n");
408 // CHECK: Terminator: func.return
410 // Get the attribute by name.
411 bool hasValueAttr
= mlirOperationHasInherentAttributeByName(
412 operation
, mlirStringRefCreateFromCString("value"));
414 // CHECK: Has attr "value"
415 fprintf(stderr
, "Has attr \"value\"");
417 MlirAttribute valueAttr0
= mlirOperationGetInherentAttributeByName(
418 operation
, mlirStringRefCreateFromCString("value"));
419 fprintf(stderr
, "Get attr \"value\": ");
420 mlirAttributePrint(valueAttr0
, printToStderr
, NULL
);
421 fprintf(stderr
, "\n");
422 // CHECK: Get attr "value": 0 : index
424 // Get a non-existing attribute and assert that it is null (sanity).
425 fprintf(stderr
, "does_not_exist is null: %d\n",
426 mlirAttributeIsNull(mlirOperationGetDiscardableAttributeByName(
427 operation
, mlirStringRefCreateFromCString("does_not_exist"))));
428 // CHECK: does_not_exist is null: 1
430 // Get result 0 and its type.
431 MlirValue value
= mlirOperationGetResult(operation
, 0);
432 fprintf(stderr
, "Result 0: ");
433 mlirValuePrint(value
, printToStderr
, NULL
);
434 fprintf(stderr
, "\n");
435 fprintf(stderr
, "Value is null: %d\n", mlirValueIsNull(value
));
436 // CHECK: Result 0: {{.*}} = arith.constant 0 : index
437 // CHECK: Value is null: 0
439 MlirType type
= mlirValueGetType(value
);
440 fprintf(stderr
, "Result 0 type: ");
441 mlirTypePrint(type
, printToStderr
, NULL
);
442 fprintf(stderr
, "\n");
443 // CHECK: Result 0 type: index
445 // Set a discardable attribute.
446 mlirOperationSetDiscardableAttributeByName(
447 operation
, mlirStringRefCreateFromCString("custom_attr"),
448 mlirBoolAttrGet(ctx
, 1));
449 fprintf(stderr
, "Op with set attr: ");
450 mlirOperationPrint(operation
, printToStderr
, NULL
);
451 fprintf(stderr
, "\n");
452 // CHECK: Op with set attr: {{.*}} {custom_attr = true}
454 // Remove the attribute.
455 fprintf(stderr
, "Remove attr: %d\n",
456 mlirOperationRemoveDiscardableAttributeByName(
457 operation
, mlirStringRefCreateFromCString("custom_attr")));
458 fprintf(stderr
, "Remove attr again: %d\n",
459 mlirOperationRemoveDiscardableAttributeByName(
460 operation
, mlirStringRefCreateFromCString("custom_attr")));
461 fprintf(stderr
, "Removed attr is null: %d\n",
462 mlirAttributeIsNull(mlirOperationGetDiscardableAttributeByName(
463 operation
, mlirStringRefCreateFromCString("custom_attr"))));
464 // CHECK: Remove attr: 1
465 // CHECK: Remove attr again: 0
466 // CHECK: Removed attr is null: 1
468 // Add a large attribute to verify printing flags.
469 int64_t eltsShape
[] = {4};
470 int32_t eltsData
[] = {1, 2, 3, 4};
471 mlirOperationSetDiscardableAttributeByName(
472 operation
, mlirStringRefCreateFromCString("elts"),
473 mlirDenseElementsAttrInt32Get(
474 mlirRankedTensorTypeGet(1, eltsShape
, mlirIntegerTypeGet(ctx
, 32),
475 mlirAttributeGetNull()),
477 MlirOpPrintingFlags flags
= mlirOpPrintingFlagsCreate();
478 mlirOpPrintingFlagsElideLargeElementsAttrs(flags
, 2);
479 mlirOpPrintingFlagsPrintGenericOpForm(flags
);
480 mlirOpPrintingFlagsEnableDebugInfo(flags
, /*enable=*/1, /*prettyForm=*/0);
481 mlirOpPrintingFlagsUseLocalScope(flags
);
482 fprintf(stderr
, "Op print with all flags: ");
483 mlirOperationPrintWithFlags(operation
, flags
, printToStderr
, NULL
);
484 fprintf(stderr
, "\n");
486 // CHECK: Op print with all flags: %{{.*}} = "arith.constant"() <{value = 0 : index}> {elts = dense_resource<__elided__> : tensor<4xi32>} : () -> index loc(unknown)
489 MlirAsmState state
= mlirAsmStateCreateForOperation(parentOperation
, flags
);
490 fprintf(stderr
, "With state: |");
491 mlirValuePrintAsOperand(value
, state
, printToStderr
, NULL
);
492 // CHECK: With state: |%0|
493 fprintf(stderr
, "|\n");
494 mlirAsmStateDestroy(state
);
496 mlirOpPrintingFlagsDestroy(flags
);
499 static int constructAndTraverseIr(MlirContext ctx
) {
500 MlirLocation location
= mlirLocationUnknownGet(ctx
);
502 MlirModule moduleOp
= makeAndDumpAdd(ctx
, location
);
503 MlirOperation module
= mlirModuleGetOperation(moduleOp
);
504 assert(!mlirModuleIsNull(mlirModuleFromOperation(module
)));
506 int errcode
= collectStats(module
);
510 printFirstOfEach(ctx
, module
);
512 mlirModuleDestroy(moduleOp
);
516 /// Creates an operation with a region containing multiple blocks with
517 /// operations and dumps it. The blocks and operations are inserted using
518 /// block/operation-relative API and their final order is checked.
519 static void buildWithInsertionsAndPrint(MlirContext ctx
) {
520 MlirLocation loc
= mlirLocationUnknownGet(ctx
);
521 mlirContextSetAllowUnregisteredDialects(ctx
, true);
523 MlirRegion owningRegion
= mlirRegionCreate();
524 MlirBlock nullBlock
= mlirRegionGetFirstBlock(owningRegion
);
525 MlirOperationState state
= mlirOperationStateGet(
526 mlirStringRefCreateFromCString("insertion.order.test"), loc
);
527 mlirOperationStateAddOwnedRegions(&state
, 1, &owningRegion
);
528 MlirOperation op
= mlirOperationCreate(&state
);
529 MlirRegion region
= mlirOperationGetRegion(op
, 0);
531 // Use integer types of different bitwidth as block arguments in order to
532 // differentiate blocks.
533 MlirType i1
= mlirIntegerTypeGet(ctx
, 1);
534 MlirType i2
= mlirIntegerTypeGet(ctx
, 2);
535 MlirType i3
= mlirIntegerTypeGet(ctx
, 3);
536 MlirType i4
= mlirIntegerTypeGet(ctx
, 4);
537 MlirType i5
= mlirIntegerTypeGet(ctx
, 5);
538 MlirBlock block1
= mlirBlockCreate(1, &i1
, &loc
);
539 MlirBlock block2
= mlirBlockCreate(1, &i2
, &loc
);
540 MlirBlock block3
= mlirBlockCreate(1, &i3
, &loc
);
541 MlirBlock block4
= mlirBlockCreate(1, &i4
, &loc
);
542 MlirBlock block5
= mlirBlockCreate(1, &i5
, &loc
);
543 // Insert blocks so as to obtain the 1-2-3-4 order,
544 mlirRegionInsertOwnedBlockBefore(region
, nullBlock
, block3
);
545 mlirRegionInsertOwnedBlockBefore(region
, block3
, block2
);
546 mlirRegionInsertOwnedBlockAfter(region
, nullBlock
, block1
);
547 mlirRegionInsertOwnedBlockAfter(region
, block3
, block4
);
548 mlirRegionInsertOwnedBlockBefore(region
, block3
, block5
);
550 MlirOperationState op1State
=
551 mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op1"), loc
);
552 MlirOperationState op2State
=
553 mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op2"), loc
);
554 MlirOperationState op3State
=
555 mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op3"), loc
);
556 MlirOperationState op4State
=
557 mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op4"), loc
);
558 MlirOperationState op5State
=
559 mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op5"), loc
);
560 MlirOperationState op6State
=
561 mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op6"), loc
);
562 MlirOperationState op7State
=
563 mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op7"), loc
);
564 MlirOperationState op8State
=
565 mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op8"), loc
);
566 MlirOperation op1
= mlirOperationCreate(&op1State
);
567 MlirOperation op2
= mlirOperationCreate(&op2State
);
568 MlirOperation op3
= mlirOperationCreate(&op3State
);
569 MlirOperation op4
= mlirOperationCreate(&op4State
);
570 MlirOperation op5
= mlirOperationCreate(&op5State
);
571 MlirOperation op6
= mlirOperationCreate(&op6State
);
572 MlirOperation op7
= mlirOperationCreate(&op7State
);
573 MlirOperation op8
= mlirOperationCreate(&op8State
);
575 // Insert operations in the first block so as to obtain the 1-2-3-4 order.
576 MlirOperation nullOperation
= mlirBlockGetFirstOperation(block1
);
577 assert(mlirOperationIsNull(nullOperation
));
578 mlirBlockInsertOwnedOperationBefore(block1
, nullOperation
, op3
);
579 mlirBlockInsertOwnedOperationBefore(block1
, op3
, op2
);
580 mlirBlockInsertOwnedOperationAfter(block1
, nullOperation
, op1
);
581 mlirBlockInsertOwnedOperationAfter(block1
, op3
, op4
);
583 // Append operations to the rest of blocks to make them non-empty and thus
585 mlirBlockAppendOwnedOperation(block2
, op5
);
586 mlirBlockAppendOwnedOperation(block3
, op6
);
587 mlirBlockAppendOwnedOperation(block4
, op7
);
588 mlirBlockAppendOwnedOperation(block5
, op8
);
591 mlirBlockDetach(block5
);
592 mlirBlockDestroy(block5
);
594 mlirOperationDump(op
);
595 mlirOperationDestroy(op
);
596 mlirContextSetAllowUnregisteredDialects(ctx
, false);
598 // CHECK-LABEL: "insertion.order.test"
599 // CHECK: ^{{.*}}(%{{.*}}: i1
600 // CHECK: "dummy.op1"
601 // CHECK-NEXT: "dummy.op2"
602 // CHECK-NEXT: "dummy.op3"
603 // CHECK-NEXT: "dummy.op4"
604 // CHECK: ^{{.*}}(%{{.*}}: i2
605 // CHECK: "dummy.op5"
606 // CHECK-NOT: ^{{.*}}(%{{.*}}: i5
607 // CHECK-NOT: "dummy.op8"
608 // CHECK: ^{{.*}}(%{{.*}}: i3
609 // CHECK: "dummy.op6"
610 // CHECK: ^{{.*}}(%{{.*}}: i4
611 // CHECK: "dummy.op7"
615 /// Creates operations with type inference and tests various failure modes.
616 static int createOperationWithTypeInference(MlirContext ctx
) {
617 MlirLocation loc
= mlirLocationUnknownGet(ctx
);
618 MlirAttribute iAttr
= mlirIntegerAttrGet(mlirIntegerTypeGet(ctx
, 32), 4);
620 // The shape.const_size op implements result type inference and is only used
622 MlirOperationState state
= mlirOperationStateGet(
623 mlirStringRefCreateFromCString("shape.const_size"), loc
);
624 MlirNamedAttribute valueAttr
= mlirNamedAttributeGet(
625 mlirIdentifierGet(ctx
, mlirStringRefCreateFromCString("value")), iAttr
);
626 mlirOperationStateAddAttributes(&state
, 1, &valueAttr
);
627 mlirOperationStateEnableResultTypeInference(&state
);
629 // Expect result type inference to succeed.
630 MlirOperation op
= mlirOperationCreate(&state
);
631 if (mlirOperationIsNull(op
)) {
632 fprintf(stderr
, "ERROR: Result type inference unexpectedly failed");
636 // CHECK: RESULT_TYPE_INFERENCE: !shape.size
637 fprintf(stderr
, "RESULT_TYPE_INFERENCE: ");
638 mlirTypeDump(mlirValueGetType(mlirOperationGetResult(op
, 0)));
639 fprintf(stderr
, "\n");
640 mlirOperationDestroy(op
);
644 /// Dumps instances of all builtin types to check that C API works correctly.
645 /// Additionally, performs simple identity checks that a builtin type
646 /// constructed with C API can be inspected and has the expected type. The
647 /// latter achieves full coverage of C API for builtin types. Returns 0 on
648 /// success and a non-zero error code on failure.
649 static int printBuiltinTypes(MlirContext ctx
) {
651 MlirType i32
= mlirIntegerTypeGet(ctx
, 32);
652 MlirType si32
= mlirIntegerTypeSignedGet(ctx
, 32);
653 MlirType ui32
= mlirIntegerTypeUnsignedGet(ctx
, 32);
654 if (!mlirTypeIsAInteger(i32
) || mlirTypeIsAF32(i32
))
656 if (!mlirTypeIsAInteger(si32
) || !mlirIntegerTypeIsSigned(si32
))
658 if (!mlirTypeIsAInteger(ui32
) || !mlirIntegerTypeIsUnsigned(ui32
))
660 if (mlirTypeEqual(i32
, ui32
) || mlirTypeEqual(i32
, si32
))
662 if (mlirIntegerTypeGetWidth(i32
) != mlirIntegerTypeGetWidth(si32
))
664 fprintf(stderr
, "@types\n");
666 fprintf(stderr
, "\n");
668 fprintf(stderr
, "\n");
670 fprintf(stderr
, "\n");
671 // CHECK-LABEL: @types
677 MlirType index
= mlirIndexTypeGet(ctx
);
678 if (!mlirTypeIsAIndex(index
))
681 fprintf(stderr
, "\n");
684 // Floating-point types.
685 MlirType bf16
= mlirBF16TypeGet(ctx
);
686 MlirType f16
= mlirF16TypeGet(ctx
);
687 MlirType f32
= mlirF32TypeGet(ctx
);
688 MlirType f64
= mlirF64TypeGet(ctx
);
689 if (!mlirTypeIsABF16(bf16
))
691 if (!mlirTypeIsAF16(f16
))
693 if (!mlirTypeIsAF32(f32
))
695 if (!mlirTypeIsAF64(f64
))
698 fprintf(stderr
, "\n");
700 fprintf(stderr
, "\n");
702 fprintf(stderr
, "\n");
704 fprintf(stderr
, "\n");
711 MlirType none
= mlirNoneTypeGet(ctx
);
712 if (!mlirTypeIsANone(none
))
715 fprintf(stderr
, "\n");
719 MlirType cplx
= mlirComplexTypeGet(f32
);
720 if (!mlirTypeIsAComplex(cplx
) ||
721 !mlirTypeEqual(mlirComplexTypeGetElementType(cplx
), f32
))
724 fprintf(stderr
, "\n");
725 // CHECK: complex<f32>
727 // Vector (and Shaped) type. ShapedType is a common base class for vectors,
728 // memrefs and tensors, one cannot create instances of this class so it is
729 // tested on an instance of vector type.
730 int64_t shape
[] = {2, 3};
732 mlirVectorTypeGet(sizeof(shape
) / sizeof(int64_t), shape
, f32
);
733 if (!mlirTypeIsAVector(vector
) || !mlirTypeIsAShaped(vector
))
735 if (!mlirTypeEqual(mlirShapedTypeGetElementType(vector
), f32
) ||
736 !mlirShapedTypeHasRank(vector
) || mlirShapedTypeGetRank(vector
) != 2 ||
737 mlirShapedTypeGetDimSize(vector
, 0) != 2 ||
738 mlirShapedTypeIsDynamicDim(vector
, 0) ||
739 mlirShapedTypeGetDimSize(vector
, 1) != 3 ||
740 !mlirShapedTypeHasStaticShape(vector
))
742 mlirTypeDump(vector
);
743 fprintf(stderr
, "\n");
744 // CHECK: vector<2x3xf32>
746 // Ranked tensor type.
747 MlirType rankedTensor
= mlirRankedTensorTypeGet(
748 sizeof(shape
) / sizeof(int64_t), shape
, f32
, mlirAttributeGetNull());
749 if (!mlirTypeIsATensor(rankedTensor
) ||
750 !mlirTypeIsARankedTensor(rankedTensor
) ||
751 !mlirAttributeIsNull(mlirRankedTensorTypeGetEncoding(rankedTensor
)))
753 mlirTypeDump(rankedTensor
);
754 fprintf(stderr
, "\n");
755 // CHECK: tensor<2x3xf32>
757 // Unranked tensor type.
758 MlirType unrankedTensor
= mlirUnrankedTensorTypeGet(f32
);
759 if (!mlirTypeIsATensor(unrankedTensor
) ||
760 !mlirTypeIsAUnrankedTensor(unrankedTensor
) ||
761 mlirShapedTypeHasRank(unrankedTensor
))
763 mlirTypeDump(unrankedTensor
);
764 fprintf(stderr
, "\n");
765 // CHECK: tensor<*xf32>
768 MlirAttribute memSpace2
= mlirIntegerAttrGet(mlirIntegerTypeGet(ctx
, 64), 2);
769 MlirType memRef
= mlirMemRefTypeContiguousGet(
770 f32
, sizeof(shape
) / sizeof(int64_t), shape
, memSpace2
);
771 if (!mlirTypeIsAMemRef(memRef
) ||
772 !mlirAttributeEqual(mlirMemRefTypeGetMemorySpace(memRef
), memSpace2
))
774 mlirTypeDump(memRef
);
775 fprintf(stderr
, "\n");
776 // CHECK: memref<2x3xf32, 2>
778 // Unranked MemRef type.
779 MlirAttribute memSpace4
= mlirIntegerAttrGet(mlirIntegerTypeGet(ctx
, 64), 4);
780 MlirType unrankedMemRef
= mlirUnrankedMemRefTypeGet(f32
, memSpace4
);
781 if (!mlirTypeIsAUnrankedMemRef(unrankedMemRef
) ||
782 mlirTypeIsAMemRef(unrankedMemRef
) ||
783 !mlirAttributeEqual(mlirUnrankedMemrefGetMemorySpace(unrankedMemRef
),
786 mlirTypeDump(unrankedMemRef
);
787 fprintf(stderr
, "\n");
788 // CHECK: memref<*xf32, 4>
791 MlirType types
[] = {unrankedMemRef
, f32
};
792 MlirType tuple
= mlirTupleTypeGet(ctx
, 2, types
);
793 if (!mlirTypeIsATuple(tuple
) || mlirTupleTypeGetNumTypes(tuple
) != 2 ||
794 !mlirTypeEqual(mlirTupleTypeGetType(tuple
, 0), unrankedMemRef
) ||
795 !mlirTypeEqual(mlirTupleTypeGetType(tuple
, 1), f32
))
798 fprintf(stderr
, "\n");
799 // CHECK: tuple<memref<*xf32, 4>, f32>
802 MlirType funcInputs
[2] = {mlirIndexTypeGet(ctx
), mlirIntegerTypeGet(ctx
, 1)};
803 MlirType funcResults
[3] = {mlirIntegerTypeGet(ctx
, 16),
804 mlirIntegerTypeGet(ctx
, 32),
805 mlirIntegerTypeGet(ctx
, 64)};
806 MlirType funcType
= mlirFunctionTypeGet(ctx
, 2, funcInputs
, 3, funcResults
);
807 if (mlirFunctionTypeGetNumInputs(funcType
) != 2)
809 if (mlirFunctionTypeGetNumResults(funcType
) != 3)
811 if (!mlirTypeEqual(funcInputs
[0], mlirFunctionTypeGetInput(funcType
, 0)) ||
812 !mlirTypeEqual(funcInputs
[1], mlirFunctionTypeGetInput(funcType
, 1)))
814 if (!mlirTypeEqual(funcResults
[0], mlirFunctionTypeGetResult(funcType
, 0)) ||
815 !mlirTypeEqual(funcResults
[1], mlirFunctionTypeGetResult(funcType
, 1)) ||
816 !mlirTypeEqual(funcResults
[2], mlirFunctionTypeGetResult(funcType
, 2)))
818 mlirTypeDump(funcType
);
819 fprintf(stderr
, "\n");
820 // CHECK: (index, i1) -> (i16, i32, i64)
823 MlirStringRef
namespace = mlirStringRefCreate("dialect", 7);
824 MlirStringRef data
= mlirStringRefCreate("type", 4);
825 mlirContextSetAllowUnregisteredDialects(ctx
, true);
826 MlirType opaque
= mlirOpaqueTypeGet(ctx
, namespace, data
);
827 mlirContextSetAllowUnregisteredDialects(ctx
, false);
828 if (!mlirTypeIsAOpaque(opaque
) ||
829 !mlirStringRefEqual(mlirOpaqueTypeGetDialectNamespace(opaque
),
831 !mlirStringRefEqual(mlirOpaqueTypeGetData(opaque
), data
))
833 mlirTypeDump(opaque
);
834 fprintf(stderr
, "\n");
835 // CHECK: !dialect.type
840 void callbackSetFixedLengthString(const char *data
, intptr_t len
,
842 strncpy(userData
, data
, len
);
845 bool stringIsEqual(const char *lhs
, MlirStringRef rhs
) {
846 if (strlen(lhs
) != rhs
.length
) {
849 return !strncmp(lhs
, rhs
.data
, rhs
.length
);
852 int printBuiltinAttributes(MlirContext ctx
) {
853 MlirAttribute floating
=
854 mlirFloatAttrDoubleGet(ctx
, mlirF64TypeGet(ctx
), 2.0);
855 if (!mlirAttributeIsAFloat(floating
) ||
856 fabs(mlirFloatAttrGetValueDouble(floating
) - 2.0) > 1E-6)
858 fprintf(stderr
, "@attrs\n");
859 mlirAttributeDump(floating
);
860 // CHECK-LABEL: @attrs
861 // CHECK: 2.000000e+00 : f64
863 // Exercise mlirAttributeGetType() just for the first one.
864 MlirType floatingType
= mlirAttributeGetType(floating
);
865 mlirTypeDump(floatingType
);
868 MlirAttribute integer
= mlirIntegerAttrGet(mlirIntegerTypeGet(ctx
, 32), 42);
869 MlirAttribute signedInteger
=
870 mlirIntegerAttrGet(mlirIntegerTypeSignedGet(ctx
, 8), -1);
871 MlirAttribute unsignedInteger
=
872 mlirIntegerAttrGet(mlirIntegerTypeUnsignedGet(ctx
, 8), 255);
873 if (!mlirAttributeIsAInteger(integer
) ||
874 mlirIntegerAttrGetValueInt(integer
) != 42 ||
875 mlirIntegerAttrGetValueSInt(signedInteger
) != -1 ||
876 mlirIntegerAttrGetValueUInt(unsignedInteger
) != 255)
878 mlirAttributeDump(integer
);
879 mlirAttributeDump(signedInteger
);
880 mlirAttributeDump(unsignedInteger
);
885 MlirAttribute boolean
= mlirBoolAttrGet(ctx
, 1);
886 if (!mlirAttributeIsABool(boolean
) || !mlirBoolAttrGetValue(boolean
))
888 mlirAttributeDump(boolean
);
891 const char data
[] = "abcdefghijklmnopqestuvwxyz";
892 MlirAttribute opaque
=
893 mlirOpaqueAttrGet(ctx
, mlirStringRefCreateFromCString("func"), 3, data
,
894 mlirNoneTypeGet(ctx
));
895 if (!mlirAttributeIsAOpaque(opaque
) ||
896 !stringIsEqual("func", mlirOpaqueAttrGetDialectNamespace(opaque
)))
899 MlirStringRef opaqueData
= mlirOpaqueAttrGetData(opaque
);
900 if (opaqueData
.length
!= 3 ||
901 strncmp(data
, opaqueData
.data
, opaqueData
.length
))
903 mlirAttributeDump(opaque
);
906 MlirAttribute string
=
907 mlirStringAttrGet(ctx
, mlirStringRefCreate(data
+ 3, 2));
908 if (!mlirAttributeIsAString(string
))
911 MlirStringRef stringValue
= mlirStringAttrGetValue(string
);
912 if (stringValue
.length
!= 2 ||
913 strncmp(data
+ 3, stringValue
.data
, stringValue
.length
))
915 mlirAttributeDump(string
);
918 MlirAttribute flatSymbolRef
=
919 mlirFlatSymbolRefAttrGet(ctx
, mlirStringRefCreate(data
+ 5, 3));
920 if (!mlirAttributeIsAFlatSymbolRef(flatSymbolRef
))
923 MlirStringRef flatSymbolRefValue
=
924 mlirFlatSymbolRefAttrGetValue(flatSymbolRef
);
925 if (flatSymbolRefValue
.length
!= 3 ||
926 strncmp(data
+ 5, flatSymbolRefValue
.data
, flatSymbolRefValue
.length
))
928 mlirAttributeDump(flatSymbolRef
);
931 MlirAttribute symbols
[] = {flatSymbolRef
, flatSymbolRef
};
932 MlirAttribute symbolRef
=
933 mlirSymbolRefAttrGet(ctx
, mlirStringRefCreate(data
+ 8, 2), 2, symbols
);
934 if (!mlirAttributeIsASymbolRef(symbolRef
) ||
935 mlirSymbolRefAttrGetNumNestedReferences(symbolRef
) != 2 ||
936 !mlirAttributeEqual(mlirSymbolRefAttrGetNestedReference(symbolRef
, 0),
938 !mlirAttributeEqual(mlirSymbolRefAttrGetNestedReference(symbolRef
, 1),
942 MlirStringRef symbolRefLeaf
= mlirSymbolRefAttrGetLeafReference(symbolRef
);
943 MlirStringRef symbolRefRoot
= mlirSymbolRefAttrGetRootReference(symbolRef
);
944 if (symbolRefLeaf
.length
!= 3 ||
945 strncmp(data
+ 5, symbolRefLeaf
.data
, symbolRefLeaf
.length
) ||
946 symbolRefRoot
.length
!= 2 ||
947 strncmp(data
+ 8, symbolRefRoot
.data
, symbolRefRoot
.length
))
949 mlirAttributeDump(symbolRef
);
950 // CHECK: @ij::@fgh::@fgh
952 MlirAttribute type
= mlirTypeAttrGet(mlirF32TypeGet(ctx
));
953 if (!mlirAttributeIsAType(type
) ||
954 !mlirTypeEqual(mlirF32TypeGet(ctx
), mlirTypeAttrGetValue(type
)))
956 mlirAttributeDump(type
);
959 MlirAttribute unit
= mlirUnitAttrGet(ctx
);
960 if (!mlirAttributeIsAUnit(unit
))
962 mlirAttributeDump(unit
);
965 int64_t shape
[] = {1, 2};
967 int bools
[] = {0, 1};
968 uint8_t uints8
[] = {0u, 1u};
969 int8_t ints8
[] = {0, 1};
970 uint16_t uints16
[] = {0u, 1u};
971 int16_t ints16
[] = {0, 1};
972 uint32_t uints32
[] = {0u, 1u};
973 int32_t ints32
[] = {0, 1};
974 uint64_t uints64
[] = {0u, 1u};
975 int64_t ints64
[] = {0, 1};
976 float floats
[] = {0.0f
, 1.0f
};
977 double doubles
[] = {0.0, 1.0};
978 uint16_t bf16s
[] = {0x0, 0x3f80};
979 uint16_t f16s
[] = {0x0, 0x3c00};
980 MlirAttribute encoding
= mlirAttributeGetNull();
981 MlirAttribute boolElements
= mlirDenseElementsAttrBoolGet(
982 mlirRankedTensorTypeGet(2, shape
, mlirIntegerTypeGet(ctx
, 1), encoding
),
984 MlirAttribute uint8Elements
= mlirDenseElementsAttrUInt8Get(
985 mlirRankedTensorTypeGet(2, shape
, mlirIntegerTypeUnsignedGet(ctx
, 8),
988 MlirAttribute int8Elements
= mlirDenseElementsAttrInt8Get(
989 mlirRankedTensorTypeGet(2, shape
, mlirIntegerTypeGet(ctx
, 8), encoding
),
991 MlirAttribute uint16Elements
= mlirDenseElementsAttrUInt16Get(
992 mlirRankedTensorTypeGet(2, shape
, mlirIntegerTypeUnsignedGet(ctx
, 16),
995 MlirAttribute int16Elements
= mlirDenseElementsAttrInt16Get(
996 mlirRankedTensorTypeGet(2, shape
, mlirIntegerTypeGet(ctx
, 16), encoding
),
998 MlirAttribute uint32Elements
= mlirDenseElementsAttrUInt32Get(
999 mlirRankedTensorTypeGet(2, shape
, mlirIntegerTypeUnsignedGet(ctx
, 32),
1002 MlirAttribute int32Elements
= mlirDenseElementsAttrInt32Get(
1003 mlirRankedTensorTypeGet(2, shape
, mlirIntegerTypeGet(ctx
, 32), encoding
),
1005 MlirAttribute uint64Elements
= mlirDenseElementsAttrUInt64Get(
1006 mlirRankedTensorTypeGet(2, shape
, mlirIntegerTypeUnsignedGet(ctx
, 64),
1009 MlirAttribute int64Elements
= mlirDenseElementsAttrInt64Get(
1010 mlirRankedTensorTypeGet(2, shape
, mlirIntegerTypeGet(ctx
, 64), encoding
),
1012 MlirAttribute floatElements
= mlirDenseElementsAttrFloatGet(
1013 mlirRankedTensorTypeGet(2, shape
, mlirF32TypeGet(ctx
), encoding
), 2,
1015 MlirAttribute doubleElements
= mlirDenseElementsAttrDoubleGet(
1016 mlirRankedTensorTypeGet(2, shape
, mlirF64TypeGet(ctx
), encoding
), 2,
1018 MlirAttribute bf16Elements
= mlirDenseElementsAttrBFloat16Get(
1019 mlirRankedTensorTypeGet(2, shape
, mlirBF16TypeGet(ctx
), encoding
), 2,
1021 MlirAttribute f16Elements
= mlirDenseElementsAttrFloat16Get(
1022 mlirRankedTensorTypeGet(2, shape
, mlirF16TypeGet(ctx
), encoding
), 2,
1025 if (!mlirAttributeIsADenseElements(boolElements
) ||
1026 !mlirAttributeIsADenseElements(uint8Elements
) ||
1027 !mlirAttributeIsADenseElements(int8Elements
) ||
1028 !mlirAttributeIsADenseElements(uint32Elements
) ||
1029 !mlirAttributeIsADenseElements(int32Elements
) ||
1030 !mlirAttributeIsADenseElements(uint64Elements
) ||
1031 !mlirAttributeIsADenseElements(int64Elements
) ||
1032 !mlirAttributeIsADenseElements(floatElements
) ||
1033 !mlirAttributeIsADenseElements(doubleElements
) ||
1034 !mlirAttributeIsADenseElements(bf16Elements
) ||
1035 !mlirAttributeIsADenseElements(f16Elements
))
1038 if (mlirDenseElementsAttrGetBoolValue(boolElements
, 1) != 1 ||
1039 mlirDenseElementsAttrGetUInt8Value(uint8Elements
, 1) != 1 ||
1040 mlirDenseElementsAttrGetInt8Value(int8Elements
, 1) != 1 ||
1041 mlirDenseElementsAttrGetUInt16Value(uint16Elements
, 1) != 1 ||
1042 mlirDenseElementsAttrGetInt16Value(int16Elements
, 1) != 1 ||
1043 mlirDenseElementsAttrGetUInt32Value(uint32Elements
, 1) != 1 ||
1044 mlirDenseElementsAttrGetInt32Value(int32Elements
, 1) != 1 ||
1045 mlirDenseElementsAttrGetUInt64Value(uint64Elements
, 1) != 1 ||
1046 mlirDenseElementsAttrGetInt64Value(int64Elements
, 1) != 1 ||
1047 fabsf(mlirDenseElementsAttrGetFloatValue(floatElements
, 1) - 1.0f
) >
1049 fabs(mlirDenseElementsAttrGetDoubleValue(doubleElements
, 1) - 1.0) > 1E-6)
1052 mlirAttributeDump(boolElements
);
1053 mlirAttributeDump(uint8Elements
);
1054 mlirAttributeDump(int8Elements
);
1055 mlirAttributeDump(uint32Elements
);
1056 mlirAttributeDump(int32Elements
);
1057 mlirAttributeDump(uint64Elements
);
1058 mlirAttributeDump(int64Elements
);
1059 mlirAttributeDump(floatElements
);
1060 mlirAttributeDump(doubleElements
);
1061 mlirAttributeDump(bf16Elements
);
1062 mlirAttributeDump(f16Elements
);
1063 // CHECK: dense<{{\[}}[false, true]]> : tensor<1x2xi1>
1064 // CHECK: dense<{{\[}}[0, 1]]> : tensor<1x2xui8>
1065 // CHECK: dense<{{\[}}[0, 1]]> : tensor<1x2xi8>
1066 // CHECK: dense<{{\[}}[0, 1]]> : tensor<1x2xui32>
1067 // CHECK: dense<{{\[}}[0, 1]]> : tensor<1x2xi32>
1068 // CHECK: dense<{{\[}}[0, 1]]> : tensor<1x2xui64>
1069 // CHECK: dense<{{\[}}[0, 1]]> : tensor<1x2xi64>
1070 // CHECK: dense<{{\[}}[0.000000e+00, 1.000000e+00]]> : tensor<1x2xf32>
1071 // CHECK: dense<{{\[}}[0.000000e+00, 1.000000e+00]]> : tensor<1x2xf64>
1072 // CHECK: dense<{{\[}}[0.000000e+00, 1.000000e+00]]> : tensor<1x2xbf16>
1073 // CHECK: dense<{{\[}}[0.000000e+00, 1.000000e+00]]> : tensor<1x2xf16>
1075 MlirAttribute splatBool
= mlirDenseElementsAttrBoolSplatGet(
1076 mlirRankedTensorTypeGet(2, shape
, mlirIntegerTypeGet(ctx
, 1), encoding
),
1078 MlirAttribute splatUInt8
= mlirDenseElementsAttrUInt8SplatGet(
1079 mlirRankedTensorTypeGet(2, shape
, mlirIntegerTypeUnsignedGet(ctx
, 8),
1082 MlirAttribute splatInt8
= mlirDenseElementsAttrInt8SplatGet(
1083 mlirRankedTensorTypeGet(2, shape
, mlirIntegerTypeGet(ctx
, 8), encoding
),
1085 MlirAttribute splatUInt32
= mlirDenseElementsAttrUInt32SplatGet(
1086 mlirRankedTensorTypeGet(2, shape
, mlirIntegerTypeUnsignedGet(ctx
, 32),
1089 MlirAttribute splatInt32
= mlirDenseElementsAttrInt32SplatGet(
1090 mlirRankedTensorTypeGet(2, shape
, mlirIntegerTypeGet(ctx
, 32), encoding
),
1092 MlirAttribute splatUInt64
= mlirDenseElementsAttrUInt64SplatGet(
1093 mlirRankedTensorTypeGet(2, shape
, mlirIntegerTypeUnsignedGet(ctx
, 64),
1096 MlirAttribute splatInt64
= mlirDenseElementsAttrInt64SplatGet(
1097 mlirRankedTensorTypeGet(2, shape
, mlirIntegerTypeGet(ctx
, 64), encoding
),
1099 MlirAttribute splatFloat
= mlirDenseElementsAttrFloatSplatGet(
1100 mlirRankedTensorTypeGet(2, shape
, mlirF32TypeGet(ctx
), encoding
), 1.0f
);
1101 MlirAttribute splatDouble
= mlirDenseElementsAttrDoubleSplatGet(
1102 mlirRankedTensorTypeGet(2, shape
, mlirF64TypeGet(ctx
), encoding
), 1.0);
1104 if (!mlirAttributeIsADenseElements(splatBool
) ||
1105 !mlirDenseElementsAttrIsSplat(splatBool
) ||
1106 !mlirAttributeIsADenseElements(splatUInt8
) ||
1107 !mlirDenseElementsAttrIsSplat(splatUInt8
) ||
1108 !mlirAttributeIsADenseElements(splatInt8
) ||
1109 !mlirDenseElementsAttrIsSplat(splatInt8
) ||
1110 !mlirAttributeIsADenseElements(splatUInt32
) ||
1111 !mlirDenseElementsAttrIsSplat(splatUInt32
) ||
1112 !mlirAttributeIsADenseElements(splatInt32
) ||
1113 !mlirDenseElementsAttrIsSplat(splatInt32
) ||
1114 !mlirAttributeIsADenseElements(splatUInt64
) ||
1115 !mlirDenseElementsAttrIsSplat(splatUInt64
) ||
1116 !mlirAttributeIsADenseElements(splatInt64
) ||
1117 !mlirDenseElementsAttrIsSplat(splatInt64
) ||
1118 !mlirAttributeIsADenseElements(splatFloat
) ||
1119 !mlirDenseElementsAttrIsSplat(splatFloat
) ||
1120 !mlirAttributeIsADenseElements(splatDouble
) ||
1121 !mlirDenseElementsAttrIsSplat(splatDouble
))
1124 if (mlirDenseElementsAttrGetBoolSplatValue(splatBool
) != 1 ||
1125 mlirDenseElementsAttrGetUInt8SplatValue(splatUInt8
) != 1 ||
1126 mlirDenseElementsAttrGetInt8SplatValue(splatInt8
) != 1 ||
1127 mlirDenseElementsAttrGetUInt32SplatValue(splatUInt32
) != 1 ||
1128 mlirDenseElementsAttrGetInt32SplatValue(splatInt32
) != 1 ||
1129 mlirDenseElementsAttrGetUInt64SplatValue(splatUInt64
) != 1 ||
1130 mlirDenseElementsAttrGetInt64SplatValue(splatInt64
) != 1 ||
1131 fabsf(mlirDenseElementsAttrGetFloatSplatValue(splatFloat
) - 1.0f
) >
1133 fabs(mlirDenseElementsAttrGetDoubleSplatValue(splatDouble
) - 1.0) > 1E-6)
1136 const uint8_t *uint8RawData
=
1137 (const uint8_t *)mlirDenseElementsAttrGetRawData(uint8Elements
);
1138 const int8_t *int8RawData
=
1139 (const int8_t *)mlirDenseElementsAttrGetRawData(int8Elements
);
1140 const uint32_t *uint32RawData
=
1141 (const uint32_t *)mlirDenseElementsAttrGetRawData(uint32Elements
);
1142 const int32_t *int32RawData
=
1143 (const int32_t *)mlirDenseElementsAttrGetRawData(int32Elements
);
1144 const uint64_t *uint64RawData
=
1145 (const uint64_t *)mlirDenseElementsAttrGetRawData(uint64Elements
);
1146 const int64_t *int64RawData
=
1147 (const int64_t *)mlirDenseElementsAttrGetRawData(int64Elements
);
1148 const float *floatRawData
=
1149 (const float *)mlirDenseElementsAttrGetRawData(floatElements
);
1150 const double *doubleRawData
=
1151 (const double *)mlirDenseElementsAttrGetRawData(doubleElements
);
1152 const uint16_t *bf16RawData
=
1153 (const uint16_t *)mlirDenseElementsAttrGetRawData(bf16Elements
);
1154 const uint16_t *f16RawData
=
1155 (const uint16_t *)mlirDenseElementsAttrGetRawData(f16Elements
);
1156 if (uint8RawData
[0] != 0u || uint8RawData
[1] != 1u || int8RawData
[0] != 0 ||
1157 int8RawData
[1] != 1 || uint32RawData
[0] != 0u || uint32RawData
[1] != 1u ||
1158 int32RawData
[0] != 0 || int32RawData
[1] != 1 || uint64RawData
[0] != 0u ||
1159 uint64RawData
[1] != 1u || int64RawData
[0] != 0 || int64RawData
[1] != 1 ||
1160 floatRawData
[0] != 0.0f
|| floatRawData
[1] != 1.0f
||
1161 doubleRawData
[0] != 0.0 || doubleRawData
[1] != 1.0 ||
1162 bf16RawData
[0] != 0 || bf16RawData
[1] != 0x3f80 || f16RawData
[0] != 0 ||
1163 f16RawData
[1] != 0x3c00)
1166 mlirAttributeDump(splatBool
);
1167 mlirAttributeDump(splatUInt8
);
1168 mlirAttributeDump(splatInt8
);
1169 mlirAttributeDump(splatUInt32
);
1170 mlirAttributeDump(splatInt32
);
1171 mlirAttributeDump(splatUInt64
);
1172 mlirAttributeDump(splatInt64
);
1173 mlirAttributeDump(splatFloat
);
1174 mlirAttributeDump(splatDouble
);
1175 // CHECK: dense<true> : tensor<1x2xi1>
1176 // CHECK: dense<1> : tensor<1x2xui8>
1177 // CHECK: dense<1> : tensor<1x2xi8>
1178 // CHECK: dense<1> : tensor<1x2xui32>
1179 // CHECK: dense<1> : tensor<1x2xi32>
1180 // CHECK: dense<1> : tensor<1x2xui64>
1181 // CHECK: dense<1> : tensor<1x2xi64>
1182 // CHECK: dense<1.000000e+00> : tensor<1x2xf32>
1183 // CHECK: dense<1.000000e+00> : tensor<1x2xf64>
1185 mlirAttributeDump(mlirElementsAttrGetValue(floatElements
, 2, uints64
));
1186 mlirAttributeDump(mlirElementsAttrGetValue(doubleElements
, 2, uints64
));
1187 mlirAttributeDump(mlirElementsAttrGetValue(bf16Elements
, 2, uints64
));
1188 mlirAttributeDump(mlirElementsAttrGetValue(f16Elements
, 2, uints64
));
1189 // CHECK: 1.000000e+00 : f32
1190 // CHECK: 1.000000e+00 : f64
1191 // CHECK: 1.000000e+00 : bf16
1192 // CHECK: 1.000000e+00 : f16
1194 int64_t indices
[] = {0, 1};
1196 MlirAttribute indicesAttr
= mlirDenseElementsAttrInt64Get(
1197 mlirRankedTensorTypeGet(2, shape
, mlirIntegerTypeGet(ctx
, 64), encoding
),
1199 MlirAttribute valuesAttr
= mlirDenseElementsAttrFloatGet(
1200 mlirRankedTensorTypeGet(1, &one
, mlirF32TypeGet(ctx
), encoding
), 1,
1202 MlirAttribute sparseAttr
= mlirSparseElementsAttribute(
1203 mlirRankedTensorTypeGet(2, shape
, mlirF32TypeGet(ctx
), encoding
),
1204 indicesAttr
, valuesAttr
);
1205 mlirAttributeDump(sparseAttr
);
1206 // CHECK: sparse<{{\[}}[0, 1]], 0.000000e+00> : tensor<1x2xf32>
1208 MlirAttribute boolArray
= mlirDenseBoolArrayGet(ctx
, 2, bools
);
1209 MlirAttribute int8Array
= mlirDenseI8ArrayGet(ctx
, 2, ints8
);
1210 MlirAttribute int16Array
= mlirDenseI16ArrayGet(ctx
, 2, ints16
);
1211 MlirAttribute int32Array
= mlirDenseI32ArrayGet(ctx
, 2, ints32
);
1212 MlirAttribute int64Array
= mlirDenseI64ArrayGet(ctx
, 2, ints64
);
1213 MlirAttribute floatArray
= mlirDenseF32ArrayGet(ctx
, 2, floats
);
1214 MlirAttribute doubleArray
= mlirDenseF64ArrayGet(ctx
, 2, doubles
);
1215 if (!mlirAttributeIsADenseBoolArray(boolArray
) ||
1216 !mlirAttributeIsADenseI8Array(int8Array
) ||
1217 !mlirAttributeIsADenseI16Array(int16Array
) ||
1218 !mlirAttributeIsADenseI32Array(int32Array
) ||
1219 !mlirAttributeIsADenseI64Array(int64Array
) ||
1220 !mlirAttributeIsADenseF32Array(floatArray
) ||
1221 !mlirAttributeIsADenseF64Array(doubleArray
))
1224 if (mlirDenseArrayGetNumElements(boolArray
) != 2 ||
1225 mlirDenseArrayGetNumElements(int8Array
) != 2 ||
1226 mlirDenseArrayGetNumElements(int16Array
) != 2 ||
1227 mlirDenseArrayGetNumElements(int32Array
) != 2 ||
1228 mlirDenseArrayGetNumElements(int64Array
) != 2 ||
1229 mlirDenseArrayGetNumElements(floatArray
) != 2 ||
1230 mlirDenseArrayGetNumElements(doubleArray
) != 2)
1233 if (mlirDenseBoolArrayGetElement(boolArray
, 1) != 1 ||
1234 mlirDenseI8ArrayGetElement(int8Array
, 1) != 1 ||
1235 mlirDenseI16ArrayGetElement(int16Array
, 1) != 1 ||
1236 mlirDenseI32ArrayGetElement(int32Array
, 1) != 1 ||
1237 mlirDenseI64ArrayGetElement(int64Array
, 1) != 1 ||
1238 fabsf(mlirDenseF32ArrayGetElement(floatArray
, 1) - 1.0f
) > 1E-6f
||
1239 fabs(mlirDenseF64ArrayGetElement(doubleArray
, 1) - 1.0) > 1E-6)
1242 int64_t layoutStrides
[3] = {5, 7, 13};
1243 MlirAttribute stridedLayoutAttr
=
1244 mlirStridedLayoutAttrGet(ctx
, 42, 3, &layoutStrides
[0]);
1246 // CHECK: strided<[5, 7, 13], offset: 42>
1247 mlirAttributeDump(stridedLayoutAttr
);
1249 if (mlirStridedLayoutAttrGetOffset(stridedLayoutAttr
) != 42 ||
1250 mlirStridedLayoutAttrGetNumStrides(stridedLayoutAttr
) != 3 ||
1251 mlirStridedLayoutAttrGetStride(stridedLayoutAttr
, 0) != 5 ||
1252 mlirStridedLayoutAttrGetStride(stridedLayoutAttr
, 1) != 7 ||
1253 mlirStridedLayoutAttrGetStride(stridedLayoutAttr
, 2) != 13)
1256 MlirAttribute uint8Blob
= mlirUnmanagedDenseUInt8ResourceElementsAttrGet(
1257 mlirRankedTensorTypeGet(2, shape
, mlirIntegerTypeUnsignedGet(ctx
, 8),
1259 mlirStringRefCreateFromCString("resource_ui8"), 2, uints8
);
1260 MlirAttribute uint16Blob
= mlirUnmanagedDenseUInt16ResourceElementsAttrGet(
1261 mlirRankedTensorTypeGet(2, shape
, mlirIntegerTypeUnsignedGet(ctx
, 16),
1263 mlirStringRefCreateFromCString("resource_ui16"), 2, uints16
);
1264 MlirAttribute uint32Blob
= mlirUnmanagedDenseUInt32ResourceElementsAttrGet(
1265 mlirRankedTensorTypeGet(2, shape
, mlirIntegerTypeUnsignedGet(ctx
, 32),
1267 mlirStringRefCreateFromCString("resource_ui32"), 2, uints32
);
1268 MlirAttribute uint64Blob
= mlirUnmanagedDenseUInt64ResourceElementsAttrGet(
1269 mlirRankedTensorTypeGet(2, shape
, mlirIntegerTypeUnsignedGet(ctx
, 64),
1271 mlirStringRefCreateFromCString("resource_ui64"), 2, uints64
);
1272 MlirAttribute int8Blob
= mlirUnmanagedDenseInt8ResourceElementsAttrGet(
1273 mlirRankedTensorTypeGet(2, shape
, mlirIntegerTypeGet(ctx
, 8), encoding
),
1274 mlirStringRefCreateFromCString("resource_i8"), 2, ints8
);
1275 MlirAttribute int16Blob
= mlirUnmanagedDenseInt16ResourceElementsAttrGet(
1276 mlirRankedTensorTypeGet(2, shape
, mlirIntegerTypeGet(ctx
, 16), encoding
),
1277 mlirStringRefCreateFromCString("resource_i16"), 2, ints16
);
1278 MlirAttribute int32Blob
= mlirUnmanagedDenseInt32ResourceElementsAttrGet(
1279 mlirRankedTensorTypeGet(2, shape
, mlirIntegerTypeGet(ctx
, 32), encoding
),
1280 mlirStringRefCreateFromCString("resource_i32"), 2, ints32
);
1281 MlirAttribute int64Blob
= mlirUnmanagedDenseInt64ResourceElementsAttrGet(
1282 mlirRankedTensorTypeGet(2, shape
, mlirIntegerTypeGet(ctx
, 64), encoding
),
1283 mlirStringRefCreateFromCString("resource_i64"), 2, ints64
);
1284 MlirAttribute floatsBlob
= mlirUnmanagedDenseFloatResourceElementsAttrGet(
1285 mlirRankedTensorTypeGet(2, shape
, mlirF32TypeGet(ctx
), encoding
),
1286 mlirStringRefCreateFromCString("resource_f32"), 2, floats
);
1287 MlirAttribute doublesBlob
= mlirUnmanagedDenseDoubleResourceElementsAttrGet(
1288 mlirRankedTensorTypeGet(2, shape
, mlirF64TypeGet(ctx
), encoding
),
1289 mlirStringRefCreateFromCString("resource_f64"), 2, doubles
);
1290 MlirAttribute blobBlob
= mlirUnmanagedDenseResourceElementsAttrGet(
1291 mlirRankedTensorTypeGet(2, shape
, mlirIntegerTypeGet(ctx
, 64), encoding
),
1292 mlirStringRefCreateFromCString("resource_i64_blob"), /*data=*/uints64
,
1293 /*dataLength=*/sizeof(uints64
),
1294 /*dataAlignment=*/_Alignof(uint64_t),
1295 /*dataIsMutable=*/false,
1296 /*deleter=*/reportResourceDelete
,
1297 /*userData=*/(void *)&resourceI64BlobUserData
);
1299 mlirAttributeDump(uint8Blob
);
1300 mlirAttributeDump(uint16Blob
);
1301 mlirAttributeDump(uint32Blob
);
1302 mlirAttributeDump(uint64Blob
);
1303 mlirAttributeDump(int8Blob
);
1304 mlirAttributeDump(int16Blob
);
1305 mlirAttributeDump(int32Blob
);
1306 mlirAttributeDump(int64Blob
);
1307 mlirAttributeDump(floatsBlob
);
1308 mlirAttributeDump(doublesBlob
);
1309 mlirAttributeDump(blobBlob
);
1310 // CHECK: dense_resource<resource_ui8> : tensor<1x2xui8>
1311 // CHECK: dense_resource<resource_ui16> : tensor<1x2xui16>
1312 // CHECK: dense_resource<resource_ui32> : tensor<1x2xui32>
1313 // CHECK: dense_resource<resource_ui64> : tensor<1x2xui64>
1314 // CHECK: dense_resource<resource_i8> : tensor<1x2xi8>
1315 // CHECK: dense_resource<resource_i16> : tensor<1x2xi16>
1316 // CHECK: dense_resource<resource_i32> : tensor<1x2xi32>
1317 // CHECK: dense_resource<resource_i64> : tensor<1x2xi64>
1318 // CHECK: dense_resource<resource_f32> : tensor<1x2xf32>
1319 // CHECK: dense_resource<resource_f64> : tensor<1x2xf64>
1320 // CHECK: dense_resource<resource_i64_blob> : tensor<1x2xi64>
1322 if (mlirDenseUInt8ResourceElementsAttrGetValue(uint8Blob
, 1) != 1 ||
1323 mlirDenseUInt16ResourceElementsAttrGetValue(uint16Blob
, 1) != 1 ||
1324 mlirDenseUInt32ResourceElementsAttrGetValue(uint32Blob
, 1) != 1 ||
1325 mlirDenseUInt64ResourceElementsAttrGetValue(uint64Blob
, 1) != 1 ||
1326 mlirDenseInt8ResourceElementsAttrGetValue(int8Blob
, 1) != 1 ||
1327 mlirDenseInt16ResourceElementsAttrGetValue(int16Blob
, 1) != 1 ||
1328 mlirDenseInt32ResourceElementsAttrGetValue(int32Blob
, 1) != 1 ||
1329 mlirDenseInt64ResourceElementsAttrGetValue(int64Blob
, 1) != 1 ||
1330 fabsf(mlirDenseF32ArrayGetElement(floatArray
, 1) - 1.0f
) > 1E-6f
||
1331 fabsf(mlirDenseFloatResourceElementsAttrGetValue(floatsBlob
, 1) - 1.0f
) >
1333 fabs(mlirDenseDoubleResourceElementsAttrGetValue(doublesBlob
, 1) - 1.0f
) >
1335 mlirDenseUInt64ResourceElementsAttrGetValue(blobBlob
, 1) != 1)
1338 MlirLocation loc
= mlirLocationUnknownGet(ctx
);
1339 MlirAttribute locAttr
= mlirLocationGetAttribute(loc
);
1340 if (!mlirAttributeIsALocation(locAttr
))
1346 int printAffineMap(MlirContext ctx
) {
1347 MlirAffineMap emptyAffineMap
= mlirAffineMapEmptyGet(ctx
);
1348 MlirAffineMap affineMap
= mlirAffineMapZeroResultGet(ctx
, 3, 2);
1349 MlirAffineMap constAffineMap
= mlirAffineMapConstantGet(ctx
, 2);
1350 MlirAffineMap multiDimIdentityAffineMap
=
1351 mlirAffineMapMultiDimIdentityGet(ctx
, 3);
1352 MlirAffineMap minorIdentityAffineMap
=
1353 mlirAffineMapMinorIdentityGet(ctx
, 3, 2);
1354 unsigned permutation
[] = {1, 2, 0};
1355 MlirAffineMap permutationAffineMap
= mlirAffineMapPermutationGet(
1356 ctx
, sizeof(permutation
) / sizeof(unsigned), permutation
);
1358 fprintf(stderr
, "@affineMap\n");
1359 mlirAffineMapDump(emptyAffineMap
);
1360 mlirAffineMapDump(affineMap
);
1361 mlirAffineMapDump(constAffineMap
);
1362 mlirAffineMapDump(multiDimIdentityAffineMap
);
1363 mlirAffineMapDump(minorIdentityAffineMap
);
1364 mlirAffineMapDump(permutationAffineMap
);
1365 // CHECK-LABEL: @affineMap
1367 // CHECK: (d0, d1, d2)[s0, s1] -> ()
1369 // CHECK: (d0, d1, d2) -> (d0, d1, d2)
1370 // CHECK: (d0, d1, d2) -> (d1, d2)
1371 // CHECK: (d0, d1, d2) -> (d1, d2, d0)
1373 if (!mlirAffineMapIsIdentity(emptyAffineMap
) ||
1374 mlirAffineMapIsIdentity(affineMap
) ||
1375 mlirAffineMapIsIdentity(constAffineMap
) ||
1376 !mlirAffineMapIsIdentity(multiDimIdentityAffineMap
) ||
1377 mlirAffineMapIsIdentity(minorIdentityAffineMap
) ||
1378 mlirAffineMapIsIdentity(permutationAffineMap
))
1381 if (!mlirAffineMapIsMinorIdentity(emptyAffineMap
) ||
1382 mlirAffineMapIsMinorIdentity(affineMap
) ||
1383 !mlirAffineMapIsMinorIdentity(multiDimIdentityAffineMap
) ||
1384 !mlirAffineMapIsMinorIdentity(minorIdentityAffineMap
) ||
1385 mlirAffineMapIsMinorIdentity(permutationAffineMap
))
1388 if (!mlirAffineMapIsEmpty(emptyAffineMap
) ||
1389 mlirAffineMapIsEmpty(affineMap
) || mlirAffineMapIsEmpty(constAffineMap
) ||
1390 mlirAffineMapIsEmpty(multiDimIdentityAffineMap
) ||
1391 mlirAffineMapIsEmpty(minorIdentityAffineMap
) ||
1392 mlirAffineMapIsEmpty(permutationAffineMap
))
1395 if (mlirAffineMapIsSingleConstant(emptyAffineMap
) ||
1396 mlirAffineMapIsSingleConstant(affineMap
) ||
1397 !mlirAffineMapIsSingleConstant(constAffineMap
) ||
1398 mlirAffineMapIsSingleConstant(multiDimIdentityAffineMap
) ||
1399 mlirAffineMapIsSingleConstant(minorIdentityAffineMap
) ||
1400 mlirAffineMapIsSingleConstant(permutationAffineMap
))
1403 if (mlirAffineMapGetSingleConstantResult(constAffineMap
) != 2)
1406 if (mlirAffineMapGetNumDims(emptyAffineMap
) != 0 ||
1407 mlirAffineMapGetNumDims(affineMap
) != 3 ||
1408 mlirAffineMapGetNumDims(constAffineMap
) != 0 ||
1409 mlirAffineMapGetNumDims(multiDimIdentityAffineMap
) != 3 ||
1410 mlirAffineMapGetNumDims(minorIdentityAffineMap
) != 3 ||
1411 mlirAffineMapGetNumDims(permutationAffineMap
) != 3)
1414 if (mlirAffineMapGetNumSymbols(emptyAffineMap
) != 0 ||
1415 mlirAffineMapGetNumSymbols(affineMap
) != 2 ||
1416 mlirAffineMapGetNumSymbols(constAffineMap
) != 0 ||
1417 mlirAffineMapGetNumSymbols(multiDimIdentityAffineMap
) != 0 ||
1418 mlirAffineMapGetNumSymbols(minorIdentityAffineMap
) != 0 ||
1419 mlirAffineMapGetNumSymbols(permutationAffineMap
) != 0)
1422 if (mlirAffineMapGetNumResults(emptyAffineMap
) != 0 ||
1423 mlirAffineMapGetNumResults(affineMap
) != 0 ||
1424 mlirAffineMapGetNumResults(constAffineMap
) != 1 ||
1425 mlirAffineMapGetNumResults(multiDimIdentityAffineMap
) != 3 ||
1426 mlirAffineMapGetNumResults(minorIdentityAffineMap
) != 2 ||
1427 mlirAffineMapGetNumResults(permutationAffineMap
) != 3)
1430 if (mlirAffineMapGetNumInputs(emptyAffineMap
) != 0 ||
1431 mlirAffineMapGetNumInputs(affineMap
) != 5 ||
1432 mlirAffineMapGetNumInputs(constAffineMap
) != 0 ||
1433 mlirAffineMapGetNumInputs(multiDimIdentityAffineMap
) != 3 ||
1434 mlirAffineMapGetNumInputs(minorIdentityAffineMap
) != 3 ||
1435 mlirAffineMapGetNumInputs(permutationAffineMap
) != 3)
1438 if (!mlirAffineMapIsProjectedPermutation(emptyAffineMap
) ||
1439 !mlirAffineMapIsPermutation(emptyAffineMap
) ||
1440 mlirAffineMapIsProjectedPermutation(affineMap
) ||
1441 mlirAffineMapIsPermutation(affineMap
) ||
1442 mlirAffineMapIsProjectedPermutation(constAffineMap
) ||
1443 mlirAffineMapIsPermutation(constAffineMap
) ||
1444 !mlirAffineMapIsProjectedPermutation(multiDimIdentityAffineMap
) ||
1445 !mlirAffineMapIsPermutation(multiDimIdentityAffineMap
) ||
1446 !mlirAffineMapIsProjectedPermutation(minorIdentityAffineMap
) ||
1447 mlirAffineMapIsPermutation(minorIdentityAffineMap
) ||
1448 !mlirAffineMapIsProjectedPermutation(permutationAffineMap
) ||
1449 !mlirAffineMapIsPermutation(permutationAffineMap
))
1452 intptr_t sub
[] = {1};
1454 MlirAffineMap subMap
= mlirAffineMapGetSubMap(
1455 multiDimIdentityAffineMap
, sizeof(sub
) / sizeof(intptr_t), sub
);
1456 MlirAffineMap majorSubMap
=
1457 mlirAffineMapGetMajorSubMap(multiDimIdentityAffineMap
, 1);
1458 MlirAffineMap minorSubMap
=
1459 mlirAffineMapGetMinorSubMap(multiDimIdentityAffineMap
, 1);
1461 mlirAffineMapDump(subMap
);
1462 mlirAffineMapDump(majorSubMap
);
1463 mlirAffineMapDump(minorSubMap
);
1464 // CHECK: (d0, d1, d2) -> (d1)
1465 // CHECK: (d0, d1, d2) -> (d0)
1466 // CHECK: (d0, d1, d2) -> (d2)
1471 int printAffineExpr(MlirContext ctx
) {
1472 MlirAffineExpr affineDimExpr
= mlirAffineDimExprGet(ctx
, 5);
1473 MlirAffineExpr affineSymbolExpr
= mlirAffineSymbolExprGet(ctx
, 5);
1474 MlirAffineExpr affineConstantExpr
= mlirAffineConstantExprGet(ctx
, 5);
1475 MlirAffineExpr affineAddExpr
=
1476 mlirAffineAddExprGet(affineDimExpr
, affineSymbolExpr
);
1477 MlirAffineExpr affineMulExpr
=
1478 mlirAffineMulExprGet(affineDimExpr
, affineSymbolExpr
);
1479 MlirAffineExpr affineModExpr
=
1480 mlirAffineModExprGet(affineDimExpr
, affineSymbolExpr
);
1481 MlirAffineExpr affineFloorDivExpr
=
1482 mlirAffineFloorDivExprGet(affineDimExpr
, affineSymbolExpr
);
1483 MlirAffineExpr affineCeilDivExpr
=
1484 mlirAffineCeilDivExprGet(affineDimExpr
, affineSymbolExpr
);
1486 // Tests mlirAffineExprDump.
1487 fprintf(stderr
, "@affineExpr\n");
1488 mlirAffineExprDump(affineDimExpr
);
1489 mlirAffineExprDump(affineSymbolExpr
);
1490 mlirAffineExprDump(affineConstantExpr
);
1491 mlirAffineExprDump(affineAddExpr
);
1492 mlirAffineExprDump(affineMulExpr
);
1493 mlirAffineExprDump(affineModExpr
);
1494 mlirAffineExprDump(affineFloorDivExpr
);
1495 mlirAffineExprDump(affineCeilDivExpr
);
1496 // CHECK-LABEL: @affineExpr
1503 // CHECK: d5 floordiv s5
1504 // CHECK: d5 ceildiv s5
1506 // Tests methods of affine binary operation expression, takes add expression
1508 mlirAffineExprDump(mlirAffineBinaryOpExprGetLHS(affineAddExpr
));
1509 mlirAffineExprDump(mlirAffineBinaryOpExprGetRHS(affineAddExpr
));
1513 // Tests methods of affine dimension expression.
1514 if (mlirAffineDimExprGetPosition(affineDimExpr
) != 5)
1517 // Tests methods of affine symbol expression.
1518 if (mlirAffineSymbolExprGetPosition(affineSymbolExpr
) != 5)
1521 // Tests methods of affine constant expression.
1522 if (mlirAffineConstantExprGetValue(affineConstantExpr
) != 5)
1525 // Tests methods of affine expression.
1526 if (mlirAffineExprIsSymbolicOrConstant(affineDimExpr
) ||
1527 !mlirAffineExprIsSymbolicOrConstant(affineSymbolExpr
) ||
1528 !mlirAffineExprIsSymbolicOrConstant(affineConstantExpr
) ||
1529 mlirAffineExprIsSymbolicOrConstant(affineAddExpr
) ||
1530 mlirAffineExprIsSymbolicOrConstant(affineMulExpr
) ||
1531 mlirAffineExprIsSymbolicOrConstant(affineModExpr
) ||
1532 mlirAffineExprIsSymbolicOrConstant(affineFloorDivExpr
) ||
1533 mlirAffineExprIsSymbolicOrConstant(affineCeilDivExpr
))
1536 if (!mlirAffineExprIsPureAffine(affineDimExpr
) ||
1537 !mlirAffineExprIsPureAffine(affineSymbolExpr
) ||
1538 !mlirAffineExprIsPureAffine(affineConstantExpr
) ||
1539 !mlirAffineExprIsPureAffine(affineAddExpr
) ||
1540 mlirAffineExprIsPureAffine(affineMulExpr
) ||
1541 mlirAffineExprIsPureAffine(affineModExpr
) ||
1542 mlirAffineExprIsPureAffine(affineFloorDivExpr
) ||
1543 mlirAffineExprIsPureAffine(affineCeilDivExpr
))
1546 if (mlirAffineExprGetLargestKnownDivisor(affineDimExpr
) != 1 ||
1547 mlirAffineExprGetLargestKnownDivisor(affineSymbolExpr
) != 1 ||
1548 mlirAffineExprGetLargestKnownDivisor(affineConstantExpr
) != 5 ||
1549 mlirAffineExprGetLargestKnownDivisor(affineAddExpr
) != 1 ||
1550 mlirAffineExprGetLargestKnownDivisor(affineMulExpr
) != 1 ||
1551 mlirAffineExprGetLargestKnownDivisor(affineModExpr
) != 1 ||
1552 mlirAffineExprGetLargestKnownDivisor(affineFloorDivExpr
) != 1 ||
1553 mlirAffineExprGetLargestKnownDivisor(affineCeilDivExpr
) != 1)
1556 if (!mlirAffineExprIsMultipleOf(affineDimExpr
, 1) ||
1557 !mlirAffineExprIsMultipleOf(affineSymbolExpr
, 1) ||
1558 !mlirAffineExprIsMultipleOf(affineConstantExpr
, 5) ||
1559 !mlirAffineExprIsMultipleOf(affineAddExpr
, 1) ||
1560 !mlirAffineExprIsMultipleOf(affineMulExpr
, 1) ||
1561 !mlirAffineExprIsMultipleOf(affineModExpr
, 1) ||
1562 !mlirAffineExprIsMultipleOf(affineFloorDivExpr
, 1) ||
1563 !mlirAffineExprIsMultipleOf(affineCeilDivExpr
, 1))
1566 if (!mlirAffineExprIsFunctionOfDim(affineDimExpr
, 5) ||
1567 mlirAffineExprIsFunctionOfDim(affineSymbolExpr
, 5) ||
1568 mlirAffineExprIsFunctionOfDim(affineConstantExpr
, 5) ||
1569 !mlirAffineExprIsFunctionOfDim(affineAddExpr
, 5) ||
1570 !mlirAffineExprIsFunctionOfDim(affineMulExpr
, 5) ||
1571 !mlirAffineExprIsFunctionOfDim(affineModExpr
, 5) ||
1572 !mlirAffineExprIsFunctionOfDim(affineFloorDivExpr
, 5) ||
1573 !mlirAffineExprIsFunctionOfDim(affineCeilDivExpr
, 5))
1576 // Tests 'IsA' methods of affine binary operation expression.
1577 if (!mlirAffineExprIsAAdd(affineAddExpr
))
1580 if (!mlirAffineExprIsAMul(affineMulExpr
))
1583 if (!mlirAffineExprIsAMod(affineModExpr
))
1586 if (!mlirAffineExprIsAFloorDiv(affineFloorDivExpr
))
1589 if (!mlirAffineExprIsACeilDiv(affineCeilDivExpr
))
1592 if (!mlirAffineExprIsABinary(affineAddExpr
))
1595 // Test other 'IsA' method on affine expressions.
1596 if (!mlirAffineExprIsAConstant(affineConstantExpr
))
1599 if (!mlirAffineExprIsADim(affineDimExpr
))
1602 if (!mlirAffineExprIsASymbol(affineSymbolExpr
))
1605 // Test equality and nullity.
1606 MlirAffineExpr otherDimExpr
= mlirAffineDimExprGet(ctx
, 5);
1607 if (!mlirAffineExprEqual(affineDimExpr
, otherDimExpr
))
1610 if (mlirAffineExprIsNull(affineDimExpr
))
1616 int affineMapFromExprs(MlirContext ctx
) {
1617 MlirAffineExpr affineDimExpr
= mlirAffineDimExprGet(ctx
, 0);
1618 MlirAffineExpr affineSymbolExpr
= mlirAffineSymbolExprGet(ctx
, 1);
1619 MlirAffineExpr exprs
[] = {affineDimExpr
, affineSymbolExpr
};
1620 MlirAffineMap map
= mlirAffineMapGet(ctx
, 3, 3, 2, exprs
);
1622 // CHECK-LABEL: @affineMapFromExprs
1623 fprintf(stderr
, "@affineMapFromExprs");
1624 // CHECK: (d0, d1, d2)[s0, s1, s2] -> (d0, s1)
1625 mlirAffineMapDump(map
);
1627 if (mlirAffineMapGetNumResults(map
) != 2)
1630 if (!mlirAffineExprEqual(mlirAffineMapGetResult(map
, 0), affineDimExpr
))
1633 if (!mlirAffineExprEqual(mlirAffineMapGetResult(map
, 1), affineSymbolExpr
))
1636 MlirAffineExpr affineDim2Expr
= mlirAffineDimExprGet(ctx
, 1);
1637 MlirAffineExpr composed
= mlirAffineExprCompose(affineDim2Expr
, map
);
1639 mlirAffineExprDump(composed
);
1640 if (!mlirAffineExprEqual(composed
, affineSymbolExpr
))
1646 int printIntegerSet(MlirContext ctx
) {
1647 MlirIntegerSet emptySet
= mlirIntegerSetEmptyGet(ctx
, 2, 1);
1649 // CHECK-LABEL: @printIntegerSet
1650 fprintf(stderr
, "@printIntegerSet");
1652 // CHECK: (d0, d1)[s0] : (1 == 0)
1653 mlirIntegerSetDump(emptySet
);
1655 if (!mlirIntegerSetIsCanonicalEmpty(emptySet
))
1658 MlirIntegerSet anotherEmptySet
= mlirIntegerSetEmptyGet(ctx
, 2, 1);
1659 if (!mlirIntegerSetEqual(emptySet
, anotherEmptySet
))
1662 // Construct a set constrained by:
1665 MlirAffineExpr negOne
= mlirAffineConstantExprGet(ctx
, -1);
1666 MlirAffineExpr negFortyTwo
= mlirAffineConstantExprGet(ctx
, -42);
1667 MlirAffineExpr d0
= mlirAffineDimExprGet(ctx
, 0);
1668 MlirAffineExpr d1
= mlirAffineDimExprGet(ctx
, 1);
1669 MlirAffineExpr s0
= mlirAffineSymbolExprGet(ctx
, 0);
1670 MlirAffineExpr negS0
= mlirAffineMulExprGet(negOne
, s0
);
1671 MlirAffineExpr d0minusS0
= mlirAffineAddExprGet(d0
, negS0
);
1672 MlirAffineExpr d1minus42
= mlirAffineAddExprGet(d1
, negFortyTwo
);
1673 MlirAffineExpr constraints
[] = {d0minusS0
, d1minus42
};
1674 bool flags
[] = {true, false};
1676 MlirIntegerSet set
= mlirIntegerSetGet(ctx
, 2, 1, 2, constraints
, flags
);
1677 // CHECK: (d0, d1)[s0] : (
1678 // CHECK-DAG: d0 - s0 == 0
1679 // CHECK-DAG: d1 - 42 >= 0
1680 mlirIntegerSetDump(set
);
1682 // Transform d1 into s0.
1683 MlirAffineExpr s1
= mlirAffineSymbolExprGet(ctx
, 1);
1684 MlirAffineExpr repl
[] = {d0
, s1
};
1685 MlirIntegerSet replaced
= mlirIntegerSetReplaceGet(set
, repl
, &s0
, 1, 2);
1686 // CHECK: (d0)[s0, s1] : (
1687 // CHECK-DAG: d0 - s0 == 0
1688 // CHECK-DAG: s1 - 42 >= 0
1689 mlirIntegerSetDump(replaced
);
1691 if (mlirIntegerSetGetNumDims(set
) != 2)
1693 if (mlirIntegerSetGetNumDims(replaced
) != 1)
1696 if (mlirIntegerSetGetNumSymbols(set
) != 1)
1698 if (mlirIntegerSetGetNumSymbols(replaced
) != 2)
1701 if (mlirIntegerSetGetNumInputs(set
) != 3)
1704 if (mlirIntegerSetGetNumConstraints(set
) != 2)
1707 if (mlirIntegerSetGetNumEqualities(set
) != 1)
1710 if (mlirIntegerSetGetNumInequalities(set
) != 1)
1713 MlirAffineExpr cstr1
= mlirIntegerSetGetConstraint(set
, 0);
1714 MlirAffineExpr cstr2
= mlirIntegerSetGetConstraint(set
, 1);
1715 bool isEq1
= mlirIntegerSetIsConstraintEq(set
, 0);
1716 bool isEq2
= mlirIntegerSetIsConstraintEq(set
, 1);
1717 if (!mlirAffineExprEqual(cstr1
, isEq1
? d0minusS0
: d1minus42
))
1719 if (!mlirAffineExprEqual(cstr2
, isEq2
? d0minusS0
: d1minus42
))
1725 int registerOnlyStd(void) {
1726 MlirContext ctx
= mlirContextCreate();
1727 // The built-in dialect is always loaded.
1728 if (mlirContextGetNumLoadedDialects(ctx
) != 1)
1731 MlirDialectHandle stdHandle
= mlirGetDialectHandle__func__();
1733 MlirDialect std
= mlirContextGetOrLoadDialect(
1734 ctx
, mlirDialectHandleGetNamespace(stdHandle
));
1735 if (!mlirDialectIsNull(std
))
1738 mlirDialectHandleRegisterDialect(stdHandle
, ctx
);
1740 std
= mlirContextGetOrLoadDialect(ctx
,
1741 mlirDialectHandleGetNamespace(stdHandle
));
1742 if (mlirDialectIsNull(std
))
1745 MlirDialect alsoStd
= mlirDialectHandleLoadDialect(stdHandle
, ctx
);
1746 if (!mlirDialectEqual(std
, alsoStd
))
1749 MlirStringRef stdNs
= mlirDialectGetNamespace(std
);
1750 MlirStringRef alsoStdNs
= mlirDialectHandleGetNamespace(stdHandle
);
1751 if (stdNs
.length
!= alsoStdNs
.length
||
1752 strncmp(stdNs
.data
, alsoStdNs
.data
, stdNs
.length
))
1755 fprintf(stderr
, "@registration\n");
1756 // CHECK-LABEL: @registration
1758 // CHECK: func.call is_registered: 1
1759 fprintf(stderr
, "func.call is_registered: %d\n",
1760 mlirContextIsRegisteredOperation(
1761 ctx
, mlirStringRefCreateFromCString("func.call")));
1763 // CHECK: func.not_existing_op is_registered: 0
1764 fprintf(stderr
, "func.not_existing_op is_registered: %d\n",
1765 mlirContextIsRegisteredOperation(
1766 ctx
, mlirStringRefCreateFromCString("func.not_existing_op")));
1768 // CHECK: not_existing_dialect.not_existing_op is_registered: 0
1769 fprintf(stderr
, "not_existing_dialect.not_existing_op is_registered: %d\n",
1770 mlirContextIsRegisteredOperation(
1771 ctx
, mlirStringRefCreateFromCString(
1772 "not_existing_dialect.not_existing_op")));
1774 mlirContextDestroy(ctx
);
1778 /// Tests backreference APIs
1779 static int testBackreferences(void) {
1780 fprintf(stderr
, "@test_backreferences\n");
1782 MlirContext ctx
= mlirContextCreate();
1783 mlirContextSetAllowUnregisteredDialects(ctx
, true);
1784 MlirLocation loc
= mlirLocationUnknownGet(ctx
);
1786 MlirOperationState opState
=
1787 mlirOperationStateGet(mlirStringRefCreateFromCString("invalid.op"), loc
);
1788 MlirRegion region
= mlirRegionCreate();
1789 MlirBlock block
= mlirBlockCreate(0, NULL
, NULL
);
1790 mlirRegionAppendOwnedBlock(region
, block
);
1791 mlirOperationStateAddOwnedRegions(&opState
, 1, ®ion
);
1792 MlirOperation op
= mlirOperationCreate(&opState
);
1793 MlirIdentifier ident
=
1794 mlirIdentifierGet(ctx
, mlirStringRefCreateFromCString("identifier"));
1796 if (!mlirContextEqual(ctx
, mlirOperationGetContext(op
))) {
1797 fprintf(stderr
, "ERROR: Getting context from operation failed\n");
1800 if (!mlirOperationEqual(op
, mlirBlockGetParentOperation(block
))) {
1801 fprintf(stderr
, "ERROR: Getting parent operation from block failed\n");
1804 if (!mlirContextEqual(ctx
, mlirIdentifierGetContext(ident
))) {
1805 fprintf(stderr
, "ERROR: Getting context from identifier failed\n");
1809 mlirOperationDestroy(op
);
1810 mlirContextDestroy(ctx
);
1812 // CHECK-LABEL: @test_backreferences
1816 /// Tests operand APIs.
1817 int testOperands(void) {
1818 fprintf(stderr
, "@testOperands\n");
1819 // CHECK-LABEL: @testOperands
1821 MlirContext ctx
= mlirContextCreate();
1822 registerAllUpstreamDialects(ctx
);
1824 mlirContextGetOrLoadDialect(ctx
, mlirStringRefCreateFromCString("arith"));
1825 mlirContextGetOrLoadDialect(ctx
, mlirStringRefCreateFromCString("test"));
1826 MlirLocation loc
= mlirLocationUnknownGet(ctx
);
1827 MlirType indexType
= mlirIndexTypeGet(ctx
);
1829 // Create some constants to use as operands.
1830 MlirAttribute indexZeroLiteral
=
1831 mlirAttributeParseGet(ctx
, mlirStringRefCreateFromCString("0 : index"));
1832 MlirNamedAttribute indexZeroValueAttr
= mlirNamedAttributeGet(
1833 mlirIdentifierGet(ctx
, mlirStringRefCreateFromCString("value")),
1835 MlirOperationState constZeroState
= mlirOperationStateGet(
1836 mlirStringRefCreateFromCString("arith.constant"), loc
);
1837 mlirOperationStateAddResults(&constZeroState
, 1, &indexType
);
1838 mlirOperationStateAddAttributes(&constZeroState
, 1, &indexZeroValueAttr
);
1839 MlirOperation constZero
= mlirOperationCreate(&constZeroState
);
1840 MlirValue constZeroValue
= mlirOperationGetResult(constZero
, 0);
1842 MlirAttribute indexOneLiteral
=
1843 mlirAttributeParseGet(ctx
, mlirStringRefCreateFromCString("1 : index"));
1844 MlirNamedAttribute indexOneValueAttr
= mlirNamedAttributeGet(
1845 mlirIdentifierGet(ctx
, mlirStringRefCreateFromCString("value")),
1847 MlirOperationState constOneState
= mlirOperationStateGet(
1848 mlirStringRefCreateFromCString("arith.constant"), loc
);
1849 mlirOperationStateAddResults(&constOneState
, 1, &indexType
);
1850 mlirOperationStateAddAttributes(&constOneState
, 1, &indexOneValueAttr
);
1851 MlirOperation constOne
= mlirOperationCreate(&constOneState
);
1852 MlirValue constOneValue
= mlirOperationGetResult(constOne
, 0);
1854 // Create the operation under test.
1855 mlirContextSetAllowUnregisteredDialects(ctx
, true);
1856 MlirOperationState opState
=
1857 mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op"), loc
);
1858 MlirValue initialOperands
[] = {constZeroValue
};
1859 mlirOperationStateAddOperands(&opState
, 1, initialOperands
);
1860 MlirOperation op
= mlirOperationCreate(&opState
);
1862 // Test operand APIs.
1863 intptr_t numOperands
= mlirOperationGetNumOperands(op
);
1864 fprintf(stderr
, "Num Operands: %" PRIdPTR
"\n", numOperands
);
1865 // CHECK: Num Operands: 1
1867 MlirValue opOperand1
= mlirOperationGetOperand(op
, 0);
1868 fprintf(stderr
, "Original operand: ");
1869 mlirValuePrint(opOperand1
, printToStderr
, NULL
);
1870 // CHECK: Original operand: {{.+}} arith.constant 0 : index
1872 mlirOperationSetOperand(op
, 0, constOneValue
);
1873 MlirValue opOperand2
= mlirOperationGetOperand(op
, 0);
1874 fprintf(stderr
, "Updated operand: ");
1875 mlirValuePrint(opOperand2
, printToStderr
, NULL
);
1876 // CHECK: Updated operand: {{.+}} arith.constant 1 : index
1878 // Test op operand APIs.
1879 MlirOpOperand use1
= mlirValueGetFirstUse(opOperand1
);
1880 if (!mlirOpOperandIsNull(use1
)) {
1881 fprintf(stderr
, "ERROR: Use should be null\n");
1885 MlirOpOperand use2
= mlirValueGetFirstUse(opOperand2
);
1886 if (mlirOpOperandIsNull(use2
)) {
1887 fprintf(stderr
, "ERROR: Use should not be null\n");
1891 fprintf(stderr
, "Use owner: ");
1892 mlirOperationPrint(mlirOpOperandGetOwner(use2
), printToStderr
, NULL
);
1893 fprintf(stderr
, "\n");
1894 // CHECK: Use owner: "dummy.op"
1896 fprintf(stderr
, "Use operandNumber: %d\n",
1897 mlirOpOperandGetOperandNumber(use2
));
1898 // CHECK: Use operandNumber: 0
1900 use2
= mlirOpOperandGetNextUse(use2
);
1901 if (!mlirOpOperandIsNull(use2
)) {
1902 fprintf(stderr
, "ERROR: Next use should be null\n");
1906 MlirOperationState op2State
=
1907 mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op2"), loc
);
1908 MlirValue initialOperands2
[] = {constOneValue
};
1909 mlirOperationStateAddOperands(&op2State
, 1, initialOperands2
);
1910 MlirOperation op2
= mlirOperationCreate(&op2State
);
1912 MlirOpOperand use3
= mlirValueGetFirstUse(constOneValue
);
1913 fprintf(stderr
, "First use owner: ");
1914 mlirOperationPrint(mlirOpOperandGetOwner(use3
), printToStderr
, NULL
);
1915 fprintf(stderr
, "\n");
1916 // CHECK: First use owner: "dummy.op2"
1918 use3
= mlirOpOperandGetNextUse(mlirValueGetFirstUse(constOneValue
));
1919 fprintf(stderr
, "Second use owner: ");
1920 mlirOperationPrint(mlirOpOperandGetOwner(use3
), printToStderr
, NULL
);
1921 fprintf(stderr
, "\n");
1922 // CHECK: Second use owner: "dummy.op"
1924 MlirAttribute indexTwoLiteral
=
1925 mlirAttributeParseGet(ctx
, mlirStringRefCreateFromCString("2 : index"));
1926 MlirNamedAttribute indexTwoValueAttr
= mlirNamedAttributeGet(
1927 mlirIdentifierGet(ctx
, mlirStringRefCreateFromCString("value")),
1929 MlirOperationState constTwoState
= mlirOperationStateGet(
1930 mlirStringRefCreateFromCString("arith.constant"), loc
);
1931 mlirOperationStateAddResults(&constTwoState
, 1, &indexType
);
1932 mlirOperationStateAddAttributes(&constTwoState
, 1, &indexTwoValueAttr
);
1933 MlirOperation constTwo
= mlirOperationCreate(&constTwoState
);
1934 MlirValue constTwoValue
= mlirOperationGetResult(constTwo
, 0);
1936 mlirValueReplaceAllUsesOfWith(constOneValue
, constTwoValue
);
1938 use3
= mlirValueGetFirstUse(constOneValue
);
1939 if (!mlirOpOperandIsNull(use3
)) {
1940 fprintf(stderr
, "ERROR: Use should be null\n");
1944 MlirOpOperand use4
= mlirValueGetFirstUse(constTwoValue
);
1945 fprintf(stderr
, "First replacement use owner: ");
1946 mlirOperationPrint(mlirOpOperandGetOwner(use4
), printToStderr
, NULL
);
1947 fprintf(stderr
, "\n");
1948 // CHECK: First replacement use owner: "dummy.op"
1950 use4
= mlirOpOperandGetNextUse(mlirValueGetFirstUse(constTwoValue
));
1951 fprintf(stderr
, "Second replacement use owner: ");
1952 mlirOperationPrint(mlirOpOperandGetOwner(use4
), printToStderr
, NULL
);
1953 fprintf(stderr
, "\n");
1954 // CHECK: Second replacement use owner: "dummy.op2"
1956 mlirOperationDestroy(op
);
1957 mlirOperationDestroy(op2
);
1958 mlirOperationDestroy(constZero
);
1959 mlirOperationDestroy(constOne
);
1960 mlirOperationDestroy(constTwo
);
1961 mlirContextDestroy(ctx
);
1966 /// Tests clone APIs.
1967 int testClone(void) {
1968 fprintf(stderr
, "@testClone\n");
1969 // CHECK-LABEL: @testClone
1971 MlirContext ctx
= mlirContextCreate();
1972 registerAllUpstreamDialects(ctx
);
1974 mlirContextGetOrLoadDialect(ctx
, mlirStringRefCreateFromCString("func"));
1975 mlirContextGetOrLoadDialect(ctx
, mlirStringRefCreateFromCString("arith"));
1976 MlirLocation loc
= mlirLocationUnknownGet(ctx
);
1977 MlirType indexType
= mlirIndexTypeGet(ctx
);
1978 MlirStringRef valueStringRef
= mlirStringRefCreateFromCString("value");
1980 MlirAttribute indexZeroLiteral
=
1981 mlirAttributeParseGet(ctx
, mlirStringRefCreateFromCString("0 : index"));
1982 MlirNamedAttribute indexZeroValueAttr
= mlirNamedAttributeGet(
1983 mlirIdentifierGet(ctx
, valueStringRef
), indexZeroLiteral
);
1984 MlirOperationState constZeroState
= mlirOperationStateGet(
1985 mlirStringRefCreateFromCString("arith.constant"), loc
);
1986 mlirOperationStateAddResults(&constZeroState
, 1, &indexType
);
1987 mlirOperationStateAddAttributes(&constZeroState
, 1, &indexZeroValueAttr
);
1988 MlirOperation constZero
= mlirOperationCreate(&constZeroState
);
1990 MlirAttribute indexOneLiteral
=
1991 mlirAttributeParseGet(ctx
, mlirStringRefCreateFromCString("1 : index"));
1992 MlirOperation constOne
= mlirOperationClone(constZero
);
1993 mlirOperationSetAttributeByName(constOne
, valueStringRef
, indexOneLiteral
);
1995 mlirOperationPrint(constZero
, printToStderr
, NULL
);
1996 mlirOperationPrint(constOne
, printToStderr
, NULL
);
1997 // CHECK: arith.constant 0 : index
1998 // CHECK: arith.constant 1 : index
2000 mlirOperationDestroy(constZero
);
2001 mlirOperationDestroy(constOne
);
2002 mlirContextDestroy(ctx
);
2006 // Wraps a diagnostic into additional text we can match against.
2007 MlirLogicalResult
errorHandler(MlirDiagnostic diagnostic
, void *userData
) {
2008 fprintf(stderr
, "processing diagnostic (userData: %" PRIdPTR
") <<\n",
2009 (intptr_t)userData
);
2010 mlirDiagnosticPrint(diagnostic
, printToStderr
, NULL
);
2011 fprintf(stderr
, "\n");
2012 MlirLocation loc
= mlirDiagnosticGetLocation(diagnostic
);
2013 mlirLocationPrint(loc
, printToStderr
, NULL
);
2014 assert(mlirDiagnosticGetNumNotes(diagnostic
) == 0);
2015 fprintf(stderr
, "\n>> end of diagnostic (userData: %" PRIdPTR
")\n",
2016 (intptr_t)userData
);
2017 return mlirLogicalResultSuccess();
2020 // Logs when the delete user data callback is called
2021 static void deleteUserData(void *userData
) {
2022 fprintf(stderr
, "deleting user data (userData: %" PRIdPTR
")\n",
2023 (intptr_t)userData
);
2026 int testTypeID(MlirContext ctx
) {
2027 fprintf(stderr
, "@testTypeID\n");
2029 // Test getting and comparing type and attribute type ids.
2030 MlirType i32
= mlirIntegerTypeGet(ctx
, 32);
2031 MlirTypeID i32ID
= mlirTypeGetTypeID(i32
);
2032 MlirType ui32
= mlirIntegerTypeUnsignedGet(ctx
, 32);
2033 MlirTypeID ui32ID
= mlirTypeGetTypeID(ui32
);
2034 MlirType f32
= mlirF32TypeGet(ctx
);
2035 MlirTypeID f32ID
= mlirTypeGetTypeID(f32
);
2036 MlirAttribute i32Attr
= mlirIntegerAttrGet(i32
, 1);
2037 MlirTypeID i32AttrID
= mlirAttributeGetTypeID(i32Attr
);
2039 if (mlirTypeIDIsNull(i32ID
) || mlirTypeIDIsNull(ui32ID
) ||
2040 mlirTypeIDIsNull(f32ID
) || mlirTypeIDIsNull(i32AttrID
)) {
2041 fprintf(stderr
, "ERROR: Expected type ids to be present\n");
2045 if (!mlirTypeIDEqual(i32ID
, ui32ID
) ||
2046 mlirTypeIDHashValue(i32ID
) != mlirTypeIDHashValue(ui32ID
)) {
2049 "ERROR: Expected different integer types to have the same type id\n");
2053 if (mlirTypeIDEqual(i32ID
, f32ID
)) {
2055 "ERROR: Expected integer type id to not equal float type id\n");
2059 if (mlirTypeIDEqual(i32ID
, i32AttrID
)) {
2060 fprintf(stderr
, "ERROR: Expected integer type id to not equal integer "
2061 "attribute type id\n");
2065 MlirLocation loc
= mlirLocationUnknownGet(ctx
);
2066 MlirType indexType
= mlirIndexTypeGet(ctx
);
2067 MlirStringRef valueStringRef
= mlirStringRefCreateFromCString("value");
2069 // Create a registered operation, which should have a type id.
2070 MlirAttribute indexZeroLiteral
=
2071 mlirAttributeParseGet(ctx
, mlirStringRefCreateFromCString("0 : index"));
2072 MlirNamedAttribute indexZeroValueAttr
= mlirNamedAttributeGet(
2073 mlirIdentifierGet(ctx
, valueStringRef
), indexZeroLiteral
);
2074 MlirOperationState constZeroState
= mlirOperationStateGet(
2075 mlirStringRefCreateFromCString("arith.constant"), loc
);
2076 mlirOperationStateAddResults(&constZeroState
, 1, &indexType
);
2077 mlirOperationStateAddAttributes(&constZeroState
, 1, &indexZeroValueAttr
);
2078 MlirOperation constZero
= mlirOperationCreate(&constZeroState
);
2080 if (!mlirOperationVerify(constZero
)) {
2081 fprintf(stderr
, "ERROR: Expected operation to verify correctly\n");
2085 if (mlirOperationIsNull(constZero
)) {
2086 fprintf(stderr
, "ERROR: Expected registered operation to be present\n");
2090 MlirTypeID registeredOpID
= mlirOperationGetTypeID(constZero
);
2092 if (mlirTypeIDIsNull(registeredOpID
)) {
2094 "ERROR: Expected registered operation type id to be present\n");
2098 // Create an unregistered operation, which should not have a type id.
2099 mlirContextSetAllowUnregisteredDialects(ctx
, true);
2100 MlirOperationState opState
=
2101 mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op"), loc
);
2102 MlirOperation unregisteredOp
= mlirOperationCreate(&opState
);
2103 if (mlirOperationIsNull(unregisteredOp
)) {
2104 fprintf(stderr
, "ERROR: Expected unregistered operation to be present\n");
2108 MlirTypeID unregisteredOpID
= mlirOperationGetTypeID(unregisteredOp
);
2110 if (!mlirTypeIDIsNull(unregisteredOpID
)) {
2112 "ERROR: Expected unregistered operation type id to be null\n");
2116 mlirOperationDestroy(constZero
);
2117 mlirOperationDestroy(unregisteredOp
);
2122 int testSymbolTable(MlirContext ctx
) {
2123 fprintf(stderr
, "@testSymbolTable\n");
2125 const char *moduleString
= "func.func private @foo()"
2126 "func.func private @bar()";
2127 const char *otherModuleString
= "func.func private @qux()"
2128 "func.func private @foo()";
2131 mlirModuleCreateParse(ctx
, mlirStringRefCreateFromCString(moduleString
));
2132 MlirModule otherModule
= mlirModuleCreateParse(
2133 ctx
, mlirStringRefCreateFromCString(otherModuleString
));
2135 MlirSymbolTable symbolTable
=
2136 mlirSymbolTableCreate(mlirModuleGetOperation(module
));
2138 MlirOperation funcFoo
=
2139 mlirSymbolTableLookup(symbolTable
, mlirStringRefCreateFromCString("foo"));
2140 if (mlirOperationIsNull(funcFoo
))
2143 MlirOperation funcBar
=
2144 mlirSymbolTableLookup(symbolTable
, mlirStringRefCreateFromCString("bar"));
2145 if (mlirOperationEqual(funcFoo
, funcBar
))
2148 MlirOperation missing
=
2149 mlirSymbolTableLookup(symbolTable
, mlirStringRefCreateFromCString("qux"));
2150 if (!mlirOperationIsNull(missing
))
2153 MlirBlock moduleBody
= mlirModuleGetBody(module
);
2154 MlirBlock otherModuleBody
= mlirModuleGetBody(otherModule
);
2155 MlirOperation operation
= mlirBlockGetFirstOperation(otherModuleBody
);
2156 mlirOperationRemoveFromParent(operation
);
2157 mlirBlockAppendOwnedOperation(moduleBody
, operation
);
2159 // At this moment, the operation is still missing from the symbol table.
2160 MlirOperation stillMissing
=
2161 mlirSymbolTableLookup(symbolTable
, mlirStringRefCreateFromCString("qux"));
2162 if (!mlirOperationIsNull(stillMissing
))
2165 // After it is added to the symbol table, and not only the operation with
2166 // which the table is associated, it can be looked up.
2167 mlirSymbolTableInsert(symbolTable
, operation
);
2168 MlirOperation funcQux
=
2169 mlirSymbolTableLookup(symbolTable
, mlirStringRefCreateFromCString("qux"));
2170 if (!mlirOperationEqual(operation
, funcQux
))
2173 // Erasing from the symbol table also removes the operation.
2174 mlirSymbolTableErase(symbolTable
, funcBar
);
2175 MlirOperation nowMissing
=
2176 mlirSymbolTableLookup(symbolTable
, mlirStringRefCreateFromCString("bar"));
2177 if (!mlirOperationIsNull(nowMissing
))
2180 // Adding a symbol with the same name to the table should rename.
2181 MlirOperation duplicateNameOp
= mlirBlockGetFirstOperation(otherModuleBody
);
2182 mlirOperationRemoveFromParent(duplicateNameOp
);
2183 mlirBlockAppendOwnedOperation(moduleBody
, duplicateNameOp
);
2184 MlirAttribute newName
= mlirSymbolTableInsert(symbolTable
, duplicateNameOp
);
2185 MlirStringRef newNameStr
= mlirStringAttrGetValue(newName
);
2186 if (mlirStringRefEqual(newNameStr
, mlirStringRefCreateFromCString("foo")))
2188 MlirAttribute updatedName
= mlirOperationGetAttributeByName(
2189 duplicateNameOp
, mlirSymbolTableGetSymbolAttributeName());
2190 if (!mlirAttributeEqual(updatedName
, newName
))
2193 mlirOperationDump(mlirModuleGetOperation(module
));
2194 mlirOperationDump(mlirModuleGetOperation(otherModule
));
2196 // CHECK-LABEL: @testSymbolTable
2198 // CHECK: func private @foo
2199 // CHECK: func private @qux
2200 // CHECK: func private @foo{{.+}}
2206 mlirSymbolTableDestroy(symbolTable
);
2207 mlirModuleDestroy(module
);
2208 mlirModuleDestroy(otherModule
);
2217 void walkCallBack(MlirOperation op
, void *rootOpVoid
) {
2218 fprintf(stderr
, "%s: %s\n", ((callBackData
*)(rootOpVoid
))->x
,
2219 mlirIdentifierStr(mlirOperationGetName(op
)).data
);
2222 int testOperationWalk(MlirContext ctx
) {
2223 // CHECK-LABEL: @testOperationWalk
2224 fprintf(stderr
, "@testOperationWalk\n");
2226 const char *moduleString
= "module {\n"
2227 " func.func @foo() {\n"
2228 " %1 = arith.constant 10: i32\n"
2229 " arith.addi %1, %1: i32\n"
2234 mlirModuleCreateParse(ctx
, mlirStringRefCreateFromCString(moduleString
));
2237 data
.x
= "i love you";
2239 // CHECK: i love you: arith.constant
2240 // CHECK: i love you: arith.addi
2241 // CHECK: i love you: func.return
2242 // CHECK: i love you: func.func
2243 // CHECK: i love you: builtin.module
2244 mlirOperationWalk(mlirModuleGetOperation(module
), walkCallBack
,
2245 (void *)(&data
), MlirWalkPostOrder
);
2247 data
.x
= "i don't love you";
2248 // CHECK: i don't love you: builtin.module
2249 // CHECK: i don't love you: func.func
2250 // CHECK: i don't love you: arith.constant
2251 // CHECK: i don't love you: arith.addi
2252 // CHECK: i don't love you: func.return
2253 mlirOperationWalk(mlirModuleGetOperation(module
), walkCallBack
,
2254 (void *)(&data
), MlirWalkPreOrder
);
2255 mlirModuleDestroy(module
);
2259 int testDialectRegistry(void) {
2260 fprintf(stderr
, "@testDialectRegistry\n");
2262 MlirDialectRegistry registry
= mlirDialectRegistryCreate();
2263 if (mlirDialectRegistryIsNull(registry
)) {
2264 fprintf(stderr
, "ERROR: Expected registry to be present\n");
2268 MlirDialectHandle stdHandle
= mlirGetDialectHandle__func__();
2269 mlirDialectHandleInsertDialect(stdHandle
, registry
);
2271 MlirContext ctx
= mlirContextCreate();
2272 if (mlirContextGetNumRegisteredDialects(ctx
) != 0) {
2274 "ERROR: Expected no dialects to be registered to new context\n");
2277 mlirContextAppendDialectRegistry(ctx
, registry
);
2278 if (mlirContextGetNumRegisteredDialects(ctx
) != 1) {
2279 fprintf(stderr
, "ERROR: Expected the dialect in the registry to be "
2280 "registered to the context\n");
2283 mlirContextDestroy(ctx
);
2284 mlirDialectRegistryDestroy(registry
);
2289 void testExplicitThreadPools(void) {
2290 MlirLlvmThreadPool threadPool
= mlirLlvmThreadPoolCreate();
2291 MlirDialectRegistry registry
= mlirDialectRegistryCreate();
2292 mlirRegisterAllDialects(registry
);
2293 MlirContext context
=
2294 mlirContextCreateWithRegistry(registry
, /*threadingEnabled=*/false);
2295 mlirContextSetThreadPool(context
, threadPool
);
2296 mlirContextDestroy(context
);
2297 mlirDialectRegistryDestroy(registry
);
2298 mlirLlvmThreadPoolDestroy(threadPool
);
2301 void testDiagnostics(void) {
2302 MlirContext ctx
= mlirContextCreate();
2303 MlirDiagnosticHandlerID id
= mlirContextAttachDiagnosticHandler(
2304 ctx
, errorHandler
, (void *)42, deleteUserData
);
2305 fprintf(stderr
, "@test_diagnostics\n");
2306 MlirLocation unknownLoc
= mlirLocationUnknownGet(ctx
);
2307 mlirEmitError(unknownLoc
, "test diagnostics");
2308 MlirAttribute unknownAttr
= mlirLocationGetAttribute(unknownLoc
);
2309 MlirLocation unknownClone
= mlirLocationFromAttribute(unknownAttr
);
2310 mlirEmitError(unknownClone
, "test clone");
2311 MlirLocation fileLineColLoc
= mlirLocationFileLineColGet(
2312 ctx
, mlirStringRefCreateFromCString("file.c"), 1, 2);
2313 mlirEmitError(fileLineColLoc
, "test diagnostics");
2314 MlirLocation callSiteLoc
= mlirLocationCallSiteGet(
2315 mlirLocationFileLineColGet(
2316 ctx
, mlirStringRefCreateFromCString("other-file.c"), 2, 3),
2318 mlirEmitError(callSiteLoc
, "test diagnostics");
2319 MlirLocation null
= {0};
2320 MlirLocation nameLoc
=
2321 mlirLocationNameGet(ctx
, mlirStringRefCreateFromCString("named"), null
);
2322 mlirEmitError(nameLoc
, "test diagnostics");
2323 MlirLocation locs
[2] = {nameLoc
, callSiteLoc
};
2324 MlirAttribute nullAttr
= {0};
2325 MlirLocation fusedLoc
= mlirLocationFusedGet(ctx
, 2, locs
, nullAttr
);
2326 mlirEmitError(fusedLoc
, "test diagnostics");
2327 mlirContextDetachDiagnosticHandler(ctx
, id
);
2328 mlirEmitError(unknownLoc
, "more test diagnostics");
2329 // CHECK-LABEL: @test_diagnostics
2330 // CHECK: processing diagnostic (userData: 42) <<
2331 // CHECK: test diagnostics
2332 // CHECK: loc(unknown)
2333 // CHECK: processing diagnostic (userData: 42) <<
2334 // CHECK: test clone
2335 // CHECK: loc(unknown)
2336 // CHECK: >> end of diagnostic (userData: 42)
2337 // CHECK: processing diagnostic (userData: 42) <<
2338 // CHECK: test diagnostics
2339 // CHECK: loc("file.c":1:2)
2340 // CHECK: >> end of diagnostic (userData: 42)
2341 // CHECK: processing diagnostic (userData: 42) <<
2342 // CHECK: test diagnostics
2343 // CHECK: loc(callsite("other-file.c":2:3 at "file.c":1:2))
2344 // CHECK: >> end of diagnostic (userData: 42)
2345 // CHECK: processing diagnostic (userData: 42) <<
2346 // CHECK: test diagnostics
2347 // CHECK: loc("named")
2348 // CHECK: >> end of diagnostic (userData: 42)
2349 // CHECK: processing diagnostic (userData: 42) <<
2350 // CHECK: test diagnostics
2351 // CHECK: loc(fused["named", callsite("other-file.c":2:3 at "file.c":1:2)])
2352 // CHECK: deleting user data (userData: 42)
2353 // CHECK-NOT: processing diagnostic
2354 // CHECK: more test diagnostics
2355 mlirContextDestroy(ctx
);
2359 MlirContext ctx
= mlirContextCreate();
2360 registerAllUpstreamDialects(ctx
);
2361 mlirContextGetOrLoadDialect(ctx
, mlirStringRefCreateFromCString("func"));
2362 mlirContextGetOrLoadDialect(ctx
, mlirStringRefCreateFromCString("memref"));
2363 mlirContextGetOrLoadDialect(ctx
, mlirStringRefCreateFromCString("shape"));
2364 mlirContextGetOrLoadDialect(ctx
, mlirStringRefCreateFromCString("scf"));
2366 if (constructAndTraverseIr(ctx
))
2368 buildWithInsertionsAndPrint(ctx
);
2369 if (createOperationWithTypeInference(ctx
))
2372 if (printBuiltinTypes(ctx
))
2374 if (printBuiltinAttributes(ctx
))
2376 if (printAffineMap(ctx
))
2378 if (printAffineExpr(ctx
))
2380 if (affineMapFromExprs(ctx
))
2382 if (printIntegerSet(ctx
))
2384 if (registerOnlyStd())
2386 if (testBackreferences())
2392 if (testTypeID(ctx
))
2394 if (testSymbolTable(ctx
))
2396 if (testDialectRegistry())
2398 if (testOperationWalk(ctx
))
2401 testExplicitThreadPools();
2404 // CHECK: DESTROY MAIN CONTEXT
2405 // CHECK: reportResourceDelete: resource_i64_blob
2406 fprintf(stderr
, "DESTROY MAIN CONTEXT\n");
2407 mlirContextDestroy(ctx
);