The Fortran standard does not specify what the result of the MAX
and MIN intrinsics are if one of the arguments is a NaN. So it
should be ok to tranform reduction for IFN_COND_MIN with vectorized
COND_MIN and REDUC_MIN.

Bootstrapped and regtested on x86_64-pc-linux-gnu{-m32,}.
Ok for trunk and backport to GCC14?

gcc/ChangeLog:

        PR 114883
        * tree-vect-loop.cc (vect_transform_reduction): Don't assert
        for IFN_COND_{MIN, MAX}.

gcc/testsuite/ChangeLog:

        * gfortran.dg/pr114883.f90: New test.
---
 gcc/testsuite/gfortran.dg/pr114883.f90 | 191 +++++++++++++++++++++++++
 gcc/tree-vect-loop.cc                  |   3 +-
 2 files changed, 193 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gfortran.dg/pr114883.f90

diff --git a/gcc/testsuite/gfortran.dg/pr114883.f90 
b/gcc/testsuite/gfortran.dg/pr114883.f90
new file mode 100644
index 00000000000..86b664a521e
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr114883.f90
@@ -0,0 +1,191 @@
+! { dg-do compile }
+! { dg-options "-O3" }
+! { dg-additional-options "-march=x86-64-v4" { target { x86_64-*-* i?86-*-* } 
} }
+
+module ndrop
+
+
+  implicit none
+
+  private
+  save
+
+  public dropmixnuc
+
+  real(8) :: npv(1011) ! number per volume concentration
+  real(8) :: alogsig(1011) ! natl log of geometric standard dev of aerosol
+
+  type qqcw_type
+     real(8), pointer :: fldcw(:,:)
+  end type qqcw_type
+
+contains
+
+  subroutine dropmixnuc(lchnk, ncol, temp,  &
+       cldn,cldo,     &
+       raer, dtmicro                   &
+       ) 
+    implicit none
+
+    !     input
+
+    integer, intent(in) :: lchnk                ! chunk identifier
+    integer, intent(in) :: ncol                 ! number of columns
+    !      type(physics_state), intent(in) :: state      ! Physics state 
variables
+    real(8), intent(in) :: dtmicro             ! time step for microphysics (s)
+    real(8), intent(in) :: temp(1,1011)    ! temperature (K)
+    real(8), intent(in) :: cldo(1,1011)    ! cloud fraction on previous time 
step
+    real(8), intent(in) :: cldn(1,1011)    ! cloud fraction
+    real(8), intent(in) :: raer(1,1011,1011) ! aerosol mass, number mixing 
ratios
+
+
+    type(qqcw_type) :: QQCW(1011)
+
+    real(8) depvel(1,1011)! deposition velocity for droplets (m/s)
+    real(8) wtke(1,1011)     ! turbulent vertical velocity at base of layer k 
(m/s)
+    real(8) wtke_cen(1,1011) ! turbulent vertical velocity at center of layer 
k (m/s)
+    real(8) zn(1011) ! g/pdel (m2/g) for layer
+    real(8) zs(1011) ! inverse of distance between levels (m)
+    real(8), parameter :: zkmin=0.01_8,zkmax=100._8
+    real(8) cs(1,1011)      ! air density (kg/m3)
+    real(8) dz(1,1011)      ! geometric thickness of layers (m)
+    real(8) zero
+
+    real(8) wdiab           ! diabatic vertical velocity
+    real(8), parameter :: wmixmin = 0.1 ! minimum turbulence vertical velocity 
(m/s)
+    !       real(8), parameter :: wmixmin = 0.2 ! minimum turbulence vertical 
velocity (m/s)
+    !      real(8), parameter :: wmixmin = 1.0 ! minimum turbulence vertical 
velocity (m/s)
+    real(8) ekk(0:1011)       ! density*diffusivity for droplets (kg/m3 m2/s)
+    real(8), parameter :: sq2pi=2.5066283_8
+    real(8) dtinv
+
+    integer km1,kp1
+    real(8) wbar,wmix,wmin,wmax
+    real(8) dumc
+    real(8) fac_srflx
+    real(8) surfrate(1011) ! surface exchange rate (/s)
+    real(8) surfratemax      ! max surfrate for all species treated here
+    real(8) dtmin,tinv,dtt
+    integer nsubmix,nsubmix_bnd
+    integer i,k,m
+    real(8) dtmix
+    real(8) pi
+    integer nnew,nsav,ntemp
+    real(8) ekkp(1011),ekkm(1011) ! zn*zs*density*diffusivity
+    integer count_submix(100)
+    save count_submix
+    real(8) nsource(1,1011)            ! droplet number source (#/kg/s)
+    real(8) ndropmix(1,1011)           ! droplet number mixing (#/kg/s)
+    real(8) ndropcol(1)               ! column droplet number (#/m2)
+
+    real(8) na(1),va(1),hy(1)
+    real(8) naermod(1011) ! (/m3)
+    real(8) hygro(1011)  ! hygroscopicity of aerosol mode
+    real(8) vaerosol(1011) ! interstit+activated aerosol volume conc (cm3/cm3)
+    real(8) :: taumix_internal_1011_inv ! 1/(internal mixing time scale for 
k=1011) (1/s)
+    real(8) :: cldo_tmp, cldn_tmp
+    real(8) :: tau_cld_regenerate
+
+    integer ixndrop, l
+    integer, parameter :: psat=6 ! number of supersaturations to calc ccn 
concentration
+    real(8)  :: supersat(psat)= & ! supersaturation (%) to determine ccn 
concentration
+         (/0.02,0.05,0.1,0.2,0.5,1.0/)
+    real(8) ccn(1,1011,psat)        ! number conc of aerosols activated at 
supersat
+    character(len=8), dimension(psat) :: ccn_name(psat)= &
+         (/'CCN1','CCN2','CCN3','CCN4','CCN5','CCN6'/)
+    real(8) arg
+    integer phase ! phase of aerosol
+
+
+
+    arg = 1.0_8
+    zero=0._8
+
+
+    pi = 4._8*atan(1.0_8)
+    dtinv=1./dtmicro
+
+    depvel(:,:) = 0.0_8        ! droplet number is done in pkg_cld_sediment, 
aerosols in mz_aerosols_intr
+
+    overall_main_i_loop: &
+         do i=1,ncol
+
+    surfratemax = 0.0_8
+    nsav=1
+    nnew=2
+    surfrate(ixndrop)=depvel(i,ixndrop)/dz(i,1011)
+    surfratemax = max( surfratemax, surfrate(ixndrop) )
+    tau_cld_regenerate = 3600.0_8 * 3.0_8 
+
+    grow_shrink_main_k_loop: &
+         do k=1,1011
+    km1=max0(k-1,1)
+    kp1=min0(k+1,1011)
+
+    cldo_tmp = cldo(i,k)
+    cldn_tmp = cldn(i,k) * exp( -dtmicro/tau_cld_regenerate )
+    cldo_tmp = cldn_tmp
+    cldn_tmp = cldn(i,k)
+
+    if(cldn_tmp-cldo_tmp.gt.0.01)then
+       wbar=wtke_cen(i,k)
+       wmix=0._8
+       wmin=0._8
+       wmax=10._8
+       wdiab=0
+
+       phase=1 ! interstitial
+       do m=1,1011
+          call loadaer(raer,qqcw,i,i,k,m,cs,npv(m),phase, &
+               na, va,  hy )
+          naermod(m)=na(i)
+          vaerosol(m)=va(i)
+          hygro(m)=hy(i)
+       end do
+       dumc=(cldn_tmp-cldo_tmp)
+    endif
+
+ enddo grow_shrink_main_k_loop
+
+ ntemp=nsav
+ nsav=nnew
+ nnew=ntemp
+ dtmin=dtmicro
+ ekk(0)=0.0
+ ekk(1011)=0.0
+ do k=1,1011
+    km1=max0(k-1,1)
+    ekkp(k)=zn(k)*ekk(k)*zs(k)
+    ekkm(k)=zn(k)*ekk(k-1)*zs(km1)
+    tinv=ekkp(k)+ekkm(k)
+
+    if(k.eq.1011)tinv=tinv+surfratemax
+    if(k.eq.1011)tinv=tinv+taumix_internal_1011_inv
+
+    if(tinv.gt.1.e-6)then
+       dtt=1./tinv
+       dtmin=min(dtmin,dtt)
+    endif
+ enddo
+ dtmix=0.9*dtmin
+ nsubmix=dtmicro/dtmix+1
+ if(nsubmix>100)then
+    nsubmix_bnd=100
+ else
+    nsubmix_bnd=nsubmix
+ endif
+ count_submix(nsubmix_bnd)=count_submix(nsubmix_bnd)+1
+ dtmix=dtmicro/nsubmix
+ fac_srflx = -1.0/(zn(1011)*nsubmix)
+
+
+ !          call t_stopf ('nsubmix')
+
+enddo overall_main_i_loop
+! end of main loop over i/longitude ....................................
+
+
+call ccncalc(lchnk,ncol,temp,cs,raer,qqcw,ccn,psat,supersat,alogsig,npv)
+return
+end subroutine dropmixnuc
+end module ndrop
diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
index a6cf0a5546c..29c03c246d4 100644
--- a/gcc/tree-vect-loop.cc
+++ b/gcc/tree-vect-loop.cc
@@ -8505,7 +8505,8 @@ vect_transform_reduction (loop_vec_info loop_vinfo,
     {
       gcc_assert (code == IFN_COND_ADD || code == IFN_COND_SUB
                  || code == IFN_COND_MUL || code == IFN_COND_AND
-                 || code == IFN_COND_IOR || code == IFN_COND_XOR);
+                 || code == IFN_COND_IOR || code == IFN_COND_XOR
+                 || code == IFN_COND_MIN || code == IFN_COND_MAX);
       gcc_assert (op.num_ops == 4
                  && (op.ops[reduc_index]
                      == op.ops[internal_fn_else_index ((internal_fn) code)]));
-- 
2.31.1

Reply via email to