mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-31 15:31:11 +08:00
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:
parent
d076e5d27d
commit
1272914c20
@ -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>
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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. */
|
||||
|
||||
|
32
gcc/testsuite/gcc.target/i386/pr21101.c
Normal file
32
gcc/testsuite/gcc.target/i386/pr21101.c
Normal 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);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user