Hi Jeff, Thanks for your comments. 在 2024/7/12 6:13, Jeff Law 写道: > > > On 7/11/24 1:32 AM, HAO CHEN GUI wrote: >> 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. It >> also fixed the issue in PR114678. >> >> Compared with previous version, the main change is to remove xfail for >> s390 in range-sincos.c and vrp-float-abs-1.c. >> https://gcc.gnu.org/pipermail/gcc-patches/2024-May/653096.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/ >> 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. >> >> patch.diff >> diff --git a/gcc/gimple-range-op.cc b/gcc/gimple-range-op.cc >> index a80b93cf063..24559951dd6 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; >> + } > So why the test for real_isinf on the upper/lower bound? If op1 is known to > be a NaN, then why test the bounds at all? If a bounds test is needed, why > only test the upper bound? > IMHO, logical is if the op1 is a NAN, it's not an infinite number. If the upper and lower bound both are finite numbers, the op1 is not an infinite number. Under both situations, the result should be set to 0 which means op1 isn't an infinite number. > >> + 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 the result of a builtin_isinf is zero, that doesn't mean the input has a > nan state. It means we know it's not infinity. The input argument could be > anything but an Inf. > If the result of a builtin_isinf is zero, it means the input might be a NAN or a finite number. So the range should be [min_rep, max_rep] U NAN.
Looking forward to your further comments. Thanks Gui Haochen > > Jeff