aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHaochen Gui <guihaoc@gcc.gnu.org>2024-08-15 11:19:10 +0800
committerHaochen Gui <guihaoc@gcc.gnu.org>2024-08-15 11:19:10 +0800
commitcd0930768ff936b681135bf8873e7f7b796a4ed9 (patch)
treee51d104949e25c74000e0ba8b31430b4ce73f440
parent4d2e8fcdaf325357591326812fd032ce6dea44e5 (diff)
downloadgcc-cd0930768ff936b681135bf8873e7f7b796a4ed9.zip
gcc-cd0930768ff936b681135bf8873e7f7b796a4ed9.tar.gz
gcc-cd0930768ff936b681135bf8873e7f7b796a4ed9.tar.bz2
Value Range: Add range op for builtin isinf
The builtin isinf is not folded at front end if the corresponding optab exists. So the range op for isinf is needed for value range analysis. This patch adds range op for builtin isinf. gcc/ PR target/114678 * gimple-range-op.cc (class cfn_isinf): New. (op_cfn_isinf): New variables. (gimple_range_op_handler::maybe_builtin_call): Handle CASE_FLT_FN (BUILT_IN_ISINF). gcc/testsuite/ PR target/114678 * gcc.dg/tree-ssa/range-isinf.c: New test. * gcc.dg/tree-ssa/range-sincos.c: Remove xfail for s390. * gcc.dg/tree-ssa/vrp-float-abs-1.c: Likewise.
-rw-r--r--gcc/gimple-range-op.cc62
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/range-isinf.c44
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/range-sincos.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/vrp-float-abs-1.c2
4 files changed, 108 insertions, 2 deletions
diff --git a/gcc/gimple-range-op.cc b/gcc/gimple-range-op.cc
index a80b93c..2455995 100644
--- a/gcc/gimple-range-op.cc
+++ b/gcc/gimple-range-op.cc
@@ -1153,6 +1153,63 @@ private:
bool m_is_pos;
} op_cfn_goacc_dim_size (false), op_cfn_goacc_dim_pos (true);
+// Implement range operator for CFN_BUILT_IN_ISINF
+class cfn_isinf : public range_operator
+{
+public:
+ using range_operator::fold_range;
+ using range_operator::op1_range;
+ virtual bool fold_range (irange &r, tree type, const frange &op1,
+ const irange &, relation_trio) const override
+ {
+ if (op1.undefined_p ())
+ return false;
+
+ if (op1.known_isinf ())
+ {
+ wide_int one = wi::one (TYPE_PRECISION (type));
+ r.set (type, one, one);
+ return true;
+ }
+
+ if (op1.known_isnan ()
+ || (!real_isinf (&op1.lower_bound ())
+ && !real_isinf (&op1.upper_bound ())))
+ {
+ r.set_zero (type);
+ return true;
+ }
+
+ r.set_varying (type);
+ return true;
+ }
+ virtual bool op1_range (frange &r, tree type, const irange &lhs,
+ const frange &, relation_trio) const override
+ {
+ if (lhs.undefined_p ())
+ return false;
+
+ if (lhs.zero_p ())
+ {
+ nan_state nan (true);
+ r.set (type, real_min_representable (type),
+ real_max_representable (type), nan);
+ return true;
+ }
+
+ if (!range_includes_zero_p (lhs))
+ {
+ // The range is [-INF,-INF][+INF,+INF], but it can't be represented.
+ // Set range to [-INF,+INF]
+ r.set_varying (type);
+ r.clear_nan ();
+ return true;
+ }
+
+ r.set_varying (type);
+ return true;
+ }
+} op_cfn_isinf;
// Implement range operator for CFN_BUILT_IN_
class cfn_parity : public range_operator
@@ -1246,6 +1303,11 @@ gimple_range_op_handler::maybe_builtin_call ()
m_operator = &op_cfn_signbit;
break;
+ CASE_FLT_FN (BUILT_IN_ISINF):
+ m_op1 = gimple_call_arg (call, 0);
+ m_operator = &op_cfn_isinf;
+ break;
+
CASE_CFN_COPYSIGN_ALL:
m_op1 = gimple_call_arg (call, 0);
m_op2 = gimple_call_arg (call, 1);
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/range-isinf.c b/gcc/testsuite/gcc.dg/tree-ssa/range-isinf.c
new file mode 100644
index 0000000..468f1bc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/range-isinf.c
@@ -0,0 +1,44 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-evrp" } */
+
+#include <math.h>
+void link_error();
+
+void
+test1 (double x)
+{
+ if (x > __DBL_MAX__ && !__builtin_isinf (x))
+ link_error ();
+ if (x < -__DBL_MAX__ && !__builtin_isinf (x))
+ link_error ();
+}
+
+void
+test2 (float x)
+{
+ if (x > __FLT_MAX__ && !__builtin_isinf (x))
+ link_error ();
+ if (x < -__FLT_MAX__ && !__builtin_isinf (x))
+ link_error ();
+}
+
+void
+test3 (double x)
+{
+ if (!__builtin_isinf (x) && !__builtin_isnan (x) && x > __DBL_MAX__)
+ link_error ();
+ if (!__builtin_isinf (x) && !__builtin_isnan (x) && x < -__DBL_MAX__)
+ link_error ();
+}
+
+void
+test4 (float x)
+{
+ if (!__builtin_isinf (x) && !__builtin_isnan (x) && x > __FLT_MAX__)
+ link_error ();
+ if (!__builtin_isinf (x) && !__builtin_isnan (x) && x < -__FLT_MAX__)
+ link_error ();
+}
+
+/* { dg-final { scan-tree-dump-not "link_error" "evrp" } } */
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/range-sincos.c b/gcc/testsuite/gcc.dg/tree-ssa/range-sincos.c
index 35b38c3..337f9cd 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/range-sincos.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/range-sincos.c
@@ -40,4 +40,4 @@ stool (double x)
link_error ();
}
-// { dg-final { scan-tree-dump-not "link_error" "evrp" { target { { *-*-linux* } && { glibc } } xfail s390*-*-* } } } xfail: PR114678
+// { dg-final { scan-tree-dump-not "link_error" "evrp" { target { { *-*-linux* } && { glibc } } } } }
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-abs-1.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-abs-1.c
index a814a97..4b7b758 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-abs-1.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-abs-1.c
@@ -14,4 +14,4 @@ foo (double x, double y)
}
}
-// { dg-final { scan-tree-dump-not "link_error" "evrp" { xfail s390*-*-* } } } xfail: PR114678
+// { dg-final { scan-tree-dump-not "link_error" "evrp" } }