]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Fix PR94043 by making vect_live_op generate lc-phi
authorKewen Lin <linkw@linux.ibm.com>
Wed, 1 Apr 2020 03:48:46 +0000 (22:48 -0500)
committerKewen Lin <linkw@linux.ibm.com>
Fri, 17 Apr 2020 07:51:11 +0000 (02:51 -0500)
As PR94043 shows, my commit r10-4524 exposed one issue in
vectorizable_live_operation, which inserts one extra BB
before the single exit, leading unexpected operand expansion
and unexpected loop depth assertion.  As Richi suggested,
this patch is to teach vectorizable_live_operation to
generate loop closed phi for vec_lhs, it looks like:
     loop;
     # lhs' = PHI <lhs>
=>
     loop;
     # vec_lhs' = PHI <vec_lhs>
     new_tree = BIT_FIELD_REF <vec_lhs', ...>;
     lhs' = new_tree;

I noticed that there are some SLP cases that have same lhs
and vec_lhs but different offsets, which can make us have
more PHIs for the same vec_lhs there.  But I think it would
be fine since only one of them is actually live, the others
should be eliminated by the following dce.  So the patch
doesn't check whether there is one phi for vec_lhs, just
create one directly instead.

Bootstrapped/regtested on powerpc64le-linux-gnu (LE) P8.

Backport from mainline.

  2020-04-01  Kewen Lin  <linkw@gcc.gnu.org>

  gcc/ChangeLog

      PR tree-optimization/94043
      * tree-vect-loop.c (vectorizable_live_operation): Generate loop-closed
      phi for vec_lhs and use it for lane extraction.

  gcc/testsuite/ChangeLog

      PR tree-optimization/94043
      * gfortran.dg/graphite/vect-pr94043.f90: New test.

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/graphite/vect-pr94043.f90 [new file with mode: 0644]
gcc/tree-vect-loop.c

index a7949385573b63473bd2238be34aecdd2d4b31eb..79c7e50f44bfd7feea481c5d03783d997eae33ff 100644 (file)
@@ -1,3 +1,12 @@
+2020-04-17  Kewen Lin  <linkw@gcc.gnu.org>
+
+       Backport from mainline
+       2020-04-01  Kewen Lin  <linkw@gcc.gnu.org>
+
+       PR tree-optimization/94043
+       * tree-vect-loop.c (vectorizable_live_operation): Generate loop-closed
+       phi for vec_lhs and use it for lane extraction.
+
 2020-04-16  Michael Meissner  <meissner@linux.ibm.com>
 
        PR target/94557
index 30ac5f5522efd36d0f69a0321c80276080b3cab9..09443adbbd8a3a0b01914317755546d21959b52d 100644 (file)
@@ -1,3 +1,11 @@
+2020-04-17  Kewen Lin  <linkw@gcc.gnu.org>
+
+       Backport from mainline
+       2020-04-01  Kewen Lin  <linkw@gcc.gnu.org>
+
+       PR tree-optimization/94043
+       * gfortran.dg/graphite/vect-pr94043.f90: New test.
+
 2020-04-16  Richard Biener  <rguenther@suse.de>
 
        Backport from mainline
diff --git a/gcc/testsuite/gfortran.dg/graphite/vect-pr94043.f90 b/gcc/testsuite/gfortran.dg/graphite/vect-pr94043.f90
new file mode 100644 (file)
index 0000000..744c0f3
--- /dev/null
@@ -0,0 +1,18 @@
+! { dg-do compile }
+! { dg-additional-options "-O3 -ftree-parallelize-loops=2 -fno-tree-dce" }
+
+! As PR94043, test it to be compiled successfully without ICE.
+
+program yw
+      integer :: hx(6, 6)
+      integer :: ps = 1, e2 = 1
+
+      do ps = 1, 6
+        do e2 = 1, 6
+            hx(e2, ps) = 0
+            if (ps >= 5 .and. e2 >= 5) then
+                hx(e2, ps) = hx(1, 1)
+            end if
+        end do
+      end do
+end program
index 0308b26b808eee18a1d4192326ea9cbce033bcc5..67bdd2e3fc60727e3a5b7782e834fbfa2485c04f 100644 (file)
@@ -7942,6 +7942,25 @@ vectorizable_live_operation (stmt_vec_info stmt_info,
       bitstart = int_const_binop (MINUS_EXPR, vec_bitsize, bitsize);
     }
 
+  /* Ensure the VEC_LHS for lane extraction stmts satisfy loop-closed PHI
+     requirement, insert one phi node for it.  It looks like:
+        loop;
+       BB:
+        # lhs' = PHI <lhs>
+     ==>
+        loop;
+       BB:
+        # vec_lhs' = PHI <vec_lhs>
+        new_tree = lane_extract <vec_lhs', ...>;
+        lhs' = new_tree;  */
+
+  basic_block exit_bb = single_exit (loop)->dest;
+  gcc_assert (single_pred_p (exit_bb));
+
+  tree vec_lhs_phi = copy_ssa_name (vec_lhs);
+  gimple *phi = create_phi_node (vec_lhs_phi, exit_bb);
+  SET_PHI_ARG_DEF (phi, single_exit (loop)->dest_idx, vec_lhs);
+
   gimple_seq stmts = NULL;
   tree new_tree;
   if (LOOP_VINFO_FULLY_MASKED_P (loop_vinfo))
@@ -7954,10 +7973,10 @@ vectorizable_live_operation (stmt_vec_info stmt_info,
         the loop mask for the final iteration.  */
       gcc_assert (ncopies == 1 && !slp_node);
       tree scalar_type = TREE_TYPE (STMT_VINFO_VECTYPE (stmt_info));
-      tree mask = vect_get_loop_mask (gsi, &LOOP_VINFO_MASKS (loop_vinfo),
-                                     1, vectype, 0);
-      tree scalar_res = gimple_build (&stmts, CFN_EXTRACT_LAST,
-                                     scalar_type, mask, vec_lhs);
+      tree mask = vect_get_loop_mask (gsi, &LOOP_VINFO_MASKS (loop_vinfo), 1,
+                                     vectype, 0);
+      tree scalar_res = gimple_build (&stmts, CFN_EXTRACT_LAST, scalar_type,
+                                     mask, vec_lhs_phi);
 
       /* Convert the extracted vector element to the required scalar type.  */
       new_tree = gimple_convert (&stmts, lhs_type, scalar_res);
@@ -7967,13 +7986,32 @@ vectorizable_live_operation (stmt_vec_info stmt_info,
       tree bftype = TREE_TYPE (vectype);
       if (VECTOR_BOOLEAN_TYPE_P (vectype))
        bftype = build_nonstandard_integer_type (tree_to_uhwi (bitsize), 1);
-      new_tree = build3 (BIT_FIELD_REF, bftype, vec_lhs, bitsize, bitstart);
+      new_tree = build3 (BIT_FIELD_REF, bftype, vec_lhs_phi, bitsize, bitstart);
       new_tree = force_gimple_operand (fold_convert (lhs_type, new_tree),
                                       &stmts, true, NULL_TREE);
     }
 
   if (stmts)
-    gsi_insert_seq_on_edge_immediate (single_exit (loop), stmts);
+    {
+      gimple_stmt_iterator exit_gsi = gsi_after_labels (exit_bb);
+      gsi_insert_before (&exit_gsi, stmts, GSI_CONTINUE_LINKING);
+
+      /* Remove existing phi from lhs and create one copy from new_tree.  */
+      tree lhs_phi = NULL_TREE;
+      gimple_stmt_iterator gsi;
+      for (gsi = gsi_start_phis (exit_bb); !gsi_end_p (gsi); gsi_next (&gsi))
+       {
+         gimple *phi = gsi_stmt (gsi);
+         if ((gimple_phi_arg_def (phi, 0) == lhs))
+           {
+             remove_phi_node (&gsi, false);
+             lhs_phi = gimple_phi_result (phi);
+             gimple *copy = gimple_build_assign (lhs_phi, new_tree);
+             gsi_insert_after (&exit_gsi, copy, GSI_CONTINUE_LINKING);
+             break;
+           }
+       }
+    }
 
   /* Replace use of lhs with newly computed result.  If the use stmt is a
      single arg PHI, just replace all uses of PHI result.  It's necessary