# [PATCH] D29107: Fix a bug when unswitching on partial LIV for SwitchInst

Xin Tong via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 1 16:56:02 PST 2017

```trentxintong added a comment.

In https://reviews.llvm.org/D29107#664178, @sanjoy wrote:

> I would say the problem here is that we're not doing a good enough job of choosing a good value to unswitch on (and not that we're unswitching on the wrong "type" of value).  That is, say we have a switch on `Inv & Var` (`Inv` being the loop invariant value) that dispatches on `0`, `200` and `300`.  In such a case, we should clearly unswitch on `Inv == 0` to simplify the switch to a direct branch to the `(Inv & Var) == 0` case in one of the loops.  Similar logic follows if we have a switch on `Inv | Var` and one of the cases is `-1`.
>
> So I think the patch should be structured as:
>
> - Keep `FindLIVLoopCondition` the same (maybe return a bit of extra information to make the next steps easier)
> - In `processCurrentLoop`, check to see if the expression we're switching on simplifies to any of the case values given some constant value for what was returned by `FindLIVLoopCondition`
>   - If there is such a constant value, unswitch on that and profit
>   - Else give up

Yes, the ability to simplify f(x) (The chain of AND(s) and OR(s)) to a meaningful case value is important here. Our current way is to pick 1 of the case values and expecting f(x) simplifies to a meaningful case value, which probably does not happen in many cases. Since we are concerning with a chain of and/or operators working on one or multiple loop-variant values and a single loop invariant values,  I think this is what we could do, we record wether the chain contains AND and OR. Once we have that we can do the following:

- If we have a case 0 in the switch and we only have AND, we can pick loop_invariant as 0, this way we can unswitch case 0 out of the loop.
- if we have a case UNSIGNED_TYPE_MAX (signed -1) and we only have ORs, we can pick the loop_invariant as UNSIGNED_TYPE_MAX and unswitch UNSIGNED_TYPE_MAX out of the loop.

What do you think ?

https://reviews.llvm.org/D29107

```