https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94919

--- Comment #1 from Marc Glisse <glisse at gcc dot gnu.org> ---
This seems related to another one you reported, in the category: i&-b == b?i:0
(for b∈{0,1}). The first form has the advantage of no branch, while the second
is less obfuscated and simplifies more naturally (like when we combine x<0||y<0
to (x|y)<0 we get something shorter, but more obfuscated which can hinder other
optimizations). Here this equivalence gives the intermediate step of
(x>=y?x^y:0)^y.

I didn't see if you posted it somewhere, but I assume those tests come from the
llvm testsuite? Did people really hit such weird code in the wild and add them
one by one to llvm? Or was there some automated process involved ? I could
imagine looking at all the expressions of a certain size using some list of
operators and only 2 variables (and maybe a few constants), compute the table
of values for a small type (a 3-bit integer?), put them in a hash table, and
study collisions? Generating completely automatically the list of
transformations may be a bit hard though. And handling undefined cases (like
signed overflow) complicates things, since we are not looking for exact matches
there.

Reply via email to