Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/facebook/8.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
LLVM将0作为参数传递给外部函数调用_Llvm_Llvm Clang_Llvm Ir_Llvm Gcc - Fatal编程技术网

LLVM将0作为参数传递给外部函数调用

LLVM将0作为参数传递给外部函数调用,llvm,llvm-clang,llvm-ir,llvm-gcc,Llvm,Llvm Clang,Llvm Ir,Llvm Gcc,好吧,也许有人能帮我 我正在编写一个小型LLVM IR测试程序: ; ModuleID = 'main' target datalayout = "e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-cygwin" define i32 @my_main() { entry: %0 = alloca i64 store i64 42, i64* %0 %1 = load i64* %0 call v

好吧,也许有人能帮我

我正在编写一个小型LLVM IR测试程序:

; ModuleID = 'main'
target datalayout = "e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-cygwin"
define i32 @my_main() {
entry:
  %0 = alloca i64
  store i64 42, i64* %0
  %1 = load i64* %0
  call void @put_integer(i32 15)
  ret i32 0
}
declare void @put_integer(i32)
实际上,它可以简化为:

; ModuleID = 'main'
target datalayout = "e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-cygwin"
define i32 @my_main() {
entry:
  call void @put_integer(i32 15)
  ret i32 0
}
declare void @put_integer(i32)
其中_put_integer是一个外部程序,我使用gcc或clang编译它(这与问题无关)

外部程序如下所示:

#include <stdio.h>
void put_integer(int Value)
{
    printf("%d", Value);
}
我还有一个小的c-main程序,它调用我的IR程序:

#include <stdio.h>
extern int my_main(void);
int main(int argc, char *args[])
{
    printf("Calling Mainprogram\n\n");
    int n_return_value = my_main();
    printf("\n\nMainprogram Returned: %u\n", n_return_value); 
    return n_return_value;
}
这工作正常,程序启动并运行

问题是实际的printf()调用打印0,而不是我作为IR调用的参数提供的15。我进入了用gdb创建的程序,检查了我的put_integer()函数中的堆栈帧,果然它说0是作为参数传递的

所以现在的问题是,我传递给LLVM IR调用的参数没有传递给外部C函数,而是传递给了0

谁能告诉我我做错了什么

多谢各位

编辑: 根据下面的注释,我在这里包含了IRBuilder代码,它在第一个块中创建了我的IR代码的相关部分

Constant *left = ConstantInt::get( getGlobalContext(), APInt( 32, 15 ) );

FunctionType *printf_type =
    TypeBuilder<void( int ), false>::get( getGlobalContext() );

Function *func = cast<Function>( MODULE.getOrInsertFunction(
    "put_integer", printf_type ) );

BUILDER.CreateCall(func,left );

但是我的代码(顺便说一句,我从这里的答案中得到的)没有生成,但是我想IRBuilder类应该最清楚要生成什么代码,所以我不知道这是否是一个问题。

在我的情况下,答案是我在LLVM模块中使用了错误的目标三元组。没有有效的三元组列表,我通过编译和分解一个C程序以某种模糊的方式获得了我的三元组列表,但结果证明它是错误的

如果有人与cygwin合作,正确的目标是:

x86_64-unknown-windows-cygnus

使用错误的目标三元组时,对外部函数的调用使用了错误类型的参数传递,结果是没有参数到达它。

这几乎肯定是管道中的一个错误。为了将问题一分为二,我建议从IR中转储由
llc
生成的程序集,并查看调用
put\u integer
的指令是否正确。实际上,我问题中的第一个块是IRBuilder类转储的结果,因此这实际上是传递给llvm工具进行处理的内容。这有点令人惊讶,因为我认为调用中需要有“calli32(i8*,…)*@printf(i8*%msg,i32 12,i8 42)”中的类型,这是手册中的一个示例。我将把生成这个问题的生成器代码添加到我的问题中
Constant *left = ConstantInt::get( getGlobalContext(), APInt( 32, 15 ) );

FunctionType *printf_type =
    TypeBuilder<void( int ), false>::get( getGlobalContext() );

Function *func = cast<Function>( MODULE.getOrInsertFunction(
    "put_integer", printf_type ) );

BUILDER.CreateCall(func,left );
call i32 (i8*, ...)* @printf(i8* %msg, i32 12, i8 42)
x86_64-unknown-windows-cygnus