aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/pr47383.c31
-rw-r--r--gcc/tree-ssa-address.c23
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;
}