Ошибка оптимизации в Apple LLVM или ошибка в коде? - PullRequest
1 голос
/ 09 апреля 2019

У меня есть некоторый код 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

Редактировать 2: Правильносборка для заданий, сгенерированная на моей машине (хотя другая арка, сейчас не может получить ту же арку, что и выше)

    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 голосов
/ 10 апреля 2019

После выполнения минимального теста я смог подтвердить, что это определенно ошибка компилятора.

Условия: никакая другая часть кода не изменяет m_Size, m_Size инициализируется math::Vec2 m_Size{1.0, 1.0};. Он отлично работает на каждой версии LLVM, которую я мог найти до 10.0, похоже, в этой версии произошла какая-то регрессия.

Отправлено в команду Apple LLVM и llvm.org.

Спасибо за комментарии.

...