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/Standard.h" 20 #include "mlir-c/IntegerSet.h" 21 #include "mlir-c/Registration.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 31 void populateLoopBody(MlirContext ctx, MlirBlock loopBody, 32 MlirLocation location, MlirBlock funcBody) { 33 MlirValue iv = mlirBlockGetArgument(loopBody, 0); 34 MlirValue funcArg0 = mlirBlockGetArgument(funcBody, 0); 35 MlirValue funcArg1 = mlirBlockGetArgument(funcBody, 1); 36 MlirType f32Type = 37 mlirTypeParseGet(ctx, mlirStringRefCreateFromCString("f32")); 38 39 MlirOperationState loadLHSState = mlirOperationStateGet( 40 mlirStringRefCreateFromCString("memref.load"), location); 41 MlirValue loadLHSOperands[] = {funcArg0, iv}; 42 mlirOperationStateAddOperands(&loadLHSState, 2, loadLHSOperands); 43 mlirOperationStateAddResults(&loadLHSState, 1, &f32Type); 44 MlirOperation loadLHS = mlirOperationCreate(&loadLHSState); 45 mlirBlockAppendOwnedOperation(loopBody, loadLHS); 46 47 MlirOperationState loadRHSState = mlirOperationStateGet( 48 mlirStringRefCreateFromCString("memref.load"), location); 49 MlirValue loadRHSOperands[] = {funcArg1, iv}; 50 mlirOperationStateAddOperands(&loadRHSState, 2, loadRHSOperands); 51 mlirOperationStateAddResults(&loadRHSState, 1, &f32Type); 52 MlirOperation loadRHS = mlirOperationCreate(&loadRHSState); 53 mlirBlockAppendOwnedOperation(loopBody, loadRHS); 54 55 MlirOperationState addState = mlirOperationStateGet( 56 mlirStringRefCreateFromCString("arith.addf"), location); 57 MlirValue addOperands[] = {mlirOperationGetResult(loadLHS, 0), 58 mlirOperationGetResult(loadRHS, 0)}; 59 mlirOperationStateAddOperands(&addState, 2, addOperands); 60 mlirOperationStateAddResults(&addState, 1, &f32Type); 61 MlirOperation add = mlirOperationCreate(&addState); 62 mlirBlockAppendOwnedOperation(loopBody, add); 63 64 MlirOperationState storeState = mlirOperationStateGet( 65 mlirStringRefCreateFromCString("memref.store"), location); 66 MlirValue storeOperands[] = {mlirOperationGetResult(add, 0), funcArg0, iv}; 67 mlirOperationStateAddOperands(&storeState, 3, storeOperands); 68 MlirOperation store = mlirOperationCreate(&storeState); 69 mlirBlockAppendOwnedOperation(loopBody, store); 70 71 MlirOperationState yieldState = mlirOperationStateGet( 72 mlirStringRefCreateFromCString("scf.yield"), location); 73 MlirOperation yield = mlirOperationCreate(&yieldState); 74 mlirBlockAppendOwnedOperation(loopBody, yield); 75 } 76 77 MlirModule makeAndDumpAdd(MlirContext ctx, MlirLocation location) { 78 MlirModule moduleOp = mlirModuleCreateEmpty(location); 79 MlirBlock moduleBody = mlirModuleGetBody(moduleOp); 80 81 MlirType memrefType = 82 mlirTypeParseGet(ctx, mlirStringRefCreateFromCString("memref<?xf32>")); 83 MlirType funcBodyArgTypes[] = {memrefType, memrefType}; 84 MlirRegion funcBodyRegion = mlirRegionCreate(); 85 MlirBlock funcBody = mlirBlockCreate( 86 sizeof(funcBodyArgTypes) / sizeof(MlirType), funcBodyArgTypes); 87 mlirRegionAppendOwnedBlock(funcBodyRegion, funcBody); 88 89 MlirAttribute funcTypeAttr = mlirAttributeParseGet( 90 ctx, 91 mlirStringRefCreateFromCString("(memref<?xf32>, memref<?xf32>) -> ()")); 92 MlirAttribute funcNameAttr = 93 mlirAttributeParseGet(ctx, mlirStringRefCreateFromCString("\"add\"")); 94 MlirNamedAttribute funcAttrs[] = { 95 mlirNamedAttributeGet( 96 mlirIdentifierGet(ctx, mlirStringRefCreateFromCString("type")), 97 funcTypeAttr), 98 mlirNamedAttributeGet( 99 mlirIdentifierGet(ctx, mlirStringRefCreateFromCString("sym_name")), 100 funcNameAttr)}; 101 MlirOperationState funcState = mlirOperationStateGet( 102 mlirStringRefCreateFromCString("builtin.func"), location); 103 mlirOperationStateAddAttributes(&funcState, 2, funcAttrs); 104 mlirOperationStateAddOwnedRegions(&funcState, 1, &funcBodyRegion); 105 MlirOperation func = mlirOperationCreate(&funcState); 106 mlirBlockInsertOwnedOperation(moduleBody, 0, func); 107 108 MlirType indexType = 109 mlirTypeParseGet(ctx, mlirStringRefCreateFromCString("index")); 110 MlirAttribute indexZeroLiteral = 111 mlirAttributeParseGet(ctx, mlirStringRefCreateFromCString("0 : index")); 112 MlirNamedAttribute indexZeroValueAttr = mlirNamedAttributeGet( 113 mlirIdentifierGet(ctx, mlirStringRefCreateFromCString("value")), 114 indexZeroLiteral); 115 MlirOperationState constZeroState = mlirOperationStateGet( 116 mlirStringRefCreateFromCString("arith.constant"), location); 117 mlirOperationStateAddResults(&constZeroState, 1, &indexType); 118 mlirOperationStateAddAttributes(&constZeroState, 1, &indexZeroValueAttr); 119 MlirOperation constZero = mlirOperationCreate(&constZeroState); 120 mlirBlockAppendOwnedOperation(funcBody, constZero); 121 122 MlirValue funcArg0 = mlirBlockGetArgument(funcBody, 0); 123 MlirValue constZeroValue = mlirOperationGetResult(constZero, 0); 124 MlirValue dimOperands[] = {funcArg0, constZeroValue}; 125 MlirOperationState dimState = mlirOperationStateGet( 126 mlirStringRefCreateFromCString("memref.dim"), location); 127 mlirOperationStateAddOperands(&dimState, 2, dimOperands); 128 mlirOperationStateAddResults(&dimState, 1, &indexType); 129 MlirOperation dim = mlirOperationCreate(&dimState); 130 mlirBlockAppendOwnedOperation(funcBody, dim); 131 132 MlirRegion loopBodyRegion = mlirRegionCreate(); 133 MlirBlock loopBody = mlirBlockCreate(0, NULL); 134 mlirBlockAddArgument(loopBody, indexType); 135 mlirRegionAppendOwnedBlock(loopBodyRegion, loopBody); 136 137 MlirAttribute indexOneLiteral = 138 mlirAttributeParseGet(ctx, mlirStringRefCreateFromCString("1 : index")); 139 MlirNamedAttribute indexOneValueAttr = mlirNamedAttributeGet( 140 mlirIdentifierGet(ctx, mlirStringRefCreateFromCString("value")), 141 indexOneLiteral); 142 MlirOperationState constOneState = mlirOperationStateGet( 143 mlirStringRefCreateFromCString("arith.constant"), location); 144 mlirOperationStateAddResults(&constOneState, 1, &indexType); 145 mlirOperationStateAddAttributes(&constOneState, 1, &indexOneValueAttr); 146 MlirOperation constOne = mlirOperationCreate(&constOneState); 147 mlirBlockAppendOwnedOperation(funcBody, constOne); 148 149 MlirValue dimValue = mlirOperationGetResult(dim, 0); 150 MlirValue constOneValue = mlirOperationGetResult(constOne, 0); 151 MlirValue loopOperands[] = {constZeroValue, dimValue, constOneValue}; 152 MlirOperationState loopState = mlirOperationStateGet( 153 mlirStringRefCreateFromCString("scf.for"), location); 154 mlirOperationStateAddOperands(&loopState, 3, loopOperands); 155 mlirOperationStateAddOwnedRegions(&loopState, 1, &loopBodyRegion); 156 MlirOperation loop = mlirOperationCreate(&loopState); 157 mlirBlockAppendOwnedOperation(funcBody, loop); 158 159 populateLoopBody(ctx, loopBody, location, funcBody); 160 161 MlirOperationState retState = mlirOperationStateGet( 162 mlirStringRefCreateFromCString("std.return"), location); 163 MlirOperation ret = mlirOperationCreate(&retState); 164 mlirBlockAppendOwnedOperation(funcBody, ret); 165 166 MlirOperation module = mlirModuleGetOperation(moduleOp); 167 mlirOperationDump(module); 168 // clang-format off 169 // CHECK: module { 170 // CHECK: func @add(%[[ARG0:.*]]: memref<?xf32>, %[[ARG1:.*]]: memref<?xf32>) { 171 // CHECK: %[[C0:.*]] = arith.constant 0 : index 172 // CHECK: %[[DIM:.*]] = memref.dim %[[ARG0]], %[[C0]] : memref<?xf32> 173 // CHECK: %[[C1:.*]] = arith.constant 1 : index 174 // CHECK: scf.for %[[I:.*]] = %[[C0]] to %[[DIM]] step %[[C1]] { 175 // CHECK: %[[LHS:.*]] = memref.load %[[ARG0]][%[[I]]] : memref<?xf32> 176 // CHECK: %[[RHS:.*]] = memref.load %[[ARG1]][%[[I]]] : memref<?xf32> 177 // CHECK: %[[SUM:.*]] = arith.addf %[[LHS]], %[[RHS]] : f32 178 // CHECK: memref.store %[[SUM]], %[[ARG0]][%[[I]]] : memref<?xf32> 179 // CHECK: } 180 // CHECK: return 181 // CHECK: } 182 // CHECK: } 183 // clang-format on 184 185 return moduleOp; 186 } 187 188 struct OpListNode { 189 MlirOperation op; 190 struct OpListNode *next; 191 }; 192 typedef struct OpListNode OpListNode; 193 194 struct ModuleStats { 195 unsigned numOperations; 196 unsigned numAttributes; 197 unsigned numBlocks; 198 unsigned numRegions; 199 unsigned numValues; 200 unsigned numBlockArguments; 201 unsigned numOpResults; 202 }; 203 typedef struct ModuleStats ModuleStats; 204 205 int collectStatsSingle(OpListNode *head, ModuleStats *stats) { 206 MlirOperation operation = head->op; 207 stats->numOperations += 1; 208 stats->numValues += mlirOperationGetNumResults(operation); 209 stats->numAttributes += mlirOperationGetNumAttributes(operation); 210 211 unsigned numRegions = mlirOperationGetNumRegions(operation); 212 213 stats->numRegions += numRegions; 214 215 intptr_t numResults = mlirOperationGetNumResults(operation); 216 for (intptr_t i = 0; i < numResults; ++i) { 217 MlirValue result = mlirOperationGetResult(operation, i); 218 if (!mlirValueIsAOpResult(result)) 219 return 1; 220 if (mlirValueIsABlockArgument(result)) 221 return 2; 222 if (!mlirOperationEqual(operation, mlirOpResultGetOwner(result))) 223 return 3; 224 if (i != mlirOpResultGetResultNumber(result)) 225 return 4; 226 ++stats->numOpResults; 227 } 228 229 for (unsigned i = 0; i < numRegions; ++i) { 230 MlirRegion region = mlirOperationGetRegion(operation, i); 231 for (MlirBlock block = mlirRegionGetFirstBlock(region); 232 !mlirBlockIsNull(block); block = mlirBlockGetNextInRegion(block)) { 233 ++stats->numBlocks; 234 intptr_t numArgs = mlirBlockGetNumArguments(block); 235 stats->numValues += numArgs; 236 for (intptr_t j = 0; j < numArgs; ++j) { 237 MlirValue arg = mlirBlockGetArgument(block, j); 238 if (!mlirValueIsABlockArgument(arg)) 239 return 5; 240 if (mlirValueIsAOpResult(arg)) 241 return 6; 242 if (!mlirBlockEqual(block, mlirBlockArgumentGetOwner(arg))) 243 return 7; 244 if (j != mlirBlockArgumentGetArgNumber(arg)) 245 return 8; 246 ++stats->numBlockArguments; 247 } 248 249 for (MlirOperation child = mlirBlockGetFirstOperation(block); 250 !mlirOperationIsNull(child); 251 child = mlirOperationGetNextInBlock(child)) { 252 OpListNode *node = malloc(sizeof(OpListNode)); 253 node->op = child; 254 node->next = head->next; 255 head->next = node; 256 } 257 } 258 } 259 return 0; 260 } 261 262 int collectStats(MlirOperation operation) { 263 OpListNode *head = malloc(sizeof(OpListNode)); 264 head->op = operation; 265 head->next = NULL; 266 267 ModuleStats stats; 268 stats.numOperations = 0; 269 stats.numAttributes = 0; 270 stats.numBlocks = 0; 271 stats.numRegions = 0; 272 stats.numValues = 0; 273 stats.numBlockArguments = 0; 274 stats.numOpResults = 0; 275 276 do { 277 int retval = collectStatsSingle(head, &stats); 278 if (retval) 279 return retval; 280 OpListNode *next = head->next; 281 free(head); 282 head = next; 283 } while (head); 284 285 if (stats.numValues != stats.numBlockArguments + stats.numOpResults) 286 return 100; 287 288 fprintf(stderr, "@stats\n"); 289 fprintf(stderr, "Number of operations: %u\n", stats.numOperations); 290 fprintf(stderr, "Number of attributes: %u\n", stats.numAttributes); 291 fprintf(stderr, "Number of blocks: %u\n", stats.numBlocks); 292 fprintf(stderr, "Number of regions: %u\n", stats.numRegions); 293 fprintf(stderr, "Number of values: %u\n", stats.numValues); 294 fprintf(stderr, "Number of block arguments: %u\n", stats.numBlockArguments); 295 fprintf(stderr, "Number of op results: %u\n", stats.numOpResults); 296 // clang-format off 297 // CHECK-LABEL: @stats 298 // CHECK: Number of operations: 12 299 // CHECK: Number of attributes: 4 300 // CHECK: Number of blocks: 3 301 // CHECK: Number of regions: 3 302 // CHECK: Number of values: 9 303 // CHECK: Number of block arguments: 3 304 // CHECK: Number of op results: 6 305 // clang-format on 306 return 0; 307 } 308 309 static void printToStderr(MlirStringRef str, void *userData) { 310 (void)userData; 311 fwrite(str.data, 1, str.length, stderr); 312 } 313 314 static void printFirstOfEach(MlirContext ctx, MlirOperation operation) { 315 // Assuming we are given a module, go to the first operation of the first 316 // function. 317 MlirRegion region = mlirOperationGetRegion(operation, 0); 318 MlirBlock block = mlirRegionGetFirstBlock(region); 319 operation = mlirBlockGetFirstOperation(block); 320 region = mlirOperationGetRegion(operation, 0); 321 MlirOperation parentOperation = operation; 322 block = mlirRegionGetFirstBlock(region); 323 operation = mlirBlockGetFirstOperation(block); 324 assert(mlirModuleIsNull(mlirModuleFromOperation(operation))); 325 326 // Verify that parent operation and block report correctly. 327 // CHECK: Parent operation eq: 1 328 fprintf(stderr, "Parent operation eq: %d\n", 329 mlirOperationEqual(mlirOperationGetParentOperation(operation), 330 parentOperation)); 331 // CHECK: Block eq: 1 332 fprintf(stderr, "Block eq: %d\n", 333 mlirBlockEqual(mlirOperationGetBlock(operation), block)); 334 // CHECK: Block parent operation eq: 1 335 fprintf( 336 stderr, "Block parent operation eq: %d\n", 337 mlirOperationEqual(mlirBlockGetParentOperation(block), parentOperation)); 338 // CHECK: Block parent region eq: 1 339 fprintf(stderr, "Block parent region eq: %d\n", 340 mlirRegionEqual(mlirBlockGetParentRegion(block), region)); 341 342 // In the module we created, the first operation of the first function is 343 // an "memref.dim", which has an attribute and a single result that we can 344 // use to test the printing mechanism. 345 mlirBlockPrint(block, printToStderr, NULL); 346 fprintf(stderr, "\n"); 347 fprintf(stderr, "First operation: "); 348 mlirOperationPrint(operation, printToStderr, NULL); 349 fprintf(stderr, "\n"); 350 // clang-format off 351 // CHECK: %[[C0:.*]] = arith.constant 0 : index 352 // CHECK: %[[DIM:.*]] = memref.dim %{{.*}}, %[[C0]] : memref<?xf32> 353 // CHECK: %[[C1:.*]] = arith.constant 1 : index 354 // CHECK: scf.for %[[I:.*]] = %[[C0]] to %[[DIM]] step %[[C1]] { 355 // CHECK: %[[LHS:.*]] = memref.load %{{.*}}[%[[I]]] : memref<?xf32> 356 // CHECK: %[[RHS:.*]] = memref.load %{{.*}}[%[[I]]] : memref<?xf32> 357 // CHECK: %[[SUM:.*]] = arith.addf %[[LHS]], %[[RHS]] : f32 358 // CHECK: memref.store %[[SUM]], %{{.*}}[%[[I]]] : memref<?xf32> 359 // CHECK: } 360 // CHECK: return 361 // CHECK: First operation: {{.*}} = arith.constant 0 : index 362 // clang-format on 363 364 // Get the operation name and print it. 365 MlirIdentifier ident = mlirOperationGetName(operation); 366 MlirStringRef identStr = mlirIdentifierStr(ident); 367 fprintf(stderr, "Operation name: '"); 368 for (size_t i = 0; i < identStr.length; ++i) 369 fputc(identStr.data[i], stderr); 370 fprintf(stderr, "'\n"); 371 // CHECK: Operation name: 'arith.constant' 372 373 // Get the identifier again and verify equal. 374 MlirIdentifier identAgain = mlirIdentifierGet(ctx, identStr); 375 fprintf(stderr, "Identifier equal: %d\n", 376 mlirIdentifierEqual(ident, identAgain)); 377 // CHECK: Identifier equal: 1 378 379 // Get the block terminator and print it. 380 MlirOperation terminator = mlirBlockGetTerminator(block); 381 fprintf(stderr, "Terminator: "); 382 mlirOperationPrint(terminator, printToStderr, NULL); 383 fprintf(stderr, "\n"); 384 // CHECK: Terminator: return 385 386 // Get the attribute by index. 387 MlirNamedAttribute namedAttr0 = mlirOperationGetAttribute(operation, 0); 388 fprintf(stderr, "Get attr 0: "); 389 mlirAttributePrint(namedAttr0.attribute, printToStderr, NULL); 390 fprintf(stderr, "\n"); 391 // CHECK: Get attr 0: 0 : index 392 393 // Now re-get the attribute by name. 394 MlirAttribute attr0ByName = mlirOperationGetAttributeByName( 395 operation, mlirIdentifierStr(namedAttr0.name)); 396 fprintf(stderr, "Get attr 0 by name: "); 397 mlirAttributePrint(attr0ByName, printToStderr, NULL); 398 fprintf(stderr, "\n"); 399 // CHECK: Get attr 0 by name: 0 : index 400 401 // Get a non-existing attribute and assert that it is null (sanity). 402 fprintf(stderr, "does_not_exist is null: %d\n", 403 mlirAttributeIsNull(mlirOperationGetAttributeByName( 404 operation, mlirStringRefCreateFromCString("does_not_exist")))); 405 // CHECK: does_not_exist is null: 1 406 407 // Get result 0 and its type. 408 MlirValue value = mlirOperationGetResult(operation, 0); 409 fprintf(stderr, "Result 0: "); 410 mlirValuePrint(value, printToStderr, NULL); 411 fprintf(stderr, "\n"); 412 fprintf(stderr, "Value is null: %d\n", mlirValueIsNull(value)); 413 // CHECK: Result 0: {{.*}} = arith.constant 0 : index 414 // CHECK: Value is null: 0 415 416 MlirType type = mlirValueGetType(value); 417 fprintf(stderr, "Result 0 type: "); 418 mlirTypePrint(type, printToStderr, NULL); 419 fprintf(stderr, "\n"); 420 // CHECK: Result 0 type: index 421 422 // Set a custom attribute. 423 mlirOperationSetAttributeByName(operation, 424 mlirStringRefCreateFromCString("custom_attr"), 425 mlirBoolAttrGet(ctx, 1)); 426 fprintf(stderr, "Op with set attr: "); 427 mlirOperationPrint(operation, printToStderr, NULL); 428 fprintf(stderr, "\n"); 429 // CHECK: Op with set attr: {{.*}} {custom_attr = true} 430 431 // Remove the attribute. 432 fprintf(stderr, "Remove attr: %d\n", 433 mlirOperationRemoveAttributeByName( 434 operation, mlirStringRefCreateFromCString("custom_attr"))); 435 fprintf(stderr, "Remove attr again: %d\n", 436 mlirOperationRemoveAttributeByName( 437 operation, mlirStringRefCreateFromCString("custom_attr"))); 438 fprintf(stderr, "Removed attr is null: %d\n", 439 mlirAttributeIsNull(mlirOperationGetAttributeByName( 440 operation, mlirStringRefCreateFromCString("custom_attr")))); 441 // CHECK: Remove attr: 1 442 // CHECK: Remove attr again: 0 443 // CHECK: Removed attr is null: 1 444 445 // Add a large attribute to verify printing flags. 446 int64_t eltsShape[] = {4}; 447 int32_t eltsData[] = {1, 2, 3, 4}; 448 mlirOperationSetAttributeByName( 449 operation, mlirStringRefCreateFromCString("elts"), 450 mlirDenseElementsAttrInt32Get( 451 mlirRankedTensorTypeGet(1, eltsShape, mlirIntegerTypeGet(ctx, 32), 452 mlirAttributeGetNull()), 453 4, eltsData)); 454 MlirOpPrintingFlags flags = mlirOpPrintingFlagsCreate(); 455 mlirOpPrintingFlagsElideLargeElementsAttrs(flags, 2); 456 mlirOpPrintingFlagsPrintGenericOpForm(flags); 457 mlirOpPrintingFlagsEnableDebugInfo(flags, /*prettyForm=*/0); 458 mlirOpPrintingFlagsUseLocalScope(flags); 459 fprintf(stderr, "Op print with all flags: "); 460 mlirOperationPrintWithFlags(operation, flags, printToStderr, NULL); 461 fprintf(stderr, "\n"); 462 // clang-format off 463 // CHECK: Op print with all flags: %{{.*}} = "arith.constant"() {elts = opaque<"_", "0xDEADBEEF"> : tensor<4xi32>, value = 0 : index} : () -> index loc(unknown) 464 // clang-format on 465 466 mlirOpPrintingFlagsDestroy(flags); 467 } 468 469 static int constructAndTraverseIr(MlirContext ctx) { 470 MlirLocation location = mlirLocationUnknownGet(ctx); 471 472 MlirModule moduleOp = makeAndDumpAdd(ctx, location); 473 MlirOperation module = mlirModuleGetOperation(moduleOp); 474 assert(!mlirModuleIsNull(mlirModuleFromOperation(module))); 475 476 int errcode = collectStats(module); 477 if (errcode) 478 return errcode; 479 480 printFirstOfEach(ctx, module); 481 482 mlirModuleDestroy(moduleOp); 483 return 0; 484 } 485 486 /// Creates an operation with a region containing multiple blocks with 487 /// operations and dumps it. The blocks and operations are inserted using 488 /// block/operation-relative API and their final order is checked. 489 static void buildWithInsertionsAndPrint(MlirContext ctx) { 490 MlirLocation loc = mlirLocationUnknownGet(ctx); 491 mlirContextSetAllowUnregisteredDialects(ctx, true); 492 493 MlirRegion owningRegion = mlirRegionCreate(); 494 MlirBlock nullBlock = mlirRegionGetFirstBlock(owningRegion); 495 MlirOperationState state = mlirOperationStateGet( 496 mlirStringRefCreateFromCString("insertion.order.test"), loc); 497 mlirOperationStateAddOwnedRegions(&state, 1, &owningRegion); 498 MlirOperation op = mlirOperationCreate(&state); 499 MlirRegion region = mlirOperationGetRegion(op, 0); 500 501 // Use integer types of different bitwidth as block arguments in order to 502 // differentiate blocks. 503 MlirType i1 = mlirIntegerTypeGet(ctx, 1); 504 MlirType i2 = mlirIntegerTypeGet(ctx, 2); 505 MlirType i3 = mlirIntegerTypeGet(ctx, 3); 506 MlirType i4 = mlirIntegerTypeGet(ctx, 4); 507 MlirBlock block1 = mlirBlockCreate(1, &i1); 508 MlirBlock block2 = mlirBlockCreate(1, &i2); 509 MlirBlock block3 = mlirBlockCreate(1, &i3); 510 MlirBlock block4 = mlirBlockCreate(1, &i4); 511 // Insert blocks so as to obtain the 1-2-3-4 order, 512 mlirRegionInsertOwnedBlockBefore(region, nullBlock, block3); 513 mlirRegionInsertOwnedBlockBefore(region, block3, block2); 514 mlirRegionInsertOwnedBlockAfter(region, nullBlock, block1); 515 mlirRegionInsertOwnedBlockAfter(region, block3, block4); 516 517 MlirOperationState op1State = 518 mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op1"), loc); 519 MlirOperationState op2State = 520 mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op2"), loc); 521 MlirOperationState op3State = 522 mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op3"), loc); 523 MlirOperationState op4State = 524 mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op4"), loc); 525 MlirOperationState op5State = 526 mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op5"), loc); 527 MlirOperationState op6State = 528 mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op6"), loc); 529 MlirOperationState op7State = 530 mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op7"), loc); 531 MlirOperation op1 = mlirOperationCreate(&op1State); 532 MlirOperation op2 = mlirOperationCreate(&op2State); 533 MlirOperation op3 = mlirOperationCreate(&op3State); 534 MlirOperation op4 = mlirOperationCreate(&op4State); 535 MlirOperation op5 = mlirOperationCreate(&op5State); 536 MlirOperation op6 = mlirOperationCreate(&op6State); 537 MlirOperation op7 = mlirOperationCreate(&op7State); 538 539 // Insert operations in the first block so as to obtain the 1-2-3-4 order. 540 MlirOperation nullOperation = mlirBlockGetFirstOperation(block1); 541 assert(mlirOperationIsNull(nullOperation)); 542 mlirBlockInsertOwnedOperationBefore(block1, nullOperation, op3); 543 mlirBlockInsertOwnedOperationBefore(block1, op3, op2); 544 mlirBlockInsertOwnedOperationAfter(block1, nullOperation, op1); 545 mlirBlockInsertOwnedOperationAfter(block1, op3, op4); 546 547 // Append operations to the rest of blocks to make them non-empty and thus 548 // printable. 549 mlirBlockAppendOwnedOperation(block2, op5); 550 mlirBlockAppendOwnedOperation(block3, op6); 551 mlirBlockAppendOwnedOperation(block4, op7); 552 553 mlirOperationDump(op); 554 mlirOperationDestroy(op); 555 mlirContextSetAllowUnregisteredDialects(ctx, false); 556 // clang-format off 557 // CHECK-LABEL: "insertion.order.test" 558 // CHECK: ^{{.*}}(%{{.*}}: i1 559 // CHECK: "dummy.op1" 560 // CHECK-NEXT: "dummy.op2" 561 // CHECK-NEXT: "dummy.op3" 562 // CHECK-NEXT: "dummy.op4" 563 // CHECK: ^{{.*}}(%{{.*}}: i2 564 // CHECK: "dummy.op5" 565 // CHECK: ^{{.*}}(%{{.*}}: i3 566 // CHECK: "dummy.op6" 567 // CHECK: ^{{.*}}(%{{.*}}: i4 568 // CHECK: "dummy.op7" 569 // clang-format on 570 } 571 572 /// Creates operations with type inference and tests various failure modes. 573 static int createOperationWithTypeInference(MlirContext ctx) { 574 MlirLocation loc = mlirLocationUnknownGet(ctx); 575 MlirAttribute iAttr = mlirIntegerAttrGet(mlirIntegerTypeGet(ctx, 32), 4); 576 577 // The shape.const_size op implements result type inference and is only used 578 // for that reason. 579 MlirOperationState state = mlirOperationStateGet( 580 mlirStringRefCreateFromCString("shape.const_size"), loc); 581 MlirNamedAttribute valueAttr = mlirNamedAttributeGet( 582 mlirIdentifierGet(ctx, mlirStringRefCreateFromCString("value")), iAttr); 583 mlirOperationStateAddAttributes(&state, 1, &valueAttr); 584 mlirOperationStateEnableResultTypeInference(&state); 585 586 // Expect result type inference to succeed. 587 MlirOperation op = mlirOperationCreate(&state); 588 if (mlirOperationIsNull(op)) { 589 fprintf(stderr, "ERROR: Result type inference unexpectedly failed"); 590 return 1; 591 } 592 593 // CHECK: RESULT_TYPE_INFERENCE: !shape.size 594 fprintf(stderr, "RESULT_TYPE_INFERENCE: "); 595 mlirTypeDump(mlirValueGetType(mlirOperationGetResult(op, 0))); 596 fprintf(stderr, "\n"); 597 mlirOperationDestroy(op); 598 return 0; 599 } 600 601 /// Dumps instances of all builtin types to check that C API works correctly. 602 /// Additionally, performs simple identity checks that a builtin type 603 /// constructed with C API can be inspected and has the expected type. The 604 /// latter achieves full coverage of C API for builtin types. Returns 0 on 605 /// success and a non-zero error code on failure. 606 static int printBuiltinTypes(MlirContext ctx) { 607 // Integer types. 608 MlirType i32 = mlirIntegerTypeGet(ctx, 32); 609 MlirType si32 = mlirIntegerTypeSignedGet(ctx, 32); 610 MlirType ui32 = mlirIntegerTypeUnsignedGet(ctx, 32); 611 if (!mlirTypeIsAInteger(i32) || mlirTypeIsAF32(i32)) 612 return 1; 613 if (!mlirTypeIsAInteger(si32) || !mlirIntegerTypeIsSigned(si32)) 614 return 2; 615 if (!mlirTypeIsAInteger(ui32) || !mlirIntegerTypeIsUnsigned(ui32)) 616 return 3; 617 if (mlirTypeEqual(i32, ui32) || mlirTypeEqual(i32, si32)) 618 return 4; 619 if (mlirIntegerTypeGetWidth(i32) != mlirIntegerTypeGetWidth(si32)) 620 return 5; 621 fprintf(stderr, "@types\n"); 622 mlirTypeDump(i32); 623 fprintf(stderr, "\n"); 624 mlirTypeDump(si32); 625 fprintf(stderr, "\n"); 626 mlirTypeDump(ui32); 627 fprintf(stderr, "\n"); 628 // CHECK-LABEL: @types 629 // CHECK: i32 630 // CHECK: si32 631 // CHECK: ui32 632 633 // Index type. 634 MlirType index = mlirIndexTypeGet(ctx); 635 if (!mlirTypeIsAIndex(index)) 636 return 6; 637 mlirTypeDump(index); 638 fprintf(stderr, "\n"); 639 // CHECK: index 640 641 // Floating-point types. 642 MlirType bf16 = mlirBF16TypeGet(ctx); 643 MlirType f16 = mlirF16TypeGet(ctx); 644 MlirType f32 = mlirF32TypeGet(ctx); 645 MlirType f64 = mlirF64TypeGet(ctx); 646 if (!mlirTypeIsABF16(bf16)) 647 return 7; 648 if (!mlirTypeIsAF16(f16)) 649 return 9; 650 if (!mlirTypeIsAF32(f32)) 651 return 10; 652 if (!mlirTypeIsAF64(f64)) 653 return 11; 654 mlirTypeDump(bf16); 655 fprintf(stderr, "\n"); 656 mlirTypeDump(f16); 657 fprintf(stderr, "\n"); 658 mlirTypeDump(f32); 659 fprintf(stderr, "\n"); 660 mlirTypeDump(f64); 661 fprintf(stderr, "\n"); 662 // CHECK: bf16 663 // CHECK: f16 664 // CHECK: f32 665 // CHECK: f64 666 667 // None type. 668 MlirType none = mlirNoneTypeGet(ctx); 669 if (!mlirTypeIsANone(none)) 670 return 12; 671 mlirTypeDump(none); 672 fprintf(stderr, "\n"); 673 // CHECK: none 674 675 // Complex type. 676 MlirType cplx = mlirComplexTypeGet(f32); 677 if (!mlirTypeIsAComplex(cplx) || 678 !mlirTypeEqual(mlirComplexTypeGetElementType(cplx), f32)) 679 return 13; 680 mlirTypeDump(cplx); 681 fprintf(stderr, "\n"); 682 // CHECK: complex<f32> 683 684 // Vector (and Shaped) type. ShapedType is a common base class for vectors, 685 // memrefs and tensors, one cannot create instances of this class so it is 686 // tested on an instance of vector type. 687 int64_t shape[] = {2, 3}; 688 MlirType vector = 689 mlirVectorTypeGet(sizeof(shape) / sizeof(int64_t), shape, f32); 690 if (!mlirTypeIsAVector(vector) || !mlirTypeIsAShaped(vector)) 691 return 14; 692 if (!mlirTypeEqual(mlirShapedTypeGetElementType(vector), f32) || 693 !mlirShapedTypeHasRank(vector) || mlirShapedTypeGetRank(vector) != 2 || 694 mlirShapedTypeGetDimSize(vector, 0) != 2 || 695 mlirShapedTypeIsDynamicDim(vector, 0) || 696 mlirShapedTypeGetDimSize(vector, 1) != 3 || 697 !mlirShapedTypeHasStaticShape(vector)) 698 return 15; 699 mlirTypeDump(vector); 700 fprintf(stderr, "\n"); 701 // CHECK: vector<2x3xf32> 702 703 // Ranked tensor type. 704 MlirType rankedTensor = mlirRankedTensorTypeGet( 705 sizeof(shape) / sizeof(int64_t), shape, f32, mlirAttributeGetNull()); 706 if (!mlirTypeIsATensor(rankedTensor) || 707 !mlirTypeIsARankedTensor(rankedTensor) || 708 !mlirAttributeIsNull(mlirRankedTensorTypeGetEncoding(rankedTensor))) 709 return 16; 710 mlirTypeDump(rankedTensor); 711 fprintf(stderr, "\n"); 712 // CHECK: tensor<2x3xf32> 713 714 // Unranked tensor type. 715 MlirType unrankedTensor = mlirUnrankedTensorTypeGet(f32); 716 if (!mlirTypeIsATensor(unrankedTensor) || 717 !mlirTypeIsAUnrankedTensor(unrankedTensor) || 718 mlirShapedTypeHasRank(unrankedTensor)) 719 return 17; 720 mlirTypeDump(unrankedTensor); 721 fprintf(stderr, "\n"); 722 // CHECK: tensor<*xf32> 723 724 // MemRef type. 725 MlirAttribute memSpace2 = mlirIntegerAttrGet(mlirIntegerTypeGet(ctx, 64), 2); 726 MlirType memRef = mlirMemRefTypeContiguousGet( 727 f32, sizeof(shape) / sizeof(int64_t), shape, memSpace2); 728 if (!mlirTypeIsAMemRef(memRef) || 729 !mlirAttributeEqual(mlirMemRefTypeGetMemorySpace(memRef), memSpace2)) 730 return 18; 731 mlirTypeDump(memRef); 732 fprintf(stderr, "\n"); 733 // CHECK: memref<2x3xf32, 2> 734 735 // Unranked MemRef type. 736 MlirAttribute memSpace4 = mlirIntegerAttrGet(mlirIntegerTypeGet(ctx, 64), 4); 737 MlirType unrankedMemRef = mlirUnrankedMemRefTypeGet(f32, memSpace4); 738 if (!mlirTypeIsAUnrankedMemRef(unrankedMemRef) || 739 mlirTypeIsAMemRef(unrankedMemRef) || 740 !mlirAttributeEqual(mlirUnrankedMemrefGetMemorySpace(unrankedMemRef), 741 memSpace4)) 742 return 19; 743 mlirTypeDump(unrankedMemRef); 744 fprintf(stderr, "\n"); 745 // CHECK: memref<*xf32, 4> 746 747 // Tuple type. 748 MlirType types[] = {unrankedMemRef, f32}; 749 MlirType tuple = mlirTupleTypeGet(ctx, 2, types); 750 if (!mlirTypeIsATuple(tuple) || mlirTupleTypeGetNumTypes(tuple) != 2 || 751 !mlirTypeEqual(mlirTupleTypeGetType(tuple, 0), unrankedMemRef) || 752 !mlirTypeEqual(mlirTupleTypeGetType(tuple, 1), f32)) 753 return 20; 754 mlirTypeDump(tuple); 755 fprintf(stderr, "\n"); 756 // CHECK: tuple<memref<*xf32, 4>, f32> 757 758 // Function type. 759 MlirType funcInputs[2] = {mlirIndexTypeGet(ctx), mlirIntegerTypeGet(ctx, 1)}; 760 MlirType funcResults[3] = {mlirIntegerTypeGet(ctx, 16), 761 mlirIntegerTypeGet(ctx, 32), 762 mlirIntegerTypeGet(ctx, 64)}; 763 MlirType funcType = mlirFunctionTypeGet(ctx, 2, funcInputs, 3, funcResults); 764 if (mlirFunctionTypeGetNumInputs(funcType) != 2) 765 return 21; 766 if (mlirFunctionTypeGetNumResults(funcType) != 3) 767 return 22; 768 if (!mlirTypeEqual(funcInputs[0], mlirFunctionTypeGetInput(funcType, 0)) || 769 !mlirTypeEqual(funcInputs[1], mlirFunctionTypeGetInput(funcType, 1))) 770 return 23; 771 if (!mlirTypeEqual(funcResults[0], mlirFunctionTypeGetResult(funcType, 0)) || 772 !mlirTypeEqual(funcResults[1], mlirFunctionTypeGetResult(funcType, 1)) || 773 !mlirTypeEqual(funcResults[2], mlirFunctionTypeGetResult(funcType, 2))) 774 return 24; 775 mlirTypeDump(funcType); 776 fprintf(stderr, "\n"); 777 // CHECK: (index, i1) -> (i16, i32, i64) 778 779 return 0; 780 } 781 782 void callbackSetFixedLengthString(const char *data, intptr_t len, 783 void *userData) { 784 strncpy(userData, data, len); 785 } 786 787 bool stringIsEqual(const char *lhs, MlirStringRef rhs) { 788 if (strlen(lhs) != rhs.length) { 789 return false; 790 } 791 return !strncmp(lhs, rhs.data, rhs.length); 792 } 793 794 int printBuiltinAttributes(MlirContext ctx) { 795 MlirAttribute floating = 796 mlirFloatAttrDoubleGet(ctx, mlirF64TypeGet(ctx), 2.0); 797 if (!mlirAttributeIsAFloat(floating) || 798 fabs(mlirFloatAttrGetValueDouble(floating) - 2.0) > 1E-6) 799 return 1; 800 fprintf(stderr, "@attrs\n"); 801 mlirAttributeDump(floating); 802 // CHECK-LABEL: @attrs 803 // CHECK: 2.000000e+00 : f64 804 805 // Exercise mlirAttributeGetType() just for the first one. 806 MlirType floatingType = mlirAttributeGetType(floating); 807 mlirTypeDump(floatingType); 808 // CHECK: f64 809 810 MlirAttribute integer = mlirIntegerAttrGet(mlirIntegerTypeGet(ctx, 32), 42); 811 if (!mlirAttributeIsAInteger(integer) || 812 mlirIntegerAttrGetValueInt(integer) != 42) 813 return 2; 814 mlirAttributeDump(integer); 815 // CHECK: 42 : i32 816 817 MlirAttribute boolean = mlirBoolAttrGet(ctx, 1); 818 if (!mlirAttributeIsABool(boolean) || !mlirBoolAttrGetValue(boolean)) 819 return 3; 820 mlirAttributeDump(boolean); 821 // CHECK: true 822 823 const char data[] = "abcdefghijklmnopqestuvwxyz"; 824 MlirAttribute opaque = 825 mlirOpaqueAttrGet(ctx, mlirStringRefCreateFromCString("std"), 3, data, 826 mlirNoneTypeGet(ctx)); 827 if (!mlirAttributeIsAOpaque(opaque) || 828 !stringIsEqual("std", mlirOpaqueAttrGetDialectNamespace(opaque))) 829 return 4; 830 831 MlirStringRef opaqueData = mlirOpaqueAttrGetData(opaque); 832 if (opaqueData.length != 3 || 833 strncmp(data, opaqueData.data, opaqueData.length)) 834 return 5; 835 mlirAttributeDump(opaque); 836 // CHECK: #std.abc 837 838 MlirAttribute string = 839 mlirStringAttrGet(ctx, mlirStringRefCreate(data + 3, 2)); 840 if (!mlirAttributeIsAString(string)) 841 return 6; 842 843 MlirStringRef stringValue = mlirStringAttrGetValue(string); 844 if (stringValue.length != 2 || 845 strncmp(data + 3, stringValue.data, stringValue.length)) 846 return 7; 847 mlirAttributeDump(string); 848 // CHECK: "de" 849 850 MlirAttribute flatSymbolRef = 851 mlirFlatSymbolRefAttrGet(ctx, mlirStringRefCreate(data + 5, 3)); 852 if (!mlirAttributeIsAFlatSymbolRef(flatSymbolRef)) 853 return 8; 854 855 MlirStringRef flatSymbolRefValue = 856 mlirFlatSymbolRefAttrGetValue(flatSymbolRef); 857 if (flatSymbolRefValue.length != 3 || 858 strncmp(data + 5, flatSymbolRefValue.data, flatSymbolRefValue.length)) 859 return 9; 860 mlirAttributeDump(flatSymbolRef); 861 // CHECK: @fgh 862 863 MlirAttribute symbols[] = {flatSymbolRef, flatSymbolRef}; 864 MlirAttribute symbolRef = 865 mlirSymbolRefAttrGet(ctx, mlirStringRefCreate(data + 8, 2), 2, symbols); 866 if (!mlirAttributeIsASymbolRef(symbolRef) || 867 mlirSymbolRefAttrGetNumNestedReferences(symbolRef) != 2 || 868 !mlirAttributeEqual(mlirSymbolRefAttrGetNestedReference(symbolRef, 0), 869 flatSymbolRef) || 870 !mlirAttributeEqual(mlirSymbolRefAttrGetNestedReference(symbolRef, 1), 871 flatSymbolRef)) 872 return 10; 873 874 MlirStringRef symbolRefLeaf = mlirSymbolRefAttrGetLeafReference(symbolRef); 875 MlirStringRef symbolRefRoot = mlirSymbolRefAttrGetRootReference(symbolRef); 876 if (symbolRefLeaf.length != 3 || 877 strncmp(data + 5, symbolRefLeaf.data, symbolRefLeaf.length) || 878 symbolRefRoot.length != 2 || 879 strncmp(data + 8, symbolRefRoot.data, symbolRefRoot.length)) 880 return 11; 881 mlirAttributeDump(symbolRef); 882 // CHECK: @ij::@fgh::@fgh 883 884 MlirAttribute type = mlirTypeAttrGet(mlirF32TypeGet(ctx)); 885 if (!mlirAttributeIsAType(type) || 886 !mlirTypeEqual(mlirF32TypeGet(ctx), mlirTypeAttrGetValue(type))) 887 return 12; 888 mlirAttributeDump(type); 889 // CHECK: f32 890 891 MlirAttribute unit = mlirUnitAttrGet(ctx); 892 if (!mlirAttributeIsAUnit(unit)) 893 return 13; 894 mlirAttributeDump(unit); 895 // CHECK: unit 896 897 int64_t shape[] = {1, 2}; 898 899 int bools[] = {0, 1}; 900 uint8_t uints8[] = {0u, 1u}; 901 int8_t ints8[] = {0, 1}; 902 uint32_t uints32[] = {0u, 1u}; 903 int32_t ints32[] = {0, 1}; 904 uint64_t uints64[] = {0u, 1u}; 905 int64_t ints64[] = {0, 1}; 906 float floats[] = {0.0f, 1.0f}; 907 double doubles[] = {0.0, 1.0}; 908 MlirAttribute encoding = mlirAttributeGetNull(); 909 MlirAttribute boolElements = mlirDenseElementsAttrBoolGet( 910 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 1), encoding), 911 2, bools); 912 MlirAttribute uint8Elements = mlirDenseElementsAttrUInt8Get( 913 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeUnsignedGet(ctx, 8), 914 encoding), 915 2, uints8); 916 MlirAttribute int8Elements = mlirDenseElementsAttrInt8Get( 917 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 8), encoding), 918 2, ints8); 919 MlirAttribute uint32Elements = mlirDenseElementsAttrUInt32Get( 920 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeUnsignedGet(ctx, 32), 921 encoding), 922 2, uints32); 923 MlirAttribute int32Elements = mlirDenseElementsAttrInt32Get( 924 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 32), encoding), 925 2, ints32); 926 MlirAttribute uint64Elements = mlirDenseElementsAttrUInt64Get( 927 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeUnsignedGet(ctx, 64), 928 encoding), 929 2, uints64); 930 MlirAttribute int64Elements = mlirDenseElementsAttrInt64Get( 931 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 64), encoding), 932 2, ints64); 933 MlirAttribute floatElements = mlirDenseElementsAttrFloatGet( 934 mlirRankedTensorTypeGet(2, shape, mlirF32TypeGet(ctx), encoding), 2, 935 floats); 936 MlirAttribute doubleElements = mlirDenseElementsAttrDoubleGet( 937 mlirRankedTensorTypeGet(2, shape, mlirF64TypeGet(ctx), encoding), 2, 938 doubles); 939 940 if (!mlirAttributeIsADenseElements(boolElements) || 941 !mlirAttributeIsADenseElements(uint8Elements) || 942 !mlirAttributeIsADenseElements(int8Elements) || 943 !mlirAttributeIsADenseElements(uint32Elements) || 944 !mlirAttributeIsADenseElements(int32Elements) || 945 !mlirAttributeIsADenseElements(uint64Elements) || 946 !mlirAttributeIsADenseElements(int64Elements) || 947 !mlirAttributeIsADenseElements(floatElements) || 948 !mlirAttributeIsADenseElements(doubleElements)) 949 return 14; 950 951 if (mlirDenseElementsAttrGetBoolValue(boolElements, 1) != 1 || 952 mlirDenseElementsAttrGetUInt8Value(uint8Elements, 1) != 1 || 953 mlirDenseElementsAttrGetInt8Value(int8Elements, 1) != 1 || 954 mlirDenseElementsAttrGetUInt32Value(uint32Elements, 1) != 1 || 955 mlirDenseElementsAttrGetInt32Value(int32Elements, 1) != 1 || 956 mlirDenseElementsAttrGetUInt64Value(uint64Elements, 1) != 1 || 957 mlirDenseElementsAttrGetInt64Value(int64Elements, 1) != 1 || 958 fabsf(mlirDenseElementsAttrGetFloatValue(floatElements, 1) - 1.0f) > 959 1E-6f || 960 fabs(mlirDenseElementsAttrGetDoubleValue(doubleElements, 1) - 1.0) > 1E-6) 961 return 15; 962 963 mlirAttributeDump(boolElements); 964 mlirAttributeDump(uint8Elements); 965 mlirAttributeDump(int8Elements); 966 mlirAttributeDump(uint32Elements); 967 mlirAttributeDump(int32Elements); 968 mlirAttributeDump(uint64Elements); 969 mlirAttributeDump(int64Elements); 970 mlirAttributeDump(floatElements); 971 mlirAttributeDump(doubleElements); 972 // CHECK: dense<{{\[}}[false, true]]> : tensor<1x2xi1> 973 // CHECK: dense<{{\[}}[0, 1]]> : tensor<1x2xui8> 974 // CHECK: dense<{{\[}}[0, 1]]> : tensor<1x2xi8> 975 // CHECK: dense<{{\[}}[0, 1]]> : tensor<1x2xui32> 976 // CHECK: dense<{{\[}}[0, 1]]> : tensor<1x2xi32> 977 // CHECK: dense<{{\[}}[0, 1]]> : tensor<1x2xui64> 978 // CHECK: dense<{{\[}}[0, 1]]> : tensor<1x2xi64> 979 // CHECK: dense<{{\[}}[0.000000e+00, 1.000000e+00]]> : tensor<1x2xf32> 980 // CHECK: dense<{{\[}}[0.000000e+00, 1.000000e+00]]> : tensor<1x2xf64> 981 982 MlirAttribute splatBool = mlirDenseElementsAttrBoolSplatGet( 983 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 1), encoding), 984 1); 985 MlirAttribute splatUInt8 = mlirDenseElementsAttrUInt8SplatGet( 986 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeUnsignedGet(ctx, 8), 987 encoding), 988 1); 989 MlirAttribute splatInt8 = mlirDenseElementsAttrInt8SplatGet( 990 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 8), encoding), 991 1); 992 MlirAttribute splatUInt32 = mlirDenseElementsAttrUInt32SplatGet( 993 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeUnsignedGet(ctx, 32), 994 encoding), 995 1); 996 MlirAttribute splatInt32 = mlirDenseElementsAttrInt32SplatGet( 997 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 32), encoding), 998 1); 999 MlirAttribute splatUInt64 = mlirDenseElementsAttrUInt64SplatGet( 1000 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeUnsignedGet(ctx, 64), 1001 encoding), 1002 1); 1003 MlirAttribute splatInt64 = mlirDenseElementsAttrInt64SplatGet( 1004 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 64), encoding), 1005 1); 1006 MlirAttribute splatFloat = mlirDenseElementsAttrFloatSplatGet( 1007 mlirRankedTensorTypeGet(2, shape, mlirF32TypeGet(ctx), encoding), 1.0f); 1008 MlirAttribute splatDouble = mlirDenseElementsAttrDoubleSplatGet( 1009 mlirRankedTensorTypeGet(2, shape, mlirF64TypeGet(ctx), encoding), 1.0); 1010 1011 if (!mlirAttributeIsADenseElements(splatBool) || 1012 !mlirDenseElementsAttrIsSplat(splatBool) || 1013 !mlirAttributeIsADenseElements(splatUInt8) || 1014 !mlirDenseElementsAttrIsSplat(splatUInt8) || 1015 !mlirAttributeIsADenseElements(splatInt8) || 1016 !mlirDenseElementsAttrIsSplat(splatInt8) || 1017 !mlirAttributeIsADenseElements(splatUInt32) || 1018 !mlirDenseElementsAttrIsSplat(splatUInt32) || 1019 !mlirAttributeIsADenseElements(splatInt32) || 1020 !mlirDenseElementsAttrIsSplat(splatInt32) || 1021 !mlirAttributeIsADenseElements(splatUInt64) || 1022 !mlirDenseElementsAttrIsSplat(splatUInt64) || 1023 !mlirAttributeIsADenseElements(splatInt64) || 1024 !mlirDenseElementsAttrIsSplat(splatInt64) || 1025 !mlirAttributeIsADenseElements(splatFloat) || 1026 !mlirDenseElementsAttrIsSplat(splatFloat) || 1027 !mlirAttributeIsADenseElements(splatDouble) || 1028 !mlirDenseElementsAttrIsSplat(splatDouble)) 1029 return 16; 1030 1031 if (mlirDenseElementsAttrGetBoolSplatValue(splatBool) != 1 || 1032 mlirDenseElementsAttrGetUInt8SplatValue(splatUInt8) != 1 || 1033 mlirDenseElementsAttrGetInt8SplatValue(splatInt8) != 1 || 1034 mlirDenseElementsAttrGetUInt32SplatValue(splatUInt32) != 1 || 1035 mlirDenseElementsAttrGetInt32SplatValue(splatInt32) != 1 || 1036 mlirDenseElementsAttrGetUInt64SplatValue(splatUInt64) != 1 || 1037 mlirDenseElementsAttrGetInt64SplatValue(splatInt64) != 1 || 1038 fabsf(mlirDenseElementsAttrGetFloatSplatValue(splatFloat) - 1.0f) > 1039 1E-6f || 1040 fabs(mlirDenseElementsAttrGetDoubleSplatValue(splatDouble) - 1.0) > 1E-6) 1041 return 17; 1042 1043 uint8_t *uint8RawData = 1044 (uint8_t *)mlirDenseElementsAttrGetRawData(uint8Elements); 1045 int8_t *int8RawData = (int8_t *)mlirDenseElementsAttrGetRawData(int8Elements); 1046 uint32_t *uint32RawData = 1047 (uint32_t *)mlirDenseElementsAttrGetRawData(uint32Elements); 1048 int32_t *int32RawData = 1049 (int32_t *)mlirDenseElementsAttrGetRawData(int32Elements); 1050 uint64_t *uint64RawData = 1051 (uint64_t *)mlirDenseElementsAttrGetRawData(uint64Elements); 1052 int64_t *int64RawData = 1053 (int64_t *)mlirDenseElementsAttrGetRawData(int64Elements); 1054 float *floatRawData = (float *)mlirDenseElementsAttrGetRawData(floatElements); 1055 double *doubleRawData = 1056 (double *)mlirDenseElementsAttrGetRawData(doubleElements); 1057 if (uint8RawData[0] != 0u || uint8RawData[1] != 1u || int8RawData[0] != 0 || 1058 int8RawData[1] != 1 || uint32RawData[0] != 0u || uint32RawData[1] != 1u || 1059 int32RawData[0] != 0 || int32RawData[1] != 1 || uint64RawData[0] != 0u || 1060 uint64RawData[1] != 1u || int64RawData[0] != 0 || int64RawData[1] != 1 || 1061 floatRawData[0] != 0.0f || floatRawData[1] != 1.0f || 1062 doubleRawData[0] != 0.0 || doubleRawData[1] != 1.0) 1063 return 18; 1064 1065 mlirAttributeDump(splatBool); 1066 mlirAttributeDump(splatUInt8); 1067 mlirAttributeDump(splatInt8); 1068 mlirAttributeDump(splatUInt32); 1069 mlirAttributeDump(splatInt32); 1070 mlirAttributeDump(splatUInt64); 1071 mlirAttributeDump(splatInt64); 1072 mlirAttributeDump(splatFloat); 1073 mlirAttributeDump(splatDouble); 1074 // CHECK: dense<true> : tensor<1x2xi1> 1075 // CHECK: dense<1> : tensor<1x2xui8> 1076 // CHECK: dense<1> : tensor<1x2xi8> 1077 // CHECK: dense<1> : tensor<1x2xui32> 1078 // CHECK: dense<1> : tensor<1x2xi32> 1079 // CHECK: dense<1> : tensor<1x2xui64> 1080 // CHECK: dense<1> : tensor<1x2xi64> 1081 // CHECK: dense<1.000000e+00> : tensor<1x2xf32> 1082 // CHECK: dense<1.000000e+00> : tensor<1x2xf64> 1083 1084 mlirAttributeDump(mlirElementsAttrGetValue(floatElements, 2, uints64)); 1085 mlirAttributeDump(mlirElementsAttrGetValue(doubleElements, 2, uints64)); 1086 // CHECK: 1.000000e+00 : f32 1087 // CHECK: 1.000000e+00 : f64 1088 1089 int64_t indices[] = {0, 1}; 1090 int64_t one = 1; 1091 MlirAttribute indicesAttr = mlirDenseElementsAttrInt64Get( 1092 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 64), encoding), 1093 2, indices); 1094 MlirAttribute valuesAttr = mlirDenseElementsAttrFloatGet( 1095 mlirRankedTensorTypeGet(1, &one, mlirF32TypeGet(ctx), encoding), 1, 1096 floats); 1097 MlirAttribute sparseAttr = mlirSparseElementsAttribute( 1098 mlirRankedTensorTypeGet(2, shape, mlirF32TypeGet(ctx), encoding), 1099 indicesAttr, valuesAttr); 1100 mlirAttributeDump(sparseAttr); 1101 // CHECK: sparse<{{\[}}[0, 1]], 0.000000e+00> : tensor<1x2xf32> 1102 1103 return 0; 1104 } 1105 1106 int printAffineMap(MlirContext ctx) { 1107 MlirAffineMap emptyAffineMap = mlirAffineMapEmptyGet(ctx); 1108 MlirAffineMap affineMap = mlirAffineMapZeroResultGet(ctx, 3, 2); 1109 MlirAffineMap constAffineMap = mlirAffineMapConstantGet(ctx, 2); 1110 MlirAffineMap multiDimIdentityAffineMap = 1111 mlirAffineMapMultiDimIdentityGet(ctx, 3); 1112 MlirAffineMap minorIdentityAffineMap = 1113 mlirAffineMapMinorIdentityGet(ctx, 3, 2); 1114 unsigned permutation[] = {1, 2, 0}; 1115 MlirAffineMap permutationAffineMap = mlirAffineMapPermutationGet( 1116 ctx, sizeof(permutation) / sizeof(unsigned), permutation); 1117 1118 fprintf(stderr, "@affineMap\n"); 1119 mlirAffineMapDump(emptyAffineMap); 1120 mlirAffineMapDump(affineMap); 1121 mlirAffineMapDump(constAffineMap); 1122 mlirAffineMapDump(multiDimIdentityAffineMap); 1123 mlirAffineMapDump(minorIdentityAffineMap); 1124 mlirAffineMapDump(permutationAffineMap); 1125 // CHECK-LABEL: @affineMap 1126 // CHECK: () -> () 1127 // CHECK: (d0, d1, d2)[s0, s1] -> () 1128 // CHECK: () -> (2) 1129 // CHECK: (d0, d1, d2) -> (d0, d1, d2) 1130 // CHECK: (d0, d1, d2) -> (d1, d2) 1131 // CHECK: (d0, d1, d2) -> (d1, d2, d0) 1132 1133 if (!mlirAffineMapIsIdentity(emptyAffineMap) || 1134 mlirAffineMapIsIdentity(affineMap) || 1135 mlirAffineMapIsIdentity(constAffineMap) || 1136 !mlirAffineMapIsIdentity(multiDimIdentityAffineMap) || 1137 mlirAffineMapIsIdentity(minorIdentityAffineMap) || 1138 mlirAffineMapIsIdentity(permutationAffineMap)) 1139 return 1; 1140 1141 if (!mlirAffineMapIsMinorIdentity(emptyAffineMap) || 1142 mlirAffineMapIsMinorIdentity(affineMap) || 1143 !mlirAffineMapIsMinorIdentity(multiDimIdentityAffineMap) || 1144 !mlirAffineMapIsMinorIdentity(minorIdentityAffineMap) || 1145 mlirAffineMapIsMinorIdentity(permutationAffineMap)) 1146 return 2; 1147 1148 if (!mlirAffineMapIsEmpty(emptyAffineMap) || 1149 mlirAffineMapIsEmpty(affineMap) || mlirAffineMapIsEmpty(constAffineMap) || 1150 mlirAffineMapIsEmpty(multiDimIdentityAffineMap) || 1151 mlirAffineMapIsEmpty(minorIdentityAffineMap) || 1152 mlirAffineMapIsEmpty(permutationAffineMap)) 1153 return 3; 1154 1155 if (mlirAffineMapIsSingleConstant(emptyAffineMap) || 1156 mlirAffineMapIsSingleConstant(affineMap) || 1157 !mlirAffineMapIsSingleConstant(constAffineMap) || 1158 mlirAffineMapIsSingleConstant(multiDimIdentityAffineMap) || 1159 mlirAffineMapIsSingleConstant(minorIdentityAffineMap) || 1160 mlirAffineMapIsSingleConstant(permutationAffineMap)) 1161 return 4; 1162 1163 if (mlirAffineMapGetSingleConstantResult(constAffineMap) != 2) 1164 return 5; 1165 1166 if (mlirAffineMapGetNumDims(emptyAffineMap) != 0 || 1167 mlirAffineMapGetNumDims(affineMap) != 3 || 1168 mlirAffineMapGetNumDims(constAffineMap) != 0 || 1169 mlirAffineMapGetNumDims(multiDimIdentityAffineMap) != 3 || 1170 mlirAffineMapGetNumDims(minorIdentityAffineMap) != 3 || 1171 mlirAffineMapGetNumDims(permutationAffineMap) != 3) 1172 return 6; 1173 1174 if (mlirAffineMapGetNumSymbols(emptyAffineMap) != 0 || 1175 mlirAffineMapGetNumSymbols(affineMap) != 2 || 1176 mlirAffineMapGetNumSymbols(constAffineMap) != 0 || 1177 mlirAffineMapGetNumSymbols(multiDimIdentityAffineMap) != 0 || 1178 mlirAffineMapGetNumSymbols(minorIdentityAffineMap) != 0 || 1179 mlirAffineMapGetNumSymbols(permutationAffineMap) != 0) 1180 return 7; 1181 1182 if (mlirAffineMapGetNumResults(emptyAffineMap) != 0 || 1183 mlirAffineMapGetNumResults(affineMap) != 0 || 1184 mlirAffineMapGetNumResults(constAffineMap) != 1 || 1185 mlirAffineMapGetNumResults(multiDimIdentityAffineMap) != 3 || 1186 mlirAffineMapGetNumResults(minorIdentityAffineMap) != 2 || 1187 mlirAffineMapGetNumResults(permutationAffineMap) != 3) 1188 return 8; 1189 1190 if (mlirAffineMapGetNumInputs(emptyAffineMap) != 0 || 1191 mlirAffineMapGetNumInputs(affineMap) != 5 || 1192 mlirAffineMapGetNumInputs(constAffineMap) != 0 || 1193 mlirAffineMapGetNumInputs(multiDimIdentityAffineMap) != 3 || 1194 mlirAffineMapGetNumInputs(minorIdentityAffineMap) != 3 || 1195 mlirAffineMapGetNumInputs(permutationAffineMap) != 3) 1196 return 9; 1197 1198 if (!mlirAffineMapIsProjectedPermutation(emptyAffineMap) || 1199 !mlirAffineMapIsPermutation(emptyAffineMap) || 1200 mlirAffineMapIsProjectedPermutation(affineMap) || 1201 mlirAffineMapIsPermutation(affineMap) || 1202 mlirAffineMapIsProjectedPermutation(constAffineMap) || 1203 mlirAffineMapIsPermutation(constAffineMap) || 1204 !mlirAffineMapIsProjectedPermutation(multiDimIdentityAffineMap) || 1205 !mlirAffineMapIsPermutation(multiDimIdentityAffineMap) || 1206 !mlirAffineMapIsProjectedPermutation(minorIdentityAffineMap) || 1207 mlirAffineMapIsPermutation(minorIdentityAffineMap) || 1208 !mlirAffineMapIsProjectedPermutation(permutationAffineMap) || 1209 !mlirAffineMapIsPermutation(permutationAffineMap)) 1210 return 10; 1211 1212 intptr_t sub[] = {1}; 1213 1214 MlirAffineMap subMap = mlirAffineMapGetSubMap( 1215 multiDimIdentityAffineMap, sizeof(sub) / sizeof(intptr_t), sub); 1216 MlirAffineMap majorSubMap = 1217 mlirAffineMapGetMajorSubMap(multiDimIdentityAffineMap, 1); 1218 MlirAffineMap minorSubMap = 1219 mlirAffineMapGetMinorSubMap(multiDimIdentityAffineMap, 1); 1220 1221 mlirAffineMapDump(subMap); 1222 mlirAffineMapDump(majorSubMap); 1223 mlirAffineMapDump(minorSubMap); 1224 // CHECK: (d0, d1, d2) -> (d1) 1225 // CHECK: (d0, d1, d2) -> (d0) 1226 // CHECK: (d0, d1, d2) -> (d2) 1227 1228 return 0; 1229 } 1230 1231 int printAffineExpr(MlirContext ctx) { 1232 MlirAffineExpr affineDimExpr = mlirAffineDimExprGet(ctx, 5); 1233 MlirAffineExpr affineSymbolExpr = mlirAffineSymbolExprGet(ctx, 5); 1234 MlirAffineExpr affineConstantExpr = mlirAffineConstantExprGet(ctx, 5); 1235 MlirAffineExpr affineAddExpr = 1236 mlirAffineAddExprGet(affineDimExpr, affineSymbolExpr); 1237 MlirAffineExpr affineMulExpr = 1238 mlirAffineMulExprGet(affineDimExpr, affineSymbolExpr); 1239 MlirAffineExpr affineModExpr = 1240 mlirAffineModExprGet(affineDimExpr, affineSymbolExpr); 1241 MlirAffineExpr affineFloorDivExpr = 1242 mlirAffineFloorDivExprGet(affineDimExpr, affineSymbolExpr); 1243 MlirAffineExpr affineCeilDivExpr = 1244 mlirAffineCeilDivExprGet(affineDimExpr, affineSymbolExpr); 1245 1246 // Tests mlirAffineExprDump. 1247 fprintf(stderr, "@affineExpr\n"); 1248 mlirAffineExprDump(affineDimExpr); 1249 mlirAffineExprDump(affineSymbolExpr); 1250 mlirAffineExprDump(affineConstantExpr); 1251 mlirAffineExprDump(affineAddExpr); 1252 mlirAffineExprDump(affineMulExpr); 1253 mlirAffineExprDump(affineModExpr); 1254 mlirAffineExprDump(affineFloorDivExpr); 1255 mlirAffineExprDump(affineCeilDivExpr); 1256 // CHECK-LABEL: @affineExpr 1257 // CHECK: d5 1258 // CHECK: s5 1259 // CHECK: 5 1260 // CHECK: d5 + s5 1261 // CHECK: d5 * s5 1262 // CHECK: d5 mod s5 1263 // CHECK: d5 floordiv s5 1264 // CHECK: d5 ceildiv s5 1265 1266 // Tests methods of affine binary operation expression, takes add expression 1267 // as an example. 1268 mlirAffineExprDump(mlirAffineBinaryOpExprGetLHS(affineAddExpr)); 1269 mlirAffineExprDump(mlirAffineBinaryOpExprGetRHS(affineAddExpr)); 1270 // CHECK: d5 1271 // CHECK: s5 1272 1273 // Tests methods of affine dimension expression. 1274 if (mlirAffineDimExprGetPosition(affineDimExpr) != 5) 1275 return 1; 1276 1277 // Tests methods of affine symbol expression. 1278 if (mlirAffineSymbolExprGetPosition(affineSymbolExpr) != 5) 1279 return 2; 1280 1281 // Tests methods of affine constant expression. 1282 if (mlirAffineConstantExprGetValue(affineConstantExpr) != 5) 1283 return 3; 1284 1285 // Tests methods of affine expression. 1286 if (mlirAffineExprIsSymbolicOrConstant(affineDimExpr) || 1287 !mlirAffineExprIsSymbolicOrConstant(affineSymbolExpr) || 1288 !mlirAffineExprIsSymbolicOrConstant(affineConstantExpr) || 1289 mlirAffineExprIsSymbolicOrConstant(affineAddExpr) || 1290 mlirAffineExprIsSymbolicOrConstant(affineMulExpr) || 1291 mlirAffineExprIsSymbolicOrConstant(affineModExpr) || 1292 mlirAffineExprIsSymbolicOrConstant(affineFloorDivExpr) || 1293 mlirAffineExprIsSymbolicOrConstant(affineCeilDivExpr)) 1294 return 4; 1295 1296 if (!mlirAffineExprIsPureAffine(affineDimExpr) || 1297 !mlirAffineExprIsPureAffine(affineSymbolExpr) || 1298 !mlirAffineExprIsPureAffine(affineConstantExpr) || 1299 !mlirAffineExprIsPureAffine(affineAddExpr) || 1300 mlirAffineExprIsPureAffine(affineMulExpr) || 1301 mlirAffineExprIsPureAffine(affineModExpr) || 1302 mlirAffineExprIsPureAffine(affineFloorDivExpr) || 1303 mlirAffineExprIsPureAffine(affineCeilDivExpr)) 1304 return 5; 1305 1306 if (mlirAffineExprGetLargestKnownDivisor(affineDimExpr) != 1 || 1307 mlirAffineExprGetLargestKnownDivisor(affineSymbolExpr) != 1 || 1308 mlirAffineExprGetLargestKnownDivisor(affineConstantExpr) != 5 || 1309 mlirAffineExprGetLargestKnownDivisor(affineAddExpr) != 1 || 1310 mlirAffineExprGetLargestKnownDivisor(affineMulExpr) != 1 || 1311 mlirAffineExprGetLargestKnownDivisor(affineModExpr) != 1 || 1312 mlirAffineExprGetLargestKnownDivisor(affineFloorDivExpr) != 1 || 1313 mlirAffineExprGetLargestKnownDivisor(affineCeilDivExpr) != 1) 1314 return 6; 1315 1316 if (!mlirAffineExprIsMultipleOf(affineDimExpr, 1) || 1317 !mlirAffineExprIsMultipleOf(affineSymbolExpr, 1) || 1318 !mlirAffineExprIsMultipleOf(affineConstantExpr, 5) || 1319 !mlirAffineExprIsMultipleOf(affineAddExpr, 1) || 1320 !mlirAffineExprIsMultipleOf(affineMulExpr, 1) || 1321 !mlirAffineExprIsMultipleOf(affineModExpr, 1) || 1322 !mlirAffineExprIsMultipleOf(affineFloorDivExpr, 1) || 1323 !mlirAffineExprIsMultipleOf(affineCeilDivExpr, 1)) 1324 return 7; 1325 1326 if (!mlirAffineExprIsFunctionOfDim(affineDimExpr, 5) || 1327 mlirAffineExprIsFunctionOfDim(affineSymbolExpr, 5) || 1328 mlirAffineExprIsFunctionOfDim(affineConstantExpr, 5) || 1329 !mlirAffineExprIsFunctionOfDim(affineAddExpr, 5) || 1330 !mlirAffineExprIsFunctionOfDim(affineMulExpr, 5) || 1331 !mlirAffineExprIsFunctionOfDim(affineModExpr, 5) || 1332 !mlirAffineExprIsFunctionOfDim(affineFloorDivExpr, 5) || 1333 !mlirAffineExprIsFunctionOfDim(affineCeilDivExpr, 5)) 1334 return 8; 1335 1336 // Tests 'IsA' methods of affine binary operation expression. 1337 if (!mlirAffineExprIsAAdd(affineAddExpr)) 1338 return 9; 1339 1340 if (!mlirAffineExprIsAMul(affineMulExpr)) 1341 return 10; 1342 1343 if (!mlirAffineExprIsAMod(affineModExpr)) 1344 return 11; 1345 1346 if (!mlirAffineExprIsAFloorDiv(affineFloorDivExpr)) 1347 return 12; 1348 1349 if (!mlirAffineExprIsACeilDiv(affineCeilDivExpr)) 1350 return 13; 1351 1352 if (!mlirAffineExprIsABinary(affineAddExpr)) 1353 return 14; 1354 1355 // Test other 'IsA' method on affine expressions. 1356 if (!mlirAffineExprIsAConstant(affineConstantExpr)) 1357 return 15; 1358 1359 if (!mlirAffineExprIsADim(affineDimExpr)) 1360 return 16; 1361 1362 if (!mlirAffineExprIsASymbol(affineSymbolExpr)) 1363 return 17; 1364 1365 // Test equality and nullity. 1366 MlirAffineExpr otherDimExpr = mlirAffineDimExprGet(ctx, 5); 1367 if (!mlirAffineExprEqual(affineDimExpr, otherDimExpr)) 1368 return 18; 1369 1370 if (mlirAffineExprIsNull(affineDimExpr)) 1371 return 19; 1372 1373 return 0; 1374 } 1375 1376 int affineMapFromExprs(MlirContext ctx) { 1377 MlirAffineExpr affineDimExpr = mlirAffineDimExprGet(ctx, 0); 1378 MlirAffineExpr affineSymbolExpr = mlirAffineSymbolExprGet(ctx, 1); 1379 MlirAffineExpr exprs[] = {affineDimExpr, affineSymbolExpr}; 1380 MlirAffineMap map = mlirAffineMapGet(ctx, 3, 3, 2, exprs); 1381 1382 // CHECK-LABEL: @affineMapFromExprs 1383 fprintf(stderr, "@affineMapFromExprs"); 1384 // CHECK: (d0, d1, d2)[s0, s1, s2] -> (d0, s1) 1385 mlirAffineMapDump(map); 1386 1387 if (mlirAffineMapGetNumResults(map) != 2) 1388 return 1; 1389 1390 if (!mlirAffineExprEqual(mlirAffineMapGetResult(map, 0), affineDimExpr)) 1391 return 2; 1392 1393 if (!mlirAffineExprEqual(mlirAffineMapGetResult(map, 1), affineSymbolExpr)) 1394 return 3; 1395 1396 return 0; 1397 } 1398 1399 int printIntegerSet(MlirContext ctx) { 1400 MlirIntegerSet emptySet = mlirIntegerSetEmptyGet(ctx, 2, 1); 1401 1402 // CHECK-LABEL: @printIntegerSet 1403 fprintf(stderr, "@printIntegerSet"); 1404 1405 // CHECK: (d0, d1)[s0] : (1 == 0) 1406 mlirIntegerSetDump(emptySet); 1407 1408 if (!mlirIntegerSetIsCanonicalEmpty(emptySet)) 1409 return 1; 1410 1411 MlirIntegerSet anotherEmptySet = mlirIntegerSetEmptyGet(ctx, 2, 1); 1412 if (!mlirIntegerSetEqual(emptySet, anotherEmptySet)) 1413 return 2; 1414 1415 // Construct a set constrained by: 1416 // d0 - s0 == 0, 1417 // d1 - 42 >= 0. 1418 MlirAffineExpr negOne = mlirAffineConstantExprGet(ctx, -1); 1419 MlirAffineExpr negFortyTwo = mlirAffineConstantExprGet(ctx, -42); 1420 MlirAffineExpr d0 = mlirAffineDimExprGet(ctx, 0); 1421 MlirAffineExpr d1 = mlirAffineDimExprGet(ctx, 1); 1422 MlirAffineExpr s0 = mlirAffineSymbolExprGet(ctx, 0); 1423 MlirAffineExpr negS0 = mlirAffineMulExprGet(negOne, s0); 1424 MlirAffineExpr d0minusS0 = mlirAffineAddExprGet(d0, negS0); 1425 MlirAffineExpr d1minus42 = mlirAffineAddExprGet(d1, negFortyTwo); 1426 MlirAffineExpr constraints[] = {d0minusS0, d1minus42}; 1427 bool flags[] = {true, false}; 1428 1429 MlirIntegerSet set = mlirIntegerSetGet(ctx, 2, 1, 2, constraints, flags); 1430 // CHECK: (d0, d1)[s0] : ( 1431 // CHECK-DAG: d0 - s0 == 0 1432 // CHECK-DAG: d1 - 42 >= 0 1433 mlirIntegerSetDump(set); 1434 1435 // Transform d1 into s0. 1436 MlirAffineExpr s1 = mlirAffineSymbolExprGet(ctx, 1); 1437 MlirAffineExpr repl[] = {d0, s1}; 1438 MlirIntegerSet replaced = mlirIntegerSetReplaceGet(set, repl, &s0, 1, 2); 1439 // CHECK: (d0)[s0, s1] : ( 1440 // CHECK-DAG: d0 - s0 == 0 1441 // CHECK-DAG: s1 - 42 >= 0 1442 mlirIntegerSetDump(replaced); 1443 1444 if (mlirIntegerSetGetNumDims(set) != 2) 1445 return 3; 1446 if (mlirIntegerSetGetNumDims(replaced) != 1) 1447 return 4; 1448 1449 if (mlirIntegerSetGetNumSymbols(set) != 1) 1450 return 5; 1451 if (mlirIntegerSetGetNumSymbols(replaced) != 2) 1452 return 6; 1453 1454 if (mlirIntegerSetGetNumInputs(set) != 3) 1455 return 7; 1456 1457 if (mlirIntegerSetGetNumConstraints(set) != 2) 1458 return 8; 1459 1460 if (mlirIntegerSetGetNumEqualities(set) != 1) 1461 return 9; 1462 1463 if (mlirIntegerSetGetNumInequalities(set) != 1) 1464 return 10; 1465 1466 MlirAffineExpr cstr1 = mlirIntegerSetGetConstraint(set, 0); 1467 MlirAffineExpr cstr2 = mlirIntegerSetGetConstraint(set, 1); 1468 bool isEq1 = mlirIntegerSetIsConstraintEq(set, 0); 1469 bool isEq2 = mlirIntegerSetIsConstraintEq(set, 1); 1470 if (!mlirAffineExprEqual(cstr1, isEq1 ? d0minusS0 : d1minus42)) 1471 return 11; 1472 if (!mlirAffineExprEqual(cstr2, isEq2 ? d0minusS0 : d1minus42)) 1473 return 12; 1474 1475 return 0; 1476 } 1477 1478 int registerOnlyStd() { 1479 MlirContext ctx = mlirContextCreate(); 1480 // The built-in dialect is always loaded. 1481 if (mlirContextGetNumLoadedDialects(ctx) != 1) 1482 return 1; 1483 1484 MlirDialectHandle stdHandle = mlirGetDialectHandle__std__(); 1485 1486 MlirDialect std = mlirContextGetOrLoadDialect( 1487 ctx, mlirDialectHandleGetNamespace(stdHandle)); 1488 if (!mlirDialectIsNull(std)) 1489 return 2; 1490 1491 mlirDialectHandleRegisterDialect(stdHandle, ctx); 1492 1493 std = mlirContextGetOrLoadDialect(ctx, 1494 mlirDialectHandleGetNamespace(stdHandle)); 1495 if (mlirDialectIsNull(std)) 1496 return 3; 1497 1498 MlirDialect alsoStd = mlirDialectHandleLoadDialect(stdHandle, ctx); 1499 if (!mlirDialectEqual(std, alsoStd)) 1500 return 4; 1501 1502 MlirStringRef stdNs = mlirDialectGetNamespace(std); 1503 MlirStringRef alsoStdNs = mlirDialectHandleGetNamespace(stdHandle); 1504 if (stdNs.length != alsoStdNs.length || 1505 strncmp(stdNs.data, alsoStdNs.data, stdNs.length)) 1506 return 5; 1507 1508 fprintf(stderr, "@registration\n"); 1509 // CHECK-LABEL: @registration 1510 1511 // CHECK: std.cond_br is_registered: 1 1512 fprintf(stderr, "std.cond_br is_registered: %d\n", 1513 mlirContextIsRegisteredOperation( 1514 ctx, mlirStringRefCreateFromCString("std.cond_br"))); 1515 1516 // CHECK: std.not_existing_op is_registered: 0 1517 fprintf(stderr, "std.not_existing_op is_registered: %d\n", 1518 mlirContextIsRegisteredOperation( 1519 ctx, mlirStringRefCreateFromCString("std.not_existing_op"))); 1520 1521 // CHECK: not_existing_dialect.not_existing_op is_registered: 0 1522 fprintf(stderr, "not_existing_dialect.not_existing_op is_registered: %d\n", 1523 mlirContextIsRegisteredOperation( 1524 ctx, mlirStringRefCreateFromCString( 1525 "not_existing_dialect.not_existing_op"))); 1526 1527 mlirContextDestroy(ctx); 1528 return 0; 1529 } 1530 1531 /// Tests backreference APIs 1532 static int testBackreferences() { 1533 fprintf(stderr, "@test_backreferences\n"); 1534 1535 MlirContext ctx = mlirContextCreate(); 1536 mlirContextSetAllowUnregisteredDialects(ctx, true); 1537 MlirLocation loc = mlirLocationUnknownGet(ctx); 1538 1539 MlirOperationState opState = 1540 mlirOperationStateGet(mlirStringRefCreateFromCString("invalid.op"), loc); 1541 MlirRegion region = mlirRegionCreate(); 1542 MlirBlock block = mlirBlockCreate(0, NULL); 1543 mlirRegionAppendOwnedBlock(region, block); 1544 mlirOperationStateAddOwnedRegions(&opState, 1, ®ion); 1545 MlirOperation op = mlirOperationCreate(&opState); 1546 MlirIdentifier ident = 1547 mlirIdentifierGet(ctx, mlirStringRefCreateFromCString("identifier")); 1548 1549 if (!mlirContextEqual(ctx, mlirOperationGetContext(op))) { 1550 fprintf(stderr, "ERROR: Getting context from operation failed\n"); 1551 return 1; 1552 } 1553 if (!mlirOperationEqual(op, mlirBlockGetParentOperation(block))) { 1554 fprintf(stderr, "ERROR: Getting parent operation from block failed\n"); 1555 return 2; 1556 } 1557 if (!mlirContextEqual(ctx, mlirIdentifierGetContext(ident))) { 1558 fprintf(stderr, "ERROR: Getting context from identifier failed\n"); 1559 return 3; 1560 } 1561 1562 mlirOperationDestroy(op); 1563 mlirContextDestroy(ctx); 1564 1565 // CHECK-LABEL: @test_backreferences 1566 return 0; 1567 } 1568 1569 /// Tests operand APIs. 1570 int testOperands() { 1571 fprintf(stderr, "@testOperands\n"); 1572 // CHECK-LABEL: @testOperands 1573 1574 MlirContext ctx = mlirContextCreate(); 1575 mlirRegisterAllDialects(ctx); 1576 mlirContextGetOrLoadDialect(ctx, mlirStringRefCreateFromCString("test")); 1577 MlirLocation loc = mlirLocationUnknownGet(ctx); 1578 MlirType indexType = mlirIndexTypeGet(ctx); 1579 1580 // Create some constants to use as operands. 1581 MlirAttribute indexZeroLiteral = 1582 mlirAttributeParseGet(ctx, mlirStringRefCreateFromCString("0 : index")); 1583 MlirNamedAttribute indexZeroValueAttr = mlirNamedAttributeGet( 1584 mlirIdentifierGet(ctx, mlirStringRefCreateFromCString("value")), 1585 indexZeroLiteral); 1586 MlirOperationState constZeroState = mlirOperationStateGet( 1587 mlirStringRefCreateFromCString("arith.constant"), loc); 1588 mlirOperationStateAddResults(&constZeroState, 1, &indexType); 1589 mlirOperationStateAddAttributes(&constZeroState, 1, &indexZeroValueAttr); 1590 MlirOperation constZero = mlirOperationCreate(&constZeroState); 1591 MlirValue constZeroValue = mlirOperationGetResult(constZero, 0); 1592 1593 MlirAttribute indexOneLiteral = 1594 mlirAttributeParseGet(ctx, mlirStringRefCreateFromCString("1 : index")); 1595 MlirNamedAttribute indexOneValueAttr = mlirNamedAttributeGet( 1596 mlirIdentifierGet(ctx, mlirStringRefCreateFromCString("value")), 1597 indexOneLiteral); 1598 MlirOperationState constOneState = mlirOperationStateGet( 1599 mlirStringRefCreateFromCString("arith.constant"), loc); 1600 mlirOperationStateAddResults(&constOneState, 1, &indexType); 1601 mlirOperationStateAddAttributes(&constOneState, 1, &indexOneValueAttr); 1602 MlirOperation constOne = mlirOperationCreate(&constOneState); 1603 MlirValue constOneValue = mlirOperationGetResult(constOne, 0); 1604 1605 // Create the operation under test. 1606 mlirContextSetAllowUnregisteredDialects(ctx, true); 1607 MlirOperationState opState = 1608 mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op"), loc); 1609 MlirValue initialOperands[] = {constZeroValue}; 1610 mlirOperationStateAddOperands(&opState, 1, initialOperands); 1611 MlirOperation op = mlirOperationCreate(&opState); 1612 1613 // Test operand APIs. 1614 intptr_t numOperands = mlirOperationGetNumOperands(op); 1615 fprintf(stderr, "Num Operands: %" PRIdPTR "\n", numOperands); 1616 // CHECK: Num Operands: 1 1617 1618 MlirValue opOperand = mlirOperationGetOperand(op, 0); 1619 fprintf(stderr, "Original operand: "); 1620 mlirValuePrint(opOperand, printToStderr, NULL); 1621 // CHECK: Original operand: {{.+}} arith.constant 0 : index 1622 1623 mlirOperationSetOperand(op, 0, constOneValue); 1624 opOperand = mlirOperationGetOperand(op, 0); 1625 fprintf(stderr, "Updated operand: "); 1626 mlirValuePrint(opOperand, printToStderr, NULL); 1627 // CHECK: Updated operand: {{.+}} arith.constant 1 : index 1628 1629 mlirOperationDestroy(op); 1630 mlirOperationDestroy(constZero); 1631 mlirOperationDestroy(constOne); 1632 mlirContextDestroy(ctx); 1633 1634 return 0; 1635 } 1636 1637 /// Tests clone APIs. 1638 int testClone() { 1639 fprintf(stderr, "@testClone\n"); 1640 // CHECK-LABEL: @testClone 1641 1642 MlirContext ctx = mlirContextCreate(); 1643 mlirRegisterAllDialects(ctx); 1644 mlirContextGetOrLoadDialect(ctx, mlirStringRefCreateFromCString("std")); 1645 MlirLocation loc = mlirLocationUnknownGet(ctx); 1646 MlirType indexType = mlirIndexTypeGet(ctx); 1647 MlirStringRef valueStringRef = mlirStringRefCreateFromCString("value"); 1648 1649 MlirAttribute indexZeroLiteral = 1650 mlirAttributeParseGet(ctx, mlirStringRefCreateFromCString("0 : index")); 1651 MlirNamedAttribute indexZeroValueAttr = mlirNamedAttributeGet( 1652 mlirIdentifierGet(ctx, valueStringRef), indexZeroLiteral); 1653 MlirOperationState constZeroState = mlirOperationStateGet( 1654 mlirStringRefCreateFromCString("arith.constant"), loc); 1655 mlirOperationStateAddResults(&constZeroState, 1, &indexType); 1656 mlirOperationStateAddAttributes(&constZeroState, 1, &indexZeroValueAttr); 1657 MlirOperation constZero = mlirOperationCreate(&constZeroState); 1658 1659 MlirAttribute indexOneLiteral = 1660 mlirAttributeParseGet(ctx, mlirStringRefCreateFromCString("1 : index")); 1661 MlirOperation constOne = mlirOperationClone(constZero); 1662 mlirOperationSetAttributeByName(constOne, valueStringRef, indexOneLiteral); 1663 1664 mlirOperationPrint(constZero, printToStderr, NULL); 1665 mlirOperationPrint(constOne, printToStderr, NULL); 1666 // CHECK: arith.constant 0 : index 1667 // CHECK: arith.constant 1 : index 1668 1669 mlirOperationDestroy(constZero); 1670 mlirOperationDestroy(constOne); 1671 mlirContextDestroy(ctx); 1672 return 0; 1673 } 1674 1675 // Wraps a diagnostic into additional text we can match against. 1676 MlirLogicalResult errorHandler(MlirDiagnostic diagnostic, void *userData) { 1677 fprintf(stderr, "processing diagnostic (userData: %" PRIdPTR ") <<\n", 1678 (intptr_t)userData); 1679 mlirDiagnosticPrint(diagnostic, printToStderr, NULL); 1680 fprintf(stderr, "\n"); 1681 MlirLocation loc = mlirDiagnosticGetLocation(diagnostic); 1682 mlirLocationPrint(loc, printToStderr, NULL); 1683 assert(mlirDiagnosticGetNumNotes(diagnostic) == 0); 1684 fprintf(stderr, "\n>> end of diagnostic (userData: %" PRIdPTR ")\n", 1685 (intptr_t)userData); 1686 return mlirLogicalResultSuccess(); 1687 } 1688 1689 // Logs when the delete user data callback is called 1690 static void deleteUserData(void *userData) { 1691 fprintf(stderr, "deleting user data (userData: %" PRIdPTR ")\n", 1692 (intptr_t)userData); 1693 } 1694 1695 void testDiagnostics() { 1696 MlirContext ctx = mlirContextCreate(); 1697 MlirDiagnosticHandlerID id = mlirContextAttachDiagnosticHandler( 1698 ctx, errorHandler, (void *)42, deleteUserData); 1699 fprintf(stderr, "@test_diagnostics\n"); 1700 MlirLocation unknownLoc = mlirLocationUnknownGet(ctx); 1701 mlirEmitError(unknownLoc, "test diagnostics"); 1702 MlirLocation fileLineColLoc = mlirLocationFileLineColGet( 1703 ctx, mlirStringRefCreateFromCString("file.c"), 1, 2); 1704 mlirEmitError(fileLineColLoc, "test diagnostics"); 1705 MlirLocation callSiteLoc = mlirLocationCallSiteGet( 1706 mlirLocationFileLineColGet( 1707 ctx, mlirStringRefCreateFromCString("other-file.c"), 2, 3), 1708 fileLineColLoc); 1709 mlirEmitError(callSiteLoc, "test diagnostics"); 1710 MlirLocation null = {0}; 1711 MlirLocation nameLoc = 1712 mlirLocationNameGet(ctx, mlirStringRefCreateFromCString("named"), null); 1713 mlirEmitError(nameLoc, "test diagnostics"); 1714 MlirLocation locs[2] = {nameLoc, callSiteLoc}; 1715 MlirAttribute nullAttr = {0}; 1716 MlirLocation fusedLoc = mlirLocationFusedGet(ctx, 2, locs, nullAttr); 1717 mlirEmitError(fusedLoc, "test diagnostics"); 1718 mlirContextDetachDiagnosticHandler(ctx, id); 1719 mlirEmitError(unknownLoc, "more test diagnostics"); 1720 // CHECK-LABEL: @test_diagnostics 1721 // CHECK: processing diagnostic (userData: 42) << 1722 // CHECK: test diagnostics 1723 // CHECK: loc(unknown) 1724 // CHECK: >> end of diagnostic (userData: 42) 1725 // CHECK: processing diagnostic (userData: 42) << 1726 // CHECK: test diagnostics 1727 // CHECK: loc("file.c":1:2) 1728 // CHECK: >> end of diagnostic (userData: 42) 1729 // CHECK: processing diagnostic (userData: 42) << 1730 // CHECK: test diagnostics 1731 // CHECK: loc(callsite("other-file.c":2:3 at "file.c":1:2)) 1732 // CHECK: >> end of diagnostic (userData: 42) 1733 // CHECK: processing diagnostic (userData: 42) << 1734 // CHECK: test diagnostics 1735 // CHECK: loc("named") 1736 // CHECK: >> end of diagnostic (userData: 42) 1737 // CHECK: processing diagnostic (userData: 42) << 1738 // CHECK: test diagnostics 1739 // CHECK: loc(fused["named", callsite("other-file.c":2:3 at "file.c":1:2)]) 1740 // CHECK: deleting user data (userData: 42) 1741 // CHECK-NOT: processing diagnostic 1742 // CHECK: more test diagnostics 1743 mlirContextDestroy(ctx); 1744 } 1745 1746 int testTypeID(MlirContext ctx) { 1747 fprintf(stderr, "@testTypeID\n"); 1748 1749 // Test getting and comparing type and attribute type ids. 1750 MlirType i32 = mlirIntegerTypeGet(ctx, 32); 1751 MlirTypeID i32ID = mlirTypeGetTypeID(i32); 1752 MlirType ui32 = mlirIntegerTypeUnsignedGet(ctx, 32); 1753 MlirTypeID ui32ID = mlirTypeGetTypeID(ui32); 1754 MlirType f32 = mlirF32TypeGet(ctx); 1755 MlirTypeID f32ID = mlirTypeGetTypeID(f32); 1756 MlirAttribute i32Attr = mlirIntegerAttrGet(i32, 1); 1757 MlirTypeID i32AttrID = mlirAttributeGetTypeID(i32Attr); 1758 1759 if (mlirTypeIDIsNull(i32ID) || mlirTypeIDIsNull(ui32ID) || 1760 mlirTypeIDIsNull(f32ID) || mlirTypeIDIsNull(i32AttrID)) { 1761 fprintf(stderr, "ERROR: Expected type ids to be present\n"); 1762 return 1; 1763 } 1764 1765 if (!mlirTypeIDEqual(i32ID, ui32ID) || 1766 mlirTypeIDHashValue(i32ID) != mlirTypeIDHashValue(ui32ID)) { 1767 fprintf( 1768 stderr, 1769 "ERROR: Expected different integer types to have the same type id\n"); 1770 return 2; 1771 } 1772 1773 if (mlirTypeIDEqual(i32ID, f32ID) || 1774 mlirTypeIDHashValue(i32ID) == mlirTypeIDHashValue(f32ID)) { 1775 fprintf(stderr, 1776 "ERROR: Expected integer type id to not equal float type id\n"); 1777 return 3; 1778 } 1779 1780 if (mlirTypeIDEqual(i32ID, i32AttrID) || 1781 mlirTypeIDHashValue(i32ID) == mlirTypeIDHashValue(i32AttrID)) { 1782 fprintf(stderr, "ERROR: Expected integer type id to not equal integer " 1783 "attribute type id\n"); 1784 return 4; 1785 } 1786 1787 MlirLocation loc = mlirLocationUnknownGet(ctx); 1788 MlirType indexType = mlirIndexTypeGet(ctx); 1789 MlirStringRef valueStringRef = mlirStringRefCreateFromCString("value"); 1790 1791 // Create a registered operation, which should have a type id. 1792 MlirAttribute indexZeroLiteral = 1793 mlirAttributeParseGet(ctx, mlirStringRefCreateFromCString("0 : index")); 1794 MlirNamedAttribute indexZeroValueAttr = mlirNamedAttributeGet( 1795 mlirIdentifierGet(ctx, valueStringRef), indexZeroLiteral); 1796 MlirOperationState constZeroState = mlirOperationStateGet( 1797 mlirStringRefCreateFromCString("arith.constant"), loc); 1798 mlirOperationStateAddResults(&constZeroState, 1, &indexType); 1799 mlirOperationStateAddAttributes(&constZeroState, 1, &indexZeroValueAttr); 1800 MlirOperation constZero = mlirOperationCreate(&constZeroState); 1801 1802 if (!mlirOperationVerify(constZero)) { 1803 fprintf(stderr, "ERROR: Expected operation to verify correctly\n"); 1804 return 5; 1805 } 1806 1807 if (mlirOperationIsNull(constZero)) { 1808 fprintf(stderr, "ERROR: Expected registered operation to be present\n"); 1809 return 6; 1810 } 1811 1812 MlirTypeID registeredOpID = mlirOperationGetTypeID(constZero); 1813 1814 if (mlirTypeIDIsNull(registeredOpID)) { 1815 fprintf(stderr, 1816 "ERROR: Expected registered operation type id to be present\n"); 1817 return 7; 1818 } 1819 1820 // Create an unregistered operation, which should not have a type id. 1821 mlirContextSetAllowUnregisteredDialects(ctx, true); 1822 MlirOperationState opState = 1823 mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op"), loc); 1824 MlirOperation unregisteredOp = mlirOperationCreate(&opState); 1825 if (mlirOperationIsNull(unregisteredOp)) { 1826 fprintf(stderr, "ERROR: Expected unregistered operation to be present\n"); 1827 return 8; 1828 } 1829 1830 MlirTypeID unregisteredOpID = mlirOperationGetTypeID(unregisteredOp); 1831 1832 if (!mlirTypeIDIsNull(unregisteredOpID)) { 1833 fprintf(stderr, 1834 "ERROR: Expected unregistered operation type id to be null\n"); 1835 return 9; 1836 } 1837 1838 mlirOperationDestroy(constZero); 1839 mlirOperationDestroy(unregisteredOp); 1840 1841 return 0; 1842 } 1843 1844 int main() { 1845 MlirContext ctx = mlirContextCreate(); 1846 mlirRegisterAllDialects(ctx); 1847 if (constructAndTraverseIr(ctx)) 1848 return 1; 1849 buildWithInsertionsAndPrint(ctx); 1850 if (createOperationWithTypeInference(ctx)) 1851 return 2; 1852 1853 if (printBuiltinTypes(ctx)) 1854 return 3; 1855 if (printBuiltinAttributes(ctx)) 1856 return 4; 1857 if (printAffineMap(ctx)) 1858 return 5; 1859 if (printAffineExpr(ctx)) 1860 return 6; 1861 if (affineMapFromExprs(ctx)) 1862 return 7; 1863 if (printIntegerSet(ctx)) 1864 return 8; 1865 if (registerOnlyStd()) 1866 return 9; 1867 if (testBackreferences()) 1868 return 10; 1869 if (testOperands()) 1870 return 11; 1871 if (testClone()) 1872 return 12; 1873 if (testTypeID(ctx)) { 1874 return 13; 1875 } 1876 1877 mlirContextDestroy(ctx); 1878 1879 testDiagnostics(); 1880 return 0; 1881 } 1882