C++ 为什么可以';VS 2015编译器是否在浮点数的abs()实现中优化分支?

C++ 为什么可以';VS 2015编译器是否在浮点数的abs()实现中优化分支?,c++,assembly,optimization,C++,Assembly,Optimization,如您所见,它仍然包含分支和条件跳转。然而,float是由IEEE754定义的,因此我可以将实现更改为仅将符号位设置为0: ; 4 : return (x < 0) ? x * -1 : x; movss xmm1, DWORD PTR _x$[ebp] xorps xmm0, xmm0 comiss xmm0, xmm1 jbe SHORT $LN3@foo xorps xmm1, DWORD PTR __xmm@8000

如您所见,它仍然包含分支和条件跳转。然而,
float
是由IEEE754定义的,因此我可以将实现更改为仅将符号位设置为0:

; 4    :    return (x < 0) ? x * -1 : x;

    movss   xmm1, DWORD PTR _x$[ebp]
    xorps   xmm0, xmm0
    comiss  xmm0, xmm1
    jbe SHORT $LN3@foo
    xorps   xmm1, DWORD PTR __xmm@80000000800000008000000080000000
$LN3@foo:
    movss   DWORD PTR tv66[ebp], xmm1
    fld DWORD PTR tv66[ebp]
\u declspec(dllexport)
浮点数foo(浮点数x){
无效*条=&x;

__int32 y=(*(uu int32*)bar)&~(1,因为这将产生负零的错误结果

负零不小于零,因此其符号保持为负,使得条件分支的消除无效

考虑使用类似于

; 3    :        void* bar = &x;
; 4    :        __int32 y = ((*(__int32*)bar) & ~(1 << 31));

    mov eax, DWORD PTR _x$[ebp]
    and eax, 2147483647             ; 7fffffffH
    mov DWORD PTR _y$[ebp], eax

; 5    :        return  *(float*)&y;

    fld DWORD PTR _y$[ebp]

>

你用明显的角情况来测试它吗?NaN、INF、-INF、DENORMS、MAX、MIN、EPHIRON、证明和测试就是这样的。@ YAKK,你的意思是ε?我只知道对于机器精度,我不知道这会如何干扰我把符号位设置为0。考虑使用<代码> CopySuth函数。z我只是列出了一堆有点特殊的浮点值。有很多,有些是古怪的。测试它们并检查它们的ieee强制位模式似乎是这里的第一步。我不是浮点专家。呸,我从我的古怪浮点列表中漏掉了
-0
。糟糕的牦牛没有饼干。
__declspec(dllexport)
float foo(float x) {
    void* bar = &x;
    __int32 y = ((*(__int32*)bar) & ~(1 << 31));
    return  *(float*)&y;
}
; 3    :        void* bar = &x;
; 4    :        __int32 y = ((*(__int32*)bar) & ~(1 << 31));

    mov eax, DWORD PTR _x$[ebp]
    and eax, 2147483647             ; 7fffffffH
    mov DWORD PTR _y$[ebp], eax

; 5    :        return  *(float*)&y;

    fld DWORD PTR _y$[ebp]
copysign(x, 0.0);