[llvm] [AMDGPU][NFC] Explicitly narrow conversions in hazard and waitcnt passes (PR #215197)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 24 02:00:49 PDT 2026
https://github.com/gretay-amd updated https://github.com/llvm/llvm-project/pull/215197
>From 8fa91b837abdac7967ba3ee112ff940208019424 Mon Sep 17 00:00:00 2001
From: Greta Y <Greta.Yorsh at amd.com>
Date: Thu, 6 Aug 2026 16:14:55 +0100
Subject: [PATCH 1/2] [AMDGPU][NFC] Explicitly narrow conversions in hazard and
waitcnt passes
This patch handles the following cases:
MachineOperand::getImm() returns int64_t and is passed to the DepCtr and Waitcnt
encode/decode helpers, which take unsigned. Add a static_cast to make the
existing narrowing conversion explicit. These operands are s_waitcnt,
s_delay_alu and s_waitcnt_depctr immediates, all 16-bit encoded fields.
Container size() returns size_t and is assigned to unsigned locals holding
counter indices and event counts. Add a static_cast to make the existing
narrowing conversion explicit.
Register values are passed to interfaces taking MCPhysReg (uint16_t). Add a
static_cast. Every one of these is inside a pass that runs after register
allocation and reads the register from a physical-register operand or from a
register-class iteration, so the value is a physical register and the narrowing
is exact.
Three DenseMapInfo::getHashValue implementations return unsigned but compute a
hash_code, which converts to size_t. Add a static_cast; a truncated hash is
still a valid hash, and the surrounding DenseMapInfo contract only requires
isEqual to be exact.
Bit-field members of the waitcnt brackets are declared uint8_t and assigned from
wider counter values. Add a static_cast; the counters are hardware wait counters
with maxima below 64.
This fixes 51 instances of MSVC warning C4244 and 9 of C4267 ("possible loss of
data") across 6 files in llvm/lib/Target/AMDGPU.
Assisted-by: Claude <noreply at anthropic.com>
---
.../Target/AMDGPU/AMDGPUInsertDelayAlu.cpp | 17 +++--
.../Target/AMDGPU/AMDGPULowerVGPREncoding.cpp | 2 +-
.../Target/AMDGPU/AMDGPUWaitSGPRHazards.cpp | 20 ++---
.../lib/Target/AMDGPU/GCNHazardRecognizer.cpp | 30 +++++---
llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp | 75 ++++++++++---------
llvm/lib/Target/AMDGPU/SIModeRegister.cpp | 16 ++--
6 files changed, 89 insertions(+), 71 deletions(-)
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUInsertDelayAlu.cpp b/llvm/lib/Target/AMDGPU/AMDGPUInsertDelayAlu.cpp
index f0962a663989f..a4083f04768f5 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUInsertDelayAlu.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUInsertDelayAlu.cpp
@@ -41,7 +41,8 @@ class AMDGPUInsertDelayAlu {
MI.getOpcode() == AMDGPU::S_SENDMSG_RTN_B64)
return true;
if (MI.getOpcode() == AMDGPU::S_WAITCNT_DEPCTR &&
- AMDGPU::DepCtr::decodeFieldVaVdst(MI.getOperand(0).getImm()) == 0)
+ AMDGPU::DepCtr::decodeFieldVaVdst(
+ static_cast<unsigned>(MI.getOperand(0).getImm())) == 0)
return true;
return false;
}
@@ -124,18 +125,18 @@ class AMDGPUInsertDelayAlu {
default:
llvm_unreachable("unexpected type");
case VALU:
- VALUCycles = Cycles;
+ VALUCycles = static_cast<uint8_t>(Cycles);
VALUNum = 0;
break;
case TRANS:
- TRANSCycles = Cycles;
+ TRANSCycles = static_cast<uint8_t>(Cycles);
TRANSNum = 0;
TRANSNumVALU = 0;
break;
case SALU:
// Guard against pseudo-instructions like SI_CALL which are marked as
// SALU but with a very high latency.
- SALUCycles = std::min(Cycles, SALU_CYCLES_MAX);
+ SALUCycles = static_cast<uint8_t>(std::min(Cycles, SALU_CYCLES_MAX));
break;
}
}
@@ -172,7 +173,7 @@ class AMDGPUInsertDelayAlu {
VALUNum = VALU_MAX;
VALUCycles = 0;
} else {
- VALUCycles -= Cycles;
+ VALUCycles -= static_cast<uint8_t>(Cycles);
Erase = false;
}
@@ -185,7 +186,7 @@ class AMDGPUInsertDelayAlu {
TRANSNumVALU = VALU_MAX;
TRANSCycles = 0;
} else {
- TRANSCycles -= Cycles;
+ TRANSCycles -= static_cast<uint8_t>(Cycles);
Erase = false;
}
@@ -194,7 +195,7 @@ class AMDGPUInsertDelayAlu {
// now.
SALUCycles = 0;
} else {
- SALUCycles -= Cycles;
+ SALUCycles -= static_cast<uint8_t>(Cycles);
Erase = false;
}
@@ -327,7 +328,7 @@ class AMDGPUInsertDelayAlu {
}
if (Skip < 6) {
MachineOperand &Op = LastDelayAlu->getOperand(0);
- unsigned LastImm = Op.getImm();
+ unsigned LastImm = static_cast<unsigned>(Op.getImm());
assert((LastImm & ~0xf) == 0 &&
"Remembered an s_delay_alu with no room for another delay!");
LastImm |= Imm << 7 | Skip << 4;
diff --git a/llvm/lib/Target/AMDGPU/AMDGPULowerVGPREncoding.cpp b/llvm/lib/Target/AMDGPU/AMDGPULowerVGPREncoding.cpp
index 75c3dd3b1de09..2f1ef975b71b8 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPULowerVGPREncoding.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPULowerVGPREncoding.cpp
@@ -614,7 +614,7 @@ bool AMDGPULowerVGPREncoding::run(MachineFunction &MF) {
if (MI.getOpcode() == AMDGPU::S_CLAUSE) {
assert(!ClauseRemaining && "Nested clauses are not supported");
- ClauseLen = MI.getOperand(0).getImm();
+ ClauseLen = static_cast<unsigned>(MI.getOperand(0).getImm());
ClauseBreaks = (ClauseLen >> 8) & 15;
ClauseLen = ClauseRemaining = (ClauseLen & 63) + 1;
Clause = &MI;
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUWaitSGPRHazards.cpp b/llvm/lib/Target/AMDGPU/AMDGPUWaitSGPRHazards.cpp
index d4bdaa245ff16..d615884f0a393 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUWaitSGPRHazards.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUWaitSGPRHazards.cpp
@@ -200,7 +200,8 @@ class AMDGPUWaitSGPRHazards {
if (It->getOpcode() != AMDGPU::S_WAITCNT_DEPCTR)
return false;
- It->getOperand(0).setImm(mergeMasks(Mask, It->getOperand(0).getImm()));
+ It->getOperand(0).setImm(
+ mergeMasks(Mask, static_cast<unsigned>(It->getOperand(0).getImm())));
return true;
}
@@ -243,7 +244,7 @@ class AMDGPUWaitSGPRHazards {
// Existing S_WAITALU can clear hazards
if (MI->getOpcode() == AMDGPU::S_WAITCNT_DEPCTR) {
- unsigned int Mask = MI->getOperand(0).getImm();
+ unsigned int Mask = static_cast<unsigned>(MI->getOperand(0).getImm());
if (AMDGPU::DepCtr::decodeFieldVaVcc(Mask) == 0)
State.VCCHazard &= ~HazardState::VALU;
if (AMDGPU::DepCtr::decodeFieldSaSdst(Mask) == 0) {
@@ -309,8 +310,8 @@ class AMDGPUWaitSGPRHazards {
return;
}
- uint8_t SGPRCount =
- AMDGPU::getRegBitWidth(*TRI->getRegClassForReg(*MRI, Reg)) / 32;
+ uint8_t SGPRCount = static_cast<uint8_t>(
+ AMDGPU::getRegBitWidth(*TRI->getRegClassForReg(*MRI, Reg)) / 32);
if (IsUse) {
// SALU reading SGPR clears VALU hazards
@@ -482,15 +483,16 @@ class AMDGPUWaitSGPRHazards {
if (PrevWait) {
// Merge previous wait into this one.
MachineOperand &MaskOp = MI.getOperand(0);
- MaskOp.setImm(
- mergeMasks(PrevWait->getOperand(0).getImm(), MaskOp.getImm()));
+ MaskOp.setImm(mergeMasks(
+ static_cast<unsigned>(PrevWait->getOperand(0).getImm()),
+ static_cast<unsigned>(MaskOp.getImm())));
PrevWait->eraseFromParent();
Changed = true;
} else {
// Starting a new region using fresh write set.
WriteSet.reset();
}
- CommitWrites(MI.getOperand(0).getImm());
+ CommitWrites(static_cast<unsigned>(MI.getOperand(0).getImm()));
PrevWait = &MI;
continue;
}
@@ -568,9 +570,9 @@ class AMDGPUWaitSGPRHazards {
MF.getFunction().hasFnAttribute("amdgpu-sgpr-hazard-mem-wait-cull");
if (!GlobalCullSGPRHazardsMemWaitThreshold.getNumOccurrences())
CullSGPRHazardsMemWaitThreshold =
- MF.getFunction().getFnAttributeAsParsedInteger(
+ static_cast<unsigned>(MF.getFunction().getFnAttributeAsParsedInteger(
"amdgpu-sgpr-hazard-mem-wait-cull-threshold",
- CullSGPRHazardsMemWaitThreshold);
+ CullSGPRHazardsMemWaitThreshold));
TII = ST->getInstrInfo();
TRI = ST->getRegisterInfo();
diff --git a/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.cpp b/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.cpp
index 08c3d7dd9b098..a318d1a2b4498 100644
--- a/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.cpp
+++ b/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.cpp
@@ -933,7 +933,7 @@ hasHazard(StateT InitialState,
}
if (!Expired) {
- unsigned StateIdx = States.size();
+ unsigned StateIdx = static_cast<unsigned>(States.size());
StateMapKey Key = {&States, StateIdx};
auto Insertion = StateMap.insert_as(std::pair(Key, StateIdx), State);
if (Insertion.second) {
@@ -1860,7 +1860,8 @@ bool GCNHazardRecognizer::fixVMEMtoScalarWriteHazards(MachineInstr *MI) {
(MI.getOpcode() == AMDGPU::S_WAITCNT &&
!MI.getOperand(0).getImm()) ||
(MI.getOpcode() == AMDGPU::S_WAITCNT_DEPCTR &&
- AMDGPU::DepCtr::decodeFieldVmVsrc(MI.getOperand(0).getImm()) == 0);
+ AMDGPU::DepCtr::decodeFieldVmVsrc(
+ static_cast<unsigned>(MI.getOperand(0).getImm())) == 0);
};
if (::getWaitStatesSince(IsHazardFn, MI, IsExpiredFn) ==
@@ -1930,7 +1931,8 @@ bool GCNHazardRecognizer::fixSMEMtoVectorWriteHazards(MachineInstr *MI) {
(MI.getOperand(0).getReg() == AMDGPU::SGPR_NULL);
case AMDGPU::S_WAITCNT: {
const int64_t Imm = MI.getOperand(0).getImm();
- AMDGPU::Waitcnt Decoded = AMDGPU::decodeWaitcnt(IV, Imm);
+ AMDGPU::Waitcnt Decoded =
+ AMDGPU::decodeWaitcnt(IV, static_cast<unsigned>(Imm));
// DsCnt corresponds to LGKMCnt here.
return Decoded.get(AMDGPU::DS_CNT) == 0;
}
@@ -1992,7 +1994,8 @@ bool GCNHazardRecognizer::fixVcmpxExecWARHazard(MachineInstr *MI) {
return true;
}
if (MI.getOpcode() == AMDGPU::S_WAITCNT_DEPCTR &&
- AMDGPU::DepCtr::decodeFieldSaSdst(MI.getOperand(0).getImm()) == 0)
+ AMDGPU::DepCtr::decodeFieldSaSdst(
+ static_cast<unsigned>(MI.getOperand(0).getImm())) == 0)
return true;
return false;
};
@@ -2154,7 +2157,8 @@ bool GCNHazardRecognizer::fixLdsDirectVMEMHazard(MachineInstr *MI) {
SIInstrInfo::isEXP(I) ||
(I.getOpcode() == AMDGPU::S_WAITCNT && !I.getOperand(0).getImm()) ||
(I.getOpcode() == AMDGPU::S_WAITCNT_DEPCTR &&
- AMDGPU::DepCtr::decodeFieldVmVsrc(I.getOperand(0).getImm()) == 0) ||
+ AMDGPU::DepCtr::decodeFieldVmVsrc(
+ static_cast<unsigned>(I.getOperand(0).getImm())) == 0) ||
(LdsdirCanWait && SIInstrInfo::isLDSDIR(I) &&
!TII.getNamedOperand(I, AMDGPU::OpName::waitvsrc)->getImm());
};
@@ -2222,7 +2226,7 @@ bool GCNHazardRecognizer::fixVALUPartialForwardingHazard(MachineInstr *MI) {
hash_code H = hash_combine(State.ExecPos, State.VALUs);
for (const auto &[Reg, Pos] : State.DefPos)
H = hash_combine(H, Reg, Pos);
- return H;
+ return static_cast<unsigned>(H);
}
static bool isEqual(const StateType &LHS, const StateType &RHS) {
return LHS.DefPos == RHS.DefPos && LHS.ExecPos == RHS.ExecPos &&
@@ -2242,7 +2246,8 @@ bool GCNHazardRecognizer::fixVALUPartialForwardingHazard(MachineInstr *MI) {
if (SIInstrInfo::isVMEM(I) || SIInstrInfo::isDS(I) ||
SIInstrInfo::isEXP(I) ||
(I.getOpcode() == AMDGPU::S_WAITCNT_DEPCTR &&
- AMDGPU::DepCtr::decodeFieldVaVdst(I.getOperand(0).getImm()) == 0))
+ AMDGPU::DepCtr::decodeFieldVaVdst(
+ static_cast<unsigned>(I.getOperand(0).getImm())) == 0))
return HazardExpired;
// Track registers writes
@@ -2366,7 +2371,7 @@ bool GCNHazardRecognizer::fixVALUTransUseHazard(MachineInstr *MI) {
int TRANS = 0;
static unsigned getHashValue(const StateType &State) {
- return hash_combine(State.VALUs, State.TRANS);
+ return static_cast<unsigned>(hash_combine(State.VALUs, State.TRANS));
}
static bool isEqual(const StateType &LHS, const StateType &RHS) {
return LHS.VALUs == RHS.VALUs && LHS.TRANS == RHS.TRANS;
@@ -2385,7 +2390,8 @@ bool GCNHazardRecognizer::fixVALUTransUseHazard(MachineInstr *MI) {
if (SIInstrInfo::isVMEM(I) || SIInstrInfo::isDS(I) ||
SIInstrInfo::isEXP(I) ||
(I.getOpcode() == AMDGPU::S_WAITCNT_DEPCTR &&
- AMDGPU::DepCtr::decodeFieldVaVdst(I.getOperand(0).getImm()) == 0))
+ AMDGPU::DepCtr::decodeFieldVaVdst(
+ static_cast<unsigned>(I.getOperand(0).getImm())) == 0))
return HazardExpired;
// Track registers writes
@@ -3948,7 +3954,7 @@ bool GCNHazardRecognizer::fixVALUMaskWriteHazard(MachineInstr *MI) {
SmallSet<Register, 2> HazardSGPRs;
static unsigned getHashValue(const StateType &State) {
- return hash_combine_range(State.HazardSGPRs);
+ return static_cast<unsigned>(hash_combine_range(State.HazardSGPRs));
}
static bool isEqual(const StateType &LHS, const StateType &RHS) {
return LHS.HazardSGPRs == RHS.HazardSGPRs;
@@ -4134,7 +4140,7 @@ bool GCNHazardRecognizer::fixRequiredExportPriority(MachineInstr *MI) {
case AMDGPU::S_SETPRIO: {
// Raise minimum priority unless in workaround.
auto &PrioOp = MI->getOperand(0);
- int Prio = PrioOp.getImm();
+ int Prio = static_cast<int>(PrioOp.getImm());
bool InWA = (Prio == PostExportPriority) &&
(It != MBB->begin() && TII.isEXP(*std::prev(It)));
if (InWA || Prio >= NormalPriority)
@@ -4278,7 +4284,7 @@ bool GCNHazardRecognizer::fixScratchBaseForwardingHazard(MachineInstr *MI) {
auto IsExpiredFn = [=](const MachineInstr &MI, int SgprWrites) {
if (MI.getOpcode() == AMDGPU::S_WAITCNT_DEPCTR) {
- unsigned Wait = MI.getOperand(0).getImm();
+ unsigned Wait = static_cast<unsigned>(MI.getOperand(0).getImm());
if (AMDGPU::DepCtr::decodeFieldSaSdst(Wait) == 0 &&
AMDGPU::DepCtr::decodeFieldVaSdst(Wait) == 0)
return true;
diff --git a/llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp b/llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp
index 33fb3c7ca37a0..2ea707215cdff 100644
--- a/llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp
+++ b/llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp
@@ -858,7 +858,7 @@ class SIInsertWaitcntsLegacy : public MachineFunctionPass {
void WaitcntBrackets::setScoreByOperand(const MachineOperand &Op,
AMDGPU::InstCounterType CntTy,
unsigned Score) {
- setRegScore(Op.getReg().asMCReg(), CntTy, Score);
+ setRegScore(static_cast<MCPhysReg>(Op.getReg().asMCReg()), CntTy, Score);
}
// Return true if the subtarget is one that enables Point Sample Acceleration
@@ -1045,7 +1045,8 @@ void WaitcntBrackets::updateByEvent(HWEvents E, MachineInstr &Inst) {
// this with another potential dependency
if (hasPointSampleAccel(Inst))
VGPRContext |= HWEvents::VMEM_READ_ACCESS;
- for (MCRegUnit RU : regunits(Op.getReg().asMCReg()))
+ for (MCRegUnit RU :
+ regunits(static_cast<MCPhysReg>(Op.getReg().asMCReg())))
VMem[toVMEMID(RU)].VGPRPendingEvents |= VGPRContext;
}
}
@@ -1074,7 +1075,8 @@ void WaitcntBrackets::updateByEvent(HWEvents E, MachineInstr &Inst) {
// is squashed into a single big object.
if (!AAI || !AAI.Scope)
break;
- for (unsigned I = 0, E = LDSDMAStores.size(); I != E && !Slot; ++I) {
+ for (unsigned I = 0, E = static_cast<unsigned>(LDSDMAStores.size());
+ I != E && !Slot; ++I) {
for (const auto *MemOp : LDSDMAStores[I]->memoperands()) {
if (MemOp->isStore() && AAI == MemOp->getAAInfo()) {
Slot = I + 1;
@@ -1088,7 +1090,7 @@ void WaitcntBrackets::updateByEvent(HWEvents E, MachineInstr &Inst) {
// means the scoreboard cannot track it. We still want to preserve the
// MI in order to check alias information, though.
LDSDMAStores.push_back(&Inst);
- Slot = LDSDMAStores.size();
+ Slot = static_cast<unsigned>(LDSDMAStores.size());
break;
}
setVMemScore(LDSDMA_BEGIN, T, CurrScore);
@@ -1446,7 +1448,7 @@ MCPhysReg WaitcntBrackets::determineVGPR16Dependency(const MachineInstr &MI,
AMDGPU::InstCounterType T,
MCPhysReg Reg) const {
const TargetRegisterClass *RC = Context->TRI.getPhysRegBaseClass(Reg);
- unsigned Size = Context->TRI.getRegSizeInBits(*RC);
+ unsigned Size = static_cast<unsigned>(Context->TRI.getRegSizeInBits(*RC));
if (Size != 16 || !Context->ST.hasD16Writes32BitVgpr())
return Reg;
@@ -1459,7 +1461,7 @@ MCPhysReg WaitcntBrackets::determineVGPR16Dependency(const MachineInstr &MI,
AMDGPU::isHi16Reg(Reg, Context->TRI) ? AMDGPU::lo16 : AMDGPU::hi16);
AMDGPU::Waitcnt Wait;
- for (MCRegUnit RU : regunits(OtherHalf))
+ for (MCRegUnit RU : regunits(static_cast<MCPhysReg>(OtherHalf)))
determineWaitForScore(T, getVMemScore(toVMEMID(RU), T), Wait);
// No wait on otherhalf
@@ -1467,7 +1469,7 @@ MCPhysReg WaitcntBrackets::determineVGPR16Dependency(const MachineInstr &MI,
return Reg;
if (Context->TII.isVALU(MI, /*AllowLDSDMA=*/false))
- return Reg32;
+ return static_cast<MCPhysReg>(Reg32);
// If hi/lo16 mixed events
HWEvents MIEvents = AMDGPU::getEventsFor(
@@ -1475,7 +1477,7 @@ MCPhysReg WaitcntBrackets::determineVGPR16Dependency(const MachineInstr &MI,
HWEvents OtherHalfEvents = Context->getWaitEvents(T);
HWEvents Events = MIEvents & OtherHalfEvents;
if (Events.size() > 1)
- return Reg32;
+ return static_cast<MCPhysReg>(Reg32);
return Reg;
}
@@ -1684,7 +1686,7 @@ bool WaitcntGeneratorPreGFX12::applyPreexistingWaitcnt(
// Update required wait count. If this is a soft waitcnt (= it was added
// by an earlier pass), it may be entirely removed.
if (Opcode == AMDGPU::S_WAITCNT) {
- unsigned IEnc = II.getOperand(0).getImm();
+ unsigned IEnc = static_cast<unsigned>(II.getOperand(0).getImm());
AMDGPU::Waitcnt OldWait = AMDGPU::decodeWaitcnt(IV, IEnc);
if (TrySimplify) {
ScoreBrackets.simplifyWaitcnt(OldWait);
@@ -1722,7 +1724,7 @@ bool WaitcntGeneratorPreGFX12::applyPreexistingWaitcnt(
// recreated by running the memory legalizer.
II.eraseFromParent();
} else if (Opcode == AMDGPU::WAIT_ASYNCMARK) {
- unsigned N = II.getOperand(0).getImm();
+ unsigned N = static_cast<unsigned>(II.getOperand(0).getImm());
LLVM_DEBUG(dbgs() << "Processing WAIT_ASYNCMARK: " << II << '\n';);
AMDGPU::Waitcnt OldWait = ScoreBrackets.determineAsyncWait(N);
Wait = Wait.combined(OldWait);
@@ -1730,8 +1732,8 @@ bool WaitcntGeneratorPreGFX12::applyPreexistingWaitcnt(
assert(Opcode == AMDGPU::S_WAITCNT_VSCNT);
assert(II.getOperand(0).getReg() == AMDGPU::SGPR_NULL);
- unsigned OldVSCnt =
- TII.getNamedOperand(II, AMDGPU::OpName::simm16)->getImm();
+ unsigned OldVSCnt = static_cast<unsigned>(
+ TII.getNamedOperand(II, AMDGPU::OpName::simm16)->getImm());
if (TrySimplify)
ScoreBrackets.simplifyWaitcnt(AMDGPU::STORE_CNT, OldVSCnt);
Wait.set(AMDGPU::STORE_CNT,
@@ -1946,8 +1948,8 @@ bool WaitcntGeneratorGFX12Plus::applyPreexistingWaitcnt(
continue;
if (Opcode == AMDGPU::S_WAIT_LOADCNT_DSCNT) {
- unsigned OldEnc =
- TII.getNamedOperand(II, AMDGPU::OpName::simm16)->getImm();
+ unsigned OldEnc = static_cast<unsigned>(
+ TII.getNamedOperand(II, AMDGPU::OpName::simm16)->getImm());
AMDGPU::Waitcnt OldWait = AMDGPU::decodeLoadcntDscnt(IV, OldEnc);
if (TrySimplify)
Wait = Wait.combined(OldWait);
@@ -1961,8 +1963,8 @@ bool WaitcntGeneratorGFX12Plus::applyPreexistingWaitcnt(
Modified = true;
}
} else if (Opcode == AMDGPU::S_WAIT_STORECNT_DSCNT) {
- unsigned OldEnc =
- TII.getNamedOperand(II, AMDGPU::OpName::simm16)->getImm();
+ unsigned OldEnc = static_cast<unsigned>(
+ TII.getNamedOperand(II, AMDGPU::OpName::simm16)->getImm());
AMDGPU::Waitcnt OldWait = AMDGPU::decodeStorecntDscnt(IV, OldEnc);
if (TrySimplify)
Wait = Wait.combined(OldWait);
@@ -1976,8 +1978,8 @@ bool WaitcntGeneratorGFX12Plus::applyPreexistingWaitcnt(
Modified = true;
}
} else if (Opcode == AMDGPU::S_WAITCNT_DEPCTR) {
- unsigned OldEnc =
- TII.getNamedOperand(II, AMDGPU::OpName::simm16)->getImm();
+ unsigned OldEnc = static_cast<unsigned>(
+ TII.getNamedOperand(II, AMDGPU::OpName::simm16)->getImm());
AMDGPU::Waitcnt OldWait;
// Set both counters to the decoded value from the single hardware field
unsigned VaVdst = AMDGPU::DepCtr::decodeFieldVaVdst(OldEnc);
@@ -1996,8 +1998,8 @@ bool WaitcntGeneratorGFX12Plus::applyPreexistingWaitcnt(
// VM_VSRC subfields of the operand are set to the "no wait"
// values.
- unsigned Enc =
- TII.getNamedOperand(II, AMDGPU::OpName::simm16)->getImm();
+ unsigned Enc = static_cast<unsigned>(
+ TII.getNamedOperand(II, AMDGPU::OpName::simm16)->getImm());
Enc = AMDGPU::DepCtr::encodeFieldVmVsrc(Enc, ~0u);
// Encode min(VA_VDST_RD, VA_VDST_WR) into the single hardware field
unsigned VaVdst = std::min(Wait.get(AMDGPU::VA_VDST_RD),
@@ -2020,15 +2022,15 @@ bool WaitcntGeneratorGFX12Plus::applyPreexistingWaitcnt(
} else if (Opcode == AMDGPU::WAIT_ASYNCMARK) {
// Update the Waitcnt, but don't erase the wait.asyncmark() itself. It
// shows up in the assembly as a comment with the original parameter N.
- unsigned N = II.getOperand(0).getImm();
+ unsigned N = static_cast<unsigned>(II.getOperand(0).getImm());
AMDGPU::Waitcnt OldWait = ScoreBrackets.determineAsyncWait(N);
Wait = Wait.combined(OldWait);
} else {
std::optional<AMDGPU::InstCounterType> CT =
AMDGPU::counterTypeForInstr(Opcode);
assert(CT.has_value());
- unsigned OldCnt =
- TII.getNamedOperand(II, AMDGPU::OpName::simm16)->getImm();
+ unsigned OldCnt = static_cast<unsigned>(
+ TII.getNamedOperand(II, AMDGPU::OpName::simm16)->getImm());
if (TrySimplify)
Wait.add(CT.value(), OldCnt);
else
@@ -2169,9 +2171,9 @@ bool WaitcntGeneratorGFX12Plus::applyPreexistingWaitcnt(
if (WaitcntDepctrInstr) {
// Get the encoded Depctr immediate and override the VA_VDST and VM_VSRC
// subfields with the new required values.
- unsigned Enc =
+ unsigned Enc = static_cast<unsigned>(
TII.getNamedOperand(*WaitcntDepctrInstr, AMDGPU::OpName::simm16)
- ->getImm();
+ ->getImm());
Enc = AMDGPU::DepCtr::encodeFieldVmVsrc(Enc, Wait.get(AMDGPU::VM_VSRC));
// Encode min(VA_VDST_RD, VA_VDST_WR) into the single hardware field
unsigned VaVdst =
@@ -2423,12 +2425,14 @@ bool SIInsertWaitcnts::generateWaitcntInstBefore(
const MachineOperand &CallAddrOp = TII.getCalleeOperand(MI);
if (CallAddrOp.isReg()) {
ScoreBrackets.determineWaitForPhysReg(
- SmemAccessCounter, CallAddrOp.getReg().asMCReg(), Wait, MI);
+ SmemAccessCounter,
+ static_cast<MCPhysReg>(CallAddrOp.getReg().asMCReg()), Wait, MI);
if (const auto *RtnAddrOp =
TII.getNamedOperand(MI, AMDGPU::OpName::dst)) {
ScoreBrackets.determineWaitForPhysReg(
- SmemAccessCounter, RtnAddrOp->getReg().asMCReg(), Wait, MI);
+ SmemAccessCounter,
+ static_cast<MCPhysReg>(RtnAddrOp->getReg().asMCReg()), Wait, MI);
}
}
} else if (Opc == AMDGPU::S_BARRIER_WAIT) {
@@ -2468,7 +2472,8 @@ bool SIInsertWaitcnts::generateWaitcntInstBefore(
unsigned TID = LDSDMA_BEGIN;
if (Ptr && Memop->getAAInfo()) {
const auto &LDSDMAStores = ScoreBrackets.getLDSDMAStores();
- for (unsigned I = 0, E = LDSDMAStores.size(); I != E; ++I) {
+ for (unsigned I = 0, E = static_cast<unsigned>(LDSDMAStores.size());
+ I != E; ++I) {
if (MI.mayAlias(AA, *LDSDMAStores[I], true)) {
if ((I + 1) >= NUM_LDSDMA) {
// We didn't have enough slot to track this LDS DMA store, it
@@ -2499,7 +2504,7 @@ bool SIInsertWaitcnts::generateWaitcntInstBefore(
if (Op.isTied() && Op.isUse() && TII.doesNotReadTiedSource(MI))
continue;
- MCPhysReg Reg = Op.getReg().asMCReg();
+ MCPhysReg Reg = static_cast<MCPhysReg>(Op.getReg().asMCReg());
const bool IsVGPR = TRI.isVectorRegister(MRI, Op.getReg());
if (IsVGPR) {
@@ -2765,7 +2770,7 @@ void SIInsertWaitcnts::updateEventWaitcntAfter(MachineInstr &Inst,
ScoreBrackets->setStateOnFunctionEntryOrReturn();
} else if (TII.isVINTERP(Inst)) {
int64_t Imm = TII.getNamedOperand(Inst, AMDGPU::OpName::waitexp)->getImm();
- ScoreBrackets->applyWaitcnt(AMDGPU::EXP_CNT, Imm);
+ ScoreBrackets->applyWaitcnt(AMDGPU::EXP_CNT, static_cast<unsigned>(Imm));
}
// Set XCNT to zero in the bracket for instructions that implicitly drain
@@ -2831,8 +2836,8 @@ bool WaitcntBrackets::mergeAsyncMarks(ArrayRef<MergeInfo> MergeInfos,
// zero/identity mark: mergeScore still applies MyShift, so the mark is
// re-expressed in the new frame instead of being left with a stale
// (pre-merge) score.
- const unsigned OtherSize = OtherMarks.size();
- const unsigned OurSize = AsyncMarks.size();
+ const unsigned OtherSize = static_cast<unsigned>(OtherMarks.size());
+ const unsigned OurSize = static_cast<unsigned>(AsyncMarks.size());
// After the both-empty early-return above, max(AsyncMarks, OtherMarks) >= 1,
// and the erase/pad steps normalize AsyncMarks to exactly MaxSize. Hence
// OurSize == MaxSize >= 1 (as long as MaxAsyncMarks != 0), so the
@@ -2965,8 +2970,10 @@ static bool isWaitInstr(MachineInstr &Inst) {
void SIInsertWaitcnts::setSchedulingMode(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I,
bool ExpertMode) const {
- const unsigned EncodedReg = AMDGPU::Hwreg::HwregEncoding::encode(
- AMDGPU::Hwreg::ID_SCHED_MODE, AMDGPU::Hwreg::HwregOffset::Default, 2);
+ const unsigned EncodedReg =
+ static_cast<unsigned>(AMDGPU::Hwreg::HwregEncoding::encode(
+ AMDGPU::Hwreg::ID_SCHED_MODE, AMDGPU::Hwreg::HwregOffset::Default,
+ 2));
BuildMI(MBB, I, DebugLoc(), TII.get(AMDGPU::S_SETREG_IMM32_B32))
.addImm(ExpertMode ? 2 : 0)
.addImm(EncodedReg);
diff --git a/llvm/lib/Target/AMDGPU/SIModeRegister.cpp b/llvm/lib/Target/AMDGPU/SIModeRegister.cpp
index dbe27a8030d4e..dc76bc584c814 100644
--- a/llvm/lib/Target/AMDGPU/SIModeRegister.cpp
+++ b/llvm/lib/Target/AMDGPU/SIModeRegister.cpp
@@ -183,31 +183,31 @@ Status SIModeRegister::getInstructionMode(MachineInstr &MI,
return Status(FP_ROUND_MODE_DP(3),
FP_ROUND_MODE_DP(FP_ROUND_ROUND_TO_ZERO));
case AMDGPU::FPTRUNC_ROUND_F16_F32_PSEUDO: {
- unsigned Mode = MI.getOperand(2).getImm();
+ unsigned Mode = static_cast<unsigned>(MI.getOperand(2).getImm());
MI.removeOperand(2);
MI.setDesc(TII->get(AMDGPU::V_CVT_F16_F32_e32));
return Status(FP_ROUND_MODE_DP(3), FP_ROUND_MODE_DP(Mode));
}
case AMDGPU::FPTRUNC_ROUND_F16_F32_PSEUDO_fake16_e32: {
- unsigned Mode = MI.getOperand(2).getImm();
+ unsigned Mode = static_cast<unsigned>(MI.getOperand(2).getImm());
MI.removeOperand(2);
MI.setDesc(TII->get(AMDGPU::V_CVT_F16_F32_fake16_e32));
return Status(FP_ROUND_MODE_DP(3), FP_ROUND_MODE_DP(Mode));
}
case AMDGPU::FPTRUNC_ROUND_F16_F32_PSEUDO_t16_e64: {
- unsigned Mode = MI.getOperand(6).getImm();
+ unsigned Mode = static_cast<unsigned>(MI.getOperand(6).getImm());
MI.removeOperand(6);
MI.setDesc(TII->get(AMDGPU::V_CVT_F16_F32_t16_e64));
return Status(FP_ROUND_MODE_DP(3), FP_ROUND_MODE_DP(Mode));
}
case AMDGPU::FPTRUNC_ROUND_F32_F64_PSEUDO: {
- unsigned Mode = MI.getOperand(2).getImm();
+ unsigned Mode = static_cast<unsigned>(MI.getOperand(2).getImm());
MI.removeOperand(2);
MI.setDesc(TII->get(AMDGPU::V_CVT_F32_F64_e32));
return Status(FP_ROUND_MODE_DP(3), FP_ROUND_MODE_DP(Mode));
}
case AMDGPU::FPTRUNC_ROUND_F16_F32_SALU_PSEUDO: {
- unsigned Mode = MI.getOperand(2).getImm();
+ unsigned Mode = static_cast<unsigned>(MI.getOperand(2).getImm());
MI.removeOperand(2);
MI.setDesc(TII->get(AMDGPU::S_CVT_F16_F32));
return Status(FP_ROUND_MODE_DP(3), FP_ROUND_MODE_DP(Mode));
@@ -279,7 +279,8 @@ void SIModeRegister::processBlockPhase1(MachineBasicBlock &MBB,
// We preserve any explicit mode register setreg instruction we encounter,
// as we assume it has been inserted by a higher authority (this is
// likely to be a very rare occurrence).
- unsigned Dst = TII->getNamedOperand(MI, AMDGPU::OpName::simm16)->getImm();
+ unsigned Dst = static_cast<unsigned>(
+ TII->getNamedOperand(MI, AMDGPU::OpName::simm16)->getImm());
using namespace AMDGPU::Hwreg;
auto [Id, Offset, Width] = HwregEncoding::decode(Dst);
if (Id != ID_MODE)
@@ -297,7 +298,8 @@ void SIModeRegister::processBlockPhase1(MachineBasicBlock &MBB,
// as unknown.
if (MI.getOpcode() == AMDGPU::S_SETREG_IMM32_B32 ||
MI.getOpcode() == AMDGPU::S_SETREG_IMM32_B32_mode) {
- unsigned Val = TII->getNamedOperand(MI, AMDGPU::OpName::imm)->getImm();
+ unsigned Val = static_cast<unsigned>(
+ TII->getNamedOperand(MI, AMDGPU::OpName::imm)->getImm());
unsigned Mode = (Val << Offset) & Mask;
Status Setreg = Status(Mask, Mode);
// If we haven't already set the initial requirements for the block we
>From 354b087b6700547fe1e71f86eecd642f52b045c8 Mon Sep 17 00:00:00 2001
From: Greta Y <Greta.Yorsh at amd.com>
Date: Wed, 23 Sep 2026 14:06:24 +0100
Subject: [PATCH 2/2] [AMDGPU][NFC] Explicitly narrow the REPLAY_MODE hwreg
encoding
HwregEncoding::encode returns uint64_t and the result is held in an unsigned
local. This code moved to SIInsertWaitcnts.cpp from SIFrameLowering.cpp, where
the cast was made in PR #215203.
Assisted-by: Claude <noreply at anthropic.com>
---
llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp b/llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp
index 2ea707215cdff..3e56652acc27f 100644
--- a/llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp
+++ b/llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp
@@ -3750,8 +3750,8 @@ bool SIInsertWaitcnts::run() {
// Set REPLAY_MODE (bit 25) in MODE register to enable multi-group XNACK
// replay. This aligns hardware behavior with the compiler's s_wait_xcnt
// insertion logic, which assumes multi-group mode by default.
- unsigned RegEncoding =
- AMDGPU::Hwreg::HwregEncoding::encode(AMDGPU::Hwreg::ID_MODE, 25, 1);
+ unsigned RegEncoding = static_cast<unsigned>(
+ AMDGPU::Hwreg::HwregEncoding::encode(AMDGPU::Hwreg::ID_MODE, 25, 1));
BuildMI(EntryBB, InsertPt, DebugLoc(),
TII.get(AMDGPU::S_SETREG_IMM32_B32))
.addImm(1)
More information about the llvm-commits
mailing list