MIPSr6: Fix COPY of reg:fgr64cc without fcmp in the same BB#185820
MIPSr6: Fix COPY of reg:fgr64cc without fcmp in the same BB#185820
Conversation
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.
|
@llvm/pr-subscribers-backend-mips Author: YunQiang Su (wzssyqa) ChangesThere may be some BB to COPY fgr64cc register, and the fgr64cc register is set by the previous BB. 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:
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
...
|
|
/cherry-pick 472c8f8 |
|
/pull-request #186008 |
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/51/builds/33557 Here is the relevant piece of the build log for the reference |
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/169/builds/20829 Here is the relevant piece of the build log for the reference |
) 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.
) 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.
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.