public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Prep for PR88828 fix
@ 2019-05-03 13:02 Richard Biener
  2019-05-03 16:48 ` H.J. Lu
  0 siblings, 1 reply; 4+ messages in thread
From: Richard Biener @ 2019-05-03 13:02 UTC (permalink / raw)
  To: gcc-patches


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  <rguenther@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)
+{
+  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;
+	  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
Index: gcc/testsuite/gcc.target/i386/pr88828-0.c
===================================================================
--- gcc/testsuite/gcc.target/i386/pr88828-0.c	(nonexistent)
+++ gcc/testsuite/gcc.target/i386/pr88828-0.c	(working copy)
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -msse4.2" } */
+
+typedef int v4si __attribute__((vector_size(16)));
+typedef float v4sf __attribute__((vector_size(16)));
+
+v4si foo (v4si x)
+{
+  return (v4si){ x[0], 1, x[2], 3 };
+}
+
+/* { dg-final { scan-assembler "pblendw" } } */
+
+v4si bar (v4sf x)
+{
+  return (v4si){ 1, x[1], x[2], 3 };
+}
+
+/* { dg-final { scan-assembler "cvttps2dq" } } */
+/* { dg-final { scan-assembler "pblendw" } } */
+
+v4si baz (v4si x)
+{
+  return (v4si) { x[1], x[2], x[3], 0 };
+}
+
+/* { dg-final { scan-assembler "psrldq" } } */

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] Prep for PR88828 fix
  2019-05-03 13:02 [PATCH] Prep for PR88828 fix Richard Biener
@ 2019-05-03 16:48 ` H.J. Lu
  2019-05-06 12:42   ` Richard Biener
  2019-05-06 19:16   ` Bernhard Reutner-Fischer
  0 siblings, 2 replies; 4+ messages in thread
From: H.J. Lu @ 2019-05-03 16:48 UTC (permalink / raw)
  To: Richard Biener; +Cc: GCC Patches

[-- Attachment #1: Type: text/plain, Size: 9904 bytes --]

On Fri, May 3, 2019 at 6:02 AM Richard Biener <rguenther@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  <rguenther@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)
> +{
> +  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.

-- 
H.J.

[-- Attachment #2: 0001-Prep-for-PR88828-fix.patch --]
[-- Type: text/x-patch, Size: 8019 bytes --]

From 3d306956a4de03cf725448101ba5d4bd438cd441 Mon Sep 17 00:00:00 2001
From: Richard Biener <rguenther@suse.de>
Date: Fri, 3 May 2019 08:22:12 -0700
Subject: [PATCH] Prep for PR88828 fix

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.

2019-05-03  Richard Biener  <rguenther@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.
---
 gcc/testsuite/gcc.target/i386/pr88828-0.c |  27 ++++
 gcc/tree-ssa-forwprop.c                   | 159 ++++++++++++++--------
 2 files changed, 131 insertions(+), 55 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/i386/pr88828-0.c

diff --git a/gcc/testsuite/gcc.target/i386/pr88828-0.c b/gcc/testsuite/gcc.target/i386/pr88828-0.c
new file mode 100644
index 00000000000..3ddb2d13526
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr88828-0.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -msse4.2" } */
+
+typedef int v4si __attribute__((vector_size(16)));
+typedef float v4sf __attribute__((vector_size(16)));
+
+v4si foo (v4si x)
+{
+  return (v4si){ x[0], 1, x[2], 3 };
+}
+
+/* { dg-final { scan-assembler "pblendw" } } */
+
+v4si bar (v4sf x)
+{
+  return (v4si){ 1, x[1], x[2], 3 };
+}
+
+/* { dg-final { scan-assembler "cvttps2dq" } } */
+/* { dg-final { scan-assembler "pblendw" } } */
+
+v4si baz (v4si x)
+{
+  return (v4si) { x[1], x[2], x[3], 0 };
+}
+
+/* { dg-final { scan-assembler "psrldq" } } */
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
index 1553c9e70ac..7dd1e64335a 100644
--- a/gcc/tree-ssa-forwprop.c
+++ b/gcc/tree-ssa-forwprop.c
@@ -1997,17 +1997,54 @@ simplify_permutation (gimple_stmt_iterator *gsi)
   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)
+{
+  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
 simplify_vector_constructor (gimple_stmt_iterator *gsi)
 {
   gimple *stmt = gsi_stmt (*gsi);
-  gimple *def_stmt;
   tree op, op2, orig[2], type, elem_type;
   unsigned elem_size, i;
   unsigned HOST_WIDE_INT nelts;
-  enum tree_code code, conv_code;
+  enum tree_code conv_code;
   constructor_elt *elt;
   bool maybe_ident;
 
@@ -2027,6 +2064,9 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi)
   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 +2074,57 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi)
       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)
-	    return false;
-	  if (TREE_CODE (op1) != SSA_NAME)
+	  if (j == 2)
 	    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;
+	  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))
+      else
 	return false;
-      if (j)
-	elt += nelts;
-      if (elt != i)
-	maybe_ident = false;
-      sel.quick_push (elt);
     }
   if (i < nelts)
     return false;
@@ -2138,9 +2167,29 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi)
       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
-- 
2.20.1


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] Prep for PR88828 fix
  2019-05-03 16:48 ` H.J. Lu
@ 2019-05-06 12:42   ` Richard Biener
  2019-05-06 19:16   ` Bernhard Reutner-Fischer
  1 sibling, 0 replies; 4+ messages in thread
From: Richard Biener @ 2019-05-06 12:42 UTC (permalink / raw)
  To: H.J. Lu; +Cc: GCC Patches

On Fri, 3 May 2019, H.J. Lu wrote:

> On Fri, May 3, 2019 at 6:02 AM Richard Biener <rguenther@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.
...
> > -             orig[j] = ref;
> > -             break;
> > -           }
> > -         else if (ref == orig[j])
> > -           break;
> 
> Missing else
>                  return false;

Oops, indeed.

The following is what I have applied after bootstrap/regtest on 
x86_64-unknown-linux-gnu.

Richard.

2019-05-06  Richard Biener  <rguenther@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 270902)
+++ gcc/tree-ssa-forwprop.c	(working copy)
@@ -1997,17 +1997,54 @@ 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)
+{
+  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
 simplify_vector_constructor (gimple_stmt_iterator *gsi)
 {
   gimple *stmt = gsi_stmt (*gsi);
-  gimple *def_stmt;
   tree op, op2, orig[2], type, elem_type;
   unsigned elem_size, i;
   unsigned HOST_WIDE_INT nelts;
-  enum tree_code code, conv_code;
+  enum tree_code conv_code;
   constructor_elt *elt;
   bool maybe_ident;
 
@@ -2027,6 +2064,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 +2074,57 @@ 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;
+	  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))
+      else
 	return false;
-      if (j)
-	elt += nelts;
-      if (elt != i)
-	maybe_ident = false;
-      sel.quick_push (elt);
     }
   if (i < nelts)
     return false;
@@ -2138,9 +2167,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
Index: gcc/testsuite/gcc.target/i386/pr88828-0.c
===================================================================
--- gcc/testsuite/gcc.target/i386/pr88828-0.c	(nonexistent)
+++ gcc/testsuite/gcc.target/i386/pr88828-0.c	(working copy)
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -msse4.2" } */
+
+typedef int v4si __attribute__((vector_size(16)));
+typedef float v4sf __attribute__((vector_size(16)));
+
+v4si foo (v4si x)
+{
+  return (v4si){ x[0], 1, x[2], 3 };
+}
+
+/* { dg-final { scan-assembler "pblendw" } } */
+
+v4si bar (v4sf x)
+{
+  return (v4si){ 1, x[1], x[2], 3 };
+}
+
+/* { dg-final { scan-assembler "cvttps2dq" } } */
+/* { dg-final { scan-assembler "pblendw" } } */
+
+v4si baz (v4si x)
+{
+  return (v4si) { x[1], x[2], x[3], 0 };
+}
+
+/* { dg-final { scan-assembler "psrldq" } } */

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] Prep for PR88828 fix
  2019-05-03 16:48 ` H.J. Lu
  2019-05-06 12:42   ` Richard Biener
@ 2019-05-06 19:16   ` Bernhard Reutner-Fischer
  1 sibling, 0 replies; 4+ messages in thread
From: Bernhard Reutner-Fischer @ 2019-05-06 19:16 UTC (permalink / raw)
  To: gcc-patches, H.J. Lu, Richard Biener; +Cc: GCC Patches

On 3 May 2019 18:48:09 CEST, "H.J. Lu" <hjl.tools@gmail.com> wrote:
>On Fri, May 3, 2019 at 6:02 AM Richard Biener <rguenther@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  <rguenther@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.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2019-05-06 19:16 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-05-03 13:02 [PATCH] Prep for PR88828 fix Richard Biener
2019-05-03 16:48 ` H.J. Lu
2019-05-06 12:42   ` Richard Biener
2019-05-06 19:16   ` Bernhard Reutner-Fischer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).