/* { dg-do compile { target { { { i?86-*-* x86_64-*-* } && lp64 } || { arm_thumb2 } } } } */ /* { dg-options "-O2 -fdump-rtl-pro_and_epilogue" } */ /* Our new threader is threading things a bit too early, and causing the testcase in gcc.dg/shrink-wrap-loop.c to fail. The gist is this BB inside a loop: : # p_2 = PHI if (p_2 != 0B) goto ; [INV] else goto ; [INV] Our threader can move this check outside of the loop (good). This is done before branch probabilities are calculated and causes the probs to be calculated as: [local count: 216361238]: if (p2_6(D) != 0B) goto ; [54.59%] else goto ; [45.41%] Logically this seems correct to me. A simple check outside of a loop should slightly but not overwhelmingly favor a non-zero value. Interestingly however, the old threader couldn't get this, but the IL ended up identical, albeit with different probabilities. What happens is that, because the old code could not thread this, the p2 != 0 check would remain inside the loop and probs would be calculated thusly: [local count: 1073741824]: # p_2 = PHI if (p_2 != 0B) goto ; [94.50%] else goto ; [5.50%] Then when the loop header copying pass ("ch") shuffled things around, the IL would end up identical to my early threader code, but with the probabilities would remain as 94.5/5.5. The above discrepancy causes the RTL ifcvt pass to generate different code, and by the time we get to the shrink wrapping pass, things look sufficiently different such that the legacy code can actually shrink wrap, whereas our new code does not. IMO, if the loop-ch pass moves conditionals outside of a loop, the probabilities should be adjusted, but that does mean the shrink wrap won't happen for this contrived testcase. */ int foo (int *p1, int *p2); int test (int *p1, int *p2) { int *p; for (p = p2; p != 0; p++) { if (!foo (p, p1)) return 0; } return 1; } /* { dg-final { scan-rtl-dump "Performing shrink-wrapping" "pro_and_epilogue" { xfail *-*-* } } } */