On Fri, Apr 22, 2016 at 11:47 AM, Richard Biener
<richard.guent...@gmail.com> wrote:
> On Fri, Apr 22, 2016 at 12:33 PM, Bin.Cheng <amker.ch...@gmail.com> wrote:
>> On Fri, Apr 22, 2016 at 11:25 AM, Richard Biener
>> <richard.guent...@gmail.com> wrote:
>>> On Fri, Apr 22, 2016 at 12:07 PM, Bin Cheng <bin.ch...@arm.com> wrote:
>>>> Hi,
>>>> Tree if-conv has below code checking on virtual PHI nodes in 
>>>> if_convertible__phi_p:
>>>>
>>>>   if (any_mask_load_store)
>>>>     return true;
>>>>
>>>>   /* When there were no if-convertible stores, check
>>>>      that there are no memory writes in the branches of the loop to be
>>>>      if-converted.  */
>>>>   if (virtual_operand_p (gimple_phi_result (phi)))
>>>>     {
>>>>       imm_use_iterator imm_iter;
>>>>       use_operand_p use_p;
>>>>
>>>>       if (bb != loop->header)
>>>>         {
>>>>           if (dump_file && (dump_flags & TDF_DETAILS))
>>>>             fprintf (dump_file, "Virtual phi not on loop->header.\n");
>>>>           return false;
>>>>         }
>>>>
>>>>       FOR_EACH_IMM_USE_FAST (use_p, imm_iter, gimple_phi_result (phi))
>>>>         {
>>>>           if (gimple_code (USE_STMT (use_p)) == GIMPLE_PHI
>>>>               && USE_STMT (use_p) != phi)
>>>>             {
>>>>               if (dump_file && (dump_flags & TDF_DETAILS))
>>>>                 fprintf (dump_file, "Difficult to handle this virtual 
>>>> phi.\n");
>>>>               return false;
>>>>             }
>>>>         }
>>>>     }
>>>>
>>>> After investigation, I think it's to bypass code in the form of:
>>>>
>>>> <bb header>
>>>>   .MEM_2232 = PHI <.MEM_574(179), .MEM_1247(183)>     // <----PHI_1
>>>>   ...
>>>>   if (cond)
>>>>     goto <bb 1>
>>>>   else
>>>>     goto <bb2>
>>>>
>>>> <bb 1>:  //empty
>>>> <bb2>:
>>>>   .MEM_1247 = PHI <.MEM_2232(180), .MEM_2232(181)>     // <----PHI_2
>>>>   if (cond2)
>>>>     goto <bb exit>
>>>>   else
>>>>     goto <bb latch>
>>>>
>>>> <bb latch>:
>>>>   goto <bb header>
>>>>
>>>> Here PHI_2 can be degenerated and deleted.  Furthermore, after propagating 
>>>> .MEM_2232 to .MEM_1247's uses, PHI_1 can also be degenerated and deleted 
>>>> in this case.  These cases are bypassed because tree if-conv doesn't 
>>>> handle virtual PHI nodes during loop conversion (it only predicates scalar 
>>>> PHI nodes).  Of course this results in loops not converted, and not 
>>>> vectorized.
>>>> This patch firstly deletes the aforementioned checking code, then adds 
>>>> code handling such virtual PHIs during conversion.  The use of 
>>>> `any_mask_load_store' now is less ambiguous with this change, which allows 
>>>> further cleanups and patches fixing PR56541.
>>>> BTW, I think the newly fix at PR70725 on PHI nodes with only one argument 
>>>> is a special case covered by this change too.  Unfortunately I can't use 
>>>> replace_uses_by because I need to handle PHIs at use point after replacing 
>>>> too.  This doesn't really matter since we only care about virtual PHI, 
>>>> it's not possible to be used by anything other than IR itself.
>>>> Bootstrap and test on x86_64 and AArch64, is it OK if no regressions?
>>>
>>> Doesn't this undo my fix for degenerate non-virtual PHIs?
>> No, since we already support degenerate non-virtual PHIs in
>> predicate_scalar_phi, your fix is also for virtual PHIs handling.
>
> Was it?  I don't remember ;)  I think it was for a non-virtual PHI.
> Anyway, you should
> see the PR70725 testcase fail again if not.
>
>>>
>>> I believe we can just drop virtual PHIs and rely on
>>>
>>>   if (any_mask_load_store)
>>>     {
>>>       mark_virtual_operands_for_renaming (cfun);
>>>       todo |= TODO_update_ssa_only_virtuals;
>>>     }
>>>
>>> re-creating them from scratch.  To do better than that we'd simply
>> I tried this, simply enable above code for all cases can't resolve
>> verify_ssa issue.  I haven't look into the details, looks like ssa
>> def-use chain is corrupted in if-conversion if we don't process it
>> explicitly.  Maybe it's possible along with your below suggestions,
>> but we need to handle uses outside of loop too.
>
> Yes.  I don't like all the new code to deal with virtual PHIs when doing
> it correctly would also avoid the above virtual SSA update ...
>
> After all the above seems to work for the case of if-converted stores
> (which is where virtual PHIs appear as well, even not degenerate).
> So I don't see exactly how it would break in the other case.  I suppose
> you may need to call mark_virtual_phi_result_for_renaming () on
> all virtual PHIs.
>
Hi Richard,
Here is the updated patch.  It also fixes PR70771 & PR70775. Root
cause for the ICE is in the fix to PR70725 because it forgot to
release single-argument PHI nodes after replacing uses.  In
combine_blocks, these PHIs are removed from basic block but are still
live in IR.  As a result, the ssa def/use chain for these PHIs are in
broken state, thus ICE is triggered whenever ssa use list is
accessed..
In this updated patch, I made below change to update virtual ssa
unconditionally.  With this change, we don't need to handle virtual
PHIs explicitly, and single-argument PHI related code in fix to
PR70725 can also be removed.

@@ -2808,11 +2758,8 @@ tree_if_conversion (struct loop *loop)
     }

   todo |= TODO_cleanup_cfg;
-  if (any_mask_load_store)
-    {
-      mark_virtual_operands_for_renaming (cfun);
-      todo |= TODO_update_ssa_only_virtuals;
-    }
+  mark_virtual_operands_for_renaming (cfun);
+  todo |= TODO_update_ssa_only_virtuals;

  cleanup:
   if (ifc_bbs)


BTW, it may be possible to only update affected PHIs using
mark_virtual_phi_result_for_renaming.  This patch didn't do that since
the update is done once per function anyway.
Bootstrap and test on x86_64, is it OK?

Thanks,
bin

2016-04-25  Bin Cheng  <bin.ch...@arm.com>

    PR tree-optimization/70771
    PR tree-optimization/70775
    * tree-if-conv.c (if_convertible_phi_p): Remove check on special
    virtual PHI nodes.  Delete parameter.
    (if_convertible_loop_p_1): Delete argument to above function.
    (predicate_all_scalar_phis): Delete code handling single-argument
    PHIs.
    (tree_if_conversion): Mark and update virtual SSA.

gcc/testsuite/ChangeLog
2016-04-25  Bin Cheng  <bin.ch...@arm.com>

    PR tree-optimization/70771
    PR tree-optimization/70775
    * gcc.dg/pr70771.c: New test.
    * gcc.dg/pr70771.c: New test.
Index: gcc/testsuite/gcc.dg/pr70771.c
===================================================================
--- gcc/testsuite/gcc.dg/pr70771.c      (revision 0)
+++ gcc/testsuite/gcc.dg/pr70771.c      (working copy)
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+
+int a, b, c, d;
+
+static void
+fn1 ()
+{
+  for (b = 0; b < 1; b++)
+    for (c = 0; c < 1; c++)
+      {
+       if (a)
+         break;
+       b = 1;
+      }
+  for (;;)
+    ;
+}
+
+int
+main ()
+{
+  if (d)
+    fn1 ();
+  return 0;
+}
Index: gcc/testsuite/gcc.dg/pr70775.c
===================================================================
--- gcc/testsuite/gcc.dg/pr70775.c      (revision 0)
+++ gcc/testsuite/gcc.dg/pr70775.c      (working copy)
@@ -0,0 +1,34 @@
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+
+struct S
+{
+  int f1;
+  int f2;
+} a;
+
+int b, c, d, e;
+short f;
+
+int
+fn1 (int p1, unsigned p2)
+{
+  return p1 + p2;
+}
+
+void
+fn2 ()
+{
+  struct S g;
+  int h;
+  for (; c; c++)
+    for (f = -3; f < 3; f = fn1 (f, 8))
+      {
+        a.f1 = e;
+        if (b)
+          a = g;
+        else
+          for (; h; h++)
+            d = b;
+      }
+}
Index: gcc/tree-if-conv.c
===================================================================
--- gcc/tree-if-conv.c  (revision 235371)
+++ gcc/tree-if-conv.c  (working copy)
@@ -640,16 +640,11 @@ phi_convertible_by_degenerating_args (gphi *phi)
    PHI is not if-convertible if:
    - it has more than 2 arguments.
 
-   When we didn't see if-convertible stores, PHI is not
-   if-convertible if:
-   - a virtual PHI is immediately used in another PHI node,
-   - there is a virtual PHI in a BB other than the loop->header.
    When the aggressive_if_conv is set, PHI can have more than
    two arguments.  */
 
 static bool
-if_convertible_phi_p (struct loop *loop, basic_block bb, gphi *phi,
-                     bool any_mask_load_store)
+if_convertible_phi_p (struct loop *loop, basic_block bb, gphi *phi)
 {
   if (dump_file && (dump_flags & TDF_DETAILS))
     {
@@ -669,36 +664,6 @@ static bool
         }
     }
 
-  if (any_mask_load_store)
-    return true;
-
-  /* When there were no if-convertible stores, check
-     that there are no memory writes in the branches of the loop to be
-     if-converted.  */
-  if (virtual_operand_p (gimple_phi_result (phi)))
-    {
-      imm_use_iterator imm_iter;
-      use_operand_p use_p;
-
-      if (bb != loop->header)
-       {
-         if (dump_file && (dump_flags & TDF_DETAILS))
-           fprintf (dump_file, "Virtual phi not on loop->header.\n");
-         return false;
-       }
-
-      FOR_EACH_IMM_USE_FAST (use_p, imm_iter, gimple_phi_result (phi))
-       {
-         if (gimple_code (USE_STMT (use_p)) == GIMPLE_PHI
-             && USE_STMT (use_p) != phi)
-           {
-             if (dump_file && (dump_flags & TDF_DETAILS))
-               fprintf (dump_file, "Difficult to handle this virtual phi.\n");
-             return false;
-           }
-       }
-    }
-
   return true;
 }
 
@@ -1405,8 +1370,7 @@ if_convertible_loop_p_1 (struct loop *loop,
       gphi_iterator itr;
 
       for (itr = gsi_start_phis (bb); !gsi_end_p (itr); gsi_next (&itr))
-       if (!if_convertible_phi_p (loop, bb, itr.phi (),
-                                  *any_mask_load_store))
+       if (!if_convertible_phi_p (loop, bb, itr.phi ()))
          return false;
     }
 
@@ -1915,28 +1879,14 @@ predicate_all_scalar_phis (struct loop *loop)
       if (gsi_end_p (phi_gsi))
        continue;
 
-      if (EDGE_COUNT (bb->preds) == 1)
+      gsi = gsi_after_labels (bb);
+      while (!gsi_end_p (phi_gsi))
        {
-         /* Propagate degenerate PHIs.  */
-         for (phi_gsi = gsi_start_phis (bb); !gsi_end_p (phi_gsi);
-              gsi_next (&phi_gsi))
-           {
-             gphi *phi = phi_gsi.phi ();
-             replace_uses_by (gimple_phi_result (phi),
-                              gimple_phi_arg_def (phi, 0));
-           }
+         phi = phi_gsi.phi ();
+         predicate_scalar_phi (phi, &gsi);
+         release_phi_node (phi);
+         gsi_next (&phi_gsi);
        }
-      else
-       {
-         gsi = gsi_after_labels (bb);
-         while (!gsi_end_p (phi_gsi))
-           {
-             phi = phi_gsi.phi ();
-             predicate_scalar_phi (phi, &gsi);
-             release_phi_node (phi);
-             gsi_next (&phi_gsi);
-           }
-       }
 
       set_phi_nodes (bb, NULL);
     }
@@ -2808,11 +2758,8 @@ tree_if_conversion (struct loop *loop)
     }
 
   todo |= TODO_cleanup_cfg;
-  if (any_mask_load_store)
-    {
-      mark_virtual_operands_for_renaming (cfun);
-      todo |= TODO_update_ssa_only_virtuals;
-    }
+  mark_virtual_operands_for_renaming (cfun);
+  todo |= TODO_update_ssa_only_virtuals;
 
  cleanup:
   if (ifc_bbs)

Reply via email to