This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH, rtl-optimization]: Fix PR rtl-optimization/33846, ICE in trunc_int_for_mode, at explow.c:55
On 10/22/07, Eric Botcazou <ebotcazou@libertysurf.fr> wrote:
> > The combiner creates:
> >
> > (set (reg:V4SI 106)
> > (ashiftrt:V4SI (xor:V4SI (reg:V4SI 102)
> > (const_int -1 [0xffffffff]))
> > (const_int 31 [0x1f])))
> >
> > and -1 is passed with V4SImode to trunc_int_for_mode.
>
> Thanks. I think that
>
> (xor:V4SI (reg:V4SI 102)
> (const_int -1 [0xffffffff]))
>
> doesn't make much sense, we should have a CONST_VECTOR instead. So I'd simply
> disable the transformation that led to this for vector modes.
The code that handles NOT case is wrong for vector modes. Attached
patch teaches this code to create CONST_VECTOR instead of CONST_INT in
this case.
Patch was bootstrapped and regression tested on i686-pc-linux-gnu.
2007-10-23 Uros Bizjak <ubizjak@gmail.com>
PR tree-optimization/33846
* combine.c (simplify_shift_const_1) [NOT]: Handle vector modes.
testsuite/ChangeLog:
2007-10-23 Uros Bizjak <ubizjak@gmail.com>
PR tree-optimization/33846
* gcc.dg/vect/pr33846.c: New testcase.
Uros.
Index: testsuite/gcc.dg/vect/pr33846.c
===================================================================
--- testsuite/gcc.dg/vect/pr33846.c (revision 0)
+++ testsuite/gcc.dg/vect/pr33846.c (revision 0)
@@ -0,0 +1,21 @@
+/* Testcase by Martin Michlmayr <tbm@cyrius.com> */
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_shift } */
+
+int clamp_val (int i)
+{
+ return ~i >> 31;
+}
+void _mix_some_samples (long buf, int *mix_buffer, int mix_size)
+{
+ int i;
+ signed int *p = mix_buffer;
+ for (i = mix_size ; i > 0; i--)
+ {
+ *((short *) buf) = clamp_val ((*p) + 0x800000);
+ buf += 2;
+ p++;
+ }
+}
+
+/* { dg-final { cleanup-tree-dump "vect" } } */
Index: combine.c
===================================================================
--- combine.c (revision 129573)
+++ combine.c (working copy)
@@ -9333,9 +9333,9 @@ simplify_shift_const_1 (enum rtx_code co
&& GET_CODE (XEXP (varop, 0)) == CONST_INT
&& GET_CODE (XEXP (varop, 1)) != CONST_INT)
{
- rtx new = simplify_const_binary_operation (code, mode,
- XEXP (varop, 0),
- GEN_INT (count));
+ new = simplify_const_binary_operation (code, mode,
+ XEXP (varop, 0),
+ GEN_INT (count));
varop = gen_rtx_fmt_ee (code, mode, new, XEXP (varop, 1));
count = 0;
continue;
@@ -9344,8 +9344,24 @@ simplify_shift_const_1 (enum rtx_code co
case NOT:
/* Make this fit the case below. */
- varop = gen_rtx_XOR (mode, XEXP (varop, 0),
- GEN_INT (GET_MODE_MASK (mode)));
+ if (VECTOR_MODE_P (mode))
+ {
+ int elt_size = GET_MODE_SIZE (GET_MODE_INNER (mode));
+ unsigned n_elts = GET_MODE_SIZE (mode) / elt_size;
+ rtvec v = rtvec_alloc (n_elts);
+ unsigned int i;
+ rtx tmp;
+
+ tmp = GEN_INT (GET_MODE_MASK (GET_MODE_INNER (mode)));
+ for (i = 0; i < n_elts; i++)
+ RTVEC_ELT (v, i) = tmp;
+
+ new = gen_rtx_CONST_VECTOR (mode, v);
+ }
+ else
+ new = GEN_INT (GET_MODE_MASK (mode));
+
+ varop = gen_rtx_XOR (mode, XEXP (varop, 0), new);
continue;
case IOR: