https://gcc.gnu.org/g:a04c0d344553cc0b405977b3b9eac4ca504a299d

commit a04c0d344553cc0b405977b3b9eac4ca504a299d
Author: Mikael Morin <mik...@gcc.gnu.org>
Date:   Mon Jul 8 22:19:43 2024 +0200

    Sauvegarde tests
    
    Correction 11 18
    
    Correction tests masque scalaire .false.

Diff:
---
 gcc/fortran/trans-intrinsic.cc         |  10 ++
 gcc/testsuite/gfortran.dg/maxloc_5.f90 | 257 +++++++++++++++++++++++++++++++++
 gcc/testsuite/gfortran.dg/minloc_5.f90 | 257 +++++++++++++++++++++++++++++++++
 3 files changed, 524 insertions(+)

diff --git a/gcc/fortran/trans-intrinsic.cc b/gcc/fortran/trans-intrinsic.cc
index 5ea10e840609..cadbd1774520 100644
--- a/gcc/fortran/trans-intrinsic.cc
+++ b/gcc/fortran/trans-intrinsic.cc
@@ -5325,6 +5325,7 @@ gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * 
expr, enum tree_code op)
   gfc_actual_arglist *actual;
   gfc_ss *arrayss;
   gfc_ss *maskss;
+  gfc_ss *backss;
   gfc_se arrayse;
   gfc_se maskse;
   gfc_expr *arrayexpr;
@@ -5390,6 +5391,11 @@ gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * 
expr, enum tree_code op)
     && maskexpr->symtree->n.sym->attr.dummy
     && maskexpr->symtree->n.sym->attr.optional;
   backexpr = actual->next->next->expr;
+  if (backexpr)
+    backss = gfc_get_scalar_ss (gfc_ss_terminator, backexpr);
+  else
+    backss = nullptr;
+
   nonempty = NULL;
   if (maskexpr && maskexpr->rank != 0)
     {
@@ -5449,6 +5455,9 @@ gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * 
expr, enum tree_code op)
   if (maskss)
     gfc_add_ss_to_loop (&loop, maskss);
 
+  if (backss)
+    gfc_add_ss_to_loop (&loop, backss);
+
   gfc_add_ss_to_loop (&loop, arrayss);
 
   /* Initialize the loop.  */
@@ -5535,6 +5544,7 @@ gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * 
expr, enum tree_code op)
   gfc_add_block_to_block (&block, &arrayse.pre);
 
   gfc_init_se (&backse, NULL);
+  backse.ss = backss;
   gfc_conv_expr_val (&backse, backexpr);
   gfc_add_block_to_block (&block, &backse.pre);
 
diff --git a/gcc/testsuite/gfortran.dg/maxloc_5.f90 
b/gcc/testsuite/gfortran.dg/maxloc_5.f90
new file mode 100644
index 000000000000..5d722450c8fb
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/maxloc_5.f90
@@ -0,0 +1,257 @@
+! { dg-do run }
+!
+! Check that the evaluation of MAXLOC's BACK argument is made only once
+! before the scalarisation loops.
+
+program p
+  implicit none
+  integer, parameter :: data10(*) = (/ 7, 4, 7, 6, 6, 4, 6, 3, 9, 8 /)
+  logical, parameter :: mask10(*) = (/ .false., .true., .false., &
+                                       .false., .true., .true.,  &
+                                       .true. , .true., .false., &
+                                       .false. /)
+  integer :: calls_count = 0
+  call check_int_const_shape
+  call check_int_const_shape_scalar_mask
+  call check_int_const_shape_array_mask
+  call check_int_const_shape_optional_mask_present
+  call check_int_const_shape_optional_mask_absent
+  call check_int_const_shape_empty
+  call check_int_alloc
+  call check_int_alloc_scalar_mask
+  call check_int_alloc_array_mask
+  call check_int_alloc_empty
+  call check_real_const_shape
+  call check_real_const_shape_scalar_mask
+  call check_real_const_shape_array_mask
+  call check_real_const_shape_optional_mask_present
+  call check_real_const_shape_optional_mask_absent
+  call check_real_const_shape_empty
+  call check_real_alloc
+  call check_real_alloc_scalar_mask
+  call check_real_alloc_array_mask
+  call check_real_alloc_empty
+contains
+  function get_scalar_false()
+    logical :: get_scalar_false
+    calls_count = calls_count + 1
+    get_scalar_false = .false.
+  end function
+  subroutine check_int_const_shape()
+    integer :: a(10)
+    logical :: m(10)
+    integer :: r
+    a = data10
+    calls_count = 0
+    r = maxloc(a, dim = 1, back = get_scalar_false())
+    if (calls_count /= 1) stop 11
+  end subroutine
+  subroutine check_int_const_shape_scalar_mask()
+    integer :: a(10)
+    integer :: r
+    a = data10
+    calls_count = 0
+    ! We only check the case of a .true. mask.
+    ! If the mask is .false., the back argument is not necessary to deduce
+    ! the value returned by maxloc, so the compiler is free to elide it,
+    ! and the value of calls_count is undefined in that case.
+    r = maxloc(a, dim = 1, mask = .true., back = get_scalar_false())
+    if (calls_count /= 1) stop 18
+  end subroutine
+  subroutine check_int_const_shape_array_mask()
+    integer :: a(10)
+    logical :: m(10)
+    integer :: r
+    a = data10
+    m = mask10
+    calls_count = 0
+    r = maxloc(a, dim = 1, mask = m, back = get_scalar_false())
+    if (calls_count /= 1) stop 32
+  end subroutine
+  subroutine call_maxloc_int(r, a, m, b)
+    integer :: a(:)
+    logical, optional :: m(:)
+    logical, optional :: b
+    integer :: r
+    r = maxloc(a, dim = 1, mask = m, back = b)
+  end subroutine
+  subroutine check_int_const_shape_optional_mask_present()
+    integer :: a(10)
+    logical :: m(10)
+    integer :: r
+    a = data10
+    m = mask10
+    calls_count = 0
+    call call_maxloc_int(r, a, m, get_scalar_false())
+    if (calls_count /= 1) stop 39
+  end subroutine
+  subroutine check_int_const_shape_optional_mask_absent()
+    integer :: a(10)
+    integer :: r
+    a = data10
+    calls_count = 0
+    call call_maxloc_int(r, a, b = get_scalar_false())
+    if (calls_count /= 1) stop 46
+  end subroutine
+  subroutine check_int_const_shape_empty()
+    integer :: a(0)
+    logical :: m(0)
+    integer :: r
+    a = (/ integer:: /)
+    m = (/ logical:: /)
+    calls_count = 0
+    r = maxloc(a, dim = 1, mask = m, back = get_scalar_false())
+    if (calls_count /= 1) stop 53
+  end subroutine
+  subroutine check_int_alloc()
+    integer, allocatable :: a(:)
+    integer :: r
+    allocate(a(10))
+    a(:) = data10
+    calls_count = 0
+    r = maxloc(a, dim = 1, back = get_scalar_false())
+    if (calls_count /= 1) stop 60
+  end subroutine
+  subroutine check_int_alloc_scalar_mask()
+    integer, allocatable :: a(:)
+    integer :: r
+    allocate(a(10))
+    a(:) = data10
+    calls_count = 0
+    ! We only check the case of a .true. mask.
+    ! If the mask is .false., the back argument is not necessary to deduce
+    ! the value returned by maxloc, so the compiler is free to elide it,
+    ! and the value of calls_count is undefined in that case.
+    r = maxloc(a, dim = 1, mask = .true., back = get_scalar_false())
+    if (calls_count /= 1) stop 67
+  end subroutine
+  subroutine check_int_alloc_array_mask()
+    integer, allocatable :: a(:)
+    logical, allocatable :: m(:)
+    integer :: r
+    allocate(a(10), m(10))
+    a(:) = data10
+    m(:) = mask10
+    calls_count = 0
+    r = maxloc(a, dim = 1, mask = m, back = get_scalar_false())
+    if (calls_count /= 1) stop 81
+  end subroutine
+  subroutine check_int_alloc_empty()
+    integer, allocatable :: a(:)
+    logical, allocatable :: m(:)
+    integer :: r
+    allocate(a(0), m(0))
+    calls_count = 0
+    r = maxloc(a, dim = 1, mask = m, back = get_scalar_false())
+    if (calls_count /= 1) stop 88
+  end subroutine
+  subroutine check_real_const_shape()
+    real :: a(10)
+    integer :: r
+    a = (/ real:: data10 /)
+    calls_count = 0
+    r = maxloc(a, dim = 1, back = get_scalar_false())
+    if (calls_count /= 1) stop 95
+  end subroutine
+  subroutine check_real_const_shape_scalar_mask()
+    real :: a(10)
+    integer :: r
+    a = (/ real:: data10 /)
+    calls_count = 0
+    ! We only check the case of a .true. mask.
+    ! If the mask is .false., the back argument is not necessary to deduce
+    ! the value returned by maxloc, so the compiler is free to elide it,
+    ! and the value of calls_count is undefined in that case.
+    r = maxloc(a, dim = 1, mask = .true., back = get_scalar_false())
+    if (calls_count /= 1) stop 102
+  end subroutine
+  subroutine check_real_const_shape_array_mask()
+    real :: a(10)
+    logical :: m(10)
+    integer :: r
+    a = (/ real:: data10 /)
+    m = mask10
+    calls_count = 0
+    r = maxloc(a, dim = 1, mask = m, back = get_scalar_false())
+    if (calls_count /= 1) stop 116
+  end subroutine
+  subroutine call_maxloc_real(r, a, m, b)
+    real :: a(:)
+    logical, optional :: m(:)
+    logical, optional :: b
+    integer :: r
+    r = maxloc(a, dim = 1, mask = m, back = b)
+  end subroutine
+  subroutine check_real_const_shape_optional_mask_present()
+    real :: a(10)
+    logical :: m(10)
+    integer :: r
+    a = (/ real:: data10 /)
+    m = mask10
+    calls_count = 0
+    call call_maxloc_real(r, a, m, b = get_scalar_false())
+    if (calls_count /= 1) stop 123
+  end subroutine
+  subroutine check_real_const_shape_optional_mask_absent()
+    real :: a(10)
+    integer :: r
+    a = (/ real:: data10 /)
+    calls_count = 0
+    call call_maxloc_real(r, a, b = get_scalar_false())
+    if (calls_count /= 1) stop 130
+  end subroutine
+  subroutine check_real_const_shape_empty()
+    real :: a(0)
+    logical :: m(0)
+    integer :: r
+    a = (/ real:: /)
+    m = (/ logical:: /)
+    calls_count = 0
+    r = maxloc(a, dim = 1, mask = m, back = get_scalar_false())
+    if (calls_count /= 1) stop 137
+  end subroutine
+  subroutine check_real_alloc()
+    real, allocatable :: a(:)
+    integer :: r
+    allocate(a(10))
+    a(:) = (/ real:: data10 /)
+    calls_count = 0
+    r = maxloc(a, dim = 1, back = get_scalar_false())
+    if (calls_count /= 1) stop 144
+  end subroutine
+  subroutine check_real_alloc_scalar_mask()
+    real, allocatable :: a(:)
+    integer :: r
+    allocate(a(10))
+    a(:) = (/ real:: data10 /)
+    calls_count = 0
+    ! We only check the case of a .true. mask.
+    ! If the mask is .false., the back argument is not necessary to deduce
+    ! the value returned by maxloc, so the compiler is free to elide it,
+    ! and the value of calls_count is undefined in that case.
+    r = maxloc(a, dim = 1, mask = .true., back = get_scalar_false())
+    if (calls_count /= 1) stop 151
+  end subroutine
+  subroutine check_real_alloc_array_mask()
+    real, allocatable :: a(:)
+    logical, allocatable :: m(:)
+    integer :: r
+    allocate(a(10), m(10))
+    a(:) = (/ real:: data10 /)
+    m(:) = mask10
+    calls_count = 0
+    r = maxloc(a, dim = 1, mask = m, back = get_scalar_false())
+    if (calls_count /= 1) stop 165
+  end subroutine
+  subroutine check_real_alloc_empty()
+    real, allocatable :: a(:)
+    logical, allocatable :: m(:)
+    integer :: r
+    allocate(a(0), m(0))
+    a(:) = (/ real:: /)
+    m(:) = (/ logical :: /)
+    calls_count = 0
+    r = maxloc(a, dim = 1, mask = m, back = get_scalar_false())
+    if (calls_count /= 1) stop 172
+  end subroutine
+end program p
diff --git a/gcc/testsuite/gfortran.dg/minloc_5.f90 
b/gcc/testsuite/gfortran.dg/minloc_5.f90
new file mode 100644
index 000000000000..cb2cd008344a
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/minloc_5.f90
@@ -0,0 +1,257 @@
+! { dg-do run }
+!
+! Check that the evaluation of MINLOC's BACK argument is made only once
+! before the scalarisation loops.
+
+program p
+  implicit none
+  integer, parameter :: data10(*) = (/ 2, 5, 2, 3, 3, 5, 3, 6, 0, 1 /)
+  logical, parameter :: mask10(*) = (/ .false., .true., .false., &
+                                       .false., .true., .true.,  &
+                                       .true. , .true., .false., &
+                                       .false. /)
+  integer :: calls_count = 0
+  call check_int_const_shape
+  call check_int_const_shape_scalar_mask
+  call check_int_const_shape_array_mask
+  call check_int_const_shape_optional_mask_present
+  call check_int_const_shape_optional_mask_absent
+  call check_int_const_shape_empty
+  call check_int_alloc
+  call check_int_alloc_scalar_mask
+  call check_int_alloc_array_mask
+  call check_int_alloc_empty
+  call check_real_const_shape
+  call check_real_const_shape_scalar_mask
+  call check_real_const_shape_array_mask
+  call check_real_const_shape_optional_mask_present
+  call check_real_const_shape_optional_mask_absent
+  call check_real_const_shape_empty
+  call check_real_alloc
+  call check_real_alloc_scalar_mask
+  call check_real_alloc_array_mask
+  call check_real_alloc_empty
+contains
+  function get_scalar_false()
+    logical :: get_scalar_false
+    calls_count = calls_count + 1
+    get_scalar_false = .false.
+  end function
+  subroutine check_int_const_shape()
+    integer :: a(10)
+    logical :: m(10)
+    integer :: r
+    a = data10
+    calls_count = 0
+    r = minloc(a, dim = 1, back = get_scalar_false())
+    if (calls_count /= 1) stop 11
+  end subroutine
+  subroutine check_int_const_shape_scalar_mask()
+    integer :: a(10)
+    integer :: r
+    a = data10
+    calls_count = 0
+    ! We only check the case of a .true. mask.
+    ! If the mask is .false., the back argument is not necessary to deduce
+    ! the value returned by minloc, so the compiler is free to elide it,
+    ! and the value of calls_count is undefined in that case.
+    r = minloc(a, dim = 1, mask = .true., back = get_scalar_false())
+    if (calls_count /= 1) stop 18
+  end subroutine
+  subroutine check_int_const_shape_array_mask()
+    integer :: a(10)
+    logical :: m(10)
+    integer :: r
+    a = data10
+    m = mask10
+    calls_count = 0
+    r = minloc(a, dim = 1, mask = m, back = get_scalar_false())
+    if (calls_count /= 1) stop 32
+  end subroutine
+  subroutine call_minloc_int(r, a, m, b)
+    integer :: a(:)
+    logical, optional :: m(:)
+    logical, optional :: b
+    integer :: r
+    r = minloc(a, dim = 1, mask = m, back = b)
+  end subroutine
+  subroutine check_int_const_shape_optional_mask_present()
+    integer :: a(10)
+    logical :: m(10)
+    integer :: r
+    a = data10
+    m = mask10
+    calls_count = 0
+    call call_minloc_int(r, a, m, get_scalar_false())
+    if (calls_count /= 1) stop 39
+  end subroutine
+  subroutine check_int_const_shape_optional_mask_absent()
+    integer :: a(10)
+    integer :: r
+    a = data10
+    calls_count = 0
+    call call_minloc_int(r, a, b = get_scalar_false())
+    if (calls_count /= 1) stop 46
+  end subroutine
+  subroutine check_int_const_shape_empty()
+    integer :: a(0)
+    logical :: m(0)
+    integer :: r
+    a = (/ integer:: /)
+    m = (/ logical:: /)
+    calls_count = 0
+    r = minloc(a, dim = 1, mask = m, back = get_scalar_false())
+    if (calls_count /= 1) stop 53
+  end subroutine
+  subroutine check_int_alloc()
+    integer, allocatable :: a(:)
+    integer :: r
+    allocate(a(10))
+    a(:) = data10
+    calls_count = 0
+    r = minloc(a, dim = 1, back = get_scalar_false())
+    if (calls_count /= 1) stop 60
+  end subroutine
+  subroutine check_int_alloc_scalar_mask()
+    integer, allocatable :: a(:)
+    integer :: r
+    allocate(a(10))
+    a(:) = data10
+    calls_count = 0
+    ! We only check the case of a .true. mask.
+    ! If the mask is .false., the back argument is not necessary to deduce
+    ! the value returned by minloc, so the compiler is free to elide it,
+    ! and the value of calls_count is undefined in that case.
+    r = minloc(a, dim = 1, mask = .true., back = get_scalar_false())
+    if (calls_count /= 1) stop 67
+  end subroutine
+  subroutine check_int_alloc_array_mask()
+    integer, allocatable :: a(:)
+    logical, allocatable :: m(:)
+    integer :: r
+    allocate(a(10), m(10))
+    a(:) = data10
+    m(:) = mask10
+    calls_count = 0
+    r = minloc(a, dim = 1, mask = m, back = get_scalar_false())
+    if (calls_count /= 1) stop 81
+  end subroutine
+  subroutine check_int_alloc_empty()
+    integer, allocatable :: a(:)
+    logical, allocatable :: m(:)
+    integer :: r
+    allocate(a(0), m(0))
+    calls_count = 0
+    r = minloc(a, dim = 1, mask = m, back = get_scalar_false())
+    if (calls_count /= 1) stop 88
+  end subroutine
+  subroutine check_real_const_shape()
+    real :: a(10)
+    integer :: r
+    a = (/ real:: data10 /)
+    calls_count = 0
+    r = minloc(a, dim = 1, back = get_scalar_false())
+    if (calls_count /= 1) stop 95
+  end subroutine
+  subroutine check_real_const_shape_scalar_mask()
+    real :: a(10)
+    integer :: r
+    a = (/ real:: data10 /)
+    calls_count = 0
+    ! We only check the case of a .true. mask.
+    ! If the mask is .false., the back argument is not necessary to deduce
+    ! the value returned by minloc, so the compiler is free to elide it,
+    ! and the value of calls_count is undefined in that case.
+    r = minloc(a, dim = 1, mask = .true., back = get_scalar_false())
+    if (calls_count /= 1) stop 102
+  end subroutine
+  subroutine check_real_const_shape_array_mask()
+    real :: a(10)
+    logical :: m(10)
+    integer :: r
+    a = (/ real:: data10 /)
+    m = mask10
+    calls_count = 0
+    r = minloc(a, dim = 1, mask = m, back = get_scalar_false())
+    if (calls_count /= 1) stop 116
+  end subroutine
+  subroutine call_minloc_real(r, a, m, b)
+    real :: a(:)
+    logical, optional :: m(:)
+    logical, optional :: b
+    integer :: r
+    r = minloc(a, dim = 1, mask = m, back = b)
+  end subroutine
+  subroutine check_real_const_shape_optional_mask_present()
+    real :: a(10)
+    logical :: m(10)
+    integer :: r
+    a = (/ real:: data10 /)
+    m = mask10
+    calls_count = 0
+    call call_minloc_real(r, a, m, b = get_scalar_false())
+    if (calls_count /= 1) stop 123
+  end subroutine
+  subroutine check_real_const_shape_optional_mask_absent()
+    real :: a(10)
+    integer :: r
+    a = (/ real:: data10 /)
+    calls_count = 0
+    call call_minloc_real(r, a, b = get_scalar_false())
+    if (calls_count /= 1) stop 130
+  end subroutine
+  subroutine check_real_const_shape_empty()
+    real :: a(0)
+    logical :: m(0)
+    integer :: r
+    a = (/ real:: /)
+    m = (/ logical:: /)
+    calls_count = 0
+    r = minloc(a, dim = 1, mask = m, back = get_scalar_false())
+    if (calls_count /= 1) stop 137
+  end subroutine
+  subroutine check_real_alloc()
+    real, allocatable :: a(:)
+    integer :: r
+    allocate(a(10))
+    a(:) = (/ real:: data10 /)
+    calls_count = 0
+    r = minloc(a, dim = 1, back = get_scalar_false())
+    if (calls_count /= 1) stop 144
+  end subroutine
+  subroutine check_real_alloc_scalar_mask()
+    real, allocatable :: a(:)
+    integer :: r
+    allocate(a(10))
+    a(:) = (/ real:: data10 /)
+    calls_count = 0
+    ! We only check the case of a .true. mask.
+    ! If the mask is .false., the back argument is not necessary to deduce
+    ! the value returned by minloc, so the compiler is free to elide it,
+    ! and the value of calls_count is undefined in that case.
+    r = minloc(a, dim = 1, mask = .true., back = get_scalar_false())
+    if (calls_count /= 1) stop 151
+  end subroutine
+  subroutine check_real_alloc_array_mask()
+    real, allocatable :: a(:)
+    logical, allocatable :: m(:)
+    integer :: r
+    allocate(a(10), m(10))
+    a(:) = (/ real:: data10 /)
+    m(:) = mask10
+    calls_count = 0
+    r = minloc(a, dim = 1, mask = m, back = get_scalar_false())
+    if (calls_count /= 1) stop 165
+  end subroutine
+  subroutine check_real_alloc_empty()
+    real, allocatable :: a(:)
+    logical, allocatable :: m(:)
+    integer :: r
+    allocate(a(0), m(0))
+    a(:) = (/ real:: /)
+    m(:) = (/ logical :: /)
+    calls_count = 0
+    r = minloc(a, dim = 1, mask = m, back = get_scalar_false())
+    if (calls_count /= 1) stop 172
+  end subroutine
+end program p

Reply via email to