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

--- Comment #27 from Jeffrey A. Law <law at redhat dot com> ---
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 <bb 3>; [INV]
  else
    goto <bb 5>; [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 <bb 4>; [INV]
  else
    goto <bb 5>; [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 <bb 4>; [INV]
  else
    goto <bb 5>; [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.

Reply via email to