如何从 LLVM IR 打印浮点数?

How to print floats from LLVM IR?

我在 LLVM IR 中使用 printf() 函数时遇到问题。我只想打印一个浮点数的值,但我只得到 0.000000。它适用于整数和字符串,但不适用于浮点数。

简单示例:

@.fstr = private unnamed_addr constant [4 x i8] c"%f[=10=]A[=10=]"

declare i32 @printf(i8*, ...)

define i32 @main() {
    %1 = getelementptr [4 x i8],[4 x i8]* @.fstr, i64 0, i64 0
    %2 = call i32 @printf(i8* %1, double 2.0)
    %3 = call i32 @printf(i8* %1, float 2.0)
    ret i32 0
}

当我用 LLVM 编译它并用 Clang link 编译它和 运行 可执行文件时,我得到:

0.000000
0.000000

如果我 运行 使用 lli 的 .bc 文件,结果相同。我已经阅读了这篇相关文章 ,但如您所见,它也不适用于双打。

在 运行 你的例子中使用 lli-10 我得到一个 @printf' defined with type 'i32 (i8*, ...)*' but expected 'i32 (i8*, double)*' 错误而不是打印 0.000000 的成功调用。

此错误是预料之中的,并解释了原因 here。 post 中的相关位是

... if the type in front of the call is a function pointer type, then that is used as the type of the thing being called, while if it's not, then it is used as the return type, and the type of the call is inferred from the arguments present on the instruction.

这就是为什么 LLVM 在第一次调用中将 printf 的类型推断为 i32 (i8*, double)* 但后来发现它被声明为 i32 (i8*, ...)* 的原因。要解决此问题,只需正确注释调用即可,

%2 = call i32 (i8*, ...) @printf(i8* %1, double 2.0)
%3 = call i32 (i8*, ...) @printf(i8* %1, float 2.0)

您很快就会注意到第二个 printf 调用仍然打印 0.000000。参见