Skip to content

release/22.x: MIPSr6: Fix COPY of reg:fgr64cc without fcmp in the same BB (#185820)#186008

Open
llvmbot wants to merge 1 commit intollvm:release/22.xfrom
llvmbot:issue185820
Open

release/22.x: MIPSr6: Fix COPY of reg:fgr64cc without fcmp in the same BB (#185820)#186008
llvmbot wants to merge 1 commit intollvm:release/22.xfrom
llvmbot:issue185820

Conversation

@llvmbot
Copy link
Copy Markdown
Member

@llvmbot llvmbot commented Mar 12, 2026

Backport 472c8f8

Requested by: @wzssyqa

)

There may be some BB to COPY fgr64cc register, and the fgr64cc register
is set by the previous BB.
We add a new pass called MipsSetMachineRegisterFlags, in which we set

We introduce a new pass called MipsSetMachineRegisterFlags, in which we
set NoSWrap flag for all instructions that works with fgr64cc registers.

And in copyPhyRegister, we allow the COPY instruction with NoSignWrap
from the double float registers to gpr32.

(cherry picked from commit 472c8f8)
@llvmbot
Copy link
Copy Markdown
Member Author

llvmbot commented Mar 12, 2026

@llvm/pr-subscribers-backend-mips

Author: None (llvmbot)

Changes

Backport 472c8f8

Requested by: @wzssyqa


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

6 Files Affected:

  • (modified) llvm/lib/Target/Mips/CMakeLists.txt (+1)
  • (modified) llvm/lib/Target/Mips/Mips.h (+2)
  • (modified) llvm/lib/Target/Mips/MipsSEInstrInfo.cpp (+2-1)
  • (added) llvm/lib/Target/Mips/MipsSetMachineRegisterFlags.cpp (+111)
  • (modified) llvm/lib/Target/Mips/MipsTargetMachine.cpp (+2)
  • (modified) llvm/test/CodeGen/MIR/Mips/mips32r6-copyPhysReg-fcmp-f64-to-gpr.mir (+16-5)
diff --git a/llvm/lib/Target/Mips/CMakeLists.txt b/llvm/lib/Target/Mips/CMakeLists.txt
index 726f0af0d8b0b..26afdcba94c69 100644
--- a/llvm/lib/Target/Mips/CMakeLists.txt
+++ b/llvm/lib/Target/Mips/CMakeLists.txt
@@ -61,6 +61,7 @@ add_llvm_target(MipsCodeGen
   MipsSEISelLowering.cpp
   MipsSERegisterInfo.cpp
   MipsSelectionDAGInfo.cpp
+  MipsSetMachineRegisterFlags.cpp
   MipsSubtarget.cpp
   MipsTargetMachine.cpp
   MipsTargetObjectFile.cpp
diff --git a/llvm/lib/Target/Mips/Mips.h b/llvm/lib/Target/Mips/Mips.h
index 60d5114f2f55a..364967d07b748 100644
--- a/llvm/lib/Target/Mips/Mips.h
+++ b/llvm/lib/Target/Mips/Mips.h
@@ -51,6 +51,7 @@ FunctionPass *createMipsExpandPseudoPass();
 FunctionPass *createMipsPreLegalizeCombiner();
 FunctionPass *createMipsPostLegalizeCombiner(bool IsOptNone);
 FunctionPass *createMipsMulMulBugPass();
+FunctionPass *createMipsSetMachineRegisterFlagsPass();
 
 InstructionSelector *
 createMipsInstructionSelector(const MipsTargetMachine &, const MipsSubtarget &,
@@ -64,6 +65,7 @@ void initializeMipsDelaySlotFillerPass(PassRegistry &);
 void initializeMipsMulMulBugFixPass(PassRegistry &);
 void initializeMipsPostLegalizerCombinerPass(PassRegistry &);
 void initializeMipsPreLegalizerCombinerPass(PassRegistry &);
+void initializeMipsSetMachineRegisterFlagsPass(PassRegistry &);
 } // namespace llvm
 
 #endif
diff --git a/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp b/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp
index 36953ecd1f532..312c792ddab18 100644
--- a/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp
+++ b/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp
@@ -172,7 +172,8 @@ void MipsSEInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
     } else if (Mips::MSACtrlRegClass.contains(SrcReg)) {
       Opc = Mips::CFCMSA;
     } else if (Mips::FGR64RegClass.contains(SrcReg) &&
-               isWritedByFCMP(I, SrcReg)) {
+               (I->getFlag(MachineInstr::MIFlag::NoSWrap) ||
+                isWritedByFCMP(I, SrcReg))) {
       Opc = Mips::MFC1_D64;
     }
   }
diff --git a/llvm/lib/Target/Mips/MipsSetMachineRegisterFlags.cpp b/llvm/lib/Target/Mips/MipsSetMachineRegisterFlags.cpp
new file mode 100644
index 0000000000000..38e54d4ca1d80
--- /dev/null
+++ b/llvm/lib/Target/Mips/MipsSetMachineRegisterFlags.cpp
@@ -0,0 +1,111 @@
+//===- MipsSetMachineRegisterFlags.cpp - Set Machine Register Flags -------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass sets machine register flags for MIPS backend.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Mips.h"
+#include "MipsInstrInfo.h"
+#include "MipsSubtarget.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/Support/Debug.h"
+
+#define DEBUG_TYPE "mips-set-machine-register-flags"
+
+using namespace llvm;
+
+namespace {
+
+class MipsSetMachineRegisterFlags : public MachineFunctionPass {
+public:
+  MipsSetMachineRegisterFlags() : MachineFunctionPass(ID) {}
+
+  StringRef getPassName() const override {
+    return "Mips Set Machine Register Flags";
+  }
+
+  bool runOnMachineFunction(MachineFunction &MF) override;
+
+  static char ID;
+
+private:
+  bool processBasicBlock(MachineBasicBlock &MBB, const MipsInstrInfo &MipsII,
+                         const MachineRegisterInfo &RegInfo);
+};
+
+} // namespace
+
+INITIALIZE_PASS(MipsSetMachineRegisterFlags, DEBUG_TYPE,
+                "Mips Set Machine Register Flags", false, false)
+
+char MipsSetMachineRegisterFlags::ID = 0;
+
+bool MipsSetMachineRegisterFlags::runOnMachineFunction(MachineFunction &MF) {
+  const MipsInstrInfo &MipsII =
+      *static_cast<const MipsInstrInfo *>(MF.getSubtarget().getInstrInfo());
+  const MachineRegisterInfo &RegInfo = MF.getRegInfo();
+
+  bool Modified = false;
+
+  for (auto &MBB : MF)
+    Modified |= processBasicBlock(MBB, MipsII, RegInfo);
+
+  return Modified;
+}
+
+bool MipsSetMachineRegisterFlags::processBasicBlock(
+    MachineBasicBlock &MBB, const MipsInstrInfo &MipsII,
+    const MachineRegisterInfo &RegInfo) {
+  bool Modified = false;
+
+  // Iterate through the instructions in the basic block
+  for (MachineBasicBlock::iterator MII = MBB.begin(), E = MBB.end(); MII != E;
+       ++MII) {
+    MachineInstr &MI = *MII;
+
+    LLVM_DEBUG(dbgs() << "Processing instruction: " << MI << "\n");
+
+    unsigned Opcode = MI.getOpcode();
+    if (Opcode >= Mips::CMP_AF_D_MMR6 && Opcode <= Mips::CMP_UN_S_MMR6) {
+      MachineOperand &DestOperand = MI.getOperand(0);
+      assert(DestOperand.isReg());
+      Register Dest = DestOperand.getReg();
+      if (Dest.isVirtual() &&
+          RegInfo.getRegClassOrNull(Dest) == &Mips::FGR64CCRegClass) {
+        MI.setFlag(MachineInstr::MIFlag::NoSWrap);
+      }
+    } else if (Opcode == Mips::COPY) {
+      MachineOperand &SrcOperand = MI.getOperand(1);
+      assert(SrcOperand.isReg());
+      Register Src = SrcOperand.getReg();
+      if (Src.isVirtual() &&
+          RegInfo.getRegClassOrNull(Src) == &Mips::FGR64CCRegClass) {
+        MI.setFlag(MachineInstr::MIFlag::NoSWrap);
+      }
+    } else if (Opcode == Mips::INSERT_SUBREG) {
+      MachineOperand &SrcOperand = MI.getOperand(2);
+      assert(SrcOperand.isReg());
+      Register Src = SrcOperand.getReg();
+      if (Src.isVirtual() &&
+          RegInfo.getRegClassOrNull(Src) == &Mips::FGR64CCRegClass) {
+        MI.setFlag(MachineInstr::MIFlag::NoSWrap);
+      }
+    }
+  }
+
+  return Modified;
+}
+
+FunctionPass *llvm::createMipsSetMachineRegisterFlagsPass() {
+  return new MipsSetMachineRegisterFlags();
+}
diff --git a/llvm/lib/Target/Mips/MipsTargetMachine.cpp b/llvm/lib/Target/Mips/MipsTargetMachine.cpp
index 03bedc5b15c4f..9e605d165e705 100644
--- a/llvm/lib/Target/Mips/MipsTargetMachine.cpp
+++ b/llvm/lib/Target/Mips/MipsTargetMachine.cpp
@@ -69,6 +69,7 @@ extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMipsTarget() {
   initializeMipsPostLegalizerCombinerPass(*PR);
   initializeMipsMulMulBugFixPass(*PR);
   initializeMipsDAGToDAGISelLegacyPass(*PR);
+  initializeMipsSetMachineRegisterFlagsPass(*PR);
 }
 
 static std::unique_ptr<TargetLoweringObjectFile> createTLOF(const Triple &TT) {
@@ -253,6 +254,7 @@ bool MipsPassConfig::addInstSelector() {
 
 void MipsPassConfig::addPreRegAlloc() {
   addPass(createMipsOptimizePICCallPass());
+  addPass(createMipsSetMachineRegisterFlagsPass());
 }
 
 TargetTransformInfo
diff --git a/llvm/test/CodeGen/MIR/Mips/mips32r6-copyPhysReg-fcmp-f64-to-gpr.mir b/llvm/test/CodeGen/MIR/Mips/mips32r6-copyPhysReg-fcmp-f64-to-gpr.mir
index ba98a525c24b5..305ff096f949d 100644
--- a/llvm/test/CodeGen/MIR/Mips/mips32r6-copyPhysReg-fcmp-f64-to-gpr.mir
+++ b/llvm/test/CodeGen/MIR/Mips/mips32r6-copyPhysReg-fcmp-f64-to-gpr.mir
@@ -1,4 +1,4 @@
-# RUN: llc -mtriple=mipsisa32r6-linux-gnu -verify-machineinstrs %s -o - | FileCheck %s
+# RUN: llc -mtriple=mipsisa32r6-linux-gnu --start-before=mips-set-machine-register-flags -verify-machineinstrs %s -o - | FileCheck %s
 
 name:	f
 alignment:       4
@@ -6,13 +6,24 @@ tracksRegLiveness: true
 body:             |
   bb.0.entry:
     liveins: $d12_64, $d14_64
+    successors: %bb.1(0x40000000), %bb.2(0x40000000)
 
-    renamable $d0_64 = CMP_LT_D renamable $d14_64, renamable $d12_64
+    %1:fgr64cc = CMP_LT_D renamable $d14_64, renamable $d12_64
     ; CHECK: cmp.lt.d
-    $v1 = MFC1_D64 $d0_64
+    %2:gpr32 = MFC1_D64 $d12_64
     ; CHECK: mfc1
-    renamable $v0 = COPY renamable $d0_64
+    %3:gpr32 = COPY renamable %1:fgr64cc
     ; CHECK: mfc1
-    renamable $v0 = SUBu killed renamable $v1, killed renamable $v0
+    %4:gpr32 = SUBu %3:gpr32, %2:gpr32
+    BEQ %3:gpr32, $zero, %bb.2, implicit-def dead $at
+
+  bb.1:
+    $v0 = ADDiu %4:gpr32, 1
+    RetRA implicit $v0
+
+  bb.2:
+    %5:gpr32 = COPY renamable %1:fgr64cc
+    ; CHECK: mfc1
+    $v0 = ADDiu %5:gpr32, 2
     RetRA implicit $v0
 ...

@dyung
Copy link
Copy Markdown
Collaborator

dyung commented Mar 17, 2026

@wzssyqa can you provide some context for this change? Is it is a regression? If so, when was it introduced. I notice that your original change had a PR but was submitted without a review.

What would be the consequences if we did not accept this change? Would we generate bad code?

@dyung
Copy link
Copy Markdown
Collaborator

dyung commented Mar 27, 2026

ping @wzssyqa

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

Projects

Status: Needs Triage

Development

Successfully merging this pull request may close these issues.

3 participants