diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp
index 242ed1eb42..518922343d 100644
--- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp
+++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp
@@ -675,11 +675,35 @@ void JitArm64::cmp(UGeckoInstruction inst)
   }
   else
   {
+    // If we're dealing with immediates, check their most significant bit to
+    // see if we can skip sign extension.
+    const auto should_sign_extend = [&](u32 reg) -> bool {
+      return !gpr.IsImm(reg) || (gpr.GetImm(reg) & (1U << 31));
+    };
+    bool sign_extend_a = should_sign_extend(a);
+    bool sign_extend_b = should_sign_extend(b);
+
     ARM64Reg RA = gpr.R(a);
     ARM64Reg RB = gpr.R(b);
 
-    SXTW(CR, RA);
-    SUB(CR, CR, RB, ArithOption(RB, ExtendSpecifier::SXTW));
+    if (sign_extend_a)
+    {
+      SXTW(CR, RA);
+      RA = CR;
+    }
+    else
+    {
+      RA = EncodeRegTo64(RA);
+    }
+
+    auto opt = ArithOption(RB, ExtendSpecifier::SXTW);
+    if (!sign_extend_b)
+    {
+      opt = ArithOption(CR, ShiftType::LSL, 0);
+      RB = EncodeRegTo64(RB);
+    }
+
+    SUB(CR, RA, RB, opt);
   }
 }