http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50419
Bug #: 50419 Summary: Bad interaction between data-ref and disambiguation with restrict pointers Classification: Unclassified Product: gcc Version: 4.7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization AssignedTo: unassig...@gcc.gnu.org ReportedBy: m...@gcc.gnu.org % cat predcom-fail.c #define INFTY 987654321 #define Ra /*__restrict*/ #define Rv __restrict void P7Viterbi(int * Ra _dc, int * Ra _mc, int * Ra _tpdd, int * Ra _tpmd, int M) { int i,k; int sc; int * Rv dc = _dc; int * Rv mc = _mc; int * Rv tpdd = _tpdd; int * Rv tpmd = _tpmd; dc[0] = -INFTY; for (k = 1; k < M; k++) { dc[k] = dc[k-1] + tpdd[k-1]; if ((sc = mc[k-1] + tpmd[k-1]) > dc[k]) dc[k] = sc; if (dc[k] < -INFTY) dc[k] = -INFTY; } } ./cc1 -Ofast predcom-fail.c should be able to predcom the loop. It doesn't because it doesn't see that the (first) dc[] write doesn't conflict with the mc/tpmd[] reads. It should be able to see that because all the int pointers are created with new restrict sets. If you defined Ra as also __restrict (making the arguments already restrict qualified) you get the transformation. The problem is an interaction between creating the datarefs and the disambiguator. The data-ref base objects contain the casted inputs: #(Data Ref: # bb: 4 # stmt: D.2741_19 = *D.2740_18; # ref: *D.2740_18; # base_object: *(int * restrict) _dc_2(D); # Access function 0: {0B, +, 4}_1 #) vs #(Data Ref: # bb: 4 # stmt: D.2743_24 = *D.2742_23; # ref: *D.2742_23; # base_object: *(int * restrict) _tpdd_6(D); # Access function 0: {0B, +, 4}_1 #) The disambiguator used is ptr_derefs_may_alias_p on those two (casted) pointers. But the first thing it does is to remove all conversions. Remembering the original type wouldn't help as we need to look into the points-to info of the restrict qualified object (i.e. the LHS of that conversion). Hence when creating the data-ref we shouldn't look through such casts, that introduce useful information. I have a patch.