On Wed, Oct 1, 2008 at 12:20 AM, DJ Delorie <[EMAIL PROTECTED]> wrote:
>
> I've got a partial patch which works with older (4.3) gccs, but fails
> gimple's check for trunk (attached). My trivial test case...
>
> char *
> foo (char *a, int b)
> {
> return a-b;
> }
>
> ...fails thusly:
>
> <integer_type 0xb7f52c30 public unsigned SI
> size <integer_cst 0xb7ee7540 type <integer_type 0xb7ef5068 bit_size_type>
> constant 32>
> unit size <integer_cst 0xb7ee72bc type <integer_type 0xb7ef5000 unsigned
> int> constant 4>
> align 8 symtab 0 alias set -1 canonical type 0xb7f52c30 precision 32 min
> <integer_cst 0xb7f6a0c4 0> max <integer_cst 0xb7ee7e8c 4294967295>>
> <integer_type 0xb7ef5000 unsigned int public unsigned sizetype HI
> size <integer_cst 0xb7ee7428 type <integer_type 0xb7ef5068 bit_size_type>
> constant 16>
> unit size <integer_cst 0xb7ee7444 type <integer_type 0xb7ef5000 unsigned
> int> constant 2>
> align 8 symtab 0 alias set -1 canonical type 0xb7efc000 precision 16 min
> <integer_cst 0xb7ee74d0 0> max <integer_cst 0xb7ee7ad4 -1>>
> useless false: ../../gcc/gcc/tree-ssa.c 1092
> dj.c: In function 'foo':
> dj.c:2: error: type mismatch in pointer plus expression
> D.1194 = a + D.1196;
>
> char *
>
> char *
>
> <unnamed-unsigned:32>
>
> D.1194 = a + D.1196;
>
> dj.c:2: internal compiler error: verify_gimple failed
>
>
> I'm obviously doing something wrong in the cast-to-bigger step. How
> can I get this to pass gimple? What I'm trying to accomplish is this:
>
> 1. Values added to pointers need to be treated as signed (at least, if
> they're signed types, certainly if you're going to use a
> NEGATE_EXPR).
>
> 2. If sizeof(size_t) < sizeof(void *), sign extend the intop to be
> pointer-sized before adding it.
>
>
>
> Index: c-common.c
> ===================================================================
> --- c-common.c (revision 140759)
> +++ c-common.c (working copy)
> @@ -3337,20 +3337,28 @@ pointer_int_sum (enum tree_code resultco
> intop = convert (c_common_type_for_size (TYPE_PRECISION (sizetype),
> TYPE_UNSIGNED (sizetype)), intop);
>
> /* Replace the integer argument with a suitable product by the object size.
> Do this multiplication as signed, then convert to the appropriate
> type for the pointer operation. */
> - intop = convert (sizetype,
> + intop = convert (ssizetype,
> build_binary_op (EXPR_LOCATION (intop),
> MULT_EXPR, intop,
> convert (TREE_TYPE (intop), size_exp), 1));
>
> /* Create the sum or difference. */
> if (resultcode == MINUS_EXPR)
> - intop = fold_build1 (NEGATE_EXPR, sizetype, intop);
> + intop = fold_build1 (NEGATE_EXPR, ssizetype, intop);
> +
> + if (TREE_CODE (result_type) == POINTER_TYPE
> + && TYPE_PRECISION (result_type) > TYPE_PRECISION (TREE_TYPE (intop)))
> + {
> + tree iptr_type = c_common_type_for_mode (TYPE_MODE (result_type),
> + TYPE_UNSIGNED (result_type));
> + intop = fold_build1 (NOP_EXPR, iptr_type, intop);
> + }
>
> ret = fold_build2 (POINTER_PLUS_EXPR, result_type, ptrop, intop);
>
> fold_undefer_and_ignore_overflow_warnings ();
>
> return ret;
I think this is the wrong place to fix this. If you would override
the sizetypes precision
from your target, would that fix it? That is, in stor-layout.c
set_sizetype make the
target allow adjusting the passed type (which is supposed to be
sizetype). If at all
then these types should be consistent.
Richard.