我有一些iOS C ++代码,这些代码可以在本地计算机(LLVM 9.0)上正确编译,但是在我的构建服务器(LLVM 10.0)上不能正确编译。该项目是通过CMake生成的(两者版本相同),因此要编译的代码是相同的,并且具有相同的编译器设置。
最终意识到在LLVM10版本上未更新某些关键值后,我调查了该程序集,发现它完全跳过了部分代码。
void SceneDisplay::SetSize(const math::Vec2 &Size)
{
m_Size = Size;
m_ScreenWidth = int(m_Size.x * float(GraphicsUtil::WIDTH));
m_ScreenHeight = int(m_Size.y * float(GraphicsUtil::HEIGHT));
UpdateOffsetScale();
}
m_Size在类构造函数中初始化为1.0,1.0。一切正常,并且使用LLVM9完美无缺-使用LLVM10,我们得到了以下反汇编:
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset %rbp, -16
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
subq $16, %rsp
movq __ZN12GraphicsUtil6HEIGHTE@GOTPCREL(%rip), %rax
movq __ZN12GraphicsUtil5WIDTHE@GOTPCREL(%rip), %rcx
movq %rdi, -8(%rbp)
movq %rsi, -16(%rbp)
movq -8(%rbp), %rsi
Ltmp2347:
movq -16(%rbp), %rdi
movq (%rdi), %rdi
movq %rdi, 56(%rsi)
movl (%rcx), %edx
movl %edx, 12(%rsi)
movl (%rax), %edx
movl %edx, 16(%rsi)
movq (%rsi), %rax
movq %rsi, %rdi
callq *136(%rax)
addq $16, %rsp
popq %rbp
retq
如您所见,两个成员变量的分配已完全“优化”,仅假设m_Size.x和m_Size.y为1.0-因此只需复制GraphicsUtil :: WIDTH和HEIGHT的值。
我通过更改代码以对这些分配使用“ Size”而不是“ m_Size”来解决此问题,并以防万一,使它们易变。但是我想知道这里是否存在合法的编译器错误,或者我缺少什么?
编辑:应该注意的是,m_Size几乎永远不会是1.0,1.0
Edit2:在我的计算机上生成的分配的正确程序集(尽管不同的arch,目前无法获得与上面相同的arch)
str x8, [x0, #56]
lsr x9, x8, #32
fmov s0, w8
adrp x8, __ZN12GraphicsUtil5WIDTHE@GOTPAGE
ldr x8, [x8, __ZN12GraphicsUtil5WIDTHE@GOTPAGEOFF]
ldr s1, [x8]
ucvtf s1, s1
fmul s0, s0, s1
fcvtzs w8, s0
str w8, [x0, #12]
fmov s0, w9
adrp x8, __ZN12GraphicsUtil6HEIGHTE@GOTPAGE
ldr x8, [x8, __ZN12GraphicsUtil6HEIGHTE@GOTPAGEOFF]
ldr s1, [x8]
ucvtf s1, s1
fmul s0, s0, s1
fcvtzs w8, s0
str w8, [x0, #16]
答案 0 :(得分:0)
在做了一个最小的测试用例之后,我能够确认那肯定是编译器错误。
条件:没有其他代码修改m_Size,初始化m_Size math::Vec2 m_Size{1.0, 1.0};
。我可以在10.0之前找到的所有LLVM版本上完美运行,似乎在该版本上发生了某种回归。
已提交给Apple的LLVM团队和llvm.org。
感谢评论。