diff --git a/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp b/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp index f04ce53340c5..bcfaa7cd2ed2 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 #include @@ -87,6 +88,87 @@ namespace { using ReverseIter = MachineBasicBlock::reverse_iterator; using BB2BrMap = SmallDenseMap; + // 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: + // 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; + + // 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 + // instruction of the next MBB `NextMBBInstr` + BranchInformation(MachineInstrBundleIterator CurrentSlot, + MachineInstrBundleIterator MBBEnd, + const MachineInstr *NextMBBInstr) + : 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; } + + // 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->BranchInstr) { + return this->BranchInstr->isIndirectBranch(); + } + return false; + } + + // Checks if we have an unconditional branch + constexpr bool isUnconditionalBranch() const { + if (this->BranchInstr) { + return this->BranchInstr->isUnconditionalBranch(); + } + return false; + } + + // Accesses the branch instruction + const MachineInstr *getBranchInstr() const { return this->BranchInstr; } + + // Accesses the instruction after the branch + const MachineInstr *getBranchElseInstr() const { + 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->BranchInstr->operands()) { + if (MO.isMBB()) { + return MO.getMBB(); + } + } + return nullptr; + } + }; + class RegDefsUses { public: RegDefsUses(const TargetRegisterInfo &TRI); @@ -197,8 +279,14 @@ 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).empty()) ? &(*MBB).instr_front() + : nullptr); + } // This pass invalidates liveness information when it reorders // instructions to fill delay slot. Without this, -verify-machineinstrs @@ -221,7 +309,8 @@ namespace { static char ID; private: - bool runOnMachineBasicBlock(MachineBasicBlock &MBB); + bool runOnMachineBasicBlock(MachineBasicBlock &MBB, + MachineInstr *FirstNextMBBInstr); Iter replaceWithCompactBranch(MachineBasicBlock &MBB, Iter Branch, const DebugLoc &DL); @@ -229,28 +318,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 MachineInstr &Candidate, RegDefsUses &RegDU, + 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 + template bool searchRange(MachineBasicBlock &MBB, IterTy Begin, IterTy End, - RegDefsUses &RegDU, InspectMemInstr &IM, Iter Slot, - IterTy &Filler) const; + 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 &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, 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, 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. @@ -650,7 +743,8 @@ 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(); bool InMicroMipsMode = STI.inMicroMipsMode(); @@ -678,20 +772,22 @@ bool MipsDelaySlotFiller::runOnMachineBasicBlock(MachineBasicBlock &MBB) { !(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, *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, 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, I)) { + } else if (searchForward(MBB, I, BranchInfo)) { LLVM_DEBUG(dbgs() << DEBUG_TYPE ": found instruction for delay slot" " in forwards search.\n"); Filled = true; @@ -745,15 +841,15 @@ bool MipsDelaySlotFiller::runOnMachineBasicBlock(MachineBasicBlock &MBB) { ++FilledSlots; Changed = true; } - return Changed; } template bool MipsDelaySlotFiller::searchRange(MachineBasicBlock &MBB, IterTy Begin, - IterTy End, RegDefsUses &RegDU, - InspectMemInstr &IM, Iter Slot, - IterTy &Filler) const { + IterTy End, + const BranchInformation &BranchInfo, + RegDefsUses &RegDU, InspectMemInstr &IM, + Iter Slot, IterTy &Filler) const { for (IterTy I = Begin; I != End;) { IterTy CurrI = I; ++I; @@ -789,10 +885,10 @@ bool MipsDelaySlotFiller::searchRange(MachineBasicBlock &MBB, IterTy Begin, continue; } - if (delayHasHazard(*CurrI, RegDU, IM)) + const MipsSubtarget &STI = MBB.getParent()->getSubtarget(); + if (delayHasHazard(STI, *CurrI, BranchInfo, RegDU, IM)) continue; - const MipsSubtarget &STI = MBB.getParent()->getSubtarget(); bool InMicroMipsMode = STI.inMicroMipsMode(); const MipsInstrInfo *TII = STI.getInstrInfo(); unsigned Opcode = (*Slot).getOpcode(); @@ -828,8 +924,9 @@ bool MipsDelaySlotFiller::searchRange(MachineBasicBlock &MBB, IterTy Begin, return false; } -bool MipsDelaySlotFiller::searchBackward(MachineBasicBlock &MBB, - MachineInstr &Slot) const { +bool MipsDelaySlotFiller::searchBackward( + MachineBasicBlock &MBB, MachineInstr &Slot, + const BranchInformation &BranchInfo) const { if (DisableBackwardSearch) return false; @@ -841,8 +938,8 @@ bool MipsDelaySlotFiller::searchBackward(MachineBasicBlock &MBB, RegDU.init(Slot); MachineBasicBlock::iterator SlotI = Slot; - if (!searchRange(MBB, ++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; @@ -854,8 +951,9 @@ bool MipsDelaySlotFiller::searchBackward(MachineBasicBlock &MBB, return true; } -bool MipsDelaySlotFiller::searchForward(MachineBasicBlock &MBB, - Iter Slot) const { +bool MipsDelaySlotFiller::searchForward( + MachineBasicBlock &MBB, Iter Slot, + const BranchInformation &BranchInfo) const { // Can handle only calls. if (DisableForwardSearch || !Slot->isCall()) return false; @@ -866,7 +964,8 @@ bool MipsDelaySlotFiller::searchForward(MachineBasicBlock &MBB, RegDU.setCallerSaved(*Slot); - if (!searchRange(MBB, 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; @@ -878,8 +977,9 @@ bool MipsDelaySlotFiller::searchForward(MachineBasicBlock &MBB, return true; } -bool MipsDelaySlotFiller::searchSuccBBs(MachineBasicBlock &MBB, - Iter Slot) const { +bool MipsDelaySlotFiller::searchSuccBBs( + MachineBasicBlock &MBB, Iter Slot, + const BranchInformation &BranchInfo) const { if (DisableSuccBBSearch) return false; @@ -913,8 +1013,8 @@ bool MipsDelaySlotFiller::searchSuccBBs(MachineBasicBlock &MBB, IM.reset(new MemDefsUses(&MFI)); } - if (!searchRange(MBB, 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); @@ -1000,7 +1100,9 @@ bool MipsDelaySlotFiller::examinePred(MachineBasicBlock &Pred, return true; } -bool MipsDelaySlotFiller::delayHasHazard(const MachineInstr &Candidate, +bool MipsDelaySlotFiller::delayHasHazard(const MipsSubtarget &STI, + const MachineInstr &Candidate, + const BranchInformation &BranchInfo, RegDefsUses &RegDU, InspectMemInstr &IM) const { assert(!Candidate.isKill() && @@ -1011,6 +1113,51 @@ bool MipsDelaySlotFiller::delayHasHazard(const MachineInstr &Candidate, HasHazard |= IM.hasHazard(Candidate); HasHazard |= RegDU.update(Candidate, 0, Candidate.getNumOperands()); + // This only matters for MIPS1 and only if we do not have a hazard already + if (STI.hasMips1() && !STI.hasMips2() && !HasHazard) { + 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 so we can not determine a hazard + // Assume the worst + if (!BranchInfo.hasBranchInstr()) { + return true; + } + + // Being an indirect branch means we can not tell if we are a hazard + // Assume the worst + if (BranchInfo.isIndirectBranch()) { + return true; + } + + // 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()) { + return true; + } + + const auto &BranchTargetInstr = TargetMBB->instr_front(); + 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 (!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; + } + } + return HasNewHazard; + } + } + return HasHazard; } diff --git a/llvm/lib/Target/Mips/MipsInstrInfo.cpp b/llvm/lib/Target/Mips/MipsInstrInfo.cpp index c08c963a33c7..d1a47750d23d 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()); }); } diff --git a/llvm/test/CodeGen/Mips/gprestore.ll b/llvm/test/CodeGen/Mips/gprestore.ll index 889685022264..674a197ca438 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 f81e1a742e44..834880f1ad74 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,22 @@ define i8 @f1() { ; MIPS32R5FP643-NEXT: # ; MIPS32R5FP643-NEXT: # ; MIPS32R5FP643-NEXT: # > +; +; MIPS1-PSX-LABEL: f1: +; MIPS1-PSX: # %bb.0: # %entry +; MIPS1-PSX-NEXT: lui $1, %hi(a) # +; MIPS1-PSX-NEXT: # > +; MIPS1-PSX-NEXT: lbu $2, %lo(a)($1) # +; MIPS1-PSX-NEXT: # +; MIPS1-PSX-NEXT: # > +; MIPS1-PSX-NEXT: jr $ra # > +; MIPS1-PSX-NEXT: nop # +; MIPS1-PSX-NEXT: # +; MIPS1-PSX-NEXT: # > entry: %0 = load i8, ptr @a ret i8 %0 @@ -193,7 +210,7 @@ define i32 @f2() { ; MIPS32-NEXT: # > ; MIPS32-NEXT: jr $ra # > -; MIPS32-NEXT: lb $2, %lo(a)($1) # ; MIPS32-NEXT: # ; MIPS32-NEXT: # > @@ -205,7 +222,7 @@ define i32 @f2() { ; MMR3-NEXT: # > ; MMR3-NEXT: jr $ra # > -; MMR3-NEXT: lb $2, %lo(a)($1) # ; MMR3-NEXT: # ; MMR3-NEXT: # > @@ -218,7 +235,7 @@ define i32 @f2() { ; MIPS32R6-NEXT: jr $ra # ; MIPS32R6-NEXT: # > -; MIPS32R6-NEXT: lb $2, %lo(a)($1) # ; MIPS32R6-NEXT: # ; MIPS32R6-NEXT: # > @@ -228,7 +245,7 @@ define i32 @f2() { ; MMR6-NEXT: lui $1, %hi(a) # ; MMR6-NEXT: # > -; MMR6-NEXT: lb $2, %lo(a)($1) # ; MMR6-NEXT: # ; MMR6-NEXT: # > @@ -258,7 +275,7 @@ define i32 @f2() { ; MIPS3-NEXT: # > ; MIPS3-NEXT: jr $ra # > -; MIPS3-NEXT: lb $2, %lo(a)($1) # ; MIPS3-NEXT: # ; MIPS3-NEXT: # > @@ -286,7 +303,7 @@ define i32 @f2() { ; MIPS64-NEXT: # > ; MIPS64-NEXT: jr $ra # > -; MIPS64-NEXT: lb $2, %lo(a)($1) # ; MIPS64-NEXT: # ; MIPS64-NEXT: # > @@ -315,7 +332,7 @@ define i32 @f2() { ; MIPS64R6-NEXT: jr $ra # ; MIPS64R6-NEXT: # > -; MIPS64R6-NEXT: lb $2, %lo(a)($1) # ; MIPS64R6-NEXT: # ; MIPS64R6-NEXT: # > @@ -327,7 +344,7 @@ define i32 @f2() { ; MMR5FP64-NEXT: # > ; MMR5FP64-NEXT: jr $ra # > -; MMR5FP64-NEXT: lb $2, %lo(a)($1) # ; MMR5FP64-NEXT: # ; MMR5FP64-NEXT: # > @@ -339,10 +356,26 @@ define i32 @f2() { ; MIPS32R5FP643-NEXT: # > ; MIPS32R5FP643-NEXT: jr $ra # > -; MIPS32R5FP643-NEXT: lb $2, %lo(a)($1) # ; MIPS32R5FP643-NEXT: # ; MIPS32R5FP643-NEXT: # > +; +; MIPS1-PSX-LABEL: f2: +; MIPS1-PSX: # %bb.0: # %entry +; MIPS1-PSX-NEXT: lui $1, %hi(a) # +; MIPS1-PSX-NEXT: # > +; MIPS1-PSX-NEXT: lb $2, %lo(a)($1) # +; MIPS1-PSX-NEXT: # +; MIPS1-PSX-NEXT: # > +; MIPS1-PSX-NEXT: jr $ra # > +; MIPS1-PSX-NEXT: nop # +; MIPS1-PSX-NEXT: # +; MIPS1-PSX-NEXT: # > entry: %0 = load i8, ptr @a %1 = sext i8 %0 to i32 @@ -357,7 +390,7 @@ define i16 @f3() { ; MIPS32-NEXT: # > ; MIPS32-NEXT: jr $ra # > -; MIPS32-NEXT: lhu $2, %lo(b)($1) # ; MIPS32-NEXT: # ; MIPS32-NEXT: # > @@ -369,7 +402,7 @@ define i16 @f3() { ; MMR3-NEXT: # > ; MMR3-NEXT: jr $ra # > -; MMR3-NEXT: lhu $2, %lo(b)($1) # ; MMR3-NEXT: # ; MMR3-NEXT: # > @@ -382,7 +415,7 @@ define i16 @f3() { ; MIPS32R6-NEXT: jr $ra # ; MIPS32R6-NEXT: # > -; MIPS32R6-NEXT: lhu $2, %lo(b)($1) # ; MIPS32R6-NEXT: # ; MIPS32R6-NEXT: # > @@ -392,7 +425,7 @@ define i16 @f3() { ; MMR6-NEXT: lui $1, %hi(b) # ; MMR6-NEXT: # > -; MMR6-NEXT: lhu $2, %lo(b)($1) # ; MMR6-NEXT: # ; MMR6-NEXT: # > @@ -422,7 +455,7 @@ define i16 @f3() { ; MIPS3-NEXT: # > ; MIPS3-NEXT: jr $ra # > -; MIPS3-NEXT: lhu $2, %lo(b)($1) # ; MIPS3-NEXT: # ; MIPS3-NEXT: # > @@ -450,7 +483,7 @@ define i16 @f3() { ; MIPS64-NEXT: # > ; MIPS64-NEXT: jr $ra # > -; MIPS64-NEXT: lhu $2, %lo(b)($1) # ; MIPS64-NEXT: # ; MIPS64-NEXT: # > @@ -479,7 +512,7 @@ define i16 @f3() { ; MIPS64R6-NEXT: jr $ra # ; MIPS64R6-NEXT: # > -; MIPS64R6-NEXT: lhu $2, %lo(b)($1) # ; MIPS64R6-NEXT: # ; MIPS64R6-NEXT: # > @@ -491,7 +524,7 @@ define i16 @f3() { ; MMR5FP64-NEXT: # > ; MMR5FP64-NEXT: jr $ra # > -; MMR5FP64-NEXT: lhu $2, %lo(b)($1) # ; MMR5FP64-NEXT: # ; MMR5FP64-NEXT: # > @@ -503,10 +536,26 @@ define i16 @f3() { ; MIPS32R5FP643-NEXT: # > ; MIPS32R5FP643-NEXT: jr $ra # > -; MIPS32R5FP643-NEXT: lhu $2, %lo(b)($1) # ; MIPS32R5FP643-NEXT: # ; MIPS32R5FP643-NEXT: # > +; +; MIPS1-PSX-LABEL: f3: +; MIPS1-PSX: # %bb.0: # %entry +; MIPS1-PSX-NEXT: lui $1, %hi(b) # +; MIPS1-PSX-NEXT: # > +; MIPS1-PSX-NEXT: lhu $2, %lo(b)($1) # +; MIPS1-PSX-NEXT: # +; MIPS1-PSX-NEXT: # > +; MIPS1-PSX-NEXT: jr $ra # > +; MIPS1-PSX-NEXT: nop # +; MIPS1-PSX-NEXT: # +; MIPS1-PSX-NEXT: # > entry: %0 = load i16, ptr @b ret i16 %0 @@ -520,7 +569,7 @@ define i32 @f4() { ; MIPS32-NEXT: # > ; MIPS32-NEXT: jr $ra # > -; MIPS32-NEXT: lh $2, %lo(b)($1) # ; MIPS32-NEXT: # ; MIPS32-NEXT: # > @@ -532,7 +581,7 @@ define i32 @f4() { ; MMR3-NEXT: # > ; MMR3-NEXT: jr $ra # > -; MMR3-NEXT: lh $2, %lo(b)($1) # ; MMR3-NEXT: # ; MMR3-NEXT: # > @@ -545,7 +594,7 @@ define i32 @f4() { ; MIPS32R6-NEXT: jr $ra # ; MIPS32R6-NEXT: # > -; MIPS32R6-NEXT: lh $2, %lo(b)($1) # ; MIPS32R6-NEXT: # ; MIPS32R6-NEXT: # > @@ -555,7 +604,7 @@ define i32 @f4() { ; MMR6-NEXT: lui $1, %hi(b) # ; MMR6-NEXT: # > -; MMR6-NEXT: lh $2, %lo(b)($1) # ; MMR6-NEXT: # ; MMR6-NEXT: # > @@ -585,7 +634,7 @@ define i32 @f4() { ; MIPS3-NEXT: # > ; MIPS3-NEXT: jr $ra # > -; MIPS3-NEXT: lh $2, %lo(b)($1) # ; MIPS3-NEXT: # ; MIPS3-NEXT: # > @@ -613,7 +662,7 @@ define i32 @f4() { ; MIPS64-NEXT: # > ; MIPS64-NEXT: jr $ra # > -; MIPS64-NEXT: lh $2, %lo(b)($1) # ; MIPS64-NEXT: # ; MIPS64-NEXT: # > @@ -642,7 +691,7 @@ define i32 @f4() { ; MIPS64R6-NEXT: jr $ra # ; MIPS64R6-NEXT: # > -; MIPS64R6-NEXT: lh $2, %lo(b)($1) # ; MIPS64R6-NEXT: # ; MIPS64R6-NEXT: # > @@ -654,7 +703,7 @@ define i32 @f4() { ; MMR5FP64-NEXT: # > ; MMR5FP64-NEXT: jr $ra # > -; MMR5FP64-NEXT: lh $2, %lo(b)($1) # ; MMR5FP64-NEXT: # ; MMR5FP64-NEXT: # > @@ -666,10 +715,26 @@ define i32 @f4() { ; MIPS32R5FP643-NEXT: # > ; MIPS32R5FP643-NEXT: jr $ra # > -; MIPS32R5FP643-NEXT: lh $2, %lo(b)($1) # ; MIPS32R5FP643-NEXT: # ; MIPS32R5FP643-NEXT: # > +; +; MIPS1-PSX-LABEL: f4: +; MIPS1-PSX: # %bb.0: # %entry +; MIPS1-PSX-NEXT: lui $1, %hi(b) # +; MIPS1-PSX-NEXT: # > +; MIPS1-PSX-NEXT: lh $2, %lo(b)($1) # +; MIPS1-PSX-NEXT: # +; MIPS1-PSX-NEXT: # > +; MIPS1-PSX-NEXT: jr $ra # > +; MIPS1-PSX-NEXT: nop # +; MIPS1-PSX-NEXT: # +; MIPS1-PSX-NEXT: # > entry: %0 = load i16, ptr @b %1 = sext i16 %0 to i32 @@ -684,7 +749,7 @@ define i32 @f5() { ; MIPS32-NEXT: # > ; MIPS32-NEXT: jr $ra # > -; MIPS32-NEXT: lw $2, %lo(c)($1) # ; MIPS32-NEXT: # ; MIPS32-NEXT: # > @@ -696,7 +761,7 @@ define i32 @f5() { ; MMR3-NEXT: # > ; MMR3-NEXT: jr $ra # > -; MMR3-NEXT: lw $2, %lo(c)($1) # ; MMR3-NEXT: # ; MMR3-NEXT: # > @@ -709,7 +774,7 @@ define i32 @f5() { ; MIPS32R6-NEXT: jr $ra # ; MIPS32R6-NEXT: # > -; MIPS32R6-NEXT: lw $2, %lo(c)($1) # ; MIPS32R6-NEXT: # ; MIPS32R6-NEXT: # > @@ -719,7 +784,7 @@ define i32 @f5() { ; MMR6-NEXT: lui $1, %hi(c) # ; MMR6-NEXT: # > -; MMR6-NEXT: lw $2, %lo(c)($1) # ; MMR6-NEXT: # ; MMR6-NEXT: # > @@ -749,7 +814,7 @@ define i32 @f5() { ; MIPS3-NEXT: # > ; MIPS3-NEXT: jr $ra # > -; MIPS3-NEXT: lw $2, %lo(c)($1) # ; MIPS3-NEXT: # ; MIPS3-NEXT: # > @@ -777,7 +842,7 @@ define i32 @f5() { ; MIPS64-NEXT: # > ; MIPS64-NEXT: jr $ra # > -; MIPS64-NEXT: lw $2, %lo(c)($1) # ; MIPS64-NEXT: # ; MIPS64-NEXT: # > @@ -806,7 +871,7 @@ define i32 @f5() { ; MIPS64R6-NEXT: jr $ra # ; MIPS64R6-NEXT: # > -; MIPS64R6-NEXT: lw $2, %lo(c)($1) # ; MIPS64R6-NEXT: # ; MIPS64R6-NEXT: # > @@ -818,7 +883,7 @@ define i32 @f5() { ; MMR5FP64-NEXT: # > ; MMR5FP64-NEXT: jr $ra # > -; MMR5FP64-NEXT: lw $2, %lo(c)($1) # ; MMR5FP64-NEXT: # ; MMR5FP64-NEXT: # > @@ -830,10 +895,26 @@ define i32 @f5() { ; MIPS32R5FP643-NEXT: # > ; MIPS32R5FP643-NEXT: jr $ra # > -; MIPS32R5FP643-NEXT: lw $2, %lo(c)($1) # ; MIPS32R5FP643-NEXT: # ; MIPS32R5FP643-NEXT: # > +; +; MIPS1-PSX-LABEL: f5: +; MIPS1-PSX: # %bb.0: # %entry +; MIPS1-PSX-NEXT: lui $1, %hi(c) # +; MIPS1-PSX-NEXT: # > +; MIPS1-PSX-NEXT: lw $2, %lo(c)($1) # +; MIPS1-PSX-NEXT: # +; MIPS1-PSX-NEXT: # > +; MIPS1-PSX-NEXT: jr $ra # > +; MIPS1-PSX-NEXT: nop # +; MIPS1-PSX-NEXT: # +; MIPS1-PSX-NEXT: # > entry: %0 = load i32, ptr @c ret i32 %0 @@ -845,13 +926,13 @@ define i64 @f6() { ; MIPS32-NEXT: lui $1, %hi(c) # ; MIPS32-NEXT: # > -; MIPS32-NEXT: lw $3, %lo(c)($1) # ; MIPS32-NEXT: # ; MIPS32-NEXT: # > ; MIPS32-NEXT: jr $ra # > -; MIPS32-NEXT: addiu $2, $zero, 0 # ; MIPS32-NEXT: # ; MIPS32-NEXT: # > @@ -861,12 +942,12 @@ define i64 @f6() { ; MMR3-NEXT: lui $1, %hi(c) # ; MMR3-NEXT: # > -; MMR3-NEXT: li16 $2, 0 # ; MMR3-NEXT: # > ; MMR3-NEXT: jr $ra # > -; MMR3-NEXT: lw $3, %lo(c)($1) # ; MMR3-NEXT: # ; MMR3-NEXT: # > @@ -876,14 +957,14 @@ define i64 @f6() { ; MIPS32R6-NEXT: lui $1, %hi(c) # ; MIPS32R6-NEXT: # > -; MIPS32R6-NEXT: lw $3, %lo(c)($1) # ; MIPS32R6-NEXT: # ; MIPS32R6-NEXT: # > ; MIPS32R6-NEXT: jr $ra # ; MIPS32R6-NEXT: # > -; MIPS32R6-NEXT: addiu $2, $zero, 0 # ; MIPS32R6-NEXT: # ; MIPS32R6-NEXT: # > @@ -893,11 +974,11 @@ define i64 @f6() { ; MMR6-NEXT: lui $1, %hi(c) # ; MMR6-NEXT: # > -; MMR6-NEXT: lw $3, %lo(c)($1) # ; MMR6-NEXT: # ; MMR6-NEXT: # > -; MMR6-NEXT: li16 $2, 0 # ; MMR6-NEXT: # > ; MMR6-NEXT: jrc $ra # > ; MIPS3-NEXT: jr $ra # > -; MIPS3-NEXT: lwu $2, %lo(c)($1) # ; MIPS3-NEXT: # ; MIPS3-NEXT: # > @@ -954,7 +1035,7 @@ define i64 @f6() { ; MIPS64-NEXT: # > ; MIPS64-NEXT: jr $ra # > -; MIPS64-NEXT: lwu $2, %lo(c)($1) # ; MIPS64-NEXT: # ; MIPS64-NEXT: # > @@ -983,7 +1064,7 @@ define i64 @f6() { ; MIPS64R6-NEXT: jr $ra # ; MIPS64R6-NEXT: # > -; MIPS64R6-NEXT: lwu $2, %lo(c)($1) # ; MIPS64R6-NEXT: # ; MIPS64R6-NEXT: # > @@ -993,12 +1074,12 @@ define i64 @f6() { ; MMR5FP64-NEXT: lui $1, %hi(c) # ; MMR5FP64-NEXT: # > -; MMR5FP64-NEXT: li16 $2, 0 # ; MMR5FP64-NEXT: # > ; MMR5FP64-NEXT: jr $ra # > -; MMR5FP64-NEXT: lw $3, %lo(c)($1) # ; MMR5FP64-NEXT: # ; MMR5FP64-NEXT: # > @@ -1008,16 +1089,32 @@ define i64 @f6() { ; MIPS32R5FP643-NEXT: lui $1, %hi(c) # ; MIPS32R5FP643-NEXT: # > -; MIPS32R5FP643-NEXT: lw $3, %lo(c)($1) # ; MIPS32R5FP643-NEXT: # ; MIPS32R5FP643-NEXT: # > ; MIPS32R5FP643-NEXT: jr $ra # > -; MIPS32R5FP643-NEXT: addiu $2, $zero, 0 # ; MIPS32R5FP643-NEXT: # ; MIPS32R5FP643-NEXT: # > +; +; MIPS1-PSX-LABEL: f6: +; MIPS1-PSX: # %bb.0: # %entry +; MIPS1-PSX-NEXT: lui $1, %hi(c) # +; MIPS1-PSX-NEXT: # > +; MIPS1-PSX-NEXT: lw $2, %lo(c)($1) # +; MIPS1-PSX-NEXT: # +; MIPS1-PSX-NEXT: # > +; MIPS1-PSX-NEXT: jr $ra # > +; MIPS1-PSX-NEXT: addiu $3, $zero, 0 # +; MIPS1-PSX-NEXT: # +; MIPS1-PSX-NEXT: # > entry: %0 = load i32, ptr @c %1 = zext i32 %0 to i64 @@ -1030,13 +1127,13 @@ define i64 @f7() { ; MIPS32-NEXT: lui $1, %hi(c) # ; MIPS32-NEXT: # > -; MIPS32-NEXT: lw $3, %lo(c)($1) # ; MIPS32-NEXT: # ; MIPS32-NEXT: # > ; MIPS32-NEXT: jr $ra # > -; MIPS32-NEXT: sra $2, $3, 31 # ; MIPS32-NEXT: # ; MIPS32-NEXT: # > @@ -1046,13 +1143,13 @@ define i64 @f7() { ; MMR3-NEXT: lui $1, %hi(c) # ; MMR3-NEXT: # > -; MMR3-NEXT: lw $3, %lo(c)($1) # ; MMR3-NEXT: # ; MMR3-NEXT: # > ; MMR3-NEXT: jr $ra # > -; MMR3-NEXT: sra $2, $3, 31 # ; MMR3-NEXT: # ; MMR3-NEXT: # > @@ -1062,14 +1159,14 @@ define i64 @f7() { ; MIPS32R6-NEXT: lui $1, %hi(c) # ; MIPS32R6-NEXT: # > -; MIPS32R6-NEXT: lw $3, %lo(c)($1) # ; MIPS32R6-NEXT: # ; MIPS32R6-NEXT: # > ; MIPS32R6-NEXT: jr $ra # ; MIPS32R6-NEXT: # > -; MIPS32R6-NEXT: sra $2, $3, 31 # ; MIPS32R6-NEXT: # ; MIPS32R6-NEXT: # > @@ -1079,11 +1176,11 @@ define i64 @f7() { ; MMR6-NEXT: lui $1, %hi(c) # ; MMR6-NEXT: # > -; MMR6-NEXT: lw $3, %lo(c)($1) # ; MMR6-NEXT: # ; MMR6-NEXT: # > -; MMR6-NEXT: sra $2, $3, 31 # ; MMR6-NEXT: # ; MMR6-NEXT: # > @@ -1113,7 +1210,7 @@ define i64 @f7() { ; MIPS3-NEXT: # > ; MIPS3-NEXT: jr $ra # > -; MIPS3-NEXT: lw $2, %lo(c)($1) # ; MIPS3-NEXT: # ; MIPS3-NEXT: # > @@ -1141,7 +1238,7 @@ define i64 @f7() { ; MIPS64-NEXT: # > ; MIPS64-NEXT: jr $ra # > -; MIPS64-NEXT: lw $2, %lo(c)($1) # ; MIPS64-NEXT: # ; MIPS64-NEXT: # > @@ -1170,7 +1267,7 @@ define i64 @f7() { ; MIPS64R6-NEXT: jr $ra # ; MIPS64R6-NEXT: # > -; MIPS64R6-NEXT: lw $2, %lo(c)($1) # ; MIPS64R6-NEXT: # ; MIPS64R6-NEXT: # > @@ -1180,13 +1277,13 @@ define i64 @f7() { ; MMR5FP64-NEXT: lui $1, %hi(c) # ; MMR5FP64-NEXT: # > -; MMR5FP64-NEXT: lw $3, %lo(c)($1) # ; MMR5FP64-NEXT: # ; MMR5FP64-NEXT: # > ; MMR5FP64-NEXT: jr $ra # > -; MMR5FP64-NEXT: sra $2, $3, 31 # ; MMR5FP64-NEXT: # ; MMR5FP64-NEXT: # > @@ -1196,16 +1293,32 @@ define i64 @f7() { ; MIPS32R5FP643-NEXT: lui $1, %hi(c) # ; MIPS32R5FP643-NEXT: # > -; MIPS32R5FP643-NEXT: lw $3, %lo(c)($1) # ; MIPS32R5FP643-NEXT: # ; MIPS32R5FP643-NEXT: # > ; MIPS32R5FP643-NEXT: jr $ra # > -; MIPS32R5FP643-NEXT: sra $2, $3, 31 # ; MIPS32R5FP643-NEXT: # ; MIPS32R5FP643-NEXT: # > +; +; MIPS1-PSX-LABEL: f7: +; MIPS1-PSX: # %bb.0: # %entry +; MIPS1-PSX-NEXT: lui $1, %hi(c) # +; MIPS1-PSX-NEXT: # > +; MIPS1-PSX-NEXT: lw $2, %lo(c)($1) # +; MIPS1-PSX-NEXT: # +; MIPS1-PSX-NEXT: # > +; MIPS1-PSX-NEXT: jr $ra # > +; MIPS1-PSX-NEXT: sra $3, $2, 31 # +; MIPS1-PSX-NEXT: # +; MIPS1-PSX-NEXT: # > entry: %0 = load i32, ptr @c %1 = sext i32 %0 to i64 @@ -1220,7 +1333,7 @@ define float @f8() { ; MIPS32-NEXT: # > ; MIPS32-NEXT: jr $ra # > -; MIPS32-NEXT: lwc1 $f0, %lo(e)($1) # ; MIPS32-NEXT: # ; MIPS32-NEXT: # > @@ -1232,7 +1345,7 @@ define float @f8() { ; MMR3-NEXT: # > ; MMR3-NEXT: jr $ra # > -; MMR3-NEXT: lwc1 $f0, %lo(e)($1) # ; MMR3-NEXT: # ; MMR3-NEXT: # > @@ -1245,7 +1358,7 @@ define float @f8() { ; MIPS32R6-NEXT: jr $ra # ; MIPS32R6-NEXT: # > -; MIPS32R6-NEXT: lwc1 $f0, %lo(e)($1) # ; MIPS32R6-NEXT: # ; MIPS32R6-NEXT: # > @@ -1255,7 +1368,7 @@ define float @f8() { ; MMR6-NEXT: lui $1, %hi(e) # ; MMR6-NEXT: # > -; MMR6-NEXT: lwc1 $f0, %lo(e)($1) # ; MMR6-NEXT: # ; MMR6-NEXT: # > @@ -1285,7 +1398,7 @@ define float @f8() { ; MIPS3-NEXT: # > ; MIPS3-NEXT: jr $ra # > -; MIPS3-NEXT: lwc1 $f0, %lo(e)($1) # ; MIPS3-NEXT: # ; MIPS3-NEXT: # > @@ -1313,7 +1426,7 @@ define float @f8() { ; MIPS64-NEXT: # > ; MIPS64-NEXT: jr $ra # > -; MIPS64-NEXT: lwc1 $f0, %lo(e)($1) # ; MIPS64-NEXT: # ; MIPS64-NEXT: # > @@ -1342,7 +1455,7 @@ define float @f8() { ; MIPS64R6-NEXT: jr $ra # ; MIPS64R6-NEXT: # > -; MIPS64R6-NEXT: lwc1 $f0, %lo(e)($1) # ; MIPS64R6-NEXT: # ; MIPS64R6-NEXT: # > @@ -1354,7 +1467,7 @@ define float @f8() { ; MMR5FP64-NEXT: # > ; MMR5FP64-NEXT: jr $ra # > -; MMR5FP64-NEXT: lwc1 $f0, %lo(e)($1) # ; MMR5FP64-NEXT: # ; MMR5FP64-NEXT: # > @@ -1366,10 +1479,22 @@ define float @f8() { ; MIPS32R5FP643-NEXT: # > ; MIPS32R5FP643-NEXT: jr $ra # > -; MIPS32R5FP643-NEXT: lwc1 $f0, %lo(e)($1) # ; MIPS32R5FP643-NEXT: # ; MIPS32R5FP643-NEXT: # > +; +; MIPS1-PSX-LABEL: f8: +; MIPS1-PSX: # %bb.0: # %entry +; MIPS1-PSX-NEXT: lui $1, %hi(e) # +; MIPS1-PSX-NEXT: # > +; MIPS1-PSX-NEXT: jr $ra # > +; MIPS1-PSX-NEXT: lwc1 $f0, %lo(e)($1) # +; MIPS1-PSX-NEXT: # +; MIPS1-PSX-NEXT: # > entry: %0 = load float, ptr @e ret float %0 @@ -1383,7 +1508,7 @@ define double @f9() { ; MIPS32-NEXT: # > ; MIPS32-NEXT: jr $ra # > -; MIPS32-NEXT: ldc1 $f0, %lo(f)($1) # ; MIPS32-NEXT: # ; MIPS32-NEXT: # > @@ -1395,7 +1520,7 @@ define double @f9() { ; MMR3-NEXT: # > ; MMR3-NEXT: jr $ra # > -; MMR3-NEXT: ldc1 $f0, %lo(f)($1) # ; MMR3-NEXT: # ; MMR3-NEXT: # > @@ -1408,7 +1533,7 @@ define double @f9() { ; MIPS32R6-NEXT: jr $ra # ; MIPS32R6-NEXT: # > -; MIPS32R6-NEXT: ldc1 $f0, %lo(f)($1) # ; MIPS32R6-NEXT: # ; MIPS32R6-NEXT: # > @@ -1418,7 +1543,7 @@ define double @f9() { ; MMR6-NEXT: lui $1, %hi(f) # ; MMR6-NEXT: # > -; MMR6-NEXT: ldc1 $f0, %lo(f)($1) # ; MMR6-NEXT: # ; MMR6-NEXT: # > @@ -1448,7 +1573,7 @@ define double @f9() { ; MIPS3-NEXT: # > ; MIPS3-NEXT: jr $ra # > -; MIPS3-NEXT: ldc1 $f0, %lo(f)($1) # ; MIPS3-NEXT: # ; MIPS3-NEXT: # > @@ -1476,7 +1601,7 @@ define double @f9() { ; MIPS64-NEXT: # > ; MIPS64-NEXT: jr $ra # > -; MIPS64-NEXT: ldc1 $f0, %lo(f)($1) # ; MIPS64-NEXT: # ; MIPS64-NEXT: # > @@ -1505,7 +1630,7 @@ define double @f9() { ; MIPS64R6-NEXT: jr $ra # ; MIPS64R6-NEXT: # > -; MIPS64R6-NEXT: ldc1 $f0, %lo(f)($1) # ; MIPS64R6-NEXT: # ; MIPS64R6-NEXT: # > @@ -1517,7 +1642,7 @@ define double @f9() { ; MMR5FP64-NEXT: # > ; MMR5FP64-NEXT: jr $ra # > -; MMR5FP64-NEXT: ldc1 $f0, %lo(f)($1) # ; MMR5FP64-NEXT: # ; MMR5FP64-NEXT: # > @@ -1529,10 +1654,22 @@ define double @f9() { ; MIPS32R5FP643-NEXT: # > ; MIPS32R5FP643-NEXT: jr $ra # > -; MIPS32R5FP643-NEXT: ldc1 $f0, %lo(f)($1) # ; MIPS32R5FP643-NEXT: # ; MIPS32R5FP643-NEXT: # > +; +; MIPS1-PSX-LABEL: f9: +; MIPS1-PSX: # %bb.0: # %entry +; MIPS1-PSX-NEXT: lui $1, %hi(f) # +; MIPS1-PSX-NEXT: # > +; MIPS1-PSX-NEXT: jr $ra # > +; MIPS1-PSX-NEXT: ldc1 $f0, %lo(f)($1) # +; MIPS1-PSX-NEXT: # +; MIPS1-PSX-NEXT: # > 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 3c1dff3da6aa..f39be636e09d 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 # +; MM32R3-NEXT: # > +; MM32R3-NEXT: mthc1 $6, $f2 # +; MM32R3-NEXT: # +; MM32R3-NEXT: # > +; MM32R3-NEXT: andi16 $2, $4, 1 # +; MM32R3-NEXT: # +; MM32R3-NEXT: # > +; MM32R3-NEXT: ldc1 $f0, 16($sp) # +; MM32R3-NEXT: # +; MM32R3-NEXT: # > +; MM32R3-NEXT: jr $ra # > +; MM32R3-NEXT: movn.d $f0, $f2, $2 # +; MM32R3-NEXT: # +; MM32R3-NEXT: # +; MM32R3-NEXT: # > ; ; 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 # +; MM32R3-NEXT: # > +; MM32R3-NEXT: lw $2, 16($sp) # +; MM32R3-NEXT: # +; MM32R3-NEXT: # > +; MM32R3-NEXT: andi16 $2, $2, 1 # +; MM32R3-NEXT: # +; MM32R3-NEXT: # > +; MM32R3-NEXT: jr $ra # > +; MM32R3-NEXT: movn.d $f0, $f12, $2 # +; MM32R3-NEXT: # +; MM32R3-NEXT: # +; MM32R3-NEXT: # > ; ; MM32R6-LABEL: tst_select_i1_double_reordered: ; MM32R6: # %bb.0: # %entry @@ -193,6 +238,19 @@ 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: 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: mov.d $f0, $f12 +; 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 +317,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 # +; MM32R3-NEXT: # > +; MM32R3-NEXT: c.olt.d $f12, $f14 # +; MM32R3-NEXT: # +; MM32R3-NEXT: # > +; MM32R3-NEXT: jr $ra # > +; MM32R3-NEXT: movt.d $f0, $f12, $fcc0 # +; MM32R3-NEXT: # +; MM32R3-NEXT: # +; MM32R3-NEXT: # > ; ; 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 +415,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 # +; MM32R3-NEXT: # > +; MM32R3-NEXT: c.ole.d $f12, $f14 # +; MM32R3-NEXT: # +; MM32R3-NEXT: # > +; MM32R3-NEXT: jr $ra # > +; MM32R3-NEXT: movt.d $f0, $f12, $fcc0 # +; MM32R3-NEXT: # +; MM32R3-NEXT: # +; MM32R3-NEXT: # > ; ; 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 +513,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 # +; MM32R3-NEXT: # > +; MM32R3-NEXT: c.ule.d $f12, $f14 # +; MM32R3-NEXT: # +; MM32R3-NEXT: # > +; MM32R3-NEXT: jr $ra # > +; MM32R3-NEXT: movf.d $f0, $f12, $fcc0 # +; MM32R3-NEXT: # +; MM32R3-NEXT: # +; MM32R3-NEXT: # > ; ; 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 +611,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 # +; MM32R3-NEXT: # > +; MM32R3-NEXT: c.ult.d $f12, $f14 # +; MM32R3-NEXT: # +; MM32R3-NEXT: # > +; MM32R3-NEXT: jr $ra # > +; MM32R3-NEXT: movf.d $f0, $f12, $fcc0 # +; MM32R3-NEXT: # +; MM32R3-NEXT: # +; MM32R3-NEXT: # > ; ; 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 +709,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 # +; MM32R3-NEXT: # > +; MM32R3-NEXT: c.eq.d $f12, $f14 # +; MM32R3-NEXT: # +; MM32R3-NEXT: # > +; MM32R3-NEXT: jr $ra # > +; MM32R3-NEXT: movt.d $f0, $f12, $fcc0 # +; MM32R3-NEXT: # +; MM32R3-NEXT: # +; MM32R3-NEXT: # > ; ; 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 +807,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 # +; MM32R3-NEXT: # > +; MM32R3-NEXT: c.ueq.d $f12, $f14 # +; MM32R3-NEXT: # +; MM32R3-NEXT: # > +; MM32R3-NEXT: jr $ra # > +; MM32R3-NEXT: movf.d $f0, $f12, $fcc0 # +; MM32R3-NEXT: # +; MM32R3-NEXT: # +; MM32R3-NEXT: # > ; ; 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 000000000000..4499dc6123fd --- /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 + +@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 5c78519e6481..88fc405f3d19 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