Skip to content

Commit

Permalink
[ExpandMemCmp] Recognize canonical form of (icmp sle/sge X, 0) in get…
Browse files Browse the repository at this point in the history
…MemCmpOneBlock. (llvm#121540)

This code recognizes special cases where the result of memcmp is
compared with 0. If the compare is sle/sge, then InstCombine
canonicalizes to (icmp slt X, 1) or (icmp sgt X, -1). We should
recognize those patterns too.
  • Loading branch information
topperc authored Jan 3, 2025
1 parent d37aa51 commit a4e4758
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 46 deletions.
8 changes: 8 additions & 0 deletions llvm/lib/CodeGen/ExpandMemCmp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -680,6 +680,14 @@ Value *MemCmpExpansion::getMemCmpOneBlock() {
m_SpecificInt(CI->getType()->getIntegerBitWidth() - 1)))) {
Pred = ICmpInst::ICMP_SLT;
NeedsZExt = true;
} else if (match(UI, m_SpecificICmp(ICmpInst::ICMP_SGT, m_Specific(CI),
m_AllOnes()))) {
// Adjust predicate as if it compared with 0.
Pred = ICmpInst::ICMP_SGE;
} else if (match(UI, m_SpecificICmp(ICmpInst::ICMP_SLT, m_Specific(CI),
m_One()))) {
// Adjust predicate as if it compared with 0.
Pred = ICmpInst::ICMP_SLE;
} else {
// In case of a successful match this call will set `Pred` variable
match(UI, m_ICmp(Pred, m_Specific(CI), m_Zero()));
Expand Down
10 changes: 2 additions & 8 deletions llvm/test/CodeGen/AArch64/memcmp.ll
Original file line number Diff line number Diff line change
Expand Up @@ -265,10 +265,7 @@ define i1 @length4_le(ptr %X, ptr %Y) nounwind {
; CHECK-NEXT: rev w8, w8
; CHECK-NEXT: rev w9, w9
; CHECK-NEXT: cmp w8, w9
; CHECK-NEXT: cset w8, hi
; CHECK-NEXT: csinv w8, w8, wzr, hs
; CHECK-NEXT: cmp w8, #1
; CHECK-NEXT: cset w0, lt
; CHECK-NEXT: cset w0, ls
; CHECK-NEXT: ret
%m = tail call i32 @memcmp(ptr %X, ptr %Y, i64 4) nounwind
%c = icmp slt i32 %m, 1
Expand All @@ -283,10 +280,7 @@ define i1 @length4_ge(ptr %X, ptr %Y) nounwind {
; CHECK-NEXT: rev w8, w8
; CHECK-NEXT: rev w9, w9
; CHECK-NEXT: cmp w8, w9
; CHECK-NEXT: cset w8, hi
; CHECK-NEXT: csinv w8, w8, wzr, hs
; CHECK-NEXT: mvn w8, w8
; CHECK-NEXT: lsr w0, w8, #31
; CHECK-NEXT: cset w0, hs
; CHECK-NEXT: ret
%m = tail call i32 @memcmp(ptr %X, ptr %Y, i64 4) nounwind
%c = icmp sgt i32 %m, -1
Expand Down
36 changes: 8 additions & 28 deletions llvm/test/CodeGen/RISCV/memcmp.ll
Original file line number Diff line number Diff line change
Expand Up @@ -6664,10 +6664,8 @@ define i1 @memcmp_le_zero(ptr %s1, ptr %s2) nounwind {
; CHECK-UNALIGNED-RV32-ZBB-NEXT: lw a1, 0(a1)
; CHECK-UNALIGNED-RV32-ZBB-NEXT: rev8 a0, a0
; CHECK-UNALIGNED-RV32-ZBB-NEXT: rev8 a1, a1
; CHECK-UNALIGNED-RV32-ZBB-NEXT: sltu a2, a0, a1
; CHECK-UNALIGNED-RV32-ZBB-NEXT: sltu a0, a1, a0
; CHECK-UNALIGNED-RV32-ZBB-NEXT: sub a0, a0, a2
; CHECK-UNALIGNED-RV32-ZBB-NEXT: slti a0, a0, 1
; CHECK-UNALIGNED-RV32-ZBB-NEXT: xori a0, a0, 1
; CHECK-UNALIGNED-RV32-ZBB-NEXT: ret
;
; CHECK-UNALIGNED-RV64-ZBB-LABEL: memcmp_le_zero:
Expand All @@ -6678,10 +6676,8 @@ define i1 @memcmp_le_zero(ptr %s1, ptr %s2) nounwind {
; CHECK-UNALIGNED-RV64-ZBB-NEXT: rev8 a1, a1
; CHECK-UNALIGNED-RV64-ZBB-NEXT: srli a0, a0, 32
; CHECK-UNALIGNED-RV64-ZBB-NEXT: srli a1, a1, 32
; CHECK-UNALIGNED-RV64-ZBB-NEXT: sltu a2, a0, a1
; CHECK-UNALIGNED-RV64-ZBB-NEXT: sltu a0, a1, a0
; CHECK-UNALIGNED-RV64-ZBB-NEXT: sub a0, a0, a2
; CHECK-UNALIGNED-RV64-ZBB-NEXT: slti a0, a0, 1
; CHECK-UNALIGNED-RV64-ZBB-NEXT: xori a0, a0, 1
; CHECK-UNALIGNED-RV64-ZBB-NEXT: ret
;
; CHECK-UNALIGNED-RV32-ZBKB-LABEL: memcmp_le_zero:
Expand All @@ -6690,10 +6686,8 @@ define i1 @memcmp_le_zero(ptr %s1, ptr %s2) nounwind {
; CHECK-UNALIGNED-RV32-ZBKB-NEXT: lw a1, 0(a1)
; CHECK-UNALIGNED-RV32-ZBKB-NEXT: rev8 a0, a0
; CHECK-UNALIGNED-RV32-ZBKB-NEXT: rev8 a1, a1
; CHECK-UNALIGNED-RV32-ZBKB-NEXT: sltu a2, a0, a1
; CHECK-UNALIGNED-RV32-ZBKB-NEXT: sltu a0, a1, a0
; CHECK-UNALIGNED-RV32-ZBKB-NEXT: sub a0, a0, a2
; CHECK-UNALIGNED-RV32-ZBKB-NEXT: slti a0, a0, 1
; CHECK-UNALIGNED-RV32-ZBKB-NEXT: xori a0, a0, 1
; CHECK-UNALIGNED-RV32-ZBKB-NEXT: ret
;
; CHECK-UNALIGNED-RV64-ZBKB-LABEL: memcmp_le_zero:
Expand All @@ -6704,10 +6698,8 @@ define i1 @memcmp_le_zero(ptr %s1, ptr %s2) nounwind {
; CHECK-UNALIGNED-RV64-ZBKB-NEXT: rev8 a1, a1
; CHECK-UNALIGNED-RV64-ZBKB-NEXT: srli a0, a0, 32
; CHECK-UNALIGNED-RV64-ZBKB-NEXT: srli a1, a1, 32
; CHECK-UNALIGNED-RV64-ZBKB-NEXT: sltu a2, a0, a1
; CHECK-UNALIGNED-RV64-ZBKB-NEXT: sltu a0, a1, a0
; CHECK-UNALIGNED-RV64-ZBKB-NEXT: sub a0, a0, a2
; CHECK-UNALIGNED-RV64-ZBKB-NEXT: slti a0, a0, 1
; CHECK-UNALIGNED-RV64-ZBKB-NEXT: xori a0, a0, 1
; CHECK-UNALIGNED-RV64-ZBKB-NEXT: ret
;
; CHECK-UNALIGNED-RV32-V-LABEL: memcmp_le_zero:
Expand Down Expand Up @@ -6864,10 +6856,7 @@ define i1 @memcmp_ge_zero(ptr %s1, ptr %s2) nounwind {
; CHECK-UNALIGNED-RV32-ZBB-NEXT: lw a1, 0(a1)
; CHECK-UNALIGNED-RV32-ZBB-NEXT: rev8 a0, a0
; CHECK-UNALIGNED-RV32-ZBB-NEXT: rev8 a1, a1
; CHECK-UNALIGNED-RV32-ZBB-NEXT: sltu a2, a0, a1
; CHECK-UNALIGNED-RV32-ZBB-NEXT: sltu a0, a1, a0
; CHECK-UNALIGNED-RV32-ZBB-NEXT: sub a0, a0, a2
; CHECK-UNALIGNED-RV32-ZBB-NEXT: slti a0, a0, 0
; CHECK-UNALIGNED-RV32-ZBB-NEXT: sltu a0, a0, a1
; CHECK-UNALIGNED-RV32-ZBB-NEXT: xori a0, a0, 1
; CHECK-UNALIGNED-RV32-ZBB-NEXT: ret
;
Expand All @@ -6879,10 +6868,7 @@ define i1 @memcmp_ge_zero(ptr %s1, ptr %s2) nounwind {
; CHECK-UNALIGNED-RV64-ZBB-NEXT: rev8 a1, a1
; CHECK-UNALIGNED-RV64-ZBB-NEXT: srli a0, a0, 32
; CHECK-UNALIGNED-RV64-ZBB-NEXT: srli a1, a1, 32
; CHECK-UNALIGNED-RV64-ZBB-NEXT: sltu a2, a0, a1
; CHECK-UNALIGNED-RV64-ZBB-NEXT: sltu a0, a1, a0
; CHECK-UNALIGNED-RV64-ZBB-NEXT: sub a0, a0, a2
; CHECK-UNALIGNED-RV64-ZBB-NEXT: slti a0, a0, 0
; CHECK-UNALIGNED-RV64-ZBB-NEXT: sltu a0, a0, a1
; CHECK-UNALIGNED-RV64-ZBB-NEXT: xori a0, a0, 1
; CHECK-UNALIGNED-RV64-ZBB-NEXT: ret
;
Expand All @@ -6892,10 +6878,7 @@ define i1 @memcmp_ge_zero(ptr %s1, ptr %s2) nounwind {
; CHECK-UNALIGNED-RV32-ZBKB-NEXT: lw a1, 0(a1)
; CHECK-UNALIGNED-RV32-ZBKB-NEXT: rev8 a0, a0
; CHECK-UNALIGNED-RV32-ZBKB-NEXT: rev8 a1, a1
; CHECK-UNALIGNED-RV32-ZBKB-NEXT: sltu a2, a0, a1
; CHECK-UNALIGNED-RV32-ZBKB-NEXT: sltu a0, a1, a0
; CHECK-UNALIGNED-RV32-ZBKB-NEXT: sub a0, a0, a2
; CHECK-UNALIGNED-RV32-ZBKB-NEXT: slti a0, a0, 0
; CHECK-UNALIGNED-RV32-ZBKB-NEXT: sltu a0, a0, a1
; CHECK-UNALIGNED-RV32-ZBKB-NEXT: xori a0, a0, 1
; CHECK-UNALIGNED-RV32-ZBKB-NEXT: ret
;
Expand All @@ -6907,10 +6890,7 @@ define i1 @memcmp_ge_zero(ptr %s1, ptr %s2) nounwind {
; CHECK-UNALIGNED-RV64-ZBKB-NEXT: rev8 a1, a1
; CHECK-UNALIGNED-RV64-ZBKB-NEXT: srli a0, a0, 32
; CHECK-UNALIGNED-RV64-ZBKB-NEXT: srli a1, a1, 32
; CHECK-UNALIGNED-RV64-ZBKB-NEXT: sltu a2, a0, a1
; CHECK-UNALIGNED-RV64-ZBKB-NEXT: sltu a0, a1, a0
; CHECK-UNALIGNED-RV64-ZBKB-NEXT: sub a0, a0, a2
; CHECK-UNALIGNED-RV64-ZBKB-NEXT: slti a0, a0, 0
; CHECK-UNALIGNED-RV64-ZBKB-NEXT: sltu a0, a0, a1
; CHECK-UNALIGNED-RV64-ZBKB-NEXT: xori a0, a0, 1
; CHECK-UNALIGNED-RV64-ZBKB-NEXT: ret
;
Expand Down
12 changes: 2 additions & 10 deletions llvm/test/CodeGen/X86/memcmp.ll
Original file line number Diff line number Diff line change
Expand Up @@ -268,11 +268,7 @@ define i1 @length4_le(ptr %X, ptr %Y) nounwind {
; X64-NEXT: bswapl %eax
; X64-NEXT: bswapl %ecx
; X64-NEXT: cmpl %ecx, %eax
; X64-NEXT: seta %al
; X64-NEXT: sbbb $0, %al
; X64-NEXT: movsbl %al, %eax
; X64-NEXT: testl %eax, %eax
; X64-NEXT: setle %al
; X64-NEXT: setbe %al
; X64-NEXT: retq
%m = tail call i32 @memcmp(ptr %X, ptr %Y, i64 4) nounwind
%c = icmp slt i32 %m, 1
Expand All @@ -287,11 +283,7 @@ define i1 @length4_ge(ptr %X, ptr %Y) nounwind {
; X64-NEXT: bswapl %eax
; X64-NEXT: bswapl %ecx
; X64-NEXT: cmpl %ecx, %eax
; X64-NEXT: seta %al
; X64-NEXT: sbbb $0, %al
; X64-NEXT: movsbl %al, %eax
; X64-NEXT: testl %eax, %eax
; X64-NEXT: setns %al
; X64-NEXT: setae %al
; X64-NEXT: retq
%m = tail call i32 @memcmp(ptr %X, ptr %Y, i64 4) nounwind
%c = icmp sgt i32 %m, -1
Expand Down

0 comments on commit a4e4758

Please sign in to comment.