[llvm] [X86][APX] Handle AND_NF instruction for compare peephole (PR #136233)

Evgenii Kudriashov via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 18 10:39:05 PDT 2025


https://github.com/e-kud updated https://github.com/llvm/llvm-project/pull/136233

>From 62eac5a97e41cf1f147a3f70e4f42d65240958bb Mon Sep 17 00:00:00 2001
From: Evgenii Kudriashov <evgenii.kudriashov at intel.com>
Date: Thu, 17 Apr 2025 17:47:29 -0700
Subject: [PATCH] [X86][APX] Handle AND_NF instruction for peephole of
 comparison

---
 llvm/lib/Target/X86/X86InstrInfo.cpp        | 16 +++++-----
 llvm/test/CodeGen/X86/apx/nf-regressions.ll | 33 +++++++++++++++++++++
 2 files changed, 41 insertions(+), 8 deletions(-)

diff --git a/llvm/lib/Target/X86/X86InstrInfo.cpp b/llvm/lib/Target/X86/X86InstrInfo.cpp
index f595642d734e8..32a94e6ab0594 100644
--- a/llvm/lib/Target/X86/X86InstrInfo.cpp
+++ b/llvm/lib/Target/X86/X86InstrInfo.cpp
@@ -1035,12 +1035,11 @@ inline static bool isTruncatedShiftCountForLEA(unsigned ShAmt) {
   return ShAmt < 4 && ShAmt > 0;
 }
 
-static bool findRedundantFlagInstr(MachineInstr &CmpInstr,
-                                   MachineInstr &CmpValDefInstr,
-                                   const MachineRegisterInfo *MRI,
-                                   MachineInstr **AndInstr,
-                                   const TargetRegisterInfo *TRI,
-                                   bool &NoSignFlag, bool &ClearsOverflowFlag) {
+static bool
+findRedundantFlagInstr(MachineInstr &CmpInstr, MachineInstr &CmpValDefInstr,
+                       const MachineRegisterInfo *MRI, MachineInstr **AndInstr,
+                       const TargetRegisterInfo *TRI, const X86Subtarget &ST,
+                       bool &NoSignFlag, bool &ClearsOverflowFlag) {
   if (!(CmpValDefInstr.getOpcode() == X86::SUBREG_TO_REG &&
         CmpInstr.getOpcode() == X86::TEST64rr) &&
       !(CmpValDefInstr.getOpcode() == X86::COPY &&
@@ -1103,7 +1102,8 @@ static bool findRedundantFlagInstr(MachineInstr &CmpInstr,
   if (VregDefInstr->getParent() != CmpValDefInstr.getParent())
     return false;
 
-  if (X86::isAND(VregDefInstr->getOpcode())) {
+  if (X86::isAND(VregDefInstr->getOpcode()) &&
+      (!ST.hasNF() || VregDefInstr->modifiesRegister(X86::EFLAGS, TRI))) {
     // Get a sequence of instructions like
     //   %reg = and* ...                    // Set EFLAGS
     //   ...                                // EFLAGS not changed
@@ -5433,7 +5433,7 @@ bool X86InstrInfo::optimizeCompareInstr(MachineInstr &CmpInstr, Register SrcReg,
         MachineInstr *AndInstr = nullptr;
         if (IsCmpZero &&
             findRedundantFlagInstr(CmpInstr, Inst, MRI, &AndInstr, TRI,
-                                   NoSignFlag, ClearsOverflowFlag)) {
+                                   Subtarget, NoSignFlag, ClearsOverflowFlag)) {
           assert(AndInstr != nullptr && X86::isAND(AndInstr->getOpcode()));
           MI = AndInstr;
           break;
diff --git a/llvm/test/CodeGen/X86/apx/nf-regressions.ll b/llvm/test/CodeGen/X86/apx/nf-regressions.ll
index 40503d85a1ddb..168893d48413d 100644
--- a/llvm/test/CodeGen/X86/apx/nf-regressions.ll
+++ b/llvm/test/CodeGen/X86/apx/nf-regressions.ll
@@ -73,3 +73,36 @@ bb14:                                             ; preds = %bb12
 bb16:                                             ; preds = %bb14, %bb11, %bb10, %bb
   ret void
 }
+
+; Replacement of CMP should happen with SUB not with AND as it is AND_NF
+define void @cmp_peephole_and_nf(i64 %arg0, ptr %ptr1, ptr %ptr2) {
+; CHECK-LABEL: cmp_peephole_and_nf:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    negq %rdi
+; CHECK-NEXT:    movl %edi, %eax
+; CHECK-NEXT:    {nf} andl $1, %eax
+; CHECK-NEXT:    jb .LBB1_2
+; CHECK-NEXT:  # %bb.1: # %true
+; CHECK-NEXT:    testq %rax, %rax
+; CHECK-NEXT:    sete (%rsi)
+; CHECK-NEXT:    retq
+; CHECK-NEXT:  .LBB1_2: # %false
+; CHECK-NEXT:    movq %rdi, (%rsi)
+; CHECK-NEXT:    movq %rax, (%rdx)
+; CHECK-NEXT:    retq
+entry:
+  %sub_flag = sub i64 0, %arg0
+  %and_nf = and i64 %sub_flag, 1
+  %elim = icmp eq i64 0, %arg0
+  br i1 %elim, label %true, label %false
+
+true:
+  %8 = icmp eq i64 %and_nf, 0
+  store i1 %8, ptr %ptr1
+  ret void
+
+false:
+  store i64 %sub_flag, ptr %ptr1
+  store i64 %and_nf, ptr %ptr2
+  ret void
+}



More information about the llvm-commits mailing list