[llvm] [X86] Try to shrink signed i64 compares if the input has enough one bits (PR #149719)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Jul 20 09:19:40 PDT 2025
https://github.com/AZero13 updated https://github.com/llvm/llvm-project/pull/149719
>From 44e4397abc827fab903992ad68ddca1964a81039 Mon Sep 17 00:00:00 2001
From: Rose <gfunni234 at gmail.com>
Date: Sun, 20 Jul 2025 11:33:52 -0400
Subject: [PATCH 1/3] Pre-commit test (NFC)
---
llvm/test/CodeGen/X86/cmp.ll | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/llvm/test/CodeGen/X86/cmp.ll b/llvm/test/CodeGen/X86/cmp.ll
index f3e141740b287..fb8a79571d98b 100644
--- a/llvm/test/CodeGen/X86/cmp.ll
+++ b/llvm/test/CodeGen/X86/cmp.ll
@@ -956,3 +956,16 @@ define i1 @fold_test_and_with_chain(ptr %x, ptr %y, i32 %z) {
store i32 %z, ptr %y
ret i1 %c
}
+
+define i1 @sext_mask(i32 %a) {
+; CHECK-LABEL: sext_mask:
+; CHECK: # %bb.0:
+; CHECK-NEXT: movslq %edi, %rax # encoding: [0x48,0x63,0xc7]
+; CHECK-NEXT: cmpq $-523, %rax # encoding: [0x48,0x3d,0xf5,0xfd,0xff,0xff]
+; CHECK-NEXT: # imm = 0xFDF5
+; CHECK-NEXT: setl %al # encoding: [0x0f,0x9c,0xc0]
+; CHECK-NEXT: retq # encoding: [0xc3]
+ %a64 = sext i32 %a to i64
+ %v1 = icmp slt i64 %a64, -523
+ ret i1 %v1
+}
>From 33959557a88036df057fdd9648af5a860f415144 Mon Sep 17 00:00:00 2001
From: Rose <gfunni234 at gmail.com>
Date: Sun, 20 Jul 2025 12:00:34 -0400
Subject: [PATCH 2/3] [X86] Try to shrink signed i64 compares if the input has
enough one bits
---
llvm/lib/Target/X86/X86ISelLowering.cpp | 16 +++++++++++++++-
llvm/test/CodeGen/X86/cmp.ll | 3 +--
2 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index d91ea1ea1bb1b..5d5d0c23376c7 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -23479,7 +23479,6 @@ static SDValue EmitCmp(SDValue Op0, SDValue Op1, X86::CondCode X86CC,
}
// Try to shrink i64 compares if the input has enough zero bits.
- // TODO: Add sign-bits equivalent for isX86CCSigned(X86CC)?
if (CmpVT == MVT::i64 && !isX86CCSigned(X86CC) &&
Op0.hasOneUse() && // Hacky way to not break CSE opportunities with sub.
DAG.MaskedValueIsZero(Op1, APInt::getHighBitsSet(64, 32)) &&
@@ -23489,6 +23488,21 @@ static SDValue EmitCmp(SDValue Op0, SDValue Op1, X86::CondCode X86CC,
Op1 = DAG.getNode(ISD::TRUNCATE, dl, CmpVT, Op1);
}
+ // Try to shrink signed i64 compares if the input has enough one bits.
+ // Or the input is sign extended from a 32-bit value.
+ if (CmpVT == MVT::i64 && isX86CCSigned(X86CC) &&
+ Op0.hasOneUse() && // Hacky way to not break CSE opportunities with sub.
+ (DAG.MaskedValueIsAllOnes(Op1, APInt::getHighBitsSet(64, 32)) ||
+ Op1.getOpcode() == ISD::SIGN_EXTEND ||
+ Op1.getOpcode() == ISD::SIGN_EXTEND_INREG) &&
+ (DAG.MaskedValueIsAllOnes(Op0, APInt::getHighBitsSet(64, 32)) ||
+ Op0.getOpcode() == ISD::SIGN_EXTEND ||
+ Op0.getOpcode() == ISD::SIGN_EXTEND_INREG)) {
+ CmpVT = MVT::i32;
+ Op0 = DAG.getNode(ISD::TRUNCATE, dl, CmpVT, Op0);
+ Op1 = DAG.getNode(ISD::TRUNCATE, dl, CmpVT, Op1);
+ }
+
// 0-x == y --> x+y == 0
// 0-x != y --> x+y != 0
if (Op0.getOpcode() == ISD::SUB && isNullConstant(Op0.getOperand(0)) &&
diff --git a/llvm/test/CodeGen/X86/cmp.ll b/llvm/test/CodeGen/X86/cmp.ll
index fb8a79571d98b..d71a7adafc652 100644
--- a/llvm/test/CodeGen/X86/cmp.ll
+++ b/llvm/test/CodeGen/X86/cmp.ll
@@ -960,8 +960,7 @@ define i1 @fold_test_and_with_chain(ptr %x, ptr %y, i32 %z) {
define i1 @sext_mask(i32 %a) {
; CHECK-LABEL: sext_mask:
; CHECK: # %bb.0:
-; CHECK-NEXT: movslq %edi, %rax # encoding: [0x48,0x63,0xc7]
-; CHECK-NEXT: cmpq $-523, %rax # encoding: [0x48,0x3d,0xf5,0xfd,0xff,0xff]
+; CHECK-NEXT: cmpl $-523, %edi # encoding: [0x81,0xff,0xf5,0xfd,0xff,0xff]
; CHECK-NEXT: # imm = 0xFDF5
; CHECK-NEXT: setl %al # encoding: [0x0f,0x9c,0xc0]
; CHECK-NEXT: retq # encoding: [0xc3]
>From 77557197317ec2b64ae82562a95477d85410847b Mon Sep 17 00:00:00 2001
From: Rose <gfunni234 at gmail.com>
Date: Sun, 20 Jul 2025 12:19:27 -0400
Subject: [PATCH 3/3] Comments
---
llvm/lib/Target/X86/X86ISelLowering.cpp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 5d5d0c23376c7..909085a647be8 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -23490,6 +23490,8 @@ static SDValue EmitCmp(SDValue Op0, SDValue Op1, X86::CondCode X86CC,
// Try to shrink signed i64 compares if the input has enough one bits.
// Or the input is sign extended from a 32-bit value.
+ // TODO: Should we peek through freeze?
+ // TODO: Is SIGN_EXTEND_INREG needed here?
if (CmpVT == MVT::i64 && isX86CCSigned(X86CC) &&
Op0.hasOneUse() && // Hacky way to not break CSE opportunities with sub.
(DAG.MaskedValueIsAllOnes(Op1, APInt::getHighBitsSet(64, 32)) ||
More information about the llvm-commits
mailing list