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.