On Mon, Jun 18, 2012 at 9:51 PM, Jiří Hruška <ji...@fud.cz> wrote: > Hi all, > > I have tracked down a bug which results in invalid code being > generated for indexed TARGET_MEM_REF expressions during dominator > optimization. > > The conditions are: accessing objects adjacent in memory in a loop (in > order to generate the TARGET_MEM_REF gimple) and optimizing this tree > item during dom optimization (to trigger folding). There might be > another set of conditions which get to the same state through a > different > > The problem is that get_ref_base_and_extent() for TARGET_MEM_REF with > variable index sets `maxsize' to -1 to signal that "via index or > index2, the whole object can be reached" and returns. But before that, > if the target object is a declaration with known size and `maxsize' is > -1, it is updated, which can be taken by the caller (if `maxsize' > equals to basic `size') as possibility to fold the expression into a > constant. > > Assuming I understood the code and comments right, the solution is > then to really take a quick exit in the abovementioned "indexed" case > instead of just breaking the loop and letting the rest of function > change the `maxsize' parameter. > > A quick search did not reveal any existing ticket for this problem. > The bug was originally found in GCC 4.6.1 while compiling x86 code > under MinGW, which is what the attached simplified testcase is based > upon (compilation with -O1 is OK, anything higher fails). > GCC 3.4.6 seems unaffected. > Also the relevant code parts seem unchanged in current trunk. > Patched build of 4.7.1 survived bootstrap on x86_64-rhel fine. > > The attached patch and all changes provided therein are released to > public domain and can be freely used or modified by anyone. > > (This is my first time dealing with GCC bowels, please excuse my > superficial understanding of everything I have written above.)
The issue is that your testcase is invalid. __attribute__((section(".rodata$int0"))) const int fooS = 0; __attribute__((section(".rodata$int1"))) const int foo1 = 1; __attribute__((section(".rodata$int2"))) const int foo2 = 2; __attribute__((section(".rodata$int3"))) const int foo3 = 3; __attribute__((section(".rodata$int4"))) const int fooE = 0; ... int x = ret(*(&fooS + i)); this access is only ever valid for i == 0 as otherwise you are creating a pointer that points outside of the object fooS. Richard. > Thanks, > Jiri Hruska