re PR rtl-optimization/71724 (ICE: Segmentation fault, deep recursion between combine...
authorBernd Schmidt <bernds@redhat.com>
Mon, 23 Jan 2017 16:30:55 +0000 (16:30 +0000)
committerBernd Schmidt <bernds@gcc.gnu.org>
Mon, 23 Jan 2017 16:30:55 +0000 (16:30 +0000)
PR rtl-optimization/71724
* combine.c (if_then_else_cond): Look for situations where it is
beneficial to undo the work of one of the recursive calls.

From-SVN: r244817

gcc/ChangeLog
gcc/combine.c

index 35694c29b99518e7808634257f434634faba9e5e..320298fefcc946d85377c709a5f98afa1504e3af 100644 (file)
@@ -5,6 +5,10 @@
        (TARGET_MAX_NOCE_IFCVT_SEQ_COST): Define.
        * ifcvt.c (noce_try_cmove): Add missing cost check.
 
+       PR rtl-optimization/71724
+       * combine.c (if_then_else_cond): Look for situations where it is
+       beneficial to undo the work of one of the recursive calls.
+
 2017-01-23  Bin Cheng  <bin.cheng@arm.com>
 
        PR tree-optimization/70754
index 28133ff3ba9cbd6e9ff9ab3e543876daa25c36d5..c643a0eb28fef30ae44158e0fe43def8c95040b1 100644 (file)
@@ -9044,11 +9044,31 @@ if_then_else_cond (rtx x, rtx *ptrue, rtx *pfalse)
      the same value, compute the new true and false values.  */
   else if (BINARY_P (x))
     {
-      cond0 = if_then_else_cond (XEXP (x, 0), &true0, &false0);
-      cond1 = if_then_else_cond (XEXP (x, 1), &true1, &false1);
+      rtx op0 = XEXP (x, 0);
+      rtx op1 = XEXP (x, 1);
+      cond0 = if_then_else_cond (op0, &true0, &false0);
+      cond1 = if_then_else_cond (op1, &true1, &false1);
+
+      if ((cond0 != 0 && cond1 != 0 && !rtx_equal_p (cond0, cond1))
+         && (REG_P (op0) || REG_P (op1)))
+       {
+         /* Try to enable a simplification by undoing work done by
+            if_then_else_cond if it converted a REG into something more
+            complex.  */
+         if (REG_P (op0))
+           {
+             cond0 = 0;
+             true0 = false0 = op0;
+           }
+         else
+           {
+             cond1 = 0;
+             true1 = false1 = op1;
+           }
+       }
 
       if ((cond0 != 0 || cond1 != 0)
-         && ! (cond0 != 0 && cond1 != 0 && ! rtx_equal_p (cond0, cond1)))
+         && ! (cond0 != 0 && cond1 != 0 && !rtx_equal_p (cond0, cond1)))
        {
          /* If if_then_else_cond returned zero, then true/false are the
             same rtl.  We must copy one of them to prevent invalid rtl