我无法理解LLVM-IR指令“fptosi ... to”和“fptoui ... to”之间的区别。
我编写了一个示例程序来更好地理解这些指令的语义。
#include <stdio.h>
int main(int argc, char** argv)
{
double d = -3.5 - 4;
unsigned int ui = (unsigned int) d;
int si = (int) d;
printf("unsigned %u, 0x%x\n", ui, ui);
printf("signed %i, 0x%x\n", si, si);
return 0;
}
正如预期的那样,clang会生成这两种指令
...
%5 = fptoui double %4 to i32
store i32 %5, i32* %ui, align 4
%6 = load double* %d, align 8
%7 = fptosi double %6 to i32
store i32 %7, i32* %si, align 4
...
运行程序输出时是:
unsigned 4294967289, 0xfffffff9
signed -7, 0xfffffff9
这意味着,两个指令都产生相同的值(仅在一种情况下,该值稍后被解释为有符号而另一种被解释为无符号)
LLVM IR文档声明:
'fptoui'指令将其浮点操作数转换为 最接近(向零舍入)无符号整数值。
负二重0的最近无符号整数值是不是? 有谁知道这些指令在哪些情况下有不同的语义?
答案 0 :(得分:3)
将负浮点值转换为无符号类型会导致C和C ++中出现未定义的行为,我相信fptoui
的意图相同。
我认为它应该用以下内容指定:
'fptoui'指令将其浮点操作数转换为最接近的(向负无穷大舍入)整数值。如果值无法由
ty2
表示,则结果未定义。
在llvm邮件列表上询问这个问题可能会更好,以获得更权威的澄清。