http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47383

Richard Guenther <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2011.02.07 12:25:25
     Ever Confirmed|0                           |1

--- Comment #9 from Richard Guenther <rguenth at gcc dot gnu.org> 2011-02-07 
12:25:25 UTC ---
(In reply to comment #8)
> (In reply to comment #7)
> 
> > > looks wrong since it assumes D.2750_34 can be negative. But
> > 
> > sizetype values are sign-extended.
> > 
> 
> ivopts uses unsigned on purpose and create_mem_ref isn't prepared
> to deal with.  This isn't the right fix. It just shows we need to
> properly sign-extended index when Pmode != ptr_mode:
> 
> diff --git a/gcc/tree-ssa-address.c b/gcc/tree-ssa-address.c
> index a9ca835..4926a6d 100644
> --- a/gcc/tree-ssa-address.c
> +++ b/gcc/tree-ssa-address.c
> @@ -45,6 +45,7 @@ along with GCC; see the file COPYING3.  If not see
>  #include "expr.h"
>  #include "ggc.h"
>  #include "target.h"
> +#include "langhooks.h"
> 
>  /* TODO -- handling of symbols (according to Richard Hendersons
>     comments, http://gcc.gnu.org/ml/gcc-patches/2005-04/msg00949.html):
> @@ -658,6 +659,13 @@ addr_to_parts (tree type, aff_tree *addr, tree iv_cand,
>      }
>    if (addr->rest)
>      add_to_parts (parts, fold_convert (sizetype, addr->rest));
> +
> +  if (Pmode != ptr_mode && parts->index)
> +    {
> +      parts->index = fold_convert (ssizetype, parts->index);
> +      parts->index = fold_convert (lang_hooks.types.type_for_mode (Pmode, 0),
> +                   parts->index);
> +    }
>  }
> 
>  /* Force the PARTS to register.  */

I think the issue is more involved.  First we loose any information
of the signedness of the offset that was present in the C source because
of our stupid idea to convert all pointer offsets to sizetype (which,
in its other stupid way is a TYPE_UNSIGNED type that is supposed to be
sign-extended).  Second, there is no way for the target to specify
whether offsets to ptr_mode should be sign- or zero-extended to
an integer type of the with of Pmode.  We'd need a OFFSETS_EXTEND_UNSIGNED
macro for this (if it should be a consistent extension).

OTOH on my TODO list there is "preserve signedness of pointer offsets",
thus, drop the sizetype conversion requirement and just extend offsets
based on their actual sign.

The above said, a IVOPTs-local solution isn't a solution.  We have
the same issue with all POINTER_PLUS_EXPRs (how does it happen that
they work for you (in all werid cases)?).

You can maybe work around the issue by computing the resulting address
in ptr_mode (including all offsets) and only then extending to
Pmode according to POINTERS_EXTEND_UNSIGNED.  That works unless
sizetype != ptr_mode size.

Reply via email to