This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Fix lto bootstrap
- From: Richard Guenther <rguenther at suse dot de>
- To: Jan Hubicka <hubicka at ucw dot cz>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Mon, 4 Oct 2010 11:06:59 +0200 (CEST)
- Subject: Re: Fix lto bootstrap
- References: <20101004003047.GC8569@kam.mff.cuni.cz>
On Mon, 4 Oct 2010, Jan Hubicka wrote:
> Hi,
> LTO bootstrap fails because we incorrectly fold
> insn_data[CODE_FOR_insv].operand[1].predicate (GEN_INT..
> into call to NULL.
>
> The problem is that we have
> MEM[ptr+24].predicate access, where ptr is isnsn_code[2000].
> The reference really access insn_code[2001].predicate, but since
> get_base_constructor handle ARRAY_REF by calling fold_const_aggregate_ref that
> return constructor of insn_code[2000] only, we don't find matching field while
> looking for field at offset 24.
>
> The following patch makes get_base_constructor to use
> get_ref_base_and_extend and simply adjust the offset of outer reference.
> This makes the code bit simpler too.
>
> Bootstrapped/regetested x86_64-linux, OK? I also did C only profedbootstrap
> and verified that it works now.
>
> Honza
>
> PR middle-end/45871
> * tree-ssa-ccp.c (get_base_constructor): Take HOST_WIDE_INT offset;
> use get_ref_base_and_offset to handle references.
> (fold_const_aggregate_ref): Update.
> Index: tree-ssa-ccp.c
> ===================================================================
> *** tree-ssa-ccp.c (revision 164917)
> --- tree-ssa-ccp.c (working copy)
> *************** ccp_fold (gimple stmt)
> *** 1319,1336 ****
> }
>
> /* See if we can find constructor defining value of BASE.
>
> As a special case, return error_mark_node when constructor
> is not explicitly available, but it is known to be zero
> such as 'static const int a;'. */
> static tree
> ! get_base_constructor (tree base, tree *offset)
> {
> ! *offset = NULL;
> if (TREE_CODE (base) == MEM_REF)
> {
> if (!integer_zerop (TREE_OPERAND (base, 1)))
> ! *offset = TREE_OPERAND (base, 1);
>
> base = get_constant_value (TREE_OPERAND (base, 0));
> if (!base || TREE_CODE (base) != ADDR_EXPR)
> --- 1319,1344 ----
> }
>
> /* See if we can find constructor defining value of BASE.
> + When we know the consructor with constant offset (such as
> + base is array[40] and we do know constructor of array), then
> + BIT_OFFSET is adjusted accordingly.
>
> As a special case, return error_mark_node when constructor
> is not explicitly available, but it is known to be zero
> such as 'static const int a;'. */
> static tree
> ! get_base_constructor (tree base, HOST_WIDE_INT *bit_offset)
> {
> ! HOST_WIDE_INT bit_offset2, size, max_size;
> if (TREE_CODE (base) == MEM_REF)
> {
> if (!integer_zerop (TREE_OPERAND (base, 1)))
> ! {
> ! if (!host_integerp (TREE_OPERAND (base, 1), 0))
> ! return NULL_TREE;
> ! *bit_offset += (TREE_INT_CST_LOW (TREE_OPERAND (base, 1))
> ! * BITS_PER_UNIT);
Please use mem_ref_offset (base).low * BITS_PER_UNIT. Note that
the overflow check is wrong as you are multiplying with BITS_PER_UNIT.
Using get_addr_base_and_unit_offset () throughout folding and
handling bit-field references explicitly would avoid this.
Consider following up with such cleanup (or I might take a stab
at the code if you like).
Ok with that change.
Thanks,
Richard.
> ! }
>
> base = get_constant_value (TREE_OPERAND (base, 0));
> if (!base || TREE_CODE (base) != ADDR_EXPR)
> *************** get_base_constructor (tree base, tree *o
> *** 1359,1365 ****
>
> case ARRAY_REF:
> case COMPONENT_REF:
> ! return fold_const_aggregate_ref (base);
> break;
>
> case STRING_CST:
> --- 1367,1377 ----
>
> case ARRAY_REF:
> case COMPONENT_REF:
> ! base = get_ref_base_and_extent (base, &bit_offset2, &size, &max_size);
> ! if (max_size == -1 || size != max_size)
> ! return NULL_TREE;
> ! *bit_offset += bit_offset2;
> ! return get_base_constructor (base, bit_offset);
> break;
>
> case STRING_CST:
> *************** fold_const_aggregate_ref (tree t)
> *** 1597,1603 ****
> tree ctor, idx, base;
> HOST_WIDE_INT offset, size, max_size;
> tree tem;
> - tree ctr_offset;
>
> if (TREE_CODE_CLASS (TREE_CODE (t)) == tcc_declaration)
> return get_symbol_constant_value (t);
> --- 1609,1614 ----
> *************** fold_const_aggregate_ref (tree t)
> *** 1633,1645 ****
> offset *= BITS_PER_UNIT;
>
> base = TREE_OPERAND (t, 0);
> ! ctor = get_base_constructor (base, &ctr_offset);
> ! if (ctr_offset)
> ! {
> ! if (!host_integerp (ctr_offset, 1))
> ! return NULL_TREE;
> ! offset += TREE_INT_CST_LOW (ctr_offset) * BITS_PER_UNIT;
> ! }
> /* Empty constructor. Always fold to 0. */
> if (ctor == error_mark_node)
> return build_zero_cst (TREE_TYPE (t));
> --- 1644,1650 ----
> offset *= BITS_PER_UNIT;
>
> base = TREE_OPERAND (t, 0);
> ! ctor = get_base_constructor (base, &offset);
> /* Empty constructor. Always fold to 0. */
> if (ctor == error_mark_node)
> return build_zero_cst (TREE_TYPE (t));
> *************** fold_const_aggregate_ref (tree t)
> *** 1661,1667 ****
> case TARGET_MEM_REF:
> case MEM_REF:
> base = get_ref_base_and_extent (t, &offset, &size, &max_size);
> ! ctor = get_base_constructor (base, &ctr_offset);
>
> /* Empty constructor. Always fold to 0. */
> if (ctor == error_mark_node)
> --- 1666,1672 ----
> case TARGET_MEM_REF:
> case MEM_REF:
> base = get_ref_base_and_extent (t, &offset, &size, &max_size);
> ! ctor = get_base_constructor (base, &offset);
>
> /* Empty constructor. Always fold to 0. */
> if (ctor == error_mark_node)
> *************** fold_const_aggregate_ref (tree t)
> *** 1673,1684 ****
> if (!ctor)
> return NULL_TREE;
>
> - if (ctr_offset)
> - {
> - if (!host_integerp (ctr_offset, 1))
> - return NULL_TREE;
> - offset += TREE_INT_CST_LOW (ctr_offset) * BITS_PER_UNIT;
> - }
> /* Out of bound array access. Value is undefined, but don't fold. */
> if (offset < 0)
> return NULL_TREE;
> --- 1678,1683 ----
>
>
--
Richard Guenther <rguenther@suse.de>
Novell / SUSE Labs
SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746 - GF: Markus Rex