http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39612
--- Comment #13 from Richard Guenther <rguenth at gcc dot gnu.org> 2012-01-17 10:01:04 UTC --- (In reply to comment #12) > (In reply to comment #11) > > Re-confirmed on trunk with the testcase in comment #4 and -Os: > > > > > ./cc1 -quiet t.c -Os -Wall -fdump-tree-all > > t.c: In function 'f2': > > t.c:4:11: warning: 'inter[0]' is used uninitialized in this function > > [-Wuninitialized] > > t.c:4:11: warning: 'inter[1]' is used uninitialized in this function > > [-Wuninitialized] > > > > There is also a store data-race introduced by LIM when the loop header > > is not copied. I suppose the real fix is to disable SM if the loop > > header is not copied. > > I do not think this is the right way. Disabling a valid (and fairly > important) > optimization in order to silence a warning seems a bit extreme. I am not sure > what you mean by "a store data-race". > > Also, the warning is at least morally right. If R <= 1, the original code > will > pass inter to foo uninitialized, which probably is not intended. So, the > right > thing to do could be issuing "may be used uninitialized" warning instead of > "is > used uninitialized" one. Yes, but the point is that without the loop header copy we insert the loads and stores from/to inter in a path that is executed even when R <= 1 and thus the loop is not executed at all, and we warn about the inserted loads - not about the final one. Modified testcase: void foo (int *); void f2 (int R) { int i, inter[3]; for (i = 1; i < R; i++) { inter[0] = 1; inter[1] = 1; inter[2] = 1; } foo (inter); } For the store data-race consider int inter[3]; void f2 (int R) { int i; for (i = 1; i < R; i++) { inter[0] = 1; inter[1] = 1; inter[2] = 1; } } where inter is protected by a mutex, but only if R > 1. We still insert loads/stores on paths that are executed when the loop is not entered: f2 (int R) { int inter_I_lsm.5; int inter_I_lsm.4; int inter_I_lsm.3; int i; <bb 2>: inter_I_lsm.3_10 = inter[0]; inter_I_lsm.4_11 = inter[1]; inter_I_lsm.5_12 = inter[2]; goto <bb 4>; <bb 3>: inter_I_lsm.3_13 = 1; inter_I_lsm.4_14 = 1; inter_I_lsm.5_15 = 1; i_4 = i_1 + 1; <bb 4>: # i_1 = PHI <1(2), i_4(3)> # inter_I_lsm.3_9 = PHI <inter_I_lsm.3_10(2), inter_I_lsm.3_13(3)> # inter_I_lsm.4_8 = PHI <inter_I_lsm.4_11(2), inter_I_lsm.4_14(3)> # inter_I_lsm.5_7 = PHI <inter_I_lsm.5_12(2), inter_I_lsm.5_15(3)> if (i_1 < R_3(D)) goto <bb 3>; else goto <bb 5>; <bb 5>: # inter_I_lsm.5_19 = PHI <inter_I_lsm.5_7(4)> # inter_I_lsm.4_20 = PHI <inter_I_lsm.4_8(4)> # inter_I_lsm.3_21 = PHI <inter_I_lsm.3_9(4)> inter[0] = inter_I_lsm.3_21; inter[1] = inter_I_lsm.4_20; inter[2] = inter_I_lsm.5_19; return; } The issue is mitigated by loop-header copying because we there have a suitable insertion place that is only executed when the loop body is executed (we seem to cater for not inserting possibly trapping insns that way but do not consider data-races possible for global memory).