Hi, Gently ping it. https://gcc.gnu.org/pipermail/gcc-patches/2024-May/653095.html
Thanks Gui Haochen 在 2024/7/1 9:12, HAO CHEN GUI 写道: > Hi, > Gently ping it. > https://gcc.gnu.org/pipermail/gcc-patches/2024-May/653095.html > > Thanks > Gui Haochen > > 在 2024/6/24 9:41, HAO CHEN GUI 写道: >> Hi, >> Gently ping it. >> https://gcc.gnu.org/pipermail/gcc-patches/2024-May/653095.html >> >> Thanks >> Gui Haochen >> >> 在 2024/6/20 14:58, HAO CHEN GUI 写道: >>> Hi, >>> Gently ping it. >>> https://gcc.gnu.org/pipermail/gcc-patches/2024-May/653095.html >>> >>> Thanks >>> Gui Haochen >>> >>> 在 2024/5/30 10:46, HAO CHEN GUI 写道: >>>> Hi, >>>> This patch adds the range op for builtin isnormal. It also adds two >>>> help function in frange to detect range of normal floating-point and >>>> range of subnormal or zero. >>>> >>>> Compared to previous version, the main change is to set the range to >>>> 1 if it's normal number otherwise to 0. >>>> https://gcc.gnu.org/pipermail/gcc-patches/2024-May/652221.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 isnormal >>>> >>>> The former patch adds optab for builtin isnormal. Thus builtin isnormal >>>> might not be folded at front end. So the range op for isnormal is needed >>>> for value range analysis. This patch adds range op for builtin isnormal. >>>> >>>> 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. >>>> * value-range.h (class frange): Declare known_isnormal and >>>> known_isdenormal_or_zero. >>>> (frange::known_isnormal): Define. >>>> (frange::known_isdenormal_or_zero): Define. >>>> >>>> gcc/testsuite/ >>>> * gcc/testsuite/gcc.dg/tree-ssa/range-isnormal.c: New test. >>>> >>>> patch.diff >>>> diff --git a/gcc/gimple-range-op.cc b/gcc/gimple-range-op.cc >>>> index 5ec5c828fa4..6787f532f11 100644 >>>> --- a/gcc/gimple-range-op.cc >>>> +++ b/gcc/gimple-range-op.cc >>>> @@ -1289,6 +1289,61 @@ public: >>>> } >>>> } op_cfn_isfinite; >>>> >>>> +//Implement range operator for CFN_BUILT_IN_ISNORMAL >>>> +class cfn_isnormal : 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_isnormal ()) >>>> + { >>>> + wide_int one = wi::one (TYPE_PRECISION (type)); >>>> + r.set (type, one, one); >>>> + return true; >>>> + } >>>> + >>>> + if (op1.known_isnan () >>>> + || op1.known_isinf () >>>> + || op1.known_isdenormal_or_zero ()) >>>> + { >>>> + 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 ()) >>>> + { >>>> + 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_isnormal; >>>> + >>>> // Implement range operator for CFN_BUILT_IN_ >>>> class cfn_parity : public range_operator >>>> { >>>> @@ -1391,6 +1446,11 @@ gimple_range_op_handler::maybe_builtin_call () >>>> m_operator = &op_cfn_isfinite; >>>> break; >>>> >>>> + case CFN_BUILT_IN_ISNORMAL: >>>> + m_op1 = gimple_call_arg (call, 0); >>>> + m_operator = &op_cfn_isnormal; >>>> + 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-isnormal.c >>>> b/gcc/testsuite/gcc.dg/tree-ssa/range-isnormal.c >>>> new file mode 100644 >>>> index 00000000000..c4df4d839b0 >>>> --- /dev/null >>>> +++ b/gcc/testsuite/gcc.dg/tree-ssa/range-isnormal.c >>>> @@ -0,0 +1,37 @@ >>>> +/* { 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_MIN__ && !__builtin_isnormal (x)) >>>> + link_error (); >>>> + >>>> + if (x < -__DBL_MIN__ && x > -__DBL_MAX__ && !__builtin_isnormal (x)) >>>> + link_error (); >>>> +} >>>> + >>>> +void test2 (float x) >>>> +{ >>>> + if (x < __FLT_MAX__ && x > __FLT_MIN__ && !__builtin_isnormal (x)) >>>> + link_error (); >>>> + >>>> + if (x < -__FLT_MIN__ && x > - __FLT_MAX__ && !__builtin_isnormal (x)) >>>> + link_error (); >>>> +} >>>> + >>>> +void test3 (double x) >>>> +{ >>>> + if (__builtin_isnormal (x) && __builtin_isinf (x)) >>>> + link_error (); >>>> +} >>>> + >>>> +void test4 (float x) >>>> +{ >>>> + if (__builtin_isnormal (x) && __builtin_isinf (x)) >>>> + link_error (); >>>> +} >>>> + >>>> +/* { dg-final { scan-tree-dump-not "link_error" "evrp" } } */ >>>> diff --git a/gcc/value-range.h b/gcc/value-range.h >>>> index 37ce91dc52d..1443d1906e5 100644 >>>> --- a/gcc/value-range.h >>>> +++ b/gcc/value-range.h >>>> @@ -588,6 +588,8 @@ public: >>>> bool maybe_isinf () const; >>>> bool signbit_p (bool &signbit) const; >>>> bool nan_signbit_p (bool &signbit) const; >>>> + bool known_isnormal () const; >>>> + bool known_isdenormal_or_zero () const; >>>> >>>> protected: >>>> virtual bool contains_p (tree cst) const override; >>>> @@ -1650,6 +1652,33 @@ frange::known_isfinite () const >>>> return (!maybe_isnan () && !real_isinf (&m_min) && !real_isinf >>>> (&m_max)); >>>> } >>>> >>>> +// Return TRUE if range is known to be normal. >>>> + >>>> +inline bool >>>> +frange::known_isnormal () const >>>> +{ >>>> + if (!known_isfinite ()) >>>> + return false; >>>> + >>>> + machine_mode mode = TYPE_MODE (type ()); >>>> + return (!real_isdenormal (&m_min, mode) && !real_isdenormal (&m_max, >>>> mode) >>>> + && !real_iszero (&m_min) && !real_iszero (&m_max) >>>> + && (!real_isneg (&m_min) || real_isneg (&m_max))); >>>> +} >>>> + >>>> +// Return TRUE if range is known to be denormal. >>>> + >>>> +inline bool >>>> +frange::known_isdenormal_or_zero () const >>>> +{ >>>> + if (!known_isfinite ()) >>>> + return false; >>>> + >>>> + machine_mode mode = TYPE_MODE (type ()); >>>> + return ((real_isdenormal (&m_min, mode) || real_iszero (&m_min)) >>>> + && (real_isdenormal (&m_max, mode) || real_iszero (&m_max))); >>>> +} >>>> + >>>> // Return TRUE if range may be infinite. >>>> >>>> inline bool