[llvm-branch-commits] [llvm] release/22.x: Prevent undefined behavior caused by combination of branch and load delay slots on MIPS1 (#185427) (PR #194224)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Sun Apr 26 02:59:07 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-mips
Author: llvmbot
<details>
<summary>Changes</summary>
Backport 458e9c452c103189865632657504174b24b91630
Requested by: @<!-- -->RKSimon
---
Patch is 84.71 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/194224.diff
7 Files Affected:
- (modified) llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp (+179-32)
- (modified) llvm/lib/Target/Mips/MipsInstrInfo.cpp (+2-1)
- (modified) llvm/test/CodeGen/Mips/gprestore.ll (+50)
- (modified) llvm/test/CodeGen/Mips/llvm-ir/load.ll (+221-84)
- (modified) llvm/test/CodeGen/Mips/llvm-ir/select-dbl.ll (+225-35)
- (added) llvm/test/CodeGen/Mips/mips1-load-in-delay-slot.ll (+61)
- (modified) llvm/test/CodeGen/Mips/unalignedload.ll (+62-6)
``````````diff
diff --git a/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp b/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp
index 850d3b59be5de..7e52cf985f795 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>
@@ -85,6 +86,87 @@ namespace {
using ReverseIter = MachineBasicBlock::reverse_iterator;
using BB2BrMap = SmallDenseMap<MachineBasicBlock *, MachineInstr *, 2>;
+ // 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<MachineInstr> CurrentSlot,
+ MachineInstrBundleIterator<MachineInstr> 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);
@@ -195,8 +277,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
@@ -219,7 +307,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);
@@ -227,28 +316,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<typename IterTy>
+ template <typename IterTy>
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.
@@ -577,7 +670,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<MipsSubtarget>();
bool InMicroMipsMode = STI.inMicroMipsMode();
@@ -593,20 +687,22 @@ bool MipsDelaySlotFiller::runOnMachineBasicBlock(MachineBasicBlock &MBB) {
!(InMicroMipsMode && STI.hasMips32r6())) {
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;
@@ -660,15 +756,15 @@ bool MipsDelaySlotFiller::runOnMachineBasicBlock(MachineBasicBlock &MBB) {
++FilledSlots;
Changed = true;
}
-
return Changed;
}
template <typename IterTy>
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;
@@ -704,10 +800,10 @@ bool MipsDelaySlotFiller::searchRange(MachineBasicBlock &MBB, IterTy Begin,
continue;
}
- if (delayHasHazard(*CurrI, RegDU, IM))
+ const MipsSubtarget &STI = MBB.getParent()->getSubtarget<MipsSubtarget>();
+ if (delayHasHazard(STI, *CurrI, BranchInfo, RegDU, IM))
continue;
- const MipsSubtarget &STI = MBB.getParent()->getSubtarget<MipsSubtarget>();
bool InMicroMipsMode = STI.inMicroMipsMode();
const MipsInstrInfo *TII = STI.getInstrInfo();
unsigned Opcode = (*Slot).getOpcode();
@@ -743,8 +839,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;
@@ -756,8 +853,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;
@@ -769,8 +866,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;
@@ -781,7 +879,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;
@@ -793,8 +892,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;
@@ -828,8 +928,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);
@@ -915,7 +1015,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() &&
@@ -926,6 +1028,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 c879c46e49dd4..6683408983acb 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 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..834880f1ad74e 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: # <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-NE...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/194224
More information about the llvm-branch-commits
mailing list