Apple的LLVM中的优化错误还是代码错误?

时间:2019-04-09 05:36:47

标签: ios gcc llvm compiler-optimization

我有一些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]

1 个答案:

答案 0 :(得分:0)

在做了一个最小的测试用例之后,我能够确认那肯定是编译器错误。

条件:没有其他代码修改m_Size,初始化m_Size math::Vec2 m_Size{1.0, 1.0};。我可以在10.0之前找到的所有LLVM版本上完美运行,似乎在该版本上发生了某种回归。

已提交给Apple的LLVM团队和llvm.org。

感谢评论。