Commit 383d9c83 by Ira Rosen Committed by Ira Rosen

tree-vectorizer.h (vect_recog_func_ptr): Make last argument to be a pointer.


        * tree-vectorizer.h (vect_recog_func_ptr): Make last argument to
        be a pointer.
        * tree-vect-patterns.c (vect_recog_widen_sum_pattern,
        vect_recog_widen_mult_pattern, vect_recog_dot_prod_pattern,
        vect_recog_pow_pattern): Likewise.
        (vect_pattern_recog_1): Remove declaration.
        (widened_name_p): Remove declaration.  Add new argument to
        specify whether to check that both types are either signed or
        unsigned.
        (vect_recog_widen_mult_pattern): Update documentation.  Handle
        unsigned patterns and multiplication by constants.
        (vect_pattern_recog_1): Update vect_recog_func references.  Use
        statement information from the statement returned from pattern
        detection functions.
        (vect_pattern_recog): Update vect_recog_func reference.
        * tree-vect-stmts.c (vectorizable_type_promotion): For widening
        multiplication by a constant use the type of the other operand.

From-SVN: r174735
parent f527cc50
2011-06-07 Ira Rosen <ira.rosen@linaro.org>
* tree-vectorizer.h (vect_recog_func_ptr): Make last argument to be
a pointer.
* tree-vect-patterns.c (vect_recog_widen_sum_pattern,
vect_recog_widen_mult_pattern, vect_recog_dot_prod_pattern,
vect_recog_pow_pattern): Likewise.
(vect_pattern_recog_1): Remove declaration.
(widened_name_p): Remove declaration. Add new argument to specify
whether to check that both types are either signed or unsigned.
(vect_recog_widen_mult_pattern): Update documentation. Handle
unsigned patterns and multiplication by constants.
(vect_pattern_recog_1): Update vect_recog_func references. Use
statement information from the statement returned from pattern
detection functions.
(vect_pattern_recog): Update vect_recog_func reference.
* tree-vect-stmts.c (vectorizable_type_promotion): For widening
multiplication by a constant use the type of the other operand.
2011-06-06 Richard Sandiford <rdsandiford@googlemail.com>
PR rtl-optimization/49145
......
2011-06-07 Ira Rosen <ira.rosen@linaro.org>
* lib/target-supports.exp
(check_effective_target_vect_widen_mult_qi_to_hi):
Add NEON as supporting target.
(check_effective_target_vect_widen_mult_hi_to_si): Likewise.
(check_effective_target_vect_widen_mult_qi_to_hi_pattern): New.
(check_effective_target_vect_widen_mult_hi_to_si_pattern): New.
* gcc.dg/vect/vect-widen-mult-u8.c: Expect to be vectorized
using widening multiplication on targets that support it.
* gcc.dg/vect/vect-widen-mult-u16.c: Likewise.
* gcc.dg/vect/vect-widen-mult-const-s16.c: New test.
* gcc.dg/vect/vect-widen-mult-const-u16.c: New test.
2011-06-06 Nicola Pero <nicola.pero@meta-innovation.com>
Updated all testcases in the ObjC/ObjC++ testsuites to use the
......
/* { dg-require-effective-target vect_int } */
#include "tree-vect.h"
#include <stdlib.h>
#define N 32
__attribute__ ((noinline)) void
foo (int *__restrict a,
short *__restrict b,
int n)
{
int i;
for (i = 0; i < n; i++)
a[i] = b[i] * 2333;
for (i = 0; i < n; i++)
if (a[i] != b[i] * 2333)
abort ();
}
__attribute__ ((noinline)) void
bar (int *__restrict a,
short *__restrict b,
int n)
{
int i;
for (i = 0; i < n; i++)
a[i] = b[i] * (short) 2333;
for (i = 0; i < n; i++)
if (a[i] != b[i] * (short) 2333)
abort ();
}
int main (void)
{
int i;
int a[N];
short b[N];
for (i = 0; i < N; i++)
{
a[i] = 0;
b[i] = i;
__asm__ volatile ("");
}
foo (a, b, N);
bar (a, b, N);
return 0;
}
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" { target vect_widen_mult_hi_to_si } } } */
/* { dg-final { scan-tree-dump-times "vect_recog_widen_mult_pattern: detected" 2 "vect" { target vect_widen_mult_hi_to_si_pattern } } } */
/* { dg-final { scan-tree-dump-times "pattern recognized" 2 "vect" { target vect_widen_mult_hi_to_si_pattern } } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
/* { dg-require-effective-target vect_int } */
#include "tree-vect.h"
#include <stdlib.h>
#define N 32
__attribute__ ((noinline)) void
foo (unsigned int *__restrict a,
unsigned short *__restrict b,
int n)
{
int i;
for (i = 0; i < n; i++)
a[i] = b[i] * 2333;
for (i = 0; i < n; i++)
if (a[i] != b[i] * 2333)
abort ();
}
__attribute__ ((noinline)) void
bar (unsigned int *__restrict a,
unsigned short *__restrict b,
int n)
{
int i;
for (i = 0; i < n; i++)
a[i] = (unsigned short) 2333 * b[i];
for (i = 0; i < n; i++)
if (a[i] != b[i] * (unsigned short) 2333)
abort ();
}
__attribute__ ((noinline)) void
baz (unsigned int *__restrict a,
unsigned short *__restrict b,
int n)
{
int i;
for (i = 0; i < n; i++)
a[i] = b[i] * 233333333;
for (i = 0; i < n; i++)
if (a[i] != b[i] * 233333333)
abort ();
}
int main (void)
{
int i;
unsigned int a[N];
unsigned short b[N];
for (i = 0; i < N; i++)
{
a[i] = 0;
b[i] = i;
__asm__ volatile ("");
}
foo (a, b, N);
bar (a, b, N);
baz (a, b, N);
return 0;
}
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 3 "vect" { target vect_widen_mult_hi_to_si } } } */
/* { dg-final { scan-tree-dump-times "vect_recog_widen_mult_pattern: detected" 2 "vect" { target vect_widen_mult_hi_to_si_pattern } } } */
/* { dg-final { scan-tree-dump-times "pattern recognized" 2 "vect" { target vect_widen_mult_hi_to_si_pattern } } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
......@@ -9,13 +9,11 @@ unsigned short X[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__)));
unsigned short Y[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__)));
unsigned int result[N];
/* short->int widening-mult */
/* unsigned short->unsigned int widening-mult. */
__attribute__ ((noinline)) int
foo1(int len) {
int i;
/* Not vectorized because X[i] and Y[i] are casted to 'int'
so the widening multiplication pattern is not recognized. */
for (i=0; i<len; i++) {
result[i] = (unsigned int)(X[i] * Y[i]);
}
......@@ -43,8 +41,8 @@ int main (void)
return 0;
}
/*The induction loop is vectorized */
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" { xfail *-*-* } } } */
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_pack_trunc } } } */
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_widen_mult_hi_to_si || vect_unpack } } } } */
/* { dg-final { scan-tree-dump-times "vect_recog_widen_mult_pattern: detected" 1 "vect" { target vect_widen_mult_hi_to_si_pattern } } } */
/* { dg-final { scan-tree-dump-times "pattern recognized" 1 "vect" { target vect_widen_mult_hi_to_si_pattern } } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
......@@ -9,7 +9,7 @@ unsigned char X[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__)));
unsigned char Y[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__)));
unsigned short result[N];
/* char->short widening-mult */
/* unsigned char-> unsigned short widening-mult. */
__attribute__ ((noinline)) int
foo1(int len) {
int i;
......@@ -28,8 +28,7 @@ int main (void)
for (i=0; i<N; i++) {
X[i] = i;
Y[i] = 64-i;
if (i%4 == 0)
X[i] = 5;
__asm__ volatile ("");
}
foo1 (N);
......@@ -43,5 +42,7 @@ int main (void)
}
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_widen_mult_qi_to_hi || vect_unpack } } } } */
/* { dg-final { scan-tree-dump-times "vect_recog_widen_mult_pattern: detected" 1 "vect" { target vect_widen_mult_qi_to_hi_pattern } } } */
/* { dg-final { scan-tree-dump-times "pattern recognized" 1 "vect" { target vect_widen_mult_qi_to_hi_pattern } } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
......@@ -2668,7 +2668,8 @@ proc check_effective_target_vect_widen_mult_qi_to_hi { } {
} else {
set et_vect_widen_mult_qi_to_hi_saved 0
}
if { [istarget powerpc*-*-*] } {
if { [istarget powerpc*-*-*]
|| ([istarget arm*-*-*] && [check_effective_target_arm_neon]) } {
set et_vect_widen_mult_qi_to_hi_saved 1
}
}
......@@ -2701,7 +2702,8 @@ proc check_effective_target_vect_widen_mult_hi_to_si { } {
|| [istarget spu-*-*]
|| [istarget ia64-*-*]
|| [istarget i?86-*-*]
|| [istarget x86_64-*-*] } {
|| [istarget x86_64-*-*]
|| ([istarget arm*-*-*] && [check_effective_target_arm_neon]) } {
set et_vect_widen_mult_hi_to_si_saved 1
}
}
......@@ -2710,6 +2712,52 @@ proc check_effective_target_vect_widen_mult_hi_to_si { } {
}
# Return 1 if the target plus current options supports a vector
# widening multiplication of *char* args into *short* result, 0 otherwise.
#
# This won't change for different subtargets so cache the result.
proc check_effective_target_vect_widen_mult_qi_to_hi_pattern { } {
global et_vect_widen_mult_qi_to_hi_pattern
if [info exists et_vect_widen_mult_qi_to_hi_pattern_saved] {
verbose "check_effective_target_vect_widen_mult_qi_to_hi_pattern: using cached result" 2
} else {
set et_vect_widen_mult_qi_to_hi_pattern_saved 0
if { [istarget powerpc*-*-*]
|| ([istarget arm*-*-*] && [check_effective_target_arm_neon]) } {
set et_vect_widen_mult_qi_to_hi_pattern_saved 1
}
}
verbose "check_effective_target_vect_widen_mult_qi_to_hi_pattern: returning $et_vect_widen_mult_qi_to_hi_pattern_saved" 2
return $et_vect_widen_mult_qi_to_hi_pattern_saved
}
# Return 1 if the target plus current options supports a vector
# widening multiplication of *short* args into *int* result, 0 otherwise.
#
# This won't change for different subtargets so cache the result.
proc check_effective_target_vect_widen_mult_hi_to_si_pattern { } {
global et_vect_widen_mult_hi_to_si_pattern
if [info exists et_vect_widen_mult_hi_to_si_pattern_saved] {
verbose "check_effective_target_vect_widen_mult_hi_to_si_pattern: using cached result" 2
} else {
set et_vect_widen_mult_hi_to_si_pattern_saved 0
if { [istarget powerpc*-*-*]
|| [istarget spu-*-*]
|| [istarget ia64-*-*]
|| [istarget i?86-*-*]
|| [istarget x86_64-*-*]
|| ([istarget arm*-*-*] && [check_effective_target_arm_neon]) } {
set et_vect_widen_mult_hi_to_si_pattern_saved 1
}
}
verbose "check_effective_target_vect_widen_mult_hi_to_si_pattern: returning $et_vect_widen_mult_hi_to_si_pattern_saved" 2
return $et_vect_widen_mult_hi_to_si_pattern_saved
}
# Return 1 if the target plus current options supports a vector
# dot-product of signed chars, 0 otherwise.
#
# This won't change for different subtargets so cache the result.
......
......@@ -3232,6 +3232,33 @@ vectorizable_type_promotion (gimple stmt, gimple_stmt_iterator *gsi,
fprintf (vect_dump, "use not simple.");
return false;
}
op_type = TREE_CODE_LENGTH (code);
if (op_type == binary_op)
{
bool ok;
op1 = gimple_assign_rhs2 (stmt);
if (code == WIDEN_MULT_EXPR)
{
/* For WIDEN_MULT_EXPR, if OP0 is a constant, use the type of
OP1. */
if (CONSTANT_CLASS_P (op0))
ok = vect_is_simple_use_1 (op1, loop_vinfo, NULL,
&def_stmt, &def, &dt[1], &vectype_in);
else
ok = vect_is_simple_use (op1, loop_vinfo, NULL, &def_stmt, &def,
&dt[1]);
if (!ok)
{
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "use not simple.");
return false;
}
}
}
/* If op0 is an external or constant def use a vector type with
the same size as the output vector type. */
if (!vectype_in)
......@@ -3264,18 +3291,6 @@ vectorizable_type_promotion (gimple stmt, gimple_stmt_iterator *gsi,
gcc_assert (ncopies >= 1);
op_type = TREE_CODE_LENGTH (code);
if (op_type == binary_op)
{
op1 = gimple_assign_rhs2 (stmt);
if (!vect_is_simple_use (op1, loop_vinfo, NULL, &def_stmt, &def, &dt[1]))
{
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "use not simple.");
return false;
}
}
/* Supportable by target? */
if (!supportable_widening_operation (code, stmt, vectype_out, vectype_in,
&decl1, &decl2, &code1, &code2,
......@@ -3301,6 +3316,14 @@ vectorizable_type_promotion (gimple stmt, gimple_stmt_iterator *gsi,
fprintf (vect_dump, "transform type promotion operation. ncopies = %d.",
ncopies);
if (code == WIDEN_MULT_EXPR)
{
if (CONSTANT_CLASS_P (op0))
op0 = fold_convert (TREE_TYPE (op1), op0);
else if (CONSTANT_CLASS_P (op1))
op1 = fold_convert (TREE_TYPE (op0), op1);
}
/* Handle def. */
/* In case of multi-step promotion, we first generate promotion operations
to the intermediate types, and then from that types to the final one.
......
......@@ -896,7 +896,7 @@ extern void vect_slp_transform_bb (basic_block);
/* Pattern recognition functions.
Additional pattern recognition functions can (and will) be added
in the future. */
typedef gimple (* vect_recog_func_ptr) (gimple, tree *, tree *);
typedef gimple (* vect_recog_func_ptr) (gimple *, tree *, tree *);
#define NUM_PATTERNS 4
void vect_pattern_recog (loop_vec_info);
......
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