[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