Bug 71626 - [4.9 regression] ICE at -O1 and above on x86_64-linux-gnu (in output_constant_pool_2, at varasm.c:3837)
Summary: [4.9 regression] ICE at -O1 and above on x86_64-linux-gnu (in output_constant...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 7.0
: P3 normal
Target Milestone: 4.9.4
Assignee: Not yet assigned to anyone
URL:
Keywords: ice-on-valid-code
Depends on:
Blocks:
 
Reported: 2016-06-22 17:54 UTC by Chengnian Sun
Modified: 2016-07-08 07:23 UTC (History)
2 users (show)

See Also:
Host:
Target: x86_64-pc-linux-gnu
Build:
Known to work:
Known to fail: 4.9.3, 5.3.0, 6.1.0, 7.0
Last reconfirmed: 2016-06-23 00:00:00


Attachments
gcc7-pr71626.patch (1.53 KB, patch)
2016-06-27 10:51 UTC, Jakub Jelinek
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Chengnian Sun 2016-06-22 17:54:19 UTC
This is a regression. gcc-4.9 also ICEs. 

$: gcc-trunk -v
Using built-in specs.
COLLECT_GCC=gcc-trunk
COLLECT_LTO_WRAPPER=/usr/local/gcc-trunk/libexec/gcc/x86_64-pc-linux-gnu/7.0.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: ../gcc-source-trunk/configure --enable-languages=c,c++,lto --prefix=/usr/local/gcc-trunk --disable-bootstrap
Thread model: posix
gcc version 7.0.0 20160622 (experimental) [trunk revision 237712] (GCC) 
$: 
$: gcc-trunk -O1 small.c
small.c: In function ‘fn’:
small.c:5:16: warning: initialization makes integer from pointer without a cast [-Wint-conversion]
   vllong1 v = {fn};
                ^~
small.c:5:16: note: (near initialization for ‘v’)
small.c: At top level:
small.c:7:1: internal compiler error: in output_constant_pool_2, at varasm.c:3837
 }
 ^
0xea3de4 output_constant_pool_2
        ../../gcc-source-trunk/gcc/varasm.c:3837
0xea3e9d output_constant_pool_1
        ../../gcc-source-trunk/gcc/varasm.c:3909
0xeb270d output_constant_pool_contents
        ../../gcc-source-trunk/gcc/varasm.c:4023
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <http://gcc.gnu.org/bugs.html> for instructions.
$: 
$: cat small.c
typedef long llong;
typedef llong vllong1 __attribute__((__vector_size__(sizeof(llong))));

vllong1 fn() {
  vllong1 v = {fn};
  return v;
}

$:
Comment 1 Martin Sebor 2016-06-23 03:14:46 UTC
Confirmed with r204274 (gcc 4.9.0) as the root cause:

r204274 | jakub | 2013-10-31 15:06:49 -0400 (Thu, 31 Oct 2013) | 19 lines

	* optabs.c (expand_vec_perm): Avoid vector mode punning
	SUBREGs in SET_DEST.
	* expmed.c (store_bit_field_1): Likewise.
	* config/i386/sse.md (movdi_to_sse, vec_pack_sfix_trunc_v2df,
	vec_pack_sfix_v2df, vec_shl_<mode>, vec_shr_<mode>,
	vec_interleave_high<mode>, vec_interleave_low<mode>): Likewise.
	* config/i386/i386.c (ix86_expand_vector_move_misalign,
	ix86_expand_sse_movcc, ix86_expand_int_vcond, ix86_expand_vec_perm,
	ix86_expand_sse_unpack, ix86_expand_args_builtin,
	ix86_expand_vector_init_duplicate, ix86_expand_vector_set,
	emit_reduc_half, expand_vec_perm_blend, expand_vec_perm_pshufb,
	expand_vec_perm_interleave2, expand_vec_perm_pshufb2,
	expand_vec_perm_vpshufb2_vpermq,
	expand_vec_perm_vpshufb2_vpermq_even_odd, expand_vec_perm_even_odd_1,
	expand_vec_perm_broadcast_1, expand_vec_perm_vpshufb4_vpermq2,
	ix86_expand_sse2_mulv4si3, ix86_expand_pinsr): Likewise.
	(expand_vec_perm_palignr): Likewise.  Modify a copy of *d rather
	than *d itself.
Comment 2 Jakub Jelinek 2016-06-27 10:02:54 UTC
One possibility would be to allow SUBREG of constant for the V1XXmode vectors like:
--- gcc/varasm.c.jj	2016-06-10 20:24:03.000000000 +0200
+++ gcc/varasm.c	2016-06-27 11:43:25.330955071 +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);
 
Without -fpic the result looks good, but with -fpic it forces something that needs relocations into .rodata.cst.* constants, which I think is bad.  Though, can't find right now where we normally avoid pushing relocatable stuff through force_const_mem...

Another option is to do something in the i386 vector move expansion.
Comment 3 Jakub Jelinek 2016-06-27 10:51:55 UTC
Created attachment 38773 [details]
gcc7-pr71626.patch

Untested fix.
Comment 4 Jakub Jelinek 2016-06-28 18:32:14 UTC
Author: jakub
Date: Tue Jun 28 18:31:42 2016
New Revision: 237826

URL: https://gcc.gnu.org/viewcvs?rev=237826&root=gcc&view=rev
Log:
	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.

Added:
    trunk/gcc/testsuite/gcc.c-torture/execute/pr71626-1.c
    trunk/gcc/testsuite/gcc.c-torture/execute/pr71626-2.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/config/i386/i386.c
    trunk/gcc/testsuite/ChangeLog
Comment 5 Jakub Jelinek 2016-06-28 19:02:41 UTC
Fixed on the trunk so far.
Comment 6 Jakub Jelinek 2016-07-02 10:21:55 UTC
Author: jakub
Date: Sat Jul  2 10:21:24 2016
New Revision: 237939

URL: https://gcc.gnu.org/viewcvs?rev=237939&root=gcc&view=rev
Log:
	Backported from mainline
	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.

Added:
    branches/gcc-6-branch/gcc/testsuite/gcc.c-torture/execute/pr71626-1.c
    branches/gcc-6-branch/gcc/testsuite/gcc.c-torture/execute/pr71626-2.c
Modified:
    branches/gcc-6-branch/gcc/ChangeLog
    branches/gcc-6-branch/gcc/config/i386/i386.c
    branches/gcc-6-branch/gcc/testsuite/ChangeLog
Comment 7 Jakub Jelinek 2016-07-07 12:48:51 UTC
Author: jakub
Date: Thu Jul  7 12:48:16 2016
New Revision: 238101

URL: https://gcc.gnu.org/viewcvs?rev=238101&root=gcc&view=rev
Log:
	Backported from mainline
	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.

Added:
    branches/gcc-5-branch/gcc/testsuite/gcc.c-torture/execute/pr71626-1.c
    branches/gcc-5-branch/gcc/testsuite/gcc.c-torture/execute/pr71626-2.c
Modified:
    branches/gcc-5-branch/gcc/ChangeLog
    branches/gcc-5-branch/gcc/config/i386/i386.c
    branches/gcc-5-branch/gcc/testsuite/ChangeLog
Comment 8 Jakub Jelinek 2016-07-07 13:21:33 UTC
Fixed also for 5.5+ and 6.2+.
Comment 9 Jakub Jelinek 2016-07-07 21:53:44 UTC
Author: jakub
Date: Thu Jul  7 21:53:12 2016
New Revision: 238145

URL: https://gcc.gnu.org/viewcvs?rev=238145&root=gcc&view=rev
Log:
	Backported from mainline
	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.

Added:
    branches/gcc-4_9-branch/gcc/testsuite/gcc.c-torture/execute/pr71626-1.c
    branches/gcc-4_9-branch/gcc/testsuite/gcc.c-torture/execute/pr71626-2.c
Modified:
    branches/gcc-4_9-branch/gcc/ChangeLog
    branches/gcc-4_9-branch/gcc/config/i386/i386.c
    branches/gcc-4_9-branch/gcc/testsuite/ChangeLog
Comment 10 Jakub Jelinek 2016-07-08 07:23:15 UTC
Fixed.