[llvm] [AMDGPU] Add custom lowering of llvm.convert.from.arbitrary.fp for FP8 (PR #194144)
Dmitry Sidorov via llvm-commits
llvm-commits at lists.llvm.org
Tue May 5 10:33:52 PDT 2026
================
@@ -10569,6 +10584,126 @@ SDValue SITargetLowering::lowerWorkitemID(SelectionDAG &DAG, SDValue Op,
DAG.getValueType(SmallVT));
}
+// Pack a vector of i8 lanes into i32 via bitcast.
+// FIXME: packing loses lane-wise poison. Should we do something about it?
+SDValue SITargetLowering::packBytesToI32(SelectionDAG &DAG, const SDLoc &SL,
+ SDValue Src, unsigned NumBytes,
+ unsigned FirstLane) {
+ EVT SrcVT = Src.getValueType();
+ assert(SrcVT.isVector() && SrcVT.getVectorElementType() == MVT::i8 &&
+ "packBytesToI32 expects a v*i8 source");
+ unsigned SrcBytes = SrcVT.getVectorNumElements();
+ assert((NumBytes == 2 || NumBytes == 4) && "expected 2 or 4 bytes");
+
+ if (NumBytes == 4) {
+ assert(FirstLane == 0 && "v4i8 -> i32 takes the full vector");
+ return DAG.getNode(ISD::BITCAST, SL, MVT::i32, Src);
+ }
+
+ // Bitcast a vector to the same-width integer, optionally shift down to the
+ // requested slice, truncate to i16, and zext to i32.
+ EVT IntVT = EVT::getIntegerVT(*DAG.getContext(), SrcBytes * 8);
+ SDValue AsInt = DAG.getNode(ISD::BITCAST, SL, IntVT, Src);
+ if (FirstLane != 0)
+ AsInt = DAG.getNode(ISD::SRL, SL, IntVT, AsInt,
+ DAG.getConstant(FirstLane * 8, SL, IntVT));
+ SDValue I16 = DAG.getNode(ISD::TRUNCATE, SL, MVT::i16, AsInt);
+ return DAG.getNode(ISD::ZERO_EXTEND, SL, MVT::i32, I16);
+}
+
+SDValue SITargetLowering::lowerFromFP8ToF32(SDValue Op, bool IsBF8,
+ SelectionDAG &DAG) const {
+ EVT DstVT = Op.getValueType();
+ SDLoc SL(Op);
+ SDValue Src = Op.getOperand(0);
+
+ assert(DstVT.isVector() && "Scalar f32 should be selected by TableGen");
+
+ auto EmitPk = [&](SDValue PackedI32, unsigned WordSel) {
+ unsigned IntrID = IsBF8 ? Intrinsic::amdgcn_cvt_pk_f32_bf8
+ : Intrinsic::amdgcn_cvt_pk_f32_fp8;
+ return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, SL, MVT::v2f32,
+ DAG.getTargetConstant(IntrID, SL, MVT::i32), PackedI32,
+ DAG.getTargetConstant(WordSel, SL, MVT::i1));
+ };
+
+ if (DstVT == MVT::v2f32)
+ return EmitPk(packBytesToI32(DAG, SL, Src, 2, 0), 0);
+
+ SDValue PackedI32 = packBytesToI32(DAG, SL, Src, 4, 0);
+ SDValue Lo = EmitPk(PackedI32, 0);
+ SDValue Hi = EmitPk(PackedI32, 1);
+ return DAG.getNode(ISD::CONCAT_VECTORS, SL, MVT::v4f32, Lo, Hi);
+}
+
+SDValue SITargetLowering::lowerFromFP8ToF16(SDValue Op, bool IsBF8,
----------------
MrSidims wrote:
Custom lowering for v2 is still there as H/W instruction is packed. I'm not sure if lowering via table gen would be more handy than manually written C++ code.
https://github.com/llvm/llvm-project/pull/194144
More information about the llvm-commits
mailing list