aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/convert.c6
-rw-r--r--gcc/cse.c5
-rw-r--r--gcc/simplify-rtx.c19
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/simd-1.c7
6 files changed, 47 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b3d7c09..4209d29 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+Thu Jul 4 07:36:29 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * simplify-rtx.c (simplify_subreg): Reduce problem of finding
+ vector mode subregs of constants to finding integer mode
+ subregs of constants.
+ * cse.c (cse_insn): Use simplify_gen_subreg.
+ * convert.c (convert_to_integer): Don't strip a NOP_EXPR
+ From a vector mode expression of different size than the
+ target mode.
+
2002-07-03 Eric Christopher <echristo@redhat.com>
* config/mips/linux.h: Add #undef for SUBTARGET_CPP_SPEC.
diff --git a/gcc/convert.c b/gcc/convert.c
index e90ce4c..e440e35 100644
--- a/gcc/convert.c
+++ b/gcc/convert.c
@@ -376,6 +376,12 @@ convert_to_integer (type, expr)
}
case NOP_EXPR:
+ /* Don't introduce a
+ "can't convert between vector values of different size" error. */
+ if (TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == VECTOR_TYPE
+ && (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (TREE_OPERAND (expr, 0))))
+ != GET_MODE_SIZE (TYPE_MODE (type))))
+ break;
/* If truncating after truncating, might as well do all at once.
If truncating after extending, we may get rid of wasted work. */
return convert (type, get_unwidened (TREE_OPERAND (expr, 0), type));
diff --git a/gcc/cse.c b/gcc/cse.c
index 01a79d5..14ffd80 100644
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -6202,9 +6202,8 @@ cse_insn (insn, libcall_insn)
&& ! exp_equiv_p (elt->exp, elt->exp, 1, 0))
continue;
- new_src = gen_lowpart_if_possible (new_mode, elt->exp);
- if (new_src == 0)
- new_src = gen_rtx_SUBREG (new_mode, elt->exp, 0);
+ new_src
+ = simplify_gen_subreg (new_mode, elt->exp, elt->mode, 0);
src_hash = HASH (new_src, new_mode);
src_elt = lookup (new_src, src_hash, new_mode);
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index 63961dd..ebb4644 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -2319,7 +2319,8 @@ simplify_subreg (outermode, op, innermode, byte)
else
return NULL_RTX;
}
- else
+ else if (GET_MODE_CLASS (outermode) != MODE_VECTOR_INT
+ && GET_MODE_CLASS (outermode) != MODE_VECTOR_FLOAT)
/* This shouldn't happen, but let's not do anything stupid. */
return NULL_RTX;
}
@@ -2330,6 +2331,22 @@ simplify_subreg (outermode, op, innermode, byte)
int offset, part;
unsigned HOST_WIDE_INT val = 0;
+ if (GET_MODE_CLASS (outermode) == MODE_VECTOR_INT
+ || GET_MODE_CLASS (outermode) == MODE_VECTOR_FLOAT)
+ {
+ /* Construct a CONST_VECTOR from individual subregs. */
+ enum machine_mode submode = GET_MODE_INNER (outermode);
+ int subsize = GET_MODE_UNIT_SIZE (outermode);
+ int i, elts = GET_MODE_NUNITS (outermode);
+ rtvec v = rtvec_alloc (elts);
+
+ for (i = 0; i < elts; i++, byte += subsize)
+ {
+ RTVEC_ELT (v, i) = simplify_subreg (submode, op, innermode, byte);
+ }
+ return gen_rtx_CONST_VECTOR (outermode, v);
+ }
+
/* ??? This code is partly redundant with code below, but can handle
the subregs of floats and similar corner cases.
Later it we should move all simplification code here and rewrite
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 9b093b5..4c8cb75 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+Thu Jul 4 07:36:48 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * gcc.c-torture/compile/simd-3.c: New test.
+
2002-07-03 Chris Demetriou <cgd@broadcom.com>
* g++.dg/abi/mangle6.C: Run for mipsisa64*-*-* targets.
diff --git a/gcc/testsuite/gcc.c-torture/compile/simd-1.c b/gcc/testsuite/gcc.c-torture/compile/simd-1.c
new file mode 100644
index 0000000..c113bd4
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/simd-1.c
@@ -0,0 +1,7 @@
+typedef int v2si __attribute__ ((mode(V2SI)));
+typedef unsigned di __attribute__ ((mode(DI)));
+void foo(unsigned long);
+void bar() {
+ v2si x = { 1, 2 };
+ foo((di) x);
+}