On Dec 18, 2024, Jakub Jelinek <ja...@redhat.com> wrote:

> and the comment right above the xor_p handling says
>   /* Turn (a ^ b) [!]= 0 into a [!]= b.  */
> but I don't see anything that would actually check that the other operand is
> 0, in the testcase below it happily optimizes (a ^ 1) == 8 into a == 1.

> The following patch adds that check.

Ugh, indeed, thanks!

> One worrying thing is the
>   /* Drop casts, only save the outermost type.  We need not worry about
>      narrowing then widening casts, or vice-versa, for those that are not
>      essential for the compare have already been optimized out at this
>      point.  */

*nod*, that one bugged me as well, but it resisted my attempts to come
up with a counterexample.  Fortunately, PR118046 came to the rescue, and
there's a patch pending review that should alleviate this specific concern.
https://gcc.gnu.org/pipermail/gcc-patches/2024-December/671809.html
I see I failed to adjust that comment, though.  Fixing...

> Also, e.g. for the xor optimization, I think there is a difference between
> int a and
>   (a ^ 0x23) == 0
> and
>   ((int) (((unsigned char) a) ^ (unsigned char) 0x23)) == 0
> etc.

Yup.  In the latter case, the final conversion to int is dropped before
we reach ifcombine, so outer_type is unsigned char and it works just as
expected.


> Another thing I'm worrying about are mixing up the different patterns
> together, there is the BIT_AND_EXPR handling, BIT_XOR_EXPR handling,
> RSHIFT_EXPR handling and then load handling.
> What if all 4 appear together, or 3 of them, 2 of them?

These combinations have come up often during testing, and I'm pretty
confident about them.  Their order in which they appear is relevant for
the code, as it is, to be able to deal with them all.

The last-minute rewrites, after years of not touching this intricate
pair of functions in gimple-fold, have been a significant source of
fallout, alas.

> Is the xor optimization still valid if there is BIT_AND_EXPR in between?
> I.e. instead of
>   (a ^ 123) == 0
> there is
>   ((a ^ 123) & 234) == 0
> ?

Yeah, that bit is sound, at least in theory.  The mask is (supposed to
be?) recognized and applied on both xor operands.  That's the reason why
*xor_cmp_op = *pexp rather than = exp.


Please feel free to share any other concerns you might have, I'd be
happy to double-check, and hopefully alleviate them, or at least follow
leads to other problems I haven't considered.

Thanks,

-- 
Alexandre Oliva, happy hacker            https://FSFLA.org/blogs/lxo/
   Free Software Activist                   GNU Toolchain Engineer
More tolerance and less prejudice are key for inclusion and diversity
Excluding neuro-others for not behaving ""normal"" is *not* inclusive

Reply via email to