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

Reply via email to