Skip to content

Commit a4e4758

Browse files
authored
[ExpandMemCmp] Recognize canonical form of (icmp sle/sge X, 0) in getMemCmpOneBlock. (#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.
1 parent d37aa51 commit a4e4758

File tree

4 files changed

+20
-46
lines changed

4 files changed

+20
-46
lines changed

llvm/lib/CodeGen/ExpandMemCmp.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -680,6 +680,14 @@ Value *MemCmpExpansion::getMemCmpOneBlock() {
680680
m_SpecificInt(CI->getType()->getIntegerBitWidth() - 1)))) {
681681
Pred = ICmpInst::ICMP_SLT;
682682
NeedsZExt = true;
683+
} else if (match(UI, m_SpecificICmp(ICmpInst::ICMP_SGT, m_Specific(CI),
684+
m_AllOnes()))) {
685+
// Adjust predicate as if it compared with 0.
686+
Pred = ICmpInst::ICMP_SGE;
687+
} else if (match(UI, m_SpecificICmp(ICmpInst::ICMP_SLT, m_Specific(CI),
688+
m_One()))) {
689+
// Adjust predicate as if it compared with 0.
690+
Pred = ICmpInst::ICMP_SLE;
683691
} else {
684692
// In case of a successful match this call will set `Pred` variable
685693
match(UI, m_ICmp(Pred, m_Specific(CI), m_Zero()));

llvm/test/CodeGen/AArch64/memcmp.ll

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -265,10 +265,7 @@ define i1 @length4_le(ptr %X, ptr %Y) nounwind {
265265
; CHECK-NEXT: rev w8, w8
266266
; CHECK-NEXT: rev w9, w9
267267
; CHECK-NEXT: cmp w8, w9
268-
; CHECK-NEXT: cset w8, hi
269-
; CHECK-NEXT: csinv w8, w8, wzr, hs
270-
; CHECK-NEXT: cmp w8, #1
271-
; CHECK-NEXT: cset w0, lt
268+
; CHECK-NEXT: cset w0, ls
272269
; CHECK-NEXT: ret
273270
%m = tail call i32 @memcmp(ptr %X, ptr %Y, i64 4) nounwind
274271
%c = icmp slt i32 %m, 1
@@ -283,10 +280,7 @@ define i1 @length4_ge(ptr %X, ptr %Y) nounwind {
283280
; CHECK-NEXT: rev w8, w8
284281
; CHECK-NEXT: rev w9, w9
285282
; CHECK-NEXT: cmp w8, w9
286-
; CHECK-NEXT: cset w8, hi
287-
; CHECK-NEXT: csinv w8, w8, wzr, hs
288-
; CHECK-NEXT: mvn w8, w8
289-
; CHECK-NEXT: lsr w0, w8, #31
283+
; CHECK-NEXT: cset w0, hs
290284
; CHECK-NEXT: ret
291285
%m = tail call i32 @memcmp(ptr %X, ptr %Y, i64 4) nounwind
292286
%c = icmp sgt i32 %m, -1

llvm/test/CodeGen/RISCV/memcmp.ll

Lines changed: 8 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -6664,10 +6664,8 @@ define i1 @memcmp_le_zero(ptr %s1, ptr %s2) nounwind {
66646664
; CHECK-UNALIGNED-RV32-ZBB-NEXT: lw a1, 0(a1)
66656665
; CHECK-UNALIGNED-RV32-ZBB-NEXT: rev8 a0, a0
66666666
; CHECK-UNALIGNED-RV32-ZBB-NEXT: rev8 a1, a1
6667-
; CHECK-UNALIGNED-RV32-ZBB-NEXT: sltu a2, a0, a1
66686667
; CHECK-UNALIGNED-RV32-ZBB-NEXT: sltu a0, a1, a0
6669-
; CHECK-UNALIGNED-RV32-ZBB-NEXT: sub a0, a0, a2
6670-
; CHECK-UNALIGNED-RV32-ZBB-NEXT: slti a0, a0, 1
6668+
; CHECK-UNALIGNED-RV32-ZBB-NEXT: xori a0, a0, 1
66716669
; CHECK-UNALIGNED-RV32-ZBB-NEXT: ret
66726670
;
66736671
; CHECK-UNALIGNED-RV64-ZBB-LABEL: memcmp_le_zero:
@@ -6678,10 +6676,8 @@ define i1 @memcmp_le_zero(ptr %s1, ptr %s2) nounwind {
66786676
; CHECK-UNALIGNED-RV64-ZBB-NEXT: rev8 a1, a1
66796677
; CHECK-UNALIGNED-RV64-ZBB-NEXT: srli a0, a0, 32
66806678
; CHECK-UNALIGNED-RV64-ZBB-NEXT: srli a1, a1, 32
6681-
; CHECK-UNALIGNED-RV64-ZBB-NEXT: sltu a2, a0, a1
66826679
; CHECK-UNALIGNED-RV64-ZBB-NEXT: sltu a0, a1, a0
6683-
; CHECK-UNALIGNED-RV64-ZBB-NEXT: sub a0, a0, a2
6684-
; CHECK-UNALIGNED-RV64-ZBB-NEXT: slti a0, a0, 1
6680+
; CHECK-UNALIGNED-RV64-ZBB-NEXT: xori a0, a0, 1
66856681
; CHECK-UNALIGNED-RV64-ZBB-NEXT: ret
66866682
;
66876683
; CHECK-UNALIGNED-RV32-ZBKB-LABEL: memcmp_le_zero:
@@ -6690,10 +6686,8 @@ define i1 @memcmp_le_zero(ptr %s1, ptr %s2) nounwind {
66906686
; CHECK-UNALIGNED-RV32-ZBKB-NEXT: lw a1, 0(a1)
66916687
; CHECK-UNALIGNED-RV32-ZBKB-NEXT: rev8 a0, a0
66926688
; CHECK-UNALIGNED-RV32-ZBKB-NEXT: rev8 a1, a1
6693-
; CHECK-UNALIGNED-RV32-ZBKB-NEXT: sltu a2, a0, a1
66946689
; CHECK-UNALIGNED-RV32-ZBKB-NEXT: sltu a0, a1, a0
6695-
; CHECK-UNALIGNED-RV32-ZBKB-NEXT: sub a0, a0, a2
6696-
; CHECK-UNALIGNED-RV32-ZBKB-NEXT: slti a0, a0, 1
6690+
; CHECK-UNALIGNED-RV32-ZBKB-NEXT: xori a0, a0, 1
66976691
; CHECK-UNALIGNED-RV32-ZBKB-NEXT: ret
66986692
;
66996693
; CHECK-UNALIGNED-RV64-ZBKB-LABEL: memcmp_le_zero:
@@ -6704,10 +6698,8 @@ define i1 @memcmp_le_zero(ptr %s1, ptr %s2) nounwind {
67046698
; CHECK-UNALIGNED-RV64-ZBKB-NEXT: rev8 a1, a1
67056699
; CHECK-UNALIGNED-RV64-ZBKB-NEXT: srli a0, a0, 32
67066700
; CHECK-UNALIGNED-RV64-ZBKB-NEXT: srli a1, a1, 32
6707-
; CHECK-UNALIGNED-RV64-ZBKB-NEXT: sltu a2, a0, a1
67086701
; CHECK-UNALIGNED-RV64-ZBKB-NEXT: sltu a0, a1, a0
6709-
; CHECK-UNALIGNED-RV64-ZBKB-NEXT: sub a0, a0, a2
6710-
; CHECK-UNALIGNED-RV64-ZBKB-NEXT: slti a0, a0, 1
6702+
; CHECK-UNALIGNED-RV64-ZBKB-NEXT: xori a0, a0, 1
67116703
; CHECK-UNALIGNED-RV64-ZBKB-NEXT: ret
67126704
;
67136705
; CHECK-UNALIGNED-RV32-V-LABEL: memcmp_le_zero:
@@ -6864,10 +6856,7 @@ define i1 @memcmp_ge_zero(ptr %s1, ptr %s2) nounwind {
68646856
; CHECK-UNALIGNED-RV32-ZBB-NEXT: lw a1, 0(a1)
68656857
; CHECK-UNALIGNED-RV32-ZBB-NEXT: rev8 a0, a0
68666858
; CHECK-UNALIGNED-RV32-ZBB-NEXT: rev8 a1, a1
6867-
; CHECK-UNALIGNED-RV32-ZBB-NEXT: sltu a2, a0, a1
6868-
; CHECK-UNALIGNED-RV32-ZBB-NEXT: sltu a0, a1, a0
6869-
; CHECK-UNALIGNED-RV32-ZBB-NEXT: sub a0, a0, a2
6870-
; CHECK-UNALIGNED-RV32-ZBB-NEXT: slti a0, a0, 0
6859+
; CHECK-UNALIGNED-RV32-ZBB-NEXT: sltu a0, a0, a1
68716860
; CHECK-UNALIGNED-RV32-ZBB-NEXT: xori a0, a0, 1
68726861
; CHECK-UNALIGNED-RV32-ZBB-NEXT: ret
68736862
;
@@ -6879,10 +6868,7 @@ define i1 @memcmp_ge_zero(ptr %s1, ptr %s2) nounwind {
68796868
; CHECK-UNALIGNED-RV64-ZBB-NEXT: rev8 a1, a1
68806869
; CHECK-UNALIGNED-RV64-ZBB-NEXT: srli a0, a0, 32
68816870
; CHECK-UNALIGNED-RV64-ZBB-NEXT: srli a1, a1, 32
6882-
; CHECK-UNALIGNED-RV64-ZBB-NEXT: sltu a2, a0, a1
6883-
; CHECK-UNALIGNED-RV64-ZBB-NEXT: sltu a0, a1, a0
6884-
; CHECK-UNALIGNED-RV64-ZBB-NEXT: sub a0, a0, a2
6885-
; CHECK-UNALIGNED-RV64-ZBB-NEXT: slti a0, a0, 0
6871+
; CHECK-UNALIGNED-RV64-ZBB-NEXT: sltu a0, a0, a1
68866872
; CHECK-UNALIGNED-RV64-ZBB-NEXT: xori a0, a0, 1
68876873
; CHECK-UNALIGNED-RV64-ZBB-NEXT: ret
68886874
;
@@ -6892,10 +6878,7 @@ define i1 @memcmp_ge_zero(ptr %s1, ptr %s2) nounwind {
68926878
; CHECK-UNALIGNED-RV32-ZBKB-NEXT: lw a1, 0(a1)
68936879
; CHECK-UNALIGNED-RV32-ZBKB-NEXT: rev8 a0, a0
68946880
; CHECK-UNALIGNED-RV32-ZBKB-NEXT: rev8 a1, a1
6895-
; CHECK-UNALIGNED-RV32-ZBKB-NEXT: sltu a2, a0, a1
6896-
; CHECK-UNALIGNED-RV32-ZBKB-NEXT: sltu a0, a1, a0
6897-
; CHECK-UNALIGNED-RV32-ZBKB-NEXT: sub a0, a0, a2
6898-
; CHECK-UNALIGNED-RV32-ZBKB-NEXT: slti a0, a0, 0
6881+
; CHECK-UNALIGNED-RV32-ZBKB-NEXT: sltu a0, a0, a1
68996882
; CHECK-UNALIGNED-RV32-ZBKB-NEXT: xori a0, a0, 1
69006883
; CHECK-UNALIGNED-RV32-ZBKB-NEXT: ret
69016884
;
@@ -6907,10 +6890,7 @@ define i1 @memcmp_ge_zero(ptr %s1, ptr %s2) nounwind {
69076890
; CHECK-UNALIGNED-RV64-ZBKB-NEXT: rev8 a1, a1
69086891
; CHECK-UNALIGNED-RV64-ZBKB-NEXT: srli a0, a0, 32
69096892
; CHECK-UNALIGNED-RV64-ZBKB-NEXT: srli a1, a1, 32
6910-
; CHECK-UNALIGNED-RV64-ZBKB-NEXT: sltu a2, a0, a1
6911-
; CHECK-UNALIGNED-RV64-ZBKB-NEXT: sltu a0, a1, a0
6912-
; CHECK-UNALIGNED-RV64-ZBKB-NEXT: sub a0, a0, a2
6913-
; CHECK-UNALIGNED-RV64-ZBKB-NEXT: slti a0, a0, 0
6893+
; CHECK-UNALIGNED-RV64-ZBKB-NEXT: sltu a0, a0, a1
69146894
; CHECK-UNALIGNED-RV64-ZBKB-NEXT: xori a0, a0, 1
69156895
; CHECK-UNALIGNED-RV64-ZBKB-NEXT: ret
69166896
;

llvm/test/CodeGen/X86/memcmp.ll

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -268,11 +268,7 @@ define i1 @length4_le(ptr %X, ptr %Y) nounwind {
268268
; X64-NEXT: bswapl %eax
269269
; X64-NEXT: bswapl %ecx
270270
; X64-NEXT: cmpl %ecx, %eax
271-
; X64-NEXT: seta %al
272-
; X64-NEXT: sbbb $0, %al
273-
; X64-NEXT: movsbl %al, %eax
274-
; X64-NEXT: testl %eax, %eax
275-
; X64-NEXT: setle %al
271+
; X64-NEXT: setbe %al
276272
; X64-NEXT: retq
277273
%m = tail call i32 @memcmp(ptr %X, ptr %Y, i64 4) nounwind
278274
%c = icmp slt i32 %m, 1
@@ -287,11 +283,7 @@ define i1 @length4_ge(ptr %X, ptr %Y) nounwind {
287283
; X64-NEXT: bswapl %eax
288284
; X64-NEXT: bswapl %ecx
289285
; X64-NEXT: cmpl %ecx, %eax
290-
; X64-NEXT: seta %al
291-
; X64-NEXT: sbbb $0, %al
292-
; X64-NEXT: movsbl %al, %eax
293-
; X64-NEXT: testl %eax, %eax
294-
; X64-NEXT: setns %al
286+
; X64-NEXT: setae %al
295287
; X64-NEXT: retq
296288
%m = tail call i32 @memcmp(ptr %X, ptr %Y, i64 4) nounwind
297289
%c = icmp sgt i32 %m, -1

0 commit comments

Comments
 (0)