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

Reply via email to