问题描述
示例代码 (t2.c):
#include <fenv.h>
#include <stdio.h>
#include <math.h>
#if _MSC_VER && ! __clang__ /*&& ! __INTEL_COMPILER*/
#pragma fenv_access (on)
#else
#pragma STDC FENV_ACCESS ON
#endif
int main(void)
{
volatile _Bool b;
volatile float f = NAN; // quiet NaN per C11
feclearexcept(FE_ALL_EXCEPT);
// b = f == f; // leads to ucomiss (signals Invalid if operand is SNaN)
b = f <= f; // leads to comiss (signals Invalid if operand is QNaN or SNaN)
if (fetestexcept(FE_INVALID))
{
printf("FE_INVALID\n");
}
return b ? 1 : 0;
}
clang t2.c -std=c11 -ffp-model=strict -S
:
callq feclearexcept
movss 44(%rsp),%xmm1 # xmm1 = mem[0],zero,zero
movss 44(%rsp),%xmm0 # xmm0 = mem[0],zero
comiss %xmm1,%xmm0
setae %al
andb $1,%al
movb %al,51(%rsp)
movl $16,%ecx
callq fetestexcept
gcc t2.c -std=c11 -S
:
call feclearexcept
movss -8(%rbp),%xmm1
movss -8(%rbp),%xmm0
comiss %xmm1,%xmm0
setnb %al
movb %al,-1(%rbp)
movl $1,%ecx
call fetestexcept
cl t2.c /std:c11 /fp:strict /Za /Fa
:
call feclearexcept
; Line 18
movss xmm0,DWORD PTR f$[rsp]
movss xmm1,DWORD PTR f$[rsp]
comiss xmm1,xmm0
jb SHORT $LN4@main
mov DWORD PTR tv76[rsp],1
jmp SHORT $LN5@main
$LN4@main:
mov DWORD PTR tv76[rsp],0
$LN5@main:
cmp DWORD PTR tv76[rsp],0
jne SHORT $LN6@main
mov DWORD PTR tv78[rsp],0
jmp SHORT $LN7@main
$LN6@main:
mov DWORD PTR tv78[rsp],1
$LN7@main:
movzx eax,BYTE PTR tv78[rsp]
mov BYTE PTR b$[rsp],al
; Line 19
mov ecx,16
call fetestexcept
注意:这里有 clang 和 gcc:
- 正在使实现符合版本
201112
或不符合实现但__STDC__
具有1
的定义 - 符合附件 F 中的规范(
__STDC_IEC_559__
具有1
的定义)
注意:comiss
和 ucomiss
的说明:
-
comiss
- https://www.felixcloutier.com/x86/comiss -
ucomiss
- https://www.felixcloutier.com/x86/ucomiss
IEEE 754-2008,5.11,p4(强调):
明确考虑quiet NaN 操作数可能性的程序可以使用 表 5.3 中的无序安静谓词,不会发出这种无效操作异常的信号。
这里我们看到无序安静谓词LT EQ
(<=
是C)在表5.3中,因此QNAN <= QNAN
不会导致无效操作异常。我错过了什么吗?为什么 QNAN <= QNAN
编译器生成 comiss
而不是 ucomiss
?
工具版本:
$ gcc --version
gcc (Ubuntu 10.2.0-5ubuntu1~20.04) 10.2.0
$ clang --version
Ubuntu clang version 11.0.0-2~ubuntu20.04.1
$ cl
Microsoft (R) C/C++ Optimizing Compiler Version 19.28.29913 for x64
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)