Files
Viper_RegressionTesting/LLvmLiteTest/App/main.vp
T
TermiNexus ee6461be46 chore(comments): Test 仓注释英文化(R11)
把 81 个 .vp 文件的中文 # 注释与三引号文档串改写为简洁英文,每个连续注释块 <=2 行;运行时中文字符串字面量(testcheck.begin/print 等用户可见消息)保持原样。骨架比对 HEAD 与工作区 112 文件漂移 0,全量 77/77 顺序回归通过。
2026-10-05 22:43:38 +08:00

1094 lines
46 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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
testcheck.check(string.strstr(buf, "module {") is not None,
"contains 'module {'",
"missing 'module {'")
testcheck.check(string.strstr(buf, "target triple") is not None,
"contains 'target triple'(MLIR 只在注释里标注)",
"missing 'target triple'")
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<i32 (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_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<i32 (i32, !llvm.ptr)>") == 0,
"func type -> !llvm.func<i32 (i32, !llvm.ptr)>",
"func type fail")
# void () -> !llvm.func<none ()>: 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<none ()>") == 0,
"void func -> !llvm.func<none ()>",
"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()