From 27c16d845fc0f4a592e57068c2e197b7f7ee991d Mon Sep 17 00:00:00 2001 From: jakub Date: Fri, 11 May 2018 07:38:49 +0000 Subject: [PATCH] PR tree-optimization/85692 * tree-ssa-forwprop.c (simplify_vector_constructor): Try two source permute as well. * gcc.target/i386/pr85692.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@260155 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 7 ++++ gcc/testsuite/ChangeLog | 6 +++ gcc/testsuite/gcc.target/i386/pr85692.c | 18 +++++++++ gcc/tree-ssa-forwprop.c | 67 ++++++++++++++++++++------------- 4 files changed, 72 insertions(+), 26 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr85692.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 75ed3b33f70..01d3b18ab44 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2018-05-11 Allan Sandfeld Jensen + Jakub Jelinek + + PR tree-optimization/85692 + * tree-ssa-forwprop.c (simplify_vector_constructor): Try two + source permute as well. + 2018-05-11 Martin Liska PR sanitizer/85556 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ee9f633ad84..1591122913d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2018-05-11 Allan Sandfeld Jensen + Jakub Jelinek + + PR tree-optimization/85692 + * gcc.target/i386/pr85692.c: New test. + 2018-05-11 Martin Liska PR sanitizer/85556 diff --git a/gcc/testsuite/gcc.target/i386/pr85692.c b/gcc/testsuite/gcc.target/i386/pr85692.c new file mode 100644 index 00000000000..45594ff00f4 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr85692.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -msse4.1" } */ +/* { dg-final { scan-assembler "unpcklps" } } */ +/* { dg-final { scan-assembler "blendps" } } */ +/* { dg-final { scan-assembler-not "shufps" } } */ +/* { dg-final { scan-assembler-not "unpckhps" } } */ + +typedef float v4sf __attribute__ ((vector_size (16))); + +v4sf unpcklps(v4sf a, v4sf b) +{ + return (v4sf){a[0],b[0],a[1],b[1]}; +} + +v4sf blendps(v4sf a, v4sf b) +{ + return (v4sf){a[0],b[1],a[2],b[3]}; +} diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c index 58ec6b47a5b..2efb5acae8f 100644 --- a/gcc/tree-ssa-forwprop.c +++ b/gcc/tree-ssa-forwprop.c @@ -2004,7 +2004,7 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi) { gimple *stmt = gsi_stmt (*gsi); gimple *def_stmt; - tree op, op2, orig, type, elem_type; + tree op, op2, orig[2], type, elem_type; unsigned elem_size, i; unsigned HOST_WIDE_INT nelts; enum tree_code code, conv_code; @@ -2023,7 +2023,8 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi) elem_size = TREE_INT_CST_LOW (TYPE_SIZE (elem_type)); vec_perm_builder sel (nelts, nelts, 1); - orig = NULL; + orig[0] = NULL; + orig[1] = NULL; conv_code = ERROR_MARK; maybe_ident = true; FOR_EACH_VEC_SAFE_ELT (CONSTRUCTOR_ELTS (op), i, elt) @@ -2063,25 +2064,35 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi) return false; op1 = gimple_assign_rhs1 (def_stmt); ref = TREE_OPERAND (op1, 0); - if (orig) + unsigned int j; + for (j = 0; j < 2; ++j) { - if (ref != orig) - return false; - } - else - { - 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; - orig = ref; + 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; } + 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); @@ -2089,14 +2100,15 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi) if (i < nelts) return false; - if (! VECTOR_TYPE_P (TREE_TYPE (orig)) + if (! VECTOR_TYPE_P (TREE_TYPE (orig[0])) || maybe_ne (TYPE_VECTOR_SUBPARTS (type), - TYPE_VECTOR_SUBPARTS (TREE_TYPE (orig)))) + TYPE_VECTOR_SUBPARTS (TREE_TYPE (orig[0])))) return false; tree tem; if (conv_code != ERROR_MARK - && (! supportable_convert_operation (conv_code, type, TREE_TYPE (orig), + && (! supportable_convert_operation (conv_code, type, + TREE_TYPE (orig[0]), &tem, &conv_code) || conv_code == CALL_EXPR)) return false; @@ -2104,16 +2116,16 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi) if (maybe_ident) { if (conv_code == ERROR_MARK) - gimple_assign_set_rhs_from_tree (gsi, orig); + gimple_assign_set_rhs_from_tree (gsi, orig[0]); else - gimple_assign_set_rhs_with_ops (gsi, conv_code, orig, + gimple_assign_set_rhs_with_ops (gsi, conv_code, orig[0], NULL_TREE, NULL_TREE); } else { tree mask_type; - vec_perm_indices indices (sel, 1, nelts); + vec_perm_indices indices (sel, orig[1] ? 2 : 1, nelts); if (!can_vec_perm_const_p (TYPE_MODE (type), indices)) return false; mask_type @@ -2124,16 +2136,19 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi) GET_MODE_SIZE (TYPE_MODE (type)))) return false; op2 = vec_perm_indices_to_tree (mask_type, indices); + if (!orig[1]) + orig[1] = orig[0]; if (conv_code == ERROR_MARK) - gimple_assign_set_rhs_with_ops (gsi, VEC_PERM_EXPR, orig, orig, op2); + gimple_assign_set_rhs_with_ops (gsi, VEC_PERM_EXPR, orig[0], + orig[1], op2); else { gimple *perm - = gimple_build_assign (make_ssa_name (TREE_TYPE (orig)), - VEC_PERM_EXPR, orig, orig, op2); - orig = gimple_assign_lhs (perm); + = gimple_build_assign (make_ssa_name (TREE_TYPE (orig[0])), + VEC_PERM_EXPR, orig[0], orig[1], op2); + orig[0] = gimple_assign_lhs (perm); gsi_insert_before (gsi, perm, GSI_SAME_STMT); - gimple_assign_set_rhs_with_ops (gsi, conv_code, orig, + gimple_assign_set_rhs_with_ops (gsi, conv_code, orig[0], NULL_TREE, NULL_TREE); } } -- 2.11.4.GIT