我正在为LLVM编写一个编译器,用于语义 explicity 定义除以的除法应始终引发浮点异常的语言。问题是,在我的原始IR上运行-mem2reg和-constprop后,我的代码转换为:
define i32 @main() {
entry:
%t3 = sdiv i32 2, 0
ret i32 7
}
然后由llc -O0
转换为:
.text
.globl _c0_main
.align 16, 0x90
.type _c0_main,@function
main:
.cfi_startproc
# BB#0: # %entry
movl $7, %eax
ret
.Ltmp0:
.size main, .Ltmp0-main
.cfi_endproc
有没有办法强制公司不要删除有效的操作?
答案 0 :(得分:1)
sdiv指令除以零语义,未定义。如果你的前端语言有一些定义的语义,你需要使用sdiv以外的指令。
也许你必须检测除以零,并在运行时分支给一系列指令,这些指令给出了你想要的语义。
答案 1 :(得分:0)
language reference表示科林所说的[d]ivision by zero leads to undefined behavior
。
因此,您必须检查被除数是否为零并显式生成浮点异常。在C中,这可能如下所示:
extern void raiseFloatingException();
int someFunc() {
int a = 2;
int b = 0;
if (!b) {
raiseFloatingException();
}
int result = a / b;
return result;
}
如果您将其编译为位代码并使用-mem2reg进行优化,您将获得可以使用后端生成的模式:
define i32 @someFunc() #0 {
%1 = icmp ne i32 0, 0
br i1 %1, label %3, label %2
; <label>:2 ; preds = %0
call void (...)* @raiseFloatingException()
br label %3
; <label>:3 ; preds = %2, %0
%4 = sdiv i32 2, 0
ret i32 %4
}
请注意,您必须提供raiseFloatingException
功能并将其与您的代码相关联。