You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用LLVM Intrinsic函数时LLVMBuildExtractValue触发空指针崩溃求助

问题原因及修复方案

根本原因

错误定义了llvm.sadd.with.overflow.i64的函数返回类型,导致后续LLVMBuildExtractValue操作非法Value对象,触发空指针访问。

llvm.sadd.with.overflow.i64是LLVM提供的带溢出检测的加法内在函数,它的返回类型不是单个i64,而是一个包含两个元素的聚合结构体:

  • 索引0:加法运算结果(i64类型)
  • 索引1:溢出标志(i1布尔类型)

你的代码中错误地将函数返回类型设置为LLVMInt64Type(),这会导致LLVMBuildCall生成的v_res不是合法的聚合类型值。当调用LLVMBuildExtractValue尝试提取索引1的元素时,LLVM内部处理非法Value对象时触发空指针访问(对应崩溃栈中llvm::Value::getContext() const访问0x0地址)。

修复代码

修改函数返回类型的定义,创建正确的结构体返回类型:

v_fn = LLVMGetNamedFunction(mod, "llvm.sadd.with.overflow.i64");
if (!v_fn)
{
    LLVMTypeRef param_types[2];
    LLVMTypeRef ret_types[2];
    LLVMTypeRef v_fn_type;

    param_types[0] = LLVMInt64Type();
    param_types[1] = LLVMInt64Type();

    // 定义正确的返回结构体类型:i64(结果)+ i1(溢出标志)
    ret_types[0] = LLVMInt64Type();
    ret_types[1] = LLVMInt1Type();
    LLVMTypeRef ret_struct_type = LLVMStructType(ret_types, 2, 0);

    v_fn_type = LLVMFunctionType(ret_struct_type, param_types, lengthof(param_types), 0);
    v_fn = LLVMAddFunction(mod, "llvm.sadd.with.overflow.i64", v_fn_type);
}

params[0] = l_int64_const(1);
params[1] = l_int64_const(1);

v_res = LLVMBuildCall(b, v_fn, params, lengthof(params), "");

v_flag = LLVMBuildExtractValue(b, v_res, 1, "");
// 注意:溢出标志是i1类型,无需调用LLVMBuildIsNotNull,直接使用即可
// v_flag = LLVMBuildIsNotNull(b, v_flag, "");

额外说明

  • 溢出标志本身是i1布尔类型,LLVMBuildIsNotNull是用于指针类型的判断逻辑,此处属于冗余代码,建议移除。
  • 修复函数类型后,LLVMBuildCall会生成合法的聚合类型值,LLVMBuildExtractValue可正常提取对应索引的元素,不会再触发空指针崩溃。

内容的提问来源于stack exchange,提问作者tutu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 07:40:36