aboutsummaryrefslogtreecommitdiff
path: root/gcc/fold-const.c
diff options
context:
space:
mode:
authorRoger Sayle <roger@eyesopen.com>2003-05-23 03:46:53 +0000
committerRoger Sayle <sayle@gcc.gnu.org>2003-05-23 03:46:53 +0000
commit18c2511ccbc14dc2899b0fb6ec60935ac87087c2 (patch)
tree5b38df8d0da0fa5e04c432815e2f600b41d5f2e5 /gcc/fold-const.c
parenta8e097d6db75fdb7fb530bd571647a656376fe97 (diff)
downloadgcc-18c2511ccbc14dc2899b0fb6ec60935ac87087c2.zip
gcc-18c2511ccbc14dc2899b0fb6ec60935ac87087c2.tar.gz
gcc-18c2511ccbc14dc2899b0fb6ec60935ac87087c2.tar.bz2
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
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r--gcc/fold-const.c40
1 files changed, 33 insertions, 7 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index eb65795..6a4e229 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -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;