This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Improve things for PR71724, in combine/if_then_else_cond


The PR is about infinite recursion in combine_simplify_rtx, because if_then_else_cond does strange things to an expression, and we end up simplifying something to itself. The patch below tries to address this by improving that function a little. As stated in the PR, the situation is that we have

(plus:SI (if_then_else:SI (eq (reg:CC 185)
            (const_int 0 [0]))
        (reg:SI 165)
        (reg:SI 174 [ t9.0_1+4 ]))
    (reg:SI 165))

Reg 165 is known to be zero or one, so it gets turned into a condition, and we have two different conditions on the operands. That causes us to fail to make the fairly obvious transformation to

 cond = reg:CC 185
 true_rtx = (plus r165 r165)
 false_rtx = (plus r174 r165)

So, when looking for situations where we have only one condition, we can try to undo the conversion of a plain REG into a condition, on the grounds that this is probably less helpful.

This seems to cure the testcase, but Segher also has a patch in the PR that looks like a good and more direct approach. IMO both should be applied. This one was bootstrapped and tested on x86_64-linux. Ok?


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

Index: gcc/combine.c
===================================================================
--- gcc/combine.c	(revision 244528)
+++ gcc/combine.c	(working copy)
@@ -9044,11 +9044,31 @@ if_then_else_cond (rtx x, rtx *ptrue, rt
      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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]