[llvm] Prevent undefined behavior caused by combination of branch and load delay slots on MIPS1 (PR #185427)

via llvm-commits llvm-commits at lists.llvm.org
Sat Apr 4 03:52:35 PDT 2026


https://github.com/JaberwockySeamonstah updated https://github.com/llvm/llvm-project/pull/185427

>From b5534c7a0d45e34f5c95fb46e56d35c818b7ef9f Mon Sep 17 00:00:00 2001
From: Jaby <jaby at william.zone>
Date: Sat, 7 Mar 2026 18:30:38 +0000
Subject: [PATCH 01/18] Disable filling delay slots with load delay slots
 commands under MIPS1

---
 llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp | 29 ++++++++++++++++----
 1 file changed, 24 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp b/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp
index f04ce53340c5d..d3965d3671e66 100644
--- a/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp
+++ b/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp
@@ -229,8 +229,8 @@ namespace {
     /// This function checks if it is valid to move Candidate to the delay slot
     /// and returns true if it isn't. It also updates memory and register
     /// dependence information.
-    bool delayHasHazard(const MachineInstr &Candidate, RegDefsUses &RegDU,
-                        InspectMemInstr &IM) const;
+    bool delayHasHazard(const MipsSubtarget& STI, const MachineInstr &Candidate, 
+                        RegDefsUses &RegDU, InspectMemInstr &IM) const;
 
     /// This function searches range [Begin, End) for an instruction that can be
     /// moved to the delay slot. Returns true on success.
@@ -789,10 +789,11 @@ bool MipsDelaySlotFiller::searchRange(MachineBasicBlock &MBB, IterTy Begin,
       continue;
     }
 
-    if (delayHasHazard(*CurrI, RegDU, IM))
+    const MipsSubtarget &STI = MBB.getParent()->getSubtarget<MipsSubtarget>();
+
+    if (delayHasHazard(STI, *CurrI, RegDU, IM))
       continue;
 
-    const MipsSubtarget &STI = MBB.getParent()->getSubtarget<MipsSubtarget>();
     bool InMicroMipsMode = STI.inMicroMipsMode();
     const MipsInstrInfo *TII = STI.getInstrInfo();
     unsigned Opcode = (*Slot).getOpcode();
@@ -1000,7 +1001,8 @@ bool MipsDelaySlotFiller::examinePred(MachineBasicBlock &Pred,
   return true;
 }
 
-bool MipsDelaySlotFiller::delayHasHazard(const MachineInstr &Candidate,
+bool MipsDelaySlotFiller::delayHasHazard(const MipsSubtarget& STI, 
+                                         const MachineInstr &Candidate,
                                          RegDefsUses &RegDU,
                                          InspectMemInstr &IM) const {
   assert(!Candidate.isKill() &&
@@ -1011,6 +1013,23 @@ bool MipsDelaySlotFiller::delayHasHazard(const MachineInstr &Candidate,
   HasHazard |= IM.hasHazard(Candidate);
   HasHazard |= RegDU.update(Candidate, 0, Candidate.getNumOperands());
 
+  if(STI.hasMips1()) {
+    const MipsInstrInfo* TII = STI.getInstrInfo();
+    const bool HasLoadDelaySlot = TII->HasLoadDelaySlot(Candidate);
+
+    // Having an instruction with a load delay slot in the branch delay slot
+    // seems to not check the load delay slots for hazards.
+    // Not allowing load delay slot commands in branch delays produces always
+    // valid code but may reduce optimization slightly.
+    //
+    // TODO: Ideally we would want to check the register being used in this command 
+    // with the registers of the next command and for the jump target. If we can not
+    // locate the jump target, then we assume hazard. 
+    if(HasLoadDelaySlot) {
+      return true;
+    }
+  }
+
   return HasHazard;
 }
 

>From 117f7e70d88aedec2300cc7ad7f7cbe0be09ad32 Mon Sep 17 00:00:00 2001
From: Jaby <jaby at william.zone>
Date: Wed, 11 Mar 2026 19:44:25 +0000
Subject: [PATCH 02/18] Predict next jump target

---
 llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp | 22 +++++++++++++++++---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp b/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp
index d3965d3671e66..d6da7fc27dea2 100644
--- a/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp
+++ b/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp
@@ -39,6 +39,7 @@
 #include "llvm/Support/CodeGen.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/raw_ostream.h"
 #include "llvm/Target/TargetMachine.h"
 #include <cassert>
 #include <iterator>
@@ -229,7 +230,7 @@ namespace {
     /// This function checks if it is valid to move Candidate to the delay slot
     /// and returns true if it isn't. It also updates memory and register
     /// dependence information.
-    bool delayHasHazard(const MipsSubtarget& STI, const MachineInstr &Candidate, 
+    bool delayHasHazard(const MachineBasicBlock &MBB, const MipsSubtarget& STI, const MachineInstr &Candidate, 
                         RegDefsUses &RegDU, InspectMemInstr &IM) const;
 
     /// This function searches range [Begin, End) for an instruction that can be
@@ -791,7 +792,7 @@ bool MipsDelaySlotFiller::searchRange(MachineBasicBlock &MBB, IterTy Begin,
 
     const MipsSubtarget &STI = MBB.getParent()->getSubtarget<MipsSubtarget>();
 
-    if (delayHasHazard(STI, *CurrI, RegDU, IM))
+    if (delayHasHazard(MBB, STI, *CurrI, RegDU, IM))
       continue;
 
     bool InMicroMipsMode = STI.inMicroMipsMode();
@@ -1001,7 +1002,7 @@ bool MipsDelaySlotFiller::examinePred(MachineBasicBlock &Pred,
   return true;
 }
 
-bool MipsDelaySlotFiller::delayHasHazard(const MipsSubtarget& STI, 
+bool MipsDelaySlotFiller::delayHasHazard(const MachineBasicBlock &MBB, const MipsSubtarget& STI, 
                                          const MachineInstr &Candidate,
                                          RegDefsUses &RegDU,
                                          InspectMemInstr &IM) const {
@@ -1017,6 +1018,21 @@ bool MipsDelaySlotFiller::delayHasHazard(const MipsSubtarget& STI,
     const MipsInstrInfo* TII = STI.getInstrInfo();
     const bool HasLoadDelaySlot = TII->HasLoadDelaySlot(Candidate);
 
+    const auto& branch = MBB.instr_back();
+    outs() << "MBB is: " << MBB << "Candidate is: " << Candidate;
+
+    // Check if this is a conditional branch by looking for an MBB operand
+    const MachineBasicBlock *TargetMBB = nullptr;
+    for (const MachineOperand &MO : branch.operands()) {
+      if(MO.isMBB()) {
+        outs() << "\t>>>" << MO << "<<<\n";
+        TargetMBB = MO.getMBB();
+      }
+    }
+    const auto& target_instr = TargetMBB->instr_front();
+    outs() << "\tDST: " << target_instr;
+    outs() << "\tRESULT: " << TII->SafeInLoadDelaySlot(target_instr, Candidate) << "\n---\n";
+
     // Having an instruction with a load delay slot in the branch delay slot
     // seems to not check the load delay slots for hazards.
     // Not allowing load delay slot commands in branch delays produces always

>From a3197a965432e970128344aa0ae9247e40b6794d Mon Sep 17 00:00:00 2001
From: Jaby <jaby at william.zone>
Date: Wed, 11 Mar 2026 22:14:31 +0000
Subject: [PATCH 03/18] Support checking next instruction

---
 llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp | 91 ++++++++++----------
 1 file changed, 45 insertions(+), 46 deletions(-)

diff --git a/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp b/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp
index d6da7fc27dea2..79748f7027198 100644
--- a/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp
+++ b/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp
@@ -44,6 +44,7 @@
 #include <cassert>
 #include <iterator>
 #include <memory>
+#include <optional>
 #include <utility>
 
 using namespace llvm;
@@ -87,6 +88,7 @@ namespace {
   using Iter = MachineBasicBlock::iterator;
   using ReverseIter = MachineBasicBlock::reverse_iterator;
   using BB2BrMap = SmallDenseMap<MachineBasicBlock *, MachineInstr *, 2>;
+  using BranchTargets = std::pair<MachineInstr&, MachineInstr*>;
 
   class RegDefsUses {
   public:
@@ -198,8 +200,12 @@ namespace {
     bool runOnMachineFunction(MachineFunction &F) override {
       TM = &F.getTarget();
       bool Changed = false;
-      for (MachineBasicBlock &MBB : F)
-        Changed |= runOnMachineBasicBlock(MBB);
+      for (auto MBB = F.begin(); MBB != F.end();) {
+        auto curMBB = MBB;
+        MBB++;
+        
+        Changed |= runOnMachineBasicBlock(*curMBB, (MBB != F.end()) ? &(*MBB).instr_front() : nullptr);
+      }
 
       // This pass invalidates liveness information when it reorders
       // instructions to fill delay slot. Without this, -verify-machineinstrs
@@ -222,7 +228,7 @@ namespace {
     static char ID;
 
   private:
-    bool runOnMachineBasicBlock(MachineBasicBlock &MBB);
+    bool runOnMachineBasicBlock(MachineBasicBlock &MBB, MachineInstr *FirstNextMBBInstr);
 
     Iter replaceWithCompactBranch(MachineBasicBlock &MBB, Iter Branch,
                                   const DebugLoc &DL);
@@ -230,28 +236,28 @@ namespace {
     /// This function checks if it is valid to move Candidate to the delay slot
     /// and returns true if it isn't. It also updates memory and register
     /// dependence information.
-    bool delayHasHazard(const MachineBasicBlock &MBB, const MipsSubtarget& STI, const MachineInstr &Candidate, 
+    bool delayHasHazard(const MipsSubtarget& STI, const BranchTargets &BranchTarget, const MachineInstr &Candidate, 
                         RegDefsUses &RegDU, InspectMemInstr &IM) const;
 
     /// This function searches range [Begin, End) for an instruction that can be
     /// moved to the delay slot. Returns true on success.
     template<typename IterTy>
-    bool searchRange(MachineBasicBlock &MBB, IterTy Begin, IterTy End,
+    bool searchRange(MachineBasicBlock &MBB, MachineInstr *FirstNextMBBInstr, IterTy Begin, IterTy End,
                      RegDefsUses &RegDU, InspectMemInstr &IM, Iter Slot,
                      IterTy &Filler) const;
 
     /// This function searches in the backward direction for an instruction that
     /// can be moved to the delay slot. Returns true on success.
-    bool searchBackward(MachineBasicBlock &MBB, MachineInstr &Slot) const;
+    bool searchBackward(MachineBasicBlock &MBB, MachineInstr *FirstNextMBBInstr, MachineInstr &Slot) const;
 
     /// This function searches MBB in the forward direction for an instruction
     /// that can be moved to the delay slot. Returns true on success.
-    bool searchForward(MachineBasicBlock &MBB, Iter Slot) const;
+    bool searchForward(MachineBasicBlock &MBB, MachineInstr *FirstNextMBBInstr, Iter Slot) const;
 
     /// This function searches one of MBB's successor blocks for an instruction
     /// that can be moved to the delay slot and inserts clones of the
     /// instruction into the successor's predecessor blocks.
-    bool searchSuccBBs(MachineBasicBlock &MBB, Iter Slot) const;
+    bool searchSuccBBs(MachineBasicBlock &MBB, MachineInstr *FirstNextMBBInstr, Iter Slot) const;
 
     /// Pick a successor block of MBB. Return NULL if MBB doesn't have a
     /// successor block that is not a landing pad.
@@ -651,7 +657,7 @@ static int getEquivalentCallShort(int Opcode) {
 
 /// runOnMachineBasicBlock - Fill in delay slots for the given basic block.
 /// We assume there is only one delay slot per delayed instruction.
-bool MipsDelaySlotFiller::runOnMachineBasicBlock(MachineBasicBlock &MBB) {
+bool MipsDelaySlotFiller::runOnMachineBasicBlock(MachineBasicBlock &MBB, MachineInstr *FirstNextMBBInstr) {
   bool Changed = false;
   const MipsSubtarget &STI = MBB.getParent()->getSubtarget<MipsSubtarget>();
   bool InMicroMipsMode = STI.inMicroMipsMode();
@@ -682,17 +688,17 @@ bool MipsDelaySlotFiller::runOnMachineBasicBlock(MachineBasicBlock &MBB) {
 
       if (MipsCompactBranchPolicy.getValue() != CB_Always ||
            !TII->getEquivalentCompactForm(I)) {
-        if (searchBackward(MBB, *I)) {
+        if (searchBackward(MBB, FirstNextMBBInstr, *I)) {
           LLVM_DEBUG(dbgs() << DEBUG_TYPE ": found instruction for delay slot"
                                           " in backwards search.\n");
           Filled = true;
         } else if (I->isTerminator()) {
-          if (searchSuccBBs(MBB, I)) {
+          if (searchSuccBBs(MBB, FirstNextMBBInstr, I)) {
             Filled = true;
             LLVM_DEBUG(dbgs() << DEBUG_TYPE ": found instruction for delay slot"
                                             " in successor BB search.\n");
           }
-        } else if (searchForward(MBB, I)) {
+        } else if (searchForward(MBB, FirstNextMBBInstr, I)) {
           LLVM_DEBUG(dbgs() << DEBUG_TYPE ": found instruction for delay slot"
                                           " in forwards search.\n");
           Filled = true;
@@ -751,7 +757,7 @@ bool MipsDelaySlotFiller::runOnMachineBasicBlock(MachineBasicBlock &MBB) {
 }
 
 template <typename IterTy>
-bool MipsDelaySlotFiller::searchRange(MachineBasicBlock &MBB, IterTy Begin,
+bool MipsDelaySlotFiller::searchRange(MachineBasicBlock &MBB, MachineInstr *FirstNextMBBInstr, IterTy Begin,
                                       IterTy End, RegDefsUses &RegDU,
                                       InspectMemInstr &IM, Iter Slot,
                                       IterTy &Filler) const {
@@ -791,8 +797,7 @@ bool MipsDelaySlotFiller::searchRange(MachineBasicBlock &MBB, IterTy Begin,
     }
 
     const MipsSubtarget &STI = MBB.getParent()->getSubtarget<MipsSubtarget>();
-
-    if (delayHasHazard(MBB, STI, *CurrI, RegDU, IM))
+    if (delayHasHazard(STI, BranchTargets(MBB.instr_back(), FirstNextMBBInstr), *CurrI, RegDU, IM))
       continue;
 
     bool InMicroMipsMode = STI.inMicroMipsMode();
@@ -830,7 +835,7 @@ bool MipsDelaySlotFiller::searchRange(MachineBasicBlock &MBB, IterTy Begin,
   return false;
 }
 
-bool MipsDelaySlotFiller::searchBackward(MachineBasicBlock &MBB,
+bool MipsDelaySlotFiller::searchBackward(MachineBasicBlock &MBB, MachineInstr *FirstNextMBBInstr,
                                          MachineInstr &Slot) const {
   if (DisableBackwardSearch)
     return false;
@@ -843,7 +848,7 @@ bool MipsDelaySlotFiller::searchBackward(MachineBasicBlock &MBB,
   RegDU.init(Slot);
 
   MachineBasicBlock::iterator SlotI = Slot;
-  if (!searchRange(MBB, ++SlotI.getReverse(), MBB.rend(), RegDU, MemDU, Slot,
+  if (!searchRange(MBB, FirstNextMBBInstr, ++SlotI.getReverse(), MBB.rend(), RegDU, MemDU, Slot,
                    Filler)) {
     LLVM_DEBUG(dbgs() << DEBUG_TYPE ": could not find instruction for delay "
                                     "slot using backwards search.\n");
@@ -856,7 +861,7 @@ bool MipsDelaySlotFiller::searchBackward(MachineBasicBlock &MBB,
   return true;
 }
 
-bool MipsDelaySlotFiller::searchForward(MachineBasicBlock &MBB,
+bool MipsDelaySlotFiller::searchForward(MachineBasicBlock &MBB, MachineInstr *FirstNextMBBInstr,
                                         Iter Slot) const {
   // Can handle only calls.
   if (DisableForwardSearch || !Slot->isCall())
@@ -868,7 +873,7 @@ bool MipsDelaySlotFiller::searchForward(MachineBasicBlock &MBB,
 
   RegDU.setCallerSaved(*Slot);
 
-  if (!searchRange(MBB, std::next(Slot), MBB.end(), RegDU, NM, Slot, Filler)) {
+  if (!searchRange(MBB, FirstNextMBBInstr, std::next(Slot), MBB.end(), RegDU, NM, Slot, Filler)) {
     LLVM_DEBUG(dbgs() << DEBUG_TYPE ": could not find instruction for delay "
                                     "slot using forwards search.\n");
     return false;
@@ -880,7 +885,7 @@ bool MipsDelaySlotFiller::searchForward(MachineBasicBlock &MBB,
   return true;
 }
 
-bool MipsDelaySlotFiller::searchSuccBBs(MachineBasicBlock &MBB,
+bool MipsDelaySlotFiller::searchSuccBBs(MachineBasicBlock &MBB, MachineInstr *FirstNextMBBInstr,
                                         Iter Slot) const {
   if (DisableSuccBBSearch)
     return false;
@@ -915,7 +920,7 @@ bool MipsDelaySlotFiller::searchSuccBBs(MachineBasicBlock &MBB,
     IM.reset(new MemDefsUses(&MFI));
   }
 
-  if (!searchRange(MBB, SuccBB->begin(), SuccBB->end(), RegDU, *IM, Slot,
+  if (!searchRange(MBB, FirstNextMBBInstr, SuccBB->begin(), SuccBB->end(), RegDU, *IM, Slot,
                    Filler))
     return false;
 
@@ -1002,7 +1007,7 @@ bool MipsDelaySlotFiller::examinePred(MachineBasicBlock &Pred,
   return true;
 }
 
-bool MipsDelaySlotFiller::delayHasHazard(const MachineBasicBlock &MBB, const MipsSubtarget& STI, 
+bool MipsDelaySlotFiller::delayHasHazard(const MipsSubtarget& STI, const BranchTargets &BranchTarget,
                                          const MachineInstr &Candidate,
                                          RegDefsUses &RegDU,
                                          InspectMemInstr &IM) const {
@@ -1018,31 +1023,25 @@ bool MipsDelaySlotFiller::delayHasHazard(const MachineBasicBlock &MBB, const Mip
     const MipsInstrInfo* TII = STI.getInstrInfo();
     const bool HasLoadDelaySlot = TII->HasLoadDelaySlot(Candidate);
 
-    const auto& branch = MBB.instr_back();
-    outs() << "MBB is: " << MBB << "Candidate is: " << Candidate;
-
-    // Check if this is a conditional branch by looking for an MBB operand
-    const MachineBasicBlock *TargetMBB = nullptr;
-    for (const MachineOperand &MO : branch.operands()) {
-      if(MO.isMBB()) {
-        outs() << "\t>>>" << MO << "<<<\n";
-        TargetMBB = MO.getMBB();
-      }
-    }
-    const auto& target_instr = TargetMBB->instr_front();
-    outs() << "\tDST: " << target_instr;
-    outs() << "\tRESULT: " << TII->SafeInLoadDelaySlot(target_instr, Candidate) << "\n---\n";
-
-    // Having an instruction with a load delay slot in the branch delay slot
-    // seems to not check the load delay slots for hazards.
-    // Not allowing load delay slot commands in branch delays produces always
-    // valid code but may reduce optimization slightly.
-    //
-    // TODO: Ideally we would want to check the register being used in this command 
-    // with the registers of the next command and for the jump target. If we can not
-    // locate the jump target, then we assume hazard. 
     if(HasLoadDelaySlot) {
-      return true;
+      const auto [branch, next_instr] = BranchTarget;
+      outs() << "Branch is: " << branch << "Candidate is: " << Candidate;
+
+      // Check if this is a conditional branch by looking for an MBB operand
+      const MachineBasicBlock *TargetMBB = nullptr;
+      for (const MachineOperand &MO : branch.operands()) {
+        if(MO.isMBB()) {
+          outs() << "\t>>>" << MO << "<<<\n";
+          TargetMBB = MO.getMBB();
+        }
+      }
+      const auto& target_instr = TargetMBB->instr_front();
+      outs() << "\tDST->: " << target_instr;
+      outs() << "\tDST-v: "; if(next_instr) {outs() << *next_instr;} else {outs() << "<NONE>";} outs() << "\n";
+      const bool HasNewHazard = !TII->SafeInLoadDelaySlot(target_instr, Candidate) || !TII->SafeInLoadDelaySlot(*next_instr, Candidate);
+      outs() << "\tNew Hazard?: " << (HasNewHazard ? "Yes" : "No") << "\n---\n";
+
+      HasHazard |= HasNewHazard;
     }
   }
 

>From a10804d370746fbcf82be99f4b15301f64ff6f6e Mon Sep 17 00:00:00 2001
From: Jaby <jaby at william.zone>
Date: Sun, 15 Mar 2026 17:32:39 +0000
Subject: [PATCH 04/18] Handle edge cases

---
 llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp | 23 +++++++++++++++-----
 1 file changed, 18 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp b/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp
index 79748f7027198..8c71b117a7d77 100644
--- a/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp
+++ b/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp
@@ -88,7 +88,7 @@ namespace {
   using Iter = MachineBasicBlock::iterator;
   using ReverseIter = MachineBasicBlock::reverse_iterator;
   using BB2BrMap = SmallDenseMap<MachineBasicBlock *, MachineInstr *, 2>;
-  using BranchTargets = std::pair<MachineInstr&, MachineInstr*>;
+  using BranchTargets = std::pair<const MachineInstr*, const MachineInstr*>;
 
   class RegDefsUses {
   public:
@@ -796,8 +796,9 @@ bool MipsDelaySlotFiller::searchRange(MachineBasicBlock &MBB, MachineInstr *Firs
       continue;
     }
 
-    const MipsSubtarget &STI = MBB.getParent()->getSubtarget<MipsSubtarget>();
-    if (delayHasHazard(STI, BranchTargets(MBB.instr_back(), FirstNextMBBInstr), *CurrI, RegDU, IM))
+    const MipsSubtarget &STI       = MBB.getParent()->getSubtarget<MipsSubtarget>();
+    const MachineInstr &last_instr = MBB.instr_back();
+    if (delayHasHazard(STI, BranchTargets(last_instr.isBranch() ? &last_instr : nullptr, FirstNextMBBInstr), *CurrI, RegDU, IM))
       continue;
 
     bool InMicroMipsMode = STI.inMicroMipsMode();
@@ -1025,11 +1026,23 @@ bool MipsDelaySlotFiller::delayHasHazard(const MipsSubtarget& STI, const BranchT
 
     if(HasLoadDelaySlot) {
       const auto [branch, next_instr] = BranchTarget;
-      outs() << "Branch is: " << branch << "Candidate is: " << Candidate;
+      // We have no branch
+      if(!branch) {
+        return false;
+      }
+
+      outs() << (branch->isIndirectBranch() ? "Indirect-" : "") << "Branch is: " << branch << "Candidate is: " << Candidate;
+
+      // Being an indirect branch means we can not tell if we are a hazard
+      // Assume the worst
+      if(branch->isIndirectBranch()) {
+        outs() << "\tNew Hazard?: Yes\n---\n";
+        return true;
+      }
 
       // Check if this is a conditional branch by looking for an MBB operand
       const MachineBasicBlock *TargetMBB = nullptr;
-      for (const MachineOperand &MO : branch.operands()) {
+      for (const MachineOperand &MO : branch->operands()) {
         if(MO.isMBB()) {
           outs() << "\t>>>" << MO << "<<<\n";
           TargetMBB = MO.getMBB();

>From d6ea4d914add5cd8a379ebb0b382f08cc374b62f Mon Sep 17 00:00:00 2001
From: Jaby <jaby at william.zone>
Date: Sun, 15 Mar 2026 19:19:37 +0000
Subject: [PATCH 05/18] Make sure new branch delay slot filler only runs for
 MIPS1

---
 llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp b/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp
index 8c71b117a7d77..0b0f6e20803aa 100644
--- a/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp
+++ b/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp
@@ -1020,7 +1020,8 @@ bool MipsDelaySlotFiller::delayHasHazard(const MipsSubtarget& STI, const BranchT
   HasHazard |= IM.hasHazard(Candidate);
   HasHazard |= RegDU.update(Candidate, 0, Candidate.getNumOperands());
 
-  if(STI.hasMips1()) {
+  // This only matters for MIPS1
+  if(!STI.hasMips2()) {
     const MipsInstrInfo* TII = STI.getInstrInfo();
     const bool HasLoadDelaySlot = TII->HasLoadDelaySlot(Candidate);
 
@@ -1031,7 +1032,7 @@ bool MipsDelaySlotFiller::delayHasHazard(const MipsSubtarget& STI, const BranchT
         return false;
       }
 
-      outs() << (branch->isIndirectBranch() ? "Indirect-" : "") << "Branch is: " << branch << "Candidate is: " << Candidate;
+      outs() << (branch->isIndirectBranch() ? "Indirect-" : "") << "Branch is: " << *branch << "Candidate is: " << Candidate;
 
       // Being an indirect branch means we can not tell if we are a hazard
       // Assume the worst

>From b242470bab975055a3ed0b37af295d53119312db Mon Sep 17 00:00:00 2001
From: Jaby <jaby at william.zone>
Date: Mon, 16 Mar 2026 21:15:01 +0000
Subject: [PATCH 06/18] Support unconditional jumps

---
 llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp | 17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp b/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp
index 0b0f6e20803aa..d6311137689a3 100644
--- a/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp
+++ b/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp
@@ -1021,7 +1021,7 @@ bool MipsDelaySlotFiller::delayHasHazard(const MipsSubtarget& STI, const BranchT
   HasHazard |= RegDU.update(Candidate, 0, Candidate.getNumOperands());
 
   // This only matters for MIPS1
-  if(!STI.hasMips2()) {
+  if (STI.hasMips1()) { //(!STI.hasMips2()) {
     const MipsInstrInfo* TII = STI.getInstrInfo();
     const bool HasLoadDelaySlot = TII->HasLoadDelaySlot(Candidate);
 
@@ -1049,13 +1049,24 @@ bool MipsDelaySlotFiller::delayHasHazard(const MipsSubtarget& STI, const BranchT
           TargetMBB = MO.getMBB();
         }
       }
+
+      if (!TargetMBB || TargetMBB->empty()) {
+        outs() << "No or empty Target MBB found\n";
+        return true;
+      }
+
       const auto& target_instr = TargetMBB->instr_front();
       outs() << "\tDST->: " << target_instr;
       outs() << "\tDST-v: "; if(next_instr) {outs() << *next_instr;} else {outs() << "<NONE>";} outs() << "\n";
-      const bool HasNewHazard = !TII->SafeInLoadDelaySlot(target_instr, Candidate) || !TII->SafeInLoadDelaySlot(*next_instr, Candidate);
+
+      bool HasNewHazard = !TII->SafeInLoadDelaySlot(target_instr, Candidate);
+      // If the branch is unconditional then we do not need to bother to check the next instruction after the branch
+      if(!branch->isUnconditionalBranch() && next_instr) {
+        HasNewHazard |= !TII->SafeInLoadDelaySlot(*next_instr, Candidate);
+      }
       outs() << "\tNew Hazard?: " << (HasNewHazard ? "Yes" : "No") << "\n---\n";
 
-      HasHazard |= HasNewHazard;
+      return HasNewHazard;
     }
   }
 

>From addf8bef369ced8ca59d271c406790c5d0d0a0eb Mon Sep 17 00:00:00 2001
From: Jaby <jaby at william.zone>
Date: Mon, 16 Mar 2026 21:23:13 +0000
Subject: [PATCH 07/18] Format code

---
 llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp | 35 ++++++++++++--------
 1 file changed, 22 insertions(+), 13 deletions(-)

diff --git a/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp b/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp
index d6311137689a3..9ade70a2f8144 100644
--- a/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp
+++ b/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp
@@ -1026,24 +1026,25 @@ bool MipsDelaySlotFiller::delayHasHazard(const MipsSubtarget& STI, const BranchT
     const bool HasLoadDelaySlot = TII->HasLoadDelaySlot(Candidate);
 
     if(HasLoadDelaySlot) {
-      const auto [branch, next_instr] = BranchTarget;
+      const auto [Branch, AfterBranchInstr] = BranchTarget;
       // We have no branch
-      if(!branch) {
+      if (!Branch) {
         return false;
       }
 
-      outs() << (branch->isIndirectBranch() ? "Indirect-" : "") << "Branch is: " << *branch << "Candidate is: " << Candidate;
+      outs() << (Branch->isIndirectBranch() ? "Indirect-" : "")
+             << "Branch is: " << *Branch << "Candidate is: " << Candidate;
 
       // Being an indirect branch means we can not tell if we are a hazard
       // Assume the worst
-      if(branch->isIndirectBranch()) {
+      if (Branch->isIndirectBranch()) {
         outs() << "\tNew Hazard?: Yes\n---\n";
         return true;
       }
 
       // Check if this is a conditional branch by looking for an MBB operand
       const MachineBasicBlock *TargetMBB = nullptr;
-      for (const MachineOperand &MO : branch->operands()) {
+      for (const MachineOperand &MO : Branch->operands()) {
         if(MO.isMBB()) {
           outs() << "\t>>>" << MO << "<<<\n";
           TargetMBB = MO.getMBB();
@@ -1055,14 +1056,22 @@ bool MipsDelaySlotFiller::delayHasHazard(const MipsSubtarget& STI, const BranchT
         return true;
       }
 
-      const auto& target_instr = TargetMBB->instr_front();
-      outs() << "\tDST->: " << target_instr;
-      outs() << "\tDST-v: "; if(next_instr) {outs() << *next_instr;} else {outs() << "<NONE>";} outs() << "\n";
-
-      bool HasNewHazard = !TII->SafeInLoadDelaySlot(target_instr, Candidate);
-      // If the branch is unconditional then we do not need to bother to check the next instruction after the branch
-      if(!branch->isUnconditionalBranch() && next_instr) {
-        HasNewHazard |= !TII->SafeInLoadDelaySlot(*next_instr, Candidate);
+      const auto &BranchTargetInstr = TargetMBB->instr_front();
+      outs() << "\tDST->: " << BranchTargetInstr;
+      outs() << "\tDST-v: ";
+      if (AfterBranchInstr) {
+        outs() << *AfterBranchInstr;
+      } else {
+        outs() << "<NONE>";
+      }
+      outs() << "\n";
+
+      bool HasNewHazard =
+          !TII->SafeInLoadDelaySlot(BranchTargetInstr, Candidate);
+      // If the branch is unconditional then we do not need to bother to check
+      // the next instruction after the branch
+      if (!Branch->isUnconditionalBranch() && AfterBranchInstr) {
+        HasNewHazard |= !TII->SafeInLoadDelaySlot(*AfterBranchInstr, Candidate);
       }
       outs() << "\tNew Hazard?: " << (HasNewHazard ? "Yes" : "No") << "\n---\n";
 

>From 2602a66b0080cc709afe28c6178c2be44230a56d Mon Sep 17 00:00:00 2001
From: Jaby <jaby at william.zone>
Date: Tue, 17 Mar 2026 22:42:49 +0000
Subject: [PATCH 08/18] Missing branch is a potential hazard

---
 llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp | 26 ++++++++++----------
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp b/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp
index 9ade70a2f8144..f5591f3aa480e 100644
--- a/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp
+++ b/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp
@@ -44,7 +44,6 @@
 #include <cassert>
 #include <iterator>
 #include <memory>
-#include <optional>
 #include <utility>
 
 using namespace llvm;
@@ -1021,7 +1020,7 @@ bool MipsDelaySlotFiller::delayHasHazard(const MipsSubtarget& STI, const BranchT
   HasHazard |= RegDU.update(Candidate, 0, Candidate.getNumOperands());
 
   // This only matters for MIPS1
-  if (STI.hasMips1()) { //(!STI.hasMips2()) {
+  if (!STI.hasMips2()) { //(!STI.hasMips2()) { // (STI.hasMips1()){
     const MipsInstrInfo* TII = STI.getInstrInfo();
     const bool HasLoadDelaySlot = TII->HasLoadDelaySlot(Candidate);
 
@@ -1029,16 +1028,17 @@ bool MipsDelaySlotFiller::delayHasHazard(const MipsSubtarget& STI, const BranchT
       const auto [Branch, AfterBranchInstr] = BranchTarget;
       // We have no branch
       if (!Branch) {
-        return false;
+        errs() << "No branch?\n";
+        return true;
       }
 
-      outs() << (Branch->isIndirectBranch() ? "Indirect-" : "")
+      errs() << (Branch->isIndirectBranch() ? "Indirect-" : "")
              << "Branch is: " << *Branch << "Candidate is: " << Candidate;
 
       // Being an indirect branch means we can not tell if we are a hazard
       // Assume the worst
       if (Branch->isIndirectBranch()) {
-        outs() << "\tNew Hazard?: Yes\n---\n";
+        errs()  << "\tNew Hazard?: Yes\n---\n";
         return true;
       }
 
@@ -1046,25 +1046,25 @@ bool MipsDelaySlotFiller::delayHasHazard(const MipsSubtarget& STI, const BranchT
       const MachineBasicBlock *TargetMBB = nullptr;
       for (const MachineOperand &MO : Branch->operands()) {
         if(MO.isMBB()) {
-          outs() << "\t>>>" << MO << "<<<\n";
+          errs()  << "\t>>>" << MO << "<<<\n";
           TargetMBB = MO.getMBB();
         }
       }
 
       if (!TargetMBB || TargetMBB->empty()) {
-        outs() << "No or empty Target MBB found\n";
+        errs()  << "No or empty Target MBB found\n";
         return true;
       }
 
       const auto &BranchTargetInstr = TargetMBB->instr_front();
-      outs() << "\tDST->: " << BranchTargetInstr;
-      outs() << "\tDST-v: ";
+      errs()  << "\tDST->: " << BranchTargetInstr;
+      errs() << "\tDST-v: ";
       if (AfterBranchInstr) {
-        outs() << *AfterBranchInstr;
+        errs() << *AfterBranchInstr;
       } else {
-        outs() << "<NONE>";
+        errs() << "<NONE>";
       }
-      outs() << "\n";
+      errs() << "\n";
 
       bool HasNewHazard =
           !TII->SafeInLoadDelaySlot(BranchTargetInstr, Candidate);
@@ -1073,7 +1073,7 @@ bool MipsDelaySlotFiller::delayHasHazard(const MipsSubtarget& STI, const BranchT
       if (!Branch->isUnconditionalBranch() && AfterBranchInstr) {
         HasNewHazard |= !TII->SafeInLoadDelaySlot(*AfterBranchInstr, Candidate);
       }
-      outs() << "\tNew Hazard?: " << (HasNewHazard ? "Yes" : "No") << "\n---\n";
+      errs() << "\tNew Hazard?: " << (HasNewHazard ? "Yes" : "No") << "\n---\n";
 
       return HasNewHazard;
     }

>From 54a95d8ff7834f64193ba6fcda41c0f1394e9f04 Mon Sep 17 00:00:00 2001
From: Jaby <jaby at william.zone>
Date: Wed, 18 Mar 2026 22:33:35 +0000
Subject: [PATCH 09/18] Improve branch prediction

---
 llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp | 179 +++++++++++++------
 1 file changed, 123 insertions(+), 56 deletions(-)

diff --git a/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp b/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp
index f5591f3aa480e..7b9bbbb15fcaf 100644
--- a/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp
+++ b/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp
@@ -87,7 +87,61 @@ namespace {
   using Iter = MachineBasicBlock::iterator;
   using ReverseIter = MachineBasicBlock::reverse_iterator;
   using BB2BrMap = SmallDenseMap<MachineBasicBlock *, MachineInstr *, 2>;
-  using BranchTargets = std::pair<const MachineInstr*, const MachineInstr*>;
+
+  class BranchInformation {
+  private:
+    const MachineInstr *branch_instr = nullptr;
+    const MachineInstr *branch_else_instr = nullptr;
+
+  public:
+    BranchInformation(MachineInstrBundleIterator<MachineInstr> current_slot,
+                      MachineInstrBundleIterator<MachineInstr> mbb_end,
+                      const MachineInstr *next_mbb_instr)
+        : branch_instr(current_slot->isBranch() ? &(*current_slot) : nullptr),
+          branch_else_instr((++current_slot) == mbb_end ? next_mbb_instr
+                                                        : &(*current_slot)) {}
+
+    constexpr bool hasBranchInstr() const { return this->branch_instr; }
+
+    constexpr bool hasBranchElseInstr() const {
+      return this->branch_else_instr;
+    }
+
+    constexpr bool isIndirectBranch() const {
+      if (this->branch_instr) {
+        return this->branch_instr->isIndirectBranch();
+      }
+      return false;
+    }
+
+    constexpr bool isUnconditionalBranch() const {
+      if (this->branch_instr) {
+        return this->branch_instr->isUnconditionalBranch();
+      }
+      return false;
+    }
+
+    const MachineInstr *getBranchInstr() const { return this->branch_instr; }
+
+    const MachineInstr *getBranchElseInstr() const {
+      return this->branch_else_instr;
+    }
+
+    const MachineBasicBlock *getBranchTarget() const {
+      if (this->isIndirectBranch() || !this->hasBranchInstr()) {
+        // Indirect branch has no known target
+        return nullptr;
+      }
+
+      for (const MachineOperand &MO : this->branch_instr->operands()) {
+        if (MO.isMBB()) {
+          errs() << "\t>>>" << MO << "<<<\n";
+          return MO.getMBB();
+        }
+      }
+      return nullptr;
+    }
+  };
 
   class RegDefsUses {
   public:
@@ -235,28 +289,32 @@ namespace {
     /// This function checks if it is valid to move Candidate to the delay slot
     /// and returns true if it isn't. It also updates memory and register
     /// dependence information.
-    bool delayHasHazard(const MipsSubtarget& STI, const BranchTargets &BranchTarget, const MachineInstr &Candidate, 
-                        RegDefsUses &RegDU, InspectMemInstr &IM) const;
+    bool delayHasHazard(const MipsSubtarget &STI, const MachineInstr &Candidate,
+                        const BranchInformation &BranchInfo, RegDefsUses &RegDU,
+                        InspectMemInstr &IM) const;
 
     /// This function searches range [Begin, End) for an instruction that can be
     /// moved to the delay slot. Returns true on success.
-    template<typename IterTy>
-    bool searchRange(MachineBasicBlock &MBB, MachineInstr *FirstNextMBBInstr, IterTy Begin, IterTy End,
-                     RegDefsUses &RegDU, InspectMemInstr &IM, Iter Slot,
-                     IterTy &Filler) const;
+    template <typename IterTy>
+    bool searchRange(MachineBasicBlock &MBB, IterTy Begin, IterTy End,
+                     const BranchInformation &BranchInfo, RegDefsUses &RegDU,
+                     InspectMemInstr &IM, Iter Slot, IterTy &Filler) const;
 
     /// This function searches in the backward direction for an instruction that
     /// can be moved to the delay slot. Returns true on success.
-    bool searchBackward(MachineBasicBlock &MBB, MachineInstr *FirstNextMBBInstr, MachineInstr &Slot) const;
+    bool searchBackward(MachineBasicBlock &MBB, MachineInstr &Slot,
+                        const BranchInformation &BranchInfo) const;
 
     /// This function searches MBB in the forward direction for an instruction
     /// that can be moved to the delay slot. Returns true on success.
-    bool searchForward(MachineBasicBlock &MBB, MachineInstr *FirstNextMBBInstr, Iter Slot) const;
+    bool searchForward(MachineBasicBlock &MBB, Iter Slot,
+                       const BranchInformation &BranchInfo) const;
 
     /// This function searches one of MBB's successor blocks for an instruction
     /// that can be moved to the delay slot and inserts clones of the
     /// instruction into the successor's predecessor blocks.
-    bool searchSuccBBs(MachineBasicBlock &MBB, MachineInstr *FirstNextMBBInstr, Iter Slot) const;
+    bool searchSuccBBs(MachineBasicBlock &MBB, Iter Slot,
+                       const BranchInformation &BranchInfo) const;
 
     /// Pick a successor block of MBB. Return NULL if MBB doesn't have a
     /// successor block that is not a landing pad.
@@ -684,20 +742,22 @@ bool MipsDelaySlotFiller::runOnMachineBasicBlock(MachineBasicBlock &MBB, Machine
         !(InMicroMipsMode && STI.hasMips32r6()) && !SkipForFixR5900) {
 
       bool Filled = false;
+      const auto BranchInfo =
+          BranchInformation(I, MBB.end(), FirstNextMBBInstr);
 
       if (MipsCompactBranchPolicy.getValue() != CB_Always ||
            !TII->getEquivalentCompactForm(I)) {
-        if (searchBackward(MBB, FirstNextMBBInstr, *I)) {
+        if (searchBackward(MBB, *I, BranchInfo)) {
           LLVM_DEBUG(dbgs() << DEBUG_TYPE ": found instruction for delay slot"
                                           " in backwards search.\n");
           Filled = true;
         } else if (I->isTerminator()) {
-          if (searchSuccBBs(MBB, FirstNextMBBInstr, I)) {
+          if (searchSuccBBs(MBB, I, BranchInfo)) {
             Filled = true;
             LLVM_DEBUG(dbgs() << DEBUG_TYPE ": found instruction for delay slot"
                                             " in successor BB search.\n");
           }
-        } else if (searchForward(MBB, FirstNextMBBInstr, I)) {
+        } else if (searchForward(MBB, I, BranchInfo)) {
           LLVM_DEBUG(dbgs() << DEBUG_TYPE ": found instruction for delay slot"
                                           " in forwards search.\n");
           Filled = true;
@@ -751,15 +811,15 @@ bool MipsDelaySlotFiller::runOnMachineBasicBlock(MachineBasicBlock &MBB, Machine
     ++FilledSlots;
     Changed = true;
   }
-
   return Changed;
 }
 
 template <typename IterTy>
-bool MipsDelaySlotFiller::searchRange(MachineBasicBlock &MBB, MachineInstr *FirstNextMBBInstr, IterTy Begin,
-                                      IterTy End, RegDefsUses &RegDU,
-                                      InspectMemInstr &IM, Iter Slot,
-                                      IterTy &Filler) const {
+bool MipsDelaySlotFiller::searchRange(MachineBasicBlock &MBB, IterTy Begin,
+                                      IterTy End,
+                                      const BranchInformation &BranchInfo,
+                                      RegDefsUses &RegDU, InspectMemInstr &IM,
+                                      Iter Slot, IterTy &Filler) const {
   for (IterTy I = Begin; I != End;) {
     IterTy CurrI = I;
     ++I;
@@ -795,9 +855,8 @@ bool MipsDelaySlotFiller::searchRange(MachineBasicBlock &MBB, MachineInstr *Firs
       continue;
     }
 
-    const MipsSubtarget &STI       = MBB.getParent()->getSubtarget<MipsSubtarget>();
-    const MachineInstr &last_instr = MBB.instr_back();
-    if (delayHasHazard(STI, BranchTargets(last_instr.isBranch() ? &last_instr : nullptr, FirstNextMBBInstr), *CurrI, RegDU, IM))
+    const MipsSubtarget &STI = MBB.getParent()->getSubtarget<MipsSubtarget>();
+    if (delayHasHazard(STI, *CurrI, BranchInfo, RegDU, IM))
       continue;
 
     bool InMicroMipsMode = STI.inMicroMipsMode();
@@ -835,8 +894,9 @@ bool MipsDelaySlotFiller::searchRange(MachineBasicBlock &MBB, MachineInstr *Firs
   return false;
 }
 
-bool MipsDelaySlotFiller::searchBackward(MachineBasicBlock &MBB, MachineInstr *FirstNextMBBInstr,
-                                         MachineInstr &Slot) const {
+bool MipsDelaySlotFiller::searchBackward(
+    MachineBasicBlock &MBB, MachineInstr &Slot,
+    const BranchInformation &BranchInfo) const {
   if (DisableBackwardSearch)
     return false;
 
@@ -848,8 +908,8 @@ bool MipsDelaySlotFiller::searchBackward(MachineBasicBlock &MBB, MachineInstr *F
   RegDU.init(Slot);
 
   MachineBasicBlock::iterator SlotI = Slot;
-  if (!searchRange(MBB, FirstNextMBBInstr, ++SlotI.getReverse(), MBB.rend(), RegDU, MemDU, Slot,
-                   Filler)) {
+  if (!searchRange(MBB, ++SlotI.getReverse(), MBB.rend(), BranchInfo, RegDU,
+                   MemDU, Slot, Filler)) {
     LLVM_DEBUG(dbgs() << DEBUG_TYPE ": could not find instruction for delay "
                                     "slot using backwards search.\n");
     return false;
@@ -861,8 +921,9 @@ bool MipsDelaySlotFiller::searchBackward(MachineBasicBlock &MBB, MachineInstr *F
   return true;
 }
 
-bool MipsDelaySlotFiller::searchForward(MachineBasicBlock &MBB, MachineInstr *FirstNextMBBInstr,
-                                        Iter Slot) const {
+bool MipsDelaySlotFiller::searchForward(
+    MachineBasicBlock &MBB, Iter Slot,
+    const BranchInformation &BranchInfo) const {
   // Can handle only calls.
   if (DisableForwardSearch || !Slot->isCall())
     return false;
@@ -873,7 +934,8 @@ bool MipsDelaySlotFiller::searchForward(MachineBasicBlock &MBB, MachineInstr *Fi
 
   RegDU.setCallerSaved(*Slot);
 
-  if (!searchRange(MBB, FirstNextMBBInstr, std::next(Slot), MBB.end(), RegDU, NM, Slot, Filler)) {
+  if (!searchRange(MBB, std::next(Slot), MBB.end(), BranchInfo, RegDU, NM, Slot,
+                   Filler)) {
     LLVM_DEBUG(dbgs() << DEBUG_TYPE ": could not find instruction for delay "
                                     "slot using forwards search.\n");
     return false;
@@ -885,8 +947,9 @@ bool MipsDelaySlotFiller::searchForward(MachineBasicBlock &MBB, MachineInstr *Fi
   return true;
 }
 
-bool MipsDelaySlotFiller::searchSuccBBs(MachineBasicBlock &MBB, MachineInstr *FirstNextMBBInstr,
-                                        Iter Slot) const {
+bool MipsDelaySlotFiller::searchSuccBBs(
+    MachineBasicBlock &MBB, Iter Slot,
+    const BranchInformation &BranchInfo) const {
   if (DisableSuccBBSearch)
     return false;
 
@@ -920,8 +983,8 @@ bool MipsDelaySlotFiller::searchSuccBBs(MachineBasicBlock &MBB, MachineInstr *Fi
     IM.reset(new MemDefsUses(&MFI));
   }
 
-  if (!searchRange(MBB, FirstNextMBBInstr, SuccBB->begin(), SuccBB->end(), RegDU, *IM, Slot,
-                   Filler))
+  if (!searchRange(MBB, SuccBB->begin(), SuccBB->end(), BranchInfo, RegDU, *IM,
+                   Slot, Filler))
     return false;
 
   insertDelayFiller(Filler, BrMap);
@@ -1007,8 +1070,9 @@ bool MipsDelaySlotFiller::examinePred(MachineBasicBlock &Pred,
   return true;
 }
 
-bool MipsDelaySlotFiller::delayHasHazard(const MipsSubtarget& STI, const BranchTargets &BranchTarget,
+bool MipsDelaySlotFiller::delayHasHazard(const MipsSubtarget &STI,
                                          const MachineInstr &Candidate,
+                                         const BranchInformation &BranchInfo,
                                          RegDefsUses &RegDU,
                                          InspectMemInstr &IM) const {
   assert(!Candidate.isKill() &&
@@ -1024,43 +1088,37 @@ bool MipsDelaySlotFiller::delayHasHazard(const MipsSubtarget& STI, const BranchT
     const MipsInstrInfo* TII = STI.getInstrInfo();
     const bool HasLoadDelaySlot = TII->HasLoadDelaySlot(Candidate);
 
-    if(HasLoadDelaySlot) {
-      const auto [Branch, AfterBranchInstr] = BranchTarget;
+    if (HasLoadDelaySlot) {
       // We have no branch
-      if (!Branch) {
+      if (!BranchInfo.hasBranchInstr()) {
         errs() << "No branch?\n";
         return true;
       }
 
-      errs() << (Branch->isIndirectBranch() ? "Indirect-" : "")
-             << "Branch is: " << *Branch << "Candidate is: " << Candidate;
+      errs() << (BranchInfo.isIndirectBranch() ? "Indirect-" : "")
+             << "Branch is: " << *BranchInfo.getBranchInstr()
+             << "Candidate is: " << Candidate;
 
       // Being an indirect branch means we can not tell if we are a hazard
       // Assume the worst
-      if (Branch->isIndirectBranch()) {
-        errs()  << "\tNew Hazard?: Yes\n---\n";
+      if (BranchInfo.isIndirectBranch()) {
+        errs() << "\tNew Hazard?: Yes\n---\n";
         return true;
       }
 
-      // Check if this is a conditional branch by looking for an MBB operand
-      const MachineBasicBlock *TargetMBB = nullptr;
-      for (const MachineOperand &MO : Branch->operands()) {
-        if(MO.isMBB()) {
-          errs()  << "\t>>>" << MO << "<<<\n";
-          TargetMBB = MO.getMBB();
-        }
-      }
-
+      // If this is a direct branch we should find a MBB operand for the jump
+      // target
+      const MachineBasicBlock *TargetMBB = BranchInfo.getBranchTarget();
       if (!TargetMBB || TargetMBB->empty()) {
-        errs()  << "No or empty Target MBB found\n";
+        errs() << "No or empty Target MBB found\n";
         return true;
       }
 
       const auto &BranchTargetInstr = TargetMBB->instr_front();
-      errs()  << "\tDST->: " << BranchTargetInstr;
+      errs() << "\tDST->: " << BranchTargetInstr;
       errs() << "\tDST-v: ";
-      if (AfterBranchInstr) {
-        errs() << *AfterBranchInstr;
+      if (BranchInfo.hasBranchElseInstr()) {
+        errs() << *BranchInfo.getBranchElseInstr();
       } else {
         errs() << "<NONE>";
       }
@@ -1070,11 +1128,20 @@ bool MipsDelaySlotFiller::delayHasHazard(const MipsSubtarget& STI, const BranchT
           !TII->SafeInLoadDelaySlot(BranchTargetInstr, Candidate);
       // If the branch is unconditional then we do not need to bother to check
       // the next instruction after the branch
-      if (!Branch->isUnconditionalBranch() && AfterBranchInstr) {
-        HasNewHazard |= !TII->SafeInLoadDelaySlot(*AfterBranchInstr, Candidate);
+      if (!BranchInfo.isUnconditionalBranch()) {
+        // We are a conditional branch so we should have an `else` branch
+        if (BranchInfo.hasBranchElseInstr()) {
+          HasNewHazard |= !TII->SafeInLoadDelaySlot(
+              *BranchInfo.getBranchElseInstr(), Candidate);
+        }
+
+        else {
+          // Without the `else` branch we need to assume the worst
+          HasNewHazard = true;
+        }
       }
-      errs() << "\tNew Hazard?: " << (HasNewHazard ? "Yes" : "No") << "\n---\n";
 
+      errs() << "\tNew Hazard?: " << (HasNewHazard ? "Yes" : "No") << "\n---\n";
       return HasNewHazard;
     }
   }

>From a1a240b3f61ec9f69f3bb79fa97de7ba16d006a9 Mon Sep 17 00:00:00 2001
From: Jaby <jaby at william.zone>
Date: Tue, 24 Mar 2026 20:39:09 +0000
Subject: [PATCH 10/18] Make output be controlled by macro

---
 llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp | 27 ++++++++++++--------
 1 file changed, 16 insertions(+), 11 deletions(-)

diff --git a/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp b/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp
index 7b9bbbb15fcaf..eefe3387bdd4a 100644
--- a/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp
+++ b/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp
@@ -88,6 +88,11 @@ namespace {
   using ReverseIter = MachineBasicBlock::reverse_iterator;
   using BB2BrMap = SmallDenseMap<MachineBasicBlock *, MachineInstr *, 2>;
 
+  #if 0
+    #define tmp_out outs()
+  #else
+    #define tmp_out nulls()
+  #endif
   class BranchInformation {
   private:
     const MachineInstr *branch_instr = nullptr;
@@ -135,7 +140,7 @@ namespace {
 
       for (const MachineOperand &MO : this->branch_instr->operands()) {
         if (MO.isMBB()) {
-          errs() << "\t>>>" << MO << "<<<\n";
+          tmp_out << "\t>>>" << MO << "<<<\n";
           return MO.getMBB();
         }
       }
@@ -1091,18 +1096,18 @@ bool MipsDelaySlotFiller::delayHasHazard(const MipsSubtarget &STI,
     if (HasLoadDelaySlot) {
       // We have no branch
       if (!BranchInfo.hasBranchInstr()) {
-        errs() << "No branch?\n";
+        tmp_out << "No branch?\n";
         return true;
       }
 
-      errs() << (BranchInfo.isIndirectBranch() ? "Indirect-" : "")
+      tmp_out << (BranchInfo.isIndirectBranch() ? "Indirect-" : "")
              << "Branch is: " << *BranchInfo.getBranchInstr()
              << "Candidate is: " << Candidate;
 
       // Being an indirect branch means we can not tell if we are a hazard
       // Assume the worst
       if (BranchInfo.isIndirectBranch()) {
-        errs() << "\tNew Hazard?: Yes\n---\n";
+        tmp_out << "\tNew Hazard?: Yes\n---\n";
         return true;
       }
 
@@ -1110,19 +1115,19 @@ bool MipsDelaySlotFiller::delayHasHazard(const MipsSubtarget &STI,
       // target
       const MachineBasicBlock *TargetMBB = BranchInfo.getBranchTarget();
       if (!TargetMBB || TargetMBB->empty()) {
-        errs() << "No or empty Target MBB found\n";
+        tmp_out << "No or empty Target MBB found\n";
         return true;
       }
 
       const auto &BranchTargetInstr = TargetMBB->instr_front();
-      errs() << "\tDST->: " << BranchTargetInstr;
-      errs() << "\tDST-v: ";
+      tmp_out << "\tDST->: " << BranchTargetInstr;
+      tmp_out << "\tDST-v: ";
       if (BranchInfo.hasBranchElseInstr()) {
-        errs() << *BranchInfo.getBranchElseInstr();
+        tmp_out << *BranchInfo.getBranchElseInstr();
       } else {
-        errs() << "<NONE>";
+        tmp_out << "<NONE>";
       }
-      errs() << "\n";
+      tmp_out << "\n";
 
       bool HasNewHazard =
           !TII->SafeInLoadDelaySlot(BranchTargetInstr, Candidate);
@@ -1141,7 +1146,7 @@ bool MipsDelaySlotFiller::delayHasHazard(const MipsSubtarget &STI,
         }
       }
 
-      errs() << "\tNew Hazard?: " << (HasNewHazard ? "Yes" : "No") << "\n---\n";
+      tmp_out << "\tNew Hazard?: " << (HasNewHazard ? "Yes" : "No") << "\n---\n";
       return HasNewHazard;
     }
   }

>From 9dabcfc27da5579f77f4dd513e6e40ad443f0e1c Mon Sep 17 00:00:00 2001
From: Jaby <jaby at william.zone>
Date: Tue, 24 Mar 2026 21:00:19 +0000
Subject: [PATCH 11/18] Add more documentation

---
 llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp | 81 ++++++++++++--------
 1 file changed, 49 insertions(+), 32 deletions(-)

diff --git a/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp b/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp
index eefe3387bdd4a..005248f31a021 100644
--- a/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp
+++ b/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp
@@ -88,57 +88,71 @@ namespace {
   using ReverseIter = MachineBasicBlock::reverse_iterator;
   using BB2BrMap = SmallDenseMap<MachineBasicBlock *, MachineInstr *, 2>;
 
-  #if 0
-    #define tmp_out outs()
-  #else
-    #define tmp_out nulls()
-  #endif
+#if 0
+#define tmp_out outs()
+#else
+#define tmp_out nulls()
+#endif
+
+  // Holds information about one branch instruction
+  // This is used by the MIPS1 target to easily find all paths of a branch to
+  // then check the first instruction for possible load delay hazards
   class BranchInformation {
   private:
-    const MachineInstr *branch_instr = nullptr;
-    const MachineInstr *branch_else_instr = nullptr;
+    // The pointer to the actual branch instruction
+    const MachineInstr *BranchInstr = nullptr;
+    // The pointer to the instruction after the branch (= the `else` case)
+    const MachineInstr *ElseBranchInstr = nullptr;
 
   public:
-    BranchInformation(MachineInstrBundleIterator<MachineInstr> current_slot,
-                      MachineInstrBundleIterator<MachineInstr> mbb_end,
-                      const MachineInstr *next_mbb_instr)
-        : branch_instr(current_slot->isBranch() ? &(*current_slot) : nullptr),
-          branch_else_instr((++current_slot) == mbb_end ? next_mbb_instr
-                                                        : &(*current_slot)) {}
-
-    constexpr bool hasBranchInstr() const { return this->branch_instr; }
-
-    constexpr bool hasBranchElseInstr() const {
-      return this->branch_else_instr;
-    }
-
+    // Creates a new `BranchInformation` from the branch candidate `CurrentSlot`
+    // together with the end (`MBBEnd`) of the current MBB and the first
+    // instruction of the next MBB `NextMBBInstr`
+    BranchInformation(MachineInstrBundleIterator<MachineInstr> CurrentSlot,
+                      MachineInstrBundleIterator<MachineInstr> MBBEnd,
+                      const MachineInstr *NextMBBInstr)
+        : BranchInstr(CurrentSlot->isBranch() ? &(*CurrentSlot) : nullptr),
+          ElseBranchInstr((++CurrentSlot) == MBBEnd ? NextMBBInstr
+                                                    : &(*CurrentSlot)) {}
+
+    // Checks if we have a branch
+    constexpr bool hasBranchInstr() const { return this->BranchInstr; }
+
+    // Checks if we have an else branch
+    constexpr bool hasBranchElseInstr() const { return this->ElseBranchInstr; }
+
+    // Checks if we have an indirect branch
     constexpr bool isIndirectBranch() const {
-      if (this->branch_instr) {
-        return this->branch_instr->isIndirectBranch();
+      if (this->BranchInstr) {
+        return this->BranchInstr->isIndirectBranch();
       }
       return false;
     }
 
+    // Checks if we have an unconditional branch
     constexpr bool isUnconditionalBranch() const {
-      if (this->branch_instr) {
-        return this->branch_instr->isUnconditionalBranch();
+      if (this->BranchInstr) {
+        return this->BranchInstr->isUnconditionalBranch();
       }
       return false;
     }
 
-    const MachineInstr *getBranchInstr() const { return this->branch_instr; }
+    // Accesses the branch instruction
+    const MachineInstr *getBranchInstr() const { return this->BranchInstr; }
 
+    // Accesses the instruction after the branch
     const MachineInstr *getBranchElseInstr() const {
-      return this->branch_else_instr;
+      return this->ElseBranchInstr;
     }
 
+    // Gets the target of the branch
     const MachineBasicBlock *getBranchTarget() const {
       if (this->isIndirectBranch() || !this->hasBranchInstr()) {
         // Indirect branch has no known target
         return nullptr;
       }
 
-      for (const MachineOperand &MO : this->branch_instr->operands()) {
+      for (const MachineOperand &MO : this->BranchInstr->operands()) {
         if (MO.isMBB()) {
           tmp_out << "\t>>>" << MO << "<<<\n";
           return MO.getMBB();
@@ -1089,20 +1103,22 @@ bool MipsDelaySlotFiller::delayHasHazard(const MipsSubtarget &STI,
   HasHazard |= RegDU.update(Candidate, 0, Candidate.getNumOperands());
 
   // This only matters for MIPS1
-  if (!STI.hasMips2()) { //(!STI.hasMips2()) { // (STI.hasMips1()){
+  if (!STI.hasMips2()) {
     const MipsInstrInfo* TII = STI.getInstrInfo();
     const bool HasLoadDelaySlot = TII->HasLoadDelaySlot(Candidate);
 
+    // We only need to act if the candidate is having a load delay slot
     if (HasLoadDelaySlot) {
-      // We have no branch
+      // We have no branch so we can not determine a hazard
+      // Assume the worst
       if (!BranchInfo.hasBranchInstr()) {
         tmp_out << "No branch?\n";
         return true;
       }
 
       tmp_out << (BranchInfo.isIndirectBranch() ? "Indirect-" : "")
-             << "Branch is: " << *BranchInfo.getBranchInstr()
-             << "Candidate is: " << Candidate;
+              << "Branch is: " << *BranchInfo.getBranchInstr()
+              << "Candidate is: " << Candidate;
 
       // Being an indirect branch means we can not tell if we are a hazard
       // Assume the worst
@@ -1146,7 +1162,8 @@ bool MipsDelaySlotFiller::delayHasHazard(const MipsSubtarget &STI,
         }
       }
 
-      tmp_out << "\tNew Hazard?: " << (HasNewHazard ? "Yes" : "No") << "\n---\n";
+      tmp_out << "\tNew Hazard?: " << (HasNewHazard ? "Yes" : "No")
+              << "\n---\n";
       return HasNewHazard;
     }
   }

>From e406e69102e5170b4198a2b7b42552bcf0ff8f61 Mon Sep 17 00:00:00 2001
From: Jaby <jaby at william.zone>
Date: Sun, 29 Mar 2026 17:37:31 +0100
Subject: [PATCH 12/18] Fix crash on pseudo instruction

---
 llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp | 20 +++++++++++++++++---
 1 file changed, 17 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp b/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp
index 005248f31a021..3bf81f1e93b0a 100644
--- a/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp
+++ b/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp
@@ -104,6 +104,15 @@ namespace {
     // The pointer to the instruction after the branch (= the `else` case)
     const MachineInstr *ElseBranchInstr = nullptr;
 
+    // Check if `Adr` is a pseudo instruction and if so, then treat it as non
+    // existing
+    static const MachineInstr *filterPseudoInstr(const MachineInstr *Adr) {
+      if (Adr && !Adr->isPseudo()) {
+        return Adr;
+      }
+      return nullptr;
+    }
+
   public:
     // Creates a new `BranchInformation` from the branch candidate `CurrentSlot`
     // together with the end (`MBBEnd`) of the current MBB and the first
@@ -111,9 +120,14 @@ namespace {
     BranchInformation(MachineInstrBundleIterator<MachineInstr> CurrentSlot,
                       MachineInstrBundleIterator<MachineInstr> MBBEnd,
                       const MachineInstr *NextMBBInstr)
-        : BranchInstr(CurrentSlot->isBranch() ? &(*CurrentSlot) : nullptr),
-          ElseBranchInstr((++CurrentSlot) == MBBEnd ? NextMBBInstr
-                                                    : &(*CurrentSlot)) {}
+        : BranchInstr(
+              CurrentSlot->isBranch()
+                  ? BranchInformation::filterPseudoInstr(&(*CurrentSlot))
+                  : nullptr),
+          ElseBranchInstr(
+              (++CurrentSlot) == MBBEnd
+                  ? BranchInformation::filterPseudoInstr(NextMBBInstr)
+                  : BranchInformation::filterPseudoInstr(&(*CurrentSlot))) {}
 
     // Checks if we have a branch
     constexpr bool hasBranchInstr() const { return this->BranchInstr; }

>From 21e4623dde8306a3c408559e11b0b50104c2e27c Mon Sep 17 00:00:00 2001
From: William Young <william at werl.me>
Date: Sun, 29 Mar 2026 17:15:15 +0000
Subject: [PATCH 13/18] Add tests

---
 llvm/test/CodeGen/Mips/gprestore.ll           |  50 +++
 llvm/test/CodeGen/Mips/llvm-ir/load.ll        | 333 +++++++++++++-----
 llvm/test/CodeGen/Mips/llvm-ir/select-dbl.ll  | 259 ++++++++++++--
 .../CodeGen/Mips/mips1-load-in-delay-slot.ll  |  61 ++++
 llvm/test/CodeGen/Mips/unalignedload.ll       |  68 +++-
 5 files changed, 646 insertions(+), 125 deletions(-)
 create mode 100644 llvm/test/CodeGen/Mips/mips1-load-in-delay-slot.ll

diff --git a/llvm/test/CodeGen/Mips/gprestore.ll b/llvm/test/CodeGen/Mips/gprestore.ll
index 889685022264b..674a197ca438f 100644
--- a/llvm/test/CodeGen/Mips/gprestore.ll
+++ b/llvm/test/CodeGen/Mips/gprestore.ll
@@ -5,6 +5,7 @@
 ; RUN: llc -mtriple=mips-mti-linux-gnu < %s -relocation-model=pic -O3 -mips-jalr-reloc=false | FileCheck %s --check-prefix=O3O32
 ; RUN: llc -mtriple=mips64-mti-linux-gnu < %s -relocation-model=pic -O3 -mips-jalr-reloc=false | FileCheck %s --check-prefix=O3N64
 ; RUN: llc -mtriple=mips64-mti-linux-gnu < %s -relocation-model=pic -target-abi n32 -O3 -mips-jalr-reloc=false | FileCheck %s --check-prefix=O3N32
+; RUN: llc -mtriple=mipsel-sony-psx -mcpu=mips1 < %s -relocation-model=pic | FileCheck %s -check-prefixes=MIPS1-PSX
 
 ; Test that PIC calls use the $25 register. This is an ABI requirement.
 
@@ -208,6 +209,55 @@ define void @f0() nounwind {
 ; O3N32-NEXT:    ld $ra, 24($sp) # 8-byte Folded Reload
 ; O3N32-NEXT:    jr $ra
 ; O3N32-NEXT:    addiu $sp, $sp, 32
+;
+; MIPS1-PSX-LABEL: f0:
+; MIPS1-PSX:       # %bb.0: # %entry
+; MIPS1-PSX-NEXT:    lui $2, %hi(_gp_disp)
+; MIPS1-PSX-NEXT:    addiu $2, $2, %lo(_gp_disp)
+; MIPS1-PSX-NEXT:    addiu $sp, $sp, -32
+; MIPS1-PSX-NEXT:    sw $ra, 28($sp) # 4-byte Folded Spill
+; MIPS1-PSX-NEXT:    sw $17, 24($sp) # 4-byte Folded Spill
+; MIPS1-PSX-NEXT:    sw $16, 20($sp) # 4-byte Folded Spill
+; MIPS1-PSX-NEXT:    addu $16, $2, $25
+; MIPS1-PSX-NEXT:    lw $25, %call16(f1)($16)
+; MIPS1-PSX-NEXT:    nop
+; MIPS1-PSX-NEXT:    .reloc $tmp0, R_MIPS_JALR, f1
+; MIPS1-PSX-NEXT:  $tmp0:
+; MIPS1-PSX-NEXT:    jalr $25
+; MIPS1-PSX-NEXT:    move $gp, $16
+; MIPS1-PSX-NEXT:    lw $1, %got(p)($16)
+; MIPS1-PSX-NEXT:    nop
+; MIPS1-PSX-NEXT:    lw $4, 0($1)
+; MIPS1-PSX-NEXT:    lw $25, %call16(f2)($16)
+; MIPS1-PSX-NEXT:    nop
+; MIPS1-PSX-NEXT:    .reloc $tmp1, R_MIPS_JALR, f2
+; MIPS1-PSX-NEXT:  $tmp1:
+; MIPS1-PSX-NEXT:    jalr $25
+; MIPS1-PSX-NEXT:    move $gp, $16
+; MIPS1-PSX-NEXT:    lw $1, %got(q)($16)
+; MIPS1-PSX-NEXT:    nop
+; MIPS1-PSX-NEXT:    lw $17, 0($1)
+; MIPS1-PSX-NEXT:    lw $25, %call16(f2)($16)
+; MIPS1-PSX-NEXT:    nop
+; MIPS1-PSX-NEXT:    .reloc $tmp2, R_MIPS_JALR, f2
+; MIPS1-PSX-NEXT:  $tmp2:
+; MIPS1-PSX-NEXT:    jalr $25
+; MIPS1-PSX-NEXT:    move $4, $17
+; MIPS1-PSX-NEXT:    lw $1, %got(r)($16)
+; MIPS1-PSX-NEXT:    nop
+; MIPS1-PSX-NEXT:    lw $5, 0($1)
+; MIPS1-PSX-NEXT:    lw $25, %call16(f3)($16)
+; MIPS1-PSX-NEXT:    move $4, $17
+; MIPS1-PSX-NEXT:    .reloc $tmp3, R_MIPS_JALR, f3
+; MIPS1-PSX-NEXT:  $tmp3:
+; MIPS1-PSX-NEXT:    jalr $25
+; MIPS1-PSX-NEXT:    move $gp, $16
+; MIPS1-PSX-NEXT:    lw $16, 20($sp) # 4-byte Folded Reload
+; MIPS1-PSX-NEXT:    lw $17, 24($sp) # 4-byte Folded Reload
+; MIPS1-PSX-NEXT:    lw $ra, 28($sp) # 4-byte Folded Reload
+; MIPS1-PSX-NEXT:    nop
+; MIPS1-PSX-NEXT:    jr $ra
+; MIPS1-PSX-NEXT:    addiu $sp, $sp, 32
 entry:
   tail call void @f1() nounwind
   %tmp = load i32, ptr @p, align 4
diff --git a/llvm/test/CodeGen/Mips/llvm-ir/load.ll b/llvm/test/CodeGen/Mips/llvm-ir/load.ll
index f81e1a742e44c..232d74677914f 100644
--- a/llvm/test/CodeGen/Mips/llvm-ir/load.ll
+++ b/llvm/test/CodeGen/Mips/llvm-ir/load.ll
@@ -8,6 +8,7 @@
 ; RUN: llc -mtriple=mips64-img-linux-gnu -mcpu=mips64r6 < %s -asm-show-inst | FileCheck %s --check-prefix=MIPS64R6
 ; RUN: llc -mtriple=mips-mti-linux-gnu -mcpu=mips32r2 -mattr=+micromips,+fp64 < %s -asm-show-inst | FileCheck %s --check-prefix=MMR5FP64
 ; RUN: llc -mtriple=mips-mti-linux-gnu -mcpu=mips32r5 -mattr=+fp64 < %s -asm-show-inst | FileCheck %s --check-prefix=MIPS32R5FP643
+; RUN: llc -mtriple=mipsel-sony-psx -mcpu=mips1 < %s -asm-show-inst | FileCheck %s -check-prefixes=MIPS1-PSX
 
 ; Test subword and word loads. We use -asm-show-inst to test that the produced
 ; instructions match the expected ISA.
@@ -180,6 +181,26 @@ define i8 @f1() {
 ; MIPS32R5FP643-NEXT:    # <MCOperand Reg:V0>
 ; MIPS32R5FP643-NEXT:    # <MCOperand Reg:AT>
 ; MIPS32R5FP643-NEXT:    # <MCOperand Expr:%lo(a)>>
+;
+; MIPS1-PSX-LABEL: f1:
+; MIPS1-PSX:       # %bb.0: # %entry
+; MIPS1-PSX-NEXT:    lui $1, %hi(a) # <MCInst #[[#MCINST1:]] LUi
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:AT>
+; MIPS1-PSX-NEXT:    # <MCOperand Expr:%hi(a)>>
+; MIPS1-PSX-NEXT:    lbu $2, %lo(a)($1) # <MCInst #[[#MCINST3:]] LBu
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:V0>
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:AT>
+; MIPS1-PSX-NEXT:    # <MCOperand Expr:%lo(a)>>
+; MIPS1-PSX-NEXT:    nop # <MCInst #[[#MCINST13:]] SLL
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:ZERO>
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:ZERO>
+; MIPS1-PSX-NEXT:    # <MCOperand Imm:0>>
+; MIPS1-PSX-NEXT:    jr $ra # <MCInst #[[#MCINST2:]] JR
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:RA>>
+; MIPS1-PSX-NEXT:    nop # <MCInst #[[#MCINST13]] SLL
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:ZERO>
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:ZERO>
+; MIPS1-PSX-NEXT:    # <MCOperand Imm:0>>
 entry:
   %0 = load i8, ptr @a
   ret i8 %0
@@ -193,7 +214,7 @@ define i32 @f2() {
 ; MIPS32-NEXT:    # <MCOperand Expr:%hi(a)>>
 ; MIPS32-NEXT:    jr $ra # <MCInst #[[#MCINST2]] JR
 ; MIPS32-NEXT:    # <MCOperand Reg:RA>>
-; MIPS32-NEXT:    lb $2, %lo(a)($1) # <MCInst #[[#MCINST13:]] LB
+; MIPS32-NEXT:    lb $2, %lo(a)($1) # <MCInst #[[#MCINST14:]] LB
 ; MIPS32-NEXT:    # <MCOperand Reg:V0>
 ; MIPS32-NEXT:    # <MCOperand Reg:AT>
 ; MIPS32-NEXT:    # <MCOperand Expr:%lo(a)>>
@@ -205,7 +226,7 @@ define i32 @f2() {
 ; MMR3-NEXT:    # <MCOperand Expr:%hi(a)>>
 ; MMR3-NEXT:    jr $ra # <MCInst #[[#MCINST5]] JR_MM
 ; MMR3-NEXT:    # <MCOperand Reg:RA>>
-; MMR3-NEXT:    lb $2, %lo(a)($1) # <MCInst #[[#MCINST14:]] LB_MM
+; MMR3-NEXT:    lb $2, %lo(a)($1) # <MCInst #[[#MCINST15:]] LB_MM
 ; MMR3-NEXT:    # <MCOperand Reg:V0>
 ; MMR3-NEXT:    # <MCOperand Reg:AT>
 ; MMR3-NEXT:    # <MCOperand Expr:%lo(a)>>
@@ -218,7 +239,7 @@ define i32 @f2() {
 ; MIPS32R6-NEXT:    jr $ra # <MCInst #[[#MCINST7]] JALR
 ; MIPS32R6-NEXT:    # <MCOperand Reg:ZERO>
 ; MIPS32R6-NEXT:    # <MCOperand Reg:RA>>
-; MIPS32R6-NEXT:    lb $2, %lo(a)($1) # <MCInst #[[#MCINST13:]] LB
+; MIPS32R6-NEXT:    lb $2, %lo(a)($1) # <MCInst #[[#MCINST14:]] LB
 ; MIPS32R6-NEXT:    # <MCOperand Reg:V0>
 ; MIPS32R6-NEXT:    # <MCOperand Reg:AT>
 ; MIPS32R6-NEXT:    # <MCOperand Expr:%lo(a)>>
@@ -228,7 +249,7 @@ define i32 @f2() {
 ; MMR6-NEXT:    lui $1, %hi(a) # <MCInst #[[#MCINST4]] LUi_MM
 ; MMR6-NEXT:    # <MCOperand Reg:AT>
 ; MMR6-NEXT:    # <MCOperand Expr:%hi(a)>>
-; MMR6-NEXT:    lb $2, %lo(a)($1) # <MCInst #[[#MCINST14:]] LB_MM
+; MMR6-NEXT:    lb $2, %lo(a)($1) # <MCInst #[[#MCINST15:]] LB_MM
 ; MMR6-NEXT:    # <MCOperand Reg:V0>
 ; MMR6-NEXT:    # <MCOperand Reg:AT>
 ; MMR6-NEXT:    # <MCOperand Expr:%lo(a)>>
@@ -258,7 +279,7 @@ define i32 @f2() {
 ; MIPS3-NEXT:    # <MCOperand Imm:16>>
 ; MIPS3-NEXT:    jr $ra # <MCInst #[[#MCINST2]] JR
 ; MIPS3-NEXT:    # <MCOperand Reg:RA_64>>
-; MIPS3-NEXT:    lb $2, %lo(a)($1) # <MCInst #[[#MCINST13:]] LB
+; MIPS3-NEXT:    lb $2, %lo(a)($1) # <MCInst #[[#MCINST14:]] LB
 ; MIPS3-NEXT:    # <MCOperand Reg:V0>
 ; MIPS3-NEXT:    # <MCOperand Reg:AT_64>
 ; MIPS3-NEXT:    # <MCOperand Expr:%lo(a)>>
@@ -286,7 +307,7 @@ define i32 @f2() {
 ; MIPS64-NEXT:    # <MCOperand Imm:16>>
 ; MIPS64-NEXT:    jr $ra # <MCInst #[[#MCINST2]] JR
 ; MIPS64-NEXT:    # <MCOperand Reg:RA_64>>
-; MIPS64-NEXT:    lb $2, %lo(a)($1) # <MCInst #[[#MCINST13:]] LB
+; MIPS64-NEXT:    lb $2, %lo(a)($1) # <MCInst #[[#MCINST14:]] LB
 ; MIPS64-NEXT:    # <MCOperand Reg:V0>
 ; MIPS64-NEXT:    # <MCOperand Reg:AT_64>
 ; MIPS64-NEXT:    # <MCOperand Expr:%lo(a)>>
@@ -315,7 +336,7 @@ define i32 @f2() {
 ; MIPS64R6-NEXT:    jr $ra # <MCInst #[[#MCINST12]] JALR64
 ; MIPS64R6-NEXT:    # <MCOperand Reg:ZERO_64>
 ; MIPS64R6-NEXT:    # <MCOperand Reg:RA_64>>
-; MIPS64R6-NEXT:    lb $2, %lo(a)($1) # <MCInst #[[#MCINST13:]] LB
+; MIPS64R6-NEXT:    lb $2, %lo(a)($1) # <MCInst #[[#MCINST14:]] LB
 ; MIPS64R6-NEXT:    # <MCOperand Reg:V0>
 ; MIPS64R6-NEXT:    # <MCOperand Reg:AT_64>
 ; MIPS64R6-NEXT:    # <MCOperand Expr:%lo(a)>>
@@ -327,7 +348,7 @@ define i32 @f2() {
 ; MMR5FP64-NEXT:    # <MCOperand Expr:%hi(a)>>
 ; MMR5FP64-NEXT:    jr $ra # <MCInst #[[#MCINST5]] JR_MM
 ; MMR5FP64-NEXT:    # <MCOperand Reg:RA>>
-; MMR5FP64-NEXT:    lb $2, %lo(a)($1) # <MCInst #[[#MCINST14:]] LB_MM
+; MMR5FP64-NEXT:    lb $2, %lo(a)($1) # <MCInst #[[#MCINST15:]] LB_MM
 ; MMR5FP64-NEXT:    # <MCOperand Reg:V0>
 ; MMR5FP64-NEXT:    # <MCOperand Reg:AT>
 ; MMR5FP64-NEXT:    # <MCOperand Expr:%lo(a)>>
@@ -339,10 +360,30 @@ define i32 @f2() {
 ; MIPS32R5FP643-NEXT:    # <MCOperand Expr:%hi(a)>>
 ; MIPS32R5FP643-NEXT:    jr $ra # <MCInst #[[#MCINST2]] JR
 ; MIPS32R5FP643-NEXT:    # <MCOperand Reg:RA>>
-; MIPS32R5FP643-NEXT:    lb $2, %lo(a)($1) # <MCInst #[[#MCINST13:]] LB
+; MIPS32R5FP643-NEXT:    lb $2, %lo(a)($1) # <MCInst #[[#MCINST14:]] LB
 ; MIPS32R5FP643-NEXT:    # <MCOperand Reg:V0>
 ; MIPS32R5FP643-NEXT:    # <MCOperand Reg:AT>
 ; MIPS32R5FP643-NEXT:    # <MCOperand Expr:%lo(a)>>
+;
+; MIPS1-PSX-LABEL: f2:
+; MIPS1-PSX:       # %bb.0: # %entry
+; MIPS1-PSX-NEXT:    lui $1, %hi(a) # <MCInst #[[#MCINST1]] LUi
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:AT>
+; MIPS1-PSX-NEXT:    # <MCOperand Expr:%hi(a)>>
+; MIPS1-PSX-NEXT:    lb $2, %lo(a)($1) # <MCInst #[[#MCINST14:]] LB
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:V0>
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:AT>
+; MIPS1-PSX-NEXT:    # <MCOperand Expr:%lo(a)>>
+; MIPS1-PSX-NEXT:    nop # <MCInst #[[#MCINST13]] SLL
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:ZERO>
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:ZERO>
+; MIPS1-PSX-NEXT:    # <MCOperand Imm:0>>
+; MIPS1-PSX-NEXT:    jr $ra # <MCInst #[[#MCINST2]] JR
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:RA>>
+; MIPS1-PSX-NEXT:    nop # <MCInst #[[#MCINST13]] SLL
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:ZERO>
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:ZERO>
+; MIPS1-PSX-NEXT:    # <MCOperand Imm:0>>
 entry:
   %0 = load i8, ptr @a
   %1 = sext i8 %0 to i32
@@ -357,7 +398,7 @@ define i16 @f3() {
 ; MIPS32-NEXT:    # <MCOperand Expr:%hi(b)>>
 ; MIPS32-NEXT:    jr $ra # <MCInst #[[#MCINST2]] JR
 ; MIPS32-NEXT:    # <MCOperand Reg:RA>>
-; MIPS32-NEXT:    lhu $2, %lo(b)($1) # <MCInst #[[#MCINST15:]] LHu
+; MIPS32-NEXT:    lhu $2, %lo(b)($1) # <MCInst #[[#MCINST16:]] LHu
 ; MIPS32-NEXT:    # <MCOperand Reg:V0>
 ; MIPS32-NEXT:    # <MCOperand Reg:AT>
 ; MIPS32-NEXT:    # <MCOperand Expr:%lo(b)>>
@@ -369,7 +410,7 @@ define i16 @f3() {
 ; MMR3-NEXT:    # <MCOperand Expr:%hi(b)>>
 ; MMR3-NEXT:    jr $ra # <MCInst #[[#MCINST5]] JR_MM
 ; MMR3-NEXT:    # <MCOperand Reg:RA>>
-; MMR3-NEXT:    lhu $2, %lo(b)($1) # <MCInst #[[#MCINST16:]] LHu_MM
+; MMR3-NEXT:    lhu $2, %lo(b)($1) # <MCInst #[[#MCINST17:]] LHu_MM
 ; MMR3-NEXT:    # <MCOperand Reg:V0>
 ; MMR3-NEXT:    # <MCOperand Reg:AT>
 ; MMR3-NEXT:    # <MCOperand Expr:%lo(b)>>
@@ -382,7 +423,7 @@ define i16 @f3() {
 ; MIPS32R6-NEXT:    jr $ra # <MCInst #[[#MCINST7]] JALR
 ; MIPS32R6-NEXT:    # <MCOperand Reg:ZERO>
 ; MIPS32R6-NEXT:    # <MCOperand Reg:RA>>
-; MIPS32R6-NEXT:    lhu $2, %lo(b)($1) # <MCInst #[[#MCINST15:]] LHu
+; MIPS32R6-NEXT:    lhu $2, %lo(b)($1) # <MCInst #[[#MCINST16:]] LHu
 ; MIPS32R6-NEXT:    # <MCOperand Reg:V0>
 ; MIPS32R6-NEXT:    # <MCOperand Reg:AT>
 ; MIPS32R6-NEXT:    # <MCOperand Expr:%lo(b)>>
@@ -392,7 +433,7 @@ define i16 @f3() {
 ; MMR6-NEXT:    lui $1, %hi(b) # <MCInst #[[#MCINST4]] LUi_MM
 ; MMR6-NEXT:    # <MCOperand Reg:AT>
 ; MMR6-NEXT:    # <MCOperand Expr:%hi(b)>>
-; MMR6-NEXT:    lhu $2, %lo(b)($1) # <MCInst #[[#MCINST16:]] LHu_MM
+; MMR6-NEXT:    lhu $2, %lo(b)($1) # <MCInst #[[#MCINST17:]] LHu_MM
 ; MMR6-NEXT:    # <MCOperand Reg:V0>
 ; MMR6-NEXT:    # <MCOperand Reg:AT>
 ; MMR6-NEXT:    # <MCOperand Expr:%lo(b)>>
@@ -422,7 +463,7 @@ define i16 @f3() {
 ; MIPS3-NEXT:    # <MCOperand Imm:16>>
 ; MIPS3-NEXT:    jr $ra # <MCInst #[[#MCINST2]] JR
 ; MIPS3-NEXT:    # <MCOperand Reg:RA_64>>
-; MIPS3-NEXT:    lhu $2, %lo(b)($1) # <MCInst #[[#MCINST15:]] LHu
+; MIPS3-NEXT:    lhu $2, %lo(b)($1) # <MCInst #[[#MCINST16:]] LHu
 ; MIPS3-NEXT:    # <MCOperand Reg:V0>
 ; MIPS3-NEXT:    # <MCOperand Reg:AT_64>
 ; MIPS3-NEXT:    # <MCOperand Expr:%lo(b)>>
@@ -450,7 +491,7 @@ define i16 @f3() {
 ; MIPS64-NEXT:    # <MCOperand Imm:16>>
 ; MIPS64-NEXT:    jr $ra # <MCInst #[[#MCINST2]] JR
 ; MIPS64-NEXT:    # <MCOperand Reg:RA_64>>
-; MIPS64-NEXT:    lhu $2, %lo(b)($1) # <MCInst #[[#MCINST15:]] LHu
+; MIPS64-NEXT:    lhu $2, %lo(b)($1) # <MCInst #[[#MCINST16:]] LHu
 ; MIPS64-NEXT:    # <MCOperand Reg:V0>
 ; MIPS64-NEXT:    # <MCOperand Reg:AT_64>
 ; MIPS64-NEXT:    # <MCOperand Expr:%lo(b)>>
@@ -479,7 +520,7 @@ define i16 @f3() {
 ; MIPS64R6-NEXT:    jr $ra # <MCInst #[[#MCINST12]] JALR64
 ; MIPS64R6-NEXT:    # <MCOperand Reg:ZERO_64>
 ; MIPS64R6-NEXT:    # <MCOperand Reg:RA_64>>
-; MIPS64R6-NEXT:    lhu $2, %lo(b)($1) # <MCInst #[[#MCINST15:]] LHu
+; MIPS64R6-NEXT:    lhu $2, %lo(b)($1) # <MCInst #[[#MCINST16:]] LHu
 ; MIPS64R6-NEXT:    # <MCOperand Reg:V0>
 ; MIPS64R6-NEXT:    # <MCOperand Reg:AT_64>
 ; MIPS64R6-NEXT:    # <MCOperand Expr:%lo(b)>>
@@ -491,7 +532,7 @@ define i16 @f3() {
 ; MMR5FP64-NEXT:    # <MCOperand Expr:%hi(b)>>
 ; MMR5FP64-NEXT:    jr $ra # <MCInst #[[#MCINST5]] JR_MM
 ; MMR5FP64-NEXT:    # <MCOperand Reg:RA>>
-; MMR5FP64-NEXT:    lhu $2, %lo(b)($1) # <MCInst #[[#MCINST16:]] LHu_MM
+; MMR5FP64-NEXT:    lhu $2, %lo(b)($1) # <MCInst #[[#MCINST17:]] LHu_MM
 ; MMR5FP64-NEXT:    # <MCOperand Reg:V0>
 ; MMR5FP64-NEXT:    # <MCOperand Reg:AT>
 ; MMR5FP64-NEXT:    # <MCOperand Expr:%lo(b)>>
@@ -503,10 +544,30 @@ define i16 @f3() {
 ; MIPS32R5FP643-NEXT:    # <MCOperand Expr:%hi(b)>>
 ; MIPS32R5FP643-NEXT:    jr $ra # <MCInst #[[#MCINST2]] JR
 ; MIPS32R5FP643-NEXT:    # <MCOperand Reg:RA>>
-; MIPS32R5FP643-NEXT:    lhu $2, %lo(b)($1) # <MCInst #[[#MCINST15:]] LHu
+; MIPS32R5FP643-NEXT:    lhu $2, %lo(b)($1) # <MCInst #[[#MCINST16:]] LHu
 ; MIPS32R5FP643-NEXT:    # <MCOperand Reg:V0>
 ; MIPS32R5FP643-NEXT:    # <MCOperand Reg:AT>
 ; MIPS32R5FP643-NEXT:    # <MCOperand Expr:%lo(b)>>
+;
+; MIPS1-PSX-LABEL: f3:
+; MIPS1-PSX:       # %bb.0: # %entry
+; MIPS1-PSX-NEXT:    lui $1, %hi(b) # <MCInst #[[#MCINST1]] LUi
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:AT>
+; MIPS1-PSX-NEXT:    # <MCOperand Expr:%hi(b)>>
+; MIPS1-PSX-NEXT:    lhu $2, %lo(b)($1) # <MCInst #[[#MCINST16:]] LHu
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:V0>
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:AT>
+; MIPS1-PSX-NEXT:    # <MCOperand Expr:%lo(b)>>
+; MIPS1-PSX-NEXT:    nop # <MCInst #[[#MCINST13]] SLL
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:ZERO>
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:ZERO>
+; MIPS1-PSX-NEXT:    # <MCOperand Imm:0>>
+; MIPS1-PSX-NEXT:    jr $ra # <MCInst #[[#MCINST2]] JR
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:RA>>
+; MIPS1-PSX-NEXT:    nop # <MCInst #[[#MCINST13]] SLL
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:ZERO>
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:ZERO>
+; MIPS1-PSX-NEXT:    # <MCOperand Imm:0>>
 entry:
   %0 = load i16, ptr @b
   ret i16 %0
@@ -520,7 +581,7 @@ define i32 @f4() {
 ; MIPS32-NEXT:    # <MCOperand Expr:%hi(b)>>
 ; MIPS32-NEXT:    jr $ra # <MCInst #[[#MCINST2]] JR
 ; MIPS32-NEXT:    # <MCOperand Reg:RA>>
-; MIPS32-NEXT:    lh $2, %lo(b)($1) # <MCInst #[[#MCINST17:]] LH
+; MIPS32-NEXT:    lh $2, %lo(b)($1) # <MCInst #[[#MCINST18:]] LH
 ; MIPS32-NEXT:    # <MCOperand Reg:V0>
 ; MIPS32-NEXT:    # <MCOperand Reg:AT>
 ; MIPS32-NEXT:    # <MCOperand Expr:%lo(b)>>
@@ -532,7 +593,7 @@ define i32 @f4() {
 ; MMR3-NEXT:    # <MCOperand Expr:%hi(b)>>
 ; MMR3-NEXT:    jr $ra # <MCInst #[[#MCINST5]] JR_MM
 ; MMR3-NEXT:    # <MCOperand Reg:RA>>
-; MMR3-NEXT:    lh $2, %lo(b)($1) # <MCInst #[[#MCINST18:]] LH_MM
+; MMR3-NEXT:    lh $2, %lo(b)($1) # <MCInst #[[#MCINST19:]] LH_MM
 ; MMR3-NEXT:    # <MCOperand Reg:V0>
 ; MMR3-NEXT:    # <MCOperand Reg:AT>
 ; MMR3-NEXT:    # <MCOperand Expr:%lo(b)>>
@@ -545,7 +606,7 @@ define i32 @f4() {
 ; MIPS32R6-NEXT:    jr $ra # <MCInst #[[#MCINST7]] JALR
 ; MIPS32R6-NEXT:    # <MCOperand Reg:ZERO>
 ; MIPS32R6-NEXT:    # <MCOperand Reg:RA>>
-; MIPS32R6-NEXT:    lh $2, %lo(b)($1) # <MCInst #[[#MCINST17:]] LH
+; MIPS32R6-NEXT:    lh $2, %lo(b)($1) # <MCInst #[[#MCINST18:]] LH
 ; MIPS32R6-NEXT:    # <MCOperand Reg:V0>
 ; MIPS32R6-NEXT:    # <MCOperand Reg:AT>
 ; MIPS32R6-NEXT:    # <MCOperand Expr:%lo(b)>>
@@ -555,7 +616,7 @@ define i32 @f4() {
 ; MMR6-NEXT:    lui $1, %hi(b) # <MCInst #[[#MCINST4]] LUi_MM
 ; MMR6-NEXT:    # <MCOperand Reg:AT>
 ; MMR6-NEXT:    # <MCOperand Expr:%hi(b)>>
-; MMR6-NEXT:    lh $2, %lo(b)($1) # <MCInst #[[#MCINST18:]] LH_MM
+; MMR6-NEXT:    lh $2, %lo(b)($1) # <MCInst #[[#MCINST19:]] LH_MM
 ; MMR6-NEXT:    # <MCOperand Reg:V0>
 ; MMR6-NEXT:    # <MCOperand Reg:AT>
 ; MMR6-NEXT:    # <MCOperand Expr:%lo(b)>>
@@ -585,7 +646,7 @@ define i32 @f4() {
 ; MIPS3-NEXT:    # <MCOperand Imm:16>>
 ; MIPS3-NEXT:    jr $ra # <MCInst #[[#MCINST2]] JR
 ; MIPS3-NEXT:    # <MCOperand Reg:RA_64>>
-; MIPS3-NEXT:    lh $2, %lo(b)($1) # <MCInst #[[#MCINST17:]] LH
+; MIPS3-NEXT:    lh $2, %lo(b)($1) # <MCInst #[[#MCINST18:]] LH
 ; MIPS3-NEXT:    # <MCOperand Reg:V0>
 ; MIPS3-NEXT:    # <MCOperand Reg:AT_64>
 ; MIPS3-NEXT:    # <MCOperand Expr:%lo(b)>>
@@ -613,7 +674,7 @@ define i32 @f4() {
 ; MIPS64-NEXT:    # <MCOperand Imm:16>>
 ; MIPS64-NEXT:    jr $ra # <MCInst #[[#MCINST2]] JR
 ; MIPS64-NEXT:    # <MCOperand Reg:RA_64>>
-; MIPS64-NEXT:    lh $2, %lo(b)($1) # <MCInst #[[#MCINST17:]] LH
+; MIPS64-NEXT:    lh $2, %lo(b)($1) # <MCInst #[[#MCINST18:]] LH
 ; MIPS64-NEXT:    # <MCOperand Reg:V0>
 ; MIPS64-NEXT:    # <MCOperand Reg:AT_64>
 ; MIPS64-NEXT:    # <MCOperand Expr:%lo(b)>>
@@ -642,7 +703,7 @@ define i32 @f4() {
 ; MIPS64R6-NEXT:    jr $ra # <MCInst #[[#MCINST12]] JALR64
 ; MIPS64R6-NEXT:    # <MCOperand Reg:ZERO_64>
 ; MIPS64R6-NEXT:    # <MCOperand Reg:RA_64>>
-; MIPS64R6-NEXT:    lh $2, %lo(b)($1) # <MCInst #[[#MCINST17:]] LH
+; MIPS64R6-NEXT:    lh $2, %lo(b)($1) # <MCInst #[[#MCINST18:]] LH
 ; MIPS64R6-NEXT:    # <MCOperand Reg:V0>
 ; MIPS64R6-NEXT:    # <MCOperand Reg:AT_64>
 ; MIPS64R6-NEXT:    # <MCOperand Expr:%lo(b)>>
@@ -654,7 +715,7 @@ define i32 @f4() {
 ; MMR5FP64-NEXT:    # <MCOperand Expr:%hi(b)>>
 ; MMR5FP64-NEXT:    jr $ra # <MCInst #[[#MCINST5]] JR_MM
 ; MMR5FP64-NEXT:    # <MCOperand Reg:RA>>
-; MMR5FP64-NEXT:    lh $2, %lo(b)($1) # <MCInst #[[#MCINST18:]] LH_MM
+; MMR5FP64-NEXT:    lh $2, %lo(b)($1) # <MCInst #[[#MCINST19:]] LH_MM
 ; MMR5FP64-NEXT:    # <MCOperand Reg:V0>
 ; MMR5FP64-NEXT:    # <MCOperand Reg:AT>
 ; MMR5FP64-NEXT:    # <MCOperand Expr:%lo(b)>>
@@ -666,10 +727,30 @@ define i32 @f4() {
 ; MIPS32R5FP643-NEXT:    # <MCOperand Expr:%hi(b)>>
 ; MIPS32R5FP643-NEXT:    jr $ra # <MCInst #[[#MCINST2]] JR
 ; MIPS32R5FP643-NEXT:    # <MCOperand Reg:RA>>
-; MIPS32R5FP643-NEXT:    lh $2, %lo(b)($1) # <MCInst #[[#MCINST17:]] LH
+; MIPS32R5FP643-NEXT:    lh $2, %lo(b)($1) # <MCInst #[[#MCINST18:]] LH
 ; MIPS32R5FP643-NEXT:    # <MCOperand Reg:V0>
 ; MIPS32R5FP643-NEXT:    # <MCOperand Reg:AT>
 ; MIPS32R5FP643-NEXT:    # <MCOperand Expr:%lo(b)>>
+;
+; MIPS1-PSX-LABEL: f4:
+; MIPS1-PSX:       # %bb.0: # %entry
+; MIPS1-PSX-NEXT:    lui $1, %hi(b) # <MCInst #[[#MCINST1]] LUi
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:AT>
+; MIPS1-PSX-NEXT:    # <MCOperand Expr:%hi(b)>>
+; MIPS1-PSX-NEXT:    lh $2, %lo(b)($1) # <MCInst #[[#MCINST18:]] LH
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:V0>
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:AT>
+; MIPS1-PSX-NEXT:    # <MCOperand Expr:%lo(b)>>
+; MIPS1-PSX-NEXT:    nop # <MCInst #[[#MCINST13]] SLL
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:ZERO>
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:ZERO>
+; MIPS1-PSX-NEXT:    # <MCOperand Imm:0>>
+; MIPS1-PSX-NEXT:    jr $ra # <MCInst #[[#MCINST2]] JR
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:RA>>
+; MIPS1-PSX-NEXT:    nop # <MCInst #[[#MCINST13]] SLL
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:ZERO>
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:ZERO>
+; MIPS1-PSX-NEXT:    # <MCOperand Imm:0>>
 entry:
   %0 = load i16, ptr @b
   %1 = sext i16 %0 to i32
@@ -684,7 +765,7 @@ define i32 @f5() {
 ; MIPS32-NEXT:    # <MCOperand Expr:%hi(c)>>
 ; MIPS32-NEXT:    jr $ra # <MCInst #[[#MCINST2]] JR
 ; MIPS32-NEXT:    # <MCOperand Reg:RA>>
-; MIPS32-NEXT:    lw $2, %lo(c)($1) # <MCInst #[[#MCINST19:]] LW
+; MIPS32-NEXT:    lw $2, %lo(c)($1) # <MCInst #[[#MCINST20:]] LW
 ; MIPS32-NEXT:    # <MCOperand Reg:V0>
 ; MIPS32-NEXT:    # <MCOperand Reg:AT>
 ; MIPS32-NEXT:    # <MCOperand Expr:%lo(c)>>
@@ -696,7 +777,7 @@ define i32 @f5() {
 ; MMR3-NEXT:    # <MCOperand Expr:%hi(c)>>
 ; MMR3-NEXT:    jr $ra # <MCInst #[[#MCINST5]] JR_MM
 ; MMR3-NEXT:    # <MCOperand Reg:RA>>
-; MMR3-NEXT:    lw $2, %lo(c)($1) # <MCInst #[[#MCINST20:]] LW_MM
+; MMR3-NEXT:    lw $2, %lo(c)($1) # <MCInst #[[#MCINST21:]] LW_MM
 ; MMR3-NEXT:    # <MCOperand Reg:V0>
 ; MMR3-NEXT:    # <MCOperand Reg:AT>
 ; MMR3-NEXT:    # <MCOperand Expr:%lo(c)>>
@@ -709,7 +790,7 @@ define i32 @f5() {
 ; MIPS32R6-NEXT:    jr $ra # <MCInst #[[#MCINST7]] JALR
 ; MIPS32R6-NEXT:    # <MCOperand Reg:ZERO>
 ; MIPS32R6-NEXT:    # <MCOperand Reg:RA>>
-; MIPS32R6-NEXT:    lw $2, %lo(c)($1) # <MCInst #[[#MCINST19:]] LW
+; MIPS32R6-NEXT:    lw $2, %lo(c)($1) # <MCInst #[[#MCINST20:]] LW
 ; MIPS32R6-NEXT:    # <MCOperand Reg:V0>
 ; MIPS32R6-NEXT:    # <MCOperand Reg:AT>
 ; MIPS32R6-NEXT:    # <MCOperand Expr:%lo(c)>>
@@ -719,7 +800,7 @@ define i32 @f5() {
 ; MMR6-NEXT:    lui $1, %hi(c) # <MCInst #[[#MCINST4]] LUi_MM
 ; MMR6-NEXT:    # <MCOperand Reg:AT>
 ; MMR6-NEXT:    # <MCOperand Expr:%hi(c)>>
-; MMR6-NEXT:    lw $2, %lo(c)($1) # <MCInst #[[#MCINST20:]] LW_MM
+; MMR6-NEXT:    lw $2, %lo(c)($1) # <MCInst #[[#MCINST21:]] LW_MM
 ; MMR6-NEXT:    # <MCOperand Reg:V0>
 ; MMR6-NEXT:    # <MCOperand Reg:AT>
 ; MMR6-NEXT:    # <MCOperand Expr:%lo(c)>>
@@ -749,7 +830,7 @@ define i32 @f5() {
 ; MIPS3-NEXT:    # <MCOperand Imm:16>>
 ; MIPS3-NEXT:    jr $ra # <MCInst #[[#MCINST2]] JR
 ; MIPS3-NEXT:    # <MCOperand Reg:RA_64>>
-; MIPS3-NEXT:    lw $2, %lo(c)($1) # <MCInst #[[#MCINST19:]] LW
+; MIPS3-NEXT:    lw $2, %lo(c)($1) # <MCInst #[[#MCINST20:]] LW
 ; MIPS3-NEXT:    # <MCOperand Reg:V0>
 ; MIPS3-NEXT:    # <MCOperand Reg:AT_64>
 ; MIPS3-NEXT:    # <MCOperand Expr:%lo(c)>>
@@ -777,7 +858,7 @@ define i32 @f5() {
 ; MIPS64-NEXT:    # <MCOperand Imm:16>>
 ; MIPS64-NEXT:    jr $ra # <MCInst #[[#MCINST2]] JR
 ; MIPS64-NEXT:    # <MCOperand Reg:RA_64>>
-; MIPS64-NEXT:    lw $2, %lo(c)($1) # <MCInst #[[#MCINST19:]] LW
+; MIPS64-NEXT:    lw $2, %lo(c)($1) # <MCInst #[[#MCINST20:]] LW
 ; MIPS64-NEXT:    # <MCOperand Reg:V0>
 ; MIPS64-NEXT:    # <MCOperand Reg:AT_64>
 ; MIPS64-NEXT:    # <MCOperand Expr:%lo(c)>>
@@ -806,7 +887,7 @@ define i32 @f5() {
 ; MIPS64R6-NEXT:    jr $ra # <MCInst #[[#MCINST12]] JALR64
 ; MIPS64R6-NEXT:    # <MCOperand Reg:ZERO_64>
 ; MIPS64R6-NEXT:    # <MCOperand Reg:RA_64>>
-; MIPS64R6-NEXT:    lw $2, %lo(c)($1) # <MCInst #[[#MCINST19:]] LW
+; MIPS64R6-NEXT:    lw $2, %lo(c)($1) # <MCInst #[[#MCINST20:]] LW
 ; MIPS64R6-NEXT:    # <MCOperand Reg:V0>
 ; MIPS64R6-NEXT:    # <MCOperand Reg:AT_64>
 ; MIPS64R6-NEXT:    # <MCOperand Expr:%lo(c)>>
@@ -818,7 +899,7 @@ define i32 @f5() {
 ; MMR5FP64-NEXT:    # <MCOperand Expr:%hi(c)>>
 ; MMR5FP64-NEXT:    jr $ra # <MCInst #[[#MCINST5]] JR_MM
 ; MMR5FP64-NEXT:    # <MCOperand Reg:RA>>
-; MMR5FP64-NEXT:    lw $2, %lo(c)($1) # <MCInst #[[#MCINST20:]] LW_MM
+; MMR5FP64-NEXT:    lw $2, %lo(c)($1) # <MCInst #[[#MCINST21:]] LW_MM
 ; MMR5FP64-NEXT:    # <MCOperand Reg:V0>
 ; MMR5FP64-NEXT:    # <MCOperand Reg:AT>
 ; MMR5FP64-NEXT:    # <MCOperand Expr:%lo(c)>>
@@ -830,10 +911,30 @@ define i32 @f5() {
 ; MIPS32R5FP643-NEXT:    # <MCOperand Expr:%hi(c)>>
 ; MIPS32R5FP643-NEXT:    jr $ra # <MCInst #[[#MCINST2]] JR
 ; MIPS32R5FP643-NEXT:    # <MCOperand Reg:RA>>
-; MIPS32R5FP643-NEXT:    lw $2, %lo(c)($1) # <MCInst #[[#MCINST19:]] LW
+; MIPS32R5FP643-NEXT:    lw $2, %lo(c)($1) # <MCInst #[[#MCINST20:]] LW
 ; MIPS32R5FP643-NEXT:    # <MCOperand Reg:V0>
 ; MIPS32R5FP643-NEXT:    # <MCOperand Reg:AT>
 ; MIPS32R5FP643-NEXT:    # <MCOperand Expr:%lo(c)>>
+;
+; MIPS1-PSX-LABEL: f5:
+; MIPS1-PSX:       # %bb.0: # %entry
+; MIPS1-PSX-NEXT:    lui $1, %hi(c) # <MCInst #[[#MCINST1]] LUi
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:AT>
+; MIPS1-PSX-NEXT:    # <MCOperand Expr:%hi(c)>>
+; MIPS1-PSX-NEXT:    lw $2, %lo(c)($1) # <MCInst #[[#MCINST20:]] LW
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:V0>
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:AT>
+; MIPS1-PSX-NEXT:    # <MCOperand Expr:%lo(c)>>
+; MIPS1-PSX-NEXT:    nop # <MCInst #[[#MCINST13]] SLL
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:ZERO>
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:ZERO>
+; MIPS1-PSX-NEXT:    # <MCOperand Imm:0>>
+; MIPS1-PSX-NEXT:    jr $ra # <MCInst #[[#MCINST2]] JR
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:RA>>
+; MIPS1-PSX-NEXT:    nop # <MCInst #[[#MCINST13]] SLL
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:ZERO>
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:ZERO>
+; MIPS1-PSX-NEXT:    # <MCOperand Imm:0>>
 entry:
   %0 = load i32, ptr @c
   ret i32 %0
@@ -845,13 +946,13 @@ define i64 @f6() {
 ; MIPS32-NEXT:    lui $1, %hi(c) # <MCInst #[[#MCINST1]] LUi
 ; MIPS32-NEXT:    # <MCOperand Reg:AT>
 ; MIPS32-NEXT:    # <MCOperand Expr:%hi(c)>>
-; MIPS32-NEXT:    lw $3, %lo(c)($1) # <MCInst #[[#MCINST19]] LW
+; MIPS32-NEXT:    lw $3, %lo(c)($1) # <MCInst #[[#MCINST20]] LW
 ; MIPS32-NEXT:    # <MCOperand Reg:V1>
 ; MIPS32-NEXT:    # <MCOperand Reg:AT>
 ; MIPS32-NEXT:    # <MCOperand Expr:%lo(c)>>
 ; MIPS32-NEXT:    jr $ra # <MCInst #[[#MCINST2]] JR
 ; MIPS32-NEXT:    # <MCOperand Reg:RA>>
-; MIPS32-NEXT:    addiu $2, $zero, 0 # <MCInst #[[#MCINST21:]] ADDiu
+; MIPS32-NEXT:    addiu $2, $zero, 0 # <MCInst #[[#MCINST22:]] ADDiu
 ; MIPS32-NEXT:    # <MCOperand Reg:V0>
 ; MIPS32-NEXT:    # <MCOperand Reg:ZERO>
 ; MIPS32-NEXT:    # <MCOperand Imm:0>>
@@ -861,12 +962,12 @@ define i64 @f6() {
 ; MMR3-NEXT:    lui $1, %hi(c) # <MCInst #[[#MCINST4]] LUi_MM
 ; MMR3-NEXT:    # <MCOperand Reg:AT>
 ; MMR3-NEXT:    # <MCOperand Expr:%hi(c)>>
-; MMR3-NEXT:    li16 $2, 0 # <MCInst #[[#MCINST22:]] LI16_MM
+; MMR3-NEXT:    li16 $2, 0 # <MCInst #[[#MCINST23:]] LI16_MM
 ; MMR3-NEXT:    # <MCOperand Reg:V0>
 ; MMR3-NEXT:    # <MCOperand Imm:0>>
 ; MMR3-NEXT:    jr $ra # <MCInst #[[#MCINST5]] JR_MM
 ; MMR3-NEXT:    # <MCOperand Reg:RA>>
-; MMR3-NEXT:    lw $3, %lo(c)($1) # <MCInst #[[#MCINST20]] LW_MM
+; MMR3-NEXT:    lw $3, %lo(c)($1) # <MCInst #[[#MCINST21]] LW_MM
 ; MMR3-NEXT:    # <MCOperand Reg:V1>
 ; MMR3-NEXT:    # <MCOperand Reg:AT>
 ; MMR3-NEXT:    # <MCOperand Expr:%lo(c)>>
@@ -876,14 +977,14 @@ define i64 @f6() {
 ; MIPS32R6-NEXT:    lui $1, %hi(c) # <MCInst #[[#MCINST1]] LUi
 ; MIPS32R6-NEXT:    # <MCOperand Reg:AT>
 ; MIPS32R6-NEXT:    # <MCOperand Expr:%hi(c)>>
-; MIPS32R6-NEXT:    lw $3, %lo(c)($1) # <MCInst #[[#MCINST19]] LW
+; MIPS32R6-NEXT:    lw $3, %lo(c)($1) # <MCInst #[[#MCINST20]] LW
 ; MIPS32R6-NEXT:    # <MCOperand Reg:V1>
 ; MIPS32R6-NEXT:    # <MCOperand Reg:AT>
 ; MIPS32R6-NEXT:    # <MCOperand Expr:%lo(c)>>
 ; MIPS32R6-NEXT:    jr $ra # <MCInst #[[#MCINST7]] JALR
 ; MIPS32R6-NEXT:    # <MCOperand Reg:ZERO>
 ; MIPS32R6-NEXT:    # <MCOperand Reg:RA>>
-; MIPS32R6-NEXT:    addiu $2, $zero, 0 # <MCInst #[[#MCINST21:]] ADDiu
+; MIPS32R6-NEXT:    addiu $2, $zero, 0 # <MCInst #[[#MCINST22:]] ADDiu
 ; MIPS32R6-NEXT:    # <MCOperand Reg:V0>
 ; MIPS32R6-NEXT:    # <MCOperand Reg:ZERO>
 ; MIPS32R6-NEXT:    # <MCOperand Imm:0>>
@@ -893,11 +994,11 @@ define i64 @f6() {
 ; MMR6-NEXT:    lui $1, %hi(c) # <MCInst #[[#MCINST4]] LUi_MM
 ; MMR6-NEXT:    # <MCOperand Reg:AT>
 ; MMR6-NEXT:    # <MCOperand Expr:%hi(c)>>
-; MMR6-NEXT:    lw $3, %lo(c)($1) # <MCInst #[[#MCINST20]] LW_MM
+; MMR6-NEXT:    lw $3, %lo(c)($1) # <MCInst #[[#MCINST21]] LW_MM
 ; MMR6-NEXT:    # <MCOperand Reg:V1>
 ; MMR6-NEXT:    # <MCOperand Reg:AT>
 ; MMR6-NEXT:    # <MCOperand Expr:%lo(c)>>
-; MMR6-NEXT:    li16 $2, 0 # <MCInst #[[#MCINST22:]] LI16_MM
+; MMR6-NEXT:    li16 $2, 0 # <MCInst #[[#MCINST23:]] LI16_MM
 ; MMR6-NEXT:    # <MCOperand Reg:V0>
 ; MMR6-NEXT:    # <MCOperand Imm:0>>
 ; MMR6-NEXT:    jrc $ra # <MCInst #[[#MCINST8]] JRC16_MM
@@ -926,7 +1027,7 @@ define i64 @f6() {
 ; MIPS3-NEXT:    # <MCOperand Imm:16>>
 ; MIPS3-NEXT:    jr $ra # <MCInst #[[#MCINST2]] JR
 ; MIPS3-NEXT:    # <MCOperand Reg:RA_64>>
-; MIPS3-NEXT:    lwu $2, %lo(c)($1) # <MCInst #[[#MCINST23:]] LWu
+; MIPS3-NEXT:    lwu $2, %lo(c)($1) # <MCInst #[[#MCINST24:]] LWu
 ; MIPS3-NEXT:    # <MCOperand Reg:V0_64>
 ; MIPS3-NEXT:    # <MCOperand Reg:AT_64>
 ; MIPS3-NEXT:    # <MCOperand Expr:%lo(c)>>
@@ -954,7 +1055,7 @@ define i64 @f6() {
 ; MIPS64-NEXT:    # <MCOperand Imm:16>>
 ; MIPS64-NEXT:    jr $ra # <MCInst #[[#MCINST2]] JR
 ; MIPS64-NEXT:    # <MCOperand Reg:RA_64>>
-; MIPS64-NEXT:    lwu $2, %lo(c)($1) # <MCInst #[[#MCINST23:]] LWu
+; MIPS64-NEXT:    lwu $2, %lo(c)($1) # <MCInst #[[#MCINST24:]] LWu
 ; MIPS64-NEXT:    # <MCOperand Reg:V0_64>
 ; MIPS64-NEXT:    # <MCOperand Reg:AT_64>
 ; MIPS64-NEXT:    # <MCOperand Expr:%lo(c)>>
@@ -983,7 +1084,7 @@ define i64 @f6() {
 ; MIPS64R6-NEXT:    jr $ra # <MCInst #[[#MCINST12]] JALR64
 ; MIPS64R6-NEXT:    # <MCOperand Reg:ZERO_64>
 ; MIPS64R6-NEXT:    # <MCOperand Reg:RA_64>>
-; MIPS64R6-NEXT:    lwu $2, %lo(c)($1) # <MCInst #[[#MCINST23:]] LWu
+; MIPS64R6-NEXT:    lwu $2, %lo(c)($1) # <MCInst #[[#MCINST24:]] LWu
 ; MIPS64R6-NEXT:    # <MCOperand Reg:V0_64>
 ; MIPS64R6-NEXT:    # <MCOperand Reg:AT_64>
 ; MIPS64R6-NEXT:    # <MCOperand Expr:%lo(c)>>
@@ -993,12 +1094,12 @@ define i64 @f6() {
 ; MMR5FP64-NEXT:    lui $1, %hi(c) # <MCInst #[[#MCINST4]] LUi_MM
 ; MMR5FP64-NEXT:    # <MCOperand Reg:AT>
 ; MMR5FP64-NEXT:    # <MCOperand Expr:%hi(c)>>
-; MMR5FP64-NEXT:    li16 $2, 0 # <MCInst #[[#MCINST22:]] LI16_MM
+; MMR5FP64-NEXT:    li16 $2, 0 # <MCInst #[[#MCINST23:]] LI16_MM
 ; MMR5FP64-NEXT:    # <MCOperand Reg:V0>
 ; MMR5FP64-NEXT:    # <MCOperand Imm:0>>
 ; MMR5FP64-NEXT:    jr $ra # <MCInst #[[#MCINST5]] JR_MM
 ; MMR5FP64-NEXT:    # <MCOperand Reg:RA>>
-; MMR5FP64-NEXT:    lw $3, %lo(c)($1) # <MCInst #[[#MCINST20]] LW_MM
+; MMR5FP64-NEXT:    lw $3, %lo(c)($1) # <MCInst #[[#MCINST21]] LW_MM
 ; MMR5FP64-NEXT:    # <MCOperand Reg:V1>
 ; MMR5FP64-NEXT:    # <MCOperand Reg:AT>
 ; MMR5FP64-NEXT:    # <MCOperand Expr:%lo(c)>>
@@ -1008,16 +1109,36 @@ define i64 @f6() {
 ; MIPS32R5FP643-NEXT:    lui $1, %hi(c) # <MCInst #[[#MCINST1]] LUi
 ; MIPS32R5FP643-NEXT:    # <MCOperand Reg:AT>
 ; MIPS32R5FP643-NEXT:    # <MCOperand Expr:%hi(c)>>
-; MIPS32R5FP643-NEXT:    lw $3, %lo(c)($1) # <MCInst #[[#MCINST19]] LW
+; MIPS32R5FP643-NEXT:    lw $3, %lo(c)($1) # <MCInst #[[#MCINST20]] LW
 ; MIPS32R5FP643-NEXT:    # <MCOperand Reg:V1>
 ; MIPS32R5FP643-NEXT:    # <MCOperand Reg:AT>
 ; MIPS32R5FP643-NEXT:    # <MCOperand Expr:%lo(c)>>
 ; MIPS32R5FP643-NEXT:    jr $ra # <MCInst #[[#MCINST2]] JR
 ; MIPS32R5FP643-NEXT:    # <MCOperand Reg:RA>>
-; MIPS32R5FP643-NEXT:    addiu $2, $zero, 0 # <MCInst #[[#MCINST21:]] ADDiu
+; MIPS32R5FP643-NEXT:    addiu $2, $zero, 0 # <MCInst #[[#MCINST22:]] ADDiu
 ; MIPS32R5FP643-NEXT:    # <MCOperand Reg:V0>
 ; MIPS32R5FP643-NEXT:    # <MCOperand Reg:ZERO>
 ; MIPS32R5FP643-NEXT:    # <MCOperand Imm:0>>
+;
+; MIPS1-PSX-LABEL: f6:
+; MIPS1-PSX:       # %bb.0: # %entry
+; MIPS1-PSX-NEXT:    lui $1, %hi(c) # <MCInst #[[#MCINST1]] LUi
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:AT>
+; MIPS1-PSX-NEXT:    # <MCOperand Expr:%hi(c)>>
+; MIPS1-PSX-NEXT:    lw $2, %lo(c)($1) # <MCInst #[[#MCINST20]] LW
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:V0>
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:AT>
+; MIPS1-PSX-NEXT:    # <MCOperand Expr:%lo(c)>>
+; MIPS1-PSX-NEXT:    nop # <MCInst #[[#MCINST13]] SLL
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:ZERO>
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:ZERO>
+; MIPS1-PSX-NEXT:    # <MCOperand Imm:0>>
+; MIPS1-PSX-NEXT:    jr $ra # <MCInst #[[#MCINST2]] JR
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:RA>>
+; MIPS1-PSX-NEXT:    addiu $3, $zero, 0 # <MCInst #[[#MCINST22:]] ADDiu
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:V1>
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:ZERO>
+; MIPS1-PSX-NEXT:    # <MCOperand Imm:0>>
 entry:
   %0 = load i32, ptr @c
   %1 = zext i32 %0 to i64
@@ -1030,13 +1151,13 @@ define i64 @f7() {
 ; MIPS32-NEXT:    lui $1, %hi(c) # <MCInst #[[#MCINST1]] LUi
 ; MIPS32-NEXT:    # <MCOperand Reg:AT>
 ; MIPS32-NEXT:    # <MCOperand Expr:%hi(c)>>
-; MIPS32-NEXT:    lw $3, %lo(c)($1) # <MCInst #[[#MCINST19]] LW
+; MIPS32-NEXT:    lw $3, %lo(c)($1) # <MCInst #[[#MCINST20]] LW
 ; MIPS32-NEXT:    # <MCOperand Reg:V1>
 ; MIPS32-NEXT:    # <MCOperand Reg:AT>
 ; MIPS32-NEXT:    # <MCOperand Expr:%lo(c)>>
 ; MIPS32-NEXT:    jr $ra # <MCInst #[[#MCINST2]] JR
 ; MIPS32-NEXT:    # <MCOperand Reg:RA>>
-; MIPS32-NEXT:    sra $2, $3, 31 # <MCInst #[[#MCINST24:]] SRA
+; MIPS32-NEXT:    sra $2, $3, 31 # <MCInst #[[#MCINST25:]] SRA
 ; MIPS32-NEXT:    # <MCOperand Reg:V0>
 ; MIPS32-NEXT:    # <MCOperand Reg:V1>
 ; MIPS32-NEXT:    # <MCOperand Imm:31>>
@@ -1046,13 +1167,13 @@ define i64 @f7() {
 ; MMR3-NEXT:    lui $1, %hi(c) # <MCInst #[[#MCINST4]] LUi_MM
 ; MMR3-NEXT:    # <MCOperand Reg:AT>
 ; MMR3-NEXT:    # <MCOperand Expr:%hi(c)>>
-; MMR3-NEXT:    lw $3, %lo(c)($1) # <MCInst #[[#MCINST20]] LW_MM
+; MMR3-NEXT:    lw $3, %lo(c)($1) # <MCInst #[[#MCINST21]] LW_MM
 ; MMR3-NEXT:    # <MCOperand Reg:V1>
 ; MMR3-NEXT:    # <MCOperand Reg:AT>
 ; MMR3-NEXT:    # <MCOperand Expr:%lo(c)>>
 ; MMR3-NEXT:    jr $ra # <MCInst #[[#MCINST5]] JR_MM
 ; MMR3-NEXT:    # <MCOperand Reg:RA>>
-; MMR3-NEXT:    sra $2, $3, 31 # <MCInst #[[#MCINST25:]] SRA_MM
+; MMR3-NEXT:    sra $2, $3, 31 # <MCInst #[[#MCINST26:]] SRA_MM
 ; MMR3-NEXT:    # <MCOperand Reg:V0>
 ; MMR3-NEXT:    # <MCOperand Reg:V1>
 ; MMR3-NEXT:    # <MCOperand Imm:31>>
@@ -1062,14 +1183,14 @@ define i64 @f7() {
 ; MIPS32R6-NEXT:    lui $1, %hi(c) # <MCInst #[[#MCINST1]] LUi
 ; MIPS32R6-NEXT:    # <MCOperand Reg:AT>
 ; MIPS32R6-NEXT:    # <MCOperand Expr:%hi(c)>>
-; MIPS32R6-NEXT:    lw $3, %lo(c)($1) # <MCInst #[[#MCINST19]] LW
+; MIPS32R6-NEXT:    lw $3, %lo(c)($1) # <MCInst #[[#MCINST20]] LW
 ; MIPS32R6-NEXT:    # <MCOperand Reg:V1>
 ; MIPS32R6-NEXT:    # <MCOperand Reg:AT>
 ; MIPS32R6-NEXT:    # <MCOperand Expr:%lo(c)>>
 ; MIPS32R6-NEXT:    jr $ra # <MCInst #[[#MCINST7]] JALR
 ; MIPS32R6-NEXT:    # <MCOperand Reg:ZERO>
 ; MIPS32R6-NEXT:    # <MCOperand Reg:RA>>
-; MIPS32R6-NEXT:    sra $2, $3, 31 # <MCInst #[[#MCINST24:]] SRA
+; MIPS32R6-NEXT:    sra $2, $3, 31 # <MCInst #[[#MCINST25:]] SRA
 ; MIPS32R6-NEXT:    # <MCOperand Reg:V0>
 ; MIPS32R6-NEXT:    # <MCOperand Reg:V1>
 ; MIPS32R6-NEXT:    # <MCOperand Imm:31>>
@@ -1079,11 +1200,11 @@ define i64 @f7() {
 ; MMR6-NEXT:    lui $1, %hi(c) # <MCInst #[[#MCINST4]] LUi_MM
 ; MMR6-NEXT:    # <MCOperand Reg:AT>
 ; MMR6-NEXT:    # <MCOperand Expr:%hi(c)>>
-; MMR6-NEXT:    lw $3, %lo(c)($1) # <MCInst #[[#MCINST20]] LW_MM
+; MMR6-NEXT:    lw $3, %lo(c)($1) # <MCInst #[[#MCINST21]] LW_MM
 ; MMR6-NEXT:    # <MCOperand Reg:V1>
 ; MMR6-NEXT:    # <MCOperand Reg:AT>
 ; MMR6-NEXT:    # <MCOperand Expr:%lo(c)>>
-; MMR6-NEXT:    sra $2, $3, 31 # <MCInst #[[#MCINST25:]] SRA_MM
+; MMR6-NEXT:    sra $2, $3, 31 # <MCInst #[[#MCINST26:]] SRA_MM
 ; MMR6-NEXT:    # <MCOperand Reg:V0>
 ; MMR6-NEXT:    # <MCOperand Reg:V1>
 ; MMR6-NEXT:    # <MCOperand Imm:31>>
@@ -1113,7 +1234,7 @@ define i64 @f7() {
 ; MIPS3-NEXT:    # <MCOperand Imm:16>>
 ; MIPS3-NEXT:    jr $ra # <MCInst #[[#MCINST2]] JR
 ; MIPS3-NEXT:    # <MCOperand Reg:RA_64>>
-; MIPS3-NEXT:    lw $2, %lo(c)($1) # <MCInst #[[#MCINST26:]] LW64
+; MIPS3-NEXT:    lw $2, %lo(c)($1) # <MCInst #[[#MCINST27:]] LW64
 ; MIPS3-NEXT:    # <MCOperand Reg:V0_64>
 ; MIPS3-NEXT:    # <MCOperand Reg:AT_64>
 ; MIPS3-NEXT:    # <MCOperand Expr:%lo(c)>>
@@ -1141,7 +1262,7 @@ define i64 @f7() {
 ; MIPS64-NEXT:    # <MCOperand Imm:16>>
 ; MIPS64-NEXT:    jr $ra # <MCInst #[[#MCINST2]] JR
 ; MIPS64-NEXT:    # <MCOperand Reg:RA_64>>
-; MIPS64-NEXT:    lw $2, %lo(c)($1) # <MCInst #[[#MCINST26:]] LW64
+; MIPS64-NEXT:    lw $2, %lo(c)($1) # <MCInst #[[#MCINST27:]] LW64
 ; MIPS64-NEXT:    # <MCOperand Reg:V0_64>
 ; MIPS64-NEXT:    # <MCOperand Reg:AT_64>
 ; MIPS64-NEXT:    # <MCOperand Expr:%lo(c)>>
@@ -1170,7 +1291,7 @@ define i64 @f7() {
 ; MIPS64R6-NEXT:    jr $ra # <MCInst #[[#MCINST12]] JALR64
 ; MIPS64R6-NEXT:    # <MCOperand Reg:ZERO_64>
 ; MIPS64R6-NEXT:    # <MCOperand Reg:RA_64>>
-; MIPS64R6-NEXT:    lw $2, %lo(c)($1) # <MCInst #[[#MCINST26:]] LW64
+; MIPS64R6-NEXT:    lw $2, %lo(c)($1) # <MCInst #[[#MCINST27:]] LW64
 ; MIPS64R6-NEXT:    # <MCOperand Reg:V0_64>
 ; MIPS64R6-NEXT:    # <MCOperand Reg:AT_64>
 ; MIPS64R6-NEXT:    # <MCOperand Expr:%lo(c)>>
@@ -1180,13 +1301,13 @@ define i64 @f7() {
 ; MMR5FP64-NEXT:    lui $1, %hi(c) # <MCInst #[[#MCINST4]] LUi_MM
 ; MMR5FP64-NEXT:    # <MCOperand Reg:AT>
 ; MMR5FP64-NEXT:    # <MCOperand Expr:%hi(c)>>
-; MMR5FP64-NEXT:    lw $3, %lo(c)($1) # <MCInst #[[#MCINST20]] LW_MM
+; MMR5FP64-NEXT:    lw $3, %lo(c)($1) # <MCInst #[[#MCINST21]] LW_MM
 ; MMR5FP64-NEXT:    # <MCOperand Reg:V1>
 ; MMR5FP64-NEXT:    # <MCOperand Reg:AT>
 ; MMR5FP64-NEXT:    # <MCOperand Expr:%lo(c)>>
 ; MMR5FP64-NEXT:    jr $ra # <MCInst #[[#MCINST5]] JR_MM
 ; MMR5FP64-NEXT:    # <MCOperand Reg:RA>>
-; MMR5FP64-NEXT:    sra $2, $3, 31 # <MCInst #[[#MCINST25:]] SRA_MM
+; MMR5FP64-NEXT:    sra $2, $3, 31 # <MCInst #[[#MCINST26:]] SRA_MM
 ; MMR5FP64-NEXT:    # <MCOperand Reg:V0>
 ; MMR5FP64-NEXT:    # <MCOperand Reg:V1>
 ; MMR5FP64-NEXT:    # <MCOperand Imm:31>>
@@ -1196,16 +1317,36 @@ define i64 @f7() {
 ; MIPS32R5FP643-NEXT:    lui $1, %hi(c) # <MCInst #[[#MCINST1]] LUi
 ; MIPS32R5FP643-NEXT:    # <MCOperand Reg:AT>
 ; MIPS32R5FP643-NEXT:    # <MCOperand Expr:%hi(c)>>
-; MIPS32R5FP643-NEXT:    lw $3, %lo(c)($1) # <MCInst #[[#MCINST19]] LW
+; MIPS32R5FP643-NEXT:    lw $3, %lo(c)($1) # <MCInst #[[#MCINST20]] LW
 ; MIPS32R5FP643-NEXT:    # <MCOperand Reg:V1>
 ; MIPS32R5FP643-NEXT:    # <MCOperand Reg:AT>
 ; MIPS32R5FP643-NEXT:    # <MCOperand Expr:%lo(c)>>
 ; MIPS32R5FP643-NEXT:    jr $ra # <MCInst #[[#MCINST2]] JR
 ; MIPS32R5FP643-NEXT:    # <MCOperand Reg:RA>>
-; MIPS32R5FP643-NEXT:    sra $2, $3, 31 # <MCInst #[[#MCINST24:]] SRA
+; MIPS32R5FP643-NEXT:    sra $2, $3, 31 # <MCInst #[[#MCINST25:]] SRA
 ; MIPS32R5FP643-NEXT:    # <MCOperand Reg:V0>
 ; MIPS32R5FP643-NEXT:    # <MCOperand Reg:V1>
 ; MIPS32R5FP643-NEXT:    # <MCOperand Imm:31>>
+;
+; MIPS1-PSX-LABEL: f7:
+; MIPS1-PSX:       # %bb.0: # %entry
+; MIPS1-PSX-NEXT:    lui $1, %hi(c) # <MCInst #[[#MCINST1]] LUi
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:AT>
+; MIPS1-PSX-NEXT:    # <MCOperand Expr:%hi(c)>>
+; MIPS1-PSX-NEXT:    lw $2, %lo(c)($1) # <MCInst #[[#MCINST20]] LW
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:V0>
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:AT>
+; MIPS1-PSX-NEXT:    # <MCOperand Expr:%lo(c)>>
+; MIPS1-PSX-NEXT:    nop # <MCInst #[[#MCINST13]] SLL
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:ZERO>
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:ZERO>
+; MIPS1-PSX-NEXT:    # <MCOperand Imm:0>>
+; MIPS1-PSX-NEXT:    jr $ra # <MCInst #[[#MCINST2]] JR
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:RA>>
+; MIPS1-PSX-NEXT:    sra $3, $2, 31 # <MCInst #[[#MCINST25:]] SRA
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:V1>
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:V0>
+; MIPS1-PSX-NEXT:    # <MCOperand Imm:31>>
 entry:
   %0 = load i32, ptr @c
   %1 = sext i32 %0 to i64
@@ -1220,7 +1361,7 @@ define float @f8() {
 ; MIPS32-NEXT:    # <MCOperand Expr:%hi(e)>>
 ; MIPS32-NEXT:    jr $ra # <MCInst #[[#MCINST2]] JR
 ; MIPS32-NEXT:    # <MCOperand Reg:RA>>
-; MIPS32-NEXT:    lwc1 $f0, %lo(e)($1) # <MCInst #[[#MCINST27:]] LWC1
+; MIPS32-NEXT:    lwc1 $f0, %lo(e)($1) # <MCInst #[[#MCINST28:]] LWC1
 ; MIPS32-NEXT:    # <MCOperand Reg:F0>
 ; MIPS32-NEXT:    # <MCOperand Reg:AT>
 ; MIPS32-NEXT:    # <MCOperand Expr:%lo(e)>>
@@ -1232,7 +1373,7 @@ define float @f8() {
 ; MMR3-NEXT:    # <MCOperand Expr:%hi(e)>>
 ; MMR3-NEXT:    jr $ra # <MCInst #[[#MCINST5]] JR_MM
 ; MMR3-NEXT:    # <MCOperand Reg:RA>>
-; MMR3-NEXT:    lwc1 $f0, %lo(e)($1) # <MCInst #[[#MCINST28:]] LWC1_MM
+; MMR3-NEXT:    lwc1 $f0, %lo(e)($1) # <MCInst #[[#MCINST29:]] LWC1_MM
 ; MMR3-NEXT:    # <MCOperand Reg:F0>
 ; MMR3-NEXT:    # <MCOperand Reg:AT>
 ; MMR3-NEXT:    # <MCOperand Expr:%lo(e)>>
@@ -1245,7 +1386,7 @@ define float @f8() {
 ; MIPS32R6-NEXT:    jr $ra # <MCInst #[[#MCINST7]] JALR
 ; MIPS32R6-NEXT:    # <MCOperand Reg:ZERO>
 ; MIPS32R6-NEXT:    # <MCOperand Reg:RA>>
-; MIPS32R6-NEXT:    lwc1 $f0, %lo(e)($1) # <MCInst #[[#MCINST27:]] LWC1
+; MIPS32R6-NEXT:    lwc1 $f0, %lo(e)($1) # <MCInst #[[#MCINST28:]] LWC1
 ; MIPS32R6-NEXT:    # <MCOperand Reg:F0>
 ; MIPS32R6-NEXT:    # <MCOperand Reg:AT>
 ; MIPS32R6-NEXT:    # <MCOperand Expr:%lo(e)>>
@@ -1255,7 +1396,7 @@ define float @f8() {
 ; MMR6-NEXT:    lui $1, %hi(e) # <MCInst #[[#MCINST4]] LUi_MM
 ; MMR6-NEXT:    # <MCOperand Reg:AT>
 ; MMR6-NEXT:    # <MCOperand Expr:%hi(e)>>
-; MMR6-NEXT:    lwc1 $f0, %lo(e)($1) # <MCInst #[[#MCINST28:]] LWC1_MM
+; MMR6-NEXT:    lwc1 $f0, %lo(e)($1) # <MCInst #[[#MCINST29:]] LWC1_MM
 ; MMR6-NEXT:    # <MCOperand Reg:F0>
 ; MMR6-NEXT:    # <MCOperand Reg:AT>
 ; MMR6-NEXT:    # <MCOperand Expr:%lo(e)>>
@@ -1285,7 +1426,7 @@ define float @f8() {
 ; MIPS3-NEXT:    # <MCOperand Imm:16>>
 ; MIPS3-NEXT:    jr $ra # <MCInst #[[#MCINST2]] JR
 ; MIPS3-NEXT:    # <MCOperand Reg:RA_64>>
-; MIPS3-NEXT:    lwc1 $f0, %lo(e)($1) # <MCInst #[[#MCINST27:]] LWC1
+; MIPS3-NEXT:    lwc1 $f0, %lo(e)($1) # <MCInst #[[#MCINST28:]] LWC1
 ; MIPS3-NEXT:    # <MCOperand Reg:F0>
 ; MIPS3-NEXT:    # <MCOperand Reg:AT_64>
 ; MIPS3-NEXT:    # <MCOperand Expr:%lo(e)>>
@@ -1313,7 +1454,7 @@ define float @f8() {
 ; MIPS64-NEXT:    # <MCOperand Imm:16>>
 ; MIPS64-NEXT:    jr $ra # <MCInst #[[#MCINST2]] JR
 ; MIPS64-NEXT:    # <MCOperand Reg:RA_64>>
-; MIPS64-NEXT:    lwc1 $f0, %lo(e)($1) # <MCInst #[[#MCINST27:]] LWC1
+; MIPS64-NEXT:    lwc1 $f0, %lo(e)($1) # <MCInst #[[#MCINST28:]] LWC1
 ; MIPS64-NEXT:    # <MCOperand Reg:F0>
 ; MIPS64-NEXT:    # <MCOperand Reg:AT_64>
 ; MIPS64-NEXT:    # <MCOperand Expr:%lo(e)>>
@@ -1342,7 +1483,7 @@ define float @f8() {
 ; MIPS64R6-NEXT:    jr $ra # <MCInst #[[#MCINST12]] JALR64
 ; MIPS64R6-NEXT:    # <MCOperand Reg:ZERO_64>
 ; MIPS64R6-NEXT:    # <MCOperand Reg:RA_64>>
-; MIPS64R6-NEXT:    lwc1 $f0, %lo(e)($1) # <MCInst #[[#MCINST27:]] LWC1
+; MIPS64R6-NEXT:    lwc1 $f0, %lo(e)($1) # <MCInst #[[#MCINST28:]] LWC1
 ; MIPS64R6-NEXT:    # <MCOperand Reg:F0>
 ; MIPS64R6-NEXT:    # <MCOperand Reg:AT_64>
 ; MIPS64R6-NEXT:    # <MCOperand Expr:%lo(e)>>
@@ -1354,7 +1495,7 @@ define float @f8() {
 ; MMR5FP64-NEXT:    # <MCOperand Expr:%hi(e)>>
 ; MMR5FP64-NEXT:    jr $ra # <MCInst #[[#MCINST5]] JR_MM
 ; MMR5FP64-NEXT:    # <MCOperand Reg:RA>>
-; MMR5FP64-NEXT:    lwc1 $f0, %lo(e)($1) # <MCInst #[[#MCINST28:]] LWC1_MM
+; MMR5FP64-NEXT:    lwc1 $f0, %lo(e)($1) # <MCInst #[[#MCINST29:]] LWC1_MM
 ; MMR5FP64-NEXT:    # <MCOperand Reg:F0>
 ; MMR5FP64-NEXT:    # <MCOperand Reg:AT>
 ; MMR5FP64-NEXT:    # <MCOperand Expr:%lo(e)>>
@@ -1366,10 +1507,22 @@ define float @f8() {
 ; MIPS32R5FP643-NEXT:    # <MCOperand Expr:%hi(e)>>
 ; MIPS32R5FP643-NEXT:    jr $ra # <MCInst #[[#MCINST2]] JR
 ; MIPS32R5FP643-NEXT:    # <MCOperand Reg:RA>>
-; MIPS32R5FP643-NEXT:    lwc1 $f0, %lo(e)($1) # <MCInst #[[#MCINST27:]] LWC1
+; MIPS32R5FP643-NEXT:    lwc1 $f0, %lo(e)($1) # <MCInst #[[#MCINST28:]] LWC1
 ; MIPS32R5FP643-NEXT:    # <MCOperand Reg:F0>
 ; MIPS32R5FP643-NEXT:    # <MCOperand Reg:AT>
 ; MIPS32R5FP643-NEXT:    # <MCOperand Expr:%lo(e)>>
+;
+; MIPS1-PSX-LABEL: f8:
+; MIPS1-PSX:       # %bb.0: # %entry
+; MIPS1-PSX-NEXT:    lui $1, %hi(e) # <MCInst #[[#MCINST1]] LUi
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:AT>
+; MIPS1-PSX-NEXT:    # <MCOperand Expr:%hi(e)>>
+; MIPS1-PSX-NEXT:    jr $ra # <MCInst #[[#MCINST2]] JR
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:RA>>
+; MIPS1-PSX-NEXT:    lwc1 $f0, %lo(e)($1) # <MCInst #[[#MCINST28:]] LWC1
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:F0>
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:AT>
+; MIPS1-PSX-NEXT:    # <MCOperand Expr:%lo(e)>>
 entry:
   %0 = load float, ptr @e
   ret float %0
@@ -1383,7 +1536,7 @@ define double @f9() {
 ; MIPS32-NEXT:    # <MCOperand Expr:%hi(f)>>
 ; MIPS32-NEXT:    jr $ra # <MCInst #[[#MCINST2]] JR
 ; MIPS32-NEXT:    # <MCOperand Reg:RA>>
-; MIPS32-NEXT:    ldc1 $f0, %lo(f)($1) # <MCInst #[[#MCINST29:]] LDC1
+; MIPS32-NEXT:    ldc1 $f0, %lo(f)($1) # <MCInst #[[#MCINST30:]] LDC1
 ; MIPS32-NEXT:    # <MCOperand Reg:D0>
 ; MIPS32-NEXT:    # <MCOperand Reg:AT>
 ; MIPS32-NEXT:    # <MCOperand Expr:%lo(f)>>
@@ -1395,7 +1548,7 @@ define double @f9() {
 ; MMR3-NEXT:    # <MCOperand Expr:%hi(f)>>
 ; MMR3-NEXT:    jr $ra # <MCInst #[[#MCINST5]] JR_MM
 ; MMR3-NEXT:    # <MCOperand Reg:RA>>
-; MMR3-NEXT:    ldc1 $f0, %lo(f)($1) # <MCInst #[[#MCINST30:]] LDC1_MM_D32
+; MMR3-NEXT:    ldc1 $f0, %lo(f)($1) # <MCInst #[[#MCINST31:]] LDC1_MM_D32
 ; MMR3-NEXT:    # <MCOperand Reg:D0>
 ; MMR3-NEXT:    # <MCOperand Reg:AT>
 ; MMR3-NEXT:    # <MCOperand Expr:%lo(f)>>
@@ -1408,7 +1561,7 @@ define double @f9() {
 ; MIPS32R6-NEXT:    jr $ra # <MCInst #[[#MCINST7]] JALR
 ; MIPS32R6-NEXT:    # <MCOperand Reg:ZERO>
 ; MIPS32R6-NEXT:    # <MCOperand Reg:RA>>
-; MIPS32R6-NEXT:    ldc1 $f0, %lo(f)($1) # <MCInst #[[#MCINST31:]] LDC164
+; MIPS32R6-NEXT:    ldc1 $f0, %lo(f)($1) # <MCInst #[[#MCINST32:]] LDC164
 ; MIPS32R6-NEXT:    # <MCOperand Reg:D0_64>
 ; MIPS32R6-NEXT:    # <MCOperand Reg:AT>
 ; MIPS32R6-NEXT:    # <MCOperand Expr:%lo(f)>>
@@ -1418,7 +1571,7 @@ define double @f9() {
 ; MMR6-NEXT:    lui $1, %hi(f) # <MCInst #[[#MCINST4]] LUi_MM
 ; MMR6-NEXT:    # <MCOperand Reg:AT>
 ; MMR6-NEXT:    # <MCOperand Expr:%hi(f)>>
-; MMR6-NEXT:    ldc1 $f0, %lo(f)($1) # <MCInst #[[#MCINST32:]] LDC1_D64_MMR6
+; MMR6-NEXT:    ldc1 $f0, %lo(f)($1) # <MCInst #[[#MCINST33:]] LDC1_D64_MMR6
 ; MMR6-NEXT:    # <MCOperand Reg:D0_64>
 ; MMR6-NEXT:    # <MCOperand Reg:AT>
 ; MMR6-NEXT:    # <MCOperand Expr:%lo(f)>>
@@ -1448,7 +1601,7 @@ define double @f9() {
 ; MIPS3-NEXT:    # <MCOperand Imm:16>>
 ; MIPS3-NEXT:    jr $ra # <MCInst #[[#MCINST2]] JR
 ; MIPS3-NEXT:    # <MCOperand Reg:RA_64>>
-; MIPS3-NEXT:    ldc1 $f0, %lo(f)($1) # <MCInst #[[#MCINST31:]] LDC164
+; MIPS3-NEXT:    ldc1 $f0, %lo(f)($1) # <MCInst #[[#MCINST32:]] LDC164
 ; MIPS3-NEXT:    # <MCOperand Reg:D0_64>
 ; MIPS3-NEXT:    # <MCOperand Reg:AT_64>
 ; MIPS3-NEXT:    # <MCOperand Expr:%lo(f)>>
@@ -1476,7 +1629,7 @@ define double @f9() {
 ; MIPS64-NEXT:    # <MCOperand Imm:16>>
 ; MIPS64-NEXT:    jr $ra # <MCInst #[[#MCINST2]] JR
 ; MIPS64-NEXT:    # <MCOperand Reg:RA_64>>
-; MIPS64-NEXT:    ldc1 $f0, %lo(f)($1) # <MCInst #[[#MCINST31:]] LDC164
+; MIPS64-NEXT:    ldc1 $f0, %lo(f)($1) # <MCInst #[[#MCINST32:]] LDC164
 ; MIPS64-NEXT:    # <MCOperand Reg:D0_64>
 ; MIPS64-NEXT:    # <MCOperand Reg:AT_64>
 ; MIPS64-NEXT:    # <MCOperand Expr:%lo(f)>>
@@ -1505,7 +1658,7 @@ define double @f9() {
 ; MIPS64R6-NEXT:    jr $ra # <MCInst #[[#MCINST12]] JALR64
 ; MIPS64R6-NEXT:    # <MCOperand Reg:ZERO_64>
 ; MIPS64R6-NEXT:    # <MCOperand Reg:RA_64>>
-; MIPS64R6-NEXT:    ldc1 $f0, %lo(f)($1) # <MCInst #[[#MCINST31:]] LDC164
+; MIPS64R6-NEXT:    ldc1 $f0, %lo(f)($1) # <MCInst #[[#MCINST32:]] LDC164
 ; MIPS64R6-NEXT:    # <MCOperand Reg:D0_64>
 ; MIPS64R6-NEXT:    # <MCOperand Reg:AT_64>
 ; MIPS64R6-NEXT:    # <MCOperand Expr:%lo(f)>>
@@ -1517,7 +1670,7 @@ define double @f9() {
 ; MMR5FP64-NEXT:    # <MCOperand Expr:%hi(f)>>
 ; MMR5FP64-NEXT:    jr $ra # <MCInst #[[#MCINST5]] JR_MM
 ; MMR5FP64-NEXT:    # <MCOperand Reg:RA>>
-; MMR5FP64-NEXT:    ldc1 $f0, %lo(f)($1) # <MCInst #[[#MCINST33:]] LDC1_MM_D64
+; MMR5FP64-NEXT:    ldc1 $f0, %lo(f)($1) # <MCInst #[[#MCINST34:]] LDC1_MM_D64
 ; MMR5FP64-NEXT:    # <MCOperand Reg:D0_64>
 ; MMR5FP64-NEXT:    # <MCOperand Reg:AT>
 ; MMR5FP64-NEXT:    # <MCOperand Expr:%lo(f)>>
@@ -1529,10 +1682,22 @@ define double @f9() {
 ; MIPS32R5FP643-NEXT:    # <MCOperand Expr:%hi(f)>>
 ; MIPS32R5FP643-NEXT:    jr $ra # <MCInst #[[#MCINST2]] JR
 ; MIPS32R5FP643-NEXT:    # <MCOperand Reg:RA>>
-; MIPS32R5FP643-NEXT:    ldc1 $f0, %lo(f)($1) # <MCInst #[[#MCINST31:]] LDC164
+; MIPS32R5FP643-NEXT:    ldc1 $f0, %lo(f)($1) # <MCInst #[[#MCINST32:]] LDC164
 ; MIPS32R5FP643-NEXT:    # <MCOperand Reg:D0_64>
 ; MIPS32R5FP643-NEXT:    # <MCOperand Reg:AT>
 ; MIPS32R5FP643-NEXT:    # <MCOperand Expr:%lo(f)>>
+;
+; MIPS1-PSX-LABEL: f9:
+; MIPS1-PSX:       # %bb.0: # %entry
+; MIPS1-PSX-NEXT:    lui $1, %hi(f) # <MCInst #[[#MCINST1]] LUi
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:AT>
+; MIPS1-PSX-NEXT:    # <MCOperand Expr:%hi(f)>>
+; MIPS1-PSX-NEXT:    jr $ra # <MCInst #[[#MCINST2]] JR
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:RA>>
+; MIPS1-PSX-NEXT:    ldc1 $f0, %lo(f)($1) # <MCInst #[[#MCINST30:]] LDC1
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:D0>
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:AT>
+; MIPS1-PSX-NEXT:    # <MCOperand Expr:%lo(f)>>
 entry:
   %0 = load double, ptr @f
   ret double %0
diff --git a/llvm/test/CodeGen/Mips/llvm-ir/select-dbl.ll b/llvm/test/CodeGen/Mips/llvm-ir/select-dbl.ll
index 3c1dff3da6aa9..f22d565098909 100644
--- a/llvm/test/CodeGen/Mips/llvm-ir/select-dbl.ll
+++ b/llvm/test/CodeGen/Mips/llvm-ir/select-dbl.ll
@@ -30,6 +30,8 @@
 ; RUN:    -check-prefix=MM32R3
 ; RUN: llc < %s -mtriple=mips-unknown-linux-gnu -mcpu=mips32r6 -mattr=+micromips -verify-machineinstrs | FileCheck %s \
 ; RUN:    -check-prefix=MM32R6
+; RUN: llc < %s -mtriple=mipsel-sony-psx -mcpu=mips1 -verify-machineinstrs | FileCheck %s \
+; RUN:    -check-prefixes=MIPS1-PSX
 
 define double @tst_select_i1_double(i1 signext %s, double %x, double %y) {
 ; M2-LABEL: tst_select_i1_double:
@@ -99,12 +101,28 @@ define double @tst_select_i1_double(i1 signext %s, double %x, double %y) {
 ;
 ; MM32R3-LABEL: tst_select_i1_double:
 ; MM32R3:       # %bb.0: # %entry
-; MM32R3:       mtc1 $7, $f2 # <MCInst #{{.*}} MTC1
-; MM32R3:       mthc1 $6, $f2 # <MCInst #{{.*}} MTHC1_D32_MM
-; MM32R3:       andi16 $2, $4, 1 # <MCInst #{{.*}} ANDI16_MM
-; MM32R3:       ldc1 $f0, 16($sp) # <MCInst #{{.*}} LDC1_MM
-; MM32R3:       jr $ra # <MCInst #{{.*}} JR_MM
-; MM32R3:       movn.d $f0, $f2, $2 # <MCInst #{{.*}} MOVN_I_D32_MM
+; MM32R3-NEXT:    mtc1 $7, $f2 # <MCInst #[[#MCINST1:]] MTC1
+; MM32R3-NEXT:    # <MCOperand Reg:F2>
+; MM32R3-NEXT:    # <MCOperand Reg:A3>>
+; MM32R3-NEXT:    mthc1 $6, $f2 # <MCInst #[[#MCINST2:]] MTHC1_D32_MM
+; MM32R3-NEXT:    # <MCOperand Reg:D1>
+; MM32R3-NEXT:    # <MCOperand Reg:D1>
+; MM32R3-NEXT:    # <MCOperand Reg:A2>>
+; MM32R3-NEXT:    andi16 $2, $4, 1 # <MCInst #[[#MCINST3:]] ANDI16_MM
+; MM32R3-NEXT:    # <MCOperand Reg:V0>
+; MM32R3-NEXT:    # <MCOperand Reg:A0>
+; MM32R3-NEXT:    # <MCOperand Imm:1>>
+; MM32R3-NEXT:    ldc1 $f0, 16($sp) # <MCInst #[[#MCINST4:]] LDC1_MM_D32
+; MM32R3-NEXT:    # <MCOperand Reg:D0>
+; MM32R3-NEXT:    # <MCOperand Reg:SP>
+; MM32R3-NEXT:    # <MCOperand Imm:16>>
+; MM32R3-NEXT:    jr $ra # <MCInst #[[#MCINST5:]] JR_MM
+; MM32R3-NEXT:    # <MCOperand Reg:RA>>
+; MM32R3-NEXT:    movn.d $f0, $f2, $2 # <MCInst #[[#MCINST6:]] MOVN_I_D32_MM
+; MM32R3-NEXT:    # <MCOperand Reg:D0>
+; MM32R3-NEXT:    # <MCOperand Reg:D1>
+; MM32R3-NEXT:    # <MCOperand Reg:V0>
+; MM32R3-NEXT:    # <MCOperand Reg:D0>>
 ;
 ; MM32R6-LABEL: tst_select_i1_double:
 ; MM32R6:       # %bb.0: # %entry
@@ -114,6 +132,20 @@ define double @tst_select_i1_double(i1 signext %s, double %x, double %y) {
 ; MM32R6-NEXT:    mtc1 $4, $f0
 ; MM32R6-NEXT:    sel.d $f0, $f2, $f1
 ; MM32R6-NEXT:    jrc $ra
+;
+; MIPS1-PSX-LABEL: tst_select_i1_double:
+; MIPS1-PSX:       # %bb.0: # %entry
+; MIPS1-PSX-NEXT:    andi $1, $4, 1
+; MIPS1-PSX-NEXT:    bnez $1, $BB0_2
+; MIPS1-PSX-NEXT:    nop
+; MIPS1-PSX-NEXT:  # %bb.1: # %entry
+; MIPS1-PSX-NEXT:    ldc1 $f0, 16($sp)
+; MIPS1-PSX-NEXT:    jr $ra
+; MIPS1-PSX-NEXT:    nop
+; MIPS1-PSX-NEXT:  $BB0_2:
+; MIPS1-PSX-NEXT:    mtc1 $6, $f0
+; MIPS1-PSX-NEXT:    jr $ra
+; MIPS1-PSX-NEXT:    mtc1 $7, $f1
 entry:
   %r = select i1 %s, double %x, double %y
   ret double %r
@@ -181,11 +213,24 @@ define double @tst_select_i1_double_reordered(double %x, double %y,
 ;
 ; MM32R3-LABEL: tst_select_i1_double_reordered:
 ; MM32R3:       # %bb.0: # %entry
-; MM32R3:       mov.d $f0, $f14 # <MCInst #{{.*}} FMOV_D32
-; MM32R3:       lw $2, 16($sp) # <MCInst #{{.*}} LWSP_MM
-; MM32R3:       andi16 $2, $2, 1 # <MCInst #{{.*}} ANDI16_MM
-; MM32R3:       jr $ra # <MCInst #{{.*}} JR_MM
-; MM32R3:       movn.d $f0, $f12, $2 # <MCInst #{{.*}} MOVN_I_D32_MM
+; MM32R3-NEXT:    mov.d $f0, $f14 # <MCInst #[[#MCINST7:]] FMOV_D32
+; MM32R3-NEXT:    # <MCOperand Reg:D0>
+; MM32R3-NEXT:    # <MCOperand Reg:D7>>
+; MM32R3-NEXT:    lw $2, 16($sp) # <MCInst #[[#MCINST8:]] LWSP_MM
+; MM32R3-NEXT:    # <MCOperand Reg:V0>
+; MM32R3-NEXT:    # <MCOperand Reg:SP>
+; MM32R3-NEXT:    # <MCOperand Imm:16>>
+; MM32R3-NEXT:    andi16 $2, $2, 1 # <MCInst #[[#MCINST3]] ANDI16_MM
+; MM32R3-NEXT:    # <MCOperand Reg:V0>
+; MM32R3-NEXT:    # <MCOperand Reg:V0>
+; MM32R3-NEXT:    # <MCOperand Imm:1>>
+; MM32R3-NEXT:    jr $ra # <MCInst #[[#MCINST5]] JR_MM
+; MM32R3-NEXT:    # <MCOperand Reg:RA>>
+; MM32R3-NEXT:    movn.d $f0, $f12, $2 # <MCInst #[[#MCINST6]] MOVN_I_D32_MM
+; MM32R3-NEXT:    # <MCOperand Reg:D0>
+; MM32R3-NEXT:    # <MCOperand Reg:D6>
+; MM32R3-NEXT:    # <MCOperand Reg:V0>
+; MM32R3-NEXT:    # <MCOperand Reg:D0>>
 ;
 ; MM32R6-LABEL: tst_select_i1_double_reordered:
 ; MM32R6:       # %bb.0: # %entry
@@ -193,6 +238,18 @@ define double @tst_select_i1_double_reordered(double %x, double %y,
 ; MM32R6-NEXT:    mtc1 $1, $f0
 ; MM32R6-NEXT:    sel.d $f0, $f14, $f12
 ; MM32R6-NEXT:    jrc $ra
+;
+; MIPS1-PSX-LABEL: tst_select_i1_double_reordered:
+; MIPS1-PSX:       # %bb.0: # %entry
+; MIPS1-PSX-NEXT:    mov.d $f0, $f12
+; MIPS1-PSX-NEXT:    andi $1, $1, 1
+; MIPS1-PSX-NEXT:    bnez $1, $BB1_2
+; MIPS1-PSX-NEXT:    lw $1, 16($sp)
+; MIPS1-PSX-NEXT:  # %bb.1: # %entry
+; MIPS1-PSX-NEXT:    mov.d $f0, $f14
+; MIPS1-PSX-NEXT:  $BB1_2: # %entry
+; MIPS1-PSX-NEXT:    jr $ra
+; MIPS1-PSX-NEXT:    nop
                                               i1 signext %s) {
 entry:
   %r = select i1 %s, double %x, double %y
@@ -259,16 +316,38 @@ define double @tst_select_fcmp_olt_double(double %x, double %y) {
 ;
 ; MM32R3-LABEL: tst_select_fcmp_olt_double:
 ; MM32R3:       # %bb.0: # %entry
-; MM32R3:       mov.d $f0, $f14 # <MCInst #{{.*}} FMOV_D32
-; MM32R3:       c.olt.d $f12, $f14 # <MCInst #{{.*}} FCMP_D32_MM
-; MM32R3:       jr $ra # <MCInst #{{.*}} JR_MM
-; MM32R3:       movt.d $f0, $f12, $fcc0 # <MCInst #{{.*}} MOVT_D32_MM
+; MM32R3-NEXT:    mov.d $f0, $f14 # <MCInst #[[#MCINST7]] FMOV_D32
+; MM32R3-NEXT:    # <MCOperand Reg:D0>
+; MM32R3-NEXT:    # <MCOperand Reg:D7>>
+; MM32R3-NEXT:    c.olt.d $f12, $f14 # <MCInst #[[#MCINST9:]] FCMP_D32_MM
+; MM32R3-NEXT:    # <MCOperand Reg:D6>
+; MM32R3-NEXT:    # <MCOperand Reg:D7>
+; MM32R3-NEXT:    # <MCOperand Imm:4>>
+; MM32R3-NEXT:    jr $ra # <MCInst #[[#MCINST5]] JR_MM
+; MM32R3-NEXT:    # <MCOperand Reg:RA>>
+; MM32R3-NEXT:    movt.d $f0, $f12, $fcc0 # <MCInst #[[#MCINST10:]] MOVT_D32_MM
+; MM32R3-NEXT:    # <MCOperand Reg:D0>
+; MM32R3-NEXT:    # <MCOperand Reg:D6>
+; MM32R3-NEXT:    # <MCOperand Reg:FCC0>
+; MM32R3-NEXT:    # <MCOperand Reg:D0>>
 ;
 ; MM32R6-LABEL: tst_select_fcmp_olt_double:
 ; MM32R6:       # %bb.0: # %entry
 ; MM32R6-NEXT:    cmp.lt.d $f0, $f12, $f14
 ; MM32R6-NEXT:    sel.d $f0, $f14, $f12
 ; MM32R6-NEXT:    jrc $ra
+;
+; MIPS1-PSX-LABEL: tst_select_fcmp_olt_double:
+; MIPS1-PSX:       # %bb.0: # %entry
+; MIPS1-PSX-NEXT:    c.olt.d $f12, $f14
+; MIPS1-PSX-NEXT:    nop
+; MIPS1-PSX-NEXT:    bc1t $BB2_2
+; MIPS1-PSX-NEXT:    mov.d $f0, $f12
+; MIPS1-PSX-NEXT:  # %bb.1: # %entry
+; MIPS1-PSX-NEXT:    mov.d $f0, $f14
+; MIPS1-PSX-NEXT:  $BB2_2: # %entry
+; MIPS1-PSX-NEXT:    jr $ra
+; MIPS1-PSX-NEXT:    nop
 entry:
   %s = fcmp olt double %x, %y
   %r = select i1 %s, double %x, double %y
@@ -335,16 +414,38 @@ define double @tst_select_fcmp_ole_double(double %x, double %y) {
 ;
 ; MM32R3-LABEL: tst_select_fcmp_ole_double:
 ; MM32R3:       # %bb.0: # %entry
-; MM32R3:       mov.d $f0, $f14 # <MCInst #{{.*}} FMOV_D32
-; MM32R3:       c.ole.d $f12, $f14 # <MCInst #{{.*}} FCMP_D32_MM
-; MM32R3:       jr $ra # <MCInst #{{.*}} JR_MM
-; MM32R3:       movt.d $f0, $f12, $fcc0 # <MCInst #{{.*}} MOVT_D32_MM
+; MM32R3-NEXT:    mov.d $f0, $f14 # <MCInst #[[#MCINST7]] FMOV_D32
+; MM32R3-NEXT:    # <MCOperand Reg:D0>
+; MM32R3-NEXT:    # <MCOperand Reg:D7>>
+; MM32R3-NEXT:    c.ole.d $f12, $f14 # <MCInst #[[#MCINST9]] FCMP_D32_MM
+; MM32R3-NEXT:    # <MCOperand Reg:D6>
+; MM32R3-NEXT:    # <MCOperand Reg:D7>
+; MM32R3-NEXT:    # <MCOperand Imm:6>>
+; MM32R3-NEXT:    jr $ra # <MCInst #[[#MCINST5]] JR_MM
+; MM32R3-NEXT:    # <MCOperand Reg:RA>>
+; MM32R3-NEXT:    movt.d $f0, $f12, $fcc0 # <MCInst #[[#MCINST10]] MOVT_D32_MM
+; MM32R3-NEXT:    # <MCOperand Reg:D0>
+; MM32R3-NEXT:    # <MCOperand Reg:D6>
+; MM32R3-NEXT:    # <MCOperand Reg:FCC0>
+; MM32R3-NEXT:    # <MCOperand Reg:D0>>
 ;
 ; MM32R6-LABEL: tst_select_fcmp_ole_double:
 ; MM32R6:       # %bb.0: # %entry
 ; MM32R6-NEXT:    cmp.le.d $f0, $f12, $f14
 ; MM32R6-NEXT:    sel.d $f0, $f14, $f12
 ; MM32R6-NEXT:    jrc $ra
+;
+; MIPS1-PSX-LABEL: tst_select_fcmp_ole_double:
+; MIPS1-PSX:       # %bb.0: # %entry
+; MIPS1-PSX-NEXT:    c.ole.d $f12, $f14
+; MIPS1-PSX-NEXT:    nop
+; MIPS1-PSX-NEXT:    bc1t $BB3_2
+; MIPS1-PSX-NEXT:    mov.d $f0, $f12
+; MIPS1-PSX-NEXT:  # %bb.1: # %entry
+; MIPS1-PSX-NEXT:    mov.d $f0, $f14
+; MIPS1-PSX-NEXT:  $BB3_2: # %entry
+; MIPS1-PSX-NEXT:    jr $ra
+; MIPS1-PSX-NEXT:    nop
 entry:
   %s = fcmp ole double %x, %y
   %r = select i1 %s, double %x, double %y
@@ -411,16 +512,38 @@ define double @tst_select_fcmp_ogt_double(double %x, double %y) {
 ;
 ; MM32R3-LABEL: tst_select_fcmp_ogt_double:
 ; MM32R3:       # %bb.0: # %entry
-; MM32R3:       mov.d $f0, $f14 # <MCInst #{{.*}} FMOV_D32
-; MM32R3:       c.ule.d $f12, $f14 # <MCInst #{{.*}} FCMP_D32_MM
-; MM32R3:       jr $ra # <MCInst #{{.*}} JR_MM
-; MM32R3:       movf.d $f0, $f12, $fcc0 # <MCInst #{{.*}} MOVF_D32_MM
+; MM32R3-NEXT:    mov.d $f0, $f14 # <MCInst #[[#MCINST7]] FMOV_D32
+; MM32R3-NEXT:    # <MCOperand Reg:D0>
+; MM32R3-NEXT:    # <MCOperand Reg:D7>>
+; MM32R3-NEXT:    c.ule.d $f12, $f14 # <MCInst #[[#MCINST9]] FCMP_D32_MM
+; MM32R3-NEXT:    # <MCOperand Reg:D6>
+; MM32R3-NEXT:    # <MCOperand Reg:D7>
+; MM32R3-NEXT:    # <MCOperand Imm:23>>
+; MM32R3-NEXT:    jr $ra # <MCInst #[[#MCINST5]] JR_MM
+; MM32R3-NEXT:    # <MCOperand Reg:RA>>
+; MM32R3-NEXT:    movf.d $f0, $f12, $fcc0 # <MCInst #[[#MCINST11:]] MOVF_D32_MM
+; MM32R3-NEXT:    # <MCOperand Reg:D0>
+; MM32R3-NEXT:    # <MCOperand Reg:D6>
+; MM32R3-NEXT:    # <MCOperand Reg:FCC0>
+; MM32R3-NEXT:    # <MCOperand Reg:D0>>
 ;
 ; MM32R6-LABEL: tst_select_fcmp_ogt_double:
 ; MM32R6:       # %bb.0: # %entry
 ; MM32R6-NEXT:    cmp.lt.d $f0, $f14, $f12
 ; MM32R6-NEXT:    sel.d $f0, $f14, $f12
 ; MM32R6-NEXT:    jrc $ra
+;
+; MIPS1-PSX-LABEL: tst_select_fcmp_ogt_double:
+; MIPS1-PSX:       # %bb.0: # %entry
+; MIPS1-PSX-NEXT:    c.ule.d $f12, $f14
+; MIPS1-PSX-NEXT:    nop
+; MIPS1-PSX-NEXT:    bc1f $BB4_2
+; MIPS1-PSX-NEXT:    mov.d $f0, $f12
+; MIPS1-PSX-NEXT:  # %bb.1: # %entry
+; MIPS1-PSX-NEXT:    mov.d $f0, $f14
+; MIPS1-PSX-NEXT:  $BB4_2: # %entry
+; MIPS1-PSX-NEXT:    jr $ra
+; MIPS1-PSX-NEXT:    nop
 entry:
   %s = fcmp ogt double %x, %y
   %r = select i1 %s, double %x, double %y
@@ -487,16 +610,38 @@ define double @tst_select_fcmp_oge_double(double %x, double %y) {
 ;
 ; MM32R3-LABEL: tst_select_fcmp_oge_double:
 ; MM32R3:       # %bb.0: # %entry
-; MM32R3:       mov.d $f0, $f14 # <MCInst #{{.*}} FMOV_D32
-; MM32R3:       c.ult.d $f12, $f14 # <MCInst #{{.*}} FCMP_D32_MM
-; MM32R3:       jr $ra # <MCInst #{{.*}} JR_MM
-; MM32R3:       movf.d $f0, $f12, $fcc0 # <MCInst #{{.*}} MOVF_D32_MM
+; MM32R3-NEXT:    mov.d $f0, $f14 # <MCInst #[[#MCINST7]] FMOV_D32
+; MM32R3-NEXT:    # <MCOperand Reg:D0>
+; MM32R3-NEXT:    # <MCOperand Reg:D7>>
+; MM32R3-NEXT:    c.ult.d $f12, $f14 # <MCInst #[[#MCINST9]] FCMP_D32_MM
+; MM32R3-NEXT:    # <MCOperand Reg:D6>
+; MM32R3-NEXT:    # <MCOperand Reg:D7>
+; MM32R3-NEXT:    # <MCOperand Imm:21>>
+; MM32R3-NEXT:    jr $ra # <MCInst #[[#MCINST5]] JR_MM
+; MM32R3-NEXT:    # <MCOperand Reg:RA>>
+; MM32R3-NEXT:    movf.d $f0, $f12, $fcc0 # <MCInst #[[#MCINST11]] MOVF_D32_MM
+; MM32R3-NEXT:    # <MCOperand Reg:D0>
+; MM32R3-NEXT:    # <MCOperand Reg:D6>
+; MM32R3-NEXT:    # <MCOperand Reg:FCC0>
+; MM32R3-NEXT:    # <MCOperand Reg:D0>>
 ;
 ; MM32R6-LABEL: tst_select_fcmp_oge_double:
 ; MM32R6:       # %bb.0: # %entry
 ; MM32R6-NEXT:    cmp.le.d $f0, $f14, $f12
 ; MM32R6-NEXT:    sel.d $f0, $f14, $f12
 ; MM32R6-NEXT:    jrc $ra
+;
+; MIPS1-PSX-LABEL: tst_select_fcmp_oge_double:
+; MIPS1-PSX:       # %bb.0: # %entry
+; MIPS1-PSX-NEXT:    c.ult.d $f12, $f14
+; MIPS1-PSX-NEXT:    nop
+; MIPS1-PSX-NEXT:    bc1f $BB5_2
+; MIPS1-PSX-NEXT:    mov.d $f0, $f12
+; MIPS1-PSX-NEXT:  # %bb.1: # %entry
+; MIPS1-PSX-NEXT:    mov.d $f0, $f14
+; MIPS1-PSX-NEXT:  $BB5_2: # %entry
+; MIPS1-PSX-NEXT:    jr $ra
+; MIPS1-PSX-NEXT:    nop
 entry:
   %s = fcmp oge double %x, %y
   %r = select i1 %s, double %x, double %y
@@ -563,16 +708,38 @@ define double @tst_select_fcmp_oeq_double(double %x, double %y) {
 ;
 ; MM32R3-LABEL: tst_select_fcmp_oeq_double:
 ; MM32R3:       # %bb.0: # %entry
-; MM32R3:       mov.d $f0, $f14 # <MCInst #{{.*}} FMOV_D32
-; MM32R3:       c.eq.d $f12, $f14 # <MCInst #{{.*}} FCMP_D32_MM
-; MM32R3:       jr $ra # <MCInst #{{.*}} JR_MM
-; MM32R3:       movt.d $f0, $f12, $fcc0 # <MCInst #{{.*}} MOVT_D32_MM
+; MM32R3-NEXT:    mov.d $f0, $f14 # <MCInst #[[#MCINST7]] FMOV_D32
+; MM32R3-NEXT:    # <MCOperand Reg:D0>
+; MM32R3-NEXT:    # <MCOperand Reg:D7>>
+; MM32R3-NEXT:    c.eq.d $f12, $f14 # <MCInst #[[#MCINST9]] FCMP_D32_MM
+; MM32R3-NEXT:    # <MCOperand Reg:D6>
+; MM32R3-NEXT:    # <MCOperand Reg:D7>
+; MM32R3-NEXT:    # <MCOperand Imm:2>>
+; MM32R3-NEXT:    jr $ra # <MCInst #[[#MCINST5]] JR_MM
+; MM32R3-NEXT:    # <MCOperand Reg:RA>>
+; MM32R3-NEXT:    movt.d $f0, $f12, $fcc0 # <MCInst #[[#MCINST10]] MOVT_D32_MM
+; MM32R3-NEXT:    # <MCOperand Reg:D0>
+; MM32R3-NEXT:    # <MCOperand Reg:D6>
+; MM32R3-NEXT:    # <MCOperand Reg:FCC0>
+; MM32R3-NEXT:    # <MCOperand Reg:D0>>
 ;
 ; MM32R6-LABEL: tst_select_fcmp_oeq_double:
 ; MM32R6:       # %bb.0: # %entry
 ; MM32R6-NEXT:    cmp.eq.d $f0, $f12, $f14
 ; MM32R6-NEXT:    sel.d $f0, $f14, $f12
 ; MM32R6-NEXT:    jrc $ra
+;
+; MIPS1-PSX-LABEL: tst_select_fcmp_oeq_double:
+; MIPS1-PSX:       # %bb.0: # %entry
+; MIPS1-PSX-NEXT:    c.eq.d $f12, $f14
+; MIPS1-PSX-NEXT:    nop
+; MIPS1-PSX-NEXT:    bc1t $BB6_2
+; MIPS1-PSX-NEXT:    mov.d $f0, $f12
+; MIPS1-PSX-NEXT:  # %bb.1: # %entry
+; MIPS1-PSX-NEXT:    mov.d $f0, $f14
+; MIPS1-PSX-NEXT:  $BB6_2: # %entry
+; MIPS1-PSX-NEXT:    jr $ra
+; MIPS1-PSX-NEXT:    nop
 entry:
   %s = fcmp oeq double %x, %y
   %r = select i1 %s, double %x, double %y
@@ -639,16 +806,38 @@ define double @tst_select_fcmp_one_double(double %x, double %y) {
 ;
 ; MM32R3-LABEL: tst_select_fcmp_one_double:
 ; MM32R3:       # %bb.0: # %entry
-; MM32R3:       mov.d $f0, $f14 # <MCInst #{{.*}} FMOV_D32
-; MM32R3:       c.ueq.d $f12, $f14 # <MCInst #{{.*}} FCMP_D32_MM
-; MM32R3:       jr $ra # <MCInst #{{.*}} JR_MM
-; MM32R3:       movf.d $f0, $f12, $fcc0 # <MCInst #{{.*}} MOVF_D32_MM
+; MM32R3-NEXT:    mov.d $f0, $f14 # <MCInst #[[#MCINST7]] FMOV_D32
+; MM32R3-NEXT:    # <MCOperand Reg:D0>
+; MM32R3-NEXT:    # <MCOperand Reg:D7>>
+; MM32R3-NEXT:    c.ueq.d $f12, $f14 # <MCInst #[[#MCINST9]] FCMP_D32_MM
+; MM32R3-NEXT:    # <MCOperand Reg:D6>
+; MM32R3-NEXT:    # <MCOperand Reg:D7>
+; MM32R3-NEXT:    # <MCOperand Imm:19>>
+; MM32R3-NEXT:    jr $ra # <MCInst #[[#MCINST5]] JR_MM
+; MM32R3-NEXT:    # <MCOperand Reg:RA>>
+; MM32R3-NEXT:    movf.d $f0, $f12, $fcc0 # <MCInst #[[#MCINST11]] MOVF_D32_MM
+; MM32R3-NEXT:    # <MCOperand Reg:D0>
+; MM32R3-NEXT:    # <MCOperand Reg:D6>
+; MM32R3-NEXT:    # <MCOperand Reg:FCC0>
+; MM32R3-NEXT:    # <MCOperand Reg:D0>>
 ;
 ; MM32R6-LABEL: tst_select_fcmp_one_double:
 ; MM32R6:       # %bb.0: # %entry
 ; MM32R6-NEXT:    cmp.ueq.d $f0, $f12, $f14
 ; MM32R6-NEXT:    sel.d $f0, $f12, $f14
 ; MM32R6-NEXT:    jrc $ra
+;
+; MIPS1-PSX-LABEL: tst_select_fcmp_one_double:
+; MIPS1-PSX:       # %bb.0: # %entry
+; MIPS1-PSX-NEXT:    c.ueq.d $f12, $f14
+; MIPS1-PSX-NEXT:    nop
+; MIPS1-PSX-NEXT:    bc1f $BB7_2
+; MIPS1-PSX-NEXT:    mov.d $f0, $f12
+; MIPS1-PSX-NEXT:  # %bb.1: # %entry
+; MIPS1-PSX-NEXT:    mov.d $f0, $f14
+; MIPS1-PSX-NEXT:  $BB7_2: # %entry
+; MIPS1-PSX-NEXT:    jr $ra
+; MIPS1-PSX-NEXT:    nop
 entry:
   %s = fcmp one double %x, %y
   %r = select i1 %s, double %x, double %y
diff --git a/llvm/test/CodeGen/Mips/mips1-load-in-delay-slot.ll b/llvm/test/CodeGen/Mips/mips1-load-in-delay-slot.ll
new file mode 100644
index 0000000000000..4499dc6123fd1
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/mips1-load-in-delay-slot.ll
@@ -0,0 +1,61 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=mipsel-sony-psx -mcpu=mips1 -relocation-model=pic | FileCheck %s -check-prefixes=MIPS1-PSX
+
+ at data = internal global <{ [1 x i8] }> <{ [1 x i8] c"\00" }>, align 4
+
+define internal fastcc void @test() unnamed_addr #0 {
+; MIPS1-PSX-LABEL: test:
+; MIPS1-PSX:       # %bb.0: # %start
+; MIPS1-PSX-NEXT:    lui $2, %hi(_gp_disp)
+; MIPS1-PSX-NEXT:    addiu $2, $2, %lo(_gp_disp)
+; MIPS1-PSX-NEXT:    addu $1, $2, $25
+; MIPS1-PSX-NEXT:    lw $2, %got(data)($1)
+; MIPS1-PSX-NEXT:    nop
+; MIPS1-PSX-NEXT:    addiu $1, $2, %lo(data)
+; MIPS1-PSX-NEXT:    lbu $1, 2($1)
+; MIPS1-PSX-NEXT:    addiu $3, $zero, 2
+; MIPS1-PSX-NEXT:    bne $1, $3, $BB0_2
+; MIPS1-PSX-NEXT:    nop
+; MIPS1-PSX-NEXT:  $BB0_1: # %unreachable.1
+; MIPS1-PSX-NEXT:    .insn
+; MIPS1-PSX-NEXT:  $BB0_2: # %bb6.i
+; MIPS1-PSX-NEXT:    lbu $2, %lo(data)($2)
+; MIPS1-PSX-NEXT:    addiu $1, $zero, 1
+; MIPS1-PSX-NEXT:    bnez $1, $BB0_5
+; MIPS1-PSX-NEXT:    nop
+; MIPS1-PSX-NEXT:  # %bb.3: # %bb9.i
+; MIPS1-PSX-NEXT:    andi $1, $2, 1
+; MIPS1-PSX-NEXT:    bnez $1, $BB0_1
+; MIPS1-PSX-NEXT:    nop
+; MIPS1-PSX-NEXT:  # %bb.4: # %bb9.i
+; MIPS1-PSX-NEXT:    b $BB0_6
+; MIPS1-PSX-NEXT:    nop
+; MIPS1-PSX-NEXT:  $BB0_5: # %bb10.i
+; MIPS1-PSX-NEXT:    andi $1, $2, 1
+; MIPS1-PSX-NEXT:    bnez $1, $BB0_1
+; MIPS1-PSX-NEXT:    nop
+; MIPS1-PSX-NEXT:  $BB0_6: # %unreachable.2
+; MIPS1-PSX-NEXT:    .insn
+start:
+  %0 = load i8, ptr getelementptr inbounds nuw (i8, ptr @data, i32 2), align 2, !range !{i8 0, i8 3}, !noundef !{}
+  %.not.i = icmp eq i8 %0, 2
+  br i1 %.not.i, label %unreachable.1, label %bb6.i
+
+bb6.i:                                            ; preds = %start
+  %1 = trunc nuw i8 0 to i1
+  %2 = load i8, ptr @data, align 4, !range !{i8 0, i8 2}, !noundef !{}
+  %3 = trunc nuw i8 %2 to i1
+  br i1 %1, label %bb9.i, label %bb10.i
+
+bb9.i:                                            ; preds = %bb6.i
+  br i1 %3, label %unreachable.1, label %unreachable.2
+
+bb10.i:                                           ; preds = %bb6.i
+  br i1 %3, label %unreachable.1, label %unreachable.2
+
+unreachable.1:
+  unreachable
+
+unreachable.2:
+  unreachable
+}
diff --git a/llvm/test/CodeGen/Mips/unalignedload.ll b/llvm/test/CodeGen/Mips/unalignedload.ll
index 5c78519e6481f..88fc405f3d198 100644
--- a/llvm/test/CodeGen/Mips/unalignedload.ll
+++ b/llvm/test/CodeGen/Mips/unalignedload.ll
@@ -1,10 +1,11 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
-; RUN: llc  < %s -mtriple=mipsel-elf -mcpu=mips32   -relocation-model=pic | FileCheck %s -check-prefixes=MIPS32-EL
-; RUN: llc  < %s -mtriple=mips-elf   -mcpu=mips32   -relocation-model=pic | FileCheck %s -check-prefixes=MIPS32-EB
-; RUN: llc  < %s -mtriple=mipsel-elf -mcpu=mips32r2 -relocation-model=pic | FileCheck %s -check-prefixes=MIPS32-EL
-; RUN: llc  < %s -mtriple=mips-elf   -mcpu=mips32r2 -relocation-model=pic | FileCheck %s -check-prefixes=MIPS32-EB
-; RUN: llc  < %s -mtriple=mipsel-elf -mcpu=mips32r6 -relocation-model=pic | FileCheck %s -check-prefixes=MIPS32R6-EL
-; RUN: llc  < %s -mtriple=mips-elf   -mcpu=mips32r6 -relocation-model=pic | FileCheck %s -check-prefixes=MIPS32R6-EB
+; RUN: llc  < %s -mtriple=mipsel-elf      -mcpu=mips32   -relocation-model=pic | FileCheck %s -check-prefixes=MIPS32-EL
+; RUN: llc  < %s -mtriple=mips-elf        -mcpu=mips32   -relocation-model=pic | FileCheck %s -check-prefixes=MIPS32-EB
+; RUN: llc  < %s -mtriple=mipsel-elf      -mcpu=mips32r2 -relocation-model=pic | FileCheck %s -check-prefixes=MIPS32-EL
+; RUN: llc  < %s -mtriple=mips-elf        -mcpu=mips32r2 -relocation-model=pic | FileCheck %s -check-prefixes=MIPS32-EB
+; RUN: llc  < %s -mtriple=mipsel-elf      -mcpu=mips32r6 -relocation-model=pic | FileCheck %s -check-prefixes=MIPS32R6-EL
+; RUN: llc  < %s -mtriple=mips-elf        -mcpu=mips32r6 -relocation-model=pic | FileCheck %s -check-prefixes=MIPS32R6-EB
+; RUN: llc  < %s -mtriple=mipsel-sony-psx -mcpu=mips1    -relocation-model=pic | FileCheck %s -check-prefixes=MIPS1-PSX
 
 %struct.S2 = type { %struct.S1, %struct.S1 }
 %struct.S1 = type { i8, i8 }
@@ -89,6 +90,30 @@ define void @bar1() nounwind {
 ; MIPS32R6-EB-NEXT:    lw $ra, 20($sp) # 4-byte Folded Reload
 ; MIPS32R6-EB-NEXT:    jr $ra
 ; MIPS32R6-EB-NEXT:    addiu $sp, $sp, 24
+;
+; MIPS1-PSX-LABEL: bar1:
+; MIPS1-PSX:       # %bb.0: # %entry
+; MIPS1-PSX-NEXT:    lui $2, %hi(_gp_disp)
+; MIPS1-PSX-NEXT:    addiu $2, $2, %lo(_gp_disp)
+; MIPS1-PSX-NEXT:    addiu $sp, $sp, -24
+; MIPS1-PSX-NEXT:    sw $ra, 20($sp) # 4-byte Folded Spill
+; MIPS1-PSX-NEXT:    addu $gp, $2, $25
+; MIPS1-PSX-NEXT:    lw $1, %got(s2)($gp)
+; MIPS1-PSX-NEXT:    nop
+; MIPS1-PSX-NEXT:    lbu $2, 2($1)
+; MIPS1-PSX-NEXT:    lbu $1, 3($1)
+; MIPS1-PSX-NEXT:    nop
+; MIPS1-PSX-NEXT:    sll $1, $1, 8
+; MIPS1-PSX-NEXT:    lw $25, %call16(foo2)($gp)
+; MIPS1-PSX-NEXT:    nop
+; MIPS1-PSX-NEXT:    .reloc $tmp0, R_MIPS_JALR, foo2
+; MIPS1-PSX-NEXT:  $tmp0:
+; MIPS1-PSX-NEXT:    jalr $25
+; MIPS1-PSX-NEXT:    or $4, $1, $2
+; MIPS1-PSX-NEXT:    lw $ra, 20($sp) # 4-byte Folded Reload
+; MIPS1-PSX-NEXT:    nop
+; MIPS1-PSX-NEXT:    jr $ra
+; MIPS1-PSX-NEXT:    addiu $sp, $sp, 24
 entry:
   tail call void @foo2(ptr byval(%struct.S1) getelementptr inbounds (%struct.S2, ptr @s2, i32 0, i32 1)) nounwind
   ret void
@@ -189,6 +214,37 @@ define void @bar2() nounwind {
 ; MIPS32R6-EB-NEXT:    lw $ra, 20($sp) # 4-byte Folded Reload
 ; MIPS32R6-EB-NEXT:    jr $ra
 ; MIPS32R6-EB-NEXT:    addiu $sp, $sp, 24
+;
+; MIPS1-PSX-LABEL: bar2:
+; MIPS1-PSX:       # %bb.0: # %entry
+; MIPS1-PSX-NEXT:    lui $2, %hi(_gp_disp)
+; MIPS1-PSX-NEXT:    addiu $2, $2, %lo(_gp_disp)
+; MIPS1-PSX-NEXT:    addiu $sp, $sp, -24
+; MIPS1-PSX-NEXT:    sw $ra, 20($sp) # 4-byte Folded Spill
+; MIPS1-PSX-NEXT:    addu $gp, $2, $25
+; MIPS1-PSX-NEXT:    lw $1, %got(s4)($gp)
+; MIPS1-PSX-NEXT:    nop
+; MIPS1-PSX-NEXT:    lwl $4, 3($1)
+; MIPS1-PSX-NEXT:    nop
+; MIPS1-PSX-NEXT:    lwr $4, 0($1)
+; MIPS1-PSX-NEXT:    lbu $2, 4($1)
+; MIPS1-PSX-NEXT:    lbu $3, 5($1)
+; MIPS1-PSX-NEXT:    nop
+; MIPS1-PSX-NEXT:    sll $3, $3, 8
+; MIPS1-PSX-NEXT:    or $2, $3, $2
+; MIPS1-PSX-NEXT:    lbu $1, 6($1)
+; MIPS1-PSX-NEXT:    nop
+; MIPS1-PSX-NEXT:    sll $1, $1, 16
+; MIPS1-PSX-NEXT:    lw $25, %call16(foo4)($gp)
+; MIPS1-PSX-NEXT:    nop
+; MIPS1-PSX-NEXT:    .reloc $tmp1, R_MIPS_JALR, foo4
+; MIPS1-PSX-NEXT:  $tmp1:
+; MIPS1-PSX-NEXT:    jalr $25
+; MIPS1-PSX-NEXT:    or $5, $2, $1
+; MIPS1-PSX-NEXT:    lw $ra, 20($sp) # 4-byte Folded Reload
+; MIPS1-PSX-NEXT:    nop
+; MIPS1-PSX-NEXT:    jr $ra
+; MIPS1-PSX-NEXT:    addiu $sp, $sp, 24
 entry:
   tail call void @foo4(ptr byval(%struct.S4) @s4) nounwind
   ret void

>From f43c7c3f4862f723201cb58d578af082fa715131 Mon Sep 17 00:00:00 2001
From: Jaby <jaby at william.zone>
Date: Fri, 3 Apr 2026 14:03:17 +0100
Subject: [PATCH 14/18] Do not ignore memory re-ordering

---
 llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp b/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp
index 3bf81f1e93b0a..92a6f048d6559 100644
--- a/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp
+++ b/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp
@@ -1116,8 +1116,8 @@ bool MipsDelaySlotFiller::delayHasHazard(const MipsSubtarget &STI,
   HasHazard |= IM.hasHazard(Candidate);
   HasHazard |= RegDU.update(Candidate, 0, Candidate.getNumOperands());
 
-  // This only matters for MIPS1
-  if (!STI.hasMips2()) {
+  // This only matters for MIPS1 and only if we do not have a hazard already
+  if (!STI.hasMips2() && !HasHazard) {
     const MipsInstrInfo* TII = STI.getInstrInfo();
     const bool HasLoadDelaySlot = TII->HasLoadDelaySlot(Candidate);
 
@@ -1176,7 +1176,7 @@ bool MipsDelaySlotFiller::delayHasHazard(const MipsSubtarget &STI,
         }
       }
 
-      tmp_out << "\tNew Hazard?: " << (HasNewHazard ? "Yes" : "No")
+      tmp_out << "\tNew Hazard detected?: " << (HasNewHazard ? "Yes" : "No") << " Old Hazard detected: " << (HasHazard ? "Yes" : "No")
               << "\n---\n";
       return HasNewHazard;
     }

>From 83b1ba348318ce65ac1618a7fe3537efa3198473 Mon Sep 17 00:00:00 2001
From: William Young <william at werl.me>
Date: Fri, 3 Apr 2026 19:16:29 +0000
Subject: [PATCH 15/18] Update tests

---
 llvm/test/CodeGen/Mips/llvm-ir/select-dbl.ll | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/llvm/test/CodeGen/Mips/llvm-ir/select-dbl.ll b/llvm/test/CodeGen/Mips/llvm-ir/select-dbl.ll
index f22d565098909..f39be636e09d4 100644
--- a/llvm/test/CodeGen/Mips/llvm-ir/select-dbl.ll
+++ b/llvm/test/CodeGen/Mips/llvm-ir/select-dbl.ll
@@ -241,10 +241,11 @@ define double @tst_select_i1_double_reordered(double %x, double %y,
 ;
 ; MIPS1-PSX-LABEL: tst_select_i1_double_reordered:
 ; MIPS1-PSX:       # %bb.0: # %entry
-; MIPS1-PSX-NEXT:    mov.d $f0, $f12
+; MIPS1-PSX-NEXT:    lw $1, 16($sp)
+; MIPS1-PSX-NEXT:    nop
 ; MIPS1-PSX-NEXT:    andi $1, $1, 1
 ; MIPS1-PSX-NEXT:    bnez $1, $BB1_2
-; MIPS1-PSX-NEXT:    lw $1, 16($sp)
+; MIPS1-PSX-NEXT:    mov.d $f0, $f12
 ; MIPS1-PSX-NEXT:  # %bb.1: # %entry
 ; MIPS1-PSX-NEXT:    mov.d $f0, $f14
 ; MIPS1-PSX-NEXT:  $BB1_2: # %entry

>From 506b5f498ffdb9a9a86168c76465bb8863ff5f29 Mon Sep 17 00:00:00 2001
From: Jaby <jaby at william.zone>
Date: Tue, 24 Mar 2026 22:10:18 +0000
Subject: [PATCH 16/18] Implicit register use in load delay slot is fine

---
 llvm/lib/Target/Mips/MipsInstrInfo.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Target/Mips/MipsInstrInfo.cpp b/llvm/lib/Target/Mips/MipsInstrInfo.cpp
index c08c963a33c71..d1a47750d23d2 100644
--- a/llvm/lib/Target/Mips/MipsInstrInfo.cpp
+++ b/llvm/lib/Target/Mips/MipsInstrInfo.cpp
@@ -636,7 +636,8 @@ bool MipsInstrInfo::SafeInLoadDelaySlot(const MachineInstr &MIInSlot,
     return false;
 
   return !llvm::any_of(LoadMI.defs(), [&](const MachineOperand &Op) {
-    return Op.isReg() && MIInSlot.readsRegister(Op.getReg(), /*TRI=*/nullptr);
+    return Op.isReg() && MIInSlot.readsRegister(Op.getReg(), /*TRI=*/nullptr) &&
+           !MIInSlot.hasRegisterImplicitUseOperand(Op.getReg());
   });
 }
 

>From dac83049dec616a5e4bf0e2781ccfa5c95d1f25c Mon Sep 17 00:00:00 2001
From: William Young <william at werl.me>
Date: Sun, 29 Mar 2026 17:37:33 +0000
Subject: [PATCH 17/18] Update tests

---
 llvm/test/CodeGen/Mips/llvm-ir/load.ll | 30 +-------------------------
 1 file changed, 1 insertion(+), 29 deletions(-)

diff --git a/llvm/test/CodeGen/Mips/llvm-ir/load.ll b/llvm/test/CodeGen/Mips/llvm-ir/load.ll
index 232d74677914f..834880f1ad74e 100644
--- a/llvm/test/CodeGen/Mips/llvm-ir/load.ll
+++ b/llvm/test/CodeGen/Mips/llvm-ir/load.ll
@@ -191,13 +191,9 @@ define i8 @f1() {
 ; MIPS1-PSX-NEXT:    # <MCOperand Reg:V0>
 ; MIPS1-PSX-NEXT:    # <MCOperand Reg:AT>
 ; MIPS1-PSX-NEXT:    # <MCOperand Expr:%lo(a)>>
-; MIPS1-PSX-NEXT:    nop # <MCInst #[[#MCINST13:]] SLL
-; MIPS1-PSX-NEXT:    # <MCOperand Reg:ZERO>
-; MIPS1-PSX-NEXT:    # <MCOperand Reg:ZERO>
-; MIPS1-PSX-NEXT:    # <MCOperand Imm:0>>
 ; MIPS1-PSX-NEXT:    jr $ra # <MCInst #[[#MCINST2:]] JR
 ; MIPS1-PSX-NEXT:    # <MCOperand Reg:RA>>
-; MIPS1-PSX-NEXT:    nop # <MCInst #[[#MCINST13]] SLL
+; MIPS1-PSX-NEXT:    nop # <MCInst #[[#MCINST13:]] SLL
 ; MIPS1-PSX-NEXT:    # <MCOperand Reg:ZERO>
 ; MIPS1-PSX-NEXT:    # <MCOperand Reg:ZERO>
 ; MIPS1-PSX-NEXT:    # <MCOperand Imm:0>>
@@ -374,10 +370,6 @@ define i32 @f2() {
 ; MIPS1-PSX-NEXT:    # <MCOperand Reg:V0>
 ; MIPS1-PSX-NEXT:    # <MCOperand Reg:AT>
 ; MIPS1-PSX-NEXT:    # <MCOperand Expr:%lo(a)>>
-; MIPS1-PSX-NEXT:    nop # <MCInst #[[#MCINST13]] SLL
-; MIPS1-PSX-NEXT:    # <MCOperand Reg:ZERO>
-; MIPS1-PSX-NEXT:    # <MCOperand Reg:ZERO>
-; MIPS1-PSX-NEXT:    # <MCOperand Imm:0>>
 ; MIPS1-PSX-NEXT:    jr $ra # <MCInst #[[#MCINST2]] JR
 ; MIPS1-PSX-NEXT:    # <MCOperand Reg:RA>>
 ; MIPS1-PSX-NEXT:    nop # <MCInst #[[#MCINST13]] SLL
@@ -558,10 +550,6 @@ define i16 @f3() {
 ; MIPS1-PSX-NEXT:    # <MCOperand Reg:V0>
 ; MIPS1-PSX-NEXT:    # <MCOperand Reg:AT>
 ; MIPS1-PSX-NEXT:    # <MCOperand Expr:%lo(b)>>
-; MIPS1-PSX-NEXT:    nop # <MCInst #[[#MCINST13]] SLL
-; MIPS1-PSX-NEXT:    # <MCOperand Reg:ZERO>
-; MIPS1-PSX-NEXT:    # <MCOperand Reg:ZERO>
-; MIPS1-PSX-NEXT:    # <MCOperand Imm:0>>
 ; MIPS1-PSX-NEXT:    jr $ra # <MCInst #[[#MCINST2]] JR
 ; MIPS1-PSX-NEXT:    # <MCOperand Reg:RA>>
 ; MIPS1-PSX-NEXT:    nop # <MCInst #[[#MCINST13]] SLL
@@ -741,10 +729,6 @@ define i32 @f4() {
 ; MIPS1-PSX-NEXT:    # <MCOperand Reg:V0>
 ; MIPS1-PSX-NEXT:    # <MCOperand Reg:AT>
 ; MIPS1-PSX-NEXT:    # <MCOperand Expr:%lo(b)>>
-; MIPS1-PSX-NEXT:    nop # <MCInst #[[#MCINST13]] SLL
-; MIPS1-PSX-NEXT:    # <MCOperand Reg:ZERO>
-; MIPS1-PSX-NEXT:    # <MCOperand Reg:ZERO>
-; MIPS1-PSX-NEXT:    # <MCOperand Imm:0>>
 ; MIPS1-PSX-NEXT:    jr $ra # <MCInst #[[#MCINST2]] JR
 ; MIPS1-PSX-NEXT:    # <MCOperand Reg:RA>>
 ; MIPS1-PSX-NEXT:    nop # <MCInst #[[#MCINST13]] SLL
@@ -925,10 +909,6 @@ define i32 @f5() {
 ; MIPS1-PSX-NEXT:    # <MCOperand Reg:V0>
 ; MIPS1-PSX-NEXT:    # <MCOperand Reg:AT>
 ; MIPS1-PSX-NEXT:    # <MCOperand Expr:%lo(c)>>
-; MIPS1-PSX-NEXT:    nop # <MCInst #[[#MCINST13]] SLL
-; MIPS1-PSX-NEXT:    # <MCOperand Reg:ZERO>
-; MIPS1-PSX-NEXT:    # <MCOperand Reg:ZERO>
-; MIPS1-PSX-NEXT:    # <MCOperand Imm:0>>
 ; MIPS1-PSX-NEXT:    jr $ra # <MCInst #[[#MCINST2]] JR
 ; MIPS1-PSX-NEXT:    # <MCOperand Reg:RA>>
 ; MIPS1-PSX-NEXT:    nop # <MCInst #[[#MCINST13]] SLL
@@ -1129,10 +1109,6 @@ define i64 @f6() {
 ; MIPS1-PSX-NEXT:    # <MCOperand Reg:V0>
 ; MIPS1-PSX-NEXT:    # <MCOperand Reg:AT>
 ; MIPS1-PSX-NEXT:    # <MCOperand Expr:%lo(c)>>
-; MIPS1-PSX-NEXT:    nop # <MCInst #[[#MCINST13]] SLL
-; MIPS1-PSX-NEXT:    # <MCOperand Reg:ZERO>
-; MIPS1-PSX-NEXT:    # <MCOperand Reg:ZERO>
-; MIPS1-PSX-NEXT:    # <MCOperand Imm:0>>
 ; MIPS1-PSX-NEXT:    jr $ra # <MCInst #[[#MCINST2]] JR
 ; MIPS1-PSX-NEXT:    # <MCOperand Reg:RA>>
 ; MIPS1-PSX-NEXT:    addiu $3, $zero, 0 # <MCInst #[[#MCINST22:]] ADDiu
@@ -1337,10 +1313,6 @@ define i64 @f7() {
 ; MIPS1-PSX-NEXT:    # <MCOperand Reg:V0>
 ; MIPS1-PSX-NEXT:    # <MCOperand Reg:AT>
 ; MIPS1-PSX-NEXT:    # <MCOperand Expr:%lo(c)>>
-; MIPS1-PSX-NEXT:    nop # <MCInst #[[#MCINST13]] SLL
-; MIPS1-PSX-NEXT:    # <MCOperand Reg:ZERO>
-; MIPS1-PSX-NEXT:    # <MCOperand Reg:ZERO>
-; MIPS1-PSX-NEXT:    # <MCOperand Imm:0>>
 ; MIPS1-PSX-NEXT:    jr $ra # <MCInst #[[#MCINST2]] JR
 ; MIPS1-PSX-NEXT:    # <MCOperand Reg:RA>>
 ; MIPS1-PSX-NEXT:    sra $3, $2, 31 # <MCInst #[[#MCINST25:]] SRA

>From 34f91a79b327c51f46fba4bfce8e3b806a430ba6 Mon Sep 17 00:00:00 2001
From: Jaby <jaby at william.zone>
Date: Fri, 3 Apr 2026 21:31:54 +0100
Subject: [PATCH 18/18] Remove debug messages

---
 llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp | 26 --------------------
 1 file changed, 26 deletions(-)

diff --git a/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp b/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp
index 92a6f048d6559..6b35b3c1017de 100644
--- a/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp
+++ b/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp
@@ -88,12 +88,6 @@ namespace {
   using ReverseIter = MachineBasicBlock::reverse_iterator;
   using BB2BrMap = SmallDenseMap<MachineBasicBlock *, MachineInstr *, 2>;
 
-#if 0
-#define tmp_out outs()
-#else
-#define tmp_out nulls()
-#endif
-
   // Holds information about one branch instruction
   // This is used by the MIPS1 target to easily find all paths of a branch to
   // then check the first instruction for possible load delay hazards
@@ -168,7 +162,6 @@ namespace {
 
       for (const MachineOperand &MO : this->BranchInstr->operands()) {
         if (MO.isMBB()) {
-          tmp_out << "\t>>>" << MO << "<<<\n";
           return MO.getMBB();
         }
       }
@@ -1126,18 +1119,12 @@ bool MipsDelaySlotFiller::delayHasHazard(const MipsSubtarget &STI,
       // We have no branch so we can not determine a hazard
       // Assume the worst
       if (!BranchInfo.hasBranchInstr()) {
-        tmp_out << "No branch?\n";
         return true;
       }
 
-      tmp_out << (BranchInfo.isIndirectBranch() ? "Indirect-" : "")
-              << "Branch is: " << *BranchInfo.getBranchInstr()
-              << "Candidate is: " << Candidate;
-
       // Being an indirect branch means we can not tell if we are a hazard
       // Assume the worst
       if (BranchInfo.isIndirectBranch()) {
-        tmp_out << "\tNew Hazard?: Yes\n---\n";
         return true;
       }
 
@@ -1145,20 +1132,10 @@ bool MipsDelaySlotFiller::delayHasHazard(const MipsSubtarget &STI,
       // target
       const MachineBasicBlock *TargetMBB = BranchInfo.getBranchTarget();
       if (!TargetMBB || TargetMBB->empty()) {
-        tmp_out << "No or empty Target MBB found\n";
         return true;
       }
 
       const auto &BranchTargetInstr = TargetMBB->instr_front();
-      tmp_out << "\tDST->: " << BranchTargetInstr;
-      tmp_out << "\tDST-v: ";
-      if (BranchInfo.hasBranchElseInstr()) {
-        tmp_out << *BranchInfo.getBranchElseInstr();
-      } else {
-        tmp_out << "<NONE>";
-      }
-      tmp_out << "\n";
-
       bool HasNewHazard =
           !TII->SafeInLoadDelaySlot(BranchTargetInstr, Candidate);
       // If the branch is unconditional then we do not need to bother to check
@@ -1175,9 +1152,6 @@ bool MipsDelaySlotFiller::delayHasHazard(const MipsSubtarget &STI,
           HasNewHazard = true;
         }
       }
-
-      tmp_out << "\tNew Hazard detected?: " << (HasNewHazard ? "Yes" : "No") << " Old Hazard detected: " << (HasHazard ? "Yes" : "No")
-              << "\n---\n";
       return HasNewHazard;
     }
   }



More information about the llvm-commits mailing list