[llvm] [AMDGPU][True16][CodeGen] S_PACK_XX_B32_B16 lowering for true16 mode (PR #162389)

Jay Foad via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 15 07:48:08 PDT 2025


================
@@ -9072,6 +9115,65 @@ void SIInstrInfo::movePackToVALU(SIInstrWorklist &Worklist,
   MachineOperand &Src1 = Inst.getOperand(2);
   const DebugLoc &DL = Inst.getDebugLoc();
 
+  if (ST.useRealTrue16Insts()) {
+    Register SrcReg0, SrcReg1;
+    if (!Src0.isReg() || (Src0.isReg() && !RI.isVGPR(MRI, Src0.getReg()))) {
+      SrcReg0 = MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass);
+      BuildMI(*MBB, Inst, DL, get(AMDGPU::V_MOV_B32_e32), SrcReg0).add(Src0);
+    } else
+      SrcReg0 = Src0.getReg();
+
+    if (!Src1.isReg() || (Src1.isReg() && !RI.isVGPR(MRI, Src1.getReg()))) {
+      SrcReg1 = MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass);
+      BuildMI(*MBB, Inst, DL, get(AMDGPU::V_MOV_B32_e32), SrcReg1).add(Src1);
+    } else
+      SrcReg1 = Src1.getReg();
+
+    bool isSrc0Reg16 = MRI.constrainRegClass(SrcReg0, &AMDGPU::VGPR_16RegClass);
+    bool isSrc1Reg16 = MRI.constrainRegClass(SrcReg1, &AMDGPU::VGPR_16RegClass);
----------------
jayfoad wrote:

Copying the example here:
```
    %1:sreg_32 = COPY %0:vgpr_32
    %2:sreg_32 = S_FMAC_F16 %1:sreg_32, %1:sreg_32, %1:sreg_32, implicit $mode
    %3:sreg_32 = S_PACK_LL_B32_B16 %2:sreg_32, %1:sreg_32, implicit-def dead $scc
```
That seems like a bug in how moveToVALU handles `S_FMAC_F16`. If we naively convert it to something like `%2:vgpr_16 = V_FMAC_F16 ...` then we have lost the fact that the original instruction generated a 32-bit result with zeroes in the high 16 bits.

https://github.com/llvm/llvm-project/pull/162389


More information about the llvm-commits mailing list