gpt4 book ai didi

floating-point - printf 不适用于 LLVM IR 中的 float

转载 作者:行者123 更新时间:2023-12-02 19:20:20 25 4
gpt4 key购买 nike

我想将浮点变量的值打印到屏幕上。我在 LLVM IR 代码中声明了 printf() 函数,它正在成功链接。

每当我打印整数或字符数据类型或字符串时,printf() 都会像在 C 代码中一样将它们正常打印到屏幕上。但是,如果我将 float 传递给 printf(),它不会打印 float ,而是打印 0.000000。我多次检查了源代码,似乎语法是正确的。它应该打印 2.75!我正在查看这段代码,但我完全不明白代码与我编写的代码有何不同的行为。

target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

@obj1 = global {i32, float, i8} zeroinitializer

@format_string = constant [10 x i8] c"%i %f %c\0A\00"

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

define i32 @main() {
entry:
%obj1 = load {i32, float, i8}, {i32, float, i8}* @obj1

%obj2 = insertvalue {i32, float, i8} %obj1, i32 44, 0
%obj3 = insertvalue {i32, float, i8} %obj2, float 2.75, 1
%obj4 = insertvalue {i32, float, i8} %obj3, i8 36, 2

store {i32, float, i8} %obj4, {i32, float, i8}* @obj1

%ptr.i32 = getelementptr {i32, float, i8}, {i32, float, i8}* @obj1, i32 0, i32 0
%0 = load i32, i32* %ptr.i32
%ptr.float = getelementptr {i32, float, i8}, {i32, float, i8}* @obj1, i32 0, i32 1
%1 = load float, float* %ptr.float
%ptr.i8 = getelementptr {i32, float, i8}, {i32, float, i8}* @obj1, i32 0, i32 2
%2 = load i8, i8* %ptr.i8

%format_ptr = getelementptr [10 x i8], [10 x i8]* @format_string, i64 0, i64 0
call i32 (i8*, ...) @printf(i8* %format_ptr, i32 %0, float %1, i8 %2)

ret i32 0
}

当我编译 LLVM IR 代码时,这是输出:

$ llvm-as code.ll -o code.bc
$ lli code.bc
44 0.000000 $

它成功打印了整数和字符,但没有打印 float !

最佳答案

原因是 printf 是可变参数函数,可变参数函数将 float 参数提升为 double。参见 Why does printf() promote a float to a double?

因此,您应该先将 %1 转换为 double,然后再将其传递给 printf,这就是 clang 所做的。例如

void f() {
float a = 1;
printf("%f", a);
}

给予

@.str = private unnamed_addr constant [3 x i8] c"%f\00", align 1

define void @f() {
%1 = alloca float, align 4
store float 1.000000e+00, float* %1, align 4
%2 = load float, float* %1, align 4
%3 = fpext float %2 to double
%4 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x
i8], [3 x i8]* @.str, i64 0, i64 0), double %3)
ret void
}

注意fpext的使用

关于floating-point - printf 不适用于 LLVM IR 中的 float ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63144506/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com