Use pointer_mode for address computation.
authorH.J. Lu <hongjiu.lu@intel.com>
Wed, 6 Jul 2011 13:19:04 +0000 (13:19 +0000)
committerH.J. Lu <hjl@gcc.gnu.org>
Wed, 6 Jul 2011 13:19:04 +0000 (06:19 -0700)
gcc/

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.

gcc/testsuite/

2011-07-06  H.J. Lu  <hongjiu.lu@intel.com>

PR middle-end/47383
* gcc.dg/pr47383.c: New.

From-SVN: r175912

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr47383.c [new file with mode: 0644]
gcc/tree-ssa-address.c

index 15e99e4fbeb9f561f34e41642f1c429c039f44cc..ab167113bcdf31a734eede51915147fd43f762c5 100644 (file)
@@ -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
index e71617fd7669d8b7cdc036de9b40194a50862377..99d804e118ec9f93a0c13510f9dcb67ce7a47361 100644 (file)
@@ -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 (file)
index 0000000..3e2b9ba
--- /dev/null
@@ -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;
+}
index e3934e15506c1fc1f534f7eafaf0e0d4b62f6054..c6dced114b7ae932a92167bce7c1caad9b8f6b1a 100644 (file)
@@ -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;
 }