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

--- Comment #22 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
(In reply to Richard Biener from comment #20)
> where SLP vectorization is confused about (char) _19 vs. BIT_FIELD_REF
> but also wouldn't handle BIT_FIELD_REFs.  It neither vectorizes the
> store to a store from a CTOR which forwprop could then pattern-match.

I ran into the issue of (cast) _1 also.  I had a function which finds BFRs and
treated the cast to a lower precision as a BFR:
/* Find a BIT_FIELD_REF from the ssa is defined by.
   Expand the BIT_FIELD_REF to BITPOS, BITSIZE and OUTERSIZE.  Returning
   the inner value of the BIT_FIELD_REF.   */
tree
ssa_name_to_BFR (tree value, unsigned HOST_WIDE_INT &bitpos,
                 unsigned HOST_WIDE_INT &bitsize,
                 unsigned HOST_WIDE_INT &outersize)
{
  if (TREE_CODE (value) != SSA_NAME)
    return NULL;
  gimple *def = SSA_NAME_DEF_STMT (value);
  if (stmt_could_throw_p (cfun, def)
      || !is_gimple_assign (def))
    return NULL;

  /* Treat a normal cast as extracting the lower bits of the inner value. */
  if (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def)))
    {
      tree inner = gimple_assign_rhs1 (def);
      tree outer_type = TREE_TYPE (value);
      tree inner_type = TREE_TYPE (inner);
      if (!INTEGRAL_TYPE_P (outer_type)
          || !INTEGRAL_TYPE_P (inner_type))
        return NULL;
      outersize = TYPE_PRECISION (inner_type);
      bitsize = TYPE_PRECISION (outer_type);
      if (outersize <= bitsize)
        return NULL;
      gimple_set_visited (def, true);
      bitpos = 0;
      return inner;
    }

  if (gimple_assign_rhs_code (def) != BIT_FIELD_REF)
    return NULL;

  tree bfr = gimple_assign_rhs1 (def);
  /* Make sure the BIT_FIELD_REF is acting on a SSA_NAME.
     Cannot handle an memory value. */
  if (TREE_CODE (TREE_OPERAND (bfr, 0)) != SSA_NAME)
    return NULL;

  bitsize = tree_to_uhwi (TREE_OPERAND (bfr, 1));
  bitpos = tree_to_uhwi (TREE_OPERAND (bfr, 2));
  tree otype = TREE_TYPE (TREE_OPERAND (bfr, 0));

  if (INTEGRAL_TYPE_P (otype))
    outersize = TYPE_PRECISION (otype);
  else
    outersize = tree_to_uhwi (TYPE_SIZE (otype));

  if (INTEGRAL_TYPE_P (otype) && BYTES_BIG_ENDIAN)
    bitpos = outersize - bitsize - bitpos;

  /* Mark the statement as visited as we might remove the
     reference to it later on. */
  gimple_set_visited (def, true);
  return TREE_OPERAND (bfr, 0);
}

Reply via email to