[llvm] [X86] Lower bf16->f32/f64 fpext without a GPR round-trip (PR #218359)
Phoebe Wang via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 24 20:54:14 PDT 2026
================
@@ -22973,6 +22975,39 @@ static SDValue LowerFP_TO_FP16(SDValue Op, SelectionDAG &DAG) {
return Res;
}
+SDValue X86TargetLowering::LowerBF16_TO_FP(SDValue Op,
+ SelectionDAG &DAG) const {
+ SDLoc DL(Op);
+ SDValue Src = Op.getOperand(0);
+ // Operand is usually already softened to i16 by type legalization.
+ if (Src.getValueType() == MVT::bf16)
+ Src = DAG.getBitcast(MVT::i16, Src);
+ else
+ Src = DAG.getAnyExtOrTrunc(Src, DL, MVT::i16);
+
+ // Peek through to bf16's underlying f16 register
+ MVT VecVT = MVT::v8i16;
+ SDValue VecSrc = Src;
+ if (Src.getOpcode() == ISD::BITCAST &&
+ Src.getOperand(0).getValueType() == MVT::f16) {
+ VecSrc = Src.getOperand(0);
+ VecVT = MVT::v8f16;
+ }
----------------
phoebewang wrote:
Yeah, I think we missed the SCALAR_TO_VECTOR combine for F16/BF16 under AVX512FP16, e.g.,
```
// Combine (v8i16 (scalar_to_vector (i16 (bitcast (f16/bf16))))) to VMOVW
if (Subtarget.hasFP16()) {
if (VT == MVT::v8i16 && SrcOp.getValueType() == MVT::f16)
return DAG.getBitcast(
VT, DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, MVT::v8f16, SrcOp));
if (VT == MVT::v8i16 && SrcOp.getValueType() == MVT::bf16)
return DAG.getBitcast(
VT, DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, MVT::v8bf16, SrcOp));
}
```
https://github.com/llvm/llvm-project/pull/218359
More information about the llvm-commits
mailing list