[ was: [RFC, PR66873] Use graphite for parloops ]
On 22/07/15 13:02, Richard Biener wrote:
+#define FIXED_POINT_TYPE_OVERFLOW_WRAPS_P(TYPE) \
+ (NON_SAT_FIXED_POINT_TYPE_P (TYPE))
somebody with knowledge about fixed-point types needs to review this.
In vect_is_simple_reduction_1 I noticed:
...
else if (SAT_FIXED_POINT_TYPE_P (type) && check_reduction)
{
/* Changing the order of operations changes the semantics. */
if (dump_enabled_p ())
report_vect_op (MSG_MISSED_OPTIMIZATION, def_stmt,
"reduction: unsafe fixed-point math
optimization: ");
return NULL;
}
...
In other words, you can change evaluation order if !SAT_FIXED_POINT_TYPE_P.
It is true that for saturating fixed point, you don't want to change
evaluation order.
But I think that we actually want to test whether the fixed-point type
wraps.
I tried to find proof that non-saturating fixed point wraps, but that
doesn't seem trivial. IMHO, non-trivial enough to define a macro
FIXED_POINT_TYPE_OVERFLOW_WRAPS_P, add a lengthy comment and use that
instead of !SAT_FIXED_POINT_TYPE_P.
The intention of the patch is that it doesn't change behaviour of the
compiler. Currently bootstrapping and reg-testing on x86_64.
OK for trunk?
Thanks,
- Tom
Add FIXED_POINT_TYPE_OVERFLOW_WRAPS_P
2015-07-24 Tom de Vries <t...@codesourcery.com>
* tree.h (FIXED_POINT_TYPE_OVERFLOW_WRAPS_P): Define.
* fold-const.c (split_tree): Use FIXED_POINT_TYPE_OVERFLOW_WRAPS_P.
* tree-ssa-reassoc.c (can_reassociate_p): Same.
* tree-vect-loop.c (vect_is_simple_reduction_1): Same.
---
gcc/fold-const.c | 3 ++-
gcc/tree-ssa-reassoc.c | 2 +-
gcc/tree-vect-loop.c | 4 +++-
gcc/tree.h | 18 ++++++++++++++++++
4 files changed, 24 insertions(+), 3 deletions(-)
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 886922f..2de71bb 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -808,7 +808,8 @@ split_tree (tree in, enum tree_code code, tree *conp, tree *litp,
*litp = in;
else if (TREE_CODE (in) == code
|| ((! FLOAT_TYPE_P (TREE_TYPE (in)) || flag_associative_math)
- && ! SAT_FIXED_POINT_TYPE_P (TREE_TYPE (in))
+ && (!FIXED_POINT_TYPE_P (TREE_TYPE (in))
+ || FIXED_POINT_TYPE_OVERFLOW_WRAPS_P (TREE_TYPE (in)))
/* We can associate addition and subtraction together (even
though the C standard doesn't say so) for integers because
the value is not affected. For reals, the value might be
diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c
index efb813c..2851a13 100644
--- a/gcc/tree-ssa-reassoc.c
+++ b/gcc/tree-ssa-reassoc.c
@@ -4229,7 +4229,7 @@ can_reassociate_p (tree op)
{
tree type = TREE_TYPE (op);
if ((INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_WRAPS (type))
- || NON_SAT_FIXED_POINT_TYPE_P (type)
+ || FIXED_POINT_TYPE_OVERFLOW_WRAPS_P (type)
|| (flag_associative_math && FLOAT_TYPE_P (type)))
return true;
return false;
diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
index 42ba5f8..0e61a02 100644
--- a/gcc/tree-vect-loop.c
+++ b/gcc/tree-vect-loop.c
@@ -2635,7 +2635,9 @@ vect_is_simple_reduction_1 (loop_vec_info loop_info, gimple phi,
return NULL;
}
}
- else if (SAT_FIXED_POINT_TYPE_P (type) && check_reduction)
+ else if (FIXED_POINT_TYPE_P (type) &&
+ !FIXED_POINT_TYPE_OVERFLOW_WRAPS_P (type)
+ && check_reduction)
{
/* Changing the order of operations changes the semantics. */
if (dump_enabled_p ())
diff --git a/gcc/tree.h b/gcc/tree.h
index 360d13e..ab0e537 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -497,6 +497,24 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int,
#define SAT_FIXED_POINT_TYPE_P(TYPE) \
(TREE_CODE (TYPE) == FIXED_POINT_TYPE && TYPE_SATURATING (TYPE))
+/* Nonzero if fixed-point type TYPE wraps at overflow.
+
+ Fixed-point types that are explictly saturating do not wrap at overflow.
+
+ The draft technical report (N1169 draft of ISO/IEC DTR 18037) specifies
+ pragmas to control overflow for a fixed-point type that is not explictly
+ saturating (FX_FRACT_OVERFLOW and FX_ACCUM_OVERFLOW). The possible states
+ of the pragmas are SAT and DEFAULT. The default state for the pragmas is
+ DEFAULT, which means overflow has undefined behaviour. GCC currently does
+ not support these pragmas.
+
+ The de-facto choice of GCC for fixed-point types that are not explictly
+ saturating seems to be modular wrap-around (as specified in Annex E.4 Modwrap
+ overflow). */
+
+#define FIXED_POINT_TYPE_OVERFLOW_WRAPS_P(TYPE) \
+ (NON_SAT_FIXED_POINT_TYPE_P (TYPE))
+
/* Nonzero if TYPE represents a fixed-point type. */
#define FIXED_POINT_TYPE_P(TYPE) (TREE_CODE (TYPE) == FIXED_POINT_TYPE)
--
1.9.1