On 3 May 2019 18:48:09 CEST, "H.J. Lu" <hjl.to...@gmail.com> wrote:
>On Fri, May 3, 2019 at 6:02 AM Richard Biener <rguent...@suse.de>
>wrote:
>>
>>
>> The following refactors simplify_vector_constructor and adds
>> handling of constants to it in a straight-forward way.
>>
>> A followup will handle the testcases posted in HJs patch.
>>
>> Bootstrap / regtest running on x86_64-unknown-linux-gnu.
>>
>> Richard.
>>
>> 2019-05-03  Richard Biener  <rguent...@suse.de>
>>
>>         PR tree-optimization/88828
>>         * tree-ssa-forwprop.c (get_bit_field_ref_def): Split out
>from...
>>         (simplify_vector_constructor): ...here.  Handle constants in
>>         the constructor.
>>
>>         * gcc.target/i386/pr88828-0.c: New testcase.
>>
>> Index: gcc/tree-ssa-forwprop.c
>> ===================================================================
>> --- gcc/tree-ssa-forwprop.c     (revision 270847)
>> +++ gcc/tree-ssa-forwprop.c     (working copy)
>> @@ -1997,6 +1997,44 @@ simplify_permutation (gimple_stmt_iterat
>>    return 0;
>>  }
>>
>> +/* Get the BIT_FIELD_REF definition of VAL, if any, looking through
>> +   conversions with code CONV_CODE or update it if still ERROR_MARK.
>> +   Return NULL_TREE if no such matching def was found.  */
>> +
>> +static tree
>> +get_bit_field_ref_def (tree val, enum tree_code &conv_code)

Also:
/enum tree_code/s/enum //g

i think.

thanks,

>> +{
>> +  if (TREE_CODE (val) != SSA_NAME)
>> +    return NULL_TREE ;
>> +  gimple *def_stmt = get_prop_source_stmt (val, false, NULL);
>> +  if (!def_stmt)
>> +    return NULL_TREE;
>> +  enum tree_code code = gimple_assign_rhs_code (def_stmt);
>> +  if (code == FLOAT_EXPR
>> +      || code == FIX_TRUNC_EXPR)
>> +    {
>> +      tree op1 = gimple_assign_rhs1 (def_stmt);
>> +      if (conv_code == ERROR_MARK)
>> +       {
>> +         if (maybe_ne (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (val))),
>> +                       GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op1)))))
>> +           return NULL_TREE;
>> +         conv_code = code;
>> +       }
>> +      else if (conv_code != code)
>> +       return NULL_TREE;
>> +      if (TREE_CODE (op1) != SSA_NAME)
>> +       return NULL_TREE;
>> +      def_stmt = SSA_NAME_DEF_STMT (op1);
>> +      if (! is_gimple_assign (def_stmt))
>> +       return NULL_TREE;
>> +      code = gimple_assign_rhs_code (def_stmt);
>> +    }
>> +  if (code != BIT_FIELD_REF)
>> +    return NULL_TREE;
>> +  return gimple_assign_rhs1 (def_stmt);
>> +}
>> +
>>  /* Recognize a VEC_PERM_EXPR.  Returns true if there were any
>changes.  */
>>
>>  static bool
>> @@ -2027,6 +2065,9 @@ simplify_vector_constructor (gimple_stmt
>>    orig[1] = NULL;
>>    conv_code = ERROR_MARK;
>>    maybe_ident = true;
>> +  tree one_constant = NULL_TREE;
>> +  auto_vec<tree> constants;
>> +  constants.safe_grow_cleared (nelts);
>>    FOR_EACH_VEC_SAFE_ELT (CONSTRUCTOR_ELTS (op), i, elt)
>>      {
>>        tree ref, op1;
>> @@ -2034,68 +2075,55 @@ simplify_vector_constructor (gimple_stmt
>>        if (i >= nelts)
>>         return false;
>>
>> -      if (TREE_CODE (elt->value) != SSA_NAME)
>> -       return false;
>> -      def_stmt = get_prop_source_stmt (elt->value, false, NULL);
>> -      if (!def_stmt)
>> -       return false;
>> -      code = gimple_assign_rhs_code (def_stmt);
>> -      if (code == FLOAT_EXPR
>> -         || code == FIX_TRUNC_EXPR)
>> +      op1 = get_bit_field_ref_def (elt->value, conv_code);
>> +      if (op1)
>>         {
>> -         op1 = gimple_assign_rhs1 (def_stmt);
>> -         if (conv_code == ERROR_MARK)
>> +         ref = TREE_OPERAND (op1, 0);
>> +         unsigned int j;
>> +         for (j = 0; j < 2; ++j)
>>             {
>> -             if (maybe_ne (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE
>(elt->value))),
>> -                           GET_MODE_SIZE (TYPE_MODE (TREE_TYPE
>(op1)))))
>> -               return false;
>> -             conv_code = code;
>> +             if (!orig[j])
>> +               {
>> +                 if (TREE_CODE (ref) != SSA_NAME)
>> +                   return false;
>> +                 if (! VECTOR_TYPE_P (TREE_TYPE (ref))
>> +                     || ! useless_type_conversion_p (TREE_TYPE
>(op1),
>> +                                                     TREE_TYPE
>(TREE_TYPE (ref))))
>> +                   return false;
>> +                 if (j && !useless_type_conversion_p (TREE_TYPE
>(orig[0]),
>> +                                                      TREE_TYPE
>(ref)))
>> +                   return false;
>> +                 orig[j] = ref;
>> +                 break;
>> +               }
>> +             else if (ref == orig[j])
>> +               break;
>>             }
>> -         else if (conv_code != code)
>> +         if (j == 2)
>>             return false;
>> -         if (TREE_CODE (op1) != SSA_NAME)
>> -           return false;
>> -         def_stmt = SSA_NAME_DEF_STMT (op1);
>> -         if (! is_gimple_assign (def_stmt))
>> +
>> +         unsigned int elt;
>> +         if (maybe_ne (bit_field_size (op1), elem_size)
>> +             || !constant_multiple_p (bit_field_offset (op1),
>elem_size, &elt))
>>             return false;
>> -         code = gimple_assign_rhs_code (def_stmt);
>> +         if (j)
>> +           elt += nelts;
>> +         if (elt != i)
>> +           maybe_ident = false;
>> +         sel.quick_push (elt);
>>         }
>> -      if (code != BIT_FIELD_REF)
>> -       return false;
>> -      op1 = gimple_assign_rhs1 (def_stmt);
>> -      ref = TREE_OPERAND (op1, 0);
>> -      unsigned int j;
>> -      for (j = 0; j < 2; ++j)
>> +      else if (CONSTANT_CLASS_P (elt->value))
>>         {
>> -         if (!orig[j])
>> -           {
>> -             if (TREE_CODE (ref) != SSA_NAME)
>> -               return false;
>> -             if (! VECTOR_TYPE_P (TREE_TYPE (ref))
>> -                 || ! useless_type_conversion_p (TREE_TYPE (op1),
>> -                                                 TREE_TYPE
>(TREE_TYPE (ref))))
>> -               return false;
>> -             if (j && !useless_type_conversion_p (TREE_TYPE
>(orig[0]),
>> -                                                  TREE_TYPE (ref)))
>> -               return false;
>> -             orig[j] = ref;
>> -             break;
>> -           }
>> -         else if (ref == orig[j])
>> -           break;
>
>Missing else
>                 return false;
>
>[hjl@gnu-cfl-1 pr88828]$ cat x5.i
>typedef float __v4sf __attribute__ ((__vector_size__ (16)));
>
>__v4sf
>foo (__v4sf x, float f, float z)
>{
>  __v4sf y =  { f, x[0], z, x[3] };
>  return y;
>}
>[hjl@gnu-cfl-1 pr88828]$ make x5.s
>/export/build/gnu/tools-build/gcc-wip-debug/build-x86_64-linux/gcc/xgcc
>-B/export/build/gnu/tools-build/gcc-wip-debug/build-x86_64-linux/gcc/
>-O2  -S x5.i
>during GIMPLE pass: forwprop
>x5.i: In function ‘foo’:
>x5.i:8:1: internal compiler error: in elt, at vector-builder.h:202
>    8 | }
>      | ^
>0xe3fb73 vector_builder<poly_int<1u, long>,
>int_vector_builder<poly_int<1u, long> > >::elt(unsigned int) const
>/export/gnu/import/git/gitlab/x86-gcc/gcc/vector-builder.h:202
>0x17b5665 vec_perm_indices::new_vector(int_vector_builder<poly_int<1u,
>long> > const&, unsigned int, poly_int<1u, unsigned long>)
>/export/gnu/import/git/gitlab/x86-gcc/gcc/vec-perm-indices.c:65
>0xe3f93b
>vec_perm_indices::vec_perm_indices(int_vector_builder<poly_int<1u,
>long> > const&, unsigned int, poly_int<1u, unsigned long>)
>/export/gnu/import/git/gitlab/x86-gcc/gcc/vec-perm-indices.h:112
>0x14e5fef simplify_vector_constructor
>/export/gnu/import/git/gitlab/x86-gcc/gcc/tree-ssa-forwprop.c:2155
>0x14e8676 execute
>/export/gnu/import/git/gitlab/x86-gcc/gcc/tree-ssa-forwprop.c:2693
>Please submit a full bug report,
>with preprocessed source if appropriate.
>Please include the complete backtrace with any bug report.
>See <https://gcc.gnu.org/bugs/> for instructions.
>make: *** [Makefile:19: x5.s] Error 1
>[hjl@gnu-cfl-1 pr88828]$
>
>This comes from my PR 88828 tests.
>
>> +         if (orig[1]
>> +             && orig[1] != error_mark_node)
>> +           return false;
>> +         orig[1] = error_mark_node;
>> +         if (!one_constant)
>> +           one_constant = elt->value;
>> +         constants[i] = elt->value;
>> +         sel.quick_push (i + nelts);
>> +         maybe_ident = false;
>>         }
>> -      if (j == 2)
>> -       return false;
>> -
>> -      unsigned int elt;
>> -      if (maybe_ne (bit_field_size (op1), elem_size)
>> -         || !constant_multiple_p (bit_field_offset (op1), elem_size,
>&elt))
>> -       return false;
>> -      if (j)
>> -       elt += nelts;
>> -      if (elt != i)
>> -       maybe_ident = false;
>> -      sel.quick_push (elt);
>>      }
>>    if (i < nelts)
>>      return false;
>> @@ -2138,9 +2166,29 @@ simplify_vector_constructor (gimple_stmt
>>        op2 = vec_perm_indices_to_tree (mask_type, indices);
>>        if (!orig[1])
>>         orig[1] = orig[0];
>> +      if (orig[1] == error_mark_node)
>> +       {
>> +         tree_vector_builder vec (type, nelts, 1);
>> +         for (unsigned i = 0; i < nelts; ++i)
>> +           if (constants[i])
>> +             vec.quick_push (constants[i]);
>> +           else
>> +             /* ??? Push a don't-care value.  */
>> +             vec.quick_push (one_constant);
>> +         orig[1] = vec.build ();
>> +       }
>>        if (conv_code == ERROR_MARK)
>>         gimple_assign_set_rhs_with_ops (gsi, VEC_PERM_EXPR, orig[0],
>>                                         orig[1], op2);
>> +      else if (TREE_CODE (orig[1]) == VECTOR_CST)
>> +       {
>> +         gimple *conv
>> +           = gimple_build_assign (make_ssa_name (type), conv_code,
>orig[0]);
>> +         orig[0] = gimple_assign_lhs (conv);
>> +         gsi_insert_before (gsi, conv, GSI_SAME_STMT);
>> +         gimple_assign_set_rhs_with_ops (gsi, VEC_PERM_EXPR,
>> +                                         orig[0], orig[1], op2);
>> +       }
>>        else
>>         {
>>           gimple *perm
>
>Here is the updated patch.

Reply via email to