Richard Biener via Gcc-patches <[email protected]> writes:
> On Thu, Jul 8, 2021 at 1:52 PM Richard Sandiford via Gcc-patches
> <[email protected]> wrote:
>>
>> match.pd has a rule to simplify an extension, operation and truncation
>> back to the original type:
>>
>> (simplify
>> (convert (op:s@0 (convert1?@3 @1) (convert2?@4 @2)))
>>
>> Currently it handles cases in which @2 is an INTEGER_CST, but it
>> also works for POLY_INT_CSTs.[*]
>>
>> For INTEGER_CST it doesn't matter whether we test @2 or @4,
>> but for POLY_INT_CST it is possible to have unfolded (convert …)s.
>
> But if it is an unfolded conversion then @4 is the conversion and of
> course not POLY_INT_CST_P, so I'm not sure what you says makes
> sense. But maybe you want to _not_ simplify the unfolded
> conversion case?
Yeah, exactly that. Extensions of POLY_INT_CSTs won't be folded because
extension doesn't distribute over (modulo) +. If an unfolded POLY_INT_CST
has the same type as @1 then the match will succeed thanks to
types_match (@1, @2). So the new pattern handles both that case
and the case in which POLY_INT_CST occurs without a conversion.
If an unfolded POLY_INT_CST has a different type from @1 then we'd need
a more complicated check for validity. Maybe that would be useful,
but it would no longer be a one-line change :-)
Thanks,
Richard
>
>> Originally I saw this leading to some bad ivopts decisions, because
>> we weren't folding away redundancies from candidate iv expressions.
>> It's also possible to test the fold directly using the SVE ACLE.
>>
>> Tested on aarch64-linux-gnu and x86_64-linux-gnu, pushed as obvious.
>>
>> Richard
>>
>> [*] Not all INTEGER_CST rules work for POLY_INT_CSTs, since extensions
>> don't necessarily distribute over the internals of the POLY_INT_CST.
>> But in this case that isn't an issue.
>>
>>
>> gcc/
>> * match.pd: Simplify an extend-operate-truncate sequence involving
>> a POLY_INT_CST.
>>
>> gcc/testsuite/
>> * gcc.target/aarch64/sve/acle/general/cntb_1.c: New test.
>> ---
>> gcc/match.pd | 2 +-
>> .../gcc.target/aarch64/sve/acle/general/cntb_1.c | 14 ++++++++++++++
>> 2 files changed, 15 insertions(+), 1 deletion(-)
>> create mode 100644
>> gcc/testsuite/gcc.target/aarch64/sve/acle/general/cntb_1.c
>>
>> diff --git a/gcc/match.pd b/gcc/match.pd
>> index 334e8cc0496..30680d488ab 100644
>> --- a/gcc/match.pd
>> +++ b/gcc/match.pd
>> @@ -6175,7 +6175,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>> && (types_match (@1, @2)
>> /* Or the second operand is const integer or converted const
>> integer from valueize. */
>> - || TREE_CODE (@2) == INTEGER_CST))
>> + || poly_int_tree_p (@4)))
>> (if (TYPE_OVERFLOW_WRAPS (TREE_TYPE (@1)))
>> (op @1 (convert @2))
>> (with { tree utype = unsigned_type_for (TREE_TYPE (@1)); }
>> diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general/cntb_1.c
>> b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/cntb_1.c
>> new file mode 100644
>> index 00000000000..b43fcf0ed6d
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/cntb_1.c
>> @@ -0,0 +1,14 @@
>> +/* { dg-options "-O -fdump-tree-optimized" } */
>> +
>> +#include <arm_sve.h>
>> +
>> +unsigned int
>> +foo (unsigned int x)
>> +{
>> + unsigned long tmp = x;
>> + tmp += svcntb ();
>> + x = tmp;
>> + return x - svcntb ();
>> +}
>> +
>> +/* { dg-final { scan-tree-dump-not { POLY_INT_CST } optimized } } */
>> --
>> 2.17.1
>>