On 3 May 2019 18:48:09 CEST, "H.J. Lu" <[email protected]> wrote:
>On Fri, May 3, 2019 at 6:02 AM Richard Biener <[email protected]>
>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 <[email protected]>
>>
>> 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.