Allow non-overflow ops in reductions
2015-08-01 Tom de Vries <tom@codesourcery.com> * tree.c (operation_can_overflow, operation_no_trapping_overflow): New function. * tree.h (operation_can_overflow, operation_no_trapping_overflow): Declare. * tree-vect-loop.c (vect_is_simple_reduction_1): Use operation_no_trapping_overflow. Allow non-overflow operations. * graphite-sese-to-poly.c (is_reduction_operation_p): Allow non-overflow operations. * gcc.dg/autopar/reduc-2char.c (init_arrays): Mark with attribute optimize ("-ftree-parallelize-loops=0"). Add successful scans for 2 detected reductions. Add xfail scans for 3 detected reductions. * gcc.dg/autopar/reduc-2short.c: Same. * gcc.dg/autopar/reduc-8.c (init_arrays): Mark with attribute optimize ("-ftree-parallelize-loops=0"). Add successful scans for 2 detected reductions. * gcc.dg/vect/trapv-vect-reduc-4.c: Update scan to match vectorized min and max reductions. From-SVN: r226463
This commit is contained in:
parent
faf4ac3218
commit
805134b917
|
@ -1,3 +1,14 @@
|
|||
2015-08-01 Tom de Vries <tom@codesourcery.com>
|
||||
|
||||
* tree.c (operation_can_overflow, operation_no_trapping_overflow): New
|
||||
function.
|
||||
* tree.h (operation_can_overflow, operation_no_trapping_overflow):
|
||||
Declare.
|
||||
* tree-vect-loop.c (vect_is_simple_reduction_1): Use
|
||||
operation_no_trapping_overflow. Allow non-overflow operations.
|
||||
* graphite-sese-to-poly.c (is_reduction_operation_p): Allow non-overflow
|
||||
operations.
|
||||
|
||||
2015-07-31 Kaz Kojima <kkojima@gcc.gnu.org>
|
||||
|
||||
PR target/67049
|
||||
|
|
|
@ -2614,8 +2614,11 @@ is_reduction_operation_p (gimple stmt)
|
|||
if (FLOAT_TYPE_P (type))
|
||||
return flag_associative_math;
|
||||
|
||||
return (INTEGRAL_TYPE_P (type)
|
||||
&& TYPE_OVERFLOW_WRAPS (type));
|
||||
if (ANY_INTEGRAL_TYPE_P (type))
|
||||
return (TYPE_OVERFLOW_WRAPS (type)
|
||||
|| !operation_can_overflow (code));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Returns true when PHI contains an argument ARG. */
|
||||
|
|
|
@ -1,3 +1,16 @@
|
|||
2015-08-01 Tom de Vries <tom@codesourcery.com>
|
||||
|
||||
* gcc.dg/autopar/reduc-2char.c (init_arrays): Mark with attribute
|
||||
optimize ("-ftree-parallelize-loops=0").
|
||||
Add successful scans for 2 detected reductions. Add xfail scans for 3
|
||||
detected reductions.
|
||||
* gcc.dg/autopar/reduc-2short.c: Same.
|
||||
* gcc.dg/autopar/reduc-8.c (init_arrays): Mark with attribute
|
||||
optimize ("-ftree-parallelize-loops=0"). Add successful scans for 2
|
||||
detected reductions.
|
||||
* gcc.dg/vect/trapv-vect-reduc-4.c: Update scan to match vectorized min
|
||||
and max reductions.
|
||||
|
||||
2015-07-31 Marek Polacek <polacek@redhat.com>
|
||||
|
||||
PR sanitizer/66977
|
||||
|
|
|
@ -39,8 +39,9 @@ void main1 (signed char x, signed char max_result, signed char min_result)
|
|||
abort ();
|
||||
}
|
||||
|
||||
__attribute__((noinline))
|
||||
void init_arrays ()
|
||||
void __attribute__((noinline))
|
||||
__attribute__((optimize ("-ftree-parallelize-loops=0")))
|
||||
init_arrays ()
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -60,7 +61,10 @@ int main (void)
|
|||
}
|
||||
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "Detected reduction" 2 "parloops" { xfail *-*-* } } } */
|
||||
/* { dg-final { scan-tree-dump-times "Detected reduction" 2 "parloops" } } */
|
||||
/* { dg-final { scan-tree-dump-times "Detected reduction" 3 "parloops" { xfail *-*-* } } } */
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "SUCCESS: may be parallelized" 2 "parloops" } } */
|
||||
/* { dg-final { scan-tree-dump-times "SUCCESS: may be parallelized" 3 "parloops" { xfail *-*-* } } } */
|
||||
|
||||
|
||||
|
|
|
@ -38,8 +38,9 @@ void main1 (short x, short max_result, short min_result)
|
|||
abort ();
|
||||
}
|
||||
|
||||
__attribute__((noinline))
|
||||
void init_arrays ()
|
||||
void __attribute__((noinline))
|
||||
__attribute__((optimize ("-ftree-parallelize-loops=0")))
|
||||
init_arrays ()
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -58,7 +59,8 @@ int main (void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "Detected reduction" 2 "parloops" } } */
|
||||
/* { dg-final { scan-tree-dump-times "Detected reduction" 3 "parloops" { xfail *-*-* } } } */
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "Detected reduction" 2 "parloops" { xfail *-*-* } } } */
|
||||
/* { dg-final { scan-tree-dump-times "SUCCESS: may be parallelized" 2 "parloops" } } */
|
||||
/* { dg-final { scan-tree-dump-times "SUCCESS: may be parallelized" 3 "parloops" { xfail *-*-* } } } */
|
||||
|
||||
|
|
|
@ -40,7 +40,8 @@ testmin (const T *c, T init, T result)
|
|||
abort ();
|
||||
}
|
||||
|
||||
int main (void)
|
||||
int __attribute__((optimize ("-ftree-parallelize-loops=0")))
|
||||
main (void)
|
||||
{
|
||||
static signed char A[N] = {
|
||||
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
|
||||
|
@ -84,5 +85,5 @@ int main (void)
|
|||
}
|
||||
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "Detected reduction" 2 "parloops" { xfail *-*-* } } } */
|
||||
/* { dg-final { scan-tree-dump-times "SUCCESS: may be parallelized" 3 "parloops" { xfail *-*-* } } } */
|
||||
/* { dg-final { scan-tree-dump-times "Detected reduction" 2 "parloops" } } */
|
||||
/* { dg-final { scan-tree-dump-times "SUCCESS: may be parallelized" 2 "parloops" } } */
|
||||
|
|
|
@ -46,4 +46,4 @@ int main (void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "vectorized 0 loops" 1 "vect" } } */
|
||||
/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" } } */
|
||||
|
|
|
@ -2615,7 +2615,7 @@ vect_is_simple_reduction_1 (loop_vec_info loop_info, gimple phi,
|
|||
}
|
||||
else if (INTEGRAL_TYPE_P (type) && check_reduction)
|
||||
{
|
||||
if (TYPE_OVERFLOW_TRAPS (type))
|
||||
if (!operation_no_trapping_overflow (type, code))
|
||||
{
|
||||
/* Changing the order of operations changes the semantics. */
|
||||
if (dump_enabled_p ())
|
||||
|
@ -2624,7 +2624,9 @@ vect_is_simple_reduction_1 (loop_vec_info loop_info, gimple phi,
|
|||
" (overflow traps): ");
|
||||
return NULL;
|
||||
}
|
||||
if (need_wrapping_integral_overflow && !TYPE_OVERFLOW_WRAPS (type))
|
||||
if (need_wrapping_integral_overflow
|
||||
&& !TYPE_OVERFLOW_WRAPS (type)
|
||||
&& operation_can_overflow (code))
|
||||
{
|
||||
/* Changing the order of operations changes the semantics. */
|
||||
if (dump_enabled_p ())
|
||||
|
|
69
gcc/tree.c
69
gcc/tree.c
|
@ -7597,6 +7597,75 @@ commutative_ternary_tree_code (enum tree_code code)
|
|||
return false;
|
||||
}
|
||||
|
||||
/* Returns true if CODE can overflow. */
|
||||
|
||||
bool
|
||||
operation_can_overflow (enum tree_code code)
|
||||
{
|
||||
switch (code)
|
||||
{
|
||||
case PLUS_EXPR:
|
||||
case MINUS_EXPR:
|
||||
case MULT_EXPR:
|
||||
case LSHIFT_EXPR:
|
||||
/* Can overflow in various ways. */
|
||||
return true;
|
||||
case TRUNC_DIV_EXPR:
|
||||
case EXACT_DIV_EXPR:
|
||||
case FLOOR_DIV_EXPR:
|
||||
case CEIL_DIV_EXPR:
|
||||
/* For INT_MIN / -1. */
|
||||
return true;
|
||||
case NEGATE_EXPR:
|
||||
case ABS_EXPR:
|
||||
/* For -INT_MIN. */
|
||||
return true;
|
||||
default:
|
||||
/* These operators cannot overflow. */
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns true if CODE operating on operands of type TYPE doesn't overflow, or
|
||||
ftrapv doesn't generate trapping insns for CODE. */
|
||||
|
||||
bool
|
||||
operation_no_trapping_overflow (tree type, enum tree_code code)
|
||||
{
|
||||
gcc_checking_assert (ANY_INTEGRAL_TYPE_P (type));
|
||||
|
||||
/* We don't generate instructions that trap on overflow for complex or vector
|
||||
types. */
|
||||
if (!INTEGRAL_TYPE_P (type))
|
||||
return true;
|
||||
|
||||
if (!TYPE_OVERFLOW_TRAPS (type))
|
||||
return true;
|
||||
|
||||
switch (code)
|
||||
{
|
||||
case PLUS_EXPR:
|
||||
case MINUS_EXPR:
|
||||
case MULT_EXPR:
|
||||
case NEGATE_EXPR:
|
||||
case ABS_EXPR:
|
||||
/* These operators can overflow, and -ftrapv generates trapping code for
|
||||
these. */
|
||||
return false;
|
||||
case TRUNC_DIV_EXPR:
|
||||
case EXACT_DIV_EXPR:
|
||||
case FLOOR_DIV_EXPR:
|
||||
case CEIL_DIV_EXPR:
|
||||
case LSHIFT_EXPR:
|
||||
/* These operators can overflow, but -ftrapv does not generate trapping
|
||||
code for these. */
|
||||
return true;
|
||||
default:
|
||||
/* These operators cannot overflow. */
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
namespace inchash
|
||||
{
|
||||
|
||||
|
|
|
@ -4369,6 +4369,8 @@ extern int type_num_arguments (const_tree);
|
|||
extern bool associative_tree_code (enum tree_code);
|
||||
extern bool commutative_tree_code (enum tree_code);
|
||||
extern bool commutative_ternary_tree_code (enum tree_code);
|
||||
extern bool operation_can_overflow (enum tree_code);
|
||||
extern bool operation_no_trapping_overflow (tree, enum tree_code);
|
||||
extern tree upper_bound_in_type (tree, tree);
|
||||
extern tree lower_bound_in_type (tree, tree);
|
||||
extern int operand_equal_for_phi_arg_p (const_tree, const_tree);
|
||||
|
|
Loading…
Reference in New Issue