[llvm] [X86] Remove redundant `cmp` before `adc` after `lzcnt` or `tzcnt` (PR #208392)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 13 23:50:57 PDT 2026
https://github.com/VachanVY updated https://github.com/llvm/llvm-project/pull/208392
>From e9766f66423c91c43b17b7bdfbad34904e8a8a08 Mon Sep 17 00:00:00 2001
From: Vachan V Y <vachanvy05 at gmail.com>
Date: Thu, 9 Jul 2026 13:25:06 +0530
Subject: [PATCH 1/9] [X86] pre commit tests
Remove redundant `cmp` before `adc` after `lzcnt` or `tzcnt`
---
.../X86/remove-redundant-cmp-lzcnt-tzcnt.ll | 160 ++++++++++++++++++
1 file changed, 160 insertions(+)
create mode 100644 llvm/test/CodeGen/X86/remove-redundant-cmp-lzcnt-tzcnt.ll
diff --git a/llvm/test/CodeGen/X86/remove-redundant-cmp-lzcnt-tzcnt.ll b/llvm/test/CodeGen/X86/remove-redundant-cmp-lzcnt-tzcnt.ll
new file mode 100644
index 0000000000000..e0302cbd6ccc8
--- /dev/null
+++ b/llvm/test/CodeGen/X86/remove-redundant-cmp-lzcnt-tzcnt.ll
@@ -0,0 +1,160 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=znver5 | FileCheck %s
+
+declare i64 @llvm.ctlz.i64(i64, i1)
+declare i32 @llvm.ctlz.i32(i32, i1)
+declare i16 @llvm.ctlz.i16(i16, i1)
+declare i64 @llvm.cttz.i64(i64, i1)
+declare i32 @llvm.cttz.i32(i32, i1)
+declare i16 @llvm.cttz.i16(i16, i1)
+
+define i64 @remove_redundant_cmp_lzcnt_i64(i64 %0) {
+; CHECK-LABEL: remove_redundant_cmp_lzcnt_i64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: lzcntq %rdi, %rax
+; CHECK-NEXT: cmpq $1, %rdi
+; CHECK-NEXT: adcq $0, %rax
+; CHECK-NEXT: retq
+ %2 = tail call i64 @llvm.ctlz.i64(i64 %0, i1 false)
+ %3 = icmp eq i64 %0, 0
+ %4 = zext i1 %3 to i64
+ %5 = add nuw nsw i64 %2, %4
+ ret i64 %5
+}
+
+define i32 @remove_redundant_cmp_lzcnt_i32(i32 %0) {
+; CHECK-LABEL: remove_redundant_cmp_lzcnt_i32:
+; CHECK: # %bb.0:
+; CHECK-NEXT: lzcntl %edi, %eax
+; CHECK-NEXT: cmpl $1, %edi
+; CHECK-NEXT: adcl $0, %eax
+; CHECK-NEXT: retq
+ %2 = tail call i32 @llvm.ctlz.i32(i32 %0, i1 false)
+ %3 = icmp eq i32 %0, 0
+ %4 = zext i1 %3 to i32
+ %5 = add nuw nsw i32 %2, %4
+ ret i32 %5
+}
+
+define i16 @remove_redundant_cmp_lzcnt_i16(i16 %0) {
+; CHECK-LABEL: remove_redundant_cmp_lzcnt_i16:
+; CHECK: # %bb.0:
+; CHECK-NEXT: lzcntw %di, %ax
+; CHECK-NEXT: cmpw $1, %di
+; CHECK-NEXT: adcw $0, %ax
+; CHECK-NEXT: retq
+ %2 = tail call i16 @llvm.ctlz.i16(i16 %0, i1 false)
+ %3 = icmp eq i16 %0, 0
+ %4 = zext i1 %3 to i16
+ %5 = add nuw nsw i16 %2, %4
+ ret i16 %5
+}
+
+define i64 @remove_redundant_cmp_lzcnt_no_constant(i64 %0, i64 %1) {
+; CHECK-LABEL: remove_redundant_cmp_lzcnt_no_constant:
+; CHECK: # %bb.0:
+; CHECK-NEXT: lzcntq %rdi, %rcx
+; CHECK-NEXT: xorl %eax, %eax
+; CHECK-NEXT: cmpq %rsi, %rdi
+; CHECK-NEXT: sete %al
+; CHECK-NEXT: addq %rcx, %rax
+; CHECK-NEXT: retq
+ %3 = tail call i64 @llvm.ctlz.i64(i64 %0, i1 false)
+ %4 = icmp eq i64 %0, %1
+ %5 = zext i1 %4 to i64
+ %6 = add nuw nsw i64 %3, %5
+ ret i64 %6
+}
+
+define i64 @remove_redundant_cmp_lzcnt_wrong_const(i64 %0) {
+; CHECK-LABEL: remove_redundant_cmp_lzcnt_wrong_const:
+; CHECK: # %bb.0:
+; CHECK-NEXT: lzcntq %rdi, %rcx
+; CHECK-NEXT: xorl %eax, %eax
+; CHECK-NEXT: cmpq $2, %rdi
+; CHECK-NEXT: sete %al
+; CHECK-NEXT: addq %rcx, %rax
+; CHECK-NEXT: retq
+ %2 = tail call i64 @llvm.ctlz.i64(i64 %0, i1 false)
+ %3 = icmp eq i64 %0, 2
+ %4 = zext i1 %3 to i64
+ %5 = add nuw nsw i64 %2, %4
+ ret i64 %5
+}
+
+define i64 @remove_redundant_cmp_tzcnt_i64(i64 %0) {
+; CHECK-LABEL: remove_redundant_cmp_tzcnt_i64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: tzcntq %rdi, %rax
+; CHECK-NEXT: cmpq $1, %rdi
+; CHECK-NEXT: adcq $0, %rax
+; CHECK-NEXT: retq
+ %2 = tail call i64 @llvm.cttz.i64(i64 %0, i1 false)
+ %3 = icmp eq i64 %0, 0
+ %4 = zext i1 %3 to i64
+ %5 = add nuw nsw i64 %2, %4
+ ret i64 %5
+}
+
+define i32 @remove_redundant_cmp_tzcnt_i32(i32 %0) {
+; CHECK-LABEL: remove_redundant_cmp_tzcnt_i32:
+; CHECK: # %bb.0:
+; CHECK-NEXT: tzcntl %edi, %eax
+; CHECK-NEXT: cmpl $1, %edi
+; CHECK-NEXT: adcl $0, %eax
+; CHECK-NEXT: retq
+ %2 = tail call i32 @llvm.cttz.i32(i32 %0, i1 false)
+ %3 = icmp eq i32 %0, 0
+ %4 = zext i1 %3 to i32
+ %5 = add nuw nsw i32 %2, %4
+ ret i32 %5
+}
+
+define i16 @remove_redundant_cmp_tzcnt_i16(i16 %0) {
+; CHECK-LABEL: remove_redundant_cmp_tzcnt_i16:
+; CHECK: # %bb.0:
+; CHECK-NEXT: movl %edi, %eax
+; CHECK-NEXT: orl $65536, %eax # imm = 0x10000
+; CHECK-NEXT: tzcntl %eax, %eax
+; CHECK-NEXT: cmpw $1, %di
+; CHECK-NEXT: adcw $0, %ax
+; CHECK-NEXT: # kill: def $ax killed $ax killed $eax
+; CHECK-NEXT: retq
+ %2 = tail call i16 @llvm.cttz.i16(i16 %0, i1 false)
+ %3 = icmp eq i16 %0, 0
+ %4 = zext i1 %3 to i16
+ %5 = add nuw nsw i16 %2, %4
+ ret i16 %5
+}
+
+define i64 @remove_redundant_cmp_tzcnt_no_constant(i64 %0, i64 %1) {
+; CHECK-LABEL: remove_redundant_cmp_tzcnt_no_constant:
+; CHECK: # %bb.0:
+; CHECK-NEXT: tzcntq %rdi, %rcx
+; CHECK-NEXT: xorl %eax, %eax
+; CHECK-NEXT: cmpq %rsi, %rdi
+; CHECK-NEXT: sete %al
+; CHECK-NEXT: addq %rcx, %rax
+; CHECK-NEXT: retq
+ %3 = tail call i64 @llvm.cttz.i64(i64 %0, i1 false)
+ %4 = icmp eq i64 %0, %1
+ %5 = zext i1 %4 to i64
+ %6 = add nuw nsw i64 %3, %5
+ ret i64 %6
+}
+
+define i64 @remove_redundant_cmp_tzcnt_wrong_const(i64 %0) {
+; CHECK-LABEL: remove_redundant_cmp_tzcnt_wrong_const:
+; CHECK: # %bb.0:
+; CHECK-NEXT: tzcntq %rdi, %rcx
+; CHECK-NEXT: xorl %eax, %eax
+; CHECK-NEXT: cmpq $2, %rdi
+; CHECK-NEXT: sete %al
+; CHECK-NEXT: addq %rcx, %rax
+; CHECK-NEXT: retq
+ %2 = tail call i64 @llvm.cttz.i64(i64 %0, i1 false)
+ %3 = icmp eq i64 %0, 2
+ %4 = zext i1 %3 to i64
+ %5 = add nuw nsw i64 %2, %4
+ ret i64 %5
+}
>From fb9464a99b4bd2c821eb4c8bbed9db875bff7d9c Mon Sep 17 00:00:00 2001
From: Vachan V Y <vachanvy05 at gmail.com>
Date: Thu, 9 Jul 2026 13:47:19 +0530
Subject: [PATCH 2/9] [X86] optimization code with DIFF
---
llvm/lib/Target/X86/X86InstrInfo.cpp | 12 ++++++++++++
.../CodeGen/X86/remove-redundant-cmp-lzcnt-tzcnt.ll | 5 -----
2 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/llvm/lib/Target/X86/X86InstrInfo.cpp b/llvm/lib/Target/X86/X86InstrInfo.cpp
index 7ff2400d06d1d..db4ac9fc0a3e3 100644
--- a/llvm/lib/Target/X86/X86InstrInfo.cpp
+++ b/llvm/lib/Target/X86/X86InstrInfo.cpp
@@ -4993,6 +4993,18 @@ bool X86InstrInfo::isRedundantFlagInstr(const MachineInstr &FlagI,
}
return FlagI.isIdenticalTo(OI);
}
+ case X86::LZCNT16rr:
+ case X86::LZCNT32rr:
+ case X86::LZCNT64rr:
+ case X86::TZCNT16rr:
+ case X86::TZCNT32rr:
+ case X86::TZCNT64rr: {
+ if (ImmMask != 0 && !SrcReg2.isValid() && ImmValue == 1 &&
+ OI.getOperand(1).isReg() && SrcReg == OI.getOperand(1).getReg()) {
+ return true;
+ }
+ return false;
+ }
default:
return false;
}
diff --git a/llvm/test/CodeGen/X86/remove-redundant-cmp-lzcnt-tzcnt.ll b/llvm/test/CodeGen/X86/remove-redundant-cmp-lzcnt-tzcnt.ll
index e0302cbd6ccc8..d836fc51817f8 100644
--- a/llvm/test/CodeGen/X86/remove-redundant-cmp-lzcnt-tzcnt.ll
+++ b/llvm/test/CodeGen/X86/remove-redundant-cmp-lzcnt-tzcnt.ll
@@ -12,7 +12,6 @@ define i64 @remove_redundant_cmp_lzcnt_i64(i64 %0) {
; CHECK-LABEL: remove_redundant_cmp_lzcnt_i64:
; CHECK: # %bb.0:
; CHECK-NEXT: lzcntq %rdi, %rax
-; CHECK-NEXT: cmpq $1, %rdi
; CHECK-NEXT: adcq $0, %rax
; CHECK-NEXT: retq
%2 = tail call i64 @llvm.ctlz.i64(i64 %0, i1 false)
@@ -26,7 +25,6 @@ define i32 @remove_redundant_cmp_lzcnt_i32(i32 %0) {
; CHECK-LABEL: remove_redundant_cmp_lzcnt_i32:
; CHECK: # %bb.0:
; CHECK-NEXT: lzcntl %edi, %eax
-; CHECK-NEXT: cmpl $1, %edi
; CHECK-NEXT: adcl $0, %eax
; CHECK-NEXT: retq
%2 = tail call i32 @llvm.ctlz.i32(i32 %0, i1 false)
@@ -40,7 +38,6 @@ define i16 @remove_redundant_cmp_lzcnt_i16(i16 %0) {
; CHECK-LABEL: remove_redundant_cmp_lzcnt_i16:
; CHECK: # %bb.0:
; CHECK-NEXT: lzcntw %di, %ax
-; CHECK-NEXT: cmpw $1, %di
; CHECK-NEXT: adcw $0, %ax
; CHECK-NEXT: retq
%2 = tail call i16 @llvm.ctlz.i16(i16 %0, i1 false)
@@ -86,7 +83,6 @@ define i64 @remove_redundant_cmp_tzcnt_i64(i64 %0) {
; CHECK-LABEL: remove_redundant_cmp_tzcnt_i64:
; CHECK: # %bb.0:
; CHECK-NEXT: tzcntq %rdi, %rax
-; CHECK-NEXT: cmpq $1, %rdi
; CHECK-NEXT: adcq $0, %rax
; CHECK-NEXT: retq
%2 = tail call i64 @llvm.cttz.i64(i64 %0, i1 false)
@@ -100,7 +96,6 @@ define i32 @remove_redundant_cmp_tzcnt_i32(i32 %0) {
; CHECK-LABEL: remove_redundant_cmp_tzcnt_i32:
; CHECK: # %bb.0:
; CHECK-NEXT: tzcntl %edi, %eax
-; CHECK-NEXT: cmpl $1, %edi
; CHECK-NEXT: adcl $0, %eax
; CHECK-NEXT: retq
%2 = tail call i32 @llvm.cttz.i32(i32 %0, i1 false)
>From 3f4151c4c0cfd8744adc86f6b51e54ffb1008244 Mon Sep 17 00:00:00 2001
From: Vachan V Y <vachanvy05 at gmail.com>
Date: Thu, 9 Jul 2026 16:11:41 +0530
Subject: [PATCH 3/9] [X86] address failing test in different file
---
llvm/test/CodeGen/X86/bitcnt-load-with-cmov.ll | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/llvm/test/CodeGen/X86/bitcnt-load-with-cmov.ll b/llvm/test/CodeGen/X86/bitcnt-load-with-cmov.ll
index d3d6b25b60c16..0a159143efa74 100644
--- a/llvm/test/CodeGen/X86/bitcnt-load-with-cmov.ll
+++ b/llvm/test/CodeGen/X86/bitcnt-load-with-cmov.ll
@@ -101,9 +101,7 @@ define i64 @popcnt64_load_cmov(ptr %p0, i64 %a1) {
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
%v = load i32, ptr %p0, align 4
>From 995fe2f834720e51e2571710df746267fd36d343 Mon Sep 17 00:00:00 2001
From: Vachan V Y <vachanvy05 at gmail.com>
Date: Thu, 9 Jul 2026 22:57:52 +0530
Subject: [PATCH 4/9] [X86] i686 test converage && `-mattr=+bmi,+lzcnt` instead
of `-mcpu=znver5`
---
.../X86/remove-redundant-cmp-lzcnt-tzcnt.ll | 327 ++++++++++++++----
1 file changed, 253 insertions(+), 74 deletions(-)
diff --git a/llvm/test/CodeGen/X86/remove-redundant-cmp-lzcnt-tzcnt.ll b/llvm/test/CodeGen/X86/remove-redundant-cmp-lzcnt-tzcnt.ll
index d836fc51817f8..6d7a5c18b6e9e 100644
--- a/llvm/test/CodeGen/X86/remove-redundant-cmp-lzcnt-tzcnt.ll
+++ b/llvm/test/CodeGen/X86/remove-redundant-cmp-lzcnt-tzcnt.ll
@@ -1,19 +1,38 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
-; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=znver5 | FileCheck %s
-
-declare i64 @llvm.ctlz.i64(i64, i1)
-declare i32 @llvm.ctlz.i32(i32, i1)
-declare i16 @llvm.ctlz.i16(i16, i1)
-declare i64 @llvm.cttz.i64(i64, i1)
-declare i32 @llvm.cttz.i32(i32, i1)
-declare i16 @llvm.cttz.i16(i16, i1)
+; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+bmi,+lzcnt | FileCheck %s --check-prefix=X64
+; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+bmi,+lzcnt | FileCheck %s --check-prefix=X86
define i64 @remove_redundant_cmp_lzcnt_i64(i64 %0) {
-; CHECK-LABEL: remove_redundant_cmp_lzcnt_i64:
-; CHECK: # %bb.0:
-; CHECK-NEXT: lzcntq %rdi, %rax
-; CHECK-NEXT: adcq $0, %rax
-; CHECK-NEXT: retq
+; X64-LABEL: remove_redundant_cmp_lzcnt_i64:
+; X64: # %bb.0:
+; X64-NEXT: lzcntq %rdi, %rax
+; X64-NEXT: adcq $0, %rax
+; X64-NEXT: retq
+;
+; X86-LABEL: remove_redundant_cmp_lzcnt_i64:
+; X86: # %bb.0:
+; X86-NEXT: pushl %esi
+; X86-NEXT: .cfi_def_cfa_offset 8
+; X86-NEXT: .cfi_offset %esi, -8
+; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT: movl {{[0-9]+}}(%esp), %edx
+; X86-NEXT: testl %edx, %edx
+; X86-NEXT: jne .LBB0_1
+; X86-NEXT: # %bb.2:
+; X86-NEXT: lzcntl %ecx, %esi
+; X86-NEXT: addl $32, %esi
+; X86-NEXT: jmp .LBB0_3
+; X86-NEXT: .LBB0_1:
+; X86-NEXT: lzcntl %edx, %esi
+; X86-NEXT: .LBB0_3:
+; X86-NEXT: xorl %eax, %eax
+; X86-NEXT: orl %edx, %ecx
+; X86-NEXT: sete %al
+; X86-NEXT: addl %esi, %eax
+; X86-NEXT: xorl %edx, %edx
+; X86-NEXT: popl %esi
+; X86-NEXT: .cfi_def_cfa_offset 4
+; X86-NEXT: retl
%2 = tail call i64 @llvm.ctlz.i64(i64 %0, i1 false)
%3 = icmp eq i64 %0, 0
%4 = zext i1 %3 to i64
@@ -22,11 +41,17 @@ define i64 @remove_redundant_cmp_lzcnt_i64(i64 %0) {
}
define i32 @remove_redundant_cmp_lzcnt_i32(i32 %0) {
-; CHECK-LABEL: remove_redundant_cmp_lzcnt_i32:
-; CHECK: # %bb.0:
-; CHECK-NEXT: lzcntl %edi, %eax
-; CHECK-NEXT: adcl $0, %eax
-; CHECK-NEXT: retq
+; X64-LABEL: remove_redundant_cmp_lzcnt_i32:
+; X64: # %bb.0:
+; X64-NEXT: lzcntl %edi, %eax
+; X64-NEXT: adcl $0, %eax
+; X64-NEXT: retq
+;
+; X86-LABEL: remove_redundant_cmp_lzcnt_i32:
+; X86: # %bb.0:
+; X86-NEXT: lzcntl {{[0-9]+}}(%esp), %eax
+; X86-NEXT: adcl $0, %eax
+; X86-NEXT: retl
%2 = tail call i32 @llvm.ctlz.i32(i32 %0, i1 false)
%3 = icmp eq i32 %0, 0
%4 = zext i1 %3 to i32
@@ -35,11 +60,17 @@ define i32 @remove_redundant_cmp_lzcnt_i32(i32 %0) {
}
define i16 @remove_redundant_cmp_lzcnt_i16(i16 %0) {
-; CHECK-LABEL: remove_redundant_cmp_lzcnt_i16:
-; CHECK: # %bb.0:
-; CHECK-NEXT: lzcntw %di, %ax
-; CHECK-NEXT: adcw $0, %ax
-; CHECK-NEXT: retq
+; X64-LABEL: remove_redundant_cmp_lzcnt_i16:
+; X64: # %bb.0:
+; X64-NEXT: lzcntw %di, %ax
+; X64-NEXT: adcw $0, %ax
+; X64-NEXT: retq
+;
+; X86-LABEL: remove_redundant_cmp_lzcnt_i16:
+; X86: # %bb.0:
+; X86-NEXT: lzcntw {{[0-9]+}}(%esp), %ax
+; X86-NEXT: adcw $0, %ax
+; X86-NEXT: retl
%2 = tail call i16 @llvm.ctlz.i16(i16 %0, i1 false)
%3 = icmp eq i16 %0, 0
%4 = zext i1 %3 to i16
@@ -48,14 +79,41 @@ define i16 @remove_redundant_cmp_lzcnt_i16(i16 %0) {
}
define i64 @remove_redundant_cmp_lzcnt_no_constant(i64 %0, i64 %1) {
-; CHECK-LABEL: remove_redundant_cmp_lzcnt_no_constant:
-; CHECK: # %bb.0:
-; CHECK-NEXT: lzcntq %rdi, %rcx
-; CHECK-NEXT: xorl %eax, %eax
-; CHECK-NEXT: cmpq %rsi, %rdi
-; CHECK-NEXT: sete %al
-; CHECK-NEXT: addq %rcx, %rax
-; CHECK-NEXT: retq
+; X64-LABEL: remove_redundant_cmp_lzcnt_no_constant:
+; X64: # %bb.0:
+; X64-NEXT: lzcntq %rdi, %rcx
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: cmpq %rsi, %rdi
+; X64-NEXT: sete %al
+; X64-NEXT: addq %rcx, %rax
+; X64-NEXT: retq
+;
+; X86-LABEL: remove_redundant_cmp_lzcnt_no_constant:
+; X86: # %bb.0:
+; X86-NEXT: pushl %esi
+; X86-NEXT: .cfi_def_cfa_offset 8
+; X86-NEXT: .cfi_offset %esi, -8
+; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT: movl {{[0-9]+}}(%esp), %edx
+; X86-NEXT: testl %edx, %edx
+; X86-NEXT: jne .LBB3_1
+; X86-NEXT: # %bb.2:
+; X86-NEXT: lzcntl %ecx, %esi
+; X86-NEXT: addl $32, %esi
+; X86-NEXT: jmp .LBB3_3
+; X86-NEXT: .LBB3_1:
+; X86-NEXT: lzcntl %edx, %esi
+; X86-NEXT: .LBB3_3:
+; X86-NEXT: xorl {{[0-9]+}}(%esp), %edx
+; X86-NEXT: xorl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT: xorl %eax, %eax
+; X86-NEXT: orl %edx, %ecx
+; X86-NEXT: sete %al
+; X86-NEXT: addl %esi, %eax
+; X86-NEXT: xorl %edx, %edx
+; X86-NEXT: popl %esi
+; X86-NEXT: .cfi_def_cfa_offset 4
+; X86-NEXT: retl
%3 = tail call i64 @llvm.ctlz.i64(i64 %0, i1 false)
%4 = icmp eq i64 %0, %1
%5 = zext i1 %4 to i64
@@ -64,14 +122,40 @@ define i64 @remove_redundant_cmp_lzcnt_no_constant(i64 %0, i64 %1) {
}
define i64 @remove_redundant_cmp_lzcnt_wrong_const(i64 %0) {
-; CHECK-LABEL: remove_redundant_cmp_lzcnt_wrong_const:
-; CHECK: # %bb.0:
-; CHECK-NEXT: lzcntq %rdi, %rcx
-; CHECK-NEXT: xorl %eax, %eax
-; CHECK-NEXT: cmpq $2, %rdi
-; CHECK-NEXT: sete %al
-; CHECK-NEXT: addq %rcx, %rax
-; CHECK-NEXT: retq
+; X64-LABEL: remove_redundant_cmp_lzcnt_wrong_const:
+; X64: # %bb.0:
+; X64-NEXT: lzcntq %rdi, %rcx
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: cmpq $2, %rdi
+; X64-NEXT: sete %al
+; X64-NEXT: addq %rcx, %rax
+; X64-NEXT: retq
+;
+; X86-LABEL: remove_redundant_cmp_lzcnt_wrong_const:
+; X86: # %bb.0:
+; X86-NEXT: pushl %esi
+; X86-NEXT: .cfi_def_cfa_offset 8
+; X86-NEXT: .cfi_offset %esi, -8
+; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT: movl {{[0-9]+}}(%esp), %edx
+; X86-NEXT: testl %edx, %edx
+; X86-NEXT: jne .LBB4_1
+; X86-NEXT: # %bb.2:
+; X86-NEXT: lzcntl %ecx, %esi
+; X86-NEXT: addl $32, %esi
+; X86-NEXT: jmp .LBB4_3
+; X86-NEXT: .LBB4_1:
+; X86-NEXT: lzcntl %edx, %esi
+; X86-NEXT: .LBB4_3:
+; X86-NEXT: xorl $2, %ecx
+; X86-NEXT: xorl %eax, %eax
+; X86-NEXT: orl %edx, %ecx
+; X86-NEXT: sete %al
+; X86-NEXT: addl %esi, %eax
+; X86-NEXT: xorl %edx, %edx
+; X86-NEXT: popl %esi
+; X86-NEXT: .cfi_def_cfa_offset 4
+; X86-NEXT: retl
%2 = tail call i64 @llvm.ctlz.i64(i64 %0, i1 false)
%3 = icmp eq i64 %0, 2
%4 = zext i1 %3 to i64
@@ -80,11 +164,36 @@ define i64 @remove_redundant_cmp_lzcnt_wrong_const(i64 %0) {
}
define i64 @remove_redundant_cmp_tzcnt_i64(i64 %0) {
-; CHECK-LABEL: remove_redundant_cmp_tzcnt_i64:
-; CHECK: # %bb.0:
-; CHECK-NEXT: tzcntq %rdi, %rax
-; CHECK-NEXT: adcq $0, %rax
-; CHECK-NEXT: retq
+; X64-LABEL: remove_redundant_cmp_tzcnt_i64:
+; X64: # %bb.0:
+; X64-NEXT: tzcntq %rdi, %rax
+; X64-NEXT: adcq $0, %rax
+; X64-NEXT: retq
+;
+; X86-LABEL: remove_redundant_cmp_tzcnt_i64:
+; X86: # %bb.0:
+; X86-NEXT: pushl %esi
+; X86-NEXT: .cfi_def_cfa_offset 8
+; X86-NEXT: .cfi_offset %esi, -8
+; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT: movl {{[0-9]+}}(%esp), %edx
+; X86-NEXT: testl %ecx, %ecx
+; X86-NEXT: jne .LBB5_1
+; X86-NEXT: # %bb.2:
+; X86-NEXT: tzcntl %edx, %esi
+; X86-NEXT: addl $32, %esi
+; X86-NEXT: jmp .LBB5_3
+; X86-NEXT: .LBB5_1:
+; X86-NEXT: tzcntl %ecx, %esi
+; X86-NEXT: .LBB5_3:
+; X86-NEXT: xorl %eax, %eax
+; X86-NEXT: orl %edx, %ecx
+; X86-NEXT: sete %al
+; X86-NEXT: addl %esi, %eax
+; X86-NEXT: xorl %edx, %edx
+; X86-NEXT: popl %esi
+; X86-NEXT: .cfi_def_cfa_offset 4
+; X86-NEXT: retl
%2 = tail call i64 @llvm.cttz.i64(i64 %0, i1 false)
%3 = icmp eq i64 %0, 0
%4 = zext i1 %3 to i64
@@ -93,11 +202,17 @@ define i64 @remove_redundant_cmp_tzcnt_i64(i64 %0) {
}
define i32 @remove_redundant_cmp_tzcnt_i32(i32 %0) {
-; CHECK-LABEL: remove_redundant_cmp_tzcnt_i32:
-; CHECK: # %bb.0:
-; CHECK-NEXT: tzcntl %edi, %eax
-; CHECK-NEXT: adcl $0, %eax
-; CHECK-NEXT: retq
+; X64-LABEL: remove_redundant_cmp_tzcnt_i32:
+; X64: # %bb.0:
+; X64-NEXT: tzcntl %edi, %eax
+; X64-NEXT: adcl $0, %eax
+; X64-NEXT: retq
+;
+; X86-LABEL: remove_redundant_cmp_tzcnt_i32:
+; X86: # %bb.0:
+; X86-NEXT: tzcntl {{[0-9]+}}(%esp), %eax
+; X86-NEXT: adcl $0, %eax
+; X86-NEXT: retl
%2 = tail call i32 @llvm.cttz.i32(i32 %0, i1 false)
%3 = icmp eq i32 %0, 0
%4 = zext i1 %3 to i32
@@ -106,15 +221,26 @@ define i32 @remove_redundant_cmp_tzcnt_i32(i32 %0) {
}
define i16 @remove_redundant_cmp_tzcnt_i16(i16 %0) {
-; CHECK-LABEL: remove_redundant_cmp_tzcnt_i16:
-; CHECK: # %bb.0:
-; CHECK-NEXT: movl %edi, %eax
-; CHECK-NEXT: orl $65536, %eax # imm = 0x10000
-; CHECK-NEXT: tzcntl %eax, %eax
-; CHECK-NEXT: cmpw $1, %di
-; CHECK-NEXT: adcw $0, %ax
-; CHECK-NEXT: # kill: def $ax killed $ax killed $eax
-; CHECK-NEXT: retq
+; X64-LABEL: remove_redundant_cmp_tzcnt_i16:
+; X64: # %bb.0:
+; X64-NEXT: movl %edi, %eax
+; X64-NEXT: orl $65536, %eax # imm = 0x10000
+; X64-NEXT: tzcntl %eax, %eax
+; X64-NEXT: cmpw $1, %di
+; X64-NEXT: adcw $0, %ax
+; X64-NEXT: # kill: def $ax killed $ax killed $eax
+; X64-NEXT: retq
+;
+; X86-LABEL: remove_redundant_cmp_tzcnt_i16:
+; X86: # %bb.0:
+; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT: movl %ecx, %eax
+; X86-NEXT: orl $65536, %eax # imm = 0x10000
+; X86-NEXT: tzcntl %eax, %eax
+; X86-NEXT: cmpw $1, %cx
+; X86-NEXT: adcw $0, %ax
+; X86-NEXT: # kill: def $ax killed $ax killed $eax
+; X86-NEXT: retl
%2 = tail call i16 @llvm.cttz.i16(i16 %0, i1 false)
%3 = icmp eq i16 %0, 0
%4 = zext i1 %3 to i16
@@ -123,14 +249,41 @@ define i16 @remove_redundant_cmp_tzcnt_i16(i16 %0) {
}
define i64 @remove_redundant_cmp_tzcnt_no_constant(i64 %0, i64 %1) {
-; CHECK-LABEL: remove_redundant_cmp_tzcnt_no_constant:
-; CHECK: # %bb.0:
-; CHECK-NEXT: tzcntq %rdi, %rcx
-; CHECK-NEXT: xorl %eax, %eax
-; CHECK-NEXT: cmpq %rsi, %rdi
-; CHECK-NEXT: sete %al
-; CHECK-NEXT: addq %rcx, %rax
-; CHECK-NEXT: retq
+; X64-LABEL: remove_redundant_cmp_tzcnt_no_constant:
+; X64: # %bb.0:
+; X64-NEXT: tzcntq %rdi, %rcx
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: cmpq %rsi, %rdi
+; X64-NEXT: sete %al
+; X64-NEXT: addq %rcx, %rax
+; X64-NEXT: retq
+;
+; X86-LABEL: remove_redundant_cmp_tzcnt_no_constant:
+; X86: # %bb.0:
+; X86-NEXT: pushl %esi
+; X86-NEXT: .cfi_def_cfa_offset 8
+; X86-NEXT: .cfi_offset %esi, -8
+; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT: movl {{[0-9]+}}(%esp), %edx
+; X86-NEXT: testl %ecx, %ecx
+; X86-NEXT: jne .LBB8_1
+; X86-NEXT: # %bb.2:
+; X86-NEXT: tzcntl %edx, %esi
+; X86-NEXT: addl $32, %esi
+; X86-NEXT: jmp .LBB8_3
+; X86-NEXT: .LBB8_1:
+; X86-NEXT: tzcntl %ecx, %esi
+; X86-NEXT: .LBB8_3:
+; X86-NEXT: xorl {{[0-9]+}}(%esp), %edx
+; X86-NEXT: xorl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT: xorl %eax, %eax
+; X86-NEXT: orl %edx, %ecx
+; X86-NEXT: sete %al
+; X86-NEXT: addl %esi, %eax
+; X86-NEXT: xorl %edx, %edx
+; X86-NEXT: popl %esi
+; X86-NEXT: .cfi_def_cfa_offset 4
+; X86-NEXT: retl
%3 = tail call i64 @llvm.cttz.i64(i64 %0, i1 false)
%4 = icmp eq i64 %0, %1
%5 = zext i1 %4 to i64
@@ -139,14 +292,40 @@ define i64 @remove_redundant_cmp_tzcnt_no_constant(i64 %0, i64 %1) {
}
define i64 @remove_redundant_cmp_tzcnt_wrong_const(i64 %0) {
-; CHECK-LABEL: remove_redundant_cmp_tzcnt_wrong_const:
-; CHECK: # %bb.0:
-; CHECK-NEXT: tzcntq %rdi, %rcx
-; CHECK-NEXT: xorl %eax, %eax
-; CHECK-NEXT: cmpq $2, %rdi
-; CHECK-NEXT: sete %al
-; CHECK-NEXT: addq %rcx, %rax
-; CHECK-NEXT: retq
+; X64-LABEL: remove_redundant_cmp_tzcnt_wrong_const:
+; X64: # %bb.0:
+; X64-NEXT: tzcntq %rdi, %rcx
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: cmpq $2, %rdi
+; X64-NEXT: sete %al
+; X64-NEXT: addq %rcx, %rax
+; X64-NEXT: retq
+;
+; X86-LABEL: remove_redundant_cmp_tzcnt_wrong_const:
+; X86: # %bb.0:
+; X86-NEXT: pushl %esi
+; X86-NEXT: .cfi_def_cfa_offset 8
+; X86-NEXT: .cfi_offset %esi, -8
+; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT: movl {{[0-9]+}}(%esp), %edx
+; X86-NEXT: testl %ecx, %ecx
+; X86-NEXT: jne .LBB9_1
+; X86-NEXT: # %bb.2:
+; X86-NEXT: tzcntl %edx, %esi
+; X86-NEXT: addl $32, %esi
+; X86-NEXT: jmp .LBB9_3
+; X86-NEXT: .LBB9_1:
+; X86-NEXT: tzcntl %ecx, %esi
+; X86-NEXT: .LBB9_3:
+; X86-NEXT: xorl $2, %ecx
+; X86-NEXT: xorl %eax, %eax
+; X86-NEXT: orl %edx, %ecx
+; X86-NEXT: sete %al
+; X86-NEXT: addl %esi, %eax
+; X86-NEXT: xorl %edx, %edx
+; X86-NEXT: popl %esi
+; X86-NEXT: .cfi_def_cfa_offset 4
+; X86-NEXT: retl
%2 = tail call i64 @llvm.cttz.i64(i64 %0, i1 false)
%3 = icmp eq i64 %0, 2
%4 = zext i1 %3 to i64
>From cc753f0e48daf0d0b32d73ab18ae0f7750def97d Mon Sep 17 00:00:00 2001
From: Vachan V Y <vachanvy05 at gmail.com>
Date: Fri, 10 Jul 2026 11:51:36 +0530
Subject: [PATCH 5/9] [X86] refactor tests -- phobewang
---
.../remove-redundant-cmp-lzcnt-tzcnt-i64.ll | 28 +++
.../X86/remove-redundant-cmp-lzcnt-tzcnt.ll | 238 ++++--------------
2 files changed, 76 insertions(+), 190 deletions(-)
create mode 100644 llvm/test/CodeGen/X86/remove-redundant-cmp-lzcnt-tzcnt-i64.ll
diff --git a/llvm/test/CodeGen/X86/remove-redundant-cmp-lzcnt-tzcnt-i64.ll b/llvm/test/CodeGen/X86/remove-redundant-cmp-lzcnt-tzcnt-i64.ll
new file mode 100644
index 0000000000000..6d36196997e17
--- /dev/null
+++ b/llvm/test/CodeGen/X86/remove-redundant-cmp-lzcnt-tzcnt-i64.ll
@@ -0,0 +1,28 @@
+; 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 --check-prefix=X64
+
+define i64 @remove_redundant_cmp_lzcnt_i64(i64 %0) {
+; X64-LABEL: remove_redundant_cmp_lzcnt_i64:
+; X64: # %bb.0:
+; X64-NEXT: lzcntq %rdi, %rax
+; X64-NEXT: adcq $0, %rax
+; X64-NEXT: retq
+ %2 = tail call i64 @llvm.ctlz.i64(i64 %0, i1 false)
+ %3 = icmp eq i64 %0, 0
+ %4 = zext i1 %3 to i64
+ %5 = add nuw nsw i64 %2, %4
+ ret i64 %5
+}
+
+define i64 @remove_redundant_cmp_tzcnt_i64(i64 %0) {
+; X64-LABEL: remove_redundant_cmp_tzcnt_i64:
+; X64: # %bb.0:
+; X64-NEXT: tzcntq %rdi, %rax
+; X64-NEXT: adcq $0, %rax
+; X64-NEXT: retq
+ %2 = tail call i64 @llvm.cttz.i64(i64 %0, i1 false)
+ %3 = icmp eq i64 %0, 0
+ %4 = zext i1 %3 to i64
+ %5 = add nuw nsw i64 %2, %4
+ ret i64 %5
+}
diff --git a/llvm/test/CodeGen/X86/remove-redundant-cmp-lzcnt-tzcnt.ll b/llvm/test/CodeGen/X86/remove-redundant-cmp-lzcnt-tzcnt.ll
index 6d7a5c18b6e9e..57ac1d5e2f4c8 100644
--- a/llvm/test/CodeGen/X86/remove-redundant-cmp-lzcnt-tzcnt.ll
+++ b/llvm/test/CodeGen/X86/remove-redundant-cmp-lzcnt-tzcnt.ll
@@ -2,44 +2,6 @@
; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+bmi,+lzcnt | FileCheck %s --check-prefix=X64
; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+bmi,+lzcnt | FileCheck %s --check-prefix=X86
-define i64 @remove_redundant_cmp_lzcnt_i64(i64 %0) {
-; X64-LABEL: remove_redundant_cmp_lzcnt_i64:
-; X64: # %bb.0:
-; X64-NEXT: lzcntq %rdi, %rax
-; X64-NEXT: adcq $0, %rax
-; X64-NEXT: retq
-;
-; X86-LABEL: remove_redundant_cmp_lzcnt_i64:
-; X86: # %bb.0:
-; X86-NEXT: pushl %esi
-; X86-NEXT: .cfi_def_cfa_offset 8
-; X86-NEXT: .cfi_offset %esi, -8
-; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT: movl {{[0-9]+}}(%esp), %edx
-; X86-NEXT: testl %edx, %edx
-; X86-NEXT: jne .LBB0_1
-; X86-NEXT: # %bb.2:
-; X86-NEXT: lzcntl %ecx, %esi
-; X86-NEXT: addl $32, %esi
-; X86-NEXT: jmp .LBB0_3
-; X86-NEXT: .LBB0_1:
-; X86-NEXT: lzcntl %edx, %esi
-; X86-NEXT: .LBB0_3:
-; X86-NEXT: xorl %eax, %eax
-; X86-NEXT: orl %edx, %ecx
-; X86-NEXT: sete %al
-; X86-NEXT: addl %esi, %eax
-; X86-NEXT: xorl %edx, %edx
-; X86-NEXT: popl %esi
-; X86-NEXT: .cfi_def_cfa_offset 4
-; X86-NEXT: retl
- %2 = tail call i64 @llvm.ctlz.i64(i64 %0, i1 false)
- %3 = icmp eq i64 %0, 0
- %4 = zext i1 %3 to i64
- %5 = add nuw nsw i64 %2, %4
- ret i64 %5
-}
-
define i32 @remove_redundant_cmp_lzcnt_i32(i32 %0) {
; X64-LABEL: remove_redundant_cmp_lzcnt_i32:
; X64: # %bb.0:
@@ -78,127 +40,56 @@ define i16 @remove_redundant_cmp_lzcnt_i16(i16 %0) {
ret i16 %5
}
-define i64 @remove_redundant_cmp_lzcnt_no_constant(i64 %0, i64 %1) {
+define i32 @remove_redundant_cmp_lzcnt_no_constant(i32 %0, i32 %1) {
; X64-LABEL: remove_redundant_cmp_lzcnt_no_constant:
; X64: # %bb.0:
-; X64-NEXT: lzcntq %rdi, %rcx
+; X64-NEXT: lzcntl %edi, %ecx
; X64-NEXT: xorl %eax, %eax
-; X64-NEXT: cmpq %rsi, %rdi
+; X64-NEXT: cmpl %esi, %edi
; X64-NEXT: sete %al
-; X64-NEXT: addq %rcx, %rax
+; X64-NEXT: addl %ecx, %eax
; X64-NEXT: retq
;
; X86-LABEL: remove_redundant_cmp_lzcnt_no_constant:
; X86: # %bb.0:
-; X86-NEXT: pushl %esi
-; X86-NEXT: .cfi_def_cfa_offset 8
-; X86-NEXT: .cfi_offset %esi, -8
; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT: movl {{[0-9]+}}(%esp), %edx
-; X86-NEXT: testl %edx, %edx
-; X86-NEXT: jne .LBB3_1
-; X86-NEXT: # %bb.2:
-; X86-NEXT: lzcntl %ecx, %esi
-; X86-NEXT: addl $32, %esi
-; X86-NEXT: jmp .LBB3_3
-; X86-NEXT: .LBB3_1:
-; X86-NEXT: lzcntl %edx, %esi
-; X86-NEXT: .LBB3_3:
-; X86-NEXT: xorl {{[0-9]+}}(%esp), %edx
-; X86-NEXT: xorl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT: lzcntl %ecx, %edx
; X86-NEXT: xorl %eax, %eax
-; X86-NEXT: orl %edx, %ecx
+; X86-NEXT: cmpl {{[0-9]+}}(%esp), %ecx
; X86-NEXT: sete %al
-; X86-NEXT: addl %esi, %eax
-; X86-NEXT: xorl %edx, %edx
-; X86-NEXT: popl %esi
-; X86-NEXT: .cfi_def_cfa_offset 4
+; X86-NEXT: addl %edx, %eax
; X86-NEXT: retl
- %3 = tail call i64 @llvm.ctlz.i64(i64 %0, i1 false)
- %4 = icmp eq i64 %0, %1
- %5 = zext i1 %4 to i64
- %6 = add nuw nsw i64 %3, %5
- ret i64 %6
+ %3 = tail call i32 @llvm.ctlz.i32(i32 %0, i1 false)
+ %4 = icmp eq i32 %0, %1
+ %5 = zext i1 %4 to i32
+ %6 = add nuw nsw i32 %3, %5
+ ret i32 %6
}
-define i64 @remove_redundant_cmp_lzcnt_wrong_const(i64 %0) {
+define i32 @remove_redundant_cmp_lzcnt_wrong_const(i32 %0) {
; X64-LABEL: remove_redundant_cmp_lzcnt_wrong_const:
; X64: # %bb.0:
-; X64-NEXT: lzcntq %rdi, %rcx
+; X64-NEXT: lzcntl %edi, %ecx
; X64-NEXT: xorl %eax, %eax
-; X64-NEXT: cmpq $2, %rdi
+; X64-NEXT: cmpl $2, %edi
; X64-NEXT: sete %al
-; X64-NEXT: addq %rcx, %rax
+; X64-NEXT: addl %ecx, %eax
; X64-NEXT: retq
;
; X86-LABEL: remove_redundant_cmp_lzcnt_wrong_const:
; X86: # %bb.0:
-; X86-NEXT: pushl %esi
-; X86-NEXT: .cfi_def_cfa_offset 8
-; X86-NEXT: .cfi_offset %esi, -8
-; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT: movl {{[0-9]+}}(%esp), %edx
-; X86-NEXT: testl %edx, %edx
-; X86-NEXT: jne .LBB4_1
-; X86-NEXT: # %bb.2:
-; X86-NEXT: lzcntl %ecx, %esi
-; X86-NEXT: addl $32, %esi
-; X86-NEXT: jmp .LBB4_3
-; X86-NEXT: .LBB4_1:
-; X86-NEXT: lzcntl %edx, %esi
-; X86-NEXT: .LBB4_3:
-; X86-NEXT: xorl $2, %ecx
-; X86-NEXT: xorl %eax, %eax
-; X86-NEXT: orl %edx, %ecx
-; X86-NEXT: sete %al
-; X86-NEXT: addl %esi, %eax
-; X86-NEXT: xorl %edx, %edx
-; X86-NEXT: popl %esi
-; X86-NEXT: .cfi_def_cfa_offset 4
-; X86-NEXT: retl
- %2 = tail call i64 @llvm.ctlz.i64(i64 %0, i1 false)
- %3 = icmp eq i64 %0, 2
- %4 = zext i1 %3 to i64
- %5 = add nuw nsw i64 %2, %4
- ret i64 %5
-}
-
-define i64 @remove_redundant_cmp_tzcnt_i64(i64 %0) {
-; X64-LABEL: remove_redundant_cmp_tzcnt_i64:
-; X64: # %bb.0:
-; X64-NEXT: tzcntq %rdi, %rax
-; X64-NEXT: adcq $0, %rax
-; X64-NEXT: retq
-;
-; X86-LABEL: remove_redundant_cmp_tzcnt_i64:
-; X86: # %bb.0:
-; X86-NEXT: pushl %esi
-; X86-NEXT: .cfi_def_cfa_offset 8
-; X86-NEXT: .cfi_offset %esi, -8
; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT: movl {{[0-9]+}}(%esp), %edx
-; X86-NEXT: testl %ecx, %ecx
-; X86-NEXT: jne .LBB5_1
-; X86-NEXT: # %bb.2:
-; X86-NEXT: tzcntl %edx, %esi
-; X86-NEXT: addl $32, %esi
-; X86-NEXT: jmp .LBB5_3
-; X86-NEXT: .LBB5_1:
-; X86-NEXT: tzcntl %ecx, %esi
-; X86-NEXT: .LBB5_3:
+; X86-NEXT: lzcntl %ecx, %edx
; X86-NEXT: xorl %eax, %eax
-; X86-NEXT: orl %edx, %ecx
+; X86-NEXT: cmpl $2, %ecx
; X86-NEXT: sete %al
-; X86-NEXT: addl %esi, %eax
-; X86-NEXT: xorl %edx, %edx
-; X86-NEXT: popl %esi
-; X86-NEXT: .cfi_def_cfa_offset 4
+; X86-NEXT: addl %edx, %eax
; X86-NEXT: retl
- %2 = tail call i64 @llvm.cttz.i64(i64 %0, i1 false)
- %3 = icmp eq i64 %0, 0
- %4 = zext i1 %3 to i64
- %5 = add nuw nsw i64 %2, %4
- ret i64 %5
+ %2 = tail call i32 @llvm.ctlz.i32(i32 %0, i1 false)
+ %3 = icmp eq i32 %0, 2
+ %4 = zext i1 %3 to i32
+ %5 = add nuw nsw i32 %2, %4
+ ret i32 %5
}
define i32 @remove_redundant_cmp_tzcnt_i32(i32 %0) {
@@ -248,87 +139,54 @@ define i16 @remove_redundant_cmp_tzcnt_i16(i16 %0) {
ret i16 %5
}
-define i64 @remove_redundant_cmp_tzcnt_no_constant(i64 %0, i64 %1) {
+define i32 @remove_redundant_cmp_tzcnt_no_constant(i32 %0, i32 %1) {
; X64-LABEL: remove_redundant_cmp_tzcnt_no_constant:
; X64: # %bb.0:
-; X64-NEXT: tzcntq %rdi, %rcx
+; X64-NEXT: tzcntl %edi, %ecx
; X64-NEXT: xorl %eax, %eax
-; X64-NEXT: cmpq %rsi, %rdi
+; X64-NEXT: cmpl %esi, %edi
; X64-NEXT: sete %al
-; X64-NEXT: addq %rcx, %rax
+; X64-NEXT: addl %ecx, %eax
; X64-NEXT: retq
;
; X86-LABEL: remove_redundant_cmp_tzcnt_no_constant:
; X86: # %bb.0:
-; X86-NEXT: pushl %esi
-; X86-NEXT: .cfi_def_cfa_offset 8
-; X86-NEXT: .cfi_offset %esi, -8
; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT: movl {{[0-9]+}}(%esp), %edx
-; X86-NEXT: testl %ecx, %ecx
-; X86-NEXT: jne .LBB8_1
-; X86-NEXT: # %bb.2:
-; X86-NEXT: tzcntl %edx, %esi
-; X86-NEXT: addl $32, %esi
-; X86-NEXT: jmp .LBB8_3
-; X86-NEXT: .LBB8_1:
-; X86-NEXT: tzcntl %ecx, %esi
-; X86-NEXT: .LBB8_3:
-; X86-NEXT: xorl {{[0-9]+}}(%esp), %edx
-; X86-NEXT: xorl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT: tzcntl %ecx, %edx
; X86-NEXT: xorl %eax, %eax
-; X86-NEXT: orl %edx, %ecx
+; X86-NEXT: cmpl {{[0-9]+}}(%esp), %ecx
; X86-NEXT: sete %al
-; X86-NEXT: addl %esi, %eax
-; X86-NEXT: xorl %edx, %edx
-; X86-NEXT: popl %esi
-; X86-NEXT: .cfi_def_cfa_offset 4
+; X86-NEXT: addl %edx, %eax
; X86-NEXT: retl
- %3 = tail call i64 @llvm.cttz.i64(i64 %0, i1 false)
- %4 = icmp eq i64 %0, %1
- %5 = zext i1 %4 to i64
- %6 = add nuw nsw i64 %3, %5
- ret i64 %6
+ %3 = tail call i32 @llvm.cttz.i32(i32 %0, i1 false)
+ %4 = icmp eq i32 %0, %1
+ %5 = zext i1 %4 to i32
+ %6 = add nuw nsw i32 %3, %5
+ ret i32 %6
}
-define i64 @remove_redundant_cmp_tzcnt_wrong_const(i64 %0) {
+define i32 @remove_redundant_cmp_tzcnt_wrong_const(i32 %0) {
; X64-LABEL: remove_redundant_cmp_tzcnt_wrong_const:
; X64: # %bb.0:
-; X64-NEXT: tzcntq %rdi, %rcx
+; X64-NEXT: tzcntl %edi, %ecx
; X64-NEXT: xorl %eax, %eax
-; X64-NEXT: cmpq $2, %rdi
+; X64-NEXT: cmpl $2, %edi
; X64-NEXT: sete %al
-; X64-NEXT: addq %rcx, %rax
+; X64-NEXT: addl %ecx, %eax
; X64-NEXT: retq
;
; X86-LABEL: remove_redundant_cmp_tzcnt_wrong_const:
; X86: # %bb.0:
-; X86-NEXT: pushl %esi
-; X86-NEXT: .cfi_def_cfa_offset 8
-; X86-NEXT: .cfi_offset %esi, -8
; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT: movl {{[0-9]+}}(%esp), %edx
-; X86-NEXT: testl %ecx, %ecx
-; X86-NEXT: jne .LBB9_1
-; X86-NEXT: # %bb.2:
-; X86-NEXT: tzcntl %edx, %esi
-; X86-NEXT: addl $32, %esi
-; X86-NEXT: jmp .LBB9_3
-; X86-NEXT: .LBB9_1:
-; X86-NEXT: tzcntl %ecx, %esi
-; X86-NEXT: .LBB9_3:
-; X86-NEXT: xorl $2, %ecx
+; X86-NEXT: tzcntl %ecx, %edx
; X86-NEXT: xorl %eax, %eax
-; X86-NEXT: orl %edx, %ecx
+; X86-NEXT: cmpl $2, %ecx
; X86-NEXT: sete %al
-; X86-NEXT: addl %esi, %eax
-; X86-NEXT: xorl %edx, %edx
-; X86-NEXT: popl %esi
-; X86-NEXT: .cfi_def_cfa_offset 4
+; X86-NEXT: addl %edx, %eax
; X86-NEXT: retl
- %2 = tail call i64 @llvm.cttz.i64(i64 %0, i1 false)
- %3 = icmp eq i64 %0, 2
- %4 = zext i1 %3 to i64
- %5 = add nuw nsw i64 %2, %4
- ret i64 %5
+ %2 = tail call i32 @llvm.cttz.i32(i32 %0, i1 false)
+ %3 = icmp eq i32 %0, 2
+ %4 = zext i1 %3 to i32
+ %5 = add nuw nsw i32 %2, %4
+ ret i32 %5
}
>From cddabda627f37f0bb98b881e40bd0fff5bacdddf Mon Sep 17 00:00:00 2001
From: Vachan V Y <vachanvy05 at gmail.com>
Date: Fri, 10 Jul 2026 12:08:25 +0530
Subject: [PATCH 6/9] [X86] remove check prefix
---
llvm/test/CodeGen/X86/remove-redundant-cmp-lzcnt-tzcnt-i64.ll | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/test/CodeGen/X86/remove-redundant-cmp-lzcnt-tzcnt-i64.ll b/llvm/test/CodeGen/X86/remove-redundant-cmp-lzcnt-tzcnt-i64.ll
index 6d36196997e17..51b1faec788d7 100644
--- a/llvm/test/CodeGen/X86/remove-redundant-cmp-lzcnt-tzcnt-i64.ll
+++ b/llvm/test/CodeGen/X86/remove-redundant-cmp-lzcnt-tzcnt-i64.ll
@@ -1,5 +1,5 @@
; 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 --check-prefix=X64
+; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+bmi,+lzcnt | FileCheck %s
define i64 @remove_redundant_cmp_lzcnt_i64(i64 %0) {
; X64-LABEL: remove_redundant_cmp_lzcnt_i64:
>From 86895bbd105c6d89f133d1c118da356763d6902e Mon Sep 17 00:00:00 2001
From: Vachan V Y <vachanvy05 at gmail.com>
Date: Fri, 10 Jul 2026 12:12:25 +0530
Subject: [PATCH 7/9] [X86] update the stale checks
---
.../remove-redundant-cmp-lzcnt-tzcnt-i64.ll | 20 +++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/llvm/test/CodeGen/X86/remove-redundant-cmp-lzcnt-tzcnt-i64.ll b/llvm/test/CodeGen/X86/remove-redundant-cmp-lzcnt-tzcnt-i64.ll
index 51b1faec788d7..e0cd38db4a277 100644
--- a/llvm/test/CodeGen/X86/remove-redundant-cmp-lzcnt-tzcnt-i64.ll
+++ b/llvm/test/CodeGen/X86/remove-redundant-cmp-lzcnt-tzcnt-i64.ll
@@ -2,11 +2,11 @@
; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+bmi,+lzcnt | FileCheck %s
define i64 @remove_redundant_cmp_lzcnt_i64(i64 %0) {
-; X64-LABEL: remove_redundant_cmp_lzcnt_i64:
-; X64: # %bb.0:
-; X64-NEXT: lzcntq %rdi, %rax
-; X64-NEXT: adcq $0, %rax
-; X64-NEXT: retq
+; CHECK-LABEL: remove_redundant_cmp_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 eq i64 %0, 0
%4 = zext i1 %3 to i64
@@ -15,11 +15,11 @@ define i64 @remove_redundant_cmp_lzcnt_i64(i64 %0) {
}
define i64 @remove_redundant_cmp_tzcnt_i64(i64 %0) {
-; X64-LABEL: remove_redundant_cmp_tzcnt_i64:
-; X64: # %bb.0:
-; X64-NEXT: tzcntq %rdi, %rax
-; X64-NEXT: adcq $0, %rax
-; X64-NEXT: retq
+; CHECK-LABEL: remove_redundant_cmp_tzcnt_i64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: tzcntq %rdi, %rax
+; CHECK-NEXT: adcq $0, %rax
+; CHECK-NEXT: retq
%2 = tail call i64 @llvm.cttz.i64(i64 %0, i1 false)
%3 = icmp eq i64 %0, 0
%4 = zext i1 %3 to i64
>From d1890c55713dd8d44840b2866e1c2b53317bbdc4 Mon Sep 17 00:00:00 2001
From: Vachan V Y <vachanvy05 at gmail.com>
Date: Sun, 12 Jul 2026 01:56:09 +0530
Subject: [PATCH 8/9] [X86] test coverage with other cmpcodes
---
.../remove-redundant-cmp-lzcnt-tzcnt-i64.ll | 277 ++++++++++-
.../X86/remove-redundant-cmp-lzcnt-tzcnt.ll | 430 +++++++++++++++++-
2 files changed, 697 insertions(+), 10 deletions(-)
diff --git a/llvm/test/CodeGen/X86/remove-redundant-cmp-lzcnt-tzcnt-i64.ll b/llvm/test/CodeGen/X86/remove-redundant-cmp-lzcnt-tzcnt-i64.ll
index e0cd38db4a277..9a2473d7734af 100644
--- a/llvm/test/CodeGen/X86/remove-redundant-cmp-lzcnt-tzcnt-i64.ll
+++ b/llvm/test/CodeGen/X86/remove-redundant-cmp-lzcnt-tzcnt-i64.ll
@@ -1,8 +1,8 @@
; 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_lzcnt_i64(i64 %0) {
-; CHECK-LABEL: remove_redundant_cmp_lzcnt_i64:
+define i64 @remove_redundant_cmp_eq_lzcnt(i64 %0) {
+; CHECK-LABEL: remove_redundant_cmp_eq_lzcnt:
; CHECK: # %bb.0:
; CHECK-NEXT: lzcntq %rdi, %rax
; CHECK-NEXT: adcq $0, %rax
@@ -14,8 +14,143 @@ define i64 @remove_redundant_cmp_lzcnt_i64(i64 %0) {
ret i64 %5
}
-define i64 @remove_redundant_cmp_tzcnt_i64(i64 %0) {
-; CHECK-LABEL: remove_redundant_cmp_tzcnt_i64:
+define i64 @remove_redundant_cmp_ult_lzcnt(i64 %0) {
+; CHECK-LABEL: remove_redundant_cmp_ult_lzcnt:
+; 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_uge_lzcnt(i64 %0) {
+; CHECK-LABEL: remove_redundant_cmp_uge_lzcnt:
+; CHECK: # %bb.0:
+; CHECK-NEXT: lzcntq %rdi, %rax
+; CHECK-NEXT: sbbq $-1, %rax
+; CHECK-NEXT: retq
+ %2 = tail call i64 @llvm.ctlz.i64(i64 %0, i1 false)
+ %3 = icmp uge 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 %0) {
+; CHECK-LABEL: remove_redundant_cmp_ugt_lzcnt:
+; 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_ule_lzcnt(i64 %0) {
+; CHECK-LABEL: remove_redundant_cmp_ule_lzcnt:
+; CHECK: # %bb.0:
+; CHECK-NEXT: lzcntq %rdi, %rax
+; CHECK-NEXT: cmpq $2, %rdi
+; CHECK-NEXT: adcq $0, %rax
+; CHECK-NEXT: retq
+ %2 = tail call i64 @llvm.ctlz.i64(i64 %0, i1 false)
+ %3 = icmp ule 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 %0) {
+; CHECK-LABEL: remove_redundant_cmp_ne_lzcnt:
+; 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
+ %2 = tail call i64 @llvm.ctlz.i64(i64 %0, i1 false)
+ %3 = icmp ne i64 %0, 1
+ %4 = zext i1 %3 to i64
+ %5 = add nuw nsw i64 %2, %4
+ ret i64 %5
+}
+
+define i64 @remove_redundant_cmp_slt_lzcnt(i64 %0) {
+; CHECK-LABEL: remove_redundant_cmp_slt_lzcnt:
+; CHECK: # %bb.0:
+; CHECK-NEXT: lzcntq %rdi, %rcx
+; CHECK-NEXT: xorl %eax, %eax
+; CHECK-NEXT: testq %rdi, %rdi
+; CHECK-NEXT: setle %al
+; CHECK-NEXT: addq %rcx, %rax
+; CHECK-NEXT: retq
+ %2 = tail call i64 @llvm.ctlz.i64(i64 %0, i1 false)
+ %3 = icmp slt i64 %0, 1
+ %4 = zext i1 %3 to i64
+ %5 = add nuw nsw i64 %2, %4
+ ret i64 %5
+}
+
+define i64 @remove_redundant_cmp_sge_lzcnt(i64 %0) {
+; CHECK-LABEL: remove_redundant_cmp_sge_lzcnt:
+; CHECK: # %bb.0:
+; CHECK-NEXT: lzcntq %rdi, %rcx
+; CHECK-NEXT: xorl %eax, %eax
+; CHECK-NEXT: testq %rdi, %rdi
+; CHECK-NEXT: setg %al
+; CHECK-NEXT: addq %rcx, %rax
+; CHECK-NEXT: retq
+ %2 = tail call i64 @llvm.ctlz.i64(i64 %0, i1 false)
+ %3 = icmp sge i64 %0, 1
+ %4 = zext i1 %3 to i64
+ %5 = add nuw nsw i64 %2, %4
+ ret i64 %5
+}
+
+define i64 @remove_redundant_cmp_sgt_lzcnt(i64 %0) {
+; CHECK-LABEL: remove_redundant_cmp_sgt_lzcnt:
+; CHECK: # %bb.0:
+; CHECK-NEXT: lzcntq %rdi, %rcx
+; CHECK-NEXT: xorl %eax, %eax
+; CHECK-NEXT: cmpq $2, %rdi
+; CHECK-NEXT: setge %al
+; CHECK-NEXT: addq %rcx, %rax
+; CHECK-NEXT: retq
+ %2 = tail call i64 @llvm.ctlz.i64(i64 %0, i1 false)
+ %3 = icmp sgt i64 %0, 1
+ %4 = zext i1 %3 to i64
+ %5 = add nuw nsw i64 %2, %4
+ ret i64 %5
+}
+
+define i64 @remove_redundant_cmp_sle_lzcnt(i64 %0) {
+; CHECK-LABEL: remove_redundant_cmp_sle_lzcnt:
+; CHECK: # %bb.0:
+; CHECK-NEXT: lzcntq %rdi, %rcx
+; CHECK-NEXT: xorl %eax, %eax
+; CHECK-NEXT: cmpq $2, %rdi
+; CHECK-NEXT: setl %al
+; CHECK-NEXT: addq %rcx, %rax
+; CHECK-NEXT: retq
+ %2 = tail call i64 @llvm.ctlz.i64(i64 %0, i1 false)
+ %3 = icmp sle i64 %0, 1
+ %4 = zext i1 %3 to i64
+ %5 = add nuw nsw i64 %2, %4
+ ret i64 %5
+}
+
+define i64 @remove_redundant_cmp_eq_tzcnt(i64 %0) {
+; CHECK-LABEL: remove_redundant_cmp_eq_tzcnt:
; CHECK: # %bb.0:
; CHECK-NEXT: tzcntq %rdi, %rax
; CHECK-NEXT: adcq $0, %rax
@@ -26,3 +161,137 @@ define i64 @remove_redundant_cmp_tzcnt_i64(i64 %0) {
%5 = add nuw nsw i64 %2, %4
ret i64 %5
}
+
+
+define i64 @remove_redundant_cmp_ult_tzcnt(i64 %0) {
+; CHECK-LABEL: remove_redundant_cmp_ult_tzcnt:
+; CHECK: # %bb.0:
+; CHECK-NEXT: tzcntq %rdi, %rax
+; CHECK-NEXT: adcq $0, %rax
+; CHECK-NEXT: retq
+ %2 = tail call i64 @llvm.cttz.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_uge_tzcnt(i64 %0) {
+; CHECK-LABEL: remove_redundant_cmp_uge_tzcnt:
+; CHECK: # %bb.0:
+; CHECK-NEXT: tzcntq %rdi, %rax
+; CHECK-NEXT: sbbq $-1, %rax
+; CHECK-NEXT: retq
+ %2 = tail call i64 @llvm.cttz.i64(i64 %0, i1 false)
+ %3 = icmp uge 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_tzcnt(i64 %0) {
+; CHECK-LABEL: remove_redundant_cmp_ugt_tzcnt:
+; CHECK: # %bb.0:
+; CHECK-NEXT: tzcntq %rdi, %rax
+; CHECK-NEXT: cmpq $2, %rdi
+; CHECK-NEXT: sbbq $-1, %rax
+; CHECK-NEXT: retq
+ %2 = tail call i64 @llvm.cttz.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_ule_tzcnt(i64 %0) {
+; CHECK-LABEL: remove_redundant_cmp_ule_tzcnt:
+; CHECK: # %bb.0:
+; CHECK-NEXT: tzcntq %rdi, %rax
+; CHECK-NEXT: cmpq $2, %rdi
+; CHECK-NEXT: adcq $0, %rax
+; CHECK-NEXT: retq
+ %2 = tail call i64 @llvm.cttz.i64(i64 %0, i1 false)
+ %3 = icmp ule 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_tzcnt(i64 %0) {
+; CHECK-LABEL: remove_redundant_cmp_ne_tzcnt:
+; CHECK: # %bb.0:
+; CHECK-NEXT: xorl %eax, %eax
+; CHECK-NEXT: tzcntq %rdi, %rcx
+; CHECK-NEXT: setne %al
+; CHECK-NEXT: addq %rcx, %rax
+; CHECK-NEXT: retq
+ %2 = tail call i64 @llvm.cttz.i64(i64 %0, i1 false)
+ %3 = icmp ne i64 %0, 1
+ %4 = zext i1 %3 to i64
+ %5 = add nuw nsw i64 %2, %4
+ ret i64 %5
+}
+
+define i64 @remove_redundant_cmp_slt_tzcnt(i64 %0) {
+; CHECK-LABEL: remove_redundant_cmp_slt_tzcnt:
+; CHECK: # %bb.0:
+; CHECK-NEXT: tzcntq %rdi, %rcx
+; CHECK-NEXT: xorl %eax, %eax
+; CHECK-NEXT: testq %rdi, %rdi
+; CHECK-NEXT: setle %al
+; CHECK-NEXT: addq %rcx, %rax
+; CHECK-NEXT: retq
+ %2 = tail call i64 @llvm.cttz.i64(i64 %0, i1 false)
+ %3 = icmp slt i64 %0, 1
+ %4 = zext i1 %3 to i64
+ %5 = add nuw nsw i64 %2, %4
+ ret i64 %5
+}
+
+define i64 @remove_redundant_cmp_sge_tzcnt(i64 %0) {
+; CHECK-LABEL: remove_redundant_cmp_sge_tzcnt:
+; CHECK: # %bb.0:
+; CHECK-NEXT: tzcntq %rdi, %rcx
+; CHECK-NEXT: xorl %eax, %eax
+; CHECK-NEXT: testq %rdi, %rdi
+; CHECK-NEXT: setg %al
+; CHECK-NEXT: addq %rcx, %rax
+; CHECK-NEXT: retq
+ %2 = tail call i64 @llvm.cttz.i64(i64 %0, i1 false)
+ %3 = icmp sge i64 %0, 1
+ %4 = zext i1 %3 to i64
+ %5 = add nuw nsw i64 %2, %4
+ ret i64 %5
+}
+
+define i64 @remove_redundant_cmp_sgt_tzcnt(i64 %0) {
+; CHECK-LABEL: remove_redundant_cmp_sgt_tzcnt:
+; CHECK: # %bb.0:
+; CHECK-NEXT: tzcntq %rdi, %rcx
+; CHECK-NEXT: xorl %eax, %eax
+; CHECK-NEXT: cmpq $2, %rdi
+; CHECK-NEXT: setge %al
+; CHECK-NEXT: addq %rcx, %rax
+; CHECK-NEXT: retq
+ %2 = tail call i64 @llvm.cttz.i64(i64 %0, i1 false)
+ %3 = icmp sgt i64 %0, 1
+ %4 = zext i1 %3 to i64
+ %5 = add nuw nsw i64 %2, %4
+ ret i64 %5
+}
+
+define i64 @remove_redundant_cmp_sle_tzcnt(i64 %0) {
+; CHECK-LABEL: remove_redundant_cmp_sle_tzcnt:
+; CHECK: # %bb.0:
+; CHECK-NEXT: tzcntq %rdi, %rcx
+; CHECK-NEXT: xorl %eax, %eax
+; CHECK-NEXT: cmpq $2, %rdi
+; CHECK-NEXT: setl %al
+; CHECK-NEXT: addq %rcx, %rax
+; CHECK-NEXT: retq
+ %2 = tail call i64 @llvm.cttz.i64(i64 %0, i1 false)
+ %3 = icmp sle i64 %0, 1
+ %4 = zext i1 %3 to i64
+ %5 = add nuw nsw i64 %2, %4
+ ret i64 %5
+}
diff --git a/llvm/test/CodeGen/X86/remove-redundant-cmp-lzcnt-tzcnt.ll b/llvm/test/CodeGen/X86/remove-redundant-cmp-lzcnt-tzcnt.ll
index 57ac1d5e2f4c8..e0bf88cda1f90 100644
--- a/llvm/test/CodeGen/X86/remove-redundant-cmp-lzcnt-tzcnt.ll
+++ b/llvm/test/CodeGen/X86/remove-redundant-cmp-lzcnt-tzcnt.ll
@@ -2,14 +2,14 @@
; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+bmi,+lzcnt | FileCheck %s --check-prefix=X64
; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+bmi,+lzcnt | FileCheck %s --check-prefix=X86
-define i32 @remove_redundant_cmp_lzcnt_i32(i32 %0) {
-; X64-LABEL: remove_redundant_cmp_lzcnt_i32:
+define i32 @remove_redundant_cmp_eq_lzcnt_i32(i32 %0) {
+; X64-LABEL: remove_redundant_cmp_eq_lzcnt_i32:
; X64: # %bb.0:
; X64-NEXT: lzcntl %edi, %eax
; X64-NEXT: adcl $0, %eax
; X64-NEXT: retq
;
-; X86-LABEL: remove_redundant_cmp_lzcnt_i32:
+; X86-LABEL: remove_redundant_cmp_eq_lzcnt_i32:
; X86: # %bb.0:
; X86-NEXT: lzcntl {{[0-9]+}}(%esp), %eax
; X86-NEXT: adcl $0, %eax
@@ -40,6 +40,215 @@ define i16 @remove_redundant_cmp_lzcnt_i16(i16 %0) {
ret i16 %5
}
+define i32 @remove_redundant_cmp_ult_lzcnt(i32 %0) {
+; X64-LABEL: remove_redundant_cmp_ult_lzcnt:
+; X64: # %bb.0:
+; X64-NEXT: lzcntl %edi, %eax
+; X64-NEXT: adcl $0, %eax
+; X64-NEXT: retq
+;
+; X86-LABEL: remove_redundant_cmp_ult_lzcnt:
+; X86: # %bb.0:
+; X86-NEXT: lzcntl {{[0-9]+}}(%esp), %eax
+; X86-NEXT: adcl $0, %eax
+; X86-NEXT: retl
+ %2 = tail call i32 @llvm.ctlz.i32(i32 %0, i1 false)
+ %3 = icmp ult i32 %0, 1
+ %4 = zext i1 %3 to i32
+ %5 = add nuw nsw i32 %2, %4
+ ret i32 %5
+}
+
+define i32 @remove_redundant_cmp_uge_lzcnt(i32 %0) {
+; X64-LABEL: remove_redundant_cmp_uge_lzcnt:
+; X64: # %bb.0:
+; X64-NEXT: lzcntl %edi, %eax
+; X64-NEXT: sbbl $-1, %eax
+; X64-NEXT: retq
+;
+; X86-LABEL: remove_redundant_cmp_uge_lzcnt:
+; X86: # %bb.0:
+; X86-NEXT: lzcntl {{[0-9]+}}(%esp), %eax
+; X86-NEXT: sbbl $-1, %eax
+; X86-NEXT: retl
+ %2 = tail call i32 @llvm.ctlz.i32(i32 %0, i1 false)
+ %3 = icmp uge i32 %0, 1
+ %4 = zext i1 %3 to i32
+ %5 = add nuw nsw i32 %2, %4
+ ret i32 %5
+}
+
+define i32 @remove_redundant_cmp_ugt_lzcnt(i32 %0) {
+; X64-LABEL: remove_redundant_cmp_ugt_lzcnt:
+; X64: # %bb.0:
+; X64-NEXT: lzcntl %edi, %eax
+; X64-NEXT: cmpl $2, %edi
+; X64-NEXT: sbbl $-1, %eax
+; X64-NEXT: retq
+;
+; X86-LABEL: remove_redundant_cmp_ugt_lzcnt:
+; X86: # %bb.0:
+; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT: lzcntl %ecx, %eax
+; X86-NEXT: cmpl $2, %ecx
+; X86-NEXT: sbbl $-1, %eax
+; X86-NEXT: retl
+ %2 = tail call i32 @llvm.ctlz.i32(i32 %0, i1 false)
+ %3 = icmp ugt i32 %0, 1
+ %4 = zext i1 %3 to i32
+ %5 = add nuw nsw i32 %2, %4
+ ret i32 %5
+}
+
+define i32 @remove_redundant_cmp_ule_lzcnt(i32 %0) {
+; X64-LABEL: remove_redundant_cmp_ule_lzcnt:
+; X64: # %bb.0:
+; X64-NEXT: lzcntl %edi, %eax
+; X64-NEXT: cmpl $2, %edi
+; X64-NEXT: adcl $0, %eax
+; X64-NEXT: retq
+;
+; X86-LABEL: remove_redundant_cmp_ule_lzcnt:
+; X86: # %bb.0:
+; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT: lzcntl %ecx, %eax
+; X86-NEXT: cmpl $2, %ecx
+; X86-NEXT: adcl $0, %eax
+; X86-NEXT: retl
+ %2 = tail call i32 @llvm.ctlz.i32(i32 %0, i1 false)
+ %3 = icmp ule i32 %0, 1
+ %4 = zext i1 %3 to i32
+ %5 = add nuw nsw i32 %2, %4
+ ret i32 %5
+}
+
+define i32 @remove_redundant_cmp_ne_lzcnt(i32 %0) {
+; X64-LABEL: remove_redundant_cmp_ne_lzcnt:
+; X64: # %bb.0:
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: lzcntl %edi, %ecx
+; X64-NEXT: setne %al
+; X64-NEXT: addl %ecx, %eax
+; X64-NEXT: retq
+;
+; X86-LABEL: remove_redundant_cmp_ne_lzcnt:
+; X86: # %bb.0:
+; X86-NEXT: xorl %eax, %eax
+; X86-NEXT: lzcntl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT: setne %al
+; X86-NEXT: addl %ecx, %eax
+; X86-NEXT: retl
+ %2 = tail call i32 @llvm.ctlz.i32(i32 %0, i1 false)
+ %3 = icmp ne i32 %0, 1
+ %4 = zext i1 %3 to i32
+ %5 = add nuw nsw i32 %2, %4
+ ret i32 %5
+}
+
+define i32 @remove_redundant_cmp_slt_lzcnt(i32 %0) {
+; X64-LABEL: remove_redundant_cmp_slt_lzcnt:
+; X64: # %bb.0:
+; X64-NEXT: lzcntl %edi, %ecx
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: testl %edi, %edi
+; X64-NEXT: setle %al
+; X64-NEXT: addl %ecx, %eax
+; X64-NEXT: retq
+;
+; X86-LABEL: remove_redundant_cmp_slt_lzcnt:
+; X86: # %bb.0:
+; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT: lzcntl %ecx, %edx
+; X86-NEXT: xorl %eax, %eax
+; X86-NEXT: testl %ecx, %ecx
+; X86-NEXT: setle %al
+; X86-NEXT: addl %edx, %eax
+; X86-NEXT: retl
+ %2 = tail call i32 @llvm.ctlz.i32(i32 %0, i1 false)
+ %3 = icmp slt i32 %0, 1
+ %4 = zext i1 %3 to i32
+ %5 = add nuw nsw i32 %2, %4
+ ret i32 %5
+}
+
+define i32 @remove_redundant_cmp_sge_lzcnt(i32 %0) {
+; X64-LABEL: remove_redundant_cmp_sge_lzcnt:
+; X64: # %bb.0:
+; X64-NEXT: lzcntl %edi, %ecx
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: testl %edi, %edi
+; X64-NEXT: setg %al
+; X64-NEXT: addl %ecx, %eax
+; X64-NEXT: retq
+;
+; X86-LABEL: remove_redundant_cmp_sge_lzcnt:
+; X86: # %bb.0:
+; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT: lzcntl %ecx, %edx
+; X86-NEXT: xorl %eax, %eax
+; X86-NEXT: testl %ecx, %ecx
+; X86-NEXT: setg %al
+; X86-NEXT: addl %edx, %eax
+; X86-NEXT: retl
+ %2 = tail call i32 @llvm.ctlz.i32(i32 %0, i1 false)
+ %3 = icmp sge i32 %0, 1
+ %4 = zext i1 %3 to i32
+ %5 = add nuw nsw i32 %2, %4
+ ret i32 %5
+}
+
+define i32 @remove_redundant_cmp_sgt_lzcnt(i32 %0) {
+; X64-LABEL: remove_redundant_cmp_sgt_lzcnt:
+; X64: # %bb.0:
+; X64-NEXT: lzcntl %edi, %ecx
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: cmpl $2, %edi
+; X64-NEXT: setge %al
+; X64-NEXT: addl %ecx, %eax
+; X64-NEXT: retq
+;
+; X86-LABEL: remove_redundant_cmp_sgt_lzcnt:
+; X86: # %bb.0:
+; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT: lzcntl %ecx, %edx
+; X86-NEXT: xorl %eax, %eax
+; X86-NEXT: cmpl $2, %ecx
+; X86-NEXT: setge %al
+; X86-NEXT: addl %edx, %eax
+; X86-NEXT: retl
+ %2 = tail call i32 @llvm.ctlz.i32(i32 %0, i1 false)
+ %3 = icmp sgt i32 %0, 1
+ %4 = zext i1 %3 to i32
+ %5 = add nuw nsw i32 %2, %4
+ ret i32 %5
+}
+
+define i32 @remove_redundant_cmp_sle_lzcnt(i32 %0) {
+; X64-LABEL: remove_redundant_cmp_sle_lzcnt:
+; X64: # %bb.0:
+; X64-NEXT: lzcntl %edi, %ecx
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: cmpl $2, %edi
+; X64-NEXT: setl %al
+; X64-NEXT: addl %ecx, %eax
+; X64-NEXT: retq
+;
+; X86-LABEL: remove_redundant_cmp_sle_lzcnt:
+; X86: # %bb.0:
+; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT: lzcntl %ecx, %edx
+; X86-NEXT: xorl %eax, %eax
+; X86-NEXT: cmpl $2, %ecx
+; X86-NEXT: setl %al
+; X86-NEXT: addl %edx, %eax
+; X86-NEXT: retl
+ %2 = tail call i32 @llvm.ctlz.i32(i32 %0, i1 false)
+ %3 = icmp sle i32 %0, 1
+ %4 = zext i1 %3 to i32
+ %5 = add nuw nsw i32 %2, %4
+ ret i32 %5
+}
+
define i32 @remove_redundant_cmp_lzcnt_no_constant(i32 %0, i32 %1) {
; X64-LABEL: remove_redundant_cmp_lzcnt_no_constant:
; X64: # %bb.0:
@@ -92,14 +301,14 @@ define i32 @remove_redundant_cmp_lzcnt_wrong_const(i32 %0) {
ret i32 %5
}
-define i32 @remove_redundant_cmp_tzcnt_i32(i32 %0) {
-; X64-LABEL: remove_redundant_cmp_tzcnt_i32:
+define i32 @remove_redundant_cmp_eq_tzcnt_i32(i32 %0) {
+; X64-LABEL: remove_redundant_cmp_eq_tzcnt_i32:
; X64: # %bb.0:
; X64-NEXT: tzcntl %edi, %eax
; X64-NEXT: adcl $0, %eax
; X64-NEXT: retq
;
-; X86-LABEL: remove_redundant_cmp_tzcnt_i32:
+; X86-LABEL: remove_redundant_cmp_eq_tzcnt_i32:
; X86: # %bb.0:
; X86-NEXT: tzcntl {{[0-9]+}}(%esp), %eax
; X86-NEXT: adcl $0, %eax
@@ -190,3 +399,212 @@ define i32 @remove_redundant_cmp_tzcnt_wrong_const(i32 %0) {
%5 = add nuw nsw i32 %2, %4
ret i32 %5
}
+
+define i32 @remove_redundant_cmp_ult_tzcnt(i32 %0) {
+; X64-LABEL: remove_redundant_cmp_ult_tzcnt:
+; X64: # %bb.0:
+; X64-NEXT: tzcntl %edi, %eax
+; X64-NEXT: adcl $0, %eax
+; X64-NEXT: retq
+;
+; X86-LABEL: remove_redundant_cmp_ult_tzcnt:
+; X86: # %bb.0:
+; X86-NEXT: tzcntl {{[0-9]+}}(%esp), %eax
+; X86-NEXT: adcl $0, %eax
+; X86-NEXT: retl
+ %2 = tail call i32 @llvm.cttz.i32(i32 %0, i1 false)
+ %3 = icmp ult i32 %0, 1
+ %4 = zext i1 %3 to i32
+ %5 = add nuw nsw i32 %2, %4
+ ret i32 %5
+}
+
+define i32 @remove_redundant_cmp_uge_tzcnt(i32 %0) {
+; X64-LABEL: remove_redundant_cmp_uge_tzcnt:
+; X64: # %bb.0:
+; X64-NEXT: tzcntl %edi, %eax
+; X64-NEXT: sbbl $-1, %eax
+; X64-NEXT: retq
+;
+; X86-LABEL: remove_redundant_cmp_uge_tzcnt:
+; X86: # %bb.0:
+; X86-NEXT: tzcntl {{[0-9]+}}(%esp), %eax
+; X86-NEXT: sbbl $-1, %eax
+; X86-NEXT: retl
+ %2 = tail call i32 @llvm.cttz.i32(i32 %0, i1 false)
+ %3 = icmp uge i32 %0, 1
+ %4 = zext i1 %3 to i32
+ %5 = add nuw nsw i32 %2, %4
+ ret i32 %5
+}
+
+define i32 @remove_redundant_cmp_ugt_tzcnt(i32 %0) {
+; X64-LABEL: remove_redundant_cmp_ugt_tzcnt:
+; X64: # %bb.0:
+; X64-NEXT: tzcntl %edi, %eax
+; X64-NEXT: cmpl $2, %edi
+; X64-NEXT: sbbl $-1, %eax
+; X64-NEXT: retq
+;
+; X86-LABEL: remove_redundant_cmp_ugt_tzcnt:
+; X86: # %bb.0:
+; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT: tzcntl %ecx, %eax
+; X86-NEXT: cmpl $2, %ecx
+; X86-NEXT: sbbl $-1, %eax
+; X86-NEXT: retl
+ %2 = tail call i32 @llvm.cttz.i32(i32 %0, i1 false)
+ %3 = icmp ugt i32 %0, 1
+ %4 = zext i1 %3 to i32
+ %5 = add nuw nsw i32 %2, %4
+ ret i32 %5
+}
+
+define i32 @remove_redundant_cmp_ule_tzcnt(i32 %0) {
+; X64-LABEL: remove_redundant_cmp_ule_tzcnt:
+; X64: # %bb.0:
+; X64-NEXT: tzcntl %edi, %eax
+; X64-NEXT: cmpl $2, %edi
+; X64-NEXT: adcl $0, %eax
+; X64-NEXT: retq
+;
+; X86-LABEL: remove_redundant_cmp_ule_tzcnt:
+; X86: # %bb.0:
+; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT: tzcntl %ecx, %eax
+; X86-NEXT: cmpl $2, %ecx
+; X86-NEXT: adcl $0, %eax
+; X86-NEXT: retl
+ %2 = tail call i32 @llvm.cttz.i32(i32 %0, i1 false)
+ %3 = icmp ule i32 %0, 1
+ %4 = zext i1 %3 to i32
+ %5 = add nuw nsw i32 %2, %4
+ ret i32 %5
+}
+
+define i32 @remove_redundant_cmp_ne_tzcnt(i32 %0) {
+; X64-LABEL: remove_redundant_cmp_ne_tzcnt:
+; X64: # %bb.0:
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: tzcntl %edi, %ecx
+; X64-NEXT: setne %al
+; X64-NEXT: addl %ecx, %eax
+; X64-NEXT: retq
+;
+; X86-LABEL: remove_redundant_cmp_ne_tzcnt:
+; X86: # %bb.0:
+; X86-NEXT: xorl %eax, %eax
+; X86-NEXT: tzcntl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT: setne %al
+; X86-NEXT: addl %ecx, %eax
+; X86-NEXT: retl
+ %2 = tail call i32 @llvm.cttz.i32(i32 %0, i1 false)
+ %3 = icmp ne i32 %0, 1
+ %4 = zext i1 %3 to i32
+ %5 = add nuw nsw i32 %2, %4
+ ret i32 %5
+}
+
+define i32 @remove_redundant_cmp_slt_tzcnt(i32 %0) {
+; X64-LABEL: remove_redundant_cmp_slt_tzcnt:
+; X64: # %bb.0:
+; X64-NEXT: tzcntl %edi, %ecx
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: testl %edi, %edi
+; X64-NEXT: setle %al
+; X64-NEXT: addl %ecx, %eax
+; X64-NEXT: retq
+;
+; X86-LABEL: remove_redundant_cmp_slt_tzcnt:
+; X86: # %bb.0:
+; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT: tzcntl %ecx, %edx
+; X86-NEXT: xorl %eax, %eax
+; X86-NEXT: testl %ecx, %ecx
+; X86-NEXT: setle %al
+; X86-NEXT: addl %edx, %eax
+; X86-NEXT: retl
+ %2 = tail call i32 @llvm.cttz.i32(i32 %0, i1 false)
+ %3 = icmp slt i32 %0, 1
+ %4 = zext i1 %3 to i32
+ %5 = add nuw nsw i32 %2, %4
+ ret i32 %5
+}
+
+define i32 @remove_redundant_cmp_sge_tzcnt(i32 %0) {
+; X64-LABEL: remove_redundant_cmp_sge_tzcnt:
+; X64: # %bb.0:
+; X64-NEXT: tzcntl %edi, %ecx
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: testl %edi, %edi
+; X64-NEXT: setg %al
+; X64-NEXT: addl %ecx, %eax
+; X64-NEXT: retq
+;
+; X86-LABEL: remove_redundant_cmp_sge_tzcnt:
+; X86: # %bb.0:
+; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT: tzcntl %ecx, %edx
+; X86-NEXT: xorl %eax, %eax
+; X86-NEXT: testl %ecx, %ecx
+; X86-NEXT: setg %al
+; X86-NEXT: addl %edx, %eax
+; X86-NEXT: retl
+ %2 = tail call i32 @llvm.cttz.i32(i32 %0, i1 false)
+ %3 = icmp sge i32 %0, 1
+ %4 = zext i1 %3 to i32
+ %5 = add nuw nsw i32 %2, %4
+ ret i32 %5
+}
+
+define i32 @remove_redundant_cmp_sgt_tzcnt(i32 %0) {
+; X64-LABEL: remove_redundant_cmp_sgt_tzcnt:
+; X64: # %bb.0:
+; X64-NEXT: tzcntl %edi, %ecx
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: cmpl $2, %edi
+; X64-NEXT: setge %al
+; X64-NEXT: addl %ecx, %eax
+; X64-NEXT: retq
+;
+; X86-LABEL: remove_redundant_cmp_sgt_tzcnt:
+; X86: # %bb.0:
+; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT: tzcntl %ecx, %edx
+; X86-NEXT: xorl %eax, %eax
+; X86-NEXT: cmpl $2, %ecx
+; X86-NEXT: setge %al
+; X86-NEXT: addl %edx, %eax
+; X86-NEXT: retl
+ %2 = tail call i32 @llvm.cttz.i32(i32 %0, i1 false)
+ %3 = icmp sgt i32 %0, 1
+ %4 = zext i1 %3 to i32
+ %5 = add nuw nsw i32 %2, %4
+ ret i32 %5
+}
+
+define i32 @remove_redundant_cmp_sle_tzcnt(i32 %0) {
+; X64-LABEL: remove_redundant_cmp_sle_tzcnt:
+; X64: # %bb.0:
+; X64-NEXT: tzcntl %edi, %ecx
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: cmpl $2, %edi
+; X64-NEXT: setl %al
+; X64-NEXT: addl %ecx, %eax
+; X64-NEXT: retq
+;
+; X86-LABEL: remove_redundant_cmp_sle_tzcnt:
+; X86: # %bb.0:
+; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT: tzcntl %ecx, %edx
+; X86-NEXT: xorl %eax, %eax
+; X86-NEXT: cmpl $2, %ecx
+; X86-NEXT: setl %al
+; X86-NEXT: addl %edx, %eax
+; X86-NEXT: retl
+ %2 = tail call i32 @llvm.cttz.i32(i32 %0, i1 false)
+ %3 = icmp sle i32 %0, 1
+ %4 = zext i1 %3 to i32
+ %5 = add nuw nsw i32 %2, %4
+ ret i32 %5
+}
>From 9ed8a02fcc166383e908f22823ca0b555ad3d3a6 Mon Sep 17 00:00:00 2001
From: Vachan V Y <vachanvy05 at gmail.com>
Date: Tue, 14 Jul 2026 12:20:34 +0530
Subject: [PATCH 9/9] [X86] refactor tests -- RKSimon
---
.../X86/remove-redundant-cmp-lzcnt-i64.ll | 76 +++
.../remove-redundant-cmp-lzcnt-tzcnt-i64.ll | 297 ---------
.../X86/remove-redundant-cmp-lzcnt-tzcnt.ll | 610 ------------------
.../CodeGen/X86/remove-redundant-cmp-lzcnt.ll | 186 ++++++
.../X86/remove-redundant-cmp-tzcnt-i64.ll | 74 +++
.../CodeGen/X86/remove-redundant-cmp-tzcnt.ll | 199 ++++++
6 files changed, 535 insertions(+), 907 deletions(-)
create mode 100644 llvm/test/CodeGen/X86/remove-redundant-cmp-lzcnt-i64.ll
delete mode 100644 llvm/test/CodeGen/X86/remove-redundant-cmp-lzcnt-tzcnt-i64.ll
delete mode 100644 llvm/test/CodeGen/X86/remove-redundant-cmp-lzcnt-tzcnt.ll
create mode 100644 llvm/test/CodeGen/X86/remove-redundant-cmp-lzcnt.ll
create mode 100644 llvm/test/CodeGen/X86/remove-redundant-cmp-tzcnt-i64.ll
create mode 100644 llvm/test/CodeGen/X86/remove-redundant-cmp-tzcnt.ll
diff --git a/llvm/test/CodeGen/X86/remove-redundant-cmp-lzcnt-i64.ll b/llvm/test/CodeGen/X86/remove-redundant-cmp-lzcnt-i64.ll
new file mode 100644
index 0000000000000..82d10a5688cfa
--- /dev/null
+++ b/llvm/test/CodeGen/X86/remove-redundant-cmp-lzcnt-i64.ll
@@ -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
+ %2 = tail call i64 @llvm.ctlz.i64(i64 %0, i1 false)
+ %3 = icmp ne i64 %0, 1
+ %4 = zext i1 %3 to i64
+ %5 = add nuw nsw i64 %2, %4
+ ret i64 %5
+}
+
+define i64 @remove_redundant_cmp_sge_lzcnt_i64(i64 %0) {
+; CHECK-LABEL: remove_redundant_cmp_sge_lzcnt_i64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: lzcntq %rdi, %rcx
+; CHECK-NEXT: xorl %eax, %eax
+; CHECK-NEXT: testq %rdi, %rdi
+; CHECK-NEXT: setg %al
+; CHECK-NEXT: addq %rcx, %rax
+; CHECK-NEXT: retq
+ %2 = tail call i64 @llvm.ctlz.i64(i64 %0, i1 false)
+ %3 = icmp sge i64 %0, 1
+ %4 = zext i1 %3 to i64
+ %5 = add nuw nsw i64 %2, %4
+ ret i64 %5
+}
+
+define i64 @remove_redundant_cmp_sle_lzcnt_i64(i64 %0) {
+; CHECK-LABEL: remove_redundant_cmp_sle_lzcnt_i64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: lzcntq %rdi, %rcx
+; CHECK-NEXT: xorl %eax, %eax
+; CHECK-NEXT: cmpq $2, %rdi
+; CHECK-NEXT: setl %al
+; CHECK-NEXT: addq %rcx, %rax
+; CHECK-NEXT: retq
+ %2 = tail call i64 @llvm.ctlz.i64(i64 %0, i1 false)
+ %3 = icmp sle i64 %0, 1
+ %4 = zext i1 %3 to i64
+ %5 = add nuw nsw i64 %2, %4
+ ret i64 %5
+}
diff --git a/llvm/test/CodeGen/X86/remove-redundant-cmp-lzcnt-tzcnt-i64.ll b/llvm/test/CodeGen/X86/remove-redundant-cmp-lzcnt-tzcnt-i64.ll
deleted file mode 100644
index 9a2473d7734af..0000000000000
--- a/llvm/test/CodeGen/X86/remove-redundant-cmp-lzcnt-tzcnt-i64.ll
+++ /dev/null
@@ -1,297 +0,0 @@
-; 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_eq_lzcnt(i64 %0) {
-; CHECK-LABEL: remove_redundant_cmp_eq_lzcnt:
-; 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 eq i64 %0, 0
- %4 = zext i1 %3 to i64
- %5 = add nuw nsw i64 %2, %4
- ret i64 %5
-}
-
-define i64 @remove_redundant_cmp_ult_lzcnt(i64 %0) {
-; CHECK-LABEL: remove_redundant_cmp_ult_lzcnt:
-; 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_uge_lzcnt(i64 %0) {
-; CHECK-LABEL: remove_redundant_cmp_uge_lzcnt:
-; CHECK: # %bb.0:
-; CHECK-NEXT: lzcntq %rdi, %rax
-; CHECK-NEXT: sbbq $-1, %rax
-; CHECK-NEXT: retq
- %2 = tail call i64 @llvm.ctlz.i64(i64 %0, i1 false)
- %3 = icmp uge 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 %0) {
-; CHECK-LABEL: remove_redundant_cmp_ugt_lzcnt:
-; 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_ule_lzcnt(i64 %0) {
-; CHECK-LABEL: remove_redundant_cmp_ule_lzcnt:
-; CHECK: # %bb.0:
-; CHECK-NEXT: lzcntq %rdi, %rax
-; CHECK-NEXT: cmpq $2, %rdi
-; CHECK-NEXT: adcq $0, %rax
-; CHECK-NEXT: retq
- %2 = tail call i64 @llvm.ctlz.i64(i64 %0, i1 false)
- %3 = icmp ule 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 %0) {
-; CHECK-LABEL: remove_redundant_cmp_ne_lzcnt:
-; 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
- %2 = tail call i64 @llvm.ctlz.i64(i64 %0, i1 false)
- %3 = icmp ne i64 %0, 1
- %4 = zext i1 %3 to i64
- %5 = add nuw nsw i64 %2, %4
- ret i64 %5
-}
-
-define i64 @remove_redundant_cmp_slt_lzcnt(i64 %0) {
-; CHECK-LABEL: remove_redundant_cmp_slt_lzcnt:
-; CHECK: # %bb.0:
-; CHECK-NEXT: lzcntq %rdi, %rcx
-; CHECK-NEXT: xorl %eax, %eax
-; CHECK-NEXT: testq %rdi, %rdi
-; CHECK-NEXT: setle %al
-; CHECK-NEXT: addq %rcx, %rax
-; CHECK-NEXT: retq
- %2 = tail call i64 @llvm.ctlz.i64(i64 %0, i1 false)
- %3 = icmp slt i64 %0, 1
- %4 = zext i1 %3 to i64
- %5 = add nuw nsw i64 %2, %4
- ret i64 %5
-}
-
-define i64 @remove_redundant_cmp_sge_lzcnt(i64 %0) {
-; CHECK-LABEL: remove_redundant_cmp_sge_lzcnt:
-; CHECK: # %bb.0:
-; CHECK-NEXT: lzcntq %rdi, %rcx
-; CHECK-NEXT: xorl %eax, %eax
-; CHECK-NEXT: testq %rdi, %rdi
-; CHECK-NEXT: setg %al
-; CHECK-NEXT: addq %rcx, %rax
-; CHECK-NEXT: retq
- %2 = tail call i64 @llvm.ctlz.i64(i64 %0, i1 false)
- %3 = icmp sge i64 %0, 1
- %4 = zext i1 %3 to i64
- %5 = add nuw nsw i64 %2, %4
- ret i64 %5
-}
-
-define i64 @remove_redundant_cmp_sgt_lzcnt(i64 %0) {
-; CHECK-LABEL: remove_redundant_cmp_sgt_lzcnt:
-; CHECK: # %bb.0:
-; CHECK-NEXT: lzcntq %rdi, %rcx
-; CHECK-NEXT: xorl %eax, %eax
-; CHECK-NEXT: cmpq $2, %rdi
-; CHECK-NEXT: setge %al
-; CHECK-NEXT: addq %rcx, %rax
-; CHECK-NEXT: retq
- %2 = tail call i64 @llvm.ctlz.i64(i64 %0, i1 false)
- %3 = icmp sgt i64 %0, 1
- %4 = zext i1 %3 to i64
- %5 = add nuw nsw i64 %2, %4
- ret i64 %5
-}
-
-define i64 @remove_redundant_cmp_sle_lzcnt(i64 %0) {
-; CHECK-LABEL: remove_redundant_cmp_sle_lzcnt:
-; CHECK: # %bb.0:
-; CHECK-NEXT: lzcntq %rdi, %rcx
-; CHECK-NEXT: xorl %eax, %eax
-; CHECK-NEXT: cmpq $2, %rdi
-; CHECK-NEXT: setl %al
-; CHECK-NEXT: addq %rcx, %rax
-; CHECK-NEXT: retq
- %2 = tail call i64 @llvm.ctlz.i64(i64 %0, i1 false)
- %3 = icmp sle i64 %0, 1
- %4 = zext i1 %3 to i64
- %5 = add nuw nsw i64 %2, %4
- ret i64 %5
-}
-
-define i64 @remove_redundant_cmp_eq_tzcnt(i64 %0) {
-; CHECK-LABEL: remove_redundant_cmp_eq_tzcnt:
-; CHECK: # %bb.0:
-; CHECK-NEXT: tzcntq %rdi, %rax
-; CHECK-NEXT: adcq $0, %rax
-; CHECK-NEXT: retq
- %2 = tail call i64 @llvm.cttz.i64(i64 %0, i1 false)
- %3 = icmp eq i64 %0, 0
- %4 = zext i1 %3 to i64
- %5 = add nuw nsw i64 %2, %4
- ret i64 %5
-}
-
-
-define i64 @remove_redundant_cmp_ult_tzcnt(i64 %0) {
-; CHECK-LABEL: remove_redundant_cmp_ult_tzcnt:
-; CHECK: # %bb.0:
-; CHECK-NEXT: tzcntq %rdi, %rax
-; CHECK-NEXT: adcq $0, %rax
-; CHECK-NEXT: retq
- %2 = tail call i64 @llvm.cttz.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_uge_tzcnt(i64 %0) {
-; CHECK-LABEL: remove_redundant_cmp_uge_tzcnt:
-; CHECK: # %bb.0:
-; CHECK-NEXT: tzcntq %rdi, %rax
-; CHECK-NEXT: sbbq $-1, %rax
-; CHECK-NEXT: retq
- %2 = tail call i64 @llvm.cttz.i64(i64 %0, i1 false)
- %3 = icmp uge 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_tzcnt(i64 %0) {
-; CHECK-LABEL: remove_redundant_cmp_ugt_tzcnt:
-; CHECK: # %bb.0:
-; CHECK-NEXT: tzcntq %rdi, %rax
-; CHECK-NEXT: cmpq $2, %rdi
-; CHECK-NEXT: sbbq $-1, %rax
-; CHECK-NEXT: retq
- %2 = tail call i64 @llvm.cttz.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_ule_tzcnt(i64 %0) {
-; CHECK-LABEL: remove_redundant_cmp_ule_tzcnt:
-; CHECK: # %bb.0:
-; CHECK-NEXT: tzcntq %rdi, %rax
-; CHECK-NEXT: cmpq $2, %rdi
-; CHECK-NEXT: adcq $0, %rax
-; CHECK-NEXT: retq
- %2 = tail call i64 @llvm.cttz.i64(i64 %0, i1 false)
- %3 = icmp ule 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_tzcnt(i64 %0) {
-; CHECK-LABEL: remove_redundant_cmp_ne_tzcnt:
-; CHECK: # %bb.0:
-; CHECK-NEXT: xorl %eax, %eax
-; CHECK-NEXT: tzcntq %rdi, %rcx
-; CHECK-NEXT: setne %al
-; CHECK-NEXT: addq %rcx, %rax
-; CHECK-NEXT: retq
- %2 = tail call i64 @llvm.cttz.i64(i64 %0, i1 false)
- %3 = icmp ne i64 %0, 1
- %4 = zext i1 %3 to i64
- %5 = add nuw nsw i64 %2, %4
- ret i64 %5
-}
-
-define i64 @remove_redundant_cmp_slt_tzcnt(i64 %0) {
-; CHECK-LABEL: remove_redundant_cmp_slt_tzcnt:
-; CHECK: # %bb.0:
-; CHECK-NEXT: tzcntq %rdi, %rcx
-; CHECK-NEXT: xorl %eax, %eax
-; CHECK-NEXT: testq %rdi, %rdi
-; CHECK-NEXT: setle %al
-; CHECK-NEXT: addq %rcx, %rax
-; CHECK-NEXT: retq
- %2 = tail call i64 @llvm.cttz.i64(i64 %0, i1 false)
- %3 = icmp slt i64 %0, 1
- %4 = zext i1 %3 to i64
- %5 = add nuw nsw i64 %2, %4
- ret i64 %5
-}
-
-define i64 @remove_redundant_cmp_sge_tzcnt(i64 %0) {
-; CHECK-LABEL: remove_redundant_cmp_sge_tzcnt:
-; CHECK: # %bb.0:
-; CHECK-NEXT: tzcntq %rdi, %rcx
-; CHECK-NEXT: xorl %eax, %eax
-; CHECK-NEXT: testq %rdi, %rdi
-; CHECK-NEXT: setg %al
-; CHECK-NEXT: addq %rcx, %rax
-; CHECK-NEXT: retq
- %2 = tail call i64 @llvm.cttz.i64(i64 %0, i1 false)
- %3 = icmp sge i64 %0, 1
- %4 = zext i1 %3 to i64
- %5 = add nuw nsw i64 %2, %4
- ret i64 %5
-}
-
-define i64 @remove_redundant_cmp_sgt_tzcnt(i64 %0) {
-; CHECK-LABEL: remove_redundant_cmp_sgt_tzcnt:
-; CHECK: # %bb.0:
-; CHECK-NEXT: tzcntq %rdi, %rcx
-; CHECK-NEXT: xorl %eax, %eax
-; CHECK-NEXT: cmpq $2, %rdi
-; CHECK-NEXT: setge %al
-; CHECK-NEXT: addq %rcx, %rax
-; CHECK-NEXT: retq
- %2 = tail call i64 @llvm.cttz.i64(i64 %0, i1 false)
- %3 = icmp sgt i64 %0, 1
- %4 = zext i1 %3 to i64
- %5 = add nuw nsw i64 %2, %4
- ret i64 %5
-}
-
-define i64 @remove_redundant_cmp_sle_tzcnt(i64 %0) {
-; CHECK-LABEL: remove_redundant_cmp_sle_tzcnt:
-; CHECK: # %bb.0:
-; CHECK-NEXT: tzcntq %rdi, %rcx
-; CHECK-NEXT: xorl %eax, %eax
-; CHECK-NEXT: cmpq $2, %rdi
-; CHECK-NEXT: setl %al
-; CHECK-NEXT: addq %rcx, %rax
-; CHECK-NEXT: retq
- %2 = tail call i64 @llvm.cttz.i64(i64 %0, i1 false)
- %3 = icmp sle i64 %0, 1
- %4 = zext i1 %3 to i64
- %5 = add nuw nsw i64 %2, %4
- ret i64 %5
-}
diff --git a/llvm/test/CodeGen/X86/remove-redundant-cmp-lzcnt-tzcnt.ll b/llvm/test/CodeGen/X86/remove-redundant-cmp-lzcnt-tzcnt.ll
deleted file mode 100644
index e0bf88cda1f90..0000000000000
--- a/llvm/test/CodeGen/X86/remove-redundant-cmp-lzcnt-tzcnt.ll
+++ /dev/null
@@ -1,610 +0,0 @@
-; 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 --check-prefix=X64
-; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+bmi,+lzcnt | FileCheck %s --check-prefix=X86
-
-define i32 @remove_redundant_cmp_eq_lzcnt_i32(i32 %0) {
-; X64-LABEL: remove_redundant_cmp_eq_lzcnt_i32:
-; X64: # %bb.0:
-; X64-NEXT: lzcntl %edi, %eax
-; X64-NEXT: adcl $0, %eax
-; X64-NEXT: retq
-;
-; X86-LABEL: remove_redundant_cmp_eq_lzcnt_i32:
-; X86: # %bb.0:
-; X86-NEXT: lzcntl {{[0-9]+}}(%esp), %eax
-; X86-NEXT: adcl $0, %eax
-; X86-NEXT: retl
- %2 = tail call i32 @llvm.ctlz.i32(i32 %0, i1 false)
- %3 = icmp eq i32 %0, 0
- %4 = zext i1 %3 to i32
- %5 = add nuw nsw i32 %2, %4
- ret i32 %5
-}
-
-define i16 @remove_redundant_cmp_lzcnt_i16(i16 %0) {
-; X64-LABEL: remove_redundant_cmp_lzcnt_i16:
-; X64: # %bb.0:
-; X64-NEXT: lzcntw %di, %ax
-; X64-NEXT: adcw $0, %ax
-; X64-NEXT: retq
-;
-; X86-LABEL: remove_redundant_cmp_lzcnt_i16:
-; X86: # %bb.0:
-; X86-NEXT: lzcntw {{[0-9]+}}(%esp), %ax
-; X86-NEXT: adcw $0, %ax
-; X86-NEXT: retl
- %2 = tail call i16 @llvm.ctlz.i16(i16 %0, i1 false)
- %3 = icmp eq i16 %0, 0
- %4 = zext i1 %3 to i16
- %5 = add nuw nsw i16 %2, %4
- ret i16 %5
-}
-
-define i32 @remove_redundant_cmp_ult_lzcnt(i32 %0) {
-; X64-LABEL: remove_redundant_cmp_ult_lzcnt:
-; X64: # %bb.0:
-; X64-NEXT: lzcntl %edi, %eax
-; X64-NEXT: adcl $0, %eax
-; X64-NEXT: retq
-;
-; X86-LABEL: remove_redundant_cmp_ult_lzcnt:
-; X86: # %bb.0:
-; X86-NEXT: lzcntl {{[0-9]+}}(%esp), %eax
-; X86-NEXT: adcl $0, %eax
-; X86-NEXT: retl
- %2 = tail call i32 @llvm.ctlz.i32(i32 %0, i1 false)
- %3 = icmp ult i32 %0, 1
- %4 = zext i1 %3 to i32
- %5 = add nuw nsw i32 %2, %4
- ret i32 %5
-}
-
-define i32 @remove_redundant_cmp_uge_lzcnt(i32 %0) {
-; X64-LABEL: remove_redundant_cmp_uge_lzcnt:
-; X64: # %bb.0:
-; X64-NEXT: lzcntl %edi, %eax
-; X64-NEXT: sbbl $-1, %eax
-; X64-NEXT: retq
-;
-; X86-LABEL: remove_redundant_cmp_uge_lzcnt:
-; X86: # %bb.0:
-; X86-NEXT: lzcntl {{[0-9]+}}(%esp), %eax
-; X86-NEXT: sbbl $-1, %eax
-; X86-NEXT: retl
- %2 = tail call i32 @llvm.ctlz.i32(i32 %0, i1 false)
- %3 = icmp uge i32 %0, 1
- %4 = zext i1 %3 to i32
- %5 = add nuw nsw i32 %2, %4
- ret i32 %5
-}
-
-define i32 @remove_redundant_cmp_ugt_lzcnt(i32 %0) {
-; X64-LABEL: remove_redundant_cmp_ugt_lzcnt:
-; X64: # %bb.0:
-; X64-NEXT: lzcntl %edi, %eax
-; X64-NEXT: cmpl $2, %edi
-; X64-NEXT: sbbl $-1, %eax
-; X64-NEXT: retq
-;
-; X86-LABEL: remove_redundant_cmp_ugt_lzcnt:
-; X86: # %bb.0:
-; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT: lzcntl %ecx, %eax
-; X86-NEXT: cmpl $2, %ecx
-; X86-NEXT: sbbl $-1, %eax
-; X86-NEXT: retl
- %2 = tail call i32 @llvm.ctlz.i32(i32 %0, i1 false)
- %3 = icmp ugt i32 %0, 1
- %4 = zext i1 %3 to i32
- %5 = add nuw nsw i32 %2, %4
- ret i32 %5
-}
-
-define i32 @remove_redundant_cmp_ule_lzcnt(i32 %0) {
-; X64-LABEL: remove_redundant_cmp_ule_lzcnt:
-; X64: # %bb.0:
-; X64-NEXT: lzcntl %edi, %eax
-; X64-NEXT: cmpl $2, %edi
-; X64-NEXT: adcl $0, %eax
-; X64-NEXT: retq
-;
-; X86-LABEL: remove_redundant_cmp_ule_lzcnt:
-; X86: # %bb.0:
-; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT: lzcntl %ecx, %eax
-; X86-NEXT: cmpl $2, %ecx
-; X86-NEXT: adcl $0, %eax
-; X86-NEXT: retl
- %2 = tail call i32 @llvm.ctlz.i32(i32 %0, i1 false)
- %3 = icmp ule i32 %0, 1
- %4 = zext i1 %3 to i32
- %5 = add nuw nsw i32 %2, %4
- ret i32 %5
-}
-
-define i32 @remove_redundant_cmp_ne_lzcnt(i32 %0) {
-; X64-LABEL: remove_redundant_cmp_ne_lzcnt:
-; X64: # %bb.0:
-; X64-NEXT: xorl %eax, %eax
-; X64-NEXT: lzcntl %edi, %ecx
-; X64-NEXT: setne %al
-; X64-NEXT: addl %ecx, %eax
-; X64-NEXT: retq
-;
-; X86-LABEL: remove_redundant_cmp_ne_lzcnt:
-; X86: # %bb.0:
-; X86-NEXT: xorl %eax, %eax
-; X86-NEXT: lzcntl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT: setne %al
-; X86-NEXT: addl %ecx, %eax
-; X86-NEXT: retl
- %2 = tail call i32 @llvm.ctlz.i32(i32 %0, i1 false)
- %3 = icmp ne i32 %0, 1
- %4 = zext i1 %3 to i32
- %5 = add nuw nsw i32 %2, %4
- ret i32 %5
-}
-
-define i32 @remove_redundant_cmp_slt_lzcnt(i32 %0) {
-; X64-LABEL: remove_redundant_cmp_slt_lzcnt:
-; X64: # %bb.0:
-; X64-NEXT: lzcntl %edi, %ecx
-; X64-NEXT: xorl %eax, %eax
-; X64-NEXT: testl %edi, %edi
-; X64-NEXT: setle %al
-; X64-NEXT: addl %ecx, %eax
-; X64-NEXT: retq
-;
-; X86-LABEL: remove_redundant_cmp_slt_lzcnt:
-; X86: # %bb.0:
-; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT: lzcntl %ecx, %edx
-; X86-NEXT: xorl %eax, %eax
-; X86-NEXT: testl %ecx, %ecx
-; X86-NEXT: setle %al
-; X86-NEXT: addl %edx, %eax
-; X86-NEXT: retl
- %2 = tail call i32 @llvm.ctlz.i32(i32 %0, i1 false)
- %3 = icmp slt i32 %0, 1
- %4 = zext i1 %3 to i32
- %5 = add nuw nsw i32 %2, %4
- ret i32 %5
-}
-
-define i32 @remove_redundant_cmp_sge_lzcnt(i32 %0) {
-; X64-LABEL: remove_redundant_cmp_sge_lzcnt:
-; X64: # %bb.0:
-; X64-NEXT: lzcntl %edi, %ecx
-; X64-NEXT: xorl %eax, %eax
-; X64-NEXT: testl %edi, %edi
-; X64-NEXT: setg %al
-; X64-NEXT: addl %ecx, %eax
-; X64-NEXT: retq
-;
-; X86-LABEL: remove_redundant_cmp_sge_lzcnt:
-; X86: # %bb.0:
-; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT: lzcntl %ecx, %edx
-; X86-NEXT: xorl %eax, %eax
-; X86-NEXT: testl %ecx, %ecx
-; X86-NEXT: setg %al
-; X86-NEXT: addl %edx, %eax
-; X86-NEXT: retl
- %2 = tail call i32 @llvm.ctlz.i32(i32 %0, i1 false)
- %3 = icmp sge i32 %0, 1
- %4 = zext i1 %3 to i32
- %5 = add nuw nsw i32 %2, %4
- ret i32 %5
-}
-
-define i32 @remove_redundant_cmp_sgt_lzcnt(i32 %0) {
-; X64-LABEL: remove_redundant_cmp_sgt_lzcnt:
-; X64: # %bb.0:
-; X64-NEXT: lzcntl %edi, %ecx
-; X64-NEXT: xorl %eax, %eax
-; X64-NEXT: cmpl $2, %edi
-; X64-NEXT: setge %al
-; X64-NEXT: addl %ecx, %eax
-; X64-NEXT: retq
-;
-; X86-LABEL: remove_redundant_cmp_sgt_lzcnt:
-; X86: # %bb.0:
-; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT: lzcntl %ecx, %edx
-; X86-NEXT: xorl %eax, %eax
-; X86-NEXT: cmpl $2, %ecx
-; X86-NEXT: setge %al
-; X86-NEXT: addl %edx, %eax
-; X86-NEXT: retl
- %2 = tail call i32 @llvm.ctlz.i32(i32 %0, i1 false)
- %3 = icmp sgt i32 %0, 1
- %4 = zext i1 %3 to i32
- %5 = add nuw nsw i32 %2, %4
- ret i32 %5
-}
-
-define i32 @remove_redundant_cmp_sle_lzcnt(i32 %0) {
-; X64-LABEL: remove_redundant_cmp_sle_lzcnt:
-; X64: # %bb.0:
-; X64-NEXT: lzcntl %edi, %ecx
-; X64-NEXT: xorl %eax, %eax
-; X64-NEXT: cmpl $2, %edi
-; X64-NEXT: setl %al
-; X64-NEXT: addl %ecx, %eax
-; X64-NEXT: retq
-;
-; X86-LABEL: remove_redundant_cmp_sle_lzcnt:
-; X86: # %bb.0:
-; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT: lzcntl %ecx, %edx
-; X86-NEXT: xorl %eax, %eax
-; X86-NEXT: cmpl $2, %ecx
-; X86-NEXT: setl %al
-; X86-NEXT: addl %edx, %eax
-; X86-NEXT: retl
- %2 = tail call i32 @llvm.ctlz.i32(i32 %0, i1 false)
- %3 = icmp sle i32 %0, 1
- %4 = zext i1 %3 to i32
- %5 = add nuw nsw i32 %2, %4
- ret i32 %5
-}
-
-define i32 @remove_redundant_cmp_lzcnt_no_constant(i32 %0, i32 %1) {
-; X64-LABEL: remove_redundant_cmp_lzcnt_no_constant:
-; X64: # %bb.0:
-; X64-NEXT: lzcntl %edi, %ecx
-; X64-NEXT: xorl %eax, %eax
-; X64-NEXT: cmpl %esi, %edi
-; X64-NEXT: sete %al
-; X64-NEXT: addl %ecx, %eax
-; X64-NEXT: retq
-;
-; X86-LABEL: remove_redundant_cmp_lzcnt_no_constant:
-; X86: # %bb.0:
-; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT: lzcntl %ecx, %edx
-; X86-NEXT: xorl %eax, %eax
-; X86-NEXT: cmpl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT: sete %al
-; X86-NEXT: addl %edx, %eax
-; X86-NEXT: retl
- %3 = tail call i32 @llvm.ctlz.i32(i32 %0, i1 false)
- %4 = icmp eq i32 %0, %1
- %5 = zext i1 %4 to i32
- %6 = add nuw nsw i32 %3, %5
- ret i32 %6
-}
-
-define i32 @remove_redundant_cmp_lzcnt_wrong_const(i32 %0) {
-; X64-LABEL: remove_redundant_cmp_lzcnt_wrong_const:
-; X64: # %bb.0:
-; X64-NEXT: lzcntl %edi, %ecx
-; X64-NEXT: xorl %eax, %eax
-; X64-NEXT: cmpl $2, %edi
-; X64-NEXT: sete %al
-; X64-NEXT: addl %ecx, %eax
-; X64-NEXT: retq
-;
-; X86-LABEL: remove_redundant_cmp_lzcnt_wrong_const:
-; X86: # %bb.0:
-; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT: lzcntl %ecx, %edx
-; X86-NEXT: xorl %eax, %eax
-; X86-NEXT: cmpl $2, %ecx
-; X86-NEXT: sete %al
-; X86-NEXT: addl %edx, %eax
-; X86-NEXT: retl
- %2 = tail call i32 @llvm.ctlz.i32(i32 %0, i1 false)
- %3 = icmp eq i32 %0, 2
- %4 = zext i1 %3 to i32
- %5 = add nuw nsw i32 %2, %4
- ret i32 %5
-}
-
-define i32 @remove_redundant_cmp_eq_tzcnt_i32(i32 %0) {
-; X64-LABEL: remove_redundant_cmp_eq_tzcnt_i32:
-; X64: # %bb.0:
-; X64-NEXT: tzcntl %edi, %eax
-; X64-NEXT: adcl $0, %eax
-; X64-NEXT: retq
-;
-; X86-LABEL: remove_redundant_cmp_eq_tzcnt_i32:
-; X86: # %bb.0:
-; X86-NEXT: tzcntl {{[0-9]+}}(%esp), %eax
-; X86-NEXT: adcl $0, %eax
-; X86-NEXT: retl
- %2 = tail call i32 @llvm.cttz.i32(i32 %0, i1 false)
- %3 = icmp eq i32 %0, 0
- %4 = zext i1 %3 to i32
- %5 = add nuw nsw i32 %2, %4
- ret i32 %5
-}
-
-define i16 @remove_redundant_cmp_tzcnt_i16(i16 %0) {
-; X64-LABEL: remove_redundant_cmp_tzcnt_i16:
-; X64: # %bb.0:
-; X64-NEXT: movl %edi, %eax
-; X64-NEXT: orl $65536, %eax # imm = 0x10000
-; X64-NEXT: tzcntl %eax, %eax
-; X64-NEXT: cmpw $1, %di
-; X64-NEXT: adcw $0, %ax
-; X64-NEXT: # kill: def $ax killed $ax killed $eax
-; X64-NEXT: retq
-;
-; X86-LABEL: remove_redundant_cmp_tzcnt_i16:
-; X86: # %bb.0:
-; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT: movl %ecx, %eax
-; X86-NEXT: orl $65536, %eax # imm = 0x10000
-; X86-NEXT: tzcntl %eax, %eax
-; X86-NEXT: cmpw $1, %cx
-; X86-NEXT: adcw $0, %ax
-; X86-NEXT: # kill: def $ax killed $ax killed $eax
-; X86-NEXT: retl
- %2 = tail call i16 @llvm.cttz.i16(i16 %0, i1 false)
- %3 = icmp eq i16 %0, 0
- %4 = zext i1 %3 to i16
- %5 = add nuw nsw i16 %2, %4
- ret i16 %5
-}
-
-define i32 @remove_redundant_cmp_tzcnt_no_constant(i32 %0, i32 %1) {
-; X64-LABEL: remove_redundant_cmp_tzcnt_no_constant:
-; X64: # %bb.0:
-; X64-NEXT: tzcntl %edi, %ecx
-; X64-NEXT: xorl %eax, %eax
-; X64-NEXT: cmpl %esi, %edi
-; X64-NEXT: sete %al
-; X64-NEXT: addl %ecx, %eax
-; X64-NEXT: retq
-;
-; X86-LABEL: remove_redundant_cmp_tzcnt_no_constant:
-; X86: # %bb.0:
-; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT: tzcntl %ecx, %edx
-; X86-NEXT: xorl %eax, %eax
-; X86-NEXT: cmpl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT: sete %al
-; X86-NEXT: addl %edx, %eax
-; X86-NEXT: retl
- %3 = tail call i32 @llvm.cttz.i32(i32 %0, i1 false)
- %4 = icmp eq i32 %0, %1
- %5 = zext i1 %4 to i32
- %6 = add nuw nsw i32 %3, %5
- ret i32 %6
-}
-
-define i32 @remove_redundant_cmp_tzcnt_wrong_const(i32 %0) {
-; X64-LABEL: remove_redundant_cmp_tzcnt_wrong_const:
-; X64: # %bb.0:
-; X64-NEXT: tzcntl %edi, %ecx
-; X64-NEXT: xorl %eax, %eax
-; X64-NEXT: cmpl $2, %edi
-; X64-NEXT: sete %al
-; X64-NEXT: addl %ecx, %eax
-; X64-NEXT: retq
-;
-; X86-LABEL: remove_redundant_cmp_tzcnt_wrong_const:
-; X86: # %bb.0:
-; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT: tzcntl %ecx, %edx
-; X86-NEXT: xorl %eax, %eax
-; X86-NEXT: cmpl $2, %ecx
-; X86-NEXT: sete %al
-; X86-NEXT: addl %edx, %eax
-; X86-NEXT: retl
- %2 = tail call i32 @llvm.cttz.i32(i32 %0, i1 false)
- %3 = icmp eq i32 %0, 2
- %4 = zext i1 %3 to i32
- %5 = add nuw nsw i32 %2, %4
- ret i32 %5
-}
-
-define i32 @remove_redundant_cmp_ult_tzcnt(i32 %0) {
-; X64-LABEL: remove_redundant_cmp_ult_tzcnt:
-; X64: # %bb.0:
-; X64-NEXT: tzcntl %edi, %eax
-; X64-NEXT: adcl $0, %eax
-; X64-NEXT: retq
-;
-; X86-LABEL: remove_redundant_cmp_ult_tzcnt:
-; X86: # %bb.0:
-; X86-NEXT: tzcntl {{[0-9]+}}(%esp), %eax
-; X86-NEXT: adcl $0, %eax
-; X86-NEXT: retl
- %2 = tail call i32 @llvm.cttz.i32(i32 %0, i1 false)
- %3 = icmp ult i32 %0, 1
- %4 = zext i1 %3 to i32
- %5 = add nuw nsw i32 %2, %4
- ret i32 %5
-}
-
-define i32 @remove_redundant_cmp_uge_tzcnt(i32 %0) {
-; X64-LABEL: remove_redundant_cmp_uge_tzcnt:
-; X64: # %bb.0:
-; X64-NEXT: tzcntl %edi, %eax
-; X64-NEXT: sbbl $-1, %eax
-; X64-NEXT: retq
-;
-; X86-LABEL: remove_redundant_cmp_uge_tzcnt:
-; X86: # %bb.0:
-; X86-NEXT: tzcntl {{[0-9]+}}(%esp), %eax
-; X86-NEXT: sbbl $-1, %eax
-; X86-NEXT: retl
- %2 = tail call i32 @llvm.cttz.i32(i32 %0, i1 false)
- %3 = icmp uge i32 %0, 1
- %4 = zext i1 %3 to i32
- %5 = add nuw nsw i32 %2, %4
- ret i32 %5
-}
-
-define i32 @remove_redundant_cmp_ugt_tzcnt(i32 %0) {
-; X64-LABEL: remove_redundant_cmp_ugt_tzcnt:
-; X64: # %bb.0:
-; X64-NEXT: tzcntl %edi, %eax
-; X64-NEXT: cmpl $2, %edi
-; X64-NEXT: sbbl $-1, %eax
-; X64-NEXT: retq
-;
-; X86-LABEL: remove_redundant_cmp_ugt_tzcnt:
-; X86: # %bb.0:
-; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT: tzcntl %ecx, %eax
-; X86-NEXT: cmpl $2, %ecx
-; X86-NEXT: sbbl $-1, %eax
-; X86-NEXT: retl
- %2 = tail call i32 @llvm.cttz.i32(i32 %0, i1 false)
- %3 = icmp ugt i32 %0, 1
- %4 = zext i1 %3 to i32
- %5 = add nuw nsw i32 %2, %4
- ret i32 %5
-}
-
-define i32 @remove_redundant_cmp_ule_tzcnt(i32 %0) {
-; X64-LABEL: remove_redundant_cmp_ule_tzcnt:
-; X64: # %bb.0:
-; X64-NEXT: tzcntl %edi, %eax
-; X64-NEXT: cmpl $2, %edi
-; X64-NEXT: adcl $0, %eax
-; X64-NEXT: retq
-;
-; X86-LABEL: remove_redundant_cmp_ule_tzcnt:
-; X86: # %bb.0:
-; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT: tzcntl %ecx, %eax
-; X86-NEXT: cmpl $2, %ecx
-; X86-NEXT: adcl $0, %eax
-; X86-NEXT: retl
- %2 = tail call i32 @llvm.cttz.i32(i32 %0, i1 false)
- %3 = icmp ule i32 %0, 1
- %4 = zext i1 %3 to i32
- %5 = add nuw nsw i32 %2, %4
- ret i32 %5
-}
-
-define i32 @remove_redundant_cmp_ne_tzcnt(i32 %0) {
-; X64-LABEL: remove_redundant_cmp_ne_tzcnt:
-; X64: # %bb.0:
-; X64-NEXT: xorl %eax, %eax
-; X64-NEXT: tzcntl %edi, %ecx
-; X64-NEXT: setne %al
-; X64-NEXT: addl %ecx, %eax
-; X64-NEXT: retq
-;
-; X86-LABEL: remove_redundant_cmp_ne_tzcnt:
-; X86: # %bb.0:
-; X86-NEXT: xorl %eax, %eax
-; X86-NEXT: tzcntl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT: setne %al
-; X86-NEXT: addl %ecx, %eax
-; X86-NEXT: retl
- %2 = tail call i32 @llvm.cttz.i32(i32 %0, i1 false)
- %3 = icmp ne i32 %0, 1
- %4 = zext i1 %3 to i32
- %5 = add nuw nsw i32 %2, %4
- ret i32 %5
-}
-
-define i32 @remove_redundant_cmp_slt_tzcnt(i32 %0) {
-; X64-LABEL: remove_redundant_cmp_slt_tzcnt:
-; X64: # %bb.0:
-; X64-NEXT: tzcntl %edi, %ecx
-; X64-NEXT: xorl %eax, %eax
-; X64-NEXT: testl %edi, %edi
-; X64-NEXT: setle %al
-; X64-NEXT: addl %ecx, %eax
-; X64-NEXT: retq
-;
-; X86-LABEL: remove_redundant_cmp_slt_tzcnt:
-; X86: # %bb.0:
-; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT: tzcntl %ecx, %edx
-; X86-NEXT: xorl %eax, %eax
-; X86-NEXT: testl %ecx, %ecx
-; X86-NEXT: setle %al
-; X86-NEXT: addl %edx, %eax
-; X86-NEXT: retl
- %2 = tail call i32 @llvm.cttz.i32(i32 %0, i1 false)
- %3 = icmp slt i32 %0, 1
- %4 = zext i1 %3 to i32
- %5 = add nuw nsw i32 %2, %4
- ret i32 %5
-}
-
-define i32 @remove_redundant_cmp_sge_tzcnt(i32 %0) {
-; X64-LABEL: remove_redundant_cmp_sge_tzcnt:
-; X64: # %bb.0:
-; X64-NEXT: tzcntl %edi, %ecx
-; X64-NEXT: xorl %eax, %eax
-; X64-NEXT: testl %edi, %edi
-; X64-NEXT: setg %al
-; X64-NEXT: addl %ecx, %eax
-; X64-NEXT: retq
-;
-; X86-LABEL: remove_redundant_cmp_sge_tzcnt:
-; X86: # %bb.0:
-; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT: tzcntl %ecx, %edx
-; X86-NEXT: xorl %eax, %eax
-; X86-NEXT: testl %ecx, %ecx
-; X86-NEXT: setg %al
-; X86-NEXT: addl %edx, %eax
-; X86-NEXT: retl
- %2 = tail call i32 @llvm.cttz.i32(i32 %0, i1 false)
- %3 = icmp sge i32 %0, 1
- %4 = zext i1 %3 to i32
- %5 = add nuw nsw i32 %2, %4
- ret i32 %5
-}
-
-define i32 @remove_redundant_cmp_sgt_tzcnt(i32 %0) {
-; X64-LABEL: remove_redundant_cmp_sgt_tzcnt:
-; X64: # %bb.0:
-; X64-NEXT: tzcntl %edi, %ecx
-; X64-NEXT: xorl %eax, %eax
-; X64-NEXT: cmpl $2, %edi
-; X64-NEXT: setge %al
-; X64-NEXT: addl %ecx, %eax
-; X64-NEXT: retq
-;
-; X86-LABEL: remove_redundant_cmp_sgt_tzcnt:
-; X86: # %bb.0:
-; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT: tzcntl %ecx, %edx
-; X86-NEXT: xorl %eax, %eax
-; X86-NEXT: cmpl $2, %ecx
-; X86-NEXT: setge %al
-; X86-NEXT: addl %edx, %eax
-; X86-NEXT: retl
- %2 = tail call i32 @llvm.cttz.i32(i32 %0, i1 false)
- %3 = icmp sgt i32 %0, 1
- %4 = zext i1 %3 to i32
- %5 = add nuw nsw i32 %2, %4
- ret i32 %5
-}
-
-define i32 @remove_redundant_cmp_sle_tzcnt(i32 %0) {
-; X64-LABEL: remove_redundant_cmp_sle_tzcnt:
-; X64: # %bb.0:
-; X64-NEXT: tzcntl %edi, %ecx
-; X64-NEXT: xorl %eax, %eax
-; X64-NEXT: cmpl $2, %edi
-; X64-NEXT: setl %al
-; X64-NEXT: addl %ecx, %eax
-; X64-NEXT: retq
-;
-; X86-LABEL: remove_redundant_cmp_sle_tzcnt:
-; X86: # %bb.0:
-; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT: tzcntl %ecx, %edx
-; X86-NEXT: xorl %eax, %eax
-; X86-NEXT: cmpl $2, %ecx
-; X86-NEXT: setl %al
-; X86-NEXT: addl %edx, %eax
-; X86-NEXT: retl
- %2 = tail call i32 @llvm.cttz.i32(i32 %0, i1 false)
- %3 = icmp sle i32 %0, 1
- %4 = zext i1 %3 to i32
- %5 = add nuw nsw i32 %2, %4
- ret i32 %5
-}
diff --git a/llvm/test/CodeGen/X86/remove-redundant-cmp-lzcnt.ll b/llvm/test/CodeGen/X86/remove-redundant-cmp-lzcnt.ll
new file mode 100644
index 0000000000000..7658e7e96c93c
--- /dev/null
+++ b/llvm/test/CodeGen/X86/remove-redundant-cmp-lzcnt.ll
@@ -0,0 +1,186 @@
+; 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 --check-prefix=X64
+; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+bmi,+lzcnt | FileCheck %s --check-prefix=X86
+
+define i32 @remove_redundant_cmp_eq_lzcnt_i32(i32 %0) {
+; X64-LABEL: remove_redundant_cmp_eq_lzcnt_i32:
+; X64: # %bb.0:
+; X64-NEXT: lzcntl %edi, %eax
+; X64-NEXT: adcl $0, %eax
+; X64-NEXT: retq
+;
+; X86-LABEL: remove_redundant_cmp_eq_lzcnt_i32:
+; X86: # %bb.0:
+; X86-NEXT: lzcntl {{[0-9]+}}(%esp), %eax
+; X86-NEXT: adcl $0, %eax
+; X86-NEXT: retl
+ %2 = tail call i32 @llvm.ctlz.i32(i32 %0, i1 false)
+ %3 = icmp eq i32 %0, 0
+ %4 = zext i1 %3 to i32
+ %5 = add nuw nsw i32 %2, %4
+ ret i32 %5
+}
+
+define i32 @remove_redundant_cmp_uge_lzcnt_i32(i32 %0) {
+; X64-LABEL: remove_redundant_cmp_uge_lzcnt_i32:
+; X64: # %bb.0:
+; X64-NEXT: lzcntl %edi, %eax
+; X64-NEXT: sbbl $-1, %eax
+; X64-NEXT: retq
+;
+; X86-LABEL: remove_redundant_cmp_uge_lzcnt_i32:
+; X86: # %bb.0:
+; X86-NEXT: lzcntl {{[0-9]+}}(%esp), %eax
+; X86-NEXT: sbbl $-1, %eax
+; X86-NEXT: retl
+ %2 = tail call i32 @llvm.ctlz.i32(i32 %0, i1 false)
+ %3 = icmp uge i32 %0, 1
+ %4 = zext i1 %3 to i32
+ %5 = add nuw nsw i32 %2, %4
+ ret i32 %5
+}
+
+define i32 @remove_redundant_cmp_ule_lzcnt_i32(i32 %0) {
+; X64-LABEL: remove_redundant_cmp_ule_lzcnt_i32:
+; X64: # %bb.0:
+; X64-NEXT: lzcntl %edi, %eax
+; X64-NEXT: cmpl $2, %edi
+; X64-NEXT: adcl $0, %eax
+; X64-NEXT: retq
+;
+; X86-LABEL: remove_redundant_cmp_ule_lzcnt_i32:
+; X86: # %bb.0:
+; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT: lzcntl %ecx, %eax
+; X86-NEXT: cmpl $2, %ecx
+; X86-NEXT: adcl $0, %eax
+; X86-NEXT: retl
+ %2 = tail call i32 @llvm.ctlz.i32(i32 %0, i1 false)
+ %3 = icmp ule i32 %0, 1
+ %4 = zext i1 %3 to i32
+ %5 = add nuw nsw i32 %2, %4
+ ret i32 %5
+}
+
+define i32 @remove_redundant_cmp_slt_lzcnt_i32(i32 %0) {
+; X64-LABEL: remove_redundant_cmp_slt_lzcnt_i32:
+; X64: # %bb.0:
+; X64-NEXT: lzcntl %edi, %ecx
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: testl %edi, %edi
+; X64-NEXT: setle %al
+; X64-NEXT: addl %ecx, %eax
+; X64-NEXT: retq
+;
+; X86-LABEL: remove_redundant_cmp_slt_lzcnt_i32:
+; X86: # %bb.0:
+; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT: lzcntl %ecx, %edx
+; X86-NEXT: xorl %eax, %eax
+; X86-NEXT: testl %ecx, %ecx
+; X86-NEXT: setle %al
+; X86-NEXT: addl %edx, %eax
+; X86-NEXT: retl
+ %2 = tail call i32 @llvm.ctlz.i32(i32 %0, i1 false)
+ %3 = icmp slt i32 %0, 1
+ %4 = zext i1 %3 to i32
+ %5 = add nuw nsw i32 %2, %4
+ ret i32 %5
+}
+
+define i32 @remove_redundant_cmp_sgt_lzcnt_i32(i32 %0) {
+; X64-LABEL: remove_redundant_cmp_sgt_lzcnt_i32:
+; X64: # %bb.0:
+; X64-NEXT: lzcntl %edi, %ecx
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: cmpl $2, %edi
+; X64-NEXT: setge %al
+; X64-NEXT: addl %ecx, %eax
+; X64-NEXT: retq
+;
+; X86-LABEL: remove_redundant_cmp_sgt_lzcnt_i32:
+; X86: # %bb.0:
+; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT: lzcntl %ecx, %edx
+; X86-NEXT: xorl %eax, %eax
+; X86-NEXT: cmpl $2, %ecx
+; X86-NEXT: setge %al
+; X86-NEXT: addl %edx, %eax
+; X86-NEXT: retl
+ %2 = tail call i32 @llvm.ctlz.i32(i32 %0, i1 false)
+ %3 = icmp sgt i32 %0, 1
+ %4 = zext i1 %3 to i32
+ %5 = add nuw nsw i32 %2, %4
+ ret i32 %5
+}
+
+define i16 @remove_redundant_cmp_lzcnt_i16(i16 %0) {
+; X64-LABEL: remove_redundant_cmp_lzcnt_i16:
+; X64: # %bb.0:
+; X64-NEXT: lzcntw %di, %ax
+; X64-NEXT: adcw $0, %ax
+; X64-NEXT: retq
+;
+; X86-LABEL: remove_redundant_cmp_lzcnt_i16:
+; X86: # %bb.0:
+; X86-NEXT: lzcntw {{[0-9]+}}(%esp), %ax
+; X86-NEXT: adcw $0, %ax
+; X86-NEXT: retl
+ %2 = tail call i16 @llvm.ctlz.i16(i16 %0, i1 false)
+ %3 = icmp eq i16 %0, 0
+ %4 = zext i1 %3 to i16
+ %5 = add nuw nsw i16 %2, %4
+ ret i16 %5
+}
+
+define i32 @remove_redundant_cmp_lzcnt_no_constant(i32 %0, i32 %1) {
+; X64-LABEL: remove_redundant_cmp_lzcnt_no_constant:
+; X64: # %bb.0:
+; X64-NEXT: lzcntl %edi, %ecx
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: cmpl %esi, %edi
+; X64-NEXT: sete %al
+; X64-NEXT: addl %ecx, %eax
+; X64-NEXT: retq
+;
+; X86-LABEL: remove_redundant_cmp_lzcnt_no_constant:
+; X86: # %bb.0:
+; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT: lzcntl %ecx, %edx
+; X86-NEXT: xorl %eax, %eax
+; X86-NEXT: cmpl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT: sete %al
+; X86-NEXT: addl %edx, %eax
+; X86-NEXT: retl
+ %3 = tail call i32 @llvm.ctlz.i32(i32 %0, i1 false)
+ %4 = icmp eq i32 %0, %1
+ %5 = zext i1 %4 to i32
+ %6 = add nuw nsw i32 %3, %5
+ ret i32 %6
+}
+
+define i32 @remove_redundant_cmp_lzcnt_wrong_const(i32 %0) {
+; X64-LABEL: remove_redundant_cmp_lzcnt_wrong_const:
+; X64: # %bb.0:
+; X64-NEXT: lzcntl %edi, %ecx
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: cmpl $2, %edi
+; X64-NEXT: sete %al
+; X64-NEXT: addl %ecx, %eax
+; X64-NEXT: retq
+;
+; X86-LABEL: remove_redundant_cmp_lzcnt_wrong_const:
+; X86: # %bb.0:
+; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT: lzcntl %ecx, %edx
+; X86-NEXT: xorl %eax, %eax
+; X86-NEXT: cmpl $2, %ecx
+; X86-NEXT: sete %al
+; X86-NEXT: addl %edx, %eax
+; X86-NEXT: retl
+ %2 = tail call i32 @llvm.ctlz.i32(i32 %0, i1 false)
+ %3 = icmp eq i32 %0, 2
+ %4 = zext i1 %3 to i32
+ %5 = add nuw nsw i32 %2, %4
+ ret i32 %5
+}
diff --git a/llvm/test/CodeGen/X86/remove-redundant-cmp-tzcnt-i64.ll b/llvm/test/CodeGen/X86/remove-redundant-cmp-tzcnt-i64.ll
new file mode 100644
index 0000000000000..a378156c639ef
--- /dev/null
+++ b/llvm/test/CodeGen/X86/remove-redundant-cmp-tzcnt-i64.ll
@@ -0,0 +1,74 @@
+; 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_eq_tzcnt_i64(i64 %0) {
+; CHECK-LABEL: remove_redundant_cmp_eq_tzcnt_i64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: tzcntq %rdi, %rax
+; CHECK-NEXT: adcq $0, %rax
+; CHECK-NEXT: retq
+ %2 = tail call i64 @llvm.cttz.i64(i64 %0, i1 false)
+ %3 = icmp eq i64 %0, 0
+ %4 = zext i1 %3 to i64
+ %5 = add nuw nsw i64 %2, %4
+ ret i64 %5
+}
+
+define i64 @remove_redundant_cmp_uge_tzcnt_i64(i64 %0) {
+; CHECK-LABEL: remove_redundant_cmp_uge_tzcnt_i64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: tzcntq %rdi, %rax
+; CHECK-NEXT: sbbq $-1, %rax
+; CHECK-NEXT: retq
+ %2 = tail call i64 @llvm.cttz.i64(i64 %0, i1 false)
+ %3 = icmp uge i64 %0, 1
+ %4 = zext i1 %3 to i64
+ %5 = add nuw nsw i64 %2, %4
+ ret i64 %5
+}
+
+define i64 @remove_redundant_cmp_ule_tzcnt_i64(i64 %0) {
+; CHECK-LABEL: remove_redundant_cmp_ule_tzcnt_i64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: tzcntq %rdi, %rax
+; CHECK-NEXT: cmpq $2, %rdi
+; CHECK-NEXT: adcq $0, %rax
+; CHECK-NEXT: retq
+ %2 = tail call i64 @llvm.cttz.i64(i64 %0, i1 false)
+ %3 = icmp ule i64 %0, 1
+ %4 = zext i1 %3 to i64
+ %5 = add nuw nsw i64 %2, %4
+ ret i64 %5
+}
+
+define i64 @remove_redundant_cmp_slt_tzcnt_i64(i64 %0) {
+; CHECK-LABEL: remove_redundant_cmp_slt_tzcnt_i64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: tzcntq %rdi, %rcx
+; CHECK-NEXT: xorl %eax, %eax
+; CHECK-NEXT: testq %rdi, %rdi
+; CHECK-NEXT: setle %al
+; CHECK-NEXT: addq %rcx, %rax
+; CHECK-NEXT: retq
+ %2 = tail call i64 @llvm.cttz.i64(i64 %0, i1 false)
+ %3 = icmp slt i64 %0, 1
+ %4 = zext i1 %3 to i64
+ %5 = add nuw nsw i64 %2, %4
+ ret i64 %5
+}
+
+define i64 @remove_redundant_cmp_sgt_tzcnt_i64(i64 %0) {
+; CHECK-LABEL: remove_redundant_cmp_sgt_tzcnt_i64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: tzcntq %rdi, %rcx
+; CHECK-NEXT: xorl %eax, %eax
+; CHECK-NEXT: cmpq $2, %rdi
+; CHECK-NEXT: setge %al
+; CHECK-NEXT: addq %rcx, %rax
+; CHECK-NEXT: retq
+ %2 = tail call i64 @llvm.cttz.i64(i64 %0, i1 false)
+ %3 = icmp sgt i64 %0, 1
+ %4 = zext i1 %3 to i64
+ %5 = add nuw nsw i64 %2, %4
+ ret i64 %5
+}
diff --git a/llvm/test/CodeGen/X86/remove-redundant-cmp-tzcnt.ll b/llvm/test/CodeGen/X86/remove-redundant-cmp-tzcnt.ll
new file mode 100644
index 0000000000000..0dee74e413066
--- /dev/null
+++ b/llvm/test/CodeGen/X86/remove-redundant-cmp-tzcnt.ll
@@ -0,0 +1,199 @@
+; 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 --check-prefix=X64
+; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+bmi,+lzcnt | FileCheck %s --check-prefix=X86
+
+define i32 @remove_redundant_cmp_ult_tzcnt_i32(i32 %0) {
+; X64-LABEL: remove_redundant_cmp_ult_tzcnt_i32:
+; X64: # %bb.0:
+; X64-NEXT: tzcntl %edi, %eax
+; X64-NEXT: adcl $0, %eax
+; X64-NEXT: retq
+;
+; X86-LABEL: remove_redundant_cmp_ult_tzcnt_i32:
+; X86: # %bb.0:
+; X86-NEXT: tzcntl {{[0-9]+}}(%esp), %eax
+; X86-NEXT: adcl $0, %eax
+; X86-NEXT: retl
+ %2 = tail call i32 @llvm.cttz.i32(i32 %0, i1 false)
+ %3 = icmp ult i32 %0, 1
+ %4 = zext i1 %3 to i32
+ %5 = add nuw nsw i32 %2, %4
+ ret i32 %5
+}
+
+define i32 @remove_redundant_cmp_ugt_tzcnt_i32(i32 %0) {
+; X64-LABEL: remove_redundant_cmp_ugt_tzcnt_i32:
+; X64: # %bb.0:
+; X64-NEXT: tzcntl %edi, %eax
+; X64-NEXT: cmpl $2, %edi
+; X64-NEXT: sbbl $-1, %eax
+; X64-NEXT: retq
+;
+; X86-LABEL: remove_redundant_cmp_ugt_tzcnt_i32:
+; X86: # %bb.0:
+; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT: tzcntl %ecx, %eax
+; X86-NEXT: cmpl $2, %ecx
+; X86-NEXT: sbbl $-1, %eax
+; X86-NEXT: retl
+ %2 = tail call i32 @llvm.cttz.i32(i32 %0, i1 false)
+ %3 = icmp ugt i32 %0, 1
+ %4 = zext i1 %3 to i32
+ %5 = add nuw nsw i32 %2, %4
+ ret i32 %5
+}
+
+define i32 @remove_redundant_cmp_ne_tzcnt_i32(i32 %0) {
+; X64-LABEL: remove_redundant_cmp_ne_tzcnt_i32:
+; X64: # %bb.0:
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: tzcntl %edi, %ecx
+; X64-NEXT: setne %al
+; X64-NEXT: addl %ecx, %eax
+; X64-NEXT: retq
+;
+; X86-LABEL: remove_redundant_cmp_ne_tzcnt_i32:
+; X86: # %bb.0:
+; X86-NEXT: xorl %eax, %eax
+; X86-NEXT: tzcntl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT: setne %al
+; X86-NEXT: addl %ecx, %eax
+; X86-NEXT: retl
+ %2 = tail call i32 @llvm.cttz.i32(i32 %0, i1 false)
+ %3 = icmp ne i32 %0, 1
+ %4 = zext i1 %3 to i32
+ %5 = add nuw nsw i32 %2, %4
+ ret i32 %5
+}
+
+define i32 @remove_redundant_cmp_sge_tzcnt_i32(i32 %0) {
+; X64-LABEL: remove_redundant_cmp_sge_tzcnt_i32:
+; X64: # %bb.0:
+; X64-NEXT: tzcntl %edi, %ecx
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: testl %edi, %edi
+; X64-NEXT: setg %al
+; X64-NEXT: addl %ecx, %eax
+; X64-NEXT: retq
+;
+; X86-LABEL: remove_redundant_cmp_sge_tzcnt_i32:
+; X86: # %bb.0:
+; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT: tzcntl %ecx, %edx
+; X86-NEXT: xorl %eax, %eax
+; X86-NEXT: testl %ecx, %ecx
+; X86-NEXT: setg %al
+; X86-NEXT: addl %edx, %eax
+; X86-NEXT: retl
+ %2 = tail call i32 @llvm.cttz.i32(i32 %0, i1 false)
+ %3 = icmp sge i32 %0, 1
+ %4 = zext i1 %3 to i32
+ %5 = add nuw nsw i32 %2, %4
+ ret i32 %5
+}
+
+define i32 @remove_redundant_cmp_sle_tzcnt_i32(i32 %0) {
+; X64-LABEL: remove_redundant_cmp_sle_tzcnt_i32:
+; X64: # %bb.0:
+; X64-NEXT: tzcntl %edi, %ecx
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: cmpl $2, %edi
+; X64-NEXT: setl %al
+; X64-NEXT: addl %ecx, %eax
+; X64-NEXT: retq
+;
+; X86-LABEL: remove_redundant_cmp_sle_tzcnt_i32:
+; X86: # %bb.0:
+; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT: tzcntl %ecx, %edx
+; X86-NEXT: xorl %eax, %eax
+; X86-NEXT: cmpl $2, %ecx
+; X86-NEXT: setl %al
+; X86-NEXT: addl %edx, %eax
+; X86-NEXT: retl
+ %2 = tail call i32 @llvm.cttz.i32(i32 %0, i1 false)
+ %3 = icmp sle i32 %0, 1
+ %4 = zext i1 %3 to i32
+ %5 = add nuw nsw i32 %2, %4
+ ret i32 %5
+}
+
+define i16 @remove_redundant_cmp_tzcnt_i16(i16 %0) {
+; X64-LABEL: remove_redundant_cmp_tzcnt_i16:
+; X64: # %bb.0:
+; X64-NEXT: movl %edi, %eax
+; X64-NEXT: orl $65536, %eax # imm = 0x10000
+; X64-NEXT: tzcntl %eax, %eax
+; X64-NEXT: cmpw $1, %di
+; X64-NEXT: adcw $0, %ax
+; X64-NEXT: # kill: def $ax killed $ax killed $eax
+; X64-NEXT: retq
+;
+; X86-LABEL: remove_redundant_cmp_tzcnt_i16:
+; X86: # %bb.0:
+; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT: movl %ecx, %eax
+; X86-NEXT: orl $65536, %eax # imm = 0x10000
+; X86-NEXT: tzcntl %eax, %eax
+; X86-NEXT: cmpw $1, %cx
+; X86-NEXT: adcw $0, %ax
+; X86-NEXT: # kill: def $ax killed $ax killed $eax
+; X86-NEXT: retl
+ %2 = tail call i16 @llvm.cttz.i16(i16 %0, i1 false)
+ %3 = icmp eq i16 %0, 0
+ %4 = zext i1 %3 to i16
+ %5 = add nuw nsw i16 %2, %4
+ ret i16 %5
+}
+
+define i32 @remove_redundant_cmp_tzcnt_no_constant(i32 %0, i32 %1) {
+; X64-LABEL: remove_redundant_cmp_tzcnt_no_constant:
+; X64: # %bb.0:
+; X64-NEXT: tzcntl %edi, %ecx
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: cmpl %esi, %edi
+; X64-NEXT: sete %al
+; X64-NEXT: addl %ecx, %eax
+; X64-NEXT: retq
+;
+; X86-LABEL: remove_redundant_cmp_tzcnt_no_constant:
+; X86: # %bb.0:
+; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT: tzcntl %ecx, %edx
+; X86-NEXT: xorl %eax, %eax
+; X86-NEXT: cmpl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT: sete %al
+; X86-NEXT: addl %edx, %eax
+; X86-NEXT: retl
+ %3 = tail call i32 @llvm.cttz.i32(i32 %0, i1 false)
+ %4 = icmp eq i32 %0, %1
+ %5 = zext i1 %4 to i32
+ %6 = add nuw nsw i32 %3, %5
+ ret i32 %6
+}
+
+define i32 @remove_redundant_cmp_tzcnt_wrong_const(i32 %0) {
+; X64-LABEL: remove_redundant_cmp_tzcnt_wrong_const:
+; X64: # %bb.0:
+; X64-NEXT: tzcntl %edi, %ecx
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: cmpl $2, %edi
+; X64-NEXT: sete %al
+; X64-NEXT: addl %ecx, %eax
+; X64-NEXT: retq
+;
+; X86-LABEL: remove_redundant_cmp_tzcnt_wrong_const:
+; X86: # %bb.0:
+; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT: tzcntl %ecx, %edx
+; X86-NEXT: xorl %eax, %eax
+; X86-NEXT: cmpl $2, %ecx
+; X86-NEXT: sete %al
+; X86-NEXT: addl %edx, %eax
+; X86-NEXT: retl
+ %2 = tail call i32 @llvm.cttz.i32(i32 %0, i1 false)
+ %3 = icmp eq i32 %0, 2
+ %4 = zext i1 %3 to i32
+ %5 = add nuw nsw i32 %2, %4
+ ret i32 %5
+}
More information about the llvm-commits
mailing list