[PATCH-2v3] Value Range: Add range op for builtin isfinite
Checks
Commit Message
Hi,
This patch adds the range op for builtin isfinite.
Compared to previous version, the main change is to set varying if
nothing is known about the range.
https://gcc.gnu.org/pipermail/gcc-patches/2024-May/650857.html
Bootstrapped and tested on x86 and powerpc64-linux BE and LE with no
regressions. Is it OK for the trunk?
Thanks
Gui Haochen
ChangeLog
Value Range: Add range op for builtin isfinite
The former patch adds optab for builtin isfinite. Thus builtin isfinite
might not be folded at front end. So the range op for isfinite is needed
for value range analysis. This patch adds range op for builtin isfinite.
gcc/
* gimple-range-op.cc (class cfn_isfinite): New.
(op_cfn_finite): New variables.
(gimple_range_op_handler::maybe_builtin_call): Handle
CFN_BUILT_IN_ISFINITE.
gcc/testsuite/
* gcc/testsuite/gcc.dg/tree-ssa/range-isfinite.c: New test.
patch.diff
@@ -1229,6 +1229,61 @@ public:
}
} op_cfn_isinf;
+//Implement range operator for CFN_BUILT_IN_ISFINITE
+class cfn_isfinite : 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_isfinite ())
+ {
+ r.set_nonzero (type);
+ return true;
+ }
+
+ if (op1.known_isnan ()
+ || op1.known_isinf ())
+ {
+ 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 ())
+ {
+ // The range is [-INF,-INF][+INF,+INF] NAN, but it can't be represented.
+ // Set range to varying
+ r.set_varying (type);
+ return true;
+ }
+
+ if (!range_includes_zero_p (lhs))
+ {
+ nan_state nan (false);
+ r.set (type, real_min_representable (type),
+ real_max_representable (type), nan);
+ return true;
+ }
+
+ r.set_varying (type);
+ return true;
+ }
+} op_cfn_isfinite;
+
// Implement range operator for CFN_BUILT_IN_
class cfn_parity : public range_operator
{
@@ -1326,6 +1381,11 @@ gimple_range_op_handler::maybe_builtin_call ()
m_operator = &op_cfn_isinf;
break;
+ case CFN_BUILT_IN_ISFINITE:
+ m_op1 = gimple_call_arg (call, 0);
+ m_operator = &op_cfn_isfinite;
+ break;
+
CASE_CFN_COPYSIGN_ALL:
m_op1 = gimple_call_arg (call, 0);
m_op2 = gimple_call_arg (call, 1);
new file mode 100644
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-evrp" } */
+
+#include <math.h>
+void link_error();
+
+void test1 (double x)
+{
+ if (x < __DBL_MAX__ && x > -__DBL_MAX__ && !__builtin_isfinite (x))
+ link_error ();
+}
+
+void test2 (float x)
+{
+ if (x < __FLT_MAX__ && x > -__FLT_MAX__ && !__builtin_isfinite (x))
+ link_error ();
+}
+
+void test3 (double x)
+{
+ if (__builtin_isfinite (x) && __builtin_isinf (x))
+ link_error ();
+}
+
+void test4 (float x)
+{
+ if (__builtin_isfinite (x) && __builtin_isinf (x))
+ link_error ();
+}
+
+/* { dg-final { scan-tree-dump-not "link_error" "evrp" } } */