diff mbox

PING: PATCH [9/n]: Prepare x32: PR middle-end/47383: ivopts miscompiles Pmode != ptr_mode

Message ID CAMe9rOp-ch9PrqjyXNdnHYG2aJ8pc+HjuKGpkOxR3b=8Zx9MQQ@mail.gmail.com
State New
Headers show

Commit Message

H.J. Lu July 5, 2011, 5:07 p.m. UTC
On Tue, Jul 5, 2011 at 8:24 AM, Richard Guenther
<richard.guenther@gmail.com> wrote:
> On Tue, Jul 5, 2011 at 4:56 PM, Ulrich Weigand <uweigand@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?

Thanks.

Comments

Richard Biener July 6, 2011, 8:26 a.m. UTC | #1
On Tue, Jul 5, 2011 at 7:07 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Tue, Jul 5, 2011 at 8:24 AM, Richard Guenther
> <richard.guenther@gmail.com> wrote:
>> On Tue, Jul 5, 2011 at 4:56 PM, Ulrich Weigand <uweigand@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.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-05  H.J. Lu  <hongjiu.lu@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.lu@intel.com>
> +
> +       PR middle-end/47383
> +       * gcc.dg/pr47383.c: New.
> +
>  2011-06-23  H.J. Lu  <hongjiu.lu@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;
>  }
>
diff mbox

Patch

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.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-05  H.J. Lu  <hongjiu.lu@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.lu@intel.com>
+
+	PR middle-end/47383
+	* gcc.dg/pr47383.c: New.
+
 2011-06-23  H.J. Lu  <hongjiu.lu@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);