[llvm-commits] PATCH: instcombine switch on select of constants to br

Frits van Bommel fvbommel at gmail.com
Mon Jan 10 02:10:48 PST 2011


On Mon, Jan 10, 2011 at 4:14 AM, Alistair Lynn <arplynn at gmail.com> wrote:
> So done.

Please don't top-post.

> On 10 Jan 2011, at 02:46, Nick Lewycky wrote:
>
>> Alistair Lynn wrote:
>>> The attached patch catches a previously missed optimisation on switches of the
>>> form switch (select cond, A, B) where A and B are constants - the switch can be
>>> folded to a conditional branch on cond.

I wrote a similar optimization for indirectbr instead of switch.

You're not updating PHI nodes in successors. You should call
Succ->removePredecessor(BB) for each successor that is removed.

Some edge cases:
 - The input values are different, and go to different successors.
Fold into a conditional branch and keep exactly one copy of both
successors.
 - The input values are different, but their successors are the same.
Keep folding this into an unconditional branch, and remove all but one
successor. In particular, note that the successor being jumped to will
have multiple PHI entries for this predecessor, and only one of those
may remain.
 - The input values are equal, or both are caught by the default case.
Remove all other successors and keep folding into unconditional
branch.
 - Some successor blocks that are the successor of multiple switch
cases which are all removed.
 - Some successor blocks that are the successor of multiple switch
cases, some (but not all) of which are removed.

Ideally your test cases should test each of these, with other edges
(not from the switch) going to the successors and (used) PHI nodes
there.


Since all of this may enlarge the code, you may want to factor it out
into a static helper function. You could use
SimplifyIndirectBrOnSelect() as an example, but note that that one has
some different edge cases (for instance, the successors it tries to
remove may not actually be present).
Maybe you can even share some code between that and your
SimplifySwitchOnSelect()? You could probably factor out all of the
code SimplifyIndirectBrOnSelect() uses to update successors[1] to a
separate helper function; the indirectbr-specific edge cases shouldn't
be reachable for a switch so it won't generate incorrect code.


[1]: which is everything after 'BasicBlock *FalseBB'.



More information about the llvm-commits mailing list