https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81601
--- Comment #27 from Jeffrey A. Law ---
So I just prototyped a bit of code that might help with this BZ.
This seems better suited for match.pd, except that match.pd doesn't seem to
want to handle BIT_FIELD_REF nodes. So I did the prototype in forwprop.
Given a BIT_AND_EXPR which just masks off high bits that is fed by a
BIT_FIELD_REF, we can adjust the # of bits in the BIT_FIELD_REF and the type of
the reference. The BIT_AND turns into a nop-conversion.
So the key blocks start like this:
;; basic block 2, loop depth 0, maybe hot
;;prev block 0, next block 3, flags: (NEW, VISITED)
;;pred: ENTRY (FALLTHRU,EXECUTABLE)
_13 = __builtin_object_size (tp_11(D), 0);
_14 = &tp_11(D)->D.2292;
.UBSAN_OBJECT_SIZE (_14, 13, _13, 0);
_1 = tp_11(D)->chrono_type;
_2 = (int) _1;
if (_1 == 0)
goto ; [INV]
else
goto ; [INV]
;;succ: 3 (TRUE_VALUE,EXECUTABLE)
;;5 (FALSE_VALUE,EXECUTABLE)
;; basic block 3, loop depth 0, maybe hot
;;prev block 2, next block 4, flags: (NEW, VISITED)
;;pred: 2 (TRUE_VALUE,EXECUTABLE)
_3 = BIT_FIELD_REF <*tp_11(D), 8, 96>;
_4 = _3 & 3;
if (_4 != 0)
goto ; [INV]
else
goto ; [INV]
;;succ: 4 (TRUE_VALUE,EXECUTABLE)
;;5 (FALSE_VALUE,EXECUTABLE)
And the bits in block #3 turn into:
;; basic block 3, loop depth 0, maybe hot
;;prev block 2, next block 4, flags: (NEW, VISITED)
;;pred: 2 (TRUE_VALUE,EXECUTABLE)
_9 = BIT_FIELD_REF <*tp_11(D), 2, 96>;
_4 = (unsigned char) _9;
if (_9 != 0)
goto ; [INV]
else
goto ; [INV]
;;succ: 4 (TRUE_VALUE,EXECUTABLE)
;;5 (FALSE_VALUE,EXECUTABLE)
That's good enough that FRE can see the redundancy between tp->chrono_type and
the BIT_FIELD_REF and all the right things just happen from that point onward.