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...