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.