#  RFR(M): 8210215: C2 should optimize trichotomy calculations

Tobias Hartmann tobias.hartmann at oracle.com
Tue Oct 2 13:52:45 UTC 2018

```Hi John,

On 02.10.2018 12:48, John Rose wrote:
> That's better.  There aren't really 36 combinations that test trichotomy,
> since some of them are just broken, like (x == y ? 0 : x == y ? 0 : 1).
> Your compare11 to compare14 are like that.
>
> The cases which truly do compute trichotomy are:
>
> x == y ? 0 : x op y ? * : *  where op is one of < > <= >= (4 cases)
> x < y ? -1 : x op y ? * : *  where op is one of > <= == != (4 cases)
> x > y ? 1 : x op y ? * : *  where op is one of < >= == != (4 cases)
>
> And that's 12 cases, which is a bit more than the 10 you have now.
>
> The basic rule is that the first operator must be strict, and the
> second operator may be anything other than the first operator
> or its exact negative.
>
> In addition, I think you should test a few more, to mix up the
> order of the phi/region inputs.  There are two predicates, and
> either can be inverted, but the second is already inverted in
> the above cases.  So invert first predicate to get another 12
> cases:
>
> x != y ? (x op y ? * : *) : 0  where op is one of < > <= >= (4 cases)
> x >= y ? (x op y ? * : *) : -1  where op is one of > <= == != (4 cases)
> x <= y ? (x op y ? * : *) : 1  where op is one of < >= == != (4 cases)

Okay, I've added all of these.

> Also, while you are at it, you could reverse the order of the
> operands of the second comparison, so that the optimizer
> sees "skewed" operand order when it must consider the first
> and second comparisons.
>
> x != y ? (y op x ? * : *) : 0  where op is one of < > <= >= (4 cases)
> x >= y ? (y op x ? * : *) : -1  where op is one of < >= == != (4 cases)
> x <= y ? (y op x ? * : *) : 1  where op is one of > <= == != (4 cases)

Yes but this shape is currently not optimized because I simply check for equality of the CmpNodes.
In this case, we have two different CmpNodes with the same inputs but swapped. I've modified the
code to handle this case by commuting the test of the to-be-removed if (see changes in
cfgnode.cpp:813f):

http://cr.openjdk.java.net/~thartmann/8210215/webrev.03/

> You could complete the square and add another 12 by combining
> the two variations, but that's probably overkill.

I've added them anyway - just to make sure. I've verified that all 432 tests are folded.

Thanks,
Tobias
```