Skip to content

Commit e57726c

Browse files
authored
Fix rounding in SSE conversion functions (#25130)
Value 3.6 was not that interesting float, replaced it with the more interesting 1022.99998194495 from #25129. Fixes: #25129
1 parent 406c368 commit e57726c

File tree

3 files changed

+38
-25
lines changed

3 files changed

+38
-25
lines changed

system/include/compat/emmintrin.h

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@ _mm_cvtpd_epi32(__m128d __a)
385385
{
386386
double e = __a[i];
387387
int x = lrint(e);
388-
if ((x != 0 || fabs(e) < 2.0) && !isnan(e) && e <= INT_MAX && e >= INT_MIN)
388+
if (e <= INT_MAX && e >= INT_MIN && (x != 0 || fabs(e) < 2.0))
389389
m[i] = x;
390390
else
391391
m[i] = (int)0x80000000;
@@ -399,7 +399,7 @@ _mm_cvtsd_si32(__m128d __a)
399399
// TODO: OPTIMIZE!
400400
double e = __a[0];
401401
int x = lrint(e);
402-
if ((x != 0 || fabs(e) < 2.0) && !isnan(e) && e <= INT_MAX && e >= INT_MIN)
402+
if (e <= INT_MAX && e >= INT_MIN && (x != 0 || fabs(e) < 2.0))
403403
return x;
404404
else
405405
return (int)0x80000000;
@@ -433,11 +433,11 @@ _mm_cvttpd_epi32(__m128d __a)
433433
int m[2];
434434
for(int i = 0; i < 2; ++i)
435435
{
436-
float elem = __a[i];
437-
if ((lrint(elem) != 0 || fabs(elem) < 2.0) && !isnanf(elem) && elem <= INT_MAX && elem >= INT_MIN)
436+
double elem = __a[i];
437+
if (elem < 2147483648.0 && elem >= -2147483648.0 && (lrint(elem) != 0 || fabs(elem) < 2.0))
438438
// Use the trapping instruction here since we have explicit bounds checks
439439
// above.
440-
m[i] = __builtin_wasm_trunc_s_i32_f32(elem);
440+
m[i] = __builtin_wasm_trunc_s_i32_f64(elem);
441441
else
442442
m[i] = (int)0x80000000;
443443
}
@@ -448,11 +448,11 @@ static __inline__ int __attribute__((__always_inline__, __nodebug__))
448448
_mm_cvttsd_si32(__m128d __a)
449449
{
450450
// TODO: OPTIMIZE!
451-
float elem = __a[0];
452-
if ((lrint(elem) != 0 || fabs(elem) < 2.0) && !isnanf(elem) && elem <= INT_MAX && elem >= INT_MIN)
451+
double elem = __a[0];
452+
if (elem < 2147483648.0 && elem >= -2147483648.0 && (lrint(elem) != 0 || fabs(elem) < 2.0))
453453
// Use the trapping instruction here since we have explicit bounds checks
454454
// above.
455-
return __builtin_wasm_trunc_s_i32_f32(elem);
455+
return __builtin_wasm_trunc_s_i32_f64(elem);
456456
else
457457
return (int)0x80000000;
458458
}
@@ -1010,7 +1010,7 @@ _mm_cvtsd_si64(__m128d __a)
10101010
double e = __a[0];
10111011
if (isnan(e) || isinf(e)) return 0x8000000000000000LL;
10121012
long long x = llrint(e);
1013-
if (x != 0xFFFFFFFF00000000ULL && (x != 0 || fabs(e) < 2.f) && e <= LLONG_MAX && e >= LLONG_MIN)
1013+
if (e <= LLONG_MAX && e >= LLONG_MIN && (x != 0 || fabs(e) < 2.f))
10141014
return x;
10151015
else
10161016
return 0x8000000000000000LL;
@@ -1023,10 +1023,10 @@ _mm_cvttsd_si64(__m128d __a)
10231023
double e = __a[0];
10241024
if (isnan(e) || isinf(e) || e > LLONG_MAX || e < LLONG_MIN) return 0x8000000000000000LL;
10251025
long long x = llrint(e);
1026-
if (x != 0xFFFFFFFF00000000ULL && (x != 0 || fabs(e) < 2.f))
1026+
if (x != 0 || fabs(e) < 2.f)
10271027
// Use the trapping instruction here since we have explicit bounds checks
10281028
// above
1029-
return __builtin_wasm_trunc_s_i64_f32(e);
1029+
return __builtin_wasm_trunc_s_i64_f64(e);
10301030
else
10311031
return 0x8000000000000000LL;
10321032
}
@@ -1049,7 +1049,7 @@ _mm_cvtps_epi32(__m128 __a)
10491049
{
10501050
double e = __a[i];
10511051
int x = lrint(e);
1052-
if ((x != 0 || fabs(e) < 2.0) && !isnan(e) && e <= INT_MAX && e >= INT_MIN)
1052+
if (e <= INT_MAX && e >= INT_MIN && (x != 0 || fabs(e) < 2.0))
10531053
u.x[i] = x;
10541054
else
10551055
u.x[i] = (int)0x80000000;
@@ -1068,8 +1068,7 @@ _mm_cvttps_epi32(__m128 __a)
10681068
for(int i = 0; i < 4; ++i)
10691069
{
10701070
float e = __a[i];
1071-
int x = lrint(e);
1072-
if ((x != 0 || fabs(e) < 2.0) && !isnanf(e) && e <= INT_MAX && e >= INT_MIN)
1071+
if (e < 2147483648.0f && e >= -2147483648.0f && (lrint(e) != 0 || fabs(e) < 2.0))
10731072
// Use the trapping instruction here since we have explicit bounds checks
10741073
// above.
10751074
u.x[i] = __builtin_wasm_trunc_s_i32_f32(e);

system/include/compat/xmmintrin.h

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -597,9 +597,8 @@ _mm_cvtsi32_ss(__m128 __a, int __b)
597597
static __inline__ int __attribute__((__always_inline__, __nodebug__, DIAGNOSE_SLOW)) _mm_cvtss_si32(__m128 __a)
598598
{
599599
float e = ((__f32x4)__a)[0];
600-
int x = lrint(e);
601-
if ((x != 0 || fabsf(e)) < 2.f && !isnan(e) && e <= INT_MAX && e >= INT_MIN)
602-
return x;
600+
if (e < 2147483648.0f && e >= -2147483648.0f && (lrint(e) != 0 || fabsf(e) < 2.f))
601+
return lrint(e);
603602
else
604603
return (int)0x80000000;
605604
}
@@ -608,8 +607,7 @@ static __inline__ int __attribute__((__always_inline__, __nodebug__, DIAGNOSE_SL
608607
static __inline__ int __attribute__((__always_inline__, __nodebug__, DIAGNOSE_SLOW)) _mm_cvttss_si32(__m128 __a)
609608
{
610609
float e = ((__f32x4)__a)[0];
611-
int x = lrint(e);
612-
if ((x != 0 || fabsf(e) < 2.f) && !isnanf(e) && e <= INT_MAX && e >= INT_MIN)
610+
if (e < 2147483648.0f && e >= -2147483648.0f && (lrint(e) != 0 || fabsf(e) < 2.f))
613611
return (int)e;
614612
else
615613
return (int)0x80000000;
@@ -629,7 +627,7 @@ _mm_cvtss_si64(__m128 __a)
629627
{
630628
float e = ((__f32x4)__a)[0];
631629
long long x = llrintf(e);
632-
if ((x != 0xFFFFFFFF00000000ULL && (x != 0 || fabsf(e) < 2.f)) && !isnanf(e) && e <= LLONG_MAX && e >= LLONG_MIN)
630+
if (e <= LLONG_MAX && e >= LLONG_MIN && (x != 0 || fabsf(e) < 2.f))
633631
return x;
634632
else
635633
return 0x8000000000000000LL;
@@ -640,7 +638,7 @@ _mm_cvttss_si64(__m128 __a)
640638
{
641639
float e = ((__f32x4)__a)[0];
642640
long long x = llrintf(e);
643-
if (x != 0xFFFFFFFF00000000ULL && (x != 0 || fabsf(e) < 2.f) && !isnanf(e) && e <= LLONG_MAX && e >= LLONG_MIN)
641+
if (e <= LLONG_MAX && e >= LLONG_MIN && (x != 0 || fabsf(e) < 2.f))
644642
return (long long)e;
645643
else
646644
return 0x8000000000000000LL;

test/sse/test_sse.h

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ __attribute__((aligned(32)))
4848
float interesting_floats_[] = {
4949
-INFINITY,
5050
-FLT_MAX,
51+
-4294967296.0f, // https://github.com/emscripten-core/emscripten/pull/25130
52+
-2147483648.1f,
53+
-2147483648.0f,
54+
-2147483647.9f,
5155
-2.5f,
5256
-1.5f,
5357
-1.4f,
@@ -63,10 +67,14 @@ float interesting_floats_[] = {
6367
0.5f,
6468
0.8f,
6569
1.0f,
66-
1.5f,
70+
1.5f, // Test different half-way values to see if banker's rounding happens.
6771
2.5f,
6872
3.5f,
69-
3.6f,
73+
1022.99998194495f, // https://github.com/emscripten-core/emscripten/issues/25129
74+
2147483647.9f, // https://github.com/emscripten-core/emscripten/pull/25130
75+
2147483648.0f,
76+
2147483648.1f,
77+
4294967296.0f,
7078
FLT_MAX,
7179
INFINITY,
7280
NAN,
@@ -83,6 +91,10 @@ __attribute__((aligned(32)))
8391
double interesting_doubles_[] = {
8492
-INFINITY,
8593
-FLT_MAX,
94+
-4294967296.0, // https://github.com/emscripten-core/emscripten/pull/25130
95+
-2147483648.1,
96+
-2147483648.0,
97+
-2147483647.9,
8698
-2.5,
8799
-1.5,
88100
-1.4,
@@ -98,10 +110,14 @@ double interesting_doubles_[] = {
98110
0.5,
99111
0.8,
100112
1.0,
101-
1.5,
113+
1.5, // Test different half-way values to see if banker's rounding happens.
102114
2.5,
103115
3.5,
104-
3.6,
116+
1022.99998194495, // https://github.com/emscripten-core/emscripten/issues/25129
117+
2147483647.9,
118+
2147483648.0, // https://github.com/emscripten-core/emscripten/pull/25130
119+
2147483648.1,
120+
4294967296.0,
105121
FLT_MAX,
106122
INFINITY,
107123
NAN,

0 commit comments

Comments
 (0)