re PR target/21101 (ICE: could not find a spill register on MMX intrinsics)

PR target/21101
        * config/i386/i386.h (CANNOT_CHANGE_MODE_CLASS): Move guts to ...
        * config/i386/i386.c (ix86_cannot_change_mode_class): ... here.
        Deny modes smaller than 4 bytes.
        * config/i386/i386-protos.h: Update.

From-SVN: r98650
This commit is contained in:
Richard Henderson 2005-04-24 00:59:22 -07:00 committed by Richard Henderson
parent d076e5d27d
commit 1272914c20
5 changed files with 83 additions and 15 deletions

View File

@ -1,3 +1,11 @@
2005-04-24 Richard Henderson <rth@redhat.com>
PR target/21101
* config/i386/i386.h (CANNOT_CHANGE_MODE_CLASS): Move guts to ...
* config/i386/i386.c (ix86_cannot_change_mode_class): ... here.
Deny modes smaller than 4 bytes.
* config/i386/i386-protos.h: Update.
2005-04-24 Ralf Corsepius <ralf.corsepius@rtems.org>
* config.gcc (h8300-*-rtems*): Add h8300-*-rtemscoff*.
@ -74,9 +82,9 @@
2005-04-23 Richard Henderson <rth@redhat.com>
PR rtl-opt/21102
* simplify-rtx.c (simplify_binary_operation): Fix mode check before
performing some integral scalar simplifications.
PR rtl-opt/21102
* simplify-rtx.c (simplify_binary_operation): Fix mode check before
performing some integral scalar simplifications.
2005-04-23 Richard Henderson <rth@redhat.com>

View File

@ -187,6 +187,8 @@ extern int ix86_register_move_cost (enum machine_mode, enum reg_class,
enum reg_class);
extern int ix86_secondary_memory_needed (enum reg_class, enum reg_class,
enum machine_mode, int);
extern bool ix86_cannot_change_mode_class (enum machine_mode,
enum machine_mode, enum reg_class);
extern enum reg_class ix86_preferred_reload_class (rtx, enum reg_class);
extern int ix86_memory_move_cost (enum machine_mode, enum reg_class, int);
extern void emit_i387_cw_initialization (rtx, rtx, int);

View File

@ -15297,6 +15297,41 @@ ix86_secondary_memory_needed (enum reg_class class1, enum reg_class class2,
return false;
}
/* Return true if the registers in CLASS cannot represent the change from
modes FROM to TO. */
bool
ix86_cannot_change_mode_class (enum machine_mode from, enum machine_mode to,
enum reg_class class)
{
if (from == to)
return false;
/* x87 registers can't do subreg at all, as all values are reformated
to extended precision. */
if (MAYBE_FLOAT_CLASS_P (class))
return true;
if (MAYBE_SSE_CLASS_P (class) || MAYBE_MMX_CLASS_P (class))
{
/* Vector registers do not support QI or HImode loads. If we don't
disallow a change to these modes, reload will assume it's ok to
drop the subreg from (subreg:SI (reg:HI 100) 0). This affects
the vec_dupv4hi pattern. */
if (GET_MODE_SIZE (from) < 4)
return true;
/* Vector registers do not support subreg with nonzero offsets, which
are otherwise valid for integer registers. Since we can't see
whether we have a nonzero offset from here, prohibit all
nonparadoxical subregs changing size. */
if (GET_MODE_SIZE (to) < GET_MODE_SIZE (from))
return true;
}
return false;
}
/* Return the cost of moving data from a register in class CLASS1 to
one in class CLASS2.

View File

@ -1338,19 +1338,10 @@ enum reg_class
|| ((CLASS) == FP_TOP_REG) \
|| ((CLASS) == FP_SECOND_REG))
/* Return a class of registers that cannot change FROM mode to TO mode.
/* Return a class of registers that cannot change FROM mode to TO mode. */
x87 registers can't do subreg as all values are reformated to extended
precision. XMM registers does not support with nonzero offsets equal
to 4, 8 and 12 otherwise valid for integer registers. Since we can't
determine these, prohibit all nonparadoxical subregs changing size. */
#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
(GET_MODE_SIZE (TO) < GET_MODE_SIZE (FROM) \
? reg_classes_intersect_p (FLOAT_SSE_REGS, (CLASS)) \
|| MAYBE_MMX_CLASS_P (CLASS) \
: GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \
? reg_classes_intersect_p (FLOAT_REGS, (CLASS)) : 0)
#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
ix86_cannot_change_mode_class (FROM, TO, CLASS)
/* Stack layout; function entry, exit and calling. */

View File

@ -0,0 +1,32 @@
/* { dg-do compile } */
/* { dg-options "-O2 -funroll-loops -march=nocona" } */
#include <mmintrin.h>
int W;
void f()
{
int j;
int B, C;
unsigned char* S;
__m64 *T = (__m64 *) &W;
for (j = 0; j < 16; j++, T++)
{
T[0] = T[1] = _mm_set1_pi8(*S);
S += W;
}
C = 3 * B;
__m64 E = _mm_set_pi16(3 * B, 3 * B, 3 * B, 5 * B);
__m64 G = _mm_set1_pi16(3 * B);
for (j = 0; j < 16; j++)
{
__m64 R = _mm_set1_pi16(B + j * C);
R = _m_paddw(R, E);
R = _m_paddw(R, G);
T[0] = _mm_srai_pi16(R, 3);
}
}