我正在为JIT目的生成LLVM IR,我注意到当涉及聚合值时,LLVM的调用约定似乎与C调用约定不匹配。例如,当我将一个函数声明为采用{i32, i32}
(即C语言中的struct {int a, b;}
)参数时,它似乎将其自己的x86-64 GPR中的每个struct元素传递给函数,即使x86-64 ABI specifies(第3.2.3节),这样的结构应该打包在一个64位GPR中。
这是尽管LLVM的文档claiming默认匹配C调用约定:
“
ccc
” - C调用约定此调用约定(如果未指定其他调用约定,则为缺省值)与目标C调用约定匹配。这个调用约定支持varargs函数调用,并容忍声明的原型中的一些不匹配,并实现函数的声明(正常C)。
我的问题是:我做错了导致LLVM与C调用约定不匹配,还是这种已知的行为? (至少,文档似乎是错误的,不是吗?)
我只能在网络上找到很少提及该问题的内容,例如2007年的this bug report,声称已修复。它还声称“首先,LLVM没有办法将聚合作为奇异值*来处理”,我不知道它是否在2007年是真的,但现在似乎不是真的,因为{ {3}}说明。我还发现extractvalue
/insertvalue
其第二个(未被接受的)答案似乎只是隐含地接受了参数强制必须手动完成。
我目前正在构建用于在我的IR生成器中进行参数强制的代码,但它使我的设计变得相当复杂(更不用说使其特定于架构),所以如果我只是做错了什么,我宁愿知道这一点。 :)