From 62eac5a97e41cf1f147a3f70e4f42d65240958bb Mon Sep 17 00:00:00 2001 From: Evgenii Kudriashov Date: Thu, 17 Apr 2025 17:47:29 -0700 Subject: [PATCH 1/2] [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 +} From 48fdb4bbbe8b97b9b742e6f2d37cca0f31814ffe Mon Sep 17 00:00:00 2001 From: Evgenii Kudriashov Date: Fri, 18 Apr 2025 10:39:37 -0700 Subject: [PATCH 2/2] Reword the test comment --- llvm/test/CodeGen/X86/apx/nf-regressions.ll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/test/CodeGen/X86/apx/nf-regressions.ll b/llvm/test/CodeGen/X86/apx/nf-regressions.ll index 168893d48413d..68bd05a0737b6 100644 --- a/llvm/test/CodeGen/X86/apx/nf-regressions.ll +++ b/llvm/test/CodeGen/X86/apx/nf-regressions.ll @@ -74,7 +74,7 @@ bb16: ; preds = %bb14, %bb11, %bb10, ret void } -; Replacement of CMP should happen with SUB not with AND as it is AND_NF +; We must not try to replace CMP with AND_NF as it sets no flags define void @cmp_peephole_and_nf(i64 %arg0, ptr %ptr1, ptr %ptr2) { ; CHECK-LABEL: cmp_peephole_and_nf: ; CHECK: # %bb.0: # %entry