diff options
Diffstat (limited to 'gcc/tree.cc')
-rw-r--r-- | gcc/tree.cc | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/gcc/tree.cc b/gcc/tree.cc index 581d448..6b3273e 100644 --- a/gcc/tree.cc +++ b/gcc/tree.cc @@ -3180,6 +3180,35 @@ real_minus_onep (const_tree expr) } } +/* Return true if T could be a floating point zero. */ + +bool +real_maybe_zerop (const_tree expr) +{ + switch (TREE_CODE (expr)) + { + case REAL_CST: + /* Can't use real_zerop here, as it always returns false for decimal + floats. And can't use TREE_REAL_CST (expr).cl == rvc_zero + either, as decimal zeros are rvc_normal. */ + return real_equal (&TREE_REAL_CST (expr), &dconst0); + case COMPLEX_CST: + return (real_maybe_zerop (TREE_REALPART (expr)) + || real_maybe_zerop (TREE_IMAGPART (expr))); + case VECTOR_CST: + { + unsigned count = vector_cst_encoded_nelts (expr); + for (unsigned int i = 0; i < count; ++i) + if (real_maybe_zerop (VECTOR_CST_ENCODED_ELT (expr, i))) + return true; + return false; + } + default: + /* Perhaps for SSA_NAMEs we could query frange. */ + return true; + } +} + /* Nonzero if EXP is a constant or a cast of a constant. */ bool |