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, take 2)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Richard Biener <rguenther at suse dot de>, Uros Bizjak <ubizjak at gmail dot com>
- Cc: Eric Botcazou <ebotcazou at adacore dot com>, gcc-patches at gcc dot gnu dot org
- Date: Tue, 28 Jun 2016 11:27:16 +0200
- Subject: [PATCH] Fix ICE with V1DImode ctor (PR middle-end/71626, take 2)
- Authentication-results: sourceware.org; auth=none
- References: <20160627181618 dot GQ7387 at tucnak dot redhat dot com> <alpine dot LSU dot 2 dot 11 dot 1606280906500 dot 29772 at t29 dot fhfr dot qr>
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
On Tue, Jun 28, 2016 at 09:15:13AM +0200, Richard Biener wrote:
> I wonder why we can rely on the MODE_FLOAT case not seeing
> (subreg:DF (reg:V2DF ) 0) but have to handle
> (subreg:V1DF (reg:DF ...) 0) in the MODE_VECTOR case.
Seems all of force_const_mem is just unprepared to handle SUBREGs
of CONSTANT_P, IMNSHO the bug is that callers shouldn't be trying
to do that.
So, this patch instead changes ix86_expand_vector_move, so that
for SUBREGs it forces the SUBREG_REG into memory (or register if
that fails, though I don't have a testcase for when that would happen),
and just re-creates a SUBREG on the forced MEM (for whole size
SUBREGs that is in the end just using different mode for the MEM).
Ok for trunk if it passes bootstrap/regtest?
I have tried the PR32065 testcase, but we don't end up with SUBREG
in that case, since we have CONST_WIDE_INT support in ix86 backend.
The relocation issue is solved by this automatically, the constant pool
code without the unexpected SUBREG around it figures for -fpic out that
there are relocations needed and uses .data.rel.ro section instead of
.rodata.*.
2016-06-28 Jakub Jelinek <jakub@redhat.com>
PR middle-end/71626
* config/i386/i386.c (ix86_expand_vector_move): For SUBREG of
a constant, force its SUBREG_REG into memory or register instead
of whole op1.
* gcc.c-torture/execute/pr71626-1.c: New test.
* gcc.c-torture/execute/pr71626-2.c: New test.
--- gcc/config/i386/i386.c.jj 2016-06-27 14:50:51.000000000 +0200
+++ gcc/config/i386/i386.c 2016-06-28 10:51:18.444624190 +0200
@@ -19610,12 +19610,29 @@ ix86_expand_vector_move (machine_mode mo
of the register, once we have that information we may be able
to handle some of them more efficiently. */
if (can_create_pseudo_p ()
- && register_operand (op0, mode)
&& (CONSTANT_P (op1)
|| (SUBREG_P (op1)
&& CONSTANT_P (SUBREG_REG (op1))))
- && !standard_sse_constant_p (op1, mode))
- op1 = validize_mem (force_const_mem (mode, op1));
+ && ((register_operand (op0, mode)
+ && !standard_sse_constant_p (op1, mode))
+ /* ix86_expand_vector_move_misalign() does not like constants. */
+ || (SSE_REG_MODE_P (mode)
+ && MEM_P (op0)
+ && MEM_ALIGN (op0) < align)))
+ {
+ if (SUBREG_P (op1))
+ {
+ machine_mode imode = GET_MODE (SUBREG_REG (op1));
+ rtx r = force_const_mem (imode, SUBREG_REG (op1));
+ if (r)
+ r = validize_mem (r);
+ else
+ r = force_reg (imode, SUBREG_REG (op1));
+ op1 = simplify_gen_subreg (mode, r, imode, SUBREG_BYTE (op1));
+ }
+ else
+ op1 = validize_mem (force_const_mem (mode, op1));
+ }
/* We need to check memory alignment for SSE mode since attribute
can make operands unaligned. */
@@ -19626,13 +19643,8 @@ ix86_expand_vector_move (machine_mode mo
{
rtx tmp[2];
- /* ix86_expand_vector_move_misalign() does not like constants ... */
- if (CONSTANT_P (op1)
- || (SUBREG_P (op1)
- && CONSTANT_P (SUBREG_REG (op1))))
- op1 = validize_mem (force_const_mem (mode, op1));
-
- /* ... nor both arguments in memory. */
+ /* ix86_expand_vector_move_misalign() does not like both
+ arguments in memory. */
if (!register_operand (op0, mode)
&& !register_operand (op1, mode))
op1 = force_reg (mode, op1);
--- gcc/testsuite/gcc.c-torture/execute/pr71626-1.c.jj 2016-06-28 10:40:12.928186649 +0200
+++ gcc/testsuite/gcc.c-torture/execute/pr71626-1.c 2016-06-28 10:40:12.928186649 +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-28 10:40:12.928186649 +0200
+++ gcc/testsuite/gcc.c-torture/execute/pr71626-2.c 2016-06-28 10:40:12.928186649 +0200
@@ -0,0 +1,4 @@
+/* PR middle-end/71626 */
+/* { dg-additional-options "-fpic" { target fpic } } */
+
+#include "pr71626-1.c"
Jakub