https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118613
--- Comment #3 from anlauf at gcc dot gnu.org --- Adding a second temporary reduces the evaluation count for the rank-1 case further: diff --git a/gcc/fortran/trans-intrinsic.cc b/gcc/fortran/trans-intrinsic.cc index afbec5b2752..0cdc886a715 100644 --- a/gcc/fortran/trans-intrinsic.cc +++ b/gcc/fortran/trans-intrinsic.cc @@ -6710,6 +6710,7 @@ gfc_conv_intrinsic_minmaxval (gfc_se * se, gfc_expr * expr, enum tree_code op) gfc_copy_loopinfo_to_se (&arrayse, &loop); arrayse.ss = arrayss; gfc_conv_expr_val (&arrayse, arrayexpr); + arrayse.expr = gfc_evaluate_now (arrayse.expr, &arrayse.pre); gfc_add_block_to_block (&block, &arrayse.pre); gfc_init_block (&block2); @@ -6816,6 +6817,7 @@ gfc_conv_intrinsic_minmaxval (gfc_se * se, gfc_expr * expr, enum tree_code op) gfc_copy_loopinfo_to_se (&arrayse, &loop); arrayse.ss = arrayss; gfc_conv_expr_val (&arrayse, arrayexpr); + arrayse.expr = gfc_evaluate_now (arrayse.expr, &arrayse.pre); gfc_add_block_to_block (&block, &arrayse.pre); /* MIN_EXPR/MAX_EXPR has unspecified behavior with NaNs or This gives: 4 0 4 0 5 0.00000000 4 0.00000000 5 0.00000000 4 0.00000000 The remaining superfluous evaluation seems to be a bug in the algorithm as described in trans-intrinsic.cc: 2) Array mask is used and NaNs need to be supported, rank 1: limit = Infinity; nonempty = false; S = from; while (S <= to) { if (mask[S]) { nonempty = true; if (a[S] <= limit) goto lab; } S++; } limit = nonempty ? NaN : huge (limit); lab: while (S <= to) { if(mask[S]) limit = min (a[S], limit); S++; } 3) NaNs need to be supported, but it is known at compile time or cheaply at runtime whether array is nonempty or not, rank 1: limit = Infinity; S = from; while (S <= to) { if (a[S] <= limit) goto lab; S++; } limit = (from <= to) ? NaN : huge (limit); lab: while (S <= to) { limit = min (a[S], limit); S++; } We should increment S either after the comparison in the first while-loop, or increment it directly after the label lab.