Commit 5a599c46 by Allan Sandfeld Jensen Committed by Jakub Jelinek

re PR tree-optimization/85692 (Two source permute not used for vector initialization)

	PR tree-optimization/85692
	* tree-ssa-forwprop.c (simplify_vector_constructor): Try two
	source permute as well.

	* gcc.target/i386/pr85692.c: New test.

Co-Authored-By: Jakub Jelinek <jakub@redhat.com>

From-SVN: r260155
parent 19916065
2018-05-11 Allan Sandfeld Jensen <allan.jensen@qt.io>
Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/85692
* tree-ssa-forwprop.c (simplify_vector_constructor): Try two
source permute as well.
2018-05-11 Martin Liska <mliska@suse.cz> 2018-05-11 Martin Liska <mliska@suse.cz>
PR sanitizer/85556 PR sanitizer/85556
......
2018-05-11 Allan Sandfeld Jensen <allan.jensen@qt.io>
Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/85692
* gcc.target/i386/pr85692.c: New test.
2018-05-11 Martin Liska <mliska@suse.cz> 2018-05-11 Martin Liska <mliska@suse.cz>
PR sanitizer/85556 PR sanitizer/85556
......
/* { 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]};
}
...@@ -2004,7 +2004,7 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi) ...@@ -2004,7 +2004,7 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi)
{ {
gimple *stmt = gsi_stmt (*gsi); gimple *stmt = gsi_stmt (*gsi);
gimple *def_stmt; gimple *def_stmt;
tree op, op2, orig, type, elem_type; tree op, op2, orig[2], type, elem_type;
unsigned elem_size, i; unsigned elem_size, i;
unsigned HOST_WIDE_INT nelts; unsigned HOST_WIDE_INT nelts;
enum tree_code code, conv_code; enum tree_code code, conv_code;
...@@ -2023,7 +2023,8 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi) ...@@ -2023,7 +2023,8 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi)
elem_size = TREE_INT_CST_LOW (TYPE_SIZE (elem_type)); elem_size = TREE_INT_CST_LOW (TYPE_SIZE (elem_type));
vec_perm_builder sel (nelts, nelts, 1); vec_perm_builder sel (nelts, nelts, 1);
orig = NULL; orig[0] = NULL;
orig[1] = NULL;
conv_code = ERROR_MARK; conv_code = ERROR_MARK;
maybe_ident = true; maybe_ident = true;
FOR_EACH_VEC_SAFE_ELT (CONSTRUCTOR_ELTS (op), i, elt) FOR_EACH_VEC_SAFE_ELT (CONSTRUCTOR_ELTS (op), i, elt)
...@@ -2063,25 +2064,35 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi) ...@@ -2063,25 +2064,35 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi)
return false; return false;
op1 = gimple_assign_rhs1 (def_stmt); op1 = gimple_assign_rhs1 (def_stmt);
ref = TREE_OPERAND (op1, 0); ref = TREE_OPERAND (op1, 0);
if (orig) unsigned int j;
for (j = 0; j < 2; ++j)
{ {
if (ref != orig) if (!orig[j])
return false; {
} if (TREE_CODE (ref) != SSA_NAME)
else return false;
{ if (! VECTOR_TYPE_P (TREE_TYPE (ref))
if (TREE_CODE (ref) != SSA_NAME) || ! useless_type_conversion_p (TREE_TYPE (op1),
return false; TREE_TYPE (TREE_TYPE (ref))))
if (! VECTOR_TYPE_P (TREE_TYPE (ref)) return false;
|| ! useless_type_conversion_p (TREE_TYPE (op1), if (j && !useless_type_conversion_p (TREE_TYPE (orig[0]),
TREE_TYPE (TREE_TYPE (ref)))) TREE_TYPE (ref)))
return false; return false;
orig = ref; orig[j] = ref;
break;
}
else if (ref == orig[j])
break;
} }
if (j == 2)
return false;
unsigned int elt; unsigned int elt;
if (maybe_ne (bit_field_size (op1), elem_size) if (maybe_ne (bit_field_size (op1), elem_size)
|| !constant_multiple_p (bit_field_offset (op1), elem_size, &elt)) || !constant_multiple_p (bit_field_offset (op1), elem_size, &elt))
return false; return false;
if (j)
elt += nelts;
if (elt != i) if (elt != i)
maybe_ident = false; maybe_ident = false;
sel.quick_push (elt); sel.quick_push (elt);
...@@ -2089,14 +2100,15 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi) ...@@ -2089,14 +2100,15 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi)
if (i < nelts) if (i < nelts)
return false; return false;
if (! VECTOR_TYPE_P (TREE_TYPE (orig)) if (! VECTOR_TYPE_P (TREE_TYPE (orig[0]))
|| maybe_ne (TYPE_VECTOR_SUBPARTS (type), || maybe_ne (TYPE_VECTOR_SUBPARTS (type),
TYPE_VECTOR_SUBPARTS (TREE_TYPE (orig)))) TYPE_VECTOR_SUBPARTS (TREE_TYPE (orig[0]))))
return false; return false;
tree tem; tree tem;
if (conv_code != ERROR_MARK 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) &tem, &conv_code)
|| conv_code == CALL_EXPR)) || conv_code == CALL_EXPR))
return false; return false;
...@@ -2104,16 +2116,16 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi) ...@@ -2104,16 +2116,16 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi)
if (maybe_ident) if (maybe_ident)
{ {
if (conv_code == ERROR_MARK) if (conv_code == ERROR_MARK)
gimple_assign_set_rhs_from_tree (gsi, orig); gimple_assign_set_rhs_from_tree (gsi, orig[0]);
else 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); NULL_TREE, NULL_TREE);
} }
else else
{ {
tree mask_type; 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)) if (!can_vec_perm_const_p (TYPE_MODE (type), indices))
return false; return false;
mask_type mask_type
...@@ -2124,16 +2136,19 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi) ...@@ -2124,16 +2136,19 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi)
GET_MODE_SIZE (TYPE_MODE (type)))) GET_MODE_SIZE (TYPE_MODE (type))))
return false; return false;
op2 = vec_perm_indices_to_tree (mask_type, indices); op2 = vec_perm_indices_to_tree (mask_type, indices);
if (!orig[1])
orig[1] = orig[0];
if (conv_code == ERROR_MARK) 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 else
{ {
gimple *perm gimple *perm
= gimple_build_assign (make_ssa_name (TREE_TYPE (orig)), = gimple_build_assign (make_ssa_name (TREE_TYPE (orig[0])),
VEC_PERM_EXPR, orig, orig, op2); VEC_PERM_EXPR, orig[0], orig[1], op2);
orig = gimple_assign_lhs (perm); orig[0] = gimple_assign_lhs (perm);
gsi_insert_before (gsi, perm, GSI_SAME_STMT); 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); NULL_TREE, NULL_TREE);
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment