diff mbox

PATCH: PR middle-end/47383: ivopts miscompiles Pmode != ptr_mode

Message ID AANLkTinOnxSrPYxNn1EUvhQPb-6_pnSdMi+PKC4GRqp_@mail.gmail.com
State New
Headers show

Commit Message

H.J. Lu Feb. 12, 2011, 5:27 p.m. UTC
On Wed, Feb 9, 2011 at 1:17 PM, Richard Guenther
<richard.guenther@gmail.com> wrote:
> On Wed, Feb 9, 2011 at 9:45 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
>> On Wed, Feb 9, 2011 at 12:17 PM, Richard Guenther
>> <richard.guenther@gmail.com> wrote:
>>> On Wed, Feb 9, 2011 at 6:17 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
>>>> On Wed, Feb 9, 2011 at 2:04 AM, Richard Guenther
>>>> <richard.guenther@gmail.com> wrote:
>>>>> On Wed, Feb 9, 2011 at 12:08 AM, H.J. Lu <hongjiu.lu@intel.com> wrote:
>>>>>> Hi,
>>>>>>
>>>>>> tree-ssa-loop-ivopts.c has
>>>>>>
>>>>>> ---
>>>>>> /* Returns variant of TYPE that can be used as base for different uses.
>>>>>>   We return unsigned type with the same precision, which avoids problems
>>>>>>   with overflows.  */
>>>>>>
>>>>>> static tree
>>>>>> generic_type_for (tree type)
>>>>>> {
>>>>>>  if (POINTER_TYPE_P (type))
>>>>>>    return unsigned_type_for (type);
>>>>>>
>>>>>>  if (TYPE_UNSIGNED (type))
>>>>>>    return type;
>>>>>>
>>>>>>  return unsigned_type_for (type);
>>>>>> }
>>>>>> ---
>>>>>>
>>>>>> It converts negative step to unsigned type with the same precision.
>>>>>> It doesn't work when Pmode != ptr_mode.  This patch disables it.
>>>>>> OK for trunk in stage 1?
>>>>>
>>>>> This does not look correct.  It rather sounds you are expanding
>>>>> TARGET_MEM_REFs the wrong way - the address computed by
>>>>> it is supposed to be calculated in ptr_mode and only the final
>>>>> result extended to Pmode.
>>>>>
>>>>
>>>>
>>>> TARGET_MEM_REF is OK. The problem is ivopts passes
>>>> the negative offset to TARGET_MEM_REF as unsigned and
>>>> expects offset will wrap.
>>>
>>> But they will wrap, as arithmetic is carried out in a type with
>>> the same precision (that of ptr_mode).
>>>
>>>>  It only works when Pmode ==
>>>> ptr_mode.  I am checking in this patch into x32 branch to
>>>> avoid such cases.
>>>
>>> I think you are wrong.
>>>
>>
>> If you have a patch, I can give a try.
>
> I'd have to debug it and I don't have a target that shows the failure, but
> just looking around I assume that in
>
> rtx
> 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);
>
> address_mode will be Pmode - that would be already wrong.  We need to
> use ptr_mode here and at the end of the function convert the
> generated address to Pmode appropriately.  Can you verify that theory?
>

This patch works for me.  However, if I add


@@ -201,7 +201,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);
+	     ptr_mode);
   else
     off = NULL_RTX;

@@ -220,16 +220,16 @@ addr_for_mem_ref (struct mem_address *addr, addr_space_t a
s,
       if (!templ->ref)
 	{
 	  sym = (addr->symbol ?
-		 gen_rtx_SYMBOL_REF (address_mode, ggc_strdup ("test_symbol"))
+		 gen_rtx_SYMBOL_REF (ptr_mode, ggc_strdup ("test_symbol"))
 		 : NULL_RTX);
 	  bse = (addr->base ?
-		 gen_raw_REG (address_mode, LAST_VIRTUAL_REGISTER + 1)
+		 gen_raw_REG (ptr_mode, LAST_VIRTUAL_REGISTER + 1)
 		 : NULL_RTX);
 	  idx = (addr->index ?
-		 gen_raw_REG (address_mode, LAST_VIRTUAL_REGISTER + 2)
+		 gen_raw_REG (ptr_mode, LAST_VIRTUAL_REGISTER + 2)
 		 : NULL_RTX);

-	  gen_addr_rtx (address_mode, sym, bse, idx,
+	  gen_addr_rtx (ptr_mode, sym, bse, idx,
 			st? const0_rtx : NULL_RTX,
 			off? const0_rtx : NULL_RTX,
 			&templ->ref,
@@ -247,16 +247,16 @@ addr_for_mem_ref (struct mem_address *addr, addr_space_t a
s,

   /* Otherwise really expand the expressions.  */
   sym = (addr->symbol
-	 ? expand_expr (addr->symbol, NULL_RTX, address_mode, EXPAND_NORMAL)
+	 ? expand_expr (addr->symbol, NULL_RTX, ptr_mode, EXPAND_NORMAL)
 	 : NULL_RTX);
   bse = (addr->base
-	 ? expand_expr (addr->base, NULL_RTX, address_mode, EXPAND_NORMAL)
+	 ? expand_expr (addr->base, NULL_RTX, ptr_mode, EXPAND_NORMAL)
 	 : NULL_RTX);
   idx = (addr->index
-	 ? expand_expr (addr->index, NULL_RTX, address_mode, EXPAND_NORMAL)
+	 ? expand_expr (addr->index, NULL_RTX, ptr_mode, EXPAND_NORMAL)
 	 : NULL_RTX);

-  gen_addr_rtx (address_mode, sym, bse, idx, st, off, &address, NULL, NULL);
+  gen_addr_rtx (ptr_mode, sym, bse, idx, st, off, &address, NULL, NULL);
   return address;
 }

Comments

Richard Biener Feb. 13, 2011, 9:42 a.m. UTC | #1
On Sat, Feb 12, 2011 at 6:27 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Wed, Feb 9, 2011 at 1:17 PM, Richard Guenther
> <richard.guenther@gmail.com> wrote:
>> On Wed, Feb 9, 2011 at 9:45 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
>>> On Wed, Feb 9, 2011 at 12:17 PM, Richard Guenther
>>> <richard.guenther@gmail.com> wrote:
>>>> On Wed, Feb 9, 2011 at 6:17 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
>>>>> On Wed, Feb 9, 2011 at 2:04 AM, Richard Guenther
>>>>> <richard.guenther@gmail.com> wrote:
>>>>>> On Wed, Feb 9, 2011 at 12:08 AM, H.J. Lu <hongjiu.lu@intel.com> wrote:
>>>>>>> Hi,
>>>>>>>
>>>>>>> tree-ssa-loop-ivopts.c has
>>>>>>>
>>>>>>> ---
>>>>>>> /* Returns variant of TYPE that can be used as base for different uses.
>>>>>>>   We return unsigned type with the same precision, which avoids problems
>>>>>>>   with overflows.  */
>>>>>>>
>>>>>>> static tree
>>>>>>> generic_type_for (tree type)
>>>>>>> {
>>>>>>>  if (POINTER_TYPE_P (type))
>>>>>>>    return unsigned_type_for (type);
>>>>>>>
>>>>>>>  if (TYPE_UNSIGNED (type))
>>>>>>>    return type;
>>>>>>>
>>>>>>>  return unsigned_type_for (type);
>>>>>>> }
>>>>>>> ---
>>>>>>>
>>>>>>> It converts negative step to unsigned type with the same precision.
>>>>>>> It doesn't work when Pmode != ptr_mode.  This patch disables it.
>>>>>>> OK for trunk in stage 1?
>>>>>>
>>>>>> This does not look correct.  It rather sounds you are expanding
>>>>>> TARGET_MEM_REFs the wrong way - the address computed by
>>>>>> it is supposed to be calculated in ptr_mode and only the final
>>>>>> result extended to Pmode.
>>>>>>
>>>>>
>>>>>
>>>>> TARGET_MEM_REF is OK. The problem is ivopts passes
>>>>> the negative offset to TARGET_MEM_REF as unsigned and
>>>>> expects offset will wrap.
>>>>
>>>> But they will wrap, as arithmetic is carried out in a type with
>>>> the same precision (that of ptr_mode).
>>>>
>>>>>  It only works when Pmode ==
>>>>> ptr_mode.  I am checking in this patch into x32 branch to
>>>>> avoid such cases.
>>>>
>>>> I think you are wrong.
>>>>
>>>
>>> If you have a patch, I can give a try.
>>
>> I'd have to debug it and I don't have a target that shows the failure, but
>> just looking around I assume that in
>>
>> rtx
>> 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);
>>
>> address_mode will be Pmode - that would be already wrong.  We need to
>> use ptr_mode here and at the end of the function convert the
>> generated address to Pmode appropriately.  Can you verify that theory?
>>
>
> This patch works for me.  However, if I add
>
> diff --git a/gcc/tree-ssa-address.c b/gcc/tree-ssa-address.c
> index 7b7e169..d9d906e 100644
> --- a/gcc/tree-ssa-address.c
> +++ b/gcc/tree-ssa-address.c
> @@ -242,6 +242,9 @@ addr_for_mem_ref (struct mem_address *addr, addr_space_t as,
>       if (off)
>   *templ->off_p = off;
>
> +      if (targetm.addr_space.address_mode (as) != ptr_mode)
> +  templ->ref = convert_to_mode (targetm.addr_space.address_mode (as),
> +                 templ->ref, 1);
>       return templ->ref;
>     }
>
> to convert MEM_REF from ptr_mode to Pmode, I get
>
> /export/build/gnu/gcc-x32/build-x86_64-linux/gcc/xgcc
> -B/export/build/gnu/gcc-x32/build-x86_64-linux/gcc/ -S -o x.s -mx32
> -O2 -g -fPIC    x.i
> x.i: In function \u2018foo\u2019:
> x.i:21:1: error: insn outside basic block
> (insn 88 0 113 (parallel [
>            (set (reg:SI 143)
>                (ashift:SI (reg:SI 60)
>                    (const_int 3 [0x3])))
>            (clobber (reg:CC 17 flags))
>        ]) -1
>     (nil))
> x.i:21:1: internal compiler error: in rtl_verify_flow_info, at cfgrtl.c:2218
> Please submit a full bug report,
> with preprocessed source if appropriate.
> See <http://gcc.gnu.org/bugs.html> for instructions.
> make: *** [x.s] Error 1
>
> Do I really need to convert MEM_REF from ptr_mode to Pmode?

Only if you do not plan to support 32bit addresses in the backend.
The above is probably
because the caller context from where that function is called isn't
prepared to have
instructions emitted (maybe it's called from the cost analysis pieces as well?)

Richard.

> Thanks.
>
> --
> H.J.
> ---
> diff --git a/gcc/tree-ssa-address.c b/gcc/tree-ssa-address.c
> index a9ca835..7b7e169 100644
> --- a/gcc/tree-ssa-address.c
> +++ b/gcc/tree-ssa-address.c
> @@ -188,12 +188,12 @@ rtx
>  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);
>   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),
> +                                ptr_mode);
>   else
>     st = NULL_RTX;
>
> @@ -201,7 +201,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);
> +            ptr_mode);
>   else
>     off = NULL_RTX;
>
> @@ -220,16 +220,16 @@ addr_for_mem_ref (struct mem_address *addr, addr_space_t a
> s,
>       if (!templ->ref)
>        {
>          sym = (addr->symbol ?
> -                gen_rtx_SYMBOL_REF (address_mode, ggc_strdup ("test_symbol"))
> +                gen_rtx_SYMBOL_REF (ptr_mode, ggc_strdup ("test_symbol"))
>                 : NULL_RTX);
>          bse = (addr->base ?
> -                gen_raw_REG (address_mode, LAST_VIRTUAL_REGISTER + 1)
> +                gen_raw_REG (ptr_mode, LAST_VIRTUAL_REGISTER + 1)
>                 : NULL_RTX);
>          idx = (addr->index ?
> -                gen_raw_REG (address_mode, LAST_VIRTUAL_REGISTER + 2)
> +                gen_raw_REG (ptr_mode, LAST_VIRTUAL_REGISTER + 2)
>                 : NULL_RTX);
>
> -         gen_addr_rtx (address_mode, sym, bse, idx,
> +         gen_addr_rtx (ptr_mode, sym, bse, idx,
>                        st? const0_rtx : NULL_RTX,
>                        off? const0_rtx : NULL_RTX,
>                        &templ->ref,
> @@ -247,16 +247,16 @@ addr_for_mem_ref (struct mem_address *addr, addr_space_t a
> s,
>
>   /* Otherwise really expand the expressions.  */
>   sym = (addr->symbol
> -        ? expand_expr (addr->symbol, NULL_RTX, address_mode, EXPAND_NORMAL)
> +        ? expand_expr (addr->symbol, NULL_RTX, ptr_mode, EXPAND_NORMAL)
>         : NULL_RTX);
>   bse = (addr->base
> -        ? expand_expr (addr->base, NULL_RTX, address_mode, EXPAND_NORMAL)
> +        ? expand_expr (addr->base, NULL_RTX, ptr_mode, EXPAND_NORMAL)
>         : NULL_RTX);
>   idx = (addr->index
> -        ? expand_expr (addr->index, NULL_RTX, address_mode, EXPAND_NORMAL)
> +        ? expand_expr (addr->index, NULL_RTX, ptr_mode, EXPAND_NORMAL)
>         : NULL_RTX);
>
> -  gen_addr_rtx (address_mode, sym, bse, idx, st, off, &address, NULL, NULL);
> +  gen_addr_rtx (ptr_mode, sym, bse, idx, st, off, &address, NULL, NULL);
>   return address;
>  }
>
H.J. Lu Feb. 13, 2011, 1:41 p.m. UTC | #2
On Sun, Feb 13, 2011 at 1:42 AM, Richard Guenther
<richard.guenther@gmail.com> wrote:
>>> rtx
>>> 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);
>>>
>>> address_mode will be Pmode - that would be already wrong.  We need to
>>> use ptr_mode here and at the end of the function convert the
>>> generated address to Pmode appropriately.  Can you verify that theory?
>>>
>>
>> This patch works for me.  However, if I add
>>
>> diff --git a/gcc/tree-ssa-address.c b/gcc/tree-ssa-address.c
>> index 7b7e169..d9d906e 100644
>> --- a/gcc/tree-ssa-address.c
>> +++ b/gcc/tree-ssa-address.c
>> @@ -242,6 +242,9 @@ addr_for_mem_ref (struct mem_address *addr, addr_space_t as,
>>       if (off)
>>   *templ->off_p = off;
>>
>> +      if (targetm.addr_space.address_mode (as) != ptr_mode)
>> +  templ->ref = convert_to_mode (targetm.addr_space.address_mode (as),
>> +                 templ->ref, 1);
>>       return templ->ref;
>>     }
>>
>> to convert MEM_REF from ptr_mode to Pmode, I get
>>
>> /export/build/gnu/gcc-x32/build-x86_64-linux/gcc/xgcc
>> -B/export/build/gnu/gcc-x32/build-x86_64-linux/gcc/ -S -o x.s -mx32
>> -O2 -g -fPIC    x.i
>> x.i: In function \u2018foo\u2019:
>> x.i:21:1: error: insn outside basic block
>> (insn 88 0 113 (parallel [
>>            (set (reg:SI 143)
>>                (ashift:SI (reg:SI 60)
>>                    (const_int 3 [0x3])))
>>            (clobber (reg:CC 17 flags))
>>        ]) -1
>>     (nil))
>> x.i:21:1: internal compiler error: in rtl_verify_flow_info, at cfgrtl.c:2218
>> Please submit a full bug report,
>> with preprocessed source if appropriate.
>> See <http://gcc.gnu.org/bugs.html> for instructions.
>> make: *** [x.s] Error 1
>>
>> Do I really need to convert MEM_REF from ptr_mode to Pmode?
>
> Only if you do not plan to support 32bit addresses in the backend.

What do you mean by that? x32 is 32bit address.

> The above is probably
> because the caller context from where that function is called isn't
> prepared to have
> instructions emitted (maybe it's called from the cost analysis pieces as well?)
>

This could be true.
Richard Biener Feb. 13, 2011, 4:24 p.m. UTC | #3
On Sun, Feb 13, 2011 at 2:41 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Sun, Feb 13, 2011 at 1:42 AM, Richard Guenther
> <richard.guenther@gmail.com> wrote:
>>>> rtx
>>>> 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);
>>>>
>>>> address_mode will be Pmode - that would be already wrong.  We need to
>>>> use ptr_mode here and at the end of the function convert the
>>>> generated address to Pmode appropriately.  Can you verify that theory?
>>>>
>>>
>>> This patch works for me.  However, if I add
>>>
>>> diff --git a/gcc/tree-ssa-address.c b/gcc/tree-ssa-address.c
>>> index 7b7e169..d9d906e 100644
>>> --- a/gcc/tree-ssa-address.c
>>> +++ b/gcc/tree-ssa-address.c
>>> @@ -242,6 +242,9 @@ addr_for_mem_ref (struct mem_address *addr, addr_space_t as,
>>>       if (off)
>>>   *templ->off_p = off;
>>>
>>> +      if (targetm.addr_space.address_mode (as) != ptr_mode)
>>> +  templ->ref = convert_to_mode (targetm.addr_space.address_mode (as),
>>> +                 templ->ref, 1);
>>>       return templ->ref;
>>>     }
>>>
>>> to convert MEM_REF from ptr_mode to Pmode, I get
>>>
>>> /export/build/gnu/gcc-x32/build-x86_64-linux/gcc/xgcc
>>> -B/export/build/gnu/gcc-x32/build-x86_64-linux/gcc/ -S -o x.s -mx32
>>> -O2 -g -fPIC    x.i
>>> x.i: In function \u2018foo\u2019:
>>> x.i:21:1: error: insn outside basic block
>>> (insn 88 0 113 (parallel [
>>>            (set (reg:SI 143)
>>>                (ashift:SI (reg:SI 60)
>>>                    (const_int 3 [0x3])))
>>>            (clobber (reg:CC 17 flags))
>>>        ]) -1
>>>     (nil))
>>> x.i:21:1: internal compiler error: in rtl_verify_flow_info, at cfgrtl.c:2218
>>> Please submit a full bug report,
>>> with preprocessed source if appropriate.
>>> See <http://gcc.gnu.org/bugs.html> for instructions.
>>> make: *** [x.s] Error 1
>>>
>>> Do I really need to convert MEM_REF from ptr_mode to Pmode?
>>
>> Only if you do not plan to support 32bit addresses in the backend.
>
> What do you mean by that? x32 is 32bit address.

I mean if the backend MEMs only accept Pmode (64bit), not
ptr_mode (32bit).

Richard.

>> The above is probably
>> because the caller context from where that function is called isn't
>> prepared to have
>> instructions emitted (maybe it's called from the cost analysis pieces as well?)
>>
>
> This could be true.
>
> --
> H.J.
>
H.J. Lu Feb. 13, 2011, 4:30 p.m. UTC | #4
On Sun, Feb 13, 2011 at 8:24 AM, Richard Guenther
<richard.guenther@gmail.com> wrote:
> On Sun, Feb 13, 2011 at 2:41 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
>> On Sun, Feb 13, 2011 at 1:42 AM, Richard Guenther
>> <richard.guenther@gmail.com> wrote:
>>>>> rtx
>>>>> 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);
>>>>>
>>>>> address_mode will be Pmode - that would be already wrong.  We need to
>>>>> use ptr_mode here and at the end of the function convert the
>>>>> generated address to Pmode appropriately.  Can you verify that theory?
>>>>>
>>>>
>>>> This patch works for me.  However, if I add
>>>>
>>>> diff --git a/gcc/tree-ssa-address.c b/gcc/tree-ssa-address.c
>>>> index 7b7e169..d9d906e 100644
>>>> --- a/gcc/tree-ssa-address.c
>>>> +++ b/gcc/tree-ssa-address.c
>>>> @@ -242,6 +242,9 @@ addr_for_mem_ref (struct mem_address *addr, addr_space_t as,
>>>>       if (off)
>>>>   *templ->off_p = off;
>>>>
>>>> +      if (targetm.addr_space.address_mode (as) != ptr_mode)
>>>> +  templ->ref = convert_to_mode (targetm.addr_space.address_mode (as),
>>>> +                 templ->ref, 1);
>>>>       return templ->ref;
>>>>     }
>>>>
>>>> to convert MEM_REF from ptr_mode to Pmode, I get
>>>>
>>>> /export/build/gnu/gcc-x32/build-x86_64-linux/gcc/xgcc
>>>> -B/export/build/gnu/gcc-x32/build-x86_64-linux/gcc/ -S -o x.s -mx32
>>>> -O2 -g -fPIC    x.i
>>>> x.i: In function \u2018foo\u2019:
>>>> x.i:21:1: error: insn outside basic block
>>>> (insn 88 0 113 (parallel [
>>>>            (set (reg:SI 143)
>>>>                (ashift:SI (reg:SI 60)
>>>>                    (const_int 3 [0x3])))
>>>>            (clobber (reg:CC 17 flags))
>>>>        ]) -1
>>>>     (nil))
>>>> x.i:21:1: internal compiler error: in rtl_verify_flow_info, at cfgrtl.c:2218
>>>> Please submit a full bug report,
>>>> with preprocessed source if appropriate.
>>>> See <http://gcc.gnu.org/bugs.html> for instructions.
>>>> make: *** [x.s] Error 1
>>>>
>>>> Do I really need to convert MEM_REF from ptr_mode to Pmode?
>>>
>>> Only if you do not plan to support 32bit addresses in the backend.
>>
>> What do you mean by that? x32 is 32bit address.
>
> I mean if the backend MEMs only accept Pmode (64bit), not
> ptr_mode (32bit).
>

x32 supports both with the first patch in:

http://gcc.gnu.org/ml/gcc-patches/2011-02/msg00811.html
diff mbox

Patch

diff --git a/gcc/tree-ssa-address.c b/gcc/tree-ssa-address.c
index 7b7e169..d9d906e 100644
--- a/gcc/tree-ssa-address.c
+++ b/gcc/tree-ssa-address.c
@@ -242,6 +242,9 @@  addr_for_mem_ref (struct mem_address *addr, addr_space_t as,
       if (off)
   *templ->off_p = off;

+      if (targetm.addr_space.address_mode (as) != ptr_mode)
+  templ->ref = convert_to_mode (targetm.addr_space.address_mode (as),
+                 templ->ref, 1);
       return templ->ref;
     }

to convert MEM_REF from ptr_mode to Pmode, I get

/export/build/gnu/gcc-x32/build-x86_64-linux/gcc/xgcc
-B/export/build/gnu/gcc-x32/build-x86_64-linux/gcc/ -S -o x.s -mx32
-O2 -g -fPIC    x.i
x.i: In function \u2018foo\u2019:
x.i:21:1: error: insn outside basic block
(insn 88 0 113 (parallel [
            (set (reg:SI 143)
                (ashift:SI (reg:SI 60)
                    (const_int 3 [0x3])))
            (clobber (reg:CC 17 flags))
        ]) -1
     (nil))
x.i:21:1: internal compiler error: in rtl_verify_flow_info, at cfgrtl.c:2218
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.
make: *** [x.s] Error 1

Do I really need to convert MEM_REF from ptr_mode to Pmode?

Thanks.

-- 
H.J.
---
diff --git a/gcc/tree-ssa-address.c b/gcc/tree-ssa-address.c
index a9ca835..7b7e169 100644
--- a/gcc/tree-ssa-address.c
+++ b/gcc/tree-ssa-address.c
@@ -188,12 +188,12 @@  rtx
 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);
   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),
+				 ptr_mode);
   else
     st = NULL_RTX;