为什么LLVM的.ll文件中main函数存在%retval变量而普通函数没有
这个差异是Clang前端对main函数的特殊语法规则兼容逻辑导致的,核心原因如下:
- C标准的特殊规定
C99及后续C标准明确要求:如果int返回值类型的main函数执行到函数末尾没有显式执行return语句,编译器必须默认给它补充返回0的逻辑,不属于未定义行为。
而普通的自定义int返回值函数如果执行到末尾没有return,属于标准明确的未定义行为,编译器不需要做任何兜底处理。 - Clang的实现逻辑
Clang在生成IR的前端阶段,为了实现上述main函数的默认返回规则,会在进入main函数的entry块时,先预分配一个%retval栈变量,默认写入初始值0。如果后续代码中出现显式的return x语句,就会把x覆盖写入这个%retval变量,最后函数返回时读取该变量的值作为返回值。
你给出的示例中因为显式写了return 0,所以最后直接返回了常量0,没有用到预分配的%retval,又因为你是在无优化(O0,对应IR中的optnone属性)模式下编译,编译器不会删除无用的预分配变量和存储指令,所以就会留在生成的IR中。如果开启优化(比如-O2),这个无用的%retval变量会被优化消除,和普通函数的生成结果一致。
普通自定义函数不需要处理默认返回的兜底逻辑,所以不会预先分配%retval变量。
内容的提问来源于stack exchange,提问作者roderickdai
相关产品推荐
相关产品推荐

