diff options
author | Pedro Lobo <pedro.lobo@tecnico.ulisboa.pt> | 2025-08-22 23:23:14 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-08-22 23:23:14 +0100 |
commit | a43c49f41e7cb6794e2f49abe8d14085948fe88c (patch) | |
tree | 3be1fb5a836daa77ca8b95444129830fe5b31f58 /llvm/utils/TableGen/DecoderEmitter.cpp | |
parent | 085d0b001674944613f61a143060350f138859e3 (diff) | |
download | llvm-a43c49f41e7cb6794e2f49abe8d14085948fe88c.zip llvm-a43c49f41e7cb6794e2f49abe8d14085948fe88c.tar.gz llvm-a43c49f41e7cb6794e2f49abe8d14085948fe88c.tar.bz2 |
[InstCombine] Fold `(x == A) || (x & -Pow2) == A + 1` into range check (#153842)
Extends `foldAndOrOfICmpsUsingRanges` to recognize and fold idioms of
the form `(x == A) || (x & -Pow2) == A + 1`, where A + 1 is aligned to
the mask and A > |mask|.
These patterns represent a special case of contiguous range checks and
can be optimized into an addition and comparison.
```llvm
define i1 @src(i32 %x) {
%icmp1 = icmp eq i32 %x, 127
%and = and i32 %x, -32
%icmp2 = icmp eq i32 %and, 128
%ret = or i1 %icmp1, %icmp2
ret i1 %ret
}
define i1 @tgt(i32 %x) {
%1 = add i32 %x, -127
%2 = icmp ult i32 %1, 33
ret i1 %2
}
```
The same can be done for a conjunction of inequalities, of the form
`(x != A) && (x & -Pow2) != A + 1`.
```llvm
define i1 @src(i32 %x) {
%icmp1 = icmp ne i32 %x, 127
%and = and i32 %x, -32
%icmp2 = icmp ne i32 %and, 128
%result = and i1 %icmp1, %icmp2
ret i1 %result
}
define i1 @tgt(i32 %x) {
%1 = add i32 %x, -160
%2 = icmp ult i32 %1, -33
ret i1 %2
}
```
Alive2 Proof:
- Equality: https://alive2.llvm.org/ce/z/gwELqs
- Inequality: https://alive2.llvm.org/ce/z/ZPdSDt
Closes #152948.
Diffstat (limited to 'llvm/utils/TableGen/DecoderEmitter.cpp')
0 files changed, 0 insertions, 0 deletions