Microsoft VS 2015编译器错误?

时间:2016-11-09 10:32:54

标签: c++ assembly visual-studio-2015

我有以下功能:

void MainLayer::onMouseScroll(cocos2d::EventMouse* event)
{
    const float scrollAmount = event->getScrollY();
    const float newMapScale = scrollAmount < 0.f ? std::min(_mapScale * k_deltaMapScaleMag, k_maxMapScale) : std::max(_mapScale * k_deltaMapScaleMin, k_minMapScale);
    const float invNewMapScale = 1.f / newMapScale;

    const Vec2 anchorScreenSpace = event->getLocationInView();
    _mapScale = newMapScale;
    _invMapScale = invNewMapScale;

    updateMapTransform();
}

Microsoft VS 2015编译器生成以下程序集:

    push    ebp
    mov ebp, esp
    push    -1
    push    __ehhandler$?onMouseScroll@MainLayer@@AAEXPAVEventMouse@cocos2d@@@Z
    mov eax, DWORD PTR fs:0
    push    eax
    sub esp, 20                 ; 00000014H
    mov eax, DWORD PTR ___security_cookie
    xor eax, ebp
    mov DWORD PTR __$ArrayPad$[ebp], eax
    push    esi
    push    eax
    lea eax, DWORD PTR __$EHRec$[ebp]
    mov DWORD PTR fs:0, eax
    mov esi, ecx
    mov ecx, DWORD PTR _event$[ebp]
; File c:\program files (x86)\microsoft visual studio 14.0\vc\include\algorithm

; 3649 :    return (_DEBUG_LT(_Right, _Left) ? _Right : _Left);

    lea edx, DWORD PTR $T1[ebp]
; File e:\projects\aliceandbob\classes\mainlayer.cpp

; 121  :    const float newMapScale = scrollAmount < 0.f ? std::min(_mapScale * k_deltaMapScaleMag, k_maxMapScale) : std::max(_mapScale * k_deltaMapScaleMin, k_minMapScale);

    movss   xmm1, DWORD PTR __real@3f800000
    xorps   xmm0, xmm0
    comiss  xmm0, DWORD PTR [ecx+56]
    movss   xmm0, DWORD PTR [esi+712]
    jbe SHORT $LN3@onMouseScr
    mulss   xmm0, DWORD PTR __real@3f99999a
; File c:\program files (x86)\microsoft visual studio 14.0\vc\include\algorithm

; 3649 :    return (_DEBUG_LT(_Right, _Left) ? _Right : _Left);

    mov eax, OFFSET ?k_maxMapScale@?A0x69cbde3b@@3MB
    comiss  xmm0, DWORD PTR __real@41200000
; File e:\projects\aliceandbob\classes\mainlayer.cpp

; 121  :    const float newMapScale = scrollAmount < 0.f ? std::min(_mapScale * k_deltaMapScaleMag, k_maxMapScale) : std::max(_mapScale * k_deltaMapScaleMin, k_minMapScale);

    jmp SHORT $LN18@onMouseScr
$LN3@onMouseScr:
    mulss   xmm0, DWORD PTR __real@3f4ccccd
; File c:\program files (x86)\microsoft visual studio 14.0\vc\include\algorithm

; 3612 :    return (_DEBUG_LT(_Left, _Right) ? _Right : _Left);

    mov eax, OFFSET ?k_minMapScale@?A0x69cbde3b@@3MB
    comiss  xmm1, xmm0
$LN18@onMouseScr:
    cmovbe  eax, edx
    movss   xmm0, DWORD PTR [eax]
; File e:\projects\aliceandbob\classes\mainlayer.cpp

; 124  :    const Vec2 anchorScreenSpace = event->getLocationInView();

    lea eax, DWORD PTR _anchorScreenSpace$[ebp]
    divss   xmm1, xmm0
    push    eax
    movss   DWORD PTR tv161[ebp], xmm0
    movss   DWORD PTR _invNewMapScale$1$[ebp], xmm1
    call    DWORD PTR __imp_?getLocationInView@EventMouse@cocos2d@@QBE?AVVec2@2@XZ

; 125  :    _mapScale = newMapScale;

    movss   xmm0, DWORD PTR tv161[ebp]

; 126  :    _invMapScale = invNewMapScale;
; 127  : 
; 128  :    updateMapTransform();

    mov ecx, esi
    mov DWORD PTR __$EHRec$[ebp+8], 0
    movss   DWORD PTR [esi+712], xmm0
    movss   xmm0, DWORD PTR _invNewMapScale$1$[ebp]
    movss   DWORD PTR [esi+716], xmm0
    call    ?updateMapTransform@MainLayer@@AAEXXZ   ; MainLayer::updateMapTransform

; 129  : }

    mov ecx, DWORD PTR __$EHRec$[ebp]
    mov DWORD PTR fs:0, ecx
    pop ecx
    pop esi
    mov ecx, DWORD PTR __$ArrayPad$[ebp]
    xor ecx, ebp
    call    @__security_check_cookie@4
    mov esp, ebp
    pop ebp
    ret 4

问题是编译器生成的代码不会将表达式的结果存储到newMapScale变量中。如您所见,它也不会在此处插入minss和maxss指令(对于std :: max()和std :: min())。如果我拒绝计算机使用SSE指令 - 它按预期工作。我试图在测试项目上重现这个问题并且失败了 - 几乎完全相同的代码有minss和maxss指令,并将表达式的结果存储到newMapScale变量中。我是否有某种未定义的行为,或者它只是一个编译器错误?

我使用VS 2015 Update 3,VS 2015 - Windows XP(v140_xp)SDK。

UPD:我只留下了有助于重现问题的源代码。从该代码中删除任何行修复了编译器行为。请注意以下几行:

    movss   xmm1, DWORD PTR __real@3f800000
    xorps   xmm0, xmm0
    comiss  xmm0, DWORD PTR [ecx+56]
    movss   xmm0, DWORD PTR [esi+712]
    jbe SHORT $LN3@onMouseScr
    mulss   xmm0, DWORD PTR __real@3f99999a
; File c:\program files (x86)\microsoft visual studio 14.0\vc\include\algorithm

; 3649 :    return (_DEBUG_LT(_Right, _Left) ? _Right : _Left);

    mov eax, OFFSET ?k_maxMapScale@?A0x69cbde3b@@3MB
    comiss  xmm0, DWORD PTR __real@41200000
; File e:\projects\aliceandbob\classes\mainlayer.cpp

; 121  :    const float newMapScale = scrollAmount < 0.f ? std::min(_mapScale * k_deltaMapScaleMag, k_maxMapScale) : std::max(_mapScale * k_deltaMapScaleMin, k_minMapScale);

    jmp SHORT $LN18@onMouseScr
$LN3@onMouseScr:
    mulss   xmm0, DWORD PTR __real@3f4ccccd
; File c:\program files (x86)\microsoft visual studio 14.0\vc\include\algorithm

; 3612 :    return (_DEBUG_LT(_Left, _Right) ? _Right : _Left);

    mov eax, OFFSET ?k_minMapScale@?A0x69cbde3b@@3MB
    comiss  xmm1, xmm0
$LN18@onMouseScr:
    cmovbe  eax, edx
    movss   xmm0, DWORD PTR [eax]
; File e:\projects\aliceandbob\classes\mainlayer.cpp

; 124  :    const Vec2 anchorScreenSpace = event->getLocationInView();

    lea eax, DWORD PTR _anchorScreenSpace$[ebp]
    divss   xmm1, xmm0
    push    eax

正如Andrey Turkin所说,xmm0虽然包含计算结果但会被丢弃。将单位化内存加载到xmm0中。

0 个答案:

没有答案