[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:13:43 PDT 2026


https://github.com/gretay-amd updated https://github.com/llvm/llvm-project/pull/215197

>From fd1515ca8381041753ccf988ecd57e02b5e7a2e3 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/3] [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 b777ea5e89c30215ca6c6cd27e66f17f7dd4609d 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/3] [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)

>From 5ce84d877e0d6c976e485fc3612da7f8737b4e61 Mon Sep 17 00:00:00 2001
From: Greta Y <Greta.Yorsh at amd.com>
Date: Thu, 24 Sep 2026 10:13:30 +0100
Subject: [PATCH 3/3] Retrigger CI (libcxx-ci checkout flake)




More information about the llvm-commits mailing list