On Fri, Dec 06, 2013 at 12:30:54PM +0400, Konstantin Vladimirov wrote: > Consider code: > > int foo(char *t, char *v, int w) > { > int i; > > for (i = 1; i != w; ++i) > { > int x = i << 2; > v[x + 4] = t[x + 4]; > } > > return 0; > } This is either job of ivopts pass, dunno why it doesn't consider turning those memory accesses to TARGET_MEM_REF with the *4 multiplication in there, or combiner (which is limited to single use though, so if you do say v[x + 4] = t[i]; int he loop instead, it will for -m32 put use the (...,4) addressing, but as you have two uses, it doesn't do it). As others said, the question is if using the more complex addressing more than once is actually beneficial or not. Anyway, while on this testcase, I wonder why VRP doesn't derive ranges here. <bb 3>: # RANGE [-2147483648, 2147483647] NONZERO 0x000000000fffffffc x_5 = i_1 << 2; # RANGE ~[2147483648, 18446744071562067967] NONZERO 0x0fffffffffffffffc _6 = (sizetype) x_5; # RANGE ~[2147483652, 18446744071562067971] NONZERO 0x0fffffffffffffffc _7 = _6 + 4; # PT = nonlocal _9 = v_8(D) + _7; # PT = nonlocal _11 = t_10(D) + _7; _12 = *_11; *_9 = _12; i_14 = i_1 + 1; <bb 4>: # i_1 = PHI <1(2), i_14(3)> if (i_1 != w_4(D)) goto <bb 3>; else goto <bb 5>; As i is signed integer with undefined overflow, and the loop starts with 1 and it is always only incremented, can't we derive # RANGE [1, 2147483647] # i_1 = PHI <1(2), i_14(3)> and similarly for i_14? We likely can't derive similar range for x_5 because at least in C++ it isn't undefined behavior if it shits into negative (or is it?), but at least with x = i * 4; instead we could. Jakub