diff options
author | Thomas Koenig <tkoenig@gcc.gnu.org> | 2024-10-05 14:17:49 +0200 |
---|---|---|
committer | Thomas Koenig <tkoenig@gcc.gnu.org> | 2024-10-07 20:40:44 +0200 |
commit | c0002a675a92e76d2f326bf4629d8e4127a0c9da (patch) | |
tree | 545c63181a5471d5bcf6f9591ea615850fee0889 /gcc | |
parent | a2a956cf26e645bfddbc0b743b97472e298c7a8c (diff) | |
download | gcc-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.cc | 12 | ||||
-rw-r--r-- | gcc/fortran/gfortran.texi | 3 | ||||
-rw-r--r-- | gcc/fortran/trans-intrinsic.cc | 20 | ||||
-rw-r--r-- | gcc/testsuite/gfortran.dg/unsigned_35.f90 | 52 |
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 |