This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix ICE with V1DImode ctor (PR middle-end/71626)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Richard Biener <rguenther at suse dot de>, Uros Bizjak <ubizjak at gmail dot com>, Eric Botcazou <ebotcazou at adacore dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Mon, 27 Jun 2016 20:16:18 +0200
- Subject: [PATCH] Fix ICE with V1DImode ctor (PR middle-end/71626)
- Authentication-results: sourceware.org; auth=none
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
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