From 518b0cf9433914f437631f16816cfb564fcce285 Mon Sep 17 00:00:00 2001
From: Fei Yang <felix.yang@huawei.com>
Date: Mon, 27 Apr 2020 15:04:57 +0800
Subject: [PATCH] forwprop: Fix ICE when building an identity constructor
 [PR94784]

In the testcase for PR94784, we have two vectors with the same ABI identity
but with different TYPE_MODEs. It would be better to flip the assert around
so that it checks that the two vectors have equal TYPE_VECTOR_SUBPARTS and
that converting the corresponding element types is a useless_type_conversion_p.

2020-04-27  Felix Yang  <felix.yang@huawei.com>

gcc/
    PR tree-optimization/94784
    * tree-ssa-forwprop.c (simplify_vector_constructor): Flip the
    assert around so that it checks that the two vectors have equal
    TYPE_VECTOR_SUBPARTS and that converting the corresponding element
    types is a useless_type_conversion_p.

gcc/testsuite/
    PR tree-optimization/94784
    * gcc.dg/pr94784.c: New test.
---
 gcc/ChangeLog                  | 11 +++++++++--
 gcc/testsuite/ChangeLog        |  5 +++++
 gcc/testsuite/gcc.dg/pr94784.c | 16 ++++++++++++++++
 gcc/tree-ssa-forwprop.c        | 14 ++++++++++++--
 4 files changed, 42 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/pr94784.c

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 38dd5837e20..03f73c736ff 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2020-04-27  Felix Yang  <felix.yang@huawei.com>
+
+	PR tree-optimization/94784
+	* tree-ssa-forwprop.c (simplify_vector_constructor): Flip the
+	assert around so that it checks that the two vectors have equal
+	TYPE_VECTOR_SUBPARTS and that converting the corresponding element
+	types is a useless_type_conversion_p.
+
 2020-04-25  David Edelsohn  <dje.gcc@gmail.com>
 
 	* config/rs6000/rs6000-logue.c (rs6000_stack_info): Don't push a
@@ -1790,8 +1798,7 @@
 
 	PR tree-optimization/94269
 	* tree-ssa-math-opts.c (convert_plusminus_to_widen): Restrict
-	this
-	operation to single basic block.
+	this operation to single basic block.
 
 2020-03-25  Jeff Law  <law@redhat.com>
 
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 07fe8a68598..cfc7b13985d 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2020-04-27  Felix Yang  <felix.yang@huawei.com>
+
+	PR tree-optimization/94784
+	* gcc.dg/pr94784.c: New test.
+
 2020-04-26  Iain Sandoe  <iain@sandoe.co.uk>
 
 	PR c++/94752
diff --git a/gcc/testsuite/gcc.dg/pr94784.c b/gcc/testsuite/gcc.dg/pr94784.c
new file mode 100644
index 00000000000..df6972f64aa
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr94784.c
@@ -0,0 +1,16 @@
+/* { dg-do compile { target aarch64*-*-* } } */
+/* { dg-options "-O2 -ftree-slp-vectorize -march=armv8.2-a+sve -msve-vector-bits=256" } */
+
+typedef short __attribute__((vector_size (8))) v4hi;
+
+typedef union U4HI { v4hi v; short a[4]; } u4hi;
+
+short a[4];
+
+void pass_v4hi (v4hi v) {
+    int j;
+    u4hi u;
+    u.v = v;
+    for (j = 0; j < 4; j++)
+      a[j] = u.a[j];
+};
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
index 8ee5450b94c..7cfb18bd618 100644
--- a/gcc/tree-ssa-forwprop.c
+++ b/gcc/tree-ssa-forwprop.c
@@ -2479,7 +2479,12 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi)
 	  tree src_type = TREE_TYPE (orig[0]);
 	  if (!useless_type_conversion_p (type, src_type))
 	    {
-	      gcc_assert (!targetm.compatible_vector_types_p (type, src_type));
+	      gcc_assert (TYPE_VECTOR_SUBPARTS (type).is_constant ()
+			  && TYPE_VECTOR_SUBPARTS (src_type).is_constant ()
+			  && (TYPE_VECTOR_SUBPARTS (type).to_constant ()
+			      == TYPE_VECTOR_SUBPARTS (src_type).to_constant ())
+			  && useless_type_conversion_p (TREE_TYPE (type),
+							TREE_TYPE (src_type)));
 	      tree rhs = build1 (VIEW_CONVERT_EXPR, type, orig[0]);
 	      orig[0] = make_ssa_name (type);
 	      gassign *assign = gimple_build_assign (orig[0], rhs);
@@ -2611,7 +2616,12 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi)
 	res = gimple_build (&stmts, conv_code, type, res);
       else if (!useless_type_conversion_p (type, TREE_TYPE (res)))
 	{
-	  gcc_assert (!targetm.compatible_vector_types_p (type, perm_type));
+	  gcc_assert (TYPE_VECTOR_SUBPARTS (type).is_constant ()
+		      && TYPE_VECTOR_SUBPARTS (perm_type).is_constant ()
+		      && (TYPE_VECTOR_SUBPARTS (type).to_constant ()
+			  == TYPE_VECTOR_SUBPARTS (perm_type).to_constant ())
+		      && useless_type_conversion_p (TREE_TYPE (type),
+						    TREE_TYPE (perm_type)));
 	  res = gimple_build (&stmts, VIEW_CONVERT_EXPR, type, res);
 	}
       /* Blend in the actual constant.  */
-- 
2.19.1

