[llvm] [X86] Port shouldBeAdjustedToZero to simplify TranslateX86CC (NFC) (PR #149742)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Jul 20 14:37:52 PDT 2025
https://github.com/AZero13 created https://github.com/llvm/llvm-project/pull/149742
This means we have a helper function to optimize by adjusting to 0 much like on AArch64
>From 9e05d5218954181ce915b7b3729ee2834e6a0baf Mon Sep 17 00:00:00 2001
From: Rose <gfunni234 at gmail.com>
Date: Sun, 20 Jul 2025 17:33:58 -0400
Subject: [PATCH] [X86] Port shouldBeAdjustedToZero to simplify TranslateX86CC
(NFC)
This means we have a helper function to optimize by adjusting to 0 much like on AArch64
---
llvm/lib/Target/X86/X86ISelLowering.cpp | 52 ++++++++++++++++++++-----
1 file changed, 42 insertions(+), 10 deletions(-)
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index d91ea1ea1bb1b..1ef608b3860f4 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -2977,6 +2977,23 @@ static X86::CondCode TranslateIntegerX86CC(ISD::CondCode SetCCOpcode) {
}
}
+// TranslateX86CC() converts comparison with one or negative one to comparison
+// with 0. Note that this only works for signed comparisons because of how ANDS
+// works.
+static bool shouldBeAdjustedToZero(SDValue LHS, APInt C, ISD::CondCode &CC) {
+ if (C.isOne() && (CC == ISD::SETLT || CC == ISD::SETGE)) {
+ CC = (CC == ISD::SETLT) ? ISD::SETLE : ISD::SETGT;
+ return true;
+ }
+
+ if (C.isAllOnes() && (CC == ISD::SETLE || CC == ISD::SETGT)) {
+ CC = (CC == ISD::SETLE) ? ISD::SETLT : ISD::SETGE;
+ return true;
+ }
+
+ return false;
+}
+
/// Do a one-to-one translation of a ISD::CondCode to the X86-specific
/// condition code, returning the condition code and the LHS/RHS of the
/// comparison to make.
@@ -2985,24 +3002,39 @@ static X86::CondCode TranslateX86CC(ISD::CondCode SetCCOpcode, const SDLoc &DL,
SelectionDAG &DAG) {
if (!isFP) {
if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS)) {
- if (SetCCOpcode == ISD::SETGT && RHSC->isAllOnes()) {
- // X > -1 -> X == 0, jump !sign.
+ // Attempt to canonicalize SGT/UGT -> SGE/UGE compares with constant which
+ // reduces the number of EFLAGs bit reads (the GE conditions don't read
+ // ZF), this may translate to less uops depending on uarch implementation.
+ // The equivalent for SLE/ULE -> SLT/ULT isn't likely to happen as we
+ // already canonicalize to that CondCode.
+
+ // NOTE: Only do this if incrementing the constant doesn't increase the
+ // bit encoding size - so it must either already be a i8 or i32 immediate,
+ // or it shrinks down to that. We don't do this for any i64's to avoid
+ // additional constant materializations.
+
+ // Note, when we are doing signed compare against 1, we can do it in
+ // reverse too, since 0 is better in general.
+
+ // We do not do this for unsigned since this will always just be =/!= 0.
+ const APInt &Op1Val = RHSC->getAPIntValue();
+ // We should try to go to 0 if and when we can.
+ // Always assume that 0 is better for encoding too.
+ if (shouldBeAdjustedToZero(LHS, Op1Val, SetCCOpcode)) {
+ // Adjust the constant to zero.
+ // CC has already been adjusted.
RHS = DAG.getConstant(0, DL, RHS.getValueType());
- return X86::COND_NS;
}
- if (SetCCOpcode == ISD::SETLT && RHSC->isZero()) {
+
+ if (SetCCOpcode == ISD::SETLT && isNullConstant(RHS)) {
// X < 0 -> X == 0, jump on sign.
return X86::COND_S;
}
- if (SetCCOpcode == ISD::SETGE && RHSC->isZero()) {
+
+ if (SetCCOpcode == ISD::SETGE && isNullConstant(RHS)) {
// X >= 0 -> X == 0, jump on !sign.
return X86::COND_NS;
}
- if (SetCCOpcode == ISD::SETLT && RHSC->isOne()) {
- // X < 1 -> X <= 0
- RHS = DAG.getConstant(0, DL, RHS.getValueType());
- return X86::COND_LE;
- }
}
return TranslateIntegerX86CC(SetCCOpcode);
More information about the llvm-commits
mailing list