[llvm-branch-commits] [llvm] [X86] Restore CCMP formation through boolean NOT (PR #230770)
Alan Li via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Sat Oct 10 03:06:09 PDT 2026
https://github.com/lialan created https://github.com/llvm/llvm-project/pull/230770
With #230700, demanded-bits simplification can turn boolean XOR with 1 into NOT, hiding the SETCC operands from CCMP formation. In `ccmp64rr_of`, this replaces `cmp + ccmpbq + jno` with separate SETCCs, NOT, and TEST; the ZU configurations also gain an unnecessary NOT.
Fold a single-use `NOT(SETCC)` under AND with another SETCC by inverting its condition. The other SETCC masks all but bit zero, so the replacement preserves the AND result. Restore the original `ccmp.ll` checks for all four configurations.
Stacked on #230701, following #230700. Addresses the [X86 regression feedback](https://github.com/llvm/llvm-project/pull/230700#discussion_r4236943681).
Validation with an assertions-enabled X86 build rebuilt at this head:
- All four `ccmp.ll` configurations pass with machine verification and encoding checks. Complete output matches the pre-regression parent byte for byte; the unfixed #230700 head fails the restored checks in all four configurations.
- Full X86 CodeGen suite: 5,720 passed, 15 expected failures, 2 unsupported, zero unexpected failures.
>From 0a65dd1175dc9ff08f7e424c54f3e26d96a8f43d Mon Sep 17 00:00:00 2001
From: Alan Li <me at alanli.org>
Date: Fri, 9 Oct 2026 17:06:12 -0700
Subject: [PATCH] fix(X86): restore CCMP through boolean NOT
Demanded-bits simplification can turn XOR with 1 into NOT, hiding
SETCC operands from CCMP formation. Invert the condition under AND
when the other SETCC masks high bits and the NOT has one use.
Restore the original ccmp.ll checks for all four configurations.
Refs #230700
---
llvm/lib/Target/X86/X86ISelLowering.cpp | 13 +++++++++++++
llvm/test/CodeGen/X86/apx/ccmp.ll | 22 ++++++----------------
2 files changed, 19 insertions(+), 16 deletions(-)
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index a265c163cf276d..0cfa3ebcf911ed 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -53422,6 +53422,19 @@ static SDValue combineAnd(SDNode *N, SelectionDAG &DAG,
}
}
+ // SETCC only produces 0 or 1, so AND only observes the low bit of the NOT.
+ // Fold the inversion even if demanded bits changed XOR with 1 into NOT.
+ // Require one use of the NOT to avoid duplicating the inverted condition.
+ SDValue SetCC, OtherSetCC;
+ if (sd_match(N, m_And(m_OneUse(m_Not(
+ m_Value(SetCC, m_SpecificOpc<X86ISD::SETCC>()))),
+ m_Value(OtherSetCC, m_SpecificOpc<X86ISD::SETCC>())))) {
+ auto CC = static_cast<X86::CondCode>(SetCC.getConstantOperandVal(0));
+ SDValue Inverted = getSETCC(X86::GetOppositeBranchCondition(CC),
+ SetCC.getOperand(1), dl, DAG);
+ return DAG.getNode(ISD::AND, dl, VT, OtherSetCC, Inverted);
+ }
+
if (SDValue SetCC = combineAndOrForCcmpCtest(N, DAG, DCI, Subtarget))
return SetCC;
diff --git a/llvm/test/CodeGen/X86/apx/ccmp.ll b/llvm/test/CodeGen/X86/apx/ccmp.ll
index 39c8b532d085ac..8629b179a17970 100644
--- a/llvm/test/CodeGen/X86/apx/ccmp.ll
+++ b/llvm/test/CodeGen/X86/apx/ccmp.ll
@@ -435,12 +435,8 @@ define void @ccmp64rr_of(i64 %a, i64 %b, i64 %c) {
; CHECK-LABEL: ccmp64rr_of:
; CHECK: # %bb.0: # %bb
; CHECK-NEXT: cmpq %rdx, %rdi # encoding: [0x48,0x39,0xd7]
-; CHECK-NEXT: setb %al # encoding: [0x0f,0x92,0xc0]
-; CHECK-NEXT: cmpq %rsi, %rdi # encoding: [0x48,0x39,0xf7]
-; CHECK-NEXT: seto %cl # encoding: [0x0f,0x90,0xc1]
-; CHECK-NEXT: notb %cl # encoding: [0xf6,0xd1]
-; CHECK-NEXT: testb %cl, %al # encoding: [0x84,0xc8]
-; CHECK-NEXT: jne .LBB6_1 # encoding: [0x75,A]
+; CHECK-NEXT: ccmpbq {dfv=of} %rsi, %rdi # encoding: [0x62,0xf4,0xc4,0x02,0x39,0xf7]
+; CHECK-NEXT: jno .LBB6_1 # encoding: [0x71,A]
; CHECK-NEXT: # fixup A - offset: 1, value: .LBB6_1, kind: FK_PCRel_1
; CHECK-NEXT: # %bb.2: # %if.then
; CHECK-NEXT: xorl %eax, %eax # encoding: [0x31,0xc0]
@@ -453,12 +449,8 @@ define void @ccmp64rr_of(i64 %a, i64 %b, i64 %c) {
; NDD-LABEL: ccmp64rr_of:
; NDD: # %bb.0: # %bb
; NDD-NEXT: cmpq %rdx, %rdi # encoding: [0x48,0x39,0xd7]
-; NDD-NEXT: setb %al # encoding: [0x0f,0x92,0xc0]
-; NDD-NEXT: cmpq %rsi, %rdi # encoding: [0x48,0x39,0xf7]
-; NDD-NEXT: seto %cl # encoding: [0x0f,0x90,0xc1]
-; NDD-NEXT: notb %cl # EVEX TO LEGACY Compression encoding: [0xf6,0xd1]
-; NDD-NEXT: testb %cl, %al # encoding: [0x84,0xc8]
-; NDD-NEXT: jne .LBB6_1 # encoding: [0x75,A]
+; NDD-NEXT: ccmpbq {dfv=of} %rsi, %rdi # encoding: [0x62,0xf4,0xc4,0x02,0x39,0xf7]
+; NDD-NEXT: jno .LBB6_1 # encoding: [0x71,A]
; NDD-NEXT: # fixup A - offset: 1, value: .LBB6_1, kind: FK_PCRel_1
; NDD-NEXT: # %bb.2: # %if.then
; NDD-NEXT: xorl %eax, %eax # encoding: [0x31,0xc0]
@@ -473,8 +465,7 @@ define void @ccmp64rr_of(i64 %a, i64 %b, i64 %c) {
; PREFER_NO_LEGACY_SETCC-NEXT: cmpq %rdx, %rdi # encoding: [0x48,0x39,0xd7]
; PREFER_NO_LEGACY_SETCC-NEXT: setzub %al # encoding: [0x62,0xf4,0x7f,0x18,0x42,0xc0]
; PREFER_NO_LEGACY_SETCC-NEXT: cmpq %rsi, %rdi # encoding: [0x48,0x39,0xf7]
-; PREFER_NO_LEGACY_SETCC-NEXT: setzuo %cl # encoding: [0x62,0xf4,0x7f,0x18,0x40,0xc1]
-; PREFER_NO_LEGACY_SETCC-NEXT: notb %cl # encoding: [0xf6,0xd1]
+; PREFER_NO_LEGACY_SETCC-NEXT: setzuno %cl # encoding: [0x62,0xf4,0x7f,0x18,0x41,0xc1]
; PREFER_NO_LEGACY_SETCC-NEXT: testb %cl, %al # encoding: [0x84,0xc8]
; PREFER_NO_LEGACY_SETCC-NEXT: jne .LBB6_1 # encoding: [0x75,A]
; PREFER_NO_LEGACY_SETCC-NEXT: # fixup A - offset: 1, value: .LBB6_1, kind: FK_PCRel_1
@@ -491,8 +482,7 @@ define void @ccmp64rr_of(i64 %a, i64 %b, i64 %c) {
; PREFER_LEGACY_SETCC-NEXT: cmpq %rdx, %rdi # encoding: [0x48,0x39,0xd7]
; PREFER_LEGACY_SETCC-NEXT: setb %al # encoding: [0x0f,0x92,0xc0]
; PREFER_LEGACY_SETCC-NEXT: cmpq %rsi, %rdi # encoding: [0x48,0x39,0xf7]
-; PREFER_LEGACY_SETCC-NEXT: seto %cl # encoding: [0x0f,0x90,0xc1]
-; PREFER_LEGACY_SETCC-NEXT: notb %cl # encoding: [0xf6,0xd1]
+; PREFER_LEGACY_SETCC-NEXT: setno %cl # encoding: [0x0f,0x91,0xc1]
; PREFER_LEGACY_SETCC-NEXT: testb %cl, %al # encoding: [0x84,0xc8]
; PREFER_LEGACY_SETCC-NEXT: jne .LBB6_1 # encoding: [0x75,A]
; PREFER_LEGACY_SETCC-NEXT: # fixup A - offset: 1, value: .LBB6_1, kind: FK_PCRel_1
More information about the llvm-branch-commits
mailing list