I've noticed that I associate negation and conversion in one place. Fixed by the following which also removes some useless converts.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied. Richard. 2013-09-03 Richard Biener <rguent...@suse.de> * tree-affine.c (add_elt_to_tree): Fix association issue, avoid useless converts and make sure to always return a properly typed result. Index: gcc/tree-affine.c =================================================================== --- gcc/tree-affine.c (revision 202196) +++ gcc/tree-affine.c (working copy) @@ -381,36 +381,43 @@ add_elt_to_tree (tree expr, tree type, t if (scale.is_minus_one () && POINTER_TYPE_P (TREE_TYPE (elt))) { - elt = fold_build1 (NEGATE_EXPR, sizetype, convert_to_ptrofftype (elt)); + elt = convert_to_ptrofftype (elt); + elt = fold_build1 (NEGATE_EXPR, TREE_TYPE (elt), elt); scale = double_int_one; } if (scale.is_one ()) { if (!expr) - return elt; + { + if (POINTER_TYPE_P (TREE_TYPE (elt))) + return elt; + else + return fold_convert (type1, elt); + } if (POINTER_TYPE_P (TREE_TYPE (expr))) - return fold_build_pointer_plus (expr, convert_to_ptrofftype (elt)); + return fold_build_pointer_plus (expr, elt); if (POINTER_TYPE_P (TREE_TYPE (elt))) - return fold_build_pointer_plus (elt, convert_to_ptrofftype (expr)); + return fold_build_pointer_plus (elt, expr); return fold_build2 (PLUS_EXPR, type1, - fold_convert (type1, expr), - fold_convert (type1, elt)); + expr, fold_convert (type1, elt)); } if (scale.is_minus_one ()) { if (!expr) - return fold_build1 (NEGATE_EXPR, TREE_TYPE (elt), elt); + return fold_build1 (NEGATE_EXPR, type1, + fold_convert (type1, elt)); if (POINTER_TYPE_P (TREE_TYPE (expr))) - return fold_build_pointer_plus - (expr, convert_to_ptrofftype - (fold_build1 (NEGATE_EXPR, TREE_TYPE (elt), elt))); + { + elt = convert_to_ptrofftype (elt); + elt = fold_build1 (NEGATE_EXPR, TREE_TYPE (elt), elt); + return fold_build_pointer_plus (expr, elt); + } return fold_build2 (MINUS_EXPR, type1, - fold_convert (type1, expr), - fold_convert (type1, elt)); + expr, fold_convert (type1, elt)); } elt = fold_convert (type1, elt); @@ -434,8 +441,7 @@ add_elt_to_tree (tree expr, tree type, t elt = fold_build1 (NEGATE_EXPR, type1, elt); return fold_build_pointer_plus (expr, elt); } - return fold_build2 (code, type1, - fold_convert (type1, expr), elt); + return fold_build2 (code, type1, expr, elt); } /* Makes tree from the affine combination COMB. */