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