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

Attachment: 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;
}

Reply via email to