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

Reply via email to