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.