Commit 98ddb75
fix(simd.h): fix longstanding probem with 16-wide bitcast for 8-wide HW (AcademySoftwareFoundation#4268)
We've been plagued on and off for a long time with spurious wrong
results in our SIMD versions of exp and log. It was really squirrelly,
came and went with changes to seemingly unrelated code, and had long
periods of time with no symptoms or ability to reproduce it. It just
started popping up again in CI in the dev-2.5 branch, consistently.
Today I think I finally tracked it down for real. I believe the problem
was actually in the SIMD bitcast_to_int and bitcast_to_float functions,
for the variety that was 8-wide when running on 4-wide hardware, and the
16-wide one when running on 8-wide (or less) hardware.
Background: When real 16-wide HW is not available, we define the 16-wide
vectors as an array of two 8-wide vectors. (Same for 8 vs 4, I'll spare
you explaining it all twice.) So most of the 16 wide functions boil down
to:
vfloat16 op (vfloat16 arg, ...)
{
#if 16 wide HW is available
return real_16_wide_intrinsic(arg);
#else /* recursively define in terms of 8-wide halves */
return vfloat16(op(arg.lo()), op(arg.hi()));
#endif
}
But for the bitcast operators, we did something different, a shade too
clever: we just did a pointer cast, dereference and return:
vint16 bitcast_to_int (const vfloat16& x)
{
#if OIIO_SIMD_AVX >= 512
return _mm512_castps_si512 (x.simd());
#else
return *(vint16 *)&x;
#endif
}
I believe that the problem is that this cast is undefined behavior for
the case where the vector x was broken into two halves, and by being in
the middle of a long code sequence of SIMD ops, the two halves happened
to be in registers at that moment. Basically, we are taking the address,
and it just doesn't seem to always understand that it needs to
materialize the whole thing in memory for the pointer cast to work
properly.
I removed the pointer cast and replaced with
return vfloat16(bitcast_to_float(x.lo()), bitcast_to_float(x.hi()));
basically falling back on the usual recursive definition of 16-wide
operations to being in terms of 8-wide operations when 16-wide HW is not
available. This totally clears up the problem since we're no longer
potentially relying on needing the address of something that has no
address at that moment.
A couple other spots (andnot) also had dubious casts that I fixed in the
same way.
N.B.: The 16-wide cast from bool to int had to do something slightly
different, because it's represented differently and isn't a true
bitcast.
Signed-off-by: Larry Gritz <lg@larrygritz.com>
Signed-off-by: Scott Wilson <scott@propersquid.com>1 parent 6fa37f5 commit 98ddb75
2 files changed
+12
-12
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1852 | 1852 | | |
1853 | 1853 | | |
1854 | 1854 | | |
1855 | | - | |
| 1855 | + | |
1856 | 1856 | | |
1857 | 1857 | | |
1858 | 1858 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5686 | 5686 | | |
5687 | 5687 | | |
5688 | 5688 | | |
5689 | | - | |
| 5689 | + | |
5690 | 5690 | | |
5691 | 5691 | | |
5692 | 5692 | | |
| |||
7738 | 7738 | | |
7739 | 7739 | | |
7740 | 7740 | | |
7741 | | - | |
7742 | | - | |
7743 | | - | |
| 7741 | + | |
| 7742 | + | |
| 7743 | + | |
7744 | 7744 | | |
7745 | 7745 | | |
7746 | 7746 | | |
| |||
9157 | 9157 | | |
9158 | 9158 | | |
9159 | 9159 | | |
9160 | | - | |
| 9160 | + | |
9161 | 9161 | | |
9162 | 9162 | | |
9163 | 9163 | | |
| |||
9166 | 9166 | | |
9167 | 9167 | | |
9168 | 9168 | | |
9169 | | - | |
| 9169 | + | |
9170 | 9170 | | |
9171 | 9171 | | |
9172 | 9172 | | |
| |||
9395 | 9395 | | |
9396 | 9396 | | |
9397 | 9397 | | |
9398 | | - | |
9399 | | - | |
9400 | | - | |
| 9398 | + | |
| 9399 | + | |
| 9400 | + | |
9401 | 9401 | | |
9402 | 9402 | | |
9403 | 9403 | | |
| |||
10030 | 10030 | | |
10031 | 10031 | | |
10032 | 10032 | | |
10033 | | - | |
| 10033 | + | |
10034 | 10034 | | |
10035 | 10035 | | |
10036 | 10036 | | |
| |||
10039 | 10039 | | |
10040 | 10040 | | |
10041 | 10041 | | |
10042 | | - | |
| 10042 | + | |
10043 | 10043 | | |
10044 | 10044 | | |
10045 | 10045 | | |
| |||
0 commit comments