Bra*_*ram 6 floating-point simd clang floating-point-exceptions sigfpe
我喜欢在启用浮点异常的情况下运行我的代码。我在 Linux 下使用:
feenableexcept( FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW );
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好。
我遇到的问题是,有时编译器(我使用 clang8)决定使用 SIMD 指令进行标量除法。好吧,如果这更快,即使对于单个标量,为什么不呢。
但结果是 SIMD 寄存器中未使用的通道可能包含零。
并且在执行 SIMD 除法时,会抛出浮点异常。
这是否意味着如果允许编译器使用 sse/avx 扩展,则根本无法使用浮点异常?
就我而言,这行 C 代码:
float a0, min, a, d;
...
a0 = (min - a) / (d);
Run Code Online (Sandbox Code Playgroud)
...被执行为:
divps %xmm2,%xmm3
Run Code Online (Sandbox Code Playgroud)
然后抛出一个:
Thread 1 "noisetuner" received signal SIGFPE, Arithmetic exception.
Run Code Online (Sandbox Code Playgroud)
我认为您在 clang 或 llvm 中发现了错误。
\nHere\xe2\x80\x99s 我如何重现,clang 10.0 发出相同的代码,即也有该错误。显然,该vdivps指令仅在向量的最初 2 个通道中具有有效数据,而在较高的 2 个通道中它将运行 0.0 / 0.0,因此,如果您在mxcsr指令仅在向量的最初 2 个通道中具有有效数据,而在较高的 2 个通道中它将运行 0.0 / 0.0,因此,如果您在寄存器你\xe2\x80\x99正在做。
Microsoft、Intel 和 gcc don\xe2\x80\x99t 不会发出divps该代码。如果可以的话,换成gcc应该就不错了。
更新: Clang 10+ 有一个控制此类优化的选项,-ffp-exception-behavior=maytrap请查看: https: //godbolt.org/z/WG7bEE