Commit 18c2511c by Roger Sayle Committed by Roger Sayle

real.c (real_maxval): New function to return the largest finite value…

real.c (real_maxval): New function to return the largest finite value representable in a given mode (i.e.


	* real.c (real_maxval): New function to return the largest finite
	value representable in a given mode (i.e. FLT_MAX and DBL_MAX).
	* real.h (real_maxval): Prototype here.
	* fold-const.c (fold_inf_compare): Transform comparisons against
	+-Infinity into comparisons against DBL_MAX (or equivalent).

	* gcc.c-torture/execute/ieee/inf-2.c: New test case.

From-SVN: r67112
parent a8e097d6
2003-05-22 Roger Sayle <roger@eyesopen.com>
* real.c (real_maxval): New function to return the largest finite
value representable in a given mode (i.e. FLT_MAX and DBL_MAX).
* real.h (real_maxval): Prototype here.
* fold-const.c (fold_inf_compare): Transform comparisons against
+-Infinity into comparisons against DBL_MAX (or equivalent).
2003-05-22 Mike Stump <mrs@apple.com>
* config.gcc (*-*-darwin*): Remove use_collect2=no, as it is the
......
......@@ -4820,15 +4820,23 @@ fold_inf_compare (code, type, arg0, arg1)
enum tree_code code;
tree type, arg0, arg1;
{
enum machine_mode mode;
REAL_VALUE_TYPE max;
tree temp;
bool neg;
mode = TYPE_MODE (TREE_TYPE (arg0));
/* For negative infinity swap the sense of the comparison. */
if (REAL_VALUE_NEGATIVE (TREE_REAL_CST (arg1)))
neg = REAL_VALUE_NEGATIVE (TREE_REAL_CST (arg1));
if (neg)
code = swap_tree_comparison (code);
switch (code)
{
case GT_EXPR:
/* x > +Inf is always false, if with ignore sNANs. */
if (HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0))))
if (HONOR_SNANS (mode))
return NULL_TREE;
return omit_one_operand (type,
convert (type, integer_zero_node),
......@@ -4836,7 +4844,7 @@ fold_inf_compare (code, type, arg0, arg1)
case LE_EXPR:
/* x <= +Inf is always true, if we don't case about NaNs. */
if (! HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))))
if (! HONOR_NANS (mode))
return omit_one_operand (type,
convert (type, integer_one_node),
arg0);
......@@ -4850,10 +4858,28 @@ fold_inf_compare (code, type, arg0, arg1)
}
break;
case EQ_EXPR: /* ??? x == +Inf is x > DBL_MAX */
case GE_EXPR: /* ??? x >= +Inf is x > DBL_MAX */
case LT_EXPR: /* ??? x < +Inf is x <= DBL_MAX */
case NE_EXPR: /* ??? x != +Inf is !(x > DBL_MAX) */
case EQ_EXPR:
case GE_EXPR:
/* x == +Inf and x >= +Inf are always equal to x > DBL_MAX. */
real_maxval (&max, neg, mode);
return fold (build (neg ? LT_EXPR : GT_EXPR, type,
arg0, build_real (TREE_TYPE (arg0), max)));
case LT_EXPR:
/* x < +Inf is always equal to x <= DBL_MAX. */
real_maxval (&max, neg, mode);
return fold (build (neg ? GE_EXPR : LE_EXPR, type,
arg0, build_real (TREE_TYPE (arg0), max)));
case NE_EXPR:
/* x != +Inf is always equal to !(x > DBL_MAX). */
real_maxval (&max, neg, mode);
if (! HONOR_NANS (mode))
return fold (build (neg ? GE_EXPR : LE_EXPR, type,
arg0, build_real (TREE_TYPE (arg0), max)));
temp = fold (build (neg ? LT_EXPR : GT_EXPR, type,
arg0, build_real (TREE_TYPE (arg0), max)));
return fold (build1 (TRUTH_NOT_EXPR, type, temp));
default:
break;
......
......@@ -2280,6 +2280,33 @@ real_nan (r, str, quiet, mode)
return true;
}
/* Fills R with the largest finite value representable in mode MODE.
If SIGN is non-zero, R is set to the most negative finite value. */
void
real_maxval (r, sign, mode)
REAL_VALUE_TYPE *r;
int sign;
enum machine_mode mode;
{
const struct real_format *fmt;
int np2;
fmt = real_format_for_mode[mode - QFmode];
if (fmt == NULL)
abort ();
r->class = rvc_normal;
r->sign = sign;
r->signalling = 0;
r->canonical = 0;
r->exp = fmt->emax * fmt->log2_b;
np2 = SIGNIFICAND_BITS - fmt->p * fmt->log2_b;
memset (r->sig, -1, SIGSZ * sizeof (unsigned long));
clear_significand_below (r, np2);
}
/* Fills R with 2**N. */
void
......
......@@ -219,6 +219,9 @@ extern void real_inf PARAMS ((REAL_VALUE_TYPE *));
extern bool real_nan PARAMS ((REAL_VALUE_TYPE *, const char *,
int, enum machine_mode));
extern void real_maxval PARAMS ((REAL_VALUE_TYPE *, int,
enum machine_mode));
extern void real_2expN PARAMS ((REAL_VALUE_TYPE *, int));
extern unsigned int real_hash PARAMS ((const REAL_VALUE_TYPE *));
......
2003-05-22 Roger Sayle <roger@eyesopen.com>
* gcc.c-torture/execute/ieee/inf-2.c: New test case.
2003-05-21 Janis Johnson <janis187@us.ibm.com>
* gcc.dg/compat/scalar-return-1_main.c: New file.
......
extern void abort (void);
void test(double f, double i)
{
if (f == __builtin_inf())
abort ();
if (f == -__builtin_inf())
abort ();
if (i == -__builtin_inf())
abort ();
if (i != __builtin_inf())
abort ();
if (f >= __builtin_inf())
abort ();
if (f > __builtin_inf())
abort ();
if (i > __builtin_inf())
abort ();
if (f <= -__builtin_inf())
abort ();
if (f < -__builtin_inf())
abort ();
}
void testf(float f, float i)
{
if (f == __builtin_inff())
abort ();
if (f == -__builtin_inff())
abort ();
if (i == -__builtin_inff())
abort ();
if (i != __builtin_inff())
abort ();
if (f >= __builtin_inff())
abort ();
if (f > __builtin_inff())
abort ();
if (i > __builtin_inff())
abort ();
if (f <= -__builtin_inff())
abort ();
if (f < -__builtin_inff())
abort ();
}
void testl(long double f, long double i)
{
if (f == __builtin_infl())
abort ();
if (f == -__builtin_infl())
abort ();
if (i == -__builtin_infl())
abort ();
if (i != __builtin_infl())
abort ();
if (f >= __builtin_infl())
abort ();
if (f > __builtin_infl())
abort ();
if (i > __builtin_infl())
abort ();
if (f <= -__builtin_infl())
abort ();
if (f < -__builtin_infl())
abort ();
}
int main()
{
test (34.0, __builtin_inf());
testf (34.0f, __builtin_inff());
testf (34.0l, __builtin_infl());
return 0;
}
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