[all-commits] [llvm/llvm-project] 6bcdd8: [X86] Merge BT with a matching BTR/BTS/BTC (#193612)
Paweł Bylica via All-commits
all-commits at lists.llvm.org
Tue Jun 2 08:08:35 PDT 2026
Branch: refs/heads/main
Home: https://github.com/llvm/llvm-project
Commit: 6bcdd843e302063c4f0d36204686155149a6bb0a
https://github.com/llvm/llvm-project/commit/6bcdd843e302063c4f0d36204686155149a6bb0a
Author: Paweł Bylica <pawel at hepcolgum.band>
Date: 2026-06-02 (Tue, 02 Jun 2026)
Changed paths:
M llvm/lib/Target/X86/X86ISelLowering.cpp
M llvm/lib/Target/X86/X86InstrCompiler.td
M llvm/lib/Target/X86/X86InstrFragments.td
M llvm/test/CodeGen/X86/bittest-big-integer.ll
A llvm/test/CodeGen/X86/bt-merge-fuse.ll
Log Message:
-----------
[X86] Merge BT with a matching BTR/BTS/BTC (#193612)
Fixes #165291.
BTR/BTS/BTC set CF from the pre-operation bit value, so a subsequent BT
on the same source and bit index produces the same CF and is redundant.
We were emitting both.
```ll
define i1 @btr_eq_i32(ptr %word, i32 %position) nounwind {
%ofs = and i32 %position, 31
%bit = shl nuw i32 1, %ofs
%mask = xor i32 %bit, -1
%ld = load i32, ptr %word
%test = and i32 %ld, %bit
%res = and i32 %ld, %mask
%cmp = icmp eq i32 %test, 0
store i32 %res, ptr %word
ret i1 %cmp
}
```
Before:
```asm
movl (%rdi), %eax
movl %eax, %ecx
btrl %esi, %ecx
btl %esi, %eax
setae %al
movl %ecx, (%rdi)
retq
```
After:
```asm
movl (%rdi), %ecx
btrl %esi, %ecx
setae %al
movl %ecx, (%rdi)
retq
```
## Approach
- Add three flag-producing DAG nodes `X86ISD::{BTR,BTS,BTC}` that model
the register-register BTR/BTS/BTC as `(res, EFLAGS) = op src, bitno`.
- Pattern-match them to the existing BTR/BTS/BTC *rr encodings.
- Add a DAG combine in `combineBT` that fuses an `X86ISD::BT` with a
sibling `AND(Src, rotl -2, X)` / `OR(Src, shl 1, X)` / `XOR(Src, shl 1,
X)` on the same source into a single flag-producing node. The
bit-position operand can differ from BT's by trunc/zext or by an `and x,
C` that preserves the low `log2(BW)` bits (BT already masks those
implicitly), so peek through those wrappers when matching.
`llvm/test/CodeGen/X86/bittest-big-integer.ll` was regenerated and
shrinks by 78 CHECK lines; dozens of `btl` instructions collapsed into
the preceding bit-modify. All 5442 X86 CodeGen tests pass.
To unsubscribe from these emails, change your notification settings at https://github.com/llvm/llvm-project/settings/notifications
More information about the All-commits
mailing list