[llvm] [Transforms/Util] Add SimplifySwitchVar pass (PR #149937)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 30 03:02:07 PDT 2025


nikic wrote:

> However, it only happens if we simplify the switch into a lookup table in [SimplifyCFG](https://github.com/llvm/llvm-project/blob/83dfdd8f5485f6b50213c88f02878f86b3f53852/llvm/lib/Transforms/Utils/SimplifyCFG.cpp#L6459). Correct me if I am wrong, but I think we can't do lookup tables efficiently on AMDGPU due to high memory latencies. Therefore, we would need to separate the linear transformation logic from the LUT creation. Then we also need to think about what to do if we have outliers, but this is less important for the case we are looking at right now.

Can't comment on the AMDGPU question, but yes to the rest: The transform of switches to linear expressions (and other representations) is currently tightly bound to lookup table generation, but it really shouldn't be. While I'd expect some of the implementation to be shared, TTI disabling lookup tables, or use of no-jump-tables really shouldn't prevent the linear expression fold. Another benefit of separating these is that we can run parts of this earlier, pre-inlining (while lookup tables should always be generated late).

I'd also love to see further generalization of that code to pick more complex mapping functions, ideally it would not be defeated by needing an extra zext somewhere.

But just getting the existing SimplifyCFG code to work for AMDGPU seems like significant win independently of the more complex cases involving GEP sinking etc.

> For this simplification to apply to the cases we are targeting, we need to
> 
>  1. improve the sinking of `getelementptr`s, so that there is only one gep in the final block and the phi only contains the offset. How should we sink if we have outliers and not every predecessor has a gep? Or if one of the geps is further away and used in multiple switches as base pointer, but is not duplicated into the relevant basic blocks?
> 
>  2. recognize base pointers, even if they don't come from a `getelementptr` with 0 offset, so we can sink them
> 
>  3. use the same logic in SimplifyCFG to find the linear transformations of the offsets, but without the LUT creation

I think https://github.com/llvm/llvm-project/pull/128171 tries to implement the necessary GEP sinking support, but I haven't looked in detail.

The general approach isn't really suitable for handling outliers. Are these important to your motivating cases?

https://github.com/llvm/llvm-project/pull/149937


More information about the llvm-commits mailing list