aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree.c
diff options
context:
space:
mode:
authorJanis Johnson <janis187@us.ibm.com>2009-06-26 18:27:30 +0000
committerJanis Johnson <janis@gcc.gnu.org>2009-06-26 18:27:30 +0000
commit4b6e55df23bf24b6f73a53510bef97ae8f8cc0b4 (patch)
treea476e7280267448dc0d062d76cbeb6102d637d18 /gcc/tree.c
parent27dbd3ac30a786c4081b2a1d75c3996bff35a374 (diff)
downloadgcc-4b6e55df23bf24b6f73a53510bef97ae8f8cc0b4.zip
gcc-4b6e55df23bf24b6f73a53510bef97ae8f8cc0b4.tar.gz
gcc-4b6e55df23bf24b6f73a53510bef97ae8f8cc0b4.tar.bz2
re PR c/39902 (x * 1.0DF gets wrong value)
PR c/39902 * tree.c (real_zerop, real_onep, real_twop, real_minus_onep): Special-case decimal float constants. * gcc.dg/dfp/pr39902.c: New test. From-SVN: r148982
Diffstat (limited to 'gcc/tree.c')
-rw-r--r--gcc/tree.c25
1 files changed, 17 insertions, 8 deletions
diff --git a/gcc/tree.c b/gcc/tree.c
index 139c1e5..ffdd888 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -1591,7 +1591,8 @@ tree_floor_log2 (const_tree expr)
: floor_log2 (low));
}
-/* Return 1 if EXPR is the real constant zero. */
+/* Return 1 if EXPR is the real constant zero. Trailing zeroes matter for
+ decimal float constants, so don't return 1 for them. */
int
real_zerop (const_tree expr)
@@ -1599,13 +1600,16 @@ real_zerop (const_tree expr)
STRIP_NOPS (expr);
return ((TREE_CODE (expr) == REAL_CST
- && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst0))
+ && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst0)
+ && !(DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (expr)))))
|| (TREE_CODE (expr) == COMPLEX_CST
&& real_zerop (TREE_REALPART (expr))
&& real_zerop (TREE_IMAGPART (expr))));
}
-/* Return 1 if EXPR is the real constant one in real or complex form. */
+/* Return 1 if EXPR is the real constant one in real or complex form.
+ Trailing zeroes matter for decimal float constants, so don't return
+ 1 for them. */
int
real_onep (const_tree expr)
@@ -1613,13 +1617,15 @@ real_onep (const_tree expr)
STRIP_NOPS (expr);
return ((TREE_CODE (expr) == REAL_CST
- && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst1))
+ && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst1)
+ && !(DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (expr)))))
|| (TREE_CODE (expr) == COMPLEX_CST
&& real_onep (TREE_REALPART (expr))
&& real_zerop (TREE_IMAGPART (expr))));
}
-/* Return 1 if EXPR is the real constant two. */
+/* Return 1 if EXPR is the real constant two. Trailing zeroes matter
+ for decimal float constants, so don't return 1 for them. */
int
real_twop (const_tree expr)
@@ -1627,13 +1633,15 @@ real_twop (const_tree expr)
STRIP_NOPS (expr);
return ((TREE_CODE (expr) == REAL_CST
- && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst2))
+ && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst2)
+ && !(DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (expr)))))
|| (TREE_CODE (expr) == COMPLEX_CST
&& real_twop (TREE_REALPART (expr))
&& real_zerop (TREE_IMAGPART (expr))));
}
-/* Return 1 if EXPR is the real constant minus one. */
+/* Return 1 if EXPR is the real constant minus one. Trailing zeroes
+ matter for decimal float constants, so don't return 1 for them. */
int
real_minus_onep (const_tree expr)
@@ -1641,7 +1649,8 @@ real_minus_onep (const_tree expr)
STRIP_NOPS (expr);
return ((TREE_CODE (expr) == REAL_CST
- && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconstm1))
+ && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconstm1)
+ && !(DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (expr)))))
|| (TREE_CODE (expr) == COMPLEX_CST
&& real_minus_onep (TREE_REALPART (expr))
&& real_zerop (TREE_IMAGPART (expr))));