Hi, Gently ping it. https://gcc.gnu.org/pipermail/gcc-patches/2024-May/653096.html
Thanks Gui Haochen 在 2024/6/20 14:56, HAO CHEN GUI 写道: > Hi, > Gently ping it. > https://gcc.gnu.org/pipermail/gcc-patches/2024-May/653096.html > > Thanks > Gui Haochen > > 在 2024/5/30 10:46, HAO CHEN GUI 写道: >> Hi, >> The builtin isinf is not folded at front end if the corresponding optab >> exists. It causes the range evaluation failed on the targets which has >> optab_isinf. For instance, range-sincos.c will fail on the targets which >> has optab_isinf as it calls builtin_isinf. >> >> This patch fixed the problem by adding range op for builtin isinf. >> >> Compared with previous version, the main change is to set the range to >> 1 if it's infinite number otherwise to 0. >> https://gcc.gnu.org/pipermail/gcc-patches/2024-May/652219.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 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/ >> * 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/ >> * gcc/testsuite/gcc.dg/tree-ssa/range-isinf.c: New test. >> >> patch.diff >> diff --git a/gcc/gimple-range-op.cc b/gcc/gimple-range-op.cc >> index 55dfbb23ce2..4e60a42eaac 100644 >> --- a/gcc/gimple-range-op.cc >> +++ b/gcc/gimple-range-op.cc >> @@ -1175,6 +1175,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 >> @@ -1268,6 +1325,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 00000000000..468f1bcf5c7 >> --- /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" } } */ >> +