gpt4 book ai didi

c++ - 为什么 clang 并不总是为相同的静态 constexpr 产生恒定值

转载 作者:行者123 更新时间:2023-12-04 09:42:14 31 4
gpt4 key购买 nike

static constexpr int
count_x(const char * str)
{
int count{};
for (;*str != 0; ++str) {
count += *str == 'x';
}
return count;
}

#define STRx1 "123456789x"
#define STRx4 STRx1 STRx1 STRx1 STRx1
#define STRx8 STRx4 STRx4
#define STRx16 STRx8 STRx8

int test1() { return count_x(STRx4); }
int test2() { return count_x(STRx8); }
int test3() { return count_x(STRx16); }
int test4() { constexpr auto k = count_x(STRx16); return k; }

给定上面的代码,clang 为 test1、test2 和 test4 生成一个常量值。为什么不用于 test3?
test1():                              # @test1()
mov eax, 4
ret
test2(): # @test2()
mov eax, 8
ret
test3(): # @test3()
xor eax, eax
mov dl, 49
mov ecx, offset .L.str.2+1
.LBB2_1: # =>This Inner Loop Header: Depth=1
xor esi, esi
cmp dl, 120
sete sil
add eax, esi
movzx edx, byte ptr [rcx]
add rcx, 1
test dl, dl
jne .LBB2_1
ret
test4(): # @test4()
mov eax, 16
ret
.L.str.2:
.asciz "123456789x123456789x123456789x123456789x123456789x123456789x123456789x123456789x123456789x123456789x123456789x123456789x123456789x123456789x123456789x123456789x"

gcc 的作用是:
test1():
mov eax, 4
ret
test2():
mov eax, 8
ret
test3():
mov eax, 16
ret
test4():
mov eax, 16
ret

使用的编译命令行:
clang++ -Ofast -std=c++2a -S -o - -c src/test.cpp | grep -Ev $'^\t+\\.'
gcc9 -Ofast -std=c++2a -S -o - -c src/test.cpp | grep -Ev $'^\t+\\.'

编译器资源管理器:
https://godbolt.org/z/V-3MEp

最佳答案

正如 Tharwen 的评论所提到的,*默认 *a 限制为 100 个字符(或迭代)。

可以使用真正隐藏的选项更改此限制:

--scalar-evolution-max-iterations

Maximum number of iterations SCEV will symbolically execute a constant derived loop (MaxBruteForceIterations: Source)



将命令更改为:
clang++ -Ofast -std=c++2a -S -o - -c src/test.cpp -mllvm --scalar-evolution-max-iterations=1000

产生:
test1():                              # @test1()
mov eax, 4
ret
test2(): # @test2()
mov eax, 8
ret
test3(): # @test3()
mov eax, 16
ret
test4(): # @test4()
mov eax, 16
ret

查看 Compiler Explorer

这个限制和被标记为真正隐藏的选项,也许是有充分理由的。所以我不会去改变它并在没有关于它的效果的适当知识的情况下在生产中使用它(如果我找到了一些我会更新这个答案)。

供引用, here在 LLVM 源代码 (ScalarEvolution::computeLoadConstantCompareExitLimit) 中,是 test3 使用限制的地方。

关于c++ - 为什么 clang 并不总是为相同的静态 constexpr 产生恒定值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58083201/

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