[PATCH]Fix computation of offset in ivopt
Richard Sandiford
rdsandiford@googlemail.com
Wed Nov 6 17:12:00 GMT 2013
Hi,
"bin.cheng" <bin.cheng@arm.com> writes:
> Index: gcc/tree-ssa-loop-ivopts.c
> ===================================================================
> --- gcc/tree-ssa-loop-ivopts.c (revision 203267)
> +++ gcc/tree-ssa-loop-ivopts.c (working copy)
> @@ -2037,12 +2037,12 @@ find_interesting_uses (struct ivopts_data *data)
>
> static tree
> strip_offset_1 (tree expr, bool inside_addr, bool top_compref,
> - unsigned HOST_WIDE_INT *offset)
> + HOST_WIDE_INT *offset)
> {
> tree op0 = NULL_TREE, op1 = NULL_TREE, tmp, step;
> enum tree_code code;
> tree type, orig_type = TREE_TYPE (expr);
> - unsigned HOST_WIDE_INT off0, off1, st;
> + HOST_WIDE_INT off0, off1, st;
> tree orig_expr = expr;
>
> STRIP_NOPS (expr);
> @@ -2133,19 +2133,32 @@ strip_offset_1 (tree expr, bool inside_addr, bool
> break;
>
> case COMPONENT_REF:
> - if (!inside_addr)
> - return orig_expr;
> + {
> + tree field;
>
> - tmp = component_ref_field_offset (expr);
> - if (top_compref
> - && cst_and_fits_in_hwi (tmp))
> - {
> - /* Strip the component reference completely. */
> - op0 = TREE_OPERAND (expr, 0);
> - op0 = strip_offset_1 (op0, inside_addr, top_compref, &off0);
> - *offset = off0 + int_cst_value (tmp);
> - return op0;
> - }
> + if (!inside_addr)
> + return orig_expr;
> +
> + tmp = component_ref_field_offset (expr);
> + field = TREE_OPERAND (expr, 1);
> + if (top_compref
> + && cst_and_fits_in_hwi (tmp)
> + && cst_and_fits_in_hwi (DECL_FIELD_BIT_OFFSET (field)))
While comparing output for wide-int and mainline, I noticed that
this condition is now always false on x86_64, since DECL_FIELD_BIT_OFFSET
is a 128-bit bitsizetype and since cst_and_fits_in_hwi rejects constants
with precision greater than HWI:
if (TREE_CODE (x) != INTEGER_CST)
return false;
if (TYPE_PRECISION (TREE_TYPE (x)) > HOST_BITS_PER_WIDE_INT)
return false;
Should this be host_integerp (DECL_FIELD_BIT_OFFSET (field), 0) instead?
> + {
> + HOST_WIDE_INT boffset, abs_off;
> +
> + /* Strip the component reference completely. */
> + op0 = TREE_OPERAND (expr, 0);
> + op0 = strip_offset_1 (op0, inside_addr, top_compref, &off0);
> + boffset = int_cst_value (DECL_FIELD_BIT_OFFSET (field));
> + abs_off = abs_hwi (boffset) / BITS_PER_UNIT;
> + if (boffset < 0)
> + abs_off = -abs_off;
> +
> + *offset = off0 + int_cst_value (tmp) + abs_off;
> + return op0;
> + }
> + }
> break;
Thanks,
Richard
More information about the Gcc-patches
mailing list