【发布时间】:2025-12-05 20:40:01
【问题描述】:
有时编译器会生成带有奇怪指令重复的代码,这些重复指令可以安全地删除。考虑以下代码:
int gcd(unsigned x, unsigned y) {
return x == 0 ? y : gcd(y % x, x);
}
这是汇编代码(生成的by clang 5.0 启用了优化):
gcd(unsigned int, unsigned int): # @gcd(unsigned int, unsigned int)
mov eax, esi
mov edx, edi
test edx, edx
je .LBB0_1
.LBB0_2: # =>This Inner Loop Header: Depth=1
mov ecx, edx
xor edx, edx
div ecx
test edx, edx
mov eax, ecx
jne .LBB0_2
mov eax, ecx
ret
.LBB0_1:
ret
在下面的sn-p中:
mov eax, ecx
jne .LBB0_2
mov eax, ecx
如果没有发生跳转,eax 会无明显原因地重新分配。
另一个例子是函数末尾的两个 ret:一个也可以完美地工作。
是编译器不够智能还是有理由不删除重复项?
【问题讨论】:
-
clang、c或c++? -
有趣的是 gcc 不这样做:godbolt.org/g/MxTiaY.
-
@lisyarus gcc 做做
-
添加
mov指令对分支预测器有何影响? -
请随时向 gcc 和 llvm 报告这个错过的优化。 2 'mov' 位于不同的基本块中,这使得优化有点困难,但仍然是可取的。
标签: c++ compiler-construction clang