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