On Wed, Nov 13, 2024 at 5:14 AM Jovan Vukic <[email protected]> wrote:
>
> The patch makes the following simplifications:
> ((X - 1) & ~X) < 0 -> X == 0
> ((X - 1) & ~X) >= 0 -> X != 0
>
> On x86, the number of instructions is reduced from 4 to 3,
> but on platforms like RISC-V, it reduces to a single instruction.
>
> Bootstrapped and tested on x86-linux-gnu with no regressions.
+/* Fold ((X - 1) & ~X) </>= 0 into X ==/!= 0. */
+(for cmp (lt ge)
+ eqne (eq ne)
+ (simplify
+ (cmp:c
+ (bit_and:c
+ (plus @0 integer_minus_onep)
+ (bit_not @0))
+ integer_zerop)
+ (if (!TYPE_UNSIGNED (TREE_TYPE (@0))
+ && INTEGRAL_TYPE_P (type)
+ && INTEGRAL_TYPE_P (TREE_TYPE (@0)))
+ (eqne @0 { build_zero_cst (TREE_TYPE (@0)); }))))
Is there a reason why you test INTEGRAL_TYPE_P (type) ? I don't think
you need to do that.
Second test INTEGRAL_TYPE_P before testing of TYPE_UNSIGNED.
Then the original comparison has a zero in the correct type, just
capture that and use it instead of building a new one (just slightly
faster).
That is:
+ (simplify
+ (cmp:c
+ (bit_and:c
+ (plus @0 integer_minus_onep)
+ (bit_not @0))
+ integer_zerop@1)
...
+ (eqne @0 @1)
Besides those 3 things the patch looks good.
It also might be useful to test `short` and `signed char` as the plus
might be done in an unsigned type.
Thanks,
Andrew Pinski
>
> gcc/ChangeLog:
>
> * match.pd: New pattern.
>
> gcc/testsuite/ChangeLog:
>
> * gcc.dg/tree-ssa/fold_neg_and_zero_cmp.c: New test.
>
>
> CONFIDENTIALITY: The contents of this e-mail are confidential and intended
> only for the above addressee(s). If you are not the intended recipient, or
> the person responsible for delivering it to the intended recipient, copying
> or delivering it to anyone else or using it in any unauthorized manner is
> prohibited and may be unlawful. If you receive this e-mail by mistake, please
> notify the sender and the systems administrator at [email protected]
> immediately.