Description
Hello.
A function like below may return an unexpected __m128
value when compiled using clang 19.1.0 with -ffast-math -O2
.
auto maskFunc = []() {
return _mm_castsi128_ps(_mm_set_epi32( 0x7FFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF ));
};
Sample code at Compiler Explorer https://godbolt.org/z/xG5r1n7xY , demonstrating different result from lambda return and immediate assignment.
Workaround:
- Remove
-ffast-math
or-O2
- Add
-fno-finite-math-only
- Use clang 18
I can speculate that this is because the i32 values set in the sample function are NaN when interpreted as float, and -ffast-math
optimizer discarded such return value as invalid. However, the __m128
value was intended for use in bitwise operation intrinsics like _mm_and_ps(), and not as a value in floating point calculation.
This was permitted in clang 18, but no longer as of clang 19.1.0. Was this behavior change intended?
If so, is guaranteeing assignment and returning of an arbitrary __m128
value, which may contain NaN or INFINITY, no longer possible with -ffast-math
enabled for clang 19 onward? In addition to bitwise intrinsics, comparison intrinsics like _mm_cmpgt_ps() will use 0xFFFFFFFF
as truth values, so handling non-finite value are necessary for multiple intrinsics by definition.
Or, is it simply not recommended to use these intrinsics with -ffast-math
, or more specifically -ffinite-math-only
? Using -ffast-math -fno-finite-math-only
combo is a valid workaround, but will affect the entire compilation, potentially preventing other uninvolved code from taking benefit of finite-math-only-optimization.
Regards,