From 0daaf8aa4d32fee71136021003bca60cc350a04e Mon Sep 17 00:00:00 2001
From: Jakub Jelinek <jakub@redhat.com>
Date: Fri, 21 Nov 2014 10:23:26 +0100
Subject: [PATCH] re PR target/63910 (ICE: simplify_immed_subreg, at
 simplify-rtx.c:5519 with -mstringop-strategy=vector_loop -mavx512f)

	PR target/63910
	* simplify-rtx.c (simplify_immed_subreg): Return NULL for integer
	modes wider than MAX_BITSIZE_MODE_ANY_INT.  If not using
	CONST_WIDE_INT, make sure r fits into CONST_DOUBLE.

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

From-SVN: r217908
---
 gcc/ChangeLog                           |  7 +++++++
 gcc/simplify-rtx.c                      |  9 +++++++--
 gcc/testsuite/ChangeLog                 |  5 +++++
 gcc/testsuite/gcc.target/i386/pr63910.c | 12 ++++++++++++
 4 files changed, 31 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/i386/pr63910.c

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index bf03c81160b0..9f03c0f24322 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2014-11-21  Jakub Jelinek  <jakub@redhat.com>
+
+	PR target/63910
+	* simplify-rtx.c (simplify_immed_subreg): Return NULL for integer
+	modes wider than MAX_BITSIZE_MODE_ANY_INT.  If not using
+	CONST_WIDE_INT, make sure r fits into CONST_DOUBLE.
+
 2014-11-21  Markus Trippelsdorf  <markus@trippelsdorf.de>
 
 	* config/rs6000/rs6000.c (includes_rldic_lshift_p): Use
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index 022e36fe7c03..98d4cebf94f7 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -5504,6 +5504,8 @@ simplify_immed_subreg (machine_mode outermode, rtx op,
 	    HOST_WIDE_INT tmp[MAX_BITSIZE_MODE_ANY_INT / HOST_BITS_PER_WIDE_INT];
 	    wide_int r;
 
+	    if (GET_MODE_PRECISION (outer_submode) > MAX_BITSIZE_MODE_ANY_INT)
+	      return NULL_RTX;
 	    for (u = 0; u < units; u++)
 	      {
 		unsigned HOST_WIDE_INT buf = 0;
@@ -5515,10 +5517,13 @@ simplify_immed_subreg (machine_mode outermode, rtx op,
 		tmp[u] = buf;
 		base += HOST_BITS_PER_WIDE_INT;
 	      }
-	    gcc_assert (GET_MODE_PRECISION (outer_submode)
-			<= MAX_BITSIZE_MODE_ANY_INT);
 	    r = wide_int::from_array (tmp, units,
 				      GET_MODE_PRECISION (outer_submode));
+#if TARGET_SUPPORTS_WIDE_INT == 0
+	    /* Make sure r will fit into CONST_INT or CONST_DOUBLE.  */
+	    if (wi::min_precision (r, SIGNED) > HOST_BITS_PER_DOUBLE_INT)
+	      return NULL_RTX;
+#endif
 	    elems[elem] = immed_wide_int_const (r, outer_submode);
 	  }
 	  break;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 9e0c6b826b18..f065cc24c192 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2014-11-21  Jakub Jelinek  <jakub@redhat.com>
+
+	PR target/63910
+	* gcc.target/i386/pr63910.c: New test.
+
 2014-11-21  Francois-Xavier Coudert  <fxcoudert@gcc.gnu.org>
 
 	PR lto/63998
diff --git a/gcc/testsuite/gcc.target/i386/pr63910.c b/gcc/testsuite/gcc.target/i386/pr63910.c
new file mode 100644
index 000000000000..2d5b3b8fe242
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr63910.c
@@ -0,0 +1,12 @@
+/* PR target/63910 */
+/* { dg-do compile } */
+/* { dg-options "-O -mstringop-strategy=vector_loop -mavx512f" } */
+
+extern void bar (float *c);
+
+void
+foo (void)
+{
+  float c[1024] = { };
+  bar (c);
+}
-- 
GitLab