Hi!

doloop_condition_get computes cmp in several places, and in one of them
wants to fail if the condition inside of it isn't NE against const0_rtx.
The problem with that is that nothing checked what cmp is yet,
  /* Check for (set (pc) (if_then_else (condition)
                                       (label_ref (label))
                                       (pc))).  */
  if (GET_CODE (cmp) != SET
      || SET_DEST (cmp) != pc_rtx
      || GET_CODE (SET_SRC (cmp)) != IF_THEN_ELSE
      || GET_CODE (XEXP (SET_SRC (cmp), 1)) != LABEL_REF
      || XEXP (SET_SRC (cmp), 2) != pc_rtx)
    return 0;           
is checked only a couple of lines later.

To fix this, either we can use the following patch which guards the
early check with the necessary subset of the later check, or we could
for
      if (GET_CODE (cmp) != SET || GET_CODE (SET_SRC (cmp)) != IF_THEN_ELSE)
        return 0;
before cond = XEXP (SET_SRC (cmp), 0);,
or set some bool flag and only verify this requirement if the bool flag
is true after the later check.

Any preferences?  The following has been successfully bootstrapped/regtested
on powerpc64le-linux.

2017-03-21  Jakub Jelinek  <ja...@redhat.com>

        PR rtl-optimization/80112
        * loop-doloop.c (doloop_condition_get): Don't check condition
        if cmp isn't SET with IF_THEN_ELSE src.

        * gcc.dg/pr80112.c: New test.

--- gcc/loop-doloop.c.jj        2017-01-16 22:34:03.000000000 +0100
+++ gcc/loop-doloop.c   2017-03-21 11:57:58.000000000 +0100
@@ -153,10 +153,13 @@ doloop_condition_get (rtx_insn *doloop_p
        }
       else
         inc = PATTERN (prev_insn);
-      /* We expect the condition to be of the form (reg != 0)  */
-      cond = XEXP (SET_SRC (cmp), 0);
-      if (GET_CODE (cond) != NE || XEXP (cond, 1) != const0_rtx)
-        return 0;
+      if (GET_CODE (cmp) == SET && GET_CODE (SET_SRC (cmp)) == IF_THEN_ELSE)
+       {
+         /* We expect the condition to be of the form (reg != 0)  */
+         cond = XEXP (SET_SRC (cmp), 0);
+         if (GET_CODE (cond) != NE || XEXP (cond, 1) != const0_rtx)
+           return 0;
+       }
     }
   else
     {
--- gcc/testsuite/gcc.dg/pr80112.c.jj   2017-03-21 12:12:23.382509916 +0100
+++ gcc/testsuite/gcc.dg/pr80112.c      2017-03-21 12:11:18.000000000 +0100
@@ -0,0 +1,21 @@
+/* PR rtl-optimization/80112 */
+/* { dg-do compile } */
+/* { dg-options "-Os -fmodulo-sched" } */
+
+void **a;
+
+void
+foo (int c)
+{
+  void *d[] = {&&e, &&f};
+  a = d;
+  switch (c)
+    {
+    f:
+      c = 9;
+      /* FALLTHRU */
+    case 9:
+      goto *a++;
+    e:;
+    }
+}

        Jakub

Reply via email to