This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix ICE with V1DImode ctor (PR middle-end/71626)


Hi!

This patch is an attempt to fix ICE on the following testcase.
In output_constant_pool_2 we assume that for vector modes, force_const_mem
must be a CONST_VECTOR, but for the weirdo vector modes with single element
it could very well be just a SUBREG of some other constant.
This isn't enough though, e.g. for -fpic we shouldn't force it into constant
pool constant, because it needs relocation.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2016-06-27  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/71626
	* output.h (compute_reloc_for_rtx): New prototype.
	* varasm.c (output_constant_pool_2): Handle SUBREGs for V1??mode
	vectors.
	(compute_reloc_for_rtx): No longer static.
	* config/i386/i386.c (ix86_expand_vector_move): For V1??mode SUBREG
	of scalar constant that needs relocation, force the constant into
	the inner mode reg first.

	* gcc.c-torture/execute/pr71626-1.c: New test.
	* gcc.c-torture/execute/pr71626-2.c: New test.

--- gcc/output.h.jj	2016-01-04 14:55:53.000000000 +0100
+++ gcc/output.h	2016-06-27 12:21:41.529484513 +0200
@@ -349,6 +349,9 @@ extern bool decl_readonly_section (const
    given a constant expression.  */
 extern int compute_reloc_for_constant (tree);
 
+/* Similarly, but for RTX.  */
+extern int compute_reloc_for_rtx (const_rtx);
+
 /* User label prefix in effect for this compilation.  */
 extern const char *user_label_prefix;
 
--- gcc/varasm.c.jj	2016-06-10 20:24:03.000000000 +0200
+++ gcc/varasm.c	2016-06-27 12:21:36.062553957 +0200
@@ -3834,6 +3834,17 @@ output_constant_pool_2 (machine_mode mod
         machine_mode submode = GET_MODE_INNER (mode);
 	unsigned int subalign = MIN (align, GET_MODE_BITSIZE (submode));
 
+	/* For V1??mode, allow SUBREGs.  */
+	if (GET_CODE (x) == SUBREG
+	    && GET_MODE_NUNITS (mode) == 1
+	    && GET_MODE_BITSIZE (submode) == GET_MODE_BITSIZE (mode)
+	    && SUBREG_BYTE (x) == 0
+	    && GET_MODE (SUBREG_REG (x)) == submode)
+	  {
+	    output_constant_pool_2 (submode, SUBREG_REG (x), align);
+	    break;
+	  }
+
 	gcc_assert (GET_CODE (x) == CONST_VECTOR);
 	units = CONST_VECTOR_NUNITS (x);
 
@@ -6637,7 +6648,7 @@ compute_reloc_for_rtx_1 (const_rtx x)
    is a mask for which bit 1 indicates a global relocation, and bit 0
    indicates a local relocation.  */
 
-static int
+int
 compute_reloc_for_rtx (const_rtx x)
 {
   switch (GET_CODE (x))
--- gcc/config/i386/i386.c.jj	2016-06-24 12:59:29.000000000 +0200
+++ gcc/config/i386/i386.c	2016-06-27 12:23:15.504290801 +0200
@@ -19605,6 +19605,20 @@ ix86_expand_vector_move (machine_mode mo
   if (push_operand (op0, VOIDmode))
     op0 = emit_move_resolve_push (mode, op0);
 
+  /* For V1XXmode subregs of scalar constants, force the scalar into
+     reg first if it would need relocations.  */
+  if (SUBREG_P (op1)
+      && CONSTANT_P (SUBREG_REG (op1))
+      && VECTOR_MODE_P (mode)
+      && GET_MODE_NUNITS (mode) == 1
+      && GET_MODE (SUBREG_REG (op1)) == GET_MODE_INNER (mode)
+      && compute_reloc_for_rtx (SUBREG_REG (op1)))
+    {
+      rtx r = force_reg (GET_MODE (SUBREG_REG (op1)), SUBREG_REG (op1));
+      op1 = simplify_gen_subreg (mode, r, GET_MODE (SUBREG_REG (op1)),
+				 SUBREG_BYTE (op1));
+    }
+
   /* Force constants other than zero into memory.  We do not know how
      the instructions used to build constants modify the upper 64 bits
      of the register, once we have that information we may be able
--- gcc/testsuite/gcc.c-torture/execute/pr71626-1.c.jj	2016-06-27 12:31:51.689755677 +0200
+++ gcc/testsuite/gcc.c-torture/execute/pr71626-1.c	2016-06-27 12:31:05.078344165 +0200
@@ -0,0 +1,19 @@
+/* PR middle-end/71626 */
+
+typedef __INTPTR_TYPE__ V __attribute__((__vector_size__(sizeof (__INTPTR_TYPE__))));
+
+__attribute__((noinline, noclone)) V
+foo ()
+{
+  V v = { (__INTPTR_TYPE__) foo };
+  return v;
+}
+
+int
+main ()
+{
+  V v = foo ();
+  if (v[0] != (__INTPTR_TYPE__) foo)
+    __builtin_abort ();
+  return 0;
+}
--- gcc/testsuite/gcc.c-torture/execute/pr71626-2.c.jj	2016-06-27 12:31:54.837715933 +0200
+++ gcc/testsuite/gcc.c-torture/execute/pr71626-2.c	2016-06-27 12:31:47.977802542 +0200
@@ -0,0 +1,4 @@
+/* PR middle-end/71626 */
+/* { dg-additional-options "-fpic" { target fpic } } */
+
+#include "pr71626-1.c"

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]