aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2005-04-24 00:59:22 -0700
committerRichard Henderson <rth@gcc.gnu.org>2005-04-24 00:59:22 -0700
commit1272914c20c57d7e4498e3a1a36c4784555a39c2 (patch)
tree6ef27bbdc28738298b27a76311c4ff4faf90efb3
parentd076e5d27d8e986eed6e5397e2b8f79a69955728 (diff)
downloadgcc-1272914c20c57d7e4498e3a1a36c4784555a39c2.zip
gcc-1272914c20c57d7e4498e3a1a36c4784555a39c2.tar.gz
gcc-1272914c20c57d7e4498e3a1a36c4784555a39c2.tar.bz2
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
-rw-r--r--gcc/ChangeLog14
-rw-r--r--gcc/config/i386/i386-protos.h2
-rw-r--r--gcc/config/i386/i386.c35
-rw-r--r--gcc/config/i386/i386.h17
-rw-r--r--gcc/testsuite/gcc.target/i386/pr21101.c32
5 files changed, 84 insertions, 16 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d4b9cf7..9f2ee99 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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>
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index 4834071..d8f15da 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -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);
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 5046cf5..110b233 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -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.
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index b58373f..fc0596b 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -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.
-
- 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)
+/* Return a class of registers that cannot change FROM mode to TO mode. */
+
+#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
+ ix86_cannot_change_mode_class (FROM, TO, CLASS)
/* Stack layout; function entry, exit and calling. */
diff --git a/gcc/testsuite/gcc.target/i386/pr21101.c b/gcc/testsuite/gcc.target/i386/pr21101.c
new file mode 100644
index 0000000..104b08c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr21101.c
@@ -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);
+ }
+}