gpt4 book ai didi

c++ - 编译器在 eax 上来回生成 mov

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:37:28 27 4
gpt4 key购买 nike

int test1(int a, int b) {
if (__builtin_expect(a < b, 0))
return a / b;
return b;
}

由 clang 使用 -O3 -march=native 编译为

test1(int, int):                             # @test1(int, int)
cmp edi, esi
jl .LBB0_1
mov eax, esi
ret
.LBB0_1:
mov eax, edi
cdq
idiv esi
mov esi, eax
mov eax, esi # moving eax back and forth
ret

为什么 eaxidiv 之后来回移动?

gcc 有类似的行为,所以这似乎是有意为之。

gcc with -O3 -march=native 将代码编译为

test1(int, int):
mov r8d, esi
cmp edi, esi
jl .L4
mov eax, r8d
ret
.L4:
mov eax, edi
cdq
idiv esi
mov r8d, eax
mov eax, r8d #back and forth mov
ret

godbolt

最佳答案

这不是拼图的完整解决方案,但应该提供一些线索。

没有 __builtin_expect,clang 生成:

test2(int, int):                             # @test2(int, int)
mov ecx, esi
cmp edi, esi
jge .LBB1_2
mov eax, edi
cdq
idiv ecx
mov ecx, eax
.LBB1_2:
mov eax, ecx
ret

虽然寄存器分配在这里仍然很奇怪,但它至少是有道理的:如果分支被采用,ecx 中的 b 的值被转移到 eax 作为返回值。如果不采用,则除法结果(在 eax 中)必须传输到 ecx 以与其他情况相同的寄存器中。

可能是 __builtin_expect 说服编译器处理特殊情况,即在编译过程中分支被延迟的情况,孤立 .LBB1_2 标签并导致它最终缺席 assembly 。

关于c++ - 编译器在 eax 上来回生成 mov,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55166749/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com