Skip to content

Commit 70cb4bd

Browse files
committed
See if a more explicit r4_equality implementation fixes the issues
1 parent 0489876 commit 70cb4bd

File tree

1 file changed

+75
-23
lines changed

1 file changed

+75
-23
lines changed

src/mono/mono/mini/interp/interp-simd.c

Lines changed: 75 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
#include <wasm_simd128.h>
77
#endif
88

9+
#include <mono/utils/mono-math.h>
10+
911
#ifdef INTERP_ENABLE_SIMD
1012

1113
gboolean interp_simd_enabled = TRUE;
@@ -175,13 +177,18 @@ interp_v128_op_bitwise_or (gpointer res, gpointer v1, gpointer v2)
175177
static void
176178
interp_v128_op_bitwise_equality (gpointer res, gpointer v1, gpointer v2)
177179
{
178-
gint64 *v1_cast = (gint64*)v1;
179-
gint64 *v2_cast = (gint64*)v2;
180+
gint64 *v1_typed = (gint64*)v1;
181+
gint64 *v2_typed = (gint64*)v2;
182+
183+
bool succeeded = true;
180184

181-
if (*v1_cast == *v2_cast && *(v1_cast + 1) == *(v2_cast + 1))
182-
*(gint32*)res = 1;
183-
else
184-
*(gint32*)res = 0;
185+
if (v1_typed [0] != v2_typed [0]) {
186+
succeeded = false;
187+
} else if (v1_typed [1] != v2_typed [1]) {
188+
succeeded = false;
189+
}
190+
191+
*(gint32*)res = succeeded ? 1 : 0;
185192
}
186193

187194
// op_ExclusiveOr
@@ -195,36 +202,81 @@ interp_v128_op_exclusive_or (gpointer res, gpointer v1, gpointer v2)
195202
static void
196203
interp_v128_op_bitwise_inequality (gpointer res, gpointer v1, gpointer v2)
197204
{
198-
gint64 *v1_cast = (gint64*)v1;
199-
gint64 *v2_cast = (gint64*)v2;
205+
gint64 *v1_typed = (gint64*)v1;
206+
gint64 *v2_typed = (gint64*)v2;
207+
208+
bool succeeded = false;
209+
210+
if (v1_typed [0] != v2_typed [0]) {
211+
succeeded = true;
212+
} else if (v1_typed [1] != v2_typed [1]) {
213+
succeeded = true;
214+
}
215+
216+
*(gint32*)res = succeeded ? 1 : 0;
217+
}
218+
219+
static bool
220+
r4_float_equality(float v1, float v2)
221+
{
222+
if (v1 == v2) {
223+
return true;
224+
} else if (mono_isnan (v1) && mono_isnan (v2)) {
225+
return true;
226+
}
200227

201-
if (*v1_cast == *v2_cast && *(v1_cast + 1) == *(v2_cast + 1))
202-
*(gint32*)res = 0;
203-
else
204-
*(gint32*)res = 1;
228+
return false;
205229
}
206230

207-
// Vector128<float>EqualsFloatingPoint
231+
// Vector128<float>.EqualsFloatingPoint
208232
static void
209233
interp_v128_r4_float_equality (gpointer res, gpointer v1, gpointer v2)
210234
{
211-
v128_r4 v1_cast = *(v128_r4*)v1;
212-
v128_r4 v2_cast = *(v128_r4*)v2;
213-
v128_r4 result = (v1_cast == v2_cast) | ~((v1_cast == v1_cast) | (v2_cast == v2_cast));
214-
memset (&v1_cast, 0xff, SIZEOF_V128);
235+
float *v1_typed = (float*)v1;
236+
float *v2_typed = (float*)v2;
237+
238+
bool succeeded = true;
239+
240+
if (!r4_float_equality(v1_typed [0], v2_typed [0])) {
241+
succeeded = false;
242+
} else if (!r4_float_equality(v1_typed [1], v2_typed [1])) {
243+
succeeded = false;
244+
} else if (!r4_float_equality(v1_typed [2], v2_typed [2])) {
245+
succeeded = false;
246+
} else if (!r4_float_equality(v1_typed [3], v2_typed [3])) {
247+
succeeded = false;
248+
}
249+
250+
*(gint32*)res = succeeded ? 1 : 0;
251+
}
252+
253+
static bool
254+
r8_float_equality(double v1, double v2)
255+
{
256+
if (v1 == v2) {
257+
return true;
258+
} else if (mono_isnan (v1) && mono_isnan (v2)) {
259+
return true;
260+
}
215261

216-
*(gint32*)res = memcmp (&v1_cast, &result, SIZEOF_V128) == 0;
262+
return false;
217263
}
218264

219265
static void
220266
interp_v128_r8_float_equality (gpointer res, gpointer v1, gpointer v2)
221267
{
222-
v128_r8 v1_cast = *(v128_r8*)v1;
223-
v128_r8 v2_cast = *(v128_r8*)v2;
224-
v128_r8 result = (v1_cast == v2_cast) | ~((v1_cast == v1_cast) | (v2_cast == v2_cast));
225-
memset (&v1_cast, 0xff, SIZEOF_V128);
268+
double *v1_typed = (double*)v1;
269+
double *v2_typed = (double*)v2;
270+
271+
bool succeeded = true;
272+
273+
if (!r8_float_equality(v1_typed [0], v2_typed [0])) {
274+
succeeded = false;
275+
} else if (!r8_float_equality(v1_typed [1], v2_typed [1])) {
276+
succeeded = false;
277+
}
226278

227-
*(gint32*)res = memcmp (&v1_cast, &result, SIZEOF_V128) == 0;
279+
*(gint32*)res = succeeded ? 1 : 0;
228280
}
229281

230282
// op_Multiply

0 commit comments

Comments
 (0)