On Thu, Aug 07, 2025 at 09:37:24AM +0000, Thomas de Bock wrote:
> Why does that it not matter that the destination of all the chain blocks'
> FALSE edge is the same, if we have:
> <bb 1> :
> _1 = this_13(D)->a;
> _2 = _14(D)->a;
> if (_1 == _2)
>   goto <bb 2>; [INV]
> else
>   goto <bb X>; [INV]
> <bb 2> :
> _3 = this_13(D)->b;
> _4 = _14(D)->b;
> if (_3 == _4)
>   goto <bb 3>; [INV]
> else
>   goto <bb Y>; [INV]
> ...
> Where X != B, and we replace bb 1 and 2 with, for example, a single bb:
> 
> <bb 4> :
> _5 = &this_13(D)->a;
> _6 = &_14(D)->a;
> _7 = __builtin_memcmp(_5, _6, somelen)
> if (_1 == _2)
>   goto <bb 3>; [INV]
> else
>   goto <bb Z>; [INV]
> 
> How are we going to decide what block Z is, since <bb 1> and <bb 2> go 
> somewhere
> different when their respective field was found to not match, but in <bb 4> we
> do not know which field caused the mismatch so we can only branch to 1 block.
> But using either X or Y for Z will result in an "optimization" that changes 
> the
> program's behaviour.

In order to replace the series of equality comparisons with memcmp, all the
edges for cases when the two SSA_NAMEs aren't equal (so for == the
EDGE_FALSE_VALUE destination, for != EDGE_TRUE_VALUE destination) have to be
the same.  So, X has to be the same as Y in your example above.
And the other edges have to point to (except for the last bb in the series)
point to the bb with next comparison.
Furthermore, not just that, but if there are any PHIs in that basic block,
for all PHIs the PHI arguments from all those edges have to be the same.
Otherwise the optimization needs to give up.

BTW, I don't think the pattern recognition should be done too early, I think
it should be done shortly after IPA optimizations, so that all inlining is
done and you can actually see everything.

        Jakub

Reply via email to