[InstCombine] Bad codegen for gep(p, select cond, 0, const) over select(cond, p, gep p, const)
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
gep(p, select cond, 0, const) tends to result in worse codegen than select(cond, p, gep p, const). InstCombine currently canonicalizes in the other direction. Not sure if we should prefer to canonicalize src->tgt or handle this in SelectionDAG.
```c++
struct U {long x[4]; }; U *src(U *u, unsigned x) { return x ? u - 1 : u; }
```
```llvm
define ptr @src(ptr %0, i32 %1) {
%3 = icmp eq i32 %1, 0
%4 = select i1 %3, i64 0, i64 -32
%5 = getelementptr inbounds i8, ptr %0, i64 %4
ret ptr %5
}
define ptr @tgt(ptr %0, i32 %1) {
%3 = icmp eq i32 %1, 0
%4 = getelementptr inbounds i8, ptr %0, i64 -32
%5 = select i1 %3, ptr %0, ptr %4
ret ptr %5
}
```
```asm
src: # @src
xor eax, eax
test esi, esi
sete al
shl eax, 5
lea rax, [rax + rdi - 32]
ret
tgt: # @tgt
lea rax, [rdi - 32]
test esi, esi
cmove rax, rdi
ret
src: // @src
mov x8, #-32 // =0xffffffffffffffe0
cmp w1, #0
csel x8, xzr, x8, eq
add x0, x0, x8
ret
tgt: // @tgt
sub x8, x0, #32
cmp w1, #0
csel x0, x0, x8, eq
ret
```
https://alive2.llvm.org/ce/z/8C7vQu
Contributor guide
Research direction
Start by reproducing the src and tgt examples for x86 and AArch64, then compare the InstCombine canonicalization with the SelectionDAG alternative. Use the provided LLVM IR and Alive2 link to verify equivalence; done means choosing and implementing a direction that produces the better codegen without breaking the transformation.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Needs clarification
- Newbie friendliness
- 30/100