This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] ARM half-precision floating point, 5/8 (detect constant overflow)
- From: Sandra Loosemore <sandra at codesourcery dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Wed, 15 Apr 2009 18:23:43 -0400
- Subject: [PATCH] ARM half-precision floating point, 5/8 (detect constant overflow)
This patch adds some logic to detect overflow on compile-time
constant conversions between floating-point formats. There's nothing
specific to half-precision here, but the main thing it's intended to
catch is overflows in conversions to formats that can't represent
infinities -- specifically, the ARM alternative half-precision
representation.
-Sandra
2009-04-15 Sandra Loosemore <sandra@codesourcery.com>
gcc/
* fold-const.c (fold_convert_const_real_from_real): Check for
overflow.
Index: gcc/fold-const.c
===================================================================
--- gcc/fold-const.c (revision 146010)
+++ gcc/fold-const.c (working copy)
@@ -2327,7 +2327,24 @@ fold_convert_const_real_from_real (tree
real_convert (&value, TYPE_MODE (type), &TREE_REAL_CST (arg1));
t = build_real (type, value);
- TREE_OVERFLOW (t) = TREE_OVERFLOW (arg1);
+ /* If converting an infinity or NAN to a representation that doesn't
+ have one, set the overflow bit so that we can produce some kind of
+ error message at the appropriate point if necessary. It's not the
+ most user-friendly message, but it's better than nothing. */
+ if (REAL_VALUE_ISINF (TREE_REAL_CST (arg1))
+ && !MODE_HAS_INFINITIES (TYPE_MODE (type)))
+ TREE_OVERFLOW (t) = 1;
+ else if (REAL_VALUE_ISNAN (TREE_REAL_CST (arg1))
+ && !MODE_HAS_NANS (TYPE_MODE (type)))
+ TREE_OVERFLOW (t) = 1;
+ /* Regular overflow, conversion produced an infinity in a mode that
+ can't represent them. */
+ else if (!MODE_HAS_INFINITIES (TYPE_MODE (type))
+ && REAL_VALUE_ISINF (value)
+ && !REAL_VALUE_ISINF (TREE_REAL_CST (arg1)))
+ TREE_OVERFLOW (t) = 1;
+ else
+ TREE_OVERFLOW (t) = TREE_OVERFLOW (arg1);
return t;
}