[llvm] MIPSr6: Fix COPY of reg:fgr64cc without fcmp in the same BB (PR #185820)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 11 00:08:03 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-mips
Author: YunQiang Su (wzssyqa)
<details>
<summary>Changes</summary>
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.
---
Full diff: https://github.com/llvm/llvm-project/pull/185820.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
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 4fbf54c72060d..6c59975a1b501 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
...
``````````
</details>
https://github.com/llvm/llvm-project/pull/185820
More information about the llvm-commits
mailing list