import stdio import string import stdlib import memhub import testcheck import mlirlite # Pool size: PrintModule needs ~1 MiB scratch and all 27 cases share one pool, so use 80 MiB. define POOL_SIZE = 83886080 # 80MB # --- Test 1: TypePrint --- def test_type_print(pool: memhub.MemBuddy*): testcheck.section("Test 1: TypePrint") core: mlirlite.LLVMTypeCore* = mlirlite.LLVMTypeCore(pool) buf: str = pool.alloc(64) # i32 ty_i32: mlirlite.LLVMType* = core.Int32() buf[0] = 0 core.PrintType(buf, 64, ty_i32) testcheck.check(string.strcmp(buf, "i32") == 0, "Int32 -> i32", "Int32 fail") # opaque pointer: Ptr(Int32) -> !llvm.ptr ty_ptr: mlirlite.LLVMType* = core.Ptr(ty_i32) buf[0] = 0 core.PrintType(buf, 64, ty_ptr) testcheck.check(string.strcmp(buf, "!llvm.ptr") == 0, "Ptr(Int32) -> !llvm.ptr", "Ptr fail") # Void -> none ty_void: mlirlite.LLVMType* = core.Void() buf[0] = 0 core.PrintType(buf, 64, ty_void) testcheck.check(string.strcmp(buf, "none") == 0, "Void -> none", "Void fail") # i64 ty_i64: mlirlite.LLVMType* = core.Int64() buf[0] = 0 core.PrintType(buf, 64, ty_i64) testcheck.check(string.strcmp(buf, "i64") == 0, "Int64 -> i64", "Int64 fail") # --- Test 2: ValuePrint --- def test_value_print(pool: memhub.MemBuddy*): testcheck.section("Test 2: ValuePrint") core: mlirlite.LLVMTypeCore* = mlirlite.LLVMTypeCore(pool) mcore: mlirlite.LLVMModuleCore* = mlirlite.LLVMModuleCore(pool) buf: str = pool.alloc(64) ty_i32: mlirlite.LLVMType* = core.Int32() # const 42 -> "42 : i32" (MLIR attribute text form) val42: mlirlite.Value* = mcore.ConstInt32(42) buf[0] = 0 mcore.PrintValue(buf, 64, val42) testcheck.check(string.strcmp(buf, "42 : i32") == 0, "ConstInt(42) -> '42 : i32'", "ConstInt fail") # SSA value %0 -> "%0" (MLIR operands carry no type) name_ssa: str = pool.alloc(16) string.strcpy(name_ssa, "%0") val_ssa: mlirlite.Value* = mcore.SSAValue(ty_i32, name_ssa) buf[0] = 0 mcore.PrintValue(buf, 64, val_ssa) testcheck.check(string.strcmp(buf, "%0") == 0, "SSAValue(%0) -> '%0'", "SSAValue fail") # --- Test 3: build add function --- def test_build_add(pool: memhub.MemBuddy*): testcheck.section("Test 3: build_add function") core: mlirlite.LLVMTypeCore* = mlirlite.LLVMTypeCore(pool) mcore: mlirlite.LLVMModuleCore* = mlirlite.LLVMModuleCore(pool) ty_i32: mlirlite.LLVMType* = core.Int32() # create module + function mod: mlirlite.Module* = mcore.NewModule("test_add") func: mlirlite.Function* = mcore.CreateFunction(mod, "add", ty_i32) # add parameters mcore.AddParam(func, ty_i32, "%a") mcore.AddParam(func, ty_i32, "%b") # create entry block entry: mlirlite.BasicBlock* = mcore.CreateBlock(func, "entry") # create builder builder: mlirlite.IRBuilder* = mcore.NewBuilder(func) mlirlite.position_at_end(builder, entry) # wrap parameters as Values v_a: mlirlite.Value* = mcore.SSAValue(ty_i32, "%a") v_b: mlirlite.Value* = mcore.SSAValue(ty_i32, "%b") # %0 = add i32 %a, %b v_c: mlirlite.Value* = mlirlite.build_add(builder, v_a, v_b) # ret i32 %0 mlirlite.build_ret(builder, v_c) # print function buf: str = pool.alloc(4096) buf[0] = 0 mcore.PrintFunction(buf, 4096, func) testcheck.info(buf) # verify key content testcheck.check(string.strstr(buf, "llvm.add %a, %b : i32") is not None, "contains 'llvm.add %a, %b : i32'", "missing 'llvm.add'") testcheck.check(string.strstr(buf, "llvm.return") is not None, "contains 'llvm.return'", "missing 'llvm.return'") testcheck.check(string.strstr(buf, "llvm.func @add(%a: i32, %b: i32) -> i32") is not None, "contains 'llvm.func @add(%a: i32, %b: i32) -> i32'", "missing function definition") # --- Test 4: build if-then-else (max) --- def test_build_if_else(pool: memhub.MemBuddy*): testcheck.section("Test 4: build if-then-else (max)") core: mlirlite.LLVMTypeCore* = mlirlite.LLVMTypeCore(pool) mcore: mlirlite.LLVMModuleCore* = mlirlite.LLVMModuleCore(pool) ty_i32: mlirlite.LLVMType* = core.Int32() mod: mlirlite.Module* = mcore.NewModule("test_max") func: mlirlite.Function* = mcore.CreateFunction(mod, "max", ty_i32) mcore.AddParam(func, ty_i32, "%a") mcore.AddParam(func, ty_i32, "%b") entry: mlirlite.BasicBlock* = mcore.CreateBlock(func, "entry") then_blk: mlirlite.BasicBlock* = mcore.CreateBlock(func, "then") else_blk: mlirlite.BasicBlock* = mcore.CreateBlock(func, "else") builder: mlirlite.IRBuilder* = mcore.NewBuilder(func) # entry: %0 = icmp sgt i32 %a, %b; br i1 %0, label %then, label %else mlirlite.position_at_end(builder, entry) v_a: mlirlite.Value* = mcore.SSAValue(ty_i32, "%a") v_b: mlirlite.Value* = mcore.SSAValue(ty_i32, "%b") v_cond: mlirlite.Value* = mlirlite.build_icmp(builder, mlirlite.ICMP_SGT, v_a, v_b) mlirlite.build_cond_br(builder, v_cond, then_blk, else_blk) # then: ret i32 %a mlirlite.position_at_end(builder, then_blk) mlirlite.build_ret(builder, v_a) # else: ret i32 %b mlirlite.position_at_end(builder, else_blk) mlirlite.build_ret(builder, v_b) # print function buf: str = pool.alloc(4096) buf[0] = 0 mcore.PrintFunction(buf, 4096, func) testcheck.info(buf) # verify key content testcheck.check(string.strstr(buf, "llvm.icmp \"sgt\"") is not None, "contains 'llvm.icmp \"sgt\"'", "missing 'llvm.icmp \"sgt\"'") testcheck.check(string.strstr(buf, "llvm.cond_br") is not None, "contains 'llvm.cond_br'", "missing 'llvm.cond_br'") testcheck.check(string.strstr(buf, "^then:") is not None, "contains '^then:'", "missing block label '^then:'") testcheck.check(string.strstr(buf, "^else:") is not None, "contains '^else:'", "missing block label '^else:'") # --- Test 5: ModulePrint --- def test_module_print(pool: memhub.MemBuddy*): testcheck.section("Test 5: ModulePrint") core: mlirlite.LLVMTypeCore* = mlirlite.LLVMTypeCore(pool) mcore: mlirlite.LLVMModuleCore* = mlirlite.LLVMModuleCore(pool) ty_i32: mlirlite.LLVMType* = core.Int32() ty_void: mlirlite.LLVMType* = core.Void() # create module mod: mlirlite.Module* = mcore.NewModule("test_module") mlirlite.module_set_target(mod, "x86_64-pc-windows-gnu") mlirlite.module_set_datalayout(mod, "e-m:w-p270:32:32") # function 1: add func_add: mlirlite.Function* = mcore.CreateFunction(mod, "add", ty_i32) mcore.AddParam(func_add, ty_i32, "%a") mcore.AddParam(func_add, ty_i32, "%b") entry1: mlirlite.BasicBlock* = mcore.CreateBlock(func_add, "entry") builder1: mlirlite.IRBuilder* = mcore.NewBuilder(func_add) mlirlite.position_at_end(builder1, entry1) v_a1: mlirlite.Value* = mcore.SSAValue(ty_i32, "%a") v_b1: mlirlite.Value* = mcore.SSAValue(ty_i32, "%b") v_sum: mlirlite.Value* = mlirlite.build_add(builder1, v_a1, v_b1) mlirlite.build_ret(builder1, v_sum) # function 2: void function func_void: mlirlite.Function* = mcore.CreateFunction(mod, "noop", ty_void) entry2: mlirlite.BasicBlock* = mcore.CreateBlock(func_void, "entry") builder2: mlirlite.IRBuilder* = mcore.NewBuilder(func_void) mlirlite.position_at_end(builder2, entry2) mlirlite.build_ret_void(builder2) # print module buf: str = pool.alloc(8192) buf[0] = 0 mcore.PrintModule(buf, 8192, mod) testcheck.info(buf) # verify key content(模块头:triple / data layout 以 llvm.* 模块属性承载, # 见 mlirlite/__module.vp;mlir-translate 会把它映射回 LLVM IR 的 target triple / target datalayout) testcheck.check(string.strstr(buf, "module attributes {llvm.target_triple = \"x86_64-pc-windows-gnu\"") is not None, "contains 'module attributes {llvm.target_triple = \"x86_64-pc-windows-gnu\"'", "missing 'module attributes {llvm.target_triple ...'") testcheck.check(string.strstr(buf, "llvm.data_layout = \"e-m:w-p270:32:32\"") is not None, "contains 'llvm.data_layout = \"e-m:w-p270:32:32\"'", "missing 'llvm.data_layout = ...'") testcheck.check(string.strstr(buf, "llvm.func @add") is not None, "contains 'llvm.func @add'", "missing add function") testcheck.check(string.strstr(buf, "llvm.func @noop()") is not None, "contains 'llvm.func @noop()'(void 返回省略 -> ty)", "missing noop function") testcheck.check(string.strstr(buf, "llvm.return") is not None, "contains 'llvm.return'", "missing 'llvm.return'") # --- Test 6: ArrayType --- def test_array_type(pool: memhub.MemBuddy*): testcheck.section("Test 6: ArrayType") core: mlirlite.LLVMTypeCore* = mlirlite.LLVMTypeCore(pool) buf: str = pool.alloc(128) # [4 x i32] -> !llvm.array<4 x i32> ty_i32: mlirlite.LLVMType* = core.Int32() ty_arr: mlirlite.LLVMType* = core.Array(ty_i32, 4) buf[0] = 0 core.PrintType(buf, 128, ty_arr) testcheck.check(string.strcmp(buf, "!llvm.array<4 x i32>") == 0, "Array(i32,4) -> !llvm.array<4 x i32>", "Array fail") # [2 x [3 x i8]] -> !llvm.array<2 x !llvm.array<3 x i8>> ty_i8: mlirlite.LLVMType* = core.Int8() ty_inner: mlirlite.LLVMType* = core.Array(ty_i8, 3) ty_nested: mlirlite.LLVMType* = core.Array(ty_inner, 2) buf[0] = 0 core.PrintType(buf, 128, ty_nested) testcheck.check(string.strcmp(buf, "!llvm.array<2 x !llvm.array<3 x i8>>") == 0, "nested array -> !llvm.array<2 x !llvm.array<3 x i8>>", "nested array fail") # --- Test 7: StructType --- def test_struct_type(pool: memhub.MemBuddy*): testcheck.section("Test 7: StructType") core: mlirlite.LLVMTypeCore* = mlirlite.LLVMTypeCore(pool) buf: str = pool.alloc(128) ty_i32: mlirlite.LLVMType* = core.Int32() ty_i8: mlirlite.LLVMType* = core.Int8() ty_i8ptr: mlirlite.LLVMType* = core.Ptr(ty_i8) # {i32, i8*} -> !llvm.struct<(i32, !llvm.ptr)> n1: mlirlite.ParamNode* = core.NewParamNode(ty_i32) n2: mlirlite.ParamNode* = core.NewParamNode(ty_i8ptr) head: mlirlite.ParamNode* = core.ParamListAppend(None, None, n1) core.ParamListAppend(head, n1, n2) ty_struct: mlirlite.LLVMType* = core.Struct(head, 2) buf[0] = 0 core.PrintType(buf, 128, ty_struct) testcheck.check(string.strcmp(buf, "!llvm.struct<(i32, !llvm.ptr)>") == 0, "struct {i32, i8*} -> !llvm.struct<(i32, !llvm.ptr)>", "struct fail") # empty struct -> !llvm.struct<()> ty_empty: mlirlite.LLVMType* = core.Struct(None, 0) buf[0] = 0 core.PrintType(buf, 128, ty_empty) testcheck.check(string.strcmp(buf, "!llvm.struct<()>") == 0, "empty struct -> !llvm.struct<()>", "empty struct fail") # --- Test 8: FuncType --- def test_func_type(pool: memhub.MemBuddy*): testcheck.section("Test 8: FuncType") core: mlirlite.LLVMTypeCore* = mlirlite.LLVMTypeCore(pool) buf: str = pool.alloc(128) ty_i32: mlirlite.LLVMType* = core.Int32() ty_i8: mlirlite.LLVMType* = core.Int8() ty_i8ptr: mlirlite.LLVMType* = core.Ptr(ty_i8) # i32 (i32, i8*) -> !llvm.func n1: mlirlite.ParamNode* = core.NewParamNode(ty_i32) n2: mlirlite.ParamNode* = core.NewParamNode(ty_i8ptr) head: mlirlite.ParamNode* = core.ParamListAppend(None, None, n1) core.ParamListAppend(head, n1, n2) ty_func: mlirlite.LLVMType* = core.Func(ty_i32, head, 2) buf[0] = 0 core.PrintType(buf, 128, ty_func) testcheck.check(string.strcmp(buf, "!llvm.func") == 0, "func type -> !llvm.func", "func type fail") # void () -> !llvm.func: no-arg void function type ty_void: mlirlite.LLVMType* = core.Void() ty_func_void: mlirlite.LLVMType* = core.Func(ty_void, None, 0) buf[0] = 0 core.PrintType(buf, 128, ty_func_void) testcheck.check(string.strcmp(buf, "!llvm.func") == 0, "void func -> !llvm.func", "void func fail") # --- Test 9: Declare vs Define --- def test_declare(pool: memhub.MemBuddy*): testcheck.section("Test 9: Declare vs Define") core: mlirlite.LLVMTypeCore* = mlirlite.LLVMTypeCore(pool) mcore: mlirlite.LLVMModuleCore* = mlirlite.LLVMModuleCore(pool) ty_i32: mlirlite.LLVMType* = core.Int32() mod: mlirlite.Module* = mcore.NewModule("test_declare") # declare i32 @extern_func(i32) func_decl: mlirlite.Function* = mcore.CreateDeclare(mod, "extern_func", ty_i32) mcore.AddParam(func_decl, ty_i32, "%x") # define i32 @defined_func(i32) { entry: ret i32 %x } func_def: mlirlite.Function* = mcore.CreateFunction(mod, "defined_func", ty_i32) mcore.AddParam(func_def, ty_i32, "%x") entry: mlirlite.BasicBlock* = mcore.CreateBlock(func_def, "entry") builder: mlirlite.IRBuilder* = mcore.NewBuilder(func_def) mlirlite.position_at_end(builder, entry) v_x: mlirlite.Value* = mcore.SSAValue(ty_i32, "%x") mlirlite.build_ret(builder, v_x) buf: str = pool.alloc(4096) buf[0] = 0 mcore.PrintModule(buf, 4096, mod) testcheck.info(buf) testcheck.check(string.strstr(buf, "llvm.func @extern_func(%x: i32) -> i32") is not None, "contains declare 'llvm.func @extern_func(%x: i32) -> i32'", "missing declare") testcheck.check(string.strstr(buf, "llvm.func @defined_func(%x: i32) -> i32") is not None, "contains define 'llvm.func @defined_func(%x: i32) -> i32'", "missing define") testcheck.check(string.strstr(buf, "llvm.func @extern_func(%x: i32) -> i32 {") is None, "declare 无函数体(不出现 '{')", "declare missing param") testcheck.check(string.strstr(buf, "llvm.return %x : i32") is not None, "define has body 'llvm.return %x : i32'", "define missing body") # --- Test 10: Float Types & ConstFloat --- def test_float_types(pool: memhub.MemBuddy*): testcheck.section("Test 10: Float Types & ConstFloat") core: mlirlite.LLVMTypeCore* = mlirlite.LLVMTypeCore(pool) mcore: mlirlite.LLVMModuleCore* = mlirlite.LLVMModuleCore(pool) buf: str = pool.alloc(128) # half -> f16 ty_half: mlirlite.LLVMType* = core.Half() buf[0] = 0 core.PrintType(buf, 128, ty_half) testcheck.check(string.strcmp(buf, "f16") == 0, "Half -> f16", "Half fail") # float -> f32 ty_float: mlirlite.LLVMType* = core.Float() buf[0] = 0 core.PrintType(buf, 128, ty_float) testcheck.check(string.strcmp(buf, "f32") == 0, "Float -> f32", "Float fail") # double -> f64 ty_double: mlirlite.LLVMType* = core.Double() buf[0] = 0 core.PrintType(buf, 128, ty_double) testcheck.check(string.strcmp(buf, "f64") == 0, "Double -> f64", "Double fail") # fp128 -> f128 ty_fp128: mlirlite.LLVMType* = core.FP128() buf[0] = 0 core.PrintType(buf, 128, ty_fp128) testcheck.check(string.strcmp(buf, "f128") == 0, "FP128 -> f128", "FP128 fail") # ConstFloat(3.14) -> "0x40091EB851EB851F : f64" (bit pattern, lossless; MLIR type f64) val_pi: mlirlite.Value* = mcore.ConstFloat(ty_double, 3.14) buf[0] = 0 mcore.PrintValue(buf, 128, val_pi) testcheck.check(string.strstr(buf, " : f64") is not None, "ConstFloat has MLIR type ' : f64'", "ConstFloat missing type") testcheck.check(string.strstr(buf, "0x") is not None, "ConstFloat has hex bit pattern", "ConstFloat missing hex pattern") # --- Test 11: Float Binary Ops --- def test_float_binops(pool: memhub.MemBuddy*): testcheck.section("Test 11: Float Binary Ops") core: mlirlite.LLVMTypeCore* = mlirlite.LLVMTypeCore(pool) mcore: mlirlite.LLVMModuleCore* = mlirlite.LLVMModuleCore(pool) ty_double: mlirlite.LLVMType* = core.Double() mod: mlirlite.Module* = mcore.NewModule("test_fadd") func: mlirlite.Function* = mcore.CreateFunction(mod, "fadd", ty_double) mcore.AddParam(func, ty_double, "%a") mcore.AddParam(func, ty_double, "%b") entry: mlirlite.BasicBlock* = mcore.CreateBlock(func, "entry") builder: mlirlite.IRBuilder* = mcore.NewBuilder(func) mlirlite.position_at_end(builder, entry) v_a: mlirlite.Value* = mcore.SSAValue(ty_double, "%a") v_b: mlirlite.Value* = mcore.SSAValue(ty_double, "%b") v_c: mlirlite.Value* = mlirlite.build_fadd(builder, v_a, v_b) mlirlite.build_ret(builder, v_c) buf: str = pool.alloc(4096) buf[0] = 0 mcore.PrintFunction(buf, 4096, func) testcheck.info(buf) testcheck.check(string.strstr(buf, "llvm.fadd %a, %b : f64") is not None, "contains 'llvm.fadd %a, %b : f64'", "missing 'llvm.fadd'") testcheck.check(string.strstr(buf, "llvm.return %0 : f64") is not None, "contains 'llvm.return %0 : f64'", "missing 'llvm.return'") # --- Test 12: Bitwise & Shift Ops --- def test_bitwise_ops(pool: memhub.MemBuddy*): testcheck.section("Test 12: Bitwise & Shift Ops") core: mlirlite.LLVMTypeCore* = mlirlite.LLVMTypeCore(pool) mcore: mlirlite.LLVMModuleCore* = mlirlite.LLVMModuleCore(pool) ty_i32: mlirlite.LLVMType* = core.Int32() mod: mlirlite.Module* = mcore.NewModule("test_bitops") func: mlirlite.Function* = mcore.CreateFunction(mod, "bitops", ty_i32) mcore.AddParam(func, ty_i32, "%a") mcore.AddParam(func, ty_i32, "%b") entry: mlirlite.BasicBlock* = mcore.CreateBlock(func, "entry") builder: mlirlite.IRBuilder* = mcore.NewBuilder(func) mlirlite.position_at_end(builder, entry) v_a: mlirlite.Value* = mcore.SSAValue(ty_i32, "%a") v_b: mlirlite.Value* = mcore.SSAValue(ty_i32, "%b") # and -> or -> xor -> shl -> ret v_and: mlirlite.Value* = mlirlite.build_and(builder, v_a, v_b) v_or: mlirlite.Value* = mlirlite.build_or(builder, v_and, v_b) v_xor: mlirlite.Value* = mlirlite.build_xor(builder, v_or, v_a) v_shl: mlirlite.Value* = mlirlite.build_shl(builder, v_xor, v_b) mlirlite.build_ret(builder, v_shl) buf: str = pool.alloc(4096) buf[0] = 0 mcore.PrintFunction(buf, 4096, func) testcheck.info(buf) testcheck.check(string.strstr(buf, "llvm.and %a, %b : i32") is not None, "has 'llvm.and %a, %b : i32'", "missing 'llvm.and'") testcheck.check(string.strstr(buf, "llvm.or %0, %b : i32") is not None, "has 'llvm.or %0, %b : i32'", "missing 'llvm.or'") testcheck.check(string.strstr(buf, "llvm.xor %1, %a : i32") is not None, "has 'llvm.xor %1, %a : i32'", "missing 'llvm.xor'") testcheck.check(string.strstr(buf, "llvm.shl %2, %b : i32") is not None, "has 'llvm.shl %2, %b : i32'", "missing 'llvm.shl'") # --- Test 13: FCMP --- def test_fcmp(pool: memhub.MemBuddy*): testcheck.section("Test 13: FCMP") core: mlirlite.LLVMTypeCore* = mlirlite.LLVMTypeCore(pool) mcore: mlirlite.LLVMModuleCore* = mlirlite.LLVMModuleCore(pool) ty_double: mlirlite.LLVMType* = core.Double() ty_i1: mlirlite.LLVMType* = core.Int1() mod: mlirlite.Module* = mcore.NewModule("test_fcmp") func: mlirlite.Function* = mcore.CreateFunction(mod, "fcmp_test", ty_i1) mcore.AddParam(func, ty_double, "%a") mcore.AddParam(func, ty_double, "%b") entry: mlirlite.BasicBlock* = mcore.CreateBlock(func, "entry") builder: mlirlite.IRBuilder* = mcore.NewBuilder(func) mlirlite.position_at_end(builder, entry) v_a: mlirlite.Value* = mcore.SSAValue(ty_double, "%a") v_b: mlirlite.Value* = mcore.SSAValue(ty_double, "%b") v_cond: mlirlite.Value* = mlirlite.build_fcmp(builder, mlirlite.FCMP_OEQ, v_a, v_b) mlirlite.build_ret(builder, v_cond) buf: str = pool.alloc(4096) buf[0] = 0 mcore.PrintFunction(buf, 4096, func) testcheck.info(buf) testcheck.check(string.strstr(buf, "llvm.fcmp \"oeq\" %a, %b : f64") is not None, "contains 'llvm.fcmp \"oeq\" %a, %b : f64'", "missing 'llvm.fcmp \"oeq\"'") # --- Test 14: Casts (zext/ptrtoint/inttoptr) --- def test_casts(pool: memhub.MemBuddy*): testcheck.section("Test 14: Casts (zext/ptrtoint/inttoptr)") core: mlirlite.LLVMTypeCore* = mlirlite.LLVMTypeCore(pool) mcore: mlirlite.LLVMModuleCore* = mlirlite.LLVMModuleCore(pool) ty_i32: mlirlite.LLVMType* = core.Int32() ty_i64: mlirlite.LLVMType* = core.Int64() ty_i8: mlirlite.LLVMType* = core.Int8() ty_i8ptr: mlirlite.LLVMType* = core.Ptr(ty_i8) mod: mlirlite.Module* = mcore.NewModule("test_casts") func: mlirlite.Function* = mcore.CreateFunction(mod, "cast_test", ty_i64) mcore.AddParam(func, ty_i32, "%x") entry: mlirlite.BasicBlock* = mcore.CreateBlock(func, "entry") builder: mlirlite.IRBuilder* = mcore.NewBuilder(func) mlirlite.position_at_end(builder, entry) v_x: mlirlite.Value* = mcore.SSAValue(ty_i32, "%x") # zext i32 %x to i64 v_ext: mlirlite.Value* = mlirlite.build_zext(builder, v_x, ty_i64) # ptrtoint i8* null to i64 v_null: mlirlite.Value* = mcore.ConstNull(ty_i8ptr, "null") v_p2i: mlirlite.Value* = mlirlite.build_ptrtoint(builder, v_null, ty_i64) # inttoptr i64 %p2i to i8* v_i2p: mlirlite.Value* = mlirlite.build_inttoptr(builder, v_p2i, ty_i8ptr) # ret i64 %ext mlirlite.build_ret(builder, v_ext) buf: str = pool.alloc(4096) buf[0] = 0 mcore.PrintFunction(buf, 4096, func) testcheck.info(buf) testcheck.check(string.strstr(buf, "llvm.zext %x : i32 to i64") is not None, "has 'llvm.zext %x : i32 to i64'", "missing 'llvm.zext'") testcheck.check(string.strstr(buf, "llvm.ptrtoint %c0 : !llvm.ptr to i64") is not None, "has 'llvm.ptrtoint %c0 : !llvm.ptr to i64'", "missing 'llvm.ptrtoint'") testcheck.check(string.strstr(buf, "llvm.inttoptr %1 : i64 to !llvm.ptr") is not None, "has 'llvm.inttoptr %1 : i64 to !llvm.ptr'", "missing 'llvm.inttoptr'") # --- Test 15: FP Conversions (fp2si/si2fp) --- def test_fp_conversions(pool: memhub.MemBuddy*): testcheck.section("Test 15: FP Conversions (fp2si/si2fp)") core: mlirlite.LLVMTypeCore* = mlirlite.LLVMTypeCore(pool) mcore: mlirlite.LLVMModuleCore* = mlirlite.LLVMModuleCore(pool) ty_i32: mlirlite.LLVMType* = core.Int32() ty_double: mlirlite.LLVMType* = core.Double() mod: mlirlite.Module* = mcore.NewModule("test_fpconv") func: mlirlite.Function* = mcore.CreateFunction(mod, "fpconv", ty_double) mcore.AddParam(func, ty_i32, "%n") entry: mlirlite.BasicBlock* = mcore.CreateBlock(func, "entry") builder: mlirlite.IRBuilder* = mcore.NewBuilder(func) mlirlite.position_at_end(builder, entry) v_n: mlirlite.Value* = mcore.SSAValue(ty_i32, "%n") # sitofp i32 %n to double v_d: mlirlite.Value* = mlirlite.build_si2fp(builder, v_n, ty_double) # fptosi double %d to i32 v_i: mlirlite.Value* = mlirlite.build_fp2si(builder, v_d, ty_i32) # sitofp i32 %i to double (return) v_r: mlirlite.Value* = mlirlite.build_si2fp(builder, v_i, ty_double) mlirlite.build_ret(builder, v_r) buf: str = pool.alloc(4096) buf[0] = 0 mcore.PrintFunction(buf, 4096, func) testcheck.info(buf) testcheck.check(string.strstr(buf, "llvm.sitofp %n : i32 to f64") is not None, "has 'llvm.sitofp %n : i32 to f64'", "missing 'llvm.sitofp'") testcheck.check(string.strstr(buf, "llvm.fptosi %0 : f64 to i32") is not None, "has 'llvm.fptosi %0 : f64 to i32'", "missing 'llvm.fptosi'") # --- Test 16: Phi Node --- def test_phi(pool: memhub.MemBuddy*): testcheck.section("Test 16: Phi Node") core: mlirlite.LLVMTypeCore* = mlirlite.LLVMTypeCore(pool) mcore: mlirlite.LLVMModuleCore* = mlirlite.LLVMModuleCore(pool) ty_i32: mlirlite.LLVMType* = core.Int32() mod: mlirlite.Module* = mcore.NewModule("test_phi") func: mlirlite.Function* = mcore.CreateFunction(mod, "phi_test", ty_i32) entry: mlirlite.BasicBlock* = mcore.CreateBlock(func, "entry") then_blk: mlirlite.BasicBlock* = mcore.CreateBlock(func, "then") else_blk: mlirlite.BasicBlock* = mcore.CreateBlock(func, "else") merge: mlirlite.BasicBlock* = mcore.CreateBlock(func, "merge") builder: mlirlite.IRBuilder* = mcore.NewBuilder(func) # entry: br label %then mlirlite.position_at_end(builder, entry) mlirlite.build_br(builder, then_blk) # then: br label %merge mlirlite.position_at_end(builder, then_blk) v_1: mlirlite.Value* = mcore.ConstInt32(1) mlirlite.build_br(builder, merge) # else: br label %merge mlirlite.position_at_end(builder, else_blk) v_2: mlirlite.Value* = mcore.ConstInt32(2) mlirlite.build_br(builder, merge) # merge: %r = phi i32 [1, %then], [2, %else]; ret i32 %r mlirlite.position_at_end(builder, merge) inc1: mlirlite.PhiIncoming* = mlirlite.new_phi_incoming(pool, v_1, then_blk) inc2: mlirlite.PhiIncoming* = mlirlite.new_phi_incoming(pool, v_2, else_blk) inc1.Next = inc2 v_r: mlirlite.Value* = mlirlite.build_phi(builder, ty_i32, inc1, 2) mlirlite.build_ret(builder, v_r) buf: str = pool.alloc(4096) buf[0] = 0 mcore.PrintFunction(buf, 4096, func) testcheck.info(buf) # phi lowered to block args: no phi line, emits ^merge(%...) + llvm.br ^merge(%...) testcheck.check(string.strstr(buf, "llvm.br ^merge(%c0 : i32)") is not None, "has 'llvm.br ^merge(%c0 : i32)'", "missing branch block operands") testcheck.check(string.strstr(buf, "^merge(%0: i32):") is not None, "has '^merge(%0: i32):'", "missing block arguments") testcheck.check(string.strstr(buf, "^then:") is not None, "has '^then:'", "missing '^then:'") testcheck.check(string.strstr(buf, "^else:") is not None, "has '^else:'", "missing '^else:'") testcheck.check(string.strstr(buf, " = phi ") is None, "phi 行不再输出", "phi line should not be emitted") # --- Test 17: Switch --- def test_switch(pool: memhub.MemBuddy*): testcheck.section("Test 17: Switch") core: mlirlite.LLVMTypeCore* = mlirlite.LLVMTypeCore(pool) mcore: mlirlite.LLVMModuleCore* = mlirlite.LLVMModuleCore(pool) ty_i32: mlirlite.LLVMType* = core.Int32() ty_void: mlirlite.LLVMType* = core.Void() mod: mlirlite.Module* = mcore.NewModule("test_switch") func: mlirlite.Function* = mcore.CreateFunction(mod, "switch_test", ty_void) mcore.AddParam(func, ty_i32, "%x") entry: mlirlite.BasicBlock* = mcore.CreateBlock(func, "entry") case0: mlirlite.BasicBlock* = mcore.CreateBlock(func, "case0") case1: mlirlite.BasicBlock* = mcore.CreateBlock(func, "case1") default_blk: mlirlite.BasicBlock* = mcore.CreateBlock(func, "default") builder: mlirlite.IRBuilder* = mcore.NewBuilder(func) # entry: switch i32 %x, label %default [i32 0, label %case0; i32 1, label %case1] mlirlite.position_at_end(builder, entry) v_x: mlirlite.Value* = mcore.SSAValue(ty_i32, "%x") v_0: mlirlite.Value* = mcore.ConstInt32(0) v_1: mlirlite.Value* = mcore.ConstInt32(1) c0: mlirlite.SwitchCase* = mlirlite.new_switch_case(pool, v_0, case0) c1: mlirlite.SwitchCase* = mlirlite.new_switch_case(pool, v_1, case1) c0.Next = c1 mlirlite.build_switch(builder, v_x, default_blk, c0, 2) # case0/case1/default: ret void mlirlite.position_at_end(builder, case0) mlirlite.build_ret_void(builder) mlirlite.position_at_end(builder, case1) mlirlite.build_ret_void(builder) mlirlite.position_at_end(builder, default_blk) mlirlite.build_ret_void(builder) buf: str = pool.alloc(4096) buf[0] = 0 mcore.PrintFunction(buf, 4096, func) testcheck.info(buf) testcheck.check(string.strstr(buf, "llvm.switch %x : i32, ^default [0: ^case0, 1: ^case1]") is not None, "has 'llvm.switch %x : i32, ^default [0: ^case0, 1: ^case1]'", "missing 'llvm.switch'") testcheck.check(string.strstr(buf, "^default:") is not None, "has '^default:'", "missing '^default:'") testcheck.check(string.strstr(buf, "^case0:") is not None, "has '^case0:'", "missing '^case0:'") # --- Test 18: Select --- def test_select(pool: memhub.MemBuddy*): testcheck.section("Test 18: Select") core: mlirlite.LLVMTypeCore* = mlirlite.LLVMTypeCore(pool) mcore: mlirlite.LLVMModuleCore* = mlirlite.LLVMModuleCore(pool) ty_i32: mlirlite.LLVMType* = core.Int32() mod: mlirlite.Module* = mcore.NewModule("test_select") func: mlirlite.Function* = mcore.CreateFunction(mod, "sel_test", ty_i32) mcore.AddParam(func, ty_i32, "%a") mcore.AddParam(func, ty_i32, "%b") entry: mlirlite.BasicBlock* = mcore.CreateBlock(func, "entry") builder: mlirlite.IRBuilder* = mcore.NewBuilder(func) mlirlite.position_at_end(builder, entry) v_a: mlirlite.Value* = mcore.SSAValue(ty_i32, "%a") v_b: mlirlite.Value* = mcore.SSAValue(ty_i32, "%b") v_cond: mlirlite.Value* = mlirlite.build_icmp(builder, mlirlite.ICMP_SLT, v_a, v_b) v_sel: mlirlite.Value* = mlirlite.build_select(builder, v_cond, v_a, v_b) mlirlite.build_ret(builder, v_sel) buf: str = pool.alloc(4096) buf[0] = 0 mcore.PrintFunction(buf, 4096, func) testcheck.info(buf) testcheck.check(string.strstr(buf, "llvm.select %0, %a, %b : i1, i32") is not None, "has 'llvm.select %0, %a, %b : i1, i32'", "missing 'llvm.select'") # --- Test 19: Global Variables --- def test_globals(pool: memhub.MemBuddy*): testcheck.section("Test 19: Global Variables") core: mlirlite.LLVMTypeCore* = mlirlite.LLVMTypeCore(pool) mcore: mlirlite.LLVMModuleCore* = mlirlite.LLVMModuleCore(pool) ty_i32: mlirlite.LLVMType* = core.Int32() ty_void: mlirlite.LLVMType* = core.Void() mod: mlirlite.Module* = mcore.NewModule("test_globals") mlirlite.module_set_target(mod, "x86_64-pc-windows-gnu") # string constant: @.str = private unnamed_addr constant [6 x i8] c"hello\00" mcore.CreateGlobalString(mod, ".str", "hello") # integer global: @counter = global i32 0 mcore.CreateGlobalInt(mod, "counter", 32, 0) # add a simple function to make the module non-empty func: mlirlite.Function* = mcore.CreateFunction(mod, "use_global", ty_void) entry: mlirlite.BasicBlock* = mcore.CreateBlock(func, "entry") builder: mlirlite.IRBuilder* = mcore.NewBuilder(func) mlirlite.position_at_end(builder, entry) mlirlite.build_ret_void(builder) buf: str = pool.alloc(8192) buf[0] = 0 mcore.PrintModule(buf, 8192, mod) testcheck.info(buf) testcheck.check(string.strstr(buf, "llvm.mlir.global") is not None, "has 'llvm.mlir.global'", "missing 'llvm.mlir.global'") testcheck.check(string.strstr(buf, "private unnamed_addr constant") is not None, "has 'private unnamed_addr constant'", "missing 'private unnamed_addr constant'") testcheck.check(string.strstr(buf, "@\".str\"(") is not None, "has '@\".str\"('", "missing quoted string global") testcheck.check(string.strstr(buf, "hello\\00") is not None, "has 'hello\\00'", "missing string content") testcheck.check(string.strstr(buf, "@counter(0 : i32) : i32") is not None, "has '@counter(0 : i32) : i32'", "missing '@counter'") testcheck.check(string.strstr(buf, "llvm.mlir.global @counter") is not None, "has 'llvm.mlir.global @counter'", "missing integer global") # --- Test 20: Function & Param Attributes --- def test_attributes(pool: memhub.MemBuddy*): testcheck.section("Test 20: Function & Param Attributes") core: mlirlite.LLVMTypeCore* = mlirlite.LLVMTypeCore(pool) mcore: mlirlite.LLVMModuleCore* = mlirlite.LLVMModuleCore(pool) ty_i32: mlirlite.LLVMType* = core.Int32() ty_i8ptr: mlirlite.LLVMType* = core.Ptr(core.Int8()) mod: mlirlite.Module* = mcore.NewModule("test_attrs") func: mlirlite.Function* = mcore.CreateFunction(mod, "attr_test", ty_i32) # param 0: i32 noundef %x p0: mlirlite.Param* = mcore.AddParam(func, ty_i32, "%x") mcore.ParamSetAttrs(p0, "noundef") # param 1: i8* nocapture %p p1: mlirlite.Param* = mcore.AddParam(func, ty_i8ptr, "%p") mcore.ParamSetAttrs(p1, "nocapture") # function attribute: nounwind mcore.FunctionSetAttrs(func, "nounwind") entry: mlirlite.BasicBlock* = mcore.CreateBlock(func, "entry") builder: mlirlite.IRBuilder* = mcore.NewBuilder(func) mlirlite.position_at_end(builder, entry) v_x: mlirlite.Value* = mcore.SSAValue(ty_i32, "%x") mlirlite.build_ret(builder, v_x) buf: str = pool.alloc(4096) buf[0] = 0 mcore.PrintFunction(buf, 4096, func) testcheck.info(buf) # MLIR v1 records func/param attrs but does not render them (see mlirlite README 3.3), # so assert the signature is correct and attr text is absent; model fields remain. testcheck.check(string.strstr(buf, "llvm.func @attr_test(%x: i32, %p: !llvm.ptr) -> i32") is not None, "has 'llvm.func @attr_test(%x: i32, %p: !llvm.ptr) -> i32'", "missing attribute-test function signature") testcheck.check(string.strstr(buf, "noundef") is None, "参数属性 'noundef' 记录但不渲染", "param attr 'noundef' should not be rendered") testcheck.check(string.strstr(buf, "nocapture") is None, "参数属性 'nocapture' 记录但不渲染", "param attr 'nocapture' should not be rendered") testcheck.check(string.strstr(buf, ") nounwind") is None, "函数属性 'nounwind' 记录但不渲染", "func attr 'nounwind' should not be rendered") # --- Test 21: Atomic Ops --- def test_atomic(pool: memhub.MemBuddy*): testcheck.section("Test 21: Atomic Ops") core: mlirlite.LLVMTypeCore* = mlirlite.LLVMTypeCore(pool) mcore: mlirlite.LLVMModuleCore* = mlirlite.LLVMModuleCore(pool) ty_i32: mlirlite.LLVMType* = core.Int32() ty_i32ptr: mlirlite.LLVMType* = core.Ptr(ty_i32) mod: mlirlite.Module* = mcore.NewModule("test_atomic") func: mlirlite.Function* = mcore.CreateFunction(mod, "atomic_test", ty_i32) mcore.AddParam(func, ty_i32ptr, "%p") entry: mlirlite.BasicBlock* = mcore.CreateBlock(func, "entry") builder: mlirlite.IRBuilder* = mcore.NewBuilder(func) mlirlite.position_at_end(builder, entry) v_p: mlirlite.Value* = mcore.SSAValue(ty_i32ptr, "%p") v_1: mlirlite.Value* = mcore.ConstInt32(1) # atomicrmw add i32* %p, i32 1 monotonic v_r: mlirlite.Value* = mlirlite.build_atomicrmw(builder, mlirlite.ATOMIC_ADD, v_p, v_1, mlirlite.ATOMIC_ORDER_MONOTONIC) mlirlite.build_ret(builder, v_r) buf: str = pool.alloc(4096) buf[0] = 0 mcore.PrintFunction(buf, 4096, func) testcheck.info(buf) testcheck.check(string.strstr(buf, "atomicrmw add") is not None, "has 'atomicrmw add'", "missing 'atomicrmw add'") testcheck.check(string.strstr(buf, "monotonic") is not None, "has 'monotonic'", "missing 'monotonic'") # --- Test 22: Inline ASM & Unreachable --- def test_inline_asm_unreachable(pool: memhub.MemBuddy*): testcheck.section("Test 22: Inline ASM & Unreachable") core: mlirlite.LLVMTypeCore* = mlirlite.LLVMTypeCore(pool) mcore: mlirlite.LLVMModuleCore* = mlirlite.LLVMModuleCore(pool) ty_void: mlirlite.LLVMType* = core.Void() mod: mlirlite.Module* = mcore.NewModule("test_asm") func: mlirlite.Function* = mcore.CreateFunction(mod, "asm_test", ty_void) entry: mlirlite.BasicBlock* = mcore.CreateBlock(func, "entry") trap_blk: mlirlite.BasicBlock* = mcore.CreateBlock(func, "trap") builder: mlirlite.IRBuilder* = mcore.NewBuilder(func) # entry: call void asm sideeffect "nop", ""(); br label %trap mlirlite.position_at_end(builder, entry) mlirlite.build_inline_asm(builder, ty_void, "nop", "", 1) mlirlite.build_br(builder, trap_blk) # trap: unreachable mlirlite.position_at_end(builder, trap_blk) mlirlite.build_unreachable(builder) buf: str = pool.alloc(4096) buf[0] = 0 mcore.PrintFunction(buf, 4096, func) testcheck.info(buf) testcheck.check(string.strstr(buf, "llvm.inline_asm has_side_effects \"nop\", \"\" : () -> ()") is not None, "has 'llvm.inline_asm has_side_effects \"nop\", \"\" : () -> ()'", "missing 'llvm.inline_asm'") testcheck.check(string.strstr(buf, "unreachable") is not None, "has 'unreachable'", "missing 'unreachable'") testcheck.check(string.strstr(buf, "llvm.unreachable") is not None, "has 'llvm.unreachable'", "missing 'llvm.unreachable'") # --- Test 23: Verify Valid Function --- def test_verify_valid(pool: memhub.MemBuddy*): testcheck.section("Test 23: Verify Valid Function") core: mlirlite.LLVMTypeCore* = mlirlite.LLVMTypeCore(pool) mcore: mlirlite.LLVMModuleCore* = mlirlite.LLVMModuleCore(pool) ty_i32: mlirlite.LLVMType* = core.Int32() mod: mlirlite.Module* = mcore.NewModule("verify_valid") func: mlirlite.Function* = mcore.CreateFunction(mod, "add", ty_i32) mcore.AddParam(func, ty_i32, "%a") mcore.AddParam(func, ty_i32, "%b") entry: mlirlite.BasicBlock* = mcore.CreateBlock(func, "entry") builder: mlirlite.IRBuilder* = mcore.NewBuilder(func) mlirlite.position_at_end(builder, entry) v_a: mlirlite.Value* = mcore.SSAValue(ty_i32, "%a") v_b: mlirlite.Value* = mcore.SSAValue(ty_i32, "%b") v_c: mlirlite.Value* = mlirlite.build_add(builder, v_a, v_b) mlirlite.build_ret(builder, v_c) result: mlirlite.VerifyResult* = mcore.NewVerifyResult(4096) err_count: int = mcore.VerifyFunction(func, result) testcheck.check(err_count == 0, "valid add function: 0 errors", "valid function should pass verification") testcheck.check(result.ErrorCode == mlirlite.VERIFY_OK, "error code = VERIFY_OK", "wrong error code for valid function") # --- Test 24: Verify Missing Terminator --- def test_verify_no_terminator(pool: memhub.MemBuddy*): testcheck.section("Test 24: Verify Missing Terminator") core: mlirlite.LLVMTypeCore* = mlirlite.LLVMTypeCore(pool) mcore: mlirlite.LLVMModuleCore* = mlirlite.LLVMModuleCore(pool) ty_i32: mlirlite.LLVMType* = core.Int32() mod: mlirlite.Module* = mcore.NewModule("verify_noterm") func: mlirlite.Function* = mcore.CreateFunction(mod, "noterm", ty_i32) mcore.AddParam(func, ty_i32, "%a") entry: mlirlite.BasicBlock* = mcore.CreateBlock(func, "entry") builder: mlirlite.IRBuilder* = mcore.NewBuilder(func) mlirlite.position_at_end(builder, entry) v_a: mlirlite.Value* = mcore.SSAValue(ty_i32, "%a") mlirlite.build_add(builder, v_a, v_a) # no ret result: mlirlite.VerifyResult* = mcore.NewVerifyResult(4096) err_count: int = mcore.VerifyFunction(func, result) testcheck.check(err_count > 0, "missing terminator detected", "should detect missing terminator") testcheck.check(result.ErrorCode == mlirlite.VERIFY_ERR_NO_TERMINATOR, "error code = NO_TERMINATOR", "wrong error code for missing terminator") # --- Test 25: Verify Duplicate Definition --- def test_verify_duplicate_def(pool: memhub.MemBuddy*): testcheck.section("Test 25: Verify Duplicate Definition") core: mlirlite.LLVMTypeCore* = mlirlite.LLVMTypeCore(pool) mcore: mlirlite.LLVMModuleCore* = mlirlite.LLVMModuleCore(pool) ty_i32: mlirlite.LLVMType* = core.Int32() mod: mlirlite.Module* = mcore.NewModule("verify_dup") func: mlirlite.Function* = mcore.CreateFunction(mod, "dup_test", ty_i32) mcore.AddParam(func, ty_i32, "%a") entry: mlirlite.BasicBlock* = mcore.CreateBlock(func, "entry") builder: mlirlite.IRBuilder* = mcore.NewBuilder(func) mlirlite.position_at_end(builder, entry) v_a: mlirlite.Value* = mcore.SSAValue(ty_i32, "%a") v_c: mlirlite.Value* = mlirlite.build_add(builder, v_a, v_a) # manually append a duplicate definition line "%0 = add i32 %a, %a" dup_text: str = pool.alloc(64) string.strcpy(dup_text, "%0 = add i32 %a, %a") mlirlite.block_append_text(pool, entry, dup_text) mlirlite.build_ret(builder, v_c) result: mlirlite.VerifyResult* = mcore.NewVerifyResult(4096) err_count: int = mcore.VerifyFunction(func, result) testcheck.check(err_count > 0, "duplicate definition detected", "should detect duplicate definition") testcheck.check(result.ErrorCode == mlirlite.VERIFY_ERR_DUPLICATE_DEF, "error code = DUPLICATE_DEF", "wrong error code for duplicate def") # --- Test 26: Verify Undefined Use --- def test_verify_undef_use(pool: memhub.MemBuddy*): testcheck.section("Test 26: Verify Undefined Use") core: mlirlite.LLVMTypeCore* = mlirlite.LLVMTypeCore(pool) mcore: mlirlite.LLVMModuleCore* = mlirlite.LLVMModuleCore(pool) ty_i32: mlirlite.LLVMType* = core.Int32() mod: mlirlite.Module* = mcore.NewModule("verify_undef") func: mlirlite.Function* = mcore.CreateFunction(mod, "undef_test", ty_i32) mcore.AddParam(func, ty_i32, "%a") entry: mlirlite.BasicBlock* = mcore.CreateBlock(func, "entry") # manually append a line with an undefined reference "%0 = add i32 %ghost, %a" line1: str = pool.alloc(64) string.strcpy(line1, "%0 = add i32 %ghost, %a") mlirlite.block_append_text(pool, entry, line1) # manually append terminator line2: str = pool.alloc(64) string.strcpy(line2, "ret i32 %0") mlirlite.block_append_text(pool, entry, line2) entry.IsTerminated = 1 result: mlirlite.VerifyResult* = mcore.NewVerifyResult(4096) err_count: int = mcore.VerifyFunction(func, result) testcheck.check(err_count > 0, "undefined use detected", "should detect undefined use") testcheck.check(result.ErrorCode == mlirlite.VERIFY_ERR_UNDEFINED_USE, "error code = UNDEFINED_USE", "wrong error code for undefined use") # --- Test 27: Verify Module (phi/labels) --- def test_verify_module(pool: memhub.MemBuddy*): testcheck.section("Test 27: Verify Module (phi/labels)") core: mlirlite.LLVMTypeCore* = mlirlite.LLVMTypeCore(pool) mcore: mlirlite.LLVMModuleCore* = mlirlite.LLVMModuleCore(pool) ty_i32: mlirlite.LLVMType* = core.Int32() mod: mlirlite.Module* = mcore.NewModule("verify_module") # function 1: simple add (valid) func1: mlirlite.Function* = mcore.CreateFunction(mod, "add", ty_i32) mcore.AddParam(func1, ty_i32, "%a") mcore.AddParam(func1, ty_i32, "%b") entry1: mlirlite.BasicBlock* = mcore.CreateBlock(func1, "entry") builder1: mlirlite.IRBuilder* = mcore.NewBuilder(func1) mlirlite.position_at_end(builder1, entry1) v_a: mlirlite.Value* = mcore.SSAValue(ty_i32, "%a") v_b: mlirlite.Value* = mcore.SSAValue(ty_i32, "%b") v_c: mlirlite.Value* = mlirlite.build_add(builder1, v_a, v_b) mlirlite.build_ret(builder1, v_c) # function 2: phi + branches (valid; block labels must not be flagged undefined) func2: mlirlite.Function* = mcore.CreateFunction(mod, "phi_test", ty_i32) f2_entry: mlirlite.BasicBlock* = mcore.CreateBlock(func2, "entry") then_blk: mlirlite.BasicBlock* = mcore.CreateBlock(func2, "then") else_blk: mlirlite.BasicBlock* = mcore.CreateBlock(func2, "else") merge: mlirlite.BasicBlock* = mcore.CreateBlock(func2, "merge") builder2: mlirlite.IRBuilder* = mcore.NewBuilder(func2) # entry: br label %then mlirlite.position_at_end(builder2, f2_entry) mlirlite.build_br(builder2, then_blk) # then: br label %merge mlirlite.position_at_end(builder2, then_blk) v_1: mlirlite.Value* = mcore.ConstInt32(1) mlirlite.build_br(builder2, merge) # else: br label %merge mlirlite.position_at_end(builder2, else_blk) v_2: mlirlite.Value* = mcore.ConstInt32(2) mlirlite.build_br(builder2, merge) # merge: %r = phi i32 [1, %then], [2, %else]; ret i32 %r mlirlite.position_at_end(builder2, merge) inc1: mlirlite.PhiIncoming* = mlirlite.new_phi_incoming(pool, v_1, then_blk) inc2: mlirlite.PhiIncoming* = mlirlite.new_phi_incoming(pool, v_2, else_blk) inc1.Next = inc2 v_r: mlirlite.Value* = mlirlite.build_phi(builder2, ty_i32, inc1, 2) mlirlite.build_ret(builder2, v_r) result: mlirlite.VerifyResult* = mcore.NewVerifyResult(4096) err_count: int = mcore.VerifyModule(mod, result) testcheck.check(err_count == 0, "module with phi/branches: 0 errors", "valid module with phi should pass verification") testcheck.check(result.ErrorCode == mlirlite.VERIFY_OK, "error code = VERIFY_OK", "wrong error code for valid module") def main() -> int: testcheck.begin("LLvmLiteTest: mlirlite 库(LLVM IR 生成)") # init pool pool_mem: bytes = stdlib.malloc(POOL_SIZE) if pool_mem is None: stdio.printf("FAIL: malloc for pool failed\n") return 1 pool: memhub.MemBuddy* = memhub.MemBuddy(pool_mem, POOL_SIZE) if pool is None: stdio.printf("FAIL: memhub.MemBuddy init failed\n") return 1 test_type_print(pool) test_value_print(pool) test_build_add(pool) test_build_if_else(pool) test_module_print(pool) test_array_type(pool) test_struct_type(pool) test_func_type(pool) test_declare(pool) test_float_types(pool) test_float_binops(pool) test_bitwise_ops(pool) test_fcmp(pool) test_casts(pool) test_fp_conversions(pool) test_phi(pool) test_switch(pool) test_select(pool) test_globals(pool) test_attributes(pool) test_atomic(pool) test_inline_asm_unreachable(pool) test_verify_valid(pool) test_verify_no_terminator(pool) test_verify_duplicate_def(pool) test_verify_undef_use(pool) test_verify_module(pool) return testcheck.end()