On Thu, 22 Mar 2018, Tom de Vries wrote: > Hi, > > This fixes a 6/7/8 regression, a P3 ICE in the tail-merge pass. > > > Consider the test-case from the patch. > > When compiling at -O2, duplicates are found in tail-merge: > ... > find_duplicates: <bb 6> duplicate of <bb 7> > find_duplicates: <bb 6> duplicate of <bb 9> > ... > So, tail-merge calls replace_block_by (bb7, bb6). > > However, bb7 has an abnormal edge bb5 -> bb7 as predecessor (bb6 has an > abnormal edge as predecessor as well, but that doesn't look necessary to > trigger the ICE): > ... > ;; basic block 9, loop depth 0 > ;; prev block 3, next block 4, flags: (NEW, REACHABLE) > ;; pred: 3 [50.0% (guessed)] (FALSE_VALUE,EXECUTABLE) > goto <bb 8>; [100.00%] > ;; succ: 8 [always] (FALLTHRU,EXECUTABLE) > > ;; basic block 6, loop depth 0 > ;; prev block 5, next block 7, flags: (NEW, REACHABLE, VISITED) > ;; pred: 5 [33.3% (guessed)] (ABNORMAL,EXECUTABLE) > goto <bb 8>; [100.00%] > ;; succ: 8 [always] (FALLTHRU,EXECUTABLE) > > ;; basic block 7, loop depth 0 > ;; prev block 6, next block 8, flags: (NEW, REACHABLE, VISITED) > ;; pred: 5 [33.3% (guessed)] (ABNORMAL,EXECUTABLE) > ;; succ: 8 [always] (FALLTHRU,EXECUTABLE) > ... > > So when replace_block_by calls redirect_edge_and_branch (bb5 -> bb7, bb6) it > lands in gimple_redirect_edge_and_branch, and fails here: > ... > 6024 if (e->flags & EDGE_ABNORMAL) > 6025 return NULL; > ... > > which causes this assert to trigger: > ... > gcc_assert (pred_edge != NULL); > ... > > > The patch fixes the ICE conservatively by skipping bbs with > bb_has_abnormal_preds in find_clusters_1. > > [ A more optimal fix could be to detect in this example that there's an > abnormal edge bb5 -> bb6, and skip redirecting bb5 -> bb7 to bb6. ] > > Bootstrapped and reg-tested on x86_64. > > OK for stage4, gcc-6-branch and gcc-7-branch?
OK everywhere. Thanks, Richard.