LLVM SimplifyCFGOpt::run触发EXC_BAD_ACCESS错误求助
从LLVM IR中排查EXC_BAD_ACCESS错误的原因
核心错误:基本块存在多条终止指令
你生成的IR里,then和else基本块都包含两条连续的终止指令(br),这直接破坏了LLVM控制流图(CFG)的合法性:
then: ; preds = %entry store i32 42, ptr %ret, align 4 br label %retblock br label %merge ; 这条指令永远无法被执行,属于无效冗余终止指令
else: ; preds = %entry store i32 24, ptr %ret, align 4 br label %retblock br label %merge ; 同样是无效的冗余终止指令
LLVM要求每个基本块的最后一条指令必须是唯一的终止指令(br/ret/switch等),多个终止指令会让优化器(比如调用栈里的SimplifyCFGOpt)在分析控制流时出现预期外的内存访问,触发EXC_BAD_ACCESS错误。
次要错误1:返回类型不匹配
main函数定义为define i32 @main(),要求返回i32类型,但merge块里的指令是ret void,返回类型完全不兼容,这也会导致LLVM后端处理失败。
次要错误2:冗余的栈分配
你额外分配了%ret栈空间存储返回值,完全可以直接在then/else块中用ret i32 42和ret i32 24直接返回,没必要先store再load,既浪费栈空间又增加冗余指令。
修正后的合法LLVM IR
define i32 @main() { entry: %a = alloca i32, align 4 ; 注:原C代码中的*0x400访问固定地址1024,属于非法内存区域,运行时仍会崩溃,但这是原代码逻辑问题,不是IR生成错误 %deref = load i32, ptr inttoptr (i32 1024 to ptr), align 4 store i32 %deref, ptr %a, align 4 %a2 = load i32, ptr %a, align 4 %cmptmp = icmp sgt i32 %a2, 123 br i1 %cmptmp, label %then, label %else then: ret i32 42 ; 直接返回数值,无需栈存储 else: ret i32 24 ; 直接返回数值,无需栈存储 }
内容的提问来源于stack exchange,提问作者Oskari Mantere
相关产品推荐
相关产品推荐

