diff options
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr47383.c | 31 | ||||
-rw-r--r-- | gcc/tree-ssa-address.c | 23 |
4 files changed, 55 insertions, 10 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 15e99e4..ab16711 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2011-07-06 H.J. Lu <hongjiu.lu@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-06 Richard Guenther <rguenther@suse.de> * tree.c (build_common_tree_nodes_2): Merge with diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e71617f..99d804e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-07-06 H.J. Lu <hongjiu.lu@intel.com> + + PR middle-end/47383 + * gcc.dg/pr47383.c: New. + 2011-07-06 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> PR tree-optimization/49647 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; } |