LLVM 通过将整数转换为浮点数

Posted

技术标签:

【中文标题】LLVM 通过将整数转换为浮点数【英文标题】:LLVM pass converting integer to float 【发布时间】:2020-06-03 05:32:06 【问题描述】:

我正在编写一个需要将整数类型转换为各种浮点类型的 LLVM 通道。我正在尝试使用 UIToFp 指令将整数值转换为浮点值。作为一个基本的测试用例,我使用类似于

的代码

Value* promotedRandom = Builder.CreateUIToFP(ConstantInt::get(Type::getInt32Ty(M.getContext()), 4), Type::getFloatTy(M.getContext()));

其中 Builder 是我的函数的 IRBuilder 实例。但是由于某种原因,转换后这个值是 0 而不是 4,我可以通过打印值来确认。奇怪的是,如果 CreateUIToFP 的类型参数是 double 类型而不是 float 类型,则会打印 4 的正确答案。在下面的 UIToFP 文档中,我没有看到发生这种行为的任何原因。这个问题的原因是什么,应该如何解决。

将无符号整数常量转换为相应的浮点常量。 TYPE 必须是标量或向量浮点类型。 CST 必须是标量或向量整数类型。 CST 和 TYPE 都必须是标量,或相同数量元素的向量。

另外,如果我用 clang 编译这段代码

int main()
    int test = 4;
    float test2 = (float)test;
    printf("%f\n", test2);

我收到以下说明

define dso_local i32 @main() #0 
  %1 = alloca i32, align 4
  %2 = alloca float, align 4
  store i32 4, i32* %1, align 4
  %3 = load i32, i32* %1, align 4
  %4 = sitofp i32 %3 to float
  store float %4, float* %2, align 4
  %5 = load float, float* %2, align 4
  %6 = fpext float %5 to double
  %7 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), double %6)
  ret i32 0

它显示了sitofp 和整数到浮点数的转换工作正常。尽管我使用的是 uitofp 而不是 sitofp,但我都尝试过,但都没有工作。

【问题讨论】:

将无符号整数转换为浮点数会牺牲精度。我猜零应该是 llvm 对精度损失或未定义行为的响应。 【参考方案1】:

我发现问题在于 printf 没有将浮点数作为参数。当浮点数传递给 printf 时,它们被提升为双精度数。当我取浮点值并将其提升为双精度值时,代码可以正常工作。

【讨论】:

以上是关于LLVM 通过将整数转换为浮点数的主要内容,如果未能解决你的问题,请参考以下文章

在 C 中的某些整数上使用位操作中断将整数转换为浮点数

将 INT_MAX 转换为浮点数,然后再转换回整数。

将文本转换为浮点数/整数/日期时,Delphi 消息“您已插入无效值”

如何在 x86(32 位)程序集中将无符号整数转换为浮点数?

如何防止 Gson 将整数表示为浮点数

C:将最小 32 位整数 (-2147483648) 转换为浮点数给出正数 (2147483648.0)