https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85563
Jeffrey A. Law <law at redhat dot com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |law at redhat dot com Target Milestone|8.4 |11.0 --- Comment #17 from Jeffrey A. Law <law at redhat dot com> --- What an interesting little bug. I was briefly worried that GCC was introducing the false positive. But we can see the uninit use still in the IL just before the __builtin_unreachable is removed by VRP1. ;; basic block 2, loop depth 0, count 118111600 (estimated locally), maybe hot ;; prev block 0, next block 3, flags: (NEW, REACHABLE, VISITED) ;; pred: ENTRY [always] count:118111600 (estimated locally) (FALLTHRU,EXECUTABLE) Vframe_list.0_1 = Vframe_list; a.1_12 = (long int) Vframe_list.0_1; _10 = (unsigned int) a.1_12; _8 = _10 & 7; if (_8 != 3) goto <bb 3>; [0.00%] else goto <bb 4>; [100.00%] ;; succ: 3 [never] count:0 (precise) (TRUE_VALUE,EXECUTABLE) ;; 4 [always] count:118111600 (estimated locally) (FALSE_VALUE,EXECUTABLE) ;; basic block 3, loop depth 0, count 0 (precise), probably never executed ;; prev block 2, next block 4, flags: (NEW, REACHABLE, VISITED) ;; pred: 2 [never] count:0 (precise) (TRUE_VALUE,EXECUTABLE) __builtin_unreachable (); ;; succ: ;; basic block 4, loop depth 1, count 1073741824 (estimated locally), maybe hot ;; prev block 3, next block 5, flags: (NEW, REACHABLE, VISITED) ;; pred: 5 [always] count:955630225 (estimated locally) (FALLTHRU,DFS_BACK,EXECUTABLE) ;; 2 [always] count:118111600 (estimated locally) (FALSE_VALUE,EXECUTABLE) # frame1_2 = PHI <frame1_11(5), frame1_7(D)(2)> # tail_3 = PHI <tail_13(5), Vframe_list.0_1(2)> a.1_14 = (long int) tail_3; _15 = (unsigned int) a.1_14; _16 = _15 & 7; if (_16 == 3) goto <bb 5>; [89.00%] else goto <bb 6>; [11.00%] ;; succ: 5 [89.0% (guessed)] count:955630224 (estimated locally) (TRUE_VALUE,EXECUTABLE) ;; 6 [11.0% (guessed)] count:118111600 (estimated locally) (FALSE_VALUE,EXECUTABLE) ;; basic block 5, loop depth 1, count 955630225 (estimated locally), maybe hot ;; prev block 4, next block 6, flags: (NEW, REACHABLE, VISITED) ;; pred: 4 [89.0% (guessed)] count:955630224 (estimated locally) (TRUE_VALUE,EXECUTABLE) _17 = tail_3 + 18446744073709551613; _18 = __builtin_assume_aligned (_17, 8); frame1_11 = _18->u.s.car; tail_13 = _18->u.s.u.cdr; goto <bb 4>; [100.00%] ;; succ: 4 [always] count:955630225 (estimated locally) (FALLTHRU,DFS_BACK,EXECUTABLE) ;; basic block 6, loop depth 0, count 118111600 (estimated locally), maybe hot ;; prev block 5, next block 1, flags: (NEW, REACHABLE, VISITED) ;; pred: 4 [11.0% (guessed)] count:118111600 (estimated locally) (FALSE_VALUE,EXECUTABLE) do_switch_frame (frame1_2); return; ;; succ: EXIT [always] count:118111600 (estimated locally) (EXECUTABLE) If we take 2->4->6, then we'd end up using an uninitialized value. Of course the path 2->4->6 is can never actually be traversed. But we'd have to realize that _16 and _8 are equivalent and that _8 can never have the value 3. VRP doesn't figure that out. DOM would if the __builtin_unreachable were left in the IL a bit longer. Deferring removal of the __builtin_unreachable looks like it'd be fairly painful since marking of the edges as unexecutable happens deep in the dominator walker. And we also have no idea how much fallout there'd be as a result. Teaching VRP to track the equivalences that would be necessary to mimick DOM's ability seems like a huge step in the wrong direction and nontrivial. I don't really see a path forward right now.