On 24/10/2022 08:17, Richard Biener wrote:

Can you check why vect_find_stmt_data_reference doesn't trip on the

   if (TREE_CODE (DR_REF (dr)) == COMPONENT_REF
       && DECL_BIT_FIELD (TREE_OPERAND (DR_REF (dr), 1)))
     {
       free_data_ref (dr);
       return opt_result::failure_at (stmt,
                                      "not vectorized:"
                                      " statement is an unsupported"
                                      " bitfield access %G", stmt);
     }

It used to, which is why this test didn't trigger the error before my patch, but we lower it to BIT_FIELD_REFs in ifcvt now so it is no longer a DECL_BIT_FIELD.

But that is a red-herring, if you change the test structure's 'type Int24 is mod 2**24;' to 'type Int24 is mod 2**32;', thus making the field we access a normal 32-bit integer, the field no longer is a DECL_BIT_FIELD and thus my lowering does nothing. However, you will still get the failure because the field before it is a packed 4-bit field, making the offset to the field we are accessing less than BITS_PER_UNIT.

?  I think we should amend this check and I guess that
checking multiple_p on DECL_FIELD_BIT_OFFSET should be enough?
That won't work either, unless we do the same walk-through the full access as we do in get_inner_reference.

Let me elaborate, the 'offending' stmt here is:
_ifc__23 = (*x_7(D))[_1].b.D.3707;

And the struct in question is:
package Loop_Optimization23_Pkg is
  type Nibble is mod 2**4;
  type Int24  is mod 2**24;
  type StructA is record
    a : Nibble;
    b : Int24;
  end record;
  pragma Pack(StructA);
  type StructB is record
    a : Nibble;
    b : StructA;
  end record;
  pragma Pack(StructB);
  type ArrayOfStructB is array(0..100) of StructB;
  procedure Foo (X : in out ArrayOfStructB);
end Loop_Optimization23_Pkg;

That D.3707 is the 'container'm i.e. the DECL_BIT_FIELD_REPRESENTATIVE of the original bitfield of type Int24.
So in vect_find_stmt_data_reference , the dr is: (*x_7(D))[_1].b.D.3707 and
TREE_OPERAND (DR_REF (dr), 1): D.3707,
which has DECL_FIELD_BIT_OFFSET: 0

So that check would also pass. However, get_inner_reference, walks the full access and comes across '.b', the member access for StructA inside StructB, that has DECL_FIELD_BIT_OFFSET: 4 Which is where we get into trouble. So to catch that here, we would need to do the same type of walking through all the member accesses, like get_inner_reference does.

Reply via email to