From 4dd96316aacffd11c3a0da8fce87d8cc295e6366 Mon Sep 17 00:00:00 2001
From: y00520163 <yangyang305@huawei.com>
Date: Wed, 15 Jul 2020 19:53:52 +0800
Subject: [PATCH] vect: Fix an ICE in vectorizable_simd_clone_call

In vectorizable_simd_clone_call, type compatibility is handled based on
the number of elements and the type compatibility of elements, which is
not enough. This patch add VIEW_CONVERT_EXPRs if the arguments types
and return type of simd clone function are distinct with the vectype of
stmt.

2020-07-15  Yang Yang <yangyang305@huawei.com>

gcc/ChangeLog:

	* tree-vect-stmts.c (vectorizable_simd_clone_call): Add
	VIEW_CONVERT_EXPRs if the arguments types and return type
	of simd clone function are distinct with the vectype of stmt.

gcc/testsuite/ChangeLog:

	* gcc.target/aarch64/sve/pr96195.c: New test.
---
 .../gcc.target/aarch64/sve/pr96195.c          | 17 +++++++++++++
 gcc/tree-vect-stmts.c                         | 25 ++++++++++++++++---
 2 files changed, 39 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/pr96195.c

diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pr96195.c b/gcc/testsuite/gcc.target/aarch64/sve/pr96195.c
new file mode 100644
index 00000000000..d879efda5c8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/pr96195.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fopenmp-simd -ftree-vectorize -msve-vector-bits=128" } */
+
+int by;
+
+#pragma omp declare simd
+int
+zp (int);
+
+void
+qh (int oh)
+{
+#pragma omp simd
+  for (by = 0; by < oh; ++by)
+    by = zp (by);
+}
+
diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
index 6730cae8085..8301494fa41 100644
--- a/gcc/tree-vect-stmts.c
+++ b/gcc/tree-vect-stmts.c
@@ -4108,7 +4108,20 @@ vectorizable_simd_clone_call (vec_info *vinfo, stmt_vec_info stmt_info,
 						  vec_oprnd0);
 			}
 		      if (k == 1)
-			vargs.safe_push (vec_oprnd0);
+			if (!useless_type_conversion_p (TREE_TYPE (vec_oprnd0),
+						       atype))
+			  {
+			    vec_oprnd0
+			      = build1 (VIEW_CONVERT_EXPR, atype, vec_oprnd0);
+			    gassign *new_stmt
+			      = gimple_build_assign (make_ssa_name (atype),
+						       vec_oprnd0);
+			    vect_finish_stmt_generation (vinfo, stmt_info,
+							 new_stmt, gsi);
+			    vargs.safe_push (gimple_assign_lhs (new_stmt));
+			  }
+			else
+			  vargs.safe_push (vec_oprnd0);
 		      else
 			{
 			  vec_oprnd0 = build_constructor (atype, ctor_elts);
@@ -4204,8 +4217,7 @@ vectorizable_simd_clone_call (vec_info *vinfo, stmt_vec_info stmt_info,
 	  gcc_assert (ratype || simd_clone_subparts (rtype) == nunits);
 	  if (ratype)
 	    new_temp = create_tmp_var (ratype);
-	  else if (simd_clone_subparts (vectype)
-		   == simd_clone_subparts (rtype))
+	  else if (useless_type_conversion_p (vectype, rtype))
 	    new_temp = make_ssa_name (vec_dest, new_call);
 	  else
 	    new_temp = make_ssa_name (rtype, new_call);
@@ -4293,6 +4305,13 @@ vectorizable_simd_clone_call (vec_info *vinfo, stmt_vec_info stmt_info,
 	      vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi);
 	      vect_clobber_variable (vinfo, stmt_info, gsi, new_temp);
 	    }
+	  else if (!useless_type_conversion_p (vectype, rtype))
+	    {
+	      vec_oprnd0 = build1 (VIEW_CONVERT_EXPR, vectype, new_temp);
+	      new_stmt
+		= gimple_build_assign (make_ssa_name (vec_dest), vec_oprnd0);
+	      vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi);
+	    }
 	}
 
       if (j == 0)
-- 
2.19.1

