https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88739
--- Comment #47 from Richard Biener <rguenth at gcc dot gnu.org> --- (In reply to Eric Botcazou from comment #45) > > So to get back to this - my thinking was that for a reference REF I can do > > > > base = get_inner_reference (ref, &bitsize, &bitpos, &offset, &mode, > > &unsignedp, &reversep, &volatilep); > > > > and get the semantically same REF building > > > > REF' = BIT_FIELD_REF<*(&base + offset), bitsize, bitpos> > > > > (plus setting REF_REVERSE_STORAGE_ORDER and TREE_THIS_VOLATILE on REF'). > > > > This appearantly breaks down (similarly for get_ref_base_and_extent) for > > bigendian and DECL_BIT_FIELD outer COMPONENT_REFs. And maybe for more? > > > > Is my expectation that the above "works" flawed? So "bit position" > > and "position of the first referenced bit" are two separate things? > > No, they are the same, but I think that BIT_FIELD_REF is not supposed to be > itself applied to a bit-field, as in the case at hand, since it's precisely > meant to designate a bit-field. In other words, the above base cannot be a > bit-field. > > So the safest route is probably to forbid such an abomination, i.e. to make > sure that the first argument of BIT_FIELD_REF is a bona-fide base type. OK, we can certainly try to enforce this. Just to make sure - this refers to TREE_TYPE (TREE_OPERAND (bfr, 0)), not the base of the component-ref chain eventually rooted here? On GIMPLE, if we want to extract some bits from a register that happens to be a non-"base" type this means we have to use shifting and masking. I suppose the same issue hits BIT_INSERT_EXPR. This makes it somewhat awkward (aka non-canonical) on the GIMPLE side :/ The most natural thing there would then be to disallow such types in the IL. Btw, are PSImode / int : 24 "bona-fide base types"? Thus, is the criteria that precision matches TYPE_SIZE? GET_MODE_PRECISION? GET_MODE_BITSIZE? I know we try to avoid introducing bit-precision ops during GIMPLE optimization but FEs happily leak those into the IL (as in this testcase). Just to remind where we're coming from - we have unData.strMemHead.b30AddrL = ulAddr >> 2; where this is a 30bit bitfield store (at bit offset % BITS_PER_UNIT == 0) from a unsigned :30 register. Via the union we now try to load 8 bits from memory contained within that 30 bits and try to extract those from the unsigned :30 register instead (with the goal to elide the memory object). In which circumnstances can we view the RHS of the above store as "proper" for applying the BIT_FIELD_REF as translated to the LHS memory to the RHS register? Is it enough to constrain the RHS type to TYPE_PRECISION == TYPE_SIZE? RTL expansion now handles various cases of handled-component expansion where the base ends up not being memory but various other kinds of entities - do they run into the same issue when, for BIT_FIELD_REFs, register bases are not equal to memory bases? [Just looking at FLOAT_WORD_ORDER and friends and considering the punning we're happily introducing via the above transform]