[gcc(refs/users/mikael/heads/refactor_descriptor_v05)] Correction partielle régression reduce_1
Mikael Morin
mikael@gcc.gnu.org
Fri Jun 13 15:13:19 GMT 2025
https://gcc.gnu.org/g:7631c35989bd70dc13dbd1d0f645a839a17d9248
commit 7631c35989bd70dc13dbd1d0f645a839a17d9248
Author: Mikael Morin <mikael@gcc.gnu.org>
Date: Mon Jun 9 11:07:30 2025 +0200
Correction partielle régression reduce_1
Diff:
---
libgfortran/intrinsics/reduce.c | 59 ++++++++++++++++++++++++++---------------
1 file changed, 38 insertions(+), 21 deletions(-)
diff --git a/libgfortran/intrinsics/reduce.c b/libgfortran/intrinsics/reduce.c
index 8e1ab3b8c2f7..de0c264323d4 100644
--- a/libgfortran/intrinsics/reduce.c
+++ b/libgfortran/intrinsics/reduce.c
@@ -50,11 +50,12 @@ reduce (parray *ret,
void *buffer;
void *res;
index_type ext0, ext1, ext2;
- index_type spc0, spc1, spc2;
+ index_type aspc0, aspc1, aspc2;
+ index_type rspc0, rspc2;
+ index_type mspc0, mspc1, mspc2;
index_type idx0, idx1, idx2;
- index_type dimen, dimen_m1, off, ext, spc;
+ index_type dimen, dimen_m1, moff, ext, spc;
bool started;
- bool masked = false;
bool dim_present = dim != NULL;
bool mask_present = mask != NULL;
bool identity_present = identity != NULL;
@@ -95,18 +96,20 @@ reduce (parray *ret,
painless by the use of pointer arithmetic throughout (except for MASK,
whose type is known. */
ext0 = ext1 = ext2 = 1;
- spc0 = spc1 = spc2 = elem_len;
+ aspc0 = aspc1 = aspc2 = elem_len;
+ rspc0 = rspc2 = elem_len;
+ mspc0 = mspc1 = mspc2 = sizeof (GFC_LOGICAL_4);
scalar_result = (!dim_present && array_rank > 1) || array_rank == 1;
+ spc = elem_len;
j = 0;
for (i = 0; i < array_rank; i++)
{
/* Obtain the shape of the reshaped ARRAY. */
ext = GFC_DESCRIPTOR_EXTENT (array,i);
- spc = GFC_DESCRIPTOR_SPACING (array,i);
- if (masked && (ext != GFC_DESCRIPTOR_EXTENT (mask, i)))
+ if (mask_present && (ext != GFC_DESCRIPTOR_EXTENT (mask, i)))
{
int mext = (int)GFC_DESCRIPTOR_EXTENT (mask, i);
runtime_error ("shape mismatch between ARRAY and MASK in the REDUCE "
@@ -126,28 +129,39 @@ reduce (parray *ret,
ext2 *= ext;
/* The dimensions of the return array. */
- if (i != (int)dimen_m1)
+ if (!scalar_result && ret->base_addr == NULL && i != (int)dimen_m1)
{
- spc = GFC_DESCRIPTOR_SPACING (array, j);
GFC_DESCRIPTOR_DIMENSION_SET (ret, j, 0, ext - 1, spc);
+ spc *= ext;
j++;
}
}
if (!scalar_result)
{
- spc1 = GFC_DESCRIPTOR_SPACING (array, dimen_m1);
+ aspc1 = GFC_DESCRIPTOR_SPACING (array, dimen_m1);
+ if (mask_present)
+ mspc1 = GFC_DESCRIPTOR_SPACING (mask, dimen_m1);
if (dimen < array_rank)
- spc2 = GFC_DESCRIPTOR_SPACING (array, dimen);
+ {
+ aspc2 = GFC_DESCRIPTOR_SPACING (array, dimen);
+ rspc2 = GFC_DESCRIPTOR_SPACING (ret, dimen_m1);
+ if (mask_present)
+ mspc2 = GFC_DESCRIPTOR_SPACING (mask, dimen);
+ }
else
- spc2 = elem_len;
+ {
+ aspc2 = 1;
+ rspc2 = 1;
+ mspc2 = 1;
+ }
}
/* Allocate the result data, the result buffer and zero. */
if (ret->base_addr == NULL)
{
ret->base_addr = calloc ((size_t)(ext0 * ext2), elem_len);
- GFC_DESCRIPTOR_SPAN (ret) = GFC_DESCRIPTOR_SIZE (ret);
+ GFC_DESCRIPTOR_SPAN (ret) = GFC_DESCRIPTOR_SIZE (ret) = elem_len;
}
buffer = calloc (1, elem_len);
@@ -158,14 +172,16 @@ reduce (parray *ret,
{
for (idx2 = 0; idx2 < ext2; idx2++)
{
- off = idx0 * spc0 + idx2 * spc2;
if (mask_present)
- maskR = *((GFC_LOGICAL_4 *) (((char*)mask->base_addr) + (size_t) off));
+ {
+ moff = idx0 * mspc0 + idx2 * mspc2;
+ maskR = *((GFC_LOGICAL_4 *) (((char*)mask->base_addr) + (size_t) moff));
+ }
started = (mask_present && maskR) || !mask_present;
buffer_ptr = array->base_addr
- + (size_t)(idx0 * spc0 + idx2 * spc2);
+ + (size_t)(idx0 * aspc0 + idx2 * aspc2);
/* Start the iteration over the second dimension of ARRAY. */
for (idx1 = 1; idx1 < ext1; idx1++)
@@ -173,12 +189,14 @@ reduce (parray *ret,
/* If masked, cycle until after first element that is not masked
out. Then set 'started' and cycle so that this becomes the
first element in the reduction. */
- off = idx0 * spc0 + idx1 * spc1 + idx2 * spc2;
if (mask_present)
- maskR = *((GFC_LOGICAL_4 *) (((char*)mask->base_addr) + (size_t) off));
+ {
+ moff = idx0 * mspc0 + idx1 * mspc1 + idx2 * mspc2;
+ maskR = *((GFC_LOGICAL_4 *) (((char*)mask->base_addr) + (size_t) moff));
+ }
array_ptr = array->base_addr
- + (size_t)(idx0 * spc0 + idx1 * spc1 + idx2 * spc2);
+ + (size_t)(idx0 * aspc0 + idx1 * aspc1 + idx2 * aspc2);
if (!started)
{
if (mask_present && maskR)
@@ -200,9 +218,8 @@ reduce (parray *ret,
/* Now the result of the iteration is transferred to the returned
result. If this result element is empty emit an error or, if
- available, set to identity. Note that str1 is paired with idx2
- here because the result skips a dimension. */
- res = ret->base_addr + (size_t)(idx0 * spc0 + idx2 * spc1);
+ available, set to identity. */
+ res = ret->base_addr + (size_t)(idx0 * rspc0 + idx2 * rspc2);
if (started)
{
operation (buffer_ptr, NULL, res);
More information about the Gcc-cvs
mailing list