[Bug fortran/120191] Functions minloc() and maxloc() ignore the "back" parameter when "kind" is present.

2025-05-09 Thread daniil2472s at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120191

--- Comment #5 from Daniil Kochergin  ---
Done. Thank you!

[Bug libfortran/120196] New: In findloc2_s* when "back" is true loop goes one more step than needed.

2025-05-09 Thread daniil2472s at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120196

Bug ID: 120196
   Summary: In findloc2_s* when "back" is true loop goes one more
step than needed.
   Product: gcc
   Version: 15.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libfortran
  Assignee: unassigned at gcc dot gnu.org
  Reporter: daniil2472s at gmail dot com
  Target Milestone: ---

Greetings!

Found a bug that actually doesn't have any effects in tests.

In findloc2_s1.c, findloc2_s4.c, and corresponding ifindloc2.m4, there are two
functions, findloc2_s* and mfindloc2_s*, with the following problem.

When "back" is true loop goes one more step than needed.

$ cat /libgfortran/generated/findloc2_s1.c
...
index_type
findloc2_s1 (gfc_array_s1 * const restrict array, const GFC_UINTEGER_1 *
restrict value,
  GFC_LOGICAL_4 back,
  gfc_charlen_type len_array, gfc_charlen_type len_value)
...
  if (back)
{
  src = array->base_addr + (extent - 1) * sstride;
  for (i = extent; i >= 0; i--)
{
  if (compare_string (len_array, (char *) src, len_value, (char *)
value) == 0)
return i;
  src -= sstride;
}
}
  else
{
  src = array->base_addr;
  for (i = 1; i <= extent; i++)
{
  if (compare_string (len_array, (char *) src, len_value, (char *)
value) == 0)
return i;
  src += sstride;
}
}
...

Please note following string: 
for (i = extent; i >= 0; i--)
It must be constraints with i >= 1 or i > 0.

I couldn't create any test that failed due to the mistake, because when the
required value lies beyond the string bound, the function returns 0, like it
hasn't found any value. To prove that there are mistakes, we can count the
number of steps when "back" is false or compare with other findlocs.

For example:
$ cat findloc1_i4.c
...
extern void
findloc1_i4 (gfc_array_index_type * const restrict retarray,
gfc_array_i4 * const restrict array, GFC_INTEGER_4 value,
const index_type * restrict pdim, GFC_LOGICAL_4 back)
...
  if (back)
{
  src = base + (len - 1) * delta * 1;
  for (n = len; n > 0; n--, src -= delta * 1)
{
  if (*src == value)
{
  result = n;
  break;
}
}
}
  else
{
  src = base;
  for (n = 1; n <= len; n++, src += delta * 1)
{
  if (*src == value)
{
  result = n;
  break;
}
}
}
...

[Bug fortran/120191] New: Functions minloc() and maxloc() ignore the "back" parameter when "kind" is present.

2025-05-09 Thread daniil2472s at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120191

Bug ID: 120191
   Summary: Functions minloc() and maxloc() ignore the "back"
parameter when "kind" is present.
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: fortran
  Assignee: unassigned at gcc dot gnu.org
  Reporter: daniil2472s at gmail dot com
  Target Milestone: ---

Created attachment 61378
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=61378&action=edit
Patch to remove "kind" parameter.

Greetings!

In the minloc() and maxloc() functions, when the "kind" parameter is present,
the "back" parameter is not working.

$ gfortran -v
Using built-in specs.
COLLECT_GCC=gfortran
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-linux-gnu/13/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu
13.3.0-6ubuntu2~24.04' --with-bugurl=file:///usr/share/doc/gcc-13/README.Bugs
--enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++,m2 --prefix=/usr
--with-gcc-major-version-only --program-suffix=-13
--program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id
--libexecdir=/usr/libexec --without-included-gettext --enable-threads=posix
--libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu
--enable-libstdcxx-debug --enable-libstdcxx-time=yes
--with-default-libstdcxx-abi=new --enable-libstdcxx-backtrace
--enable-gnu-unique-object --disable-vtable-verify --enable-plugin
--enable-default-pie --with-system-zlib --enable-libphobos-checking=release
--with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch
--disable-werror --enable-cet --with-arch-32=i686 --with-abi=m64
--with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic
--enable-offload-targets=nvptx-none=/build/gcc-13-fG75Ri/gcc-13-13.3.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/gcc-13-fG75Ri/gcc-13-13.3.0/debian/tmp-gcn/usr
--enable-offload-defaulted --without-cuda-driver --enable-checking=release
--build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
--with-build-config=bootstrap-lto-lean --enable-link-serialization=2
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 13.3.0 (Ubuntu 13.3.0-6ubuntu2~24.04)


Simple test.

$ cat test_minmaxloc.f90
program main
  implicit none
  real, dimension(4) :: a

  a = [ 3.0, 1.0, 3.0, 1.0]

  print *, "+++ kind=default +++"

  print *, "back=default:", maxloc(a)
  print *, "back=.true. :", maxloc(a, back=.true.)
  print *, "back=.false.:", maxloc(a, back=.false.)

  print *, "+++ kind=1 +++"

  print *, "back=default:", maxloc(a, kind=1)
  print *, "back=.true. :", maxloc(a, kind=1, back=.true.)
  print *, "back=.false.:", maxloc(a, kind=1, back=.false.)

end program

$ gfortran -Wall -Wextra -fdump-tree-original test_minmaxloc.f90
 +++ kind=default +++
 back=default:   1
 back=.true. :   3
 back=.false.:   1
 +++ kind=1 +++
 back=default:3
 back=.true. :3
 back=.false.:3

If we look at a C-like dump file, we will see a function call with four
parameters:
_gfortran_maxloc0_4_r4 (&atmp.30, D.4403, D.4407, 1);
but the corresponding libgfortran function receives only three parameters:
extern void maxloc0_4_r4 (gfc_array_i4 * const restrict retarray, 
gfc_array_r4 * const restrict array, GFC_LOGICAL_4);

The third parameter in the function call is "kind." Since the "kind" parameter
converts to an intrinsic name for minloc and maxloc functions, it's redundant
in the function call.

As far as I figured it out, the problem is in the following file
  gcc/fortran/trans-intrinsic.cc
in function
  gfc_conv_intrinsic_minmaxloc()

The strip_kind_from_actual() function must be called in any case to remove the
"kind" argument.

For now it's called only with the condition "if (arrayexpr->ts.type ==
BT_CHARACTER)".

Attaching the proposed patch.

[Bug fortran/120191] Functions minloc() and maxloc() ignore the "back" parameter when "kind" is present.

2025-05-09 Thread daniil2472s at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120191

--- Comment #3 from Daniil Kochergin  ---
(In reply to Jakub Jelinek from comment #2)
> Created attachment 61380 [details]
> gcc16-pr120191-test.patch
> 
> Perhaps like this?

Sorry for the trivial question, but should I mail the patch along with your
test?