On Tue, Jul 5, 2011 at 7:07 PM, H.J. Lu <hjl.to...@gmail.com> wrote: > On Tue, Jul 5, 2011 at 8:24 AM, Richard Guenther > <richard.guent...@gmail.com> wrote: >> On Tue, Jul 5, 2011 at 4:56 PM, Ulrich Weigand <uweig...@de.ibm.com> wrote: >>> H.J. Lu wrote: >>> >>>> > However, this still seems odd to me, as I had understood the address in >>>> > a TARGET_MEM_REF needs to be an *address*, i.e. use address_mode. =A0If >>>> > this is not true (has changed?) a lot of other places would need to >>>> > change as well ... >>>> >>>> I was told that TARGET_MEM_REF needs ptr_mode. >>> >>> Can you elaborate? We are talking about the mode returned from >>> addr_for_mem_ref here. I do now understand how this can be anything >>> but an address mode: >> >> That is an address mode, but the intermediate computation >> (base + index * step + offset) is done in pointer mode. The >> code currently performs this in address mode as well which is >> bogus. Which is why I suggested to use pointer mode for the >> computation (now, with the other target hook you mention) and >> then convert the result to address mode. >> > > I am testing this [patch. OK for trunk if there are no regressions?
Ok. Thanks, Richard. > Thanks. > > -- > H.J. > --- > diff --git a/gcc/ChangeLog.x32 b/gcc/ChangeLog.x32 > index c5edfe7..7d85746 100644 > --- a/gcc/ChangeLog.x32 > +++ b/gcc/ChangeLog.x32 > @@ -1,5 +1,11 @@ > 2011-07-05 H.J. Lu <hongjiu...@intel.com> > > + PR middle-end/47383 > + * tree-ssa-address.c (addr_for_mem_ref): Use pointer_mode for > + address computation and convert to address_mode if needed. > + > +2011-07-05 H.J. Lu <hongjiu...@intel.com> > + > * tree-ssa-address.c (addr_for_mem_ref): Use > targetm.addr_space.address_mode. > > diff --git a/gcc/testsuite/ChangeLog.x32 b/gcc/testsuite/ChangeLog.x32 > index cde8d41..492be5c 100644 > --- a/gcc/testsuite/ChangeLog.x32 > +++ b/gcc/testsuite/ChangeLog.x32 > @@ -1,3 +1,8 @@ > +2011-07-05 H.J. Lu <hongjiu...@intel.com> > + > + PR middle-end/47383 > + * gcc.dg/pr47383.c: New. > + > 2011-06-23 H.J. Lu <hongjiu...@intel.com> > > * gcc.target/i386/pr49504.c (main): Check correct return value. > diff --git a/gcc/testsuite/gcc.dg/pr47383.c b/gcc/testsuite/gcc.dg/pr47383.c > new file mode 100644 > index 0000000..3e2b9ba > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/pr47383.c > @@ -0,0 +1,31 @@ > +/* { dg-do run { target fpic } } */ > +/* { dg-options "-O2 -fPIC" } */ > + > +static int heap[2*(256 +1+29)+1]; > +static int heap_len; > +static int heap_max; > +void > +__attribute__ ((noinline)) > +foo (int elems) > +{ > + int n, m; > + int max_code = -1; > + int node = elems; > + heap_len = 0, heap_max = (2*(256 +1+29)+1); > + for (n = 0; n < elems; n++) > + heap[++heap_len] = max_code = n; > + do { > + n = heap[1]; > + heap[1] = heap[heap_len--]; > + m = heap[1]; > + heap[--heap_max] = n; > + heap[--heap_max] = m; > + } while (heap_len >= 2); > +} > + > +int > +main () > +{ > + foo (286); > + return 0; > +} > diff --git a/gcc/tree-ssa-address.c b/gcc/tree-ssa-address.c > index e3934e1..c6dced1 100644 > --- a/gcc/tree-ssa-address.c > +++ b/gcc/tree-ssa-address.c > @@ -189,11 +189,12 @@ addr_for_mem_ref (struct mem_address *addr, > addr_space_t as, > bool really_expand) > { > enum machine_mode address_mode = targetm.addr_space.address_mode (as); > + enum machine_mode pointer_mode = targetm.addr_space.pointer_mode (as); > rtx address, sym, bse, idx, st, off; > struct mem_addr_template *templ; > > if (addr->step && !integer_onep (addr->step)) > - st = immed_double_int_const (tree_to_double_int (addr->step), > address_mode); > + st = immed_double_int_const (tree_to_double_int (addr->step), > pointer_mode); > else > st = NULL_RTX; > > @@ -201,7 +202,7 @@ addr_for_mem_ref (struct mem_address *addr, addr_space_t > as, > off = immed_double_int_const > (double_int_sext (tree_to_double_int (addr->offset), > TYPE_PRECISION (TREE_TYPE (addr->offset))), > - address_mode); > + pointer_mode); > else > off = NULL_RTX; > > @@ -220,16 +221,16 @@ addr_for_mem_ref (struct mem_address *addr, > addr_space_t as, > if (!templ->ref) > { > sym = (addr->symbol ? > - gen_rtx_SYMBOL_REF (address_mode, ggc_strdup ("test_symbol")) > + gen_rtx_SYMBOL_REF (pointer_mode, ggc_strdup ("test_symbol")) > : NULL_RTX); > bse = (addr->base ? > - gen_raw_REG (address_mode, LAST_VIRTUAL_REGISTER + 1) > + gen_raw_REG (pointer_mode, LAST_VIRTUAL_REGISTER + 1) > : NULL_RTX); > idx = (addr->index ? > - gen_raw_REG (address_mode, LAST_VIRTUAL_REGISTER + 2) > + gen_raw_REG (pointer_mode, LAST_VIRTUAL_REGISTER + 2) > : NULL_RTX); > > - gen_addr_rtx (address_mode, sym, bse, idx, > + gen_addr_rtx (pointer_mode, sym, bse, idx, > st? const0_rtx : NULL_RTX, > off? const0_rtx : NULL_RTX, > &templ->ref, > @@ -247,16 +248,18 @@ addr_for_mem_ref (struct mem_address *addr, > addr_space_t as, > > /* Otherwise really expand the expressions. */ > sym = (addr->symbol > - ? expand_expr (addr->symbol, NULL_RTX, address_mode, EXPAND_NORMAL) > + ? expand_expr (addr->symbol, NULL_RTX, pointer_mode, EXPAND_NORMAL) > : NULL_RTX); > bse = (addr->base > - ? expand_expr (addr->base, NULL_RTX, address_mode, EXPAND_NORMAL) > + ? expand_expr (addr->base, NULL_RTX, pointer_mode, EXPAND_NORMAL) > : NULL_RTX); > idx = (addr->index > - ? expand_expr (addr->index, NULL_RTX, address_mode, EXPAND_NORMAL) > + ? expand_expr (addr->index, NULL_RTX, pointer_mode, EXPAND_NORMAL) > : NULL_RTX); > > - gen_addr_rtx (address_mode, sym, bse, idx, st, off, &address, NULL, NULL); > + gen_addr_rtx (pointer_mode, sym, bse, idx, st, off, &address, NULL, NULL); > + if (pointer_mode != address_mode) > + address = convert_memory_address (address_mode, address); > return address; > } >