https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88579
--- Comment #1 from Harald Anlauf <anlauf at gmx dot de> ---
OK, here's my proof-of-concept patch (not cleaned up):
Index: gcc/fortran/trans-expr.c
===================================================================
--- gcc/fortran/trans-expr.c (revision 267353)
+++ gcc/fortran/trans-expr.c (working copy)
@@ -3068,7 +3068,8 @@
se->expr = build_int_cst (TREE_TYPE (lse.expr), 1);
return;
}
- else if (v == 2 || v == 4 || v == 8 || v == 16)
+ // else if (v == 2 || v == 4 || v == 8 || v == 16)
+ else if (v > 1 && ((v & (v-1)) == 0))
{
/* 2**n = 1<<n, 4**n = 1<<(n+n), 8**n = 1 <<(3*n), 16**n =
1<<(4*n), but we have to make sure to return zero if the
@@ -3089,6 +3090,15 @@
shift = fold_build2_loc (input_location, PLUS_EXPR,
TREE_TYPE (rse.expr),
rse.expr, rse.expr);
+ else if (v >= 8)
+ {
+ int e = wi::popcount (v-1);
+ shift = fold_build2_loc (input_location, MULT_EXPR,
+ TREE_TYPE (rse.expr),
+ build_int_cst (TREE_TYPE (rse.expr), e),
+ rse.expr);
+ }
+#if 0
else if (v == 8)
shift = fold_build2_loc (input_location, MULT_EXPR,
TREE_TYPE (rse.expr),
@@ -3099,6 +3109,7 @@
TREE_TYPE (rse.expr),
build_int_cst (TREE_TYPE (rse.expr), 4),
rse.expr);
+#endif
else
gcc_unreachable ();
Running
make check-fortran RUNTESTFLAGS='dg.exp=power*.f90'
passes cleanly, but for some reason my setup always wants to run the
libgomp tests...