[llvm] [AMDGPU] Support TFE D16 format buffer loads on gfx8/10/11/12 (PR #211465)

Arseniy Obolenskiy via llvm-commits llvm-commits at lists.llvm.org
Sun Sep 13 11:27:07 PDT 2026


================
@@ -6967,7 +6977,60 @@ bool AMDGPULegalizerInfo::legalizeBufferLoad(MachineInstr &MI,
     }
   }
 
-  if (IsTFE) {
+  if (IsTFE && IsD16 && Ty.isVector()) {
+    // D16 dwords are packed (or, on unpacked-D16 targets, one element per
+    // dword) at a different granularity than Ty's own bit width, so the
+    // dwords loaded for the value do not necessarily cover Ty exactly (e.g.
+    // v3i16 needs 2 dwords = 64 bits for its 48 bits of data). Load the
+    // dwords, then repack/truncate down to Ty the same way the MUBUF/MIMG
+    // TFE v3i16 case does.
+    const unsigned NumElts = Ty.getNumElements();
+    const unsigned NumValueDWords =
+        Unpacked ? NumElts : divideCeil(NumElts * 16, 32);
+    const unsigned NumLoadDWords = NumValueDWords + 1;
+    LLT LoadTy = LLT::fixed_vector(NumLoadDWords, I32);
+    Register LoadDstReg = B.getMRI()->createGenericVirtualRegister(LoadTy);
+    buildBufferLoad(Opc, LoadDstReg, RSrc, VIndex, VOffset, SOffset, ImmOffset,
+                    Format, AuxiliaryData, MMO, IsTyped, HasVIndex, B);
+
+    SmallVector<Register, 5> LoadElts;
+    for (unsigned I = 0; I != NumValueDWords; ++I)
+      LoadElts.push_back(B.getMRI()->createGenericVirtualRegister(I32));
+    LoadElts.push_back(StatusDst);
+    B.buildUnmerge(LoadElts, LoadDstReg);
+    LoadElts.truncate(NumValueDWords);
+
+    Register PackedI16;
+    if (Unpacked) {
+      SmallVector<Register, 4> Repack;
+      for (Register R : LoadElts)
+        Repack.push_back(B.buildTrunc(LLT::integer(16), R).getReg(0));
+      LLT RepackedTy = LLT::fixed_vector(NumValueDWords, LLT::integer(16));
+      PackedI16 = B.buildMergeLikeInstr(RepackedTy, Repack).getReg(0);
+    } else {
+      Register Merged;
+      if (NumValueDWords == 1) {
+        Merged = LoadElts[0];
+      } else {
+        LLT MergedTy = LLT::fixed_vector(NumValueDWords, I32);
+        Merged = B.buildMergeLikeInstr(MergedTy, LoadElts).getReg(0);
+      }
+      LLT PackedI16Ty = LLT::fixed_vector(NumValueDWords * 2, LLT::integer(16));
+      PackedI16 = B.buildBitcast(PackedI16Ty, Merged).getReg(0);
+    }
+
+    LLT PackedI16Ty = B.getMRI()->getType(PackedI16);
+    LLT DstIntTy = Ty.changeElementType(LLT::integer(16));
+    Register ValueI16 = PackedI16;
+    if (PackedI16Ty.getNumElements() != NumElts) {
+      ValueI16 = B.getMRI()->createGenericVirtualRegister(DstIntTy);
+      B.buildDeleteTrailingVectorElements(ValueI16, PackedI16);
+    }
+    if (EltTy.isFloat())
+      B.buildBitcast(Dst, ValueI16);
+    else
+      B.buildCopy(Dst, ValueI16);
----------------
aobolensk wrote:

Simplified 

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


More information about the llvm-commits mailing list