[llvm] [X86] Remove redundant `cmp` before `adc` after `lzcnt` or `tzcnt` (PR #208392)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Jul 17 13:05:57 PDT 2026
================
@@ -0,0 +1,76 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+bmi,+lzcnt | FileCheck %s
+
+define i64 @remove_redundant_cmp_ult_lzcnt_i64(i64 %0) {
+; CHECK-LABEL: remove_redundant_cmp_ult_lzcnt_i64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: lzcntq %rdi, %rax
+; CHECK-NEXT: adcq $0, %rax
+; CHECK-NEXT: retq
+ %2 = tail call i64 @llvm.ctlz.i64(i64 %0, i1 false)
+ %3 = icmp ult i64 %0, 1
+ %4 = zext i1 %3 to i64
+ %5 = add nuw nsw i64 %2, %4
+ ret i64 %5
+}
+
+define i64 @remove_redundant_cmp_ugt_lzcnt_i64(i64 %0) {
+; CHECK-LABEL: remove_redundant_cmp_ugt_lzcnt_i64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: lzcntq %rdi, %rax
+; CHECK-NEXT: cmpq $2, %rdi
+; CHECK-NEXT: sbbq $-1, %rax
+; CHECK-NEXT: retq
+ %2 = tail call i64 @llvm.ctlz.i64(i64 %0, i1 false)
+ %3 = icmp ugt i64 %0, 1
+ %4 = zext i1 %3 to i64
+ %5 = add nuw nsw i64 %2, %4
+ ret i64 %5
+}
+
+define i64 @remove_redundant_cmp_ne_lzcnt_i64(i64 %0) {
+; CHECK-LABEL: remove_redundant_cmp_ne_lzcnt_i64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: xorl %eax, %eax
+; CHECK-NEXT: lzcntq %rdi, %rcx
+; CHECK-NEXT: setne %al
+; CHECK-NEXT: addq %rcx, %rax
+; CHECK-NEXT: retq
----------------
VachanVY wrote:
`llvm/test/CodeGen/X86/bitcnt-load-with-cmov.ll`
```diff
define i32 @lzcnt32_no_fold_nonzero_cmp(ptr %p0, i32 %a1) {
; CHECK-LABEL: lzcnt32_no_fold_nonzero_cmp:
; CHECK: # %bb.0:
-; CHECK-NEXT: movl (%rdi), %ecx
-; CHECK-NEXT: lzcntl %ecx, %eax
-; CHECK-NEXT: cmpl $1, %ecx
+; CHECK-NEXT: lzcntl (%rdi), %eax
; CHECK-NEXT: cmovel %esi, %eax
; CHECK-NEXT: retq
...
```
here too. cmove uses ZF flags not CF Flags soo can't remove cmp.
https://github.com/llvm/llvm-project/pull/208392
More information about the llvm-commits
mailing list