Skip to content

[X86] Port shouldBeAdjustedToZero to simplify TranslateX86CC (NFC) #149742

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

AZero13
Copy link
Contributor

@AZero13 AZero13 commented Jul 20, 2025

This means we have a helper function to optimize by adjusting to 0 much like on AArch64

This means we have a helper function to optimize by adjusting to 0 much like on AArch64
@llvmbot
Copy link
Member

llvmbot commented Jul 20, 2025

@llvm/pr-subscribers-backend-x86

Author: AZero13 (AZero13)

Changes

This means we have a helper function to optimize by adjusting to 0 much like on AArch64


Full diff: https://github.com/llvm/llvm-project/pull/149742.diff

1 Files Affected:

  • (modified) llvm/lib/Target/X86/X86ISelLowering.cpp (+42-10)
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);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants