http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47564
Summary: internal compiler error in memory_address_addr_space,
at explow.c:504
Product: gcc
Version: 4.6.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: middle-end
AssignedTo: [email protected]
ReportedBy: [email protected]
Compiling the test case at the end with -O2 causes:
$ ./cc1plus -O2 -quiet a.cc
a.cc: In function 'void E(uint64*, uint64*, const void*, int64)':
a.cc:18:15: internal compiler error: in memory_address_addr_space, at
explow.c:504
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.
The ICE occurs during RTL expansion for the statement:
$G =$5 = 0x7ffff7124410
# VUSE <.MEM_58(D)>
D.2207_9 = *lo_8(D);
Both sides are uint64, but in expand_expr_real_1, when we call
memory_address_addr_space on *lo_8, we get:
#3 0x00000000010e6c3d in expand_expr_real_1 (exp=0x7ffff7ff88c0,
target=0x7ffff6f0fcc0, tmode=DImode, modifier=EXPAND_NORMAL,
alt_rtl=0x7fffffffd7f8) at /home/dnovillo/gcc/src/gcc/expr.c:8735
8735 op0 = memory_address_addr_space (address_mode, op0, as);
(gdb) ptu exp
$NODE =$10 = 0x7ffff7ff88c0
*lo_8(D);
(gdb) p address_mode
$11 = DImode
(gdb) pr op0
(reg/v/f:DI 8 st [ lo ])
void(gdb) down
#2 0x00000000010720f0 in memory_address_addr_space (mode=DImode,
x=0x7ffff6f16100, as=0 '\000') at /home/dnovillo/gcc/src/gcc/explow.c:504
504 gcc_assert (memory_address_addr_space_p (mode, x, as));
(gdb) pr x
(reg:DI 12 st(4))
and X fails the memory_address_addr_space_p() test.
Test case:
=========================================================================
typedef unsigned long long uint64;
typedef long long int64;
typedef unsigned char uint8;
static const int PT = 8 * 1024;
typedef unsigned int uint32;
static inline uint64 L(const uint8 *p) {
return 1;
}
void E(uint64 *, uint64 *, const void *, int64) __attribute__ ((__target__
("sse4")));
void
E (uint64 * lo, uint64 * hi, const void *bytes, int64 length)
{
const uint8 *p = static_cast < const uint8 * >(bytes);
const uint8 *e = p + length;
uint32 l = *lo;
uint64 l64 = l;
if ((e - p) >= PT)
{
while ((e - p) >= 128)
{
l64 = __builtin_ia32_crc32di (l64, L (p));
l64 = __builtin_ia32_crc32di (l64, L (p));
l64 = __builtin_ia32_crc32di (l64, L (p));
l64 = __builtin_ia32_crc32di (l64, L (p));
l64 = __builtin_ia32_crc32di (l64, L (p));
l64 = __builtin_ia32_crc32di (l64, L (p));
l64 = __builtin_ia32_crc32di (l64, L (p));
l64 = __builtin_ia32_crc32di (l64, L (p));
l64 = __builtin_ia32_crc32di (l64, L (p));
}
}
while ((e - p) >= 16)
{
l64 = __builtin_ia32_crc32di (l64, L (p));
l64 = __builtin_ia32_crc32di (l64, L (p));
}
l = l64;
*lo = l;
}