Thanks Richard and Jakub for comments. 

Ideally would like to make sure the imm operand will have exactly the same type 
as operand 1.
But for uint8_t/uint16_t types, the INTERGER_CST will become the (const_int 3) 
with int type before matching.
Thus, add the type check like that, as well as some negative test case like 
fail to match .SAT_ADD (uint32_t, 3ull).. etc.

.SAT_ADD (uint8_t, (uint8_t)3u)
.SAT_ADD (uint16_t, (uint16_t)3u)
.SAT_ADD (uint32_t, 3u)
.SAT_ADD (uint64_t, 3ull)

Thanks again, good to know int_fits_type_p and let me have a try in v2.

Pan

-----Original Message-----
From: Jakub Jelinek <ja...@redhat.com> 
Sent: Sunday, August 25, 2024 1:16 AM
To: Li, Pan2 <pan2...@intel.com>
Cc: gcc-patches@gcc.gnu.org; richard.guent...@gmail.com; 
tamar.christ...@arm.com; juzhe.zh...@rivai.ai; kito.ch...@gmail.com; 
jeffreya...@gmail.com; rdapp....@gmail.com
Subject: Re: [PATCH v1] Match: Add type check for .SAT_ADD imm operand

On Sat, Aug 24, 2024 at 07:33:06PM +0800, pan2...@intel.com wrote:
> From: Pan Li <pan2...@intel.com>
> 
> This patch would like to add strict check for imm operand of .SAT_ADD
> matching.  We have no type checking for imm operand in previous,  which
> may result in unexpected IL to be catched by .SAT_ADD pattern.
> 
> However,  things may become more complicated due to the int promotion.
> This means any const_int without any suffix will be promoted to int
> before matching.  For example as below.
> 
> uint8_t a;
> uint8_t sum = .SAT_ADD (a, 12);
> 
> The second operand will be (const_int 12) with int type when try to
> match .SAT_ADD.  Thus,  to support int8/int16 .SAT_ADD,  only the
> int32 and int64 will be strictly checked.
> 
> The below test suite are passed for this patch:
> * The rv64gcv fully regression test.
> * The x86 bootstrap test.
> * The x86 fully regression test.
> 
> gcc/ChangeLog:
> 
>       * match.pd:

???
>       * match.pd: Add strict type check for .SAT_ADD imm operand.

Usually you should say
        * match.pd (pattern you change): What you change.

> --- a/gcc/match.pd
> +++ b/gcc/match.pd
> @@ -3190,7 +3190,16 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>   (cond^ (ne (imagpart (IFN_ADD_OVERFLOW@2 @0 INTEGER_CST@1)) integer_zerop)
>    integer_minus_onep (realpart @2))
>    (if (INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type)
> -      && types_match (type, @0))))
> +       && types_match (type, @0))
> +   (with
> +    {
> +     unsigned precision = TYPE_PRECISION (type);
> +     unsigned int_precision = HOST_BITS_PER_INT;

This has nothing to do with HOST_BITS_PER_INT.
The INTEGER_CST can have any type, not just int.

> +    }
> +    /* The const_int will perform int promotion,  the const_int will have at

const_int (well, CONST_INT) is an RTL name, it is INTEGER_CST in GIMPLE.
Just one space after ,

> +       least the int_precision.  Thus, type less than int_precision will be
> +       skipped the type match checking.  */

But the whole comment doesn't make much sense to me, the INTEGER_CST won't
perform any int promotion.

> +    (if (precision < int_precision || types_match (type, @1))))))

Why do you compare precision of type against anything?

You want to check that the INTEGER_CST@1 is representable in the type
(compatible with TREE_TYPE (@0)), because only then the caller can
fold_convert @1 to type without the value being altered.
So, IMHO best would be
    (if (int_fits_type_p (@1, type))))))

        Jakub

Reply via email to