aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorThomas Koenig <tkoenig@gcc.gnu.org>2024-10-05 14:17:49 +0200
committerThomas Koenig <tkoenig@gcc.gnu.org>2024-10-07 20:40:44 +0200
commitc0002a675a92e76d2f326bf4629d8e4127a0c9da (patch)
tree545c63181a5471d5bcf6f9591ea615850fee0889 /gcc
parenta2a956cf26e645bfddbc0b743b97472e298c7a8c (diff)
downloadgcc-c0002a675a92e76d2f326bf4629d8e4127a0c9da.zip
gcc-c0002a675a92e76d2f326bf4629d8e4127a0c9da.tar.gz
gcc-c0002a675a92e76d2f326bf4629d8e4127a0c9da.tar.bz2
Implement MAXLOC and MINLOC for unsigned.
gcc/fortran/ChangeLog: * check.cc (gfc_check_minloc_maxloc): Handle BT_UNSIGNED. * trans-intrinsic.cc (gfc_conv_intrinsic_minmaxloc): Likewise. * gfortran.texi: Document MAXLOC and MINLOC for UNSIGNED. libgfortran/ChangeLog: * Makefile.am: Add files for unsigned MINLOC and MAXLOC. * Makefile.in: Regenerated. * gfortran.map: Add files for unsigned MINLOC and MAXLOC. * generated/maxloc0_16_m1.c: New file. * generated/maxloc0_16_m16.c: New file. * generated/maxloc0_16_m2.c: New file. * generated/maxloc0_16_m4.c: New file. * generated/maxloc0_16_m8.c: New file. * generated/maxloc0_4_m1.c: New file. * generated/maxloc0_4_m16.c: New file. * generated/maxloc0_4_m2.c: New file. * generated/maxloc0_4_m4.c: New file. * generated/maxloc0_4_m8.c: New file. * generated/maxloc0_8_m1.c: New file. * generated/maxloc0_8_m16.c: New file. * generated/maxloc0_8_m2.c: New file. * generated/maxloc0_8_m4.c: New file. * generated/maxloc0_8_m8.c: New file. * generated/maxloc1_16_m1.c: New file. * generated/maxloc1_16_m2.c: New file. * generated/maxloc1_16_m4.c: New file. * generated/maxloc1_16_m8.c: New file. * generated/maxloc1_4_m1.c: New file. * generated/maxloc1_4_m16.c: New file. * generated/maxloc1_4_m2.c: New file. * generated/maxloc1_4_m4.c: New file. * generated/maxloc1_4_m8.c: New file. * generated/maxloc1_8_m1.c: New file. * generated/maxloc1_8_m16.c: New file. * generated/maxloc1_8_m2.c: New file. * generated/maxloc1_8_m4.c: New file. * generated/maxloc1_8_m8.c: New file. * generated/minloc0_16_m1.c: New file. * generated/minloc0_16_m16.c: New file. * generated/minloc0_16_m2.c: New file. * generated/minloc0_16_m4.c: New file. * generated/minloc0_16_m8.c: New file. * generated/minloc0_4_m1.c: New file. * generated/minloc0_4_m16.c: New file. * generated/minloc0_4_m2.c: New file. * generated/minloc0_4_m4.c: New file. * generated/minloc0_4_m8.c: New file. * generated/minloc0_8_m1.c: New file. * generated/minloc0_8_m16.c: New file. * generated/minloc0_8_m2.c: New file. * generated/minloc0_8_m4.c: New file. * generated/minloc0_8_m8.c: New file. * generated/minloc1_16_m1.c: New file. * generated/minloc1_16_m16.c: New file. * generated/minloc1_16_m2.c: New file. * generated/minloc1_16_m4.c: New file. * generated/minloc1_16_m8.c: New file. * generated/minloc1_4_m1.c: New file. * generated/minloc1_4_m16.c: New file. * generated/minloc1_4_m2.c: New file. * generated/minloc1_4_m4.c: New file. * generated/minloc1_4_m8.c: New file. * generated/minloc1_8_m1.c: New file. * generated/minloc1_8_m16.c: New file. * generated/minloc1_8_m2.c: New file. * generated/minloc1_8_m4.c: New file. * generated/minloc1_8_m8.c: New file. gcc/testsuite/ChangeLog: * gfortran.dg/unsigned_35.f90: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/fortran/check.cc12
-rw-r--r--gcc/fortran/gfortran.texi3
-rw-r--r--gcc/fortran/trans-intrinsic.cc20
-rw-r--r--gcc/testsuite/gfortran.dg/unsigned_35.f9052
4 files changed, 83 insertions, 4 deletions
diff --git a/gcc/fortran/check.cc b/gcc/fortran/check.cc
index 9c0b72f..79e6668 100644
--- a/gcc/fortran/check.cc
+++ b/gcc/fortran/check.cc
@@ -4219,7 +4219,17 @@ gfc_check_minloc_maxloc (gfc_actual_arglist *ap)
gfc_expr *a, *m, *d, *k, *b;
a = ap->expr;
- if (!int_or_real_or_char_check_f2003 (a, 0) || !array_check (a, 0))
+
+ if (flag_unsigned)
+ {
+ if (!int_or_real_or_char_or_unsigned_check_f2003 (a, 0))
+ return false;
+ }
+ else
+ if (!int_or_real_or_char_check_f2003 (a, 0))
+ return false;
+
+ if (!array_check (a, 0))
return false;
d = ap->next->expr;
diff --git a/gcc/fortran/gfortran.texi b/gcc/fortran/gfortran.texi
index db8c44f..f0926be 100644
--- a/gcc/fortran/gfortran.texi
+++ b/gcc/fortran/gfortran.texi
@@ -2793,7 +2793,8 @@ As of now, the following intrinsics take unsigned arguments:
@item @code{RANDOM_NUMBER}
@item @code{CSHIFT} and @code{EOSHIFT}
@item @code{FINDLOC}
-@item @code{MAXVAL} and @code{MINVAL}.
+@item @code{MAXVAL} and @code{MINVAL}
+@item @code{MAXLOC} and @code{MINLOC}.
@end itemize
This list will grow in the near future.
@c ---------------------------------------------------------------------
diff --git a/gcc/fortran/trans-intrinsic.cc b/gcc/fortran/trans-intrinsic.cc
index e065e31..a282ae1 100644
--- a/gcc/fortran/trans-intrinsic.cc
+++ b/gcc/fortran/trans-intrinsic.cc
@@ -5637,6 +5637,21 @@ gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, enum tree_code op)
arrayexpr->ts.kind);
break;
+ case BT_UNSIGNED:
+ /* For MAXVAL, the minimum is zero, for MINVAL it is HUGE(). */
+ if (op == GT_EXPR)
+ {
+ tmp = gfc_get_unsigned_type (arrayexpr->ts.kind);
+ tmp = build_int_cst (tmp, 0);
+ }
+ else
+ {
+ n = gfc_validate_kind (arrayexpr->ts.type, arrayexpr->ts.kind, false);
+ tmp = gfc_conv_mpz_unsigned_to_tree (gfc_unsigned_kinds[n].huge,
+ expr->ts.kind);
+ }
+ break;
+
default:
gcc_unreachable ();
}
@@ -5644,8 +5659,9 @@ gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, enum tree_code op)
/* We start with the most negative possible value for MAXLOC, and the most
positive possible value for MINLOC. The most negative possible value is
-HUGE for BT_REAL and (-HUGE - 1) for BT_INTEGER; the most positive
- possible value is HUGE in both cases. */
- if (op == GT_EXPR)
+ possible value is HUGE in both cases. BT_UNSIGNED has already been dealt
+ with above. */
+ if (op == GT_EXPR && expr->ts.type != BT_UNSIGNED)
tmp = fold_build1_loc (input_location, NEGATE_EXPR, TREE_TYPE (tmp), tmp);
if (op == GT_EXPR && arrayexpr->ts.type == BT_INTEGER)
tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (tmp), tmp,
diff --git a/gcc/testsuite/gfortran.dg/unsigned_35.f90 b/gcc/testsuite/gfortran.dg/unsigned_35.f90
new file mode 100644
index 0000000..9c94bfb
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/unsigned_35.f90
@@ -0,0 +1,52 @@
+! { dg-do run }
+! { dg-options "-funsigned" }
+program memain
+ implicit none
+ call test1
+contains
+ subroutine test1
+ unsigned, dimension(3) :: v
+ integer :: t1, t2
+ unsigned(2), dimension(3,3) :: w
+ integer, dimension(3,3) :: j
+ integer :: di
+ v = [1u, 2u, 4294967286u]
+ t1 = maxloc(v,dim=1)
+ if (t1 /= 3) error stop 1
+ t2 = minloc(v,dim=1)
+ if (t2 /= 1) error stop 2
+ call check_empty(0)
+ j = reshape([1,2,3,65534,5,1,65000,2,1],[3,3])
+ w = uint(j,2)
+ if (any(maxloc(j,dim=1) /= int(maxloc(w,dim=1)))) error stop 5
+ di = 2
+ if (any(maxloc(j,dim=di) /= int(maxloc(w,dim=di)))) error stop 6
+ end subroutine test1
+ subroutine check_empty(n)
+ integer, intent(in) :: n
+ unsigned, dimension(n) :: empty
+ if (minloc(empty, dim=1) /= 0) error stop 3
+ if (maxloc(empty, dim=1) /= 0) error stop 4
+ end subroutine check_empty
+ subroutine test2
+ integer :: i
+ unsigned, dimension(3), parameter :: v = [1u, 2u, 4294967286u]
+ integer, parameter :: t1 = maxloc(v,dim=1)
+ integer, parameter :: t2 = minloc(v,dim=1)
+ unsigned, parameter, dimension(2:1) :: empty = [(0u,i=2,1)]
+ integer, parameter :: t3 = minloc(empty,1)
+ integer, parameter :: t4 = maxloc(empty,1)
+ unsigned(2), parameter, dimension(2:1,2:1) :: e2 = reshape(empty,[0,0])
+ integer, parameter, dimension(3,3) :: j = reshape([1,2,3,65534,5,1,65000,2,1],[3,3])
+ integer, parameter, dimension(3) :: maxvj = maxloc(j,1), minvj=minloc(j,2)
+ unsigned, parameter, dimension(3,3) :: w = uint(j,2)
+ integer(2), parameter, dimension(3) :: maxvw = maxloc(w,1), minvw = minloc(w,2)
+
+ if (t1 /= 3) error stop 11
+ if (t2 /= 1) error stop 12
+ if (t3 /= 0) error stop 13
+ if (t4 /= 0) error stop 14
+ if (any(maxvj /= maxvw)) error stop 15
+ if (any(minvj /= minvw)) error stop 16
+ end subroutine test2
+end program memain