Files
Viper_RegressionTesting/LLvmLiteTest/App/main.vp
T
TermiNexus 55a517fbd2 test(llvmlitest): 断言迁移到 MLIR 口径 + 内存池放大到 80MB
mlirlite 发射器改输出 MLIR 文本后,本测试 58 条断言仍在断言旧 LLVM IR 文本
(i32*、add i32、icmp sgt、asm sideeffect、label %then、@.str = 等)→ 全部
迁移到实际 MLIR 形态(!llvm.ptr、llvm.add、llvm.icmp "sgt"、
llvm.inline_asm has_side_effects、^then:、llvm.mlir.global 等)。属性用例按
README §3.3「记录但不渲染」改为签名正向 + 属性文本负向断言。

同时 POOL_SIZE 512KB → 80MB:本测试 27 用例共享同一池(不像 MLIRLiteTest
每用例切子池),mlirlite 单次 PrintModule 需约 1MiB 缩进缓冲,512KB 会池耗尽。

本文件另含既有未提交的注解现代化改动(X | t.CPtr → X*、t.CChar | t.CPtr →
str 等),一并纳入本次提交。结果:PASS 80 / FAIL 0。
2026-10-04 21:51:34 +08:00

1164 lines
50 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
# 内存大小
# 单端 MLIR 后 mlirlite 渲染单次 PrintModule 需约 1 MiB 缩进缓冲 + 类型/初值
# 草稿,且本测试 27 个用例共享**同一个**池(不像 MLIRLiteTest 每用例切子池)
# ⇒ 512 KB 远不够(池耗尽)。与 MLIRLiteTest 主池同口径放大到 80 MiB。
define POOL_SIZE = 83886080 # 80MB
# ============================================================
# 测试 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")
# 不透明指针: 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")
# ============================================================
# 测试 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()
# 常量 42 -> "42 : i32"(MLIR attribute 文本形态)
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 值 %0 -> "%0"(MLIR 操作数不带类型)
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")
# ============================================================
# 测试 3: 构建 add 函数
# llvm.func @add(%a: i32, %b: i32) -> i32 {
# %0 = llvm.add %a, %b : i32
# llvm.return %0 : i32
# }
# ============================================================
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()
# 创建模块 + 函数
mod: mlirlite.Module* = mcore.NewModule("test_add")
func: mlirlite.Function* = mcore.CreateFunction(mod, "add", ty_i32)
# 添加参数
mcore.AddParam(func, ty_i32, "%a")
mcore.AddParam(func, ty_i32, "%b")
# 创建 entry 块
entry: mlirlite.BasicBlock* = mcore.CreateBlock(func, "entry")
# 创建 builder
builder: mlirlite.IRBuilder* = mcore.NewBuilder(func)
mlirlite.position_at_end(builder, entry)
# 为参数创建 Value 包装
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)
# 打印函数
buf: str = pool.alloc(4096)
buf[0] = 0
mcore.PrintFunction(buf, 4096, func)
testcheck.info(buf)
# 验证关键内容
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")
# ============================================================
# 测试 4: 构建 if-then-else 函数(max)
# llvm.func @max(%a: i32, %b: i32) -> i32 {
# %0 = llvm.icmp "sgt" %a, %b : i32
# llvm.cond_br %0, ^then, ^else
# ^then:
# llvm.return %a : i32
# ^else:
# llvm.return %b : i32
# }
# ============================================================
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)
# 打印函数
buf: str = pool.alloc(4096)
buf[0] = 0
mcore.PrintFunction(buf, 4096, func)
testcheck.info(buf)
# 验证关键内容
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:'")
# ============================================================
# 测试 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()
# 创建模块
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")
# 函数 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)
# 函数 2: void 函数
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)
# 打印模块
buf: str = pool.alloc(8192)
buf[0] = 0
mcore.PrintModule(buf, 8192, mod)
testcheck.info(buf)
# 验证关键内容
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'")
# ============================================================
# 测试 6: 数组类型打印
# ============================================================
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")
# ============================================================
# 测试 7: 结构体类型打印
# ============================================================
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")
# 空结构体 -> !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")
# ============================================================
# 测试 8: 函数类型打印
# ============================================================
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 ()> — 无参数 void 函数类型
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")
# ============================================================
# 测试 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")
# ============================================================
# 测试 10: 浮点类型与 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"
# (位模式无精度损失;类型注解为 MLIR 形态 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")
# ============================================================
# 测试 11: 浮点二元运算
# ============================================================
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'")
# ============================================================
# 测试 12: 位运算与移位
# ============================================================
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'")
# ============================================================
# 测试 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\"'")
# ============================================================
# 测试 14: 类型转换 (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'")
# ============================================================
# 测试 15: 浮点转换 (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'")
# ============================================================
# 测试 16: Phi 节点
# ============================================================
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 已转为块参数:不再输出 phi 行,改为 ^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")
# ============================================================
# 测试 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:'")
# ============================================================
# 测试 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'")
# ============================================================
# 测试 19: 全局变量 (字符串常量 + 整数)
# ============================================================
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")
# 字符串常量: @.str = private unnamed_addr constant [6 x i8] c"hello\00"
mcore.CreateGlobalString(mod, ".str", "hello")
# 整数全局变量: @counter = global i32 0
mcore.CreateGlobalInt(mod, "counter", 32, 0)
# 添加一个简单函数使模块非空
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")
# ============================================================
# 测试 20: 函数与参数属性
# ============================================================
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)
# 参数 0: i32 noundef %x
p0: mlirlite.Param* = mcore.AddParam(func, ty_i32, "%x")
mcore.ParamSetAttrs(p0, "noundef")
# 参数 1: i8* nocapture %p
p1: mlirlite.Param* = mcore.AddParam(func, ty_i8ptr, "%p")
mcore.ParamSetAttrs(p1, "nocapture")
# 函数属性: 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: 函数/参数属性(Attrs)记录但不渲染(见 includes/mlirlite/README.md §3.3)。
# 故断言签名本身正确、且属性文本不出现(模型字段仍保留)。
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")
# ============================================================
# 测试 21: 原子操作 (atomicrmw / cmpxchg)
# ============================================================
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'")
# ============================================================
# 测试 22: 内联汇编 + 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'")
# ============================================================
# 测试 23: SSA 验证 - 合法函数通过
# ============================================================
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")
# ============================================================
# 测试 24: SSA 验证 - 缺少终止指令
# ============================================================
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) # 无 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")
# ============================================================
# 测试 25: SSA 验证 - 重复定义
# ============================================================
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)
# 手动追加重复定义行 "%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")
# ============================================================
# 测试 26: SSA 验证 - 未定义引用
# ============================================================
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")
# 手动追加含未定义引用的行 "%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)
# 手动追加终止指令
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")
# ============================================================
# 测试 27: SSA 验证 - 模块级验证(含 phi/分支,验证块标签修复)
# ============================================================
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")
# 函数 1: 简单 add(合法)
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)
# 函数 2: 含 phi 与分支(合法,验证块标签不被误报为未定义)
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 生成)")
# 初始化 mpool
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()