Commit ad6c0864 by Michael Meissner Committed by Michael Meissner

Fix PR 40049

From-SVN: r147298
parent c94f9067
2009-05-07 Michael Meissner <meissner@linux.vnet.ibm.com>
PR tree-optimization/40049
* tree-vect-stmts.c (vectorizable_operation): If the machine has
only vector/vector shifts, convert the type of the constant to the
appropriate type to avoid building incorrect trees, which
eventually have problems with garbage collection.
2009-05-08 Joseph Myers <joseph@codesourcery.com>
* fold-const.c (fold_binary): Do not fold multiplication by 1 or
......
2009-05-08 Michael Meissner <meissner@linux.vnet.ibm.com>
PR tree-optimization/40049
* gcc.dg/vect/vect-shift-2.c: New test.
2009-05-08 Joseph Myers <joseph@codesourcery.com>
* gcc.dg/torture/complex-sign-mul-minus-one.c,
......
/* { dg-require-effective-target vect_shift } */
/* { dg-require-effective-target vect_int } */
/* Check the standard integer types for left and right shifts to see if the
compiler replaced a scalar instruction with a vector instruction whether the
correct value is generated. */
#ifdef TRACE
#include <stdio.h>
#endif
#include <stdarg.h>
#include "tree-vect.h"
#ifndef ALIGN
#define ALIGN __attribute__((__aligned__(32)))
#endif
#ifndef NOINLINE
#define NOINLINE __attribute__((__noinline__))
#endif
#ifdef TRACE
#define TRACE_FUNC(PREFIX, NAME) printf (#PREFIX #NAME "\n")
#define TRACE_DONE() printf ("done!\n")
#define TRACE_ABORT(I,E,G) \
do { \
printf ("Element %d, expected 0x%lx, got 0x%lx\n", \
I, (long)(E), (long)(G)); \
abort (); \
} while (0)
#else
#define TRACE_FUNC(PREFIX, A)
#define TRACE_DONE()
#define TRACE_ABORT(I,E,G) abort ()
#endif
#define NAME(A,B) A ## B
#define VECT_TESTS(PREFIX, TYPE, N) \
/* Restrict the optimizer from optimizing the setup loops. */ \
volatile TYPE NAME (PREFIX, zero) = 0; \
\
TYPE NAME (PREFIX, a)[N] ALIGN; \
TYPE NAME (PREFIX, b)[N] ALIGN; \
TYPE NAME (PREFIX, c)[N] ALIGN; \
TYPE NAME (PREFIX, d)[N] ALIGN; \
\
static void NOINLINE \
NAME (PREFIX, lshift_2) (void) \
{ \
int i; \
\
TRACE_FUNC (PREFIX, lshift_2); \
for (i = 0; i < N; i++) \
NAME (PREFIX, a)[i] = NAME (PREFIX, b)[i] << 2; \
} \
\
static void NOINLINE \
NAME (PREFIX, lshift_var) (int shift) \
{ \
int i; \
\
TRACE_FUNC (PREFIX, lshift_var); \
for (i = 0; i < N; i++) \
NAME (PREFIX, a)[i] = NAME (PREFIX, b)[i] << shift; \
} \
\
static void NOINLINE \
NAME (PREFIX, lshift_vect) (void) \
{ \
int i; \
\
TRACE_FUNC (PREFIX, lshift_vect); \
for (i = 0; i < N; i++) \
NAME (PREFIX, a)[i] = NAME (PREFIX, b)[i] << NAME (PREFIX, c)[i]; \
} \
\
static void NOINLINE \
NAME (PREFIX, rshift_2) (void) \
{ \
int i; \
\
TRACE_FUNC (PREFIX, rshift_2); \
for (i = 0; i < N; i++) \
NAME (PREFIX, a)[i] = NAME (PREFIX, b)[i] >> 2; \
} \
\
static void NOINLINE \
NAME (PREFIX, rshift_var) (int shift) \
{ \
int i; \
\
TRACE_FUNC (PREFIX, rshift_var); \
for (i = 0; i < N; i++) \
NAME (PREFIX, a)[i] = NAME (PREFIX, b)[i] >> shift; \
} \
\
static void NOINLINE \
NAME (PREFIX, rshift_vect) (void) \
{ \
int i; \
\
TRACE_FUNC (PREFIX, rshift_vect); \
for (i = 0; i < N; i++) \
NAME (PREFIX, a)[i] = NAME (PREFIX, b)[i] >> NAME (PREFIX, c)[i]; \
} \
\
static void NOINLINE \
NAME (PREFIX, check) (void) \
{ \
int i; \
\
TRACE_FUNC (PREFIX, check); \
for (i = 0; i < N; i++) \
if (NAME (PREFIX, a)[i] != NAME (PREFIX, d)[i]) \
TRACE_ABORT (i, NAME (PREFIX, d)[i], NAME (PREFIX, a)[i]); \
} \
\
static void NOINLINE \
NAME (PREFIX, tests) (void) \
{ \
int i; \
\
TRACE_FUNC (PREFIX, tests); \
for (i = 0; i < N; i++) \
{ \
NAME (PREFIX, b)[i] = (i + NAME (PREFIX, zero)); \
NAME (PREFIX, c)[i] = 2; \
NAME (PREFIX, d)[i] = (i + NAME (PREFIX, zero)) << 2; \
} \
\
NAME (PREFIX, lshift_2) (); \
NAME (PREFIX, check) (); \
\
NAME (PREFIX, lshift_var) (2); \
NAME (PREFIX, check) (); \
\
NAME (PREFIX, lshift_vect) (); \
NAME (PREFIX, check) (); \
\
for (i = 0; i < N; i++) \
{ \
NAME (PREFIX, b)[i] = ((i + NAME (PREFIX, zero)) << 4) \
| (((TYPE)0x80) << ((sizeof (TYPE) * 8) - 8)); \
NAME (PREFIX, c)[i] = 2; \
NAME (PREFIX, d)[i] = (TYPE)((NAME (PREFIX, b)[i] \
+ NAME (PREFIX, zero)) >> 2); \
} \
\
NAME (PREFIX, rshift_2) (); \
NAME (PREFIX, check) (); \
\
NAME (PREFIX, rshift_var) (2); \
NAME (PREFIX, check) (); \
\
NAME (PREFIX, rshift_vect) (); \
NAME (PREFIX, check) (); \
}
VECT_TESTS(uc_, unsigned char, 16)
VECT_TESTS(us_, unsigned short, 32)
VECT_TESTS(ui_, unsigned int, 32)
VECT_TESTS(ul_, unsigned long, 32)
VECT_TESTS(sc_, signed char, 16)
VECT_TESTS(ss_, short, 32)
VECT_TESTS(si_, int, 32)
VECT_TESTS(sl_, long, 32)
int main ()
{
int i;
check_vect ();
uc_tests ();
us_tests ();
ui_tests ();
ul_tests ();
sc_tests ();
ss_tests ();
si_tests ();
sl_tests ();
TRACE_DONE ();
return 0;
}
......@@ -1974,11 +1974,20 @@ vectorizable_operation (gimple stmt, gimple_stmt_iterator *gsi,
else
{
optab = optab_for_tree_code (code, vectype, optab_vector);
if (vect_print_dump_info (REPORT_DETAILS)
&& optab
if (optab
&& (optab_handler (optab, TYPE_MODE (vectype))->insn_code
!= CODE_FOR_nothing))
fprintf (vect_dump, "vector/vector shift/rotate found.");
{
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "vector/vector shift/rotate found.");
/* Unlike the other binary operators, shifts/rotates have
the rhs being int, instead of the same type as the lhs,
so make sure the scalar is the right type if we are
dealing with vectors of short/char. */
if (dt[1] == vect_constant_def)
op1 = fold_convert (TREE_TYPE (vectype), op1);
}
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment