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.) Thanks, Jiri Hruska
mem-ref-maxsize-with-index.patch
Description: Binary data
/* x86: gcc -O1 -m32 testcase.c */ #include <stdio.h> __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; static int ret(int v) { asm(""); /* Force no inlining */ return v; } int main(void) { int i = 0; do { int x = ret(*(&fooS + i)); int y = ret(*(&fooS + i)); if (x != y) return 1; i++; } while(*(&fooS + i)); return 0; }