我正在为LLVM编写一个编译器,用于一种语言,它的语义解释定义了零的除法应该总是引发浮点异常。问题是,在我的原始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有没有办法迫使llc不移除有效的操作?
发布于 2015-11-27 15:44:35
sdiv指令除以未定义的零语义。如果前端语言对此有一些定义的语义,则需要使用sdiv以外的其他指令。
也许您必须在运行时检测到一个除以零和分支的指令序列,这些指令提供了您想要的语义。
发布于 2015-11-30 08:30:14
语言参考指出了科林所说的[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函数并将其与代码链接。
https://stackoverflow.com/questions/33956873
复制相似问题