[llvm] [InstCombine] Extend `foldICmpAddConstant` to disjoint `or`. (PR #75899)
Mikhail Gudim via llvm-commits
llvm-commits at lists.llvm.org
Thu Jan 4 01:13:42 PST 2024
mgudim wrote:
OK, I see what's going on. First, note that 9223372036854775792 has 0 in position 63, bits [0, 3] are zero and all other bits are 1. Below is the simplified test case:
```
define i64 @foo(i64 %x, i64 %y, i1 %c) {
%shlx_ = shl i64 %x, 8
%shly_ = shl i64 %y, 4
%add2 = add i64 %shly_, 16
%select_ = select i1 %c, i64 %shlx_, i64 %add2
%add_ = add i64 %select_, 15
%cmp_ = icmp slt i64 %add_, 0
br i1 %cmp_, label %t, label %f
t:
unreachable
f:
%and_ = and i64 %add_, 9223372036854775792
ret i64 %and_
}
```
Before my change, the code looks like this when we come to `visitAnd` in `InstCombine`:
```
define i64 @foo(i64 %x, i64 %y, i1 %c) {
%shlx_ = shl i64 %x, 8
%shly_ = shl i64 %y, 4
%add2 = add i64 %shly_, 16
%select_ = select i1 %c, i64 %shlx_, i64 %add2
%cmp_ = icmp slt i64 %select_, 0
br i1 %cmp_, label %t, label %f
t: ; preds = %0
unreachable
f: ; preds = %0
%add_ = or disjoint i64 %select_, 15
%and = and i64 %select_, 9223372036854775792
ret i64 %and
}
```
In other words, the `cmp_ = icmp slt i64 %select_, 0` was NOT simplified, so we know that if we come to `f` highest bit is zero. We now see that `add` and `and` are not needed.
After my change:
```
define i64 @foo(i64 %x, i64 %y, i1 %c) {
%shlx_ = shl i64 %x, 8
%shly_ = shl i64 %y, 4
%add2 = add i64 %shly_, 16
%select_ = select i1 %c, i64 %shlx_, i64 %add2
%cmp_ = icmp slt i64 %select_, -15
br i1 %cmp_, label %t, label %f
t: ; preds = %0
unreachable
f: ; preds = %0
%add_ = or disjoint i64 %select_, 15
%and = and i64 %add_, 9223372036854775792
ret i64 %and
}
```
The compare instruction is now changed to `%cmp_ = icmp slt i64 %select_, -15`, so now when we analyze `and` we can't deduce that the highest bit is zero anyway.
There are a couple of ways to fix this but I am not sure which one is the best. I was thinking we could add some capabilities to `simplifyICmpWithZero`. Or maybe `foldICmpUsingKnownBits`?
@nikic What do you think?
https://github.com/llvm/llvm-project/pull/75899
More information about the llvm-commits
mailing list