[llvm] [RISCV] Bitcast fixed length bf16/f16 build_vector to i16 with Zvfbfmin/Zvfhmin+Zfbfmin/Zfhmin. (PR #106637)
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 29 18:53:47 PDT 2024
================
@@ -3924,38 +3924,55 @@ static SDValue lowerBuildVectorViaPacking(SDValue Op, SelectionDAG &DAG,
DAG.getBuildVector(WideVecVT, DL, NewOperands));
}
-// Convert to an vXf16 build_vector to vXi16 with bitcasts.
-static SDValue lowerBUILD_VECTORvXf16(SDValue Op, SelectionDAG &DAG) {
- MVT VT = Op.getSimpleValueType();
- MVT IVT = VT.changeVectorElementType(MVT::i16);
- SmallVector<SDValue, 16> NewOps(Op.getNumOperands());
- for (unsigned I = 0, E = Op.getNumOperands(); I != E; ++I)
- NewOps[I] = DAG.getBitcast(MVT::i16, Op.getOperand(I));
- SDValue Res = DAG.getNode(ISD::BUILD_VECTOR, SDLoc(Op), IVT, NewOps);
- return DAG.getBitcast(VT, Res);
-}
-
static SDValue lowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG,
const RISCVSubtarget &Subtarget) {
MVT VT = Op.getSimpleValueType();
assert(VT.isFixedLengthVector() && "Unexpected vector!");
- // If we don't have scalar f16/bf16, we need to bitcast to an i16 vector.
- if ((VT.getVectorElementType() == MVT::f16 && !Subtarget.hasStdExtZfhmin()) ||
- (VT.getVectorElementType() == MVT::bf16 && !Subtarget.hasStdExtZfbfmin()))
- return lowerBUILD_VECTORvXf16(Op, DAG);
+ MVT EltVT = VT.getVectorElementType();
+ MVT XLenVT = Subtarget.getXLenVT();
+
+ SDLoc DL(Op);
+
+ // Proper support for f16 requires Zvfh. bf16 always requires special
+ // handling. We need to cast the scalar to integer and create an integer
+ // build_vector.
+ if ((EltVT == MVT::f16 && !Subtarget.hasStdExtZvfh()) || EltVT == MVT::bf16) {
+ MVT IVT = VT.changeVectorElementType(MVT::i16);
+ SmallVector<SDValue, 16> NewOps(Op.getNumOperands());
+ for (unsigned I = 0, E = Op.getNumOperands(); I != E; ++I) {
+ SDValue Elem = Op.getOperand(I);
+ if ((EltVT == MVT::bf16 && Subtarget.hasStdExtZfbfmin()) ||
+ (EltVT == MVT::f16 && Subtarget.hasStdExtZfhmin())) {
+ // Called by LegalizeDAG, we need to use XLenVT operations since we
+ // can't create illegal types.
+ if (auto *C = dyn_cast<ConstantFPSDNode>(Elem)) {
+ // Manually constant fold.
+ // FIXME: Add a constant fold combine for FMV_X_ANYEXTH.
----------------
topperc wrote:
I tried but it produces worse code because the fold won't happen before the integer build_vector is lowered. We need to LowerBUILD_VECTOR to see it as a vector of constants.
https://github.com/llvm/llvm-project/pull/106637
More information about the llvm-commits
mailing list