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

--- Comment #14 from Jeffrey A. Law <law at gcc dot gnu.org> ---
So with a hackish match.pd pattern which recognizes these kinds of idioms:


  _1 = BIT_FIELD_REF <b, 8, 0>;
  _2 = _1 & 1;

And turning it into something like this:

  _15 = BIT_FIELD_REF <b, 1, 0>;

Allows fre1 to clean things up in the desired ways resulting in:

;;   basic block 2, loop depth 0, maybe hot
;;    prev block 0, next block 3, flags: (NEW, VISITED)
;;    pred:       ENTRY (FALLTHRU,EXECUTABLE)
  b$i_4 = b.i;
  b$j_2 = b.j;
  if (b$i_4 != 0)
    goto <bb 4>; [INV]
  else
    goto <bb 3>; [INV]
;;    succ:       4 (TRUE_VALUE,EXECUTABLE)
;;                3 (FALSE_VALUE,EXECUTABLE)

;;   basic block 3, loop depth 0, maybe hot
;;    prev block 2, next block 4, flags: (NEW, VISITED)
;;    pred:       2 (FALSE_VALUE,EXECUTABLE)
;;    succ:       4 (FALLTHRU,EXECUTABLE)

;;   basic block 4, loop depth 0, maybe hot
;;    prev block 3, next block 1, flags: (NEW, VISITED)
;;    pred:       2 (TRUE_VALUE,EXECUTABLE)
;;                3 (FALLTHRU,EXECUTABLE)
  # x_6 = PHI <x_13(D)(2), b$i_4(3)>
  b.j = 0;
  return;

And the bogus warning gets elided.

Here's the pattern I was playing with

/* Squash away masking by adjusting the BIT_FIELD_REF if possible.  */
(simplify
  (bit_and (BIT_FIELD_REF@0 @1 @2 @3) integer_pow2p@4)
  (with {
    HOST_WIDE_INT pos = tree_log2 (@4);
    pos = pos + TREE_INT_CST_LOW (@3);
   }
  (convert (BIT_FIELD_REF:boolean_type_node @1 {build_one_cst (bitsizetype);} {
build_int_cst (bitsizetype, pos); }))))

It doesn't work as-is because something in gimple-match*.cc is requiring @1 to
be an SSA_NAME and rejects PARM_DECL.

Not really chasing this further right now, but there is a potential path
forward.  I'll also note that this transformation would likely help the targets
that have single bit extraction/manipulation like RISC-V and others.

Reply via email to