https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117217

Martin Jambor <jamborm at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Assignee|unassigned at gcc dot gnu.org      |jamborm at gcc dot 
gnu.org
             Status|NEW                         |ASSIGNED

--- Comment #5 from Martin Jambor <jamborm at gcc dot gnu.org> ---
This no longer reproduces because after r15-5747-gfd62fdc5e1b3c4
(Jakub Jelinek: c++: Small initial fixes for zeroing of padding bits
[PR117256]), the input to SRA looks very different and SRA does not do
anything.

Before that commit, SRA sees the following input (on the testcase from
bug description with the packed attribute):

  D.2908.i = 0;
  D.2908.b = 0;
  e ={v} {CLOBBER(bob)};
  e.b = MEM[(const struct B &)&D.2908];
  D.2908 ={v} {CLOBBER(eos)};

(Where the "e" in "e.b" is actually a MEM_REF of the union type into
&e so that is why the "data" field is missing.)

Field D.2908.b is a SRA candidate of boolean type and has size 1 bit
because its decl has size 1 bit even though its type has size 8 bits.

The SRA access representing the store to D.2908.b is then propagated
across the assignment to e and in the process
build_user_friendly_ref_for_offset tries to find a nice expression for
it to possibly use in warnings.  It finds types_compatible_p
e.data.a.b which however has size 8 bits and so the verifier screams
when it discovers the discrepancy from the copied-over size of 1 bit.

Assuming bit-fields are the only cases where the type and decl size
discrepancy, the easiest way forward is to exclude them from
propagation like below.  Alternatively we could re-run
get_ref_base_and_extent on expressions created in
create_artificial_child_access and fix-up the new access accordingly,
but we'd probably also have to make sure not to exceed the parent
access.


diff --git a/gcc/tree-sra.cc b/gcc/tree-sra.cc
index 6ad095c5267..3f2b2ac0f0b 100644
--- a/gcc/tree-sra.cc
+++ b/gcc/tree-sra.cc
@@ -3232,6 +3232,7 @@ propagate_subaccesses_from_rhs (struct access *lacc,
struct access *racc)
        }

       if (rchild->grp_unscalarizable_region
+         || (rchild->size % BITS_PER_UNIT) != 0
          || !budget_for_propagation_access (lacc->base))
        {
          if (!lacc->grp_write && access_or_its_child_written (rchild))
@@ -3291,6 +3292,7 @@ propagate_subaccesses_from_lhs (struct access *lacc,
struct access *racc)
       HOST_WIDE_INT norm_offset = lchild->offset + norm_delta;

       if (lchild->grp_unscalarizable_region
+         || (lchild->size % BITS_PER_UNIT) != 0
          || child_would_conflict_in_acc (racc, norm_offset, lchild->size,
                                          &matching_acc)
          || !budget_for_propagation_access (racc->base))

Reply via email to