Commit 805134b9 by Tom de Vries Committed by Tom de Vries

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
parent faf4ac32
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> 2015-07-31 Kaz Kojima <kkojima@gcc.gnu.org>
PR target/67049 PR target/67049
......
...@@ -2614,8 +2614,11 @@ is_reduction_operation_p (gimple stmt) ...@@ -2614,8 +2614,11 @@ is_reduction_operation_p (gimple stmt)
if (FLOAT_TYPE_P (type)) if (FLOAT_TYPE_P (type))
return flag_associative_math; return flag_associative_math;
return (INTEGRAL_TYPE_P (type) if (ANY_INTEGRAL_TYPE_P (type))
&& TYPE_OVERFLOW_WRAPS (type)); return (TYPE_OVERFLOW_WRAPS (type)
|| !operation_can_overflow (code));
return false;
} }
/* Returns true when PHI contains an argument ARG. */ /* Returns true when PHI contains an argument ARG. */
......
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> 2015-07-31 Marek Polacek <polacek@redhat.com>
PR sanitizer/66977 PR sanitizer/66977
......
...@@ -39,8 +39,9 @@ void main1 (signed char x, signed char max_result, signed char min_result) ...@@ -39,8 +39,9 @@ void main1 (signed char x, signed char max_result, signed char min_result)
abort (); abort ();
} }
__attribute__((noinline)) void __attribute__((noinline))
void init_arrays () __attribute__((optimize ("-ftree-parallelize-loops=0")))
init_arrays ()
{ {
int i; int i;
...@@ -60,7 +61,10 @@ int main (void) ...@@ -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 *-*-* } } } */ /* { 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) ...@@ -38,8 +38,9 @@ void main1 (short x, short max_result, short min_result)
abort (); abort ();
} }
__attribute__((noinline)) void __attribute__((noinline))
void init_arrays () __attribute__((optimize ("-ftree-parallelize-loops=0")))
init_arrays ()
{ {
int i; int i;
...@@ -58,7 +59,8 @@ int main (void) ...@@ -58,7 +59,8 @@ int main (void)
return 0; 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 *-*-* } } } */ /* { 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) ...@@ -40,7 +40,8 @@ testmin (const T *c, T init, T result)
abort (); abort ();
} }
int main (void) int __attribute__((optimize ("-ftree-parallelize-loops=0")))
main (void)
{ {
static signed char A[N] = { static signed char A[N] = {
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
...@@ -84,5 +85,5 @@ int main (void) ...@@ -84,5 +85,5 @@ 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 "SUCCESS: may be parallelized" 3 "parloops" { xfail *-*-* } } } */ /* { dg-final { scan-tree-dump-times "SUCCESS: may be parallelized" 2 "parloops" } } */
...@@ -46,4 +46,4 @@ int main (void) ...@@ -46,4 +46,4 @@ int main (void)
return 0; 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, ...@@ -2615,7 +2615,7 @@ vect_is_simple_reduction_1 (loop_vec_info loop_info, gimple phi,
} }
else if (INTEGRAL_TYPE_P (type) && check_reduction) 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. */ /* Changing the order of operations changes the semantics. */
if (dump_enabled_p ()) if (dump_enabled_p ())
...@@ -2624,7 +2624,9 @@ vect_is_simple_reduction_1 (loop_vec_info loop_info, gimple phi, ...@@ -2624,7 +2624,9 @@ vect_is_simple_reduction_1 (loop_vec_info loop_info, gimple phi,
" (overflow traps): "); " (overflow traps): ");
return NULL; 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. */ /* Changing the order of operations changes the semantics. */
if (dump_enabled_p ()) if (dump_enabled_p ())
......
...@@ -7597,6 +7597,75 @@ commutative_ternary_tree_code (enum tree_code code) ...@@ -7597,6 +7597,75 @@ commutative_ternary_tree_code (enum tree_code code)
return false; 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 namespace inchash
{ {
......
...@@ -4369,6 +4369,8 @@ extern int type_num_arguments (const_tree); ...@@ -4369,6 +4369,8 @@ extern int type_num_arguments (const_tree);
extern bool associative_tree_code (enum tree_code); extern bool associative_tree_code (enum tree_code);
extern bool commutative_tree_code (enum tree_code); extern bool commutative_tree_code (enum tree_code);
extern bool commutative_ternary_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 upper_bound_in_type (tree, tree);
extern tree lower_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); extern int operand_equal_for_phi_arg_p (const_tree, const_tree);
......
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