https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85301
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jakub at gcc dot gnu.org --- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Maybe uninit just doesn't understand that in: <bb 2> [local count: 1073741825]: _1 = BIT_FIELD_REF <tick_nohz_idle_exit_ts, 8, 0>; _2 = _1 & 3; if (_2 != 0) goto <bb 3>; [33.00%] else goto <bb 7>; [67.00%] <bb 7> [local count: 719407025]: goto <bb 4>; [100.00%] <bb 3> [local count: 354334802]: now_11 = ktime_get (); pretmp_14 = BIT_FIELD_REF <tick_nohz_idle_exit_ts, 8, 0>; <bb 4> [local count: 1073741825]: # now_5 = PHI <now_11(3), now_9(D)(7)> # prephitmp_15 = PHI <pretmp_14(3), _1(7)> _4 = prephitmp_15 & 1; if (_4 != 0) goto <bb 5>; [33.00%] else goto <bb 8>; [67.00%] <bb 8> [local count: 719407025]: goto <bb 6>; [100.00%] <bb 5> [local count: 354334802]: __tick_nohz_idle_restart_tick (now_5); [tail call] <bb 6> [local count: 1073741825]: return; if (_1 & 3) != 0 it implies (_1 & 1) != 0. Though, if I change the testcase to: void tick_nohz_idle_exit(void) { long now; struct tick_sched t = tick_nohz_idle_exit_ts; if (t.idle_active || t.tick_stopped) now = ktime_get(); if (t.tick_stopped) __tick_nohz_idle_restart_tick(now); } so that it doesn't have to reread tick_nohz_idle_exit_ts.tick_stopped after the ktime_get call, it doesn't warn anymore. In that case now is always initialized though, so it shouldn't matter what value we read for the uninit warning.