@@ -55,7 +55,8 @@ quad_to_quad_resolve_descriptors(PyObject *NPY_UNUSED(self),
5555 // Different backends require actual conversion, no view possible
5656 *view_offset = NPY_MIN_INTP ;
5757 if (given_descrs[0 ]->backend == BACKEND_SLEEF ) {
58- return NPY_SAME_KIND_CASTING ; // SLEEF -> long double may lose precision
58+ // SLEEF -> long double may lose precision
59+ return static_cast <NPY_CASTING >(NPY_SAME_KIND_CASTING | NPY_SAME_VALUE_CASTING_FLAG );
5960 }
6061 // long double -> SLEEF preserves value exactly
6162 return static_cast <NPY_CASTING >(NPY_SAFE_CASTING | NPY_SAME_VALUE_CASTING_FLAG );
@@ -81,42 +82,47 @@ quad_to_quad_strided_loop(PyArrayMethod_Context *context, char *const data[],
8182 QuadPrecDTypeObject *descr_out = (QuadPrecDTypeObject *)context->descriptors [1 ];
8283 QuadBackendType backend_in = descr_in->backend ;
8384 QuadBackendType backend_out = descr_out->backend ;
85+ int same_value_casting = ((context->flags & NPY_SAME_VALUE_CONTEXT_FLAG ) == NPY_SAME_VALUE_CONTEXT_FLAG );
8486
8587 // inter-backend casting
8688 if (backend_in != backend_out) {
8789 while (N--) {
88- quad_value in_val = load_quad<Aligned>(in_ptr, backend_in);
90+ quad_value in_val;
91+ load_quad<Aligned>(in_ptr, backend_in, &in_val);
92+ quad_value out_val;
8993 if (backend_in == BACKEND_SLEEF )
9094 {
91- long double res = Sleef_cast_to_doubleq1 (in_val.sleef_value );
92- store<Aligned>(out_ptr, res);
95+ out_val.longdouble_value = static_cast <long double >(Sleef_cast_to_doubleq1 (in_val.sleef_value ));
9396 }
9497 else
9598 {
96- Sleef_quad res;
9799 long double ld = in_val.longdouble_value ;
98100 if (std::isnan (ld)) {
99- res = QUAD_PRECISION_NAN ;
101+ out_val. sleef_value = QUAD_PRECISION_NAN ;
100102 }
101103 else if (std::isinf (ld)) {
102- res = (ld > 0 ) ? QUAD_PRECISION_INF : QUAD_PRECISION_NINF ;
104+ out_val. sleef_value = (ld > 0 ) ? QUAD_PRECISION_INF : QUAD_PRECISION_NINF ;
103105 }
104106 else
105107 {
106- res = Sleef_cast_from_doubleq1 (static_cast <double >(ld));
108+ // to prevent compiler optimizations, ABI handling issues with __float128 on x86-64 machines
109+ // won't be expensive as for fixed size compiler can optimize memcpy with movq
110+ Sleef_quad temp = Sleef_cast_from_doubleq1 (static_cast <double >(ld));
111+ std::memcpy (&out_val.sleef_value , &temp, sizeof (Sleef_quad));
107112 }
108- store<Aligned>(out_ptr, res);
109113 }
114+ store_quad<Aligned>(out_ptr, &out_val, backend_out);
110115 in_ptr += in_stride;
111116 out_ptr += out_stride;
112117 }
113118 return 0 ;
114119 }
115120
116121 // same backend: direct copy
117- while (N--) {
118- quad_value val = load_quad<Aligned>(in_ptr, backend_in);
119- store_quad<Aligned>(out_ptr, val, backend_out);
122+ while (N--) {
123+ quad_value val;
124+ load_quad<Aligned>(in_ptr, backend_in, &val);
125+ store_quad<Aligned>(out_ptr, &val, backend_out);
120126 in_ptr += in_stride;
121127 out_ptr += out_stride;
122128 }
@@ -242,7 +248,7 @@ unicode_to_quad_strided_loop(PyArrayMethod_Context *context, char *const data[],
242248 return -1 ;
243249 }
244250
245- store_quad<Aligned>(out_ptr, out_val, backend);
251+ store_quad<Aligned>(out_ptr, & out_val, backend);
246252
247253 in_ptr += in_stride;
248254 out_ptr += out_stride;
@@ -464,7 +470,8 @@ quad_to_unicode_loop(PyArrayMethod_Context *context, char *const data[],
464470 int same_value_casting = ((context->flags & NPY_SAME_VALUE_CONTEXT_FLAG ) == NPY_SAME_VALUE_CONTEXT_FLAG );
465471
466472 while (N--) {
467- quad_value in_val = load_quad<Aligned>(in_ptr, backend);
473+ quad_value in_val;
474+ load_quad<Aligned>(in_ptr, backend, &in_val);
468475
469476 // Convert to Sleef_quad for Dragon4
470477 Sleef_quad sleef_val = quad_to_sleef_quad (&in_val, backend);
@@ -595,7 +602,7 @@ bytes_to_quad_strided_loop(PyArrayMethod_Context *context, char *const data[],
595602 return -1 ;
596603 }
597604
598- store_quad<Aligned>(out_ptr, out_val, backend);
605+ store_quad<Aligned>(out_ptr, & out_val, backend);
599606
600607 in_ptr += in_stride;
601608 out_ptr += out_stride;
@@ -657,7 +664,8 @@ quad_to_bytes_loop(PyArrayMethod_Context *context, char *const data[],
657664 int same_value_casting = ((context->flags & NPY_SAME_VALUE_CONTEXT_FLAG ) == NPY_SAME_VALUE_CONTEXT_FLAG );
658665
659666 while (N--) {
660- quad_value in_val = load_quad<Aligned>(in_ptr, backend);
667+ quad_value in_val;
668+ load_quad<Aligned>(in_ptr, backend, &in_val);
661669 Sleef_quad sleef_val = quad_to_sleef_quad (&in_val, backend);
662670
663671 const char *temp_str = quad_to_string_adaptive_cstr (&sleef_val, bytes_size);
@@ -756,7 +764,7 @@ stringdtype_to_quad_strided_loop(PyArrayMethod_Context *context, char *const dat
756764 return -1 ;
757765 }
758766
759- store_quad<Aligned>(out_ptr, out_val, backend);
767+ store_quad<Aligned>(out_ptr, & out_val, backend);
760768
761769 in_ptr += in_stride;
762770 out_ptr += out_stride;
@@ -814,7 +822,8 @@ quad_to_stringdtype_strided_loop(PyArrayMethod_Context *context, char *const dat
814822 npy_string_allocator *allocator = NpyString_acquire_allocator (str_descr);
815823
816824 while (N--) {
817- quad_value in_val = load_quad<Aligned>(in_ptr, backend);
825+ quad_value in_val;
826+ load_quad<Aligned>(in_ptr, backend, &in_val);
818827 Sleef_quad sleef_val = quad_to_sleef_quad (&in_val, backend);
819828
820829 // Get string representation with adaptive notation
@@ -1123,7 +1132,7 @@ numpy_to_quad_strided_loop(PyArrayMethod_Context *context, char *const data[],
11231132 while (N--) {
11241133 typename NpyType<T>::TYPE in_val = load<Aligned, typename NpyType<T>::TYPE >(in_ptr);
11251134 quad_value out_val = to_quad<T>(in_val, backend);
1126- store_quad<Aligned>(out_ptr, out_val, backend);
1135+ store_quad<Aligned>(out_ptr, & out_val, backend);
11271136
11281137 in_ptr += strides[0 ];
11291138 out_ptr += strides[1 ];
@@ -1408,7 +1417,8 @@ quad_to_numpy_strided_loop(PyArrayMethod_Context *context, char *const data[],
14081417
14091418 if (same_value_casting) {
14101419 while (N--) {
1411- quad_value in_val = load_quad<Aligned>(in_ptr, backend);
1420+ quad_value in_val;
1421+ load_quad<Aligned>(in_ptr, backend, &in_val);
14121422 typename NpyType<T>::TYPE out_val;
14131423 int ret = quad_to_numpy_same_value_check<T>(&in_val, backend, &out_val);
14141424 if (ret < 0 )
@@ -1421,7 +1431,8 @@ quad_to_numpy_strided_loop(PyArrayMethod_Context *context, char *const data[],
14211431 return 0 ;
14221432 }
14231433 while (N--) {
1424- quad_value in_val = load_quad<Aligned>(in_ptr, backend);
1434+ quad_value in_val;
1435+ load_quad<Aligned>(in_ptr, backend, &in_val);
14251436 typename NpyType<T>::TYPE out_val = from_quad<T>(&in_val, backend);
14261437 store<Aligned, typename NpyType<T>::TYPE >(out_ptr, out_val);
14271438
0 commit comments