Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Floating point printf不适用于LLVM IR中的浮动_Floating Point_Printf_Llvm_Llvm Ir - Fatal编程技术网

Floating point printf不适用于LLVM IR中的浮动

Floating point printf不适用于LLVM IR中的浮动,floating-point,printf,llvm,llvm-ir,Floating Point,Printf,Llvm,Llvm Ir,我想在屏幕上打印浮点变量的值。我在LLVM IR代码中声明printf函数,它正在成功链接 每当我打印一个整数、一个字符数据类型或一个字符串时,printf都会像在C代码中打印一样将它们正常地打印到屏幕上。但是,如果我将浮点值传递给printf,它将打印0.000000,而不是打印浮点数。我多次检查源代码,似乎语法是正确的。它应该是打印2.75!我正在看这段代码,我完全不明白代码的行为与我写的代码有什么不同 target datalayout = "e-m:e-i64:64-f80:1

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

每当我打印一个整数、一个字符数据类型或一个字符串时,printf都会像在C代码中打印一样将它们正常地打印到屏幕上。但是,如果我将浮点值传递给printf,它将打印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 $
它成功地打印了整数和字符,但不是浮点数

原因是printf是一个可变函数,可变函数将浮点参数提升为双变量。看

因此,在将%1传递给printf之前,应该首先将其强制转换为double,这就是clang所做的。比如说

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

注意使用fpext的原因是printf是一个可变函数,可变函数将浮点参数提升为双精度。看

因此,在将%1传递给printf之前,应该首先将其强制转换为double,这就是clang所做的。比如说

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


请注意fpext的使用只是一个猜测:您是否可以尝试在GEP之前重新加载obj,或者对obj4执行GEP?我的假设是,您处理的是“旧”数据,但整数和字符值是意外正确打印的。这只是一个猜测:您可以尝试在GEP之前重新加载obj,或者对obj4执行GEP吗?我的假设是,您处理的是“旧”数据,但意外地正确打印了整数值和字符值。我认为%lf是double的格式说明符。我提供了它%f,它是float的格式说明符。至少当我在C/C++代码中尝试使用float数据类型调用printf时,它可以正常工作,而不需要将float转换为double。LLVM IR是否使用与C/C++不同的printf版本?printf LLVM调用的函数是您在libcWell中熟悉的函数我认为%lf是double的格式说明符。我提供了它%f,它是float的格式说明符。至少当我在C/C++代码中尝试使用float数据类型调用printf时,它可以正常工作,而不需要将float转换为double。LLVM IR是否使用与C/C++不同的printf版本?printf LLVM调用的函数是您在libc中熟悉的函数