https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71724

--- Comment #4 from Bernd Schmidt <bernds at gcc dot gnu.org> ---
Maybe we just need to test for that condition, even though it's ugly. However,
I think there are some other improvements we could make here.

Part of the problem seems to be what if_then_else_cond does on this rtx:

(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)

I'm testing the following, which tries to undo such transformation of plain REG
if that seems it'll enable other transformations which are more likely to be
beneficial. It makes the crash go away.

Index: combine.c
===================================================================
--- combine.c   (revision 242958)
+++ combine.c   (working copy)
@@ -9031,11 +9031,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

Reply via email to