[llvm] [RISCV][llvm] Support [s|u]int_to_fp and fp_to_[s|u]int for zvfbfa (PR #192287)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 15 09:49:18 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-risc-v
Author: Brandon Wu (4vtomat)
<details>
<summary>Changes</summary>
---
Patch is 222.60 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/192287.diff
13 Files Affected:
- (modified) llvm/lib/Target/RISCV/RISCVISelLowering.cpp (+17-5)
- (modified) llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td (+29-18)
- (modified) llvm/lib/Target/RISCV/RISCVInstrInfoVSDPatterns.td (+10-8)
- (modified) llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td (+15-12)
- (modified) llvm/lib/Target/RISCV/RISCVInstrInfoZvfofp8min.td (-9)
- (modified) llvm/test/CodeGen/RISCV/rvv/fixed-vectors-fp2i.ll (+201-73)
- (modified) llvm/test/CodeGen/RISCV/rvv/fixed-vectors-i2fp.ll (+433-109)
- (modified) llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vfptoi-constrained-sdnode.ll (+68-2)
- (modified) llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vitofp-constrained-sdnode.ll (+68-2)
- (modified) llvm/test/CodeGen/RISCV/rvv/vfptoi-constrained-sdnode.ll (+114-2)
- (modified) llvm/test/CodeGen/RISCV/rvv/vfptoi-sdnode.ll (+862-474)
- (modified) llvm/test/CodeGen/RISCV/rvv/vitofp-constrained-sdnode.ll (+114-2)
- (modified) llvm/test/CodeGen/RISCV/rvv/vitofp-sdnode.ll (+878-476)
``````````diff
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 1148b801530a0..91d807d98e86f 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -8044,11 +8044,16 @@ SDValue RISCVTargetLowering::LowerOperation(SDValue Op,
return lowerStrictFPExtendOrRoundLike(Op, DAG);
case ISD::SINT_TO_FP:
case ISD::UINT_TO_FP:
- if (Op.getValueType().isVector() &&
+ // Fall back to zvfbfmin for bf16 case if source type is wider than 8 bits.
+ if (SDValue Op1 = Op.getOperand(0);
+ Op.getValueType().isVector() &&
((Op.getValueType().getScalarType() == MVT::f16 &&
(Subtarget.hasVInstructionsF16Minimal() &&
!Subtarget.hasVInstructionsF16())) ||
- Op.getValueType().getScalarType() == MVT::bf16)) {
+ (Op.getValueType().getScalarType() == MVT::bf16 &&
+ (Subtarget.hasVInstructionsBF16Minimal() &&
+ (!Subtarget.hasVInstructionsBF16() ||
+ Op1.getValueType().getScalarSizeInBits() > 8))))) {
MVT NVT =
MVT::getVectorVT(MVT::f32, Op.getValueType().getVectorElementCount());
if (!isTypeLegal(NVT))
@@ -8063,12 +8068,17 @@ SDValue RISCVTargetLowering::LowerOperation(SDValue Op,
[[fallthrough]];
case ISD::FP_TO_SINT:
case ISD::FP_TO_UINT:
+ // Fall back to zvfbfmin for bf16 case if destination type is wider than 8
+ // bits.
if (SDValue Op1 = Op.getOperand(0);
Op1.getValueType().isVector() &&
((Op1.getValueType().getScalarType() == MVT::f16 &&
(Subtarget.hasVInstructionsF16Minimal() &&
!Subtarget.hasVInstructionsF16())) ||
- Op1.getValueType().getScalarType() == MVT::bf16)) {
+ (Op1.getValueType().getScalarType() == MVT::bf16 &&
+ (Subtarget.hasVInstructionsBF16Minimal() &&
+ (!Subtarget.hasVInstructionsBF16() ||
+ Op.getValueType().getScalarSizeInBits() > 8))))) {
MVT NVT = MVT::getVectorVT(MVT::f32,
Op1.getValueType().getVectorElementCount());
if (!isTypeLegal(NVT))
@@ -8123,7 +8133,8 @@ SDValue RISCVTargetLowering::LowerOperation(SDValue Op,
return DAG.getNode(Op.getOpcode(), DL, VT, Ext);
}
// FP2Int
- assert(SrcEltVT == MVT::f16 && "Unexpected FP_TO_[US]INT lowering");
+ assert((SrcEltVT == MVT::f16 || SrcEltVT == MVT::bf16) &&
+ "Unexpected FP_TO_[US]INT lowering");
// Do one doubling fp_extend then complete the operation by converting
// to int.
MVT InterimFVT = MVT::getVectorVT(MVT::f32, VT.getVectorElementCount());
@@ -8140,7 +8151,8 @@ SDValue RISCVTargetLowering::LowerOperation(SDValue Op,
if (SrcEltSize > (2 * EltSize)) {
if (IsInt2FP) {
// One narrowing int_to_fp, then an fp_round.
- assert(EltVT == MVT::f16 && "Unexpected [US]_TO_FP lowering");
+ assert((EltVT == MVT::f16 || EltVT == MVT::bf16) &&
+ "Unexpected [US]_TO_FP lowering");
MVT InterimFVT = MVT::getVectorVT(MVT::f32, VT.getVectorElementCount());
if (IsStrict) {
SDValue Int2FP = DAG.getNode(Op.getOpcode(), DL,
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td b/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td
index a5b3b1d3f940b..9f041a9f00444 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td
@@ -538,24 +538,35 @@ defset list<VTypeInfoToFraction> AllFractionableVF8IntVectors = {
def : VTypeInfoToFraction<VI64M8, VI8M1>;
}
-defset list<VTypeInfoToWide> AllWidenableIntToFloatVectors = {
- def : VTypeInfoToWide<VI8MF8, VF16MF4>;
- def : VTypeInfoToWide<VI8MF4, VF16MF2>;
- def : VTypeInfoToWide<VI8MF2, VF16M1>;
- def : VTypeInfoToWide<VI8M1, VF16M2>;
- def : VTypeInfoToWide<VI8M2, VF16M4>;
- def : VTypeInfoToWide<VI8M4, VF16M8>;
-
- def : VTypeInfoToWide<VI16MF4, VF32MF2>;
- def : VTypeInfoToWide<VI16MF2, VF32M1>;
- def : VTypeInfoToWide<VI16M1, VF32M2>;
- def : VTypeInfoToWide<VI16M2, VF32M4>;
- def : VTypeInfoToWide<VI16M4, VF32M8>;
-
- def : VTypeInfoToWide<VI32MF2, VF64M1>;
- def : VTypeInfoToWide<VI32M1, VF64M2>;
- def : VTypeInfoToWide<VI32M2, VF64M4>;
- def : VTypeInfoToWide<VI32M4, VF64M8>;
+defset list<VTypeInfoToWide> AllWidenableIntToFloatAndBF16Vectors = {
+ defset list<VTypeInfoToWide> AllWidenableIntToFloatVectors = {
+ def : VTypeInfoToWide<VI8MF8, VF16MF4>;
+ def : VTypeInfoToWide<VI8MF4, VF16MF2>;
+ def : VTypeInfoToWide<VI8MF2, VF16M1>;
+ def : VTypeInfoToWide<VI8M1, VF16M2>;
+ def : VTypeInfoToWide<VI8M2, VF16M4>;
+ def : VTypeInfoToWide<VI8M4, VF16M8>;
+
+ def : VTypeInfoToWide<VI16MF4, VF32MF2>;
+ def : VTypeInfoToWide<VI16MF2, VF32M1>;
+ def : VTypeInfoToWide<VI16M1, VF32M2>;
+ def : VTypeInfoToWide<VI16M2, VF32M4>;
+ def : VTypeInfoToWide<VI16M4, VF32M8>;
+
+ def : VTypeInfoToWide<VI32MF2, VF64M1>;
+ def : VTypeInfoToWide<VI32M1, VF64M2>;
+ def : VTypeInfoToWide<VI32M2, VF64M4>;
+ def : VTypeInfoToWide<VI32M4, VF64M8>;
+ }
+
+ defset list<VTypeInfoToWide> AllWidenableIntToBFloatVectors = {
+ def : VTypeInfoToWide<VI8MF8, VBF16MF4>;
+ def : VTypeInfoToWide<VI8MF4, VBF16MF2>;
+ def : VTypeInfoToWide<VI8MF2, VBF16M1>;
+ def : VTypeInfoToWide<VI8M1, VBF16M2>;
+ def : VTypeInfoToWide<VI8M2, VBF16M4>;
+ def : VTypeInfoToWide<VI8M4, VBF16M8>;
+ }
}
// This class holds the record of the RISCVVPseudoTable below.
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoVSDPatterns.td b/llvm/lib/Target/RISCV/RISCVInstrInfoVSDPatterns.td
index 4c558c4524c5b..97d2e664db6b7 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoVSDPatterns.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoVSDPatterns.td
@@ -416,13 +416,14 @@ multiclass VPatConvertFP2ISDNode_V<SDPatternOperator vop,
multiclass VPatWConvertI2FPSDNode_V<SDPatternOperator vop,
string instruction_name> {
- foreach vtiToWti = AllWidenableIntToFloatVectors in {
+ foreach vtiToWti = AllWidenableIntToFloatAndBF16Vectors in {
defvar ivti = vtiToWti.Vti;
defvar fwti = vtiToWti.Wti;
+ defvar alt = !if(!eq(fwti.Scalar, bf16), "_ALT", "");
let Predicates = !listconcat(GetVTypePredicates<ivti>.Predicates,
GetVTypePredicates<fwti>.Predicates) in
def : Pat<(fwti.Vector (vop (ivti.Vector ivti.RegClass:$rs1))),
- (!cast<Instruction>(instruction_name#"_"#ivti.LMul.MX#"_E"#ivti.SEW)
+ (!cast<Instruction>(instruction_name#alt#"_V_"#ivti.LMul.MX#"_E"#ivti.SEW)
(fwti.Vector (IMPLICIT_DEF)),
ivti.RegClass:$rs1,
ivti.AVL, ivti.Log2SEW, TA_MA)>;
@@ -463,13 +464,14 @@ multiclass VPatNConvertI2FPSDNode_W_RM<SDPatternOperator vop,
multiclass VPatNConvertFP2ISDNode_W<SDPatternOperator vop,
string instruction_name> {
- foreach vtiToWti = AllWidenableIntToFloatVectors in {
+ foreach vtiToWti = AllWidenableIntToFloatAndBF16Vectors in {
defvar vti = vtiToWti.Vti;
defvar fwti = vtiToWti.Wti;
+ defvar alt = !if(!eq(fwti.Scalar, bf16), "_ALT", "");
let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates,
GetVTypePredicates<fwti>.Predicates) in
def : Pat<(vti.Vector (vop (fwti.Vector fwti.RegClass:$rs1))),
- (!cast<Instruction>(instruction_name#"_"#vti.LMul.MX)
+ (!cast<Instruction>(instruction_name#alt#"_W_"#vti.LMul.MX)
(vti.Vector (IMPLICIT_DEF)),
fwti.RegClass:$rs1, vti.AVL, vti.Log2SEW, TA_MA)>;
}
@@ -1508,12 +1510,12 @@ defm : VPatConvertI2FPSDNode_V_RM<any_uint_to_fp, "PseudoVFCVT_F_XU_V">;
// 13.18. Widening Floating-Point/Integer Type-Convert Instructions
defm : VPatWConvertFP2ISDNode_V<any_fp_to_sint, "PseudoVFWCVT_RTZ_X_F_V">;
defm : VPatWConvertFP2ISDNode_V<any_fp_to_uint, "PseudoVFWCVT_RTZ_XU_F_V">;
-defm : VPatWConvertI2FPSDNode_V<any_sint_to_fp, "PseudoVFWCVT_F_X_V">;
-defm : VPatWConvertI2FPSDNode_V<any_uint_to_fp, "PseudoVFWCVT_F_XU_V">;
+defm : VPatWConvertI2FPSDNode_V<any_sint_to_fp, "PseudoVFWCVT_F_X">;
+defm : VPatWConvertI2FPSDNode_V<any_uint_to_fp, "PseudoVFWCVT_F_XU">;
// 13.19. Narrowing Floating-Point/Integer Type-Convert Instructions
-defm : VPatNConvertFP2ISDNode_W<any_fp_to_sint, "PseudoVFNCVT_RTZ_X_F_W">;
-defm : VPatNConvertFP2ISDNode_W<any_fp_to_uint, "PseudoVFNCVT_RTZ_XU_F_W">;
+defm : VPatNConvertFP2ISDNode_W<any_fp_to_sint, "PseudoVFNCVT_RTZ_X_F">;
+defm : VPatNConvertFP2ISDNode_W<any_fp_to_uint, "PseudoVFNCVT_RTZ_XU_F">;
defm : VPatNConvertI2FPSDNode_W_RM<any_sint_to_fp, "PseudoVFNCVT_F_X_W">;
defm : VPatNConvertI2FPSDNode_W_RM<any_uint_to_fp, "PseudoVFNCVT_F_XU_W">;
foreach fvtiToFWti = AllWidenableFloatAndBF16Vectors in {
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td b/llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td
index 2a99492bc5596..56d817ea637d9 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td
@@ -1374,15 +1374,16 @@ multiclass VPatWConvertFP2I_RM_VL_V<SDNode vop, string instruction_name> {
multiclass VPatWConvertI2FPVL_V<SDPatternOperator vop,
string instruction_name> {
- foreach vtiToWti = AllWidenableIntToFloatVectors in {
+ foreach vtiToWti = AllWidenableIntToFloatAndBF16Vectors in {
defvar ivti = vtiToWti.Vti;
defvar fwti = vtiToWti.Wti;
+ defvar alt = !if(!eq(fwti.Scalar, bf16), "_ALT", "");
let Predicates = !listconcat(GetVTypePredicates<ivti>.Predicates,
GetVTypePredicates<fwti>.Predicates) in
def : Pat<(fwti.Vector (vop (ivti.Vector ivti.RegClass:$rs1),
(ivti.Mask VMV0:$vm),
VLOpFrag)),
- (!cast<Instruction>(instruction_name#"_"#ivti.LMul.MX#"_E"#ivti.SEW#"_MASK")
+ (!cast<Instruction>(instruction_name#alt#"_V_"#ivti.LMul.MX#"_E"#ivti.SEW#"_MASK")
(fwti.Vector (IMPLICIT_DEF)), ivti.RegClass:$rs1,
(ivti.Mask VMV0:$vm),
GPR:$vl, ivti.Log2SEW, TA_MA)>;
@@ -1395,30 +1396,32 @@ multiclass VPatNConvertFP2IVL_W<SDPatternOperator vop,
string instruction_name> {
// Reuse the same list of types used in the widening nodes, but just swap the
// direction of types around so we're converting from Wti -> Vti
- foreach vtiToWti = AllWidenableIntToFloatVectors in {
+ foreach vtiToWti = AllWidenableIntToFloatAndBF16Vectors in {
defvar vti = vtiToWti.Vti;
defvar fwti = vtiToWti.Wti;
+ defvar alt = !if(!eq(fwti.Scalar, bf16), "_ALT", "");
let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates,
GetVTypePredicates<fwti>.Predicates) in
def : Pat<(vti.Vector (vop (fwti.Vector fwti.RegClass:$rs1),
(fwti.Mask VMV0:$vm),
VLOpFrag)),
- (!cast<Instruction>(instruction_name#"_"#vti.LMul.MX#"_MASK")
+ (!cast<Instruction>(instruction_name#alt#"_W_"#vti.LMul.MX#"_MASK")
(vti.Vector (IMPLICIT_DEF)), fwti.RegClass:$rs1,
(fwti.Mask VMV0:$vm), GPR:$vl, vti.Log2SEW, TA_MA)>;
}
}
multiclass VPatNConvertFP2I_RM_VL_W<SDNode vop, string instruction_name> {
- foreach vtiToWti = AllWidenableIntToFloatVectors in {
+ foreach vtiToWti = AllWidenableIntToFloatAndBF16Vectors in {
defvar vti = vtiToWti.Vti;
defvar fwti = vtiToWti.Wti;
+ defvar alt = !if(!eq(fwti.Scalar, bf16), "_ALT", "");
let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates,
GetVTypePredicates<fwti>.Predicates) in
def : Pat<(vti.Vector (vop (fwti.Vector fwti.RegClass:$rs1),
(fwti.Mask VMV0:$vm), (XLenVT timm:$frm),
VLOpFrag)),
- (!cast<Instruction>(instruction_name#"_"#vti.LMul.MX#"_MASK")
+ (!cast<Instruction>(instruction_name#alt#"_W_"#vti.LMul.MX#"_MASK")
(vti.Vector (IMPLICIT_DEF)), fwti.RegClass:$rs1,
(fwti.Mask VMV0:$vm), timm:$frm, GPR:$vl, vti.Log2SEW, TA_MA)>;
}
@@ -2686,8 +2689,8 @@ defm : VPatWConvertFP2I_RM_VL_V<riscv_vfcvt_rm_x_f_vl, "PseudoVFWCVT_X_F_V">;
defm : VPatWConvertFP2IVL_V<any_riscv_vfcvt_rtz_xu_f_vl, "PseudoVFWCVT_RTZ_XU_F_V">;
defm : VPatWConvertFP2IVL_V<any_riscv_vfcvt_rtz_x_f_vl, "PseudoVFWCVT_RTZ_X_F_V">;
-defm : VPatWConvertI2FPVL_V<any_riscv_uint_to_fp_vl, "PseudoVFWCVT_F_XU_V">;
-defm : VPatWConvertI2FPVL_V<any_riscv_sint_to_fp_vl, "PseudoVFWCVT_F_X_V">;
+defm : VPatWConvertI2FPVL_V<any_riscv_uint_to_fp_vl, "PseudoVFWCVT_F_XU">;
+defm : VPatWConvertI2FPVL_V<any_riscv_sint_to_fp_vl, "PseudoVFWCVT_F_X">;
foreach fvtiToFWti = AllWidenableFloatAndBF16Vectors in {
defvar fvti = fvtiToFWti.Vti;
@@ -2724,11 +2727,11 @@ foreach fvtiToFWti = AllWidenableFloatAndBF16Vectors in {
}
// 13.19 Narrowing Floating-Point/Integer Type-Convert Instructions
-defm : VPatNConvertFP2I_RM_VL_W<riscv_vfcvt_rm_xu_f_vl, "PseudoVFNCVT_XU_F_W">;
-defm : VPatNConvertFP2I_RM_VL_W<riscv_vfcvt_rm_x_f_vl, "PseudoVFNCVT_X_F_W">;
+defm : VPatNConvertFP2I_RM_VL_W<riscv_vfcvt_rm_xu_f_vl, "PseudoVFNCVT_XU_F">;
+defm : VPatNConvertFP2I_RM_VL_W<riscv_vfcvt_rm_x_f_vl, "PseudoVFNCVT_X_F">;
-defm : VPatNConvertFP2IVL_W<any_riscv_vfcvt_rtz_xu_f_vl, "PseudoVFNCVT_RTZ_XU_F_W">;
-defm : VPatNConvertFP2IVL_W<any_riscv_vfcvt_rtz_x_f_vl, "PseudoVFNCVT_RTZ_X_F_W">;
+defm : VPatNConvertFP2IVL_W<any_riscv_vfcvt_rtz_xu_f_vl, "PseudoVFNCVT_RTZ_XU_F">;
+defm : VPatNConvertFP2IVL_W<any_riscv_vfcvt_rtz_x_f_vl, "PseudoVFNCVT_RTZ_X_F">;
defm : VPatNConvertI2FPVL_W_RM<any_riscv_uint_to_fp_vl, "PseudoVFNCVT_F_XU_W">;
defm : VPatNConvertI2FPVL_W_RM<any_riscv_sint_to_fp_vl, "PseudoVFNCVT_F_X_W">;
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZvfofp8min.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZvfofp8min.td
index 094fb31550637..bc2e4ab0aa8c9 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoZvfofp8min.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZvfofp8min.td
@@ -30,15 +30,6 @@ let Predicates = [HasStdExtZvfofp8min], Constraints = "@earlyclobber $vd",
//===----------------------------------------------------------------------===//
defvar MxListQ = [V_MF8, V_MF4, V_MF2, V_M1, V_M2];
-defset list<VTypeInfoToWide> AllWidenableIntToBFloatVectors = {
- def : VTypeInfoToWide<VI8MF8, VBF16MF4>;
- def : VTypeInfoToWide<VI8MF4, VBF16MF2>;
- def : VTypeInfoToWide<VI8MF2, VBF16M1>;
- def : VTypeInfoToWide<VI8M1, VBF16M2>;
- def : VTypeInfoToWide<VI8M2, VBF16M4>;
- def : VTypeInfoToWide<VI8M4, VBF16M8>;
-}
-
defset list<VTypeInfoToWide> AllWidenableInt8ToFloat32Vectors = {
def : VTypeInfoToWide<VI8MF8, VF32MF2>;
def : VTypeInfoToWide<VI8MF4, VF32M1>;
diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-fp2i.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-fp2i.ll
index e9357b629628c..350de6c52a775 100644
--- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-fp2i.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-fp2i.ll
@@ -1,8 +1,10 @@
-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
-; RUN: llc -mtriple=riscv32 -target-abi=ilp32d -mattr=+v,+zvfh,+zvfbfmin,+f,+d -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFH,ZVFH32
-; RUN: llc -mtriple=riscv64 -target-abi=lp64d -mattr=+v,+zvfh,+zvfbfmin,+f,+d -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFH,ZVFH64
-; RUN: llc -mtriple=riscv32 -target-abi=ilp32d -mattr=+v,+zvfhmin,+zvfbfmin,+f,+d -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFHMIN,ZVFHMIN32
-; RUN: llc -mtriple=riscv64 -target-abi=lp64d -mattr=+v,+zvfhmin,+zvfbfmin,+f,+d -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFHMIN,ZVFHMIN64
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc -mtriple=riscv32 -target-abi=ilp32d -mattr=+v,+zvfh,+zvfbfmin,+f,+d -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFH,ZVFH32,ZVFBFMIN
+; RUN: llc -mtriple=riscv64 -target-abi=lp64d -mattr=+v,+zvfh,+zvfbfmin,+f,+d -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFH,ZVFH64,ZVFBFMIN
+; RUN: llc -mtriple=riscv32 -target-abi=ilp32d -mattr=+v,+zvfhmin,+zvfbfmin,+f,+d -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFHMIN,ZVFHMIN32,ZVFBFMIN
+; RUN: llc -mtriple=riscv64 -target-abi=lp64d -mattr=+v,+zvfhmin,+zvfbfmin,+f,+d -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFHMIN,ZVFHMIN64,ZVFBFMIN
+; RUN: llc -mtriple=riscv32 -target-abi=ilp32d -mattr=+v,+zvfh,+experimental-zvfbfa,+f,+d -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFH,ZVFH32,ZVFBFA
+; RUN: llc -mtriple=riscv64 -target-abi=lp64d -mattr=+v,+zvfh,+experimental-zvfbfa,+f,+d -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,ZVFH,ZVFH64,ZVFBFA
define void @fp2si_v2f32_v2i32(ptr %x, ptr %y) {
; CHECK-LABEL: fp2si_v2f32_v2i32:
@@ -419,15 +421,25 @@ define void @fp2ui_v8f32_v8i64(ptr %x, ptr %y) {
}
define void @fp2si_v2bf16_v2i64(ptr %x, ptr %y) {
-; CHECK-LABEL: fp2si_v2bf16_v2i64:
-; CHECK: # %bb.0:
-; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma
-; CHECK-NEXT: vle16.v v8, (a0)
-; CHECK-NEXT: vfwcvtbf16.f.f.v v9, v8
-; CHECK-NEXT: vsetvli zero, zero, e32, mf2, ta, ma
-; CHECK-NEXT: vfwcvt.rtz.x.f.v v8, v9
-; CHECK-NEXT: vse64.v v8, (a1)
-; CHECK-NEXT: ret
+; ZVFBFMIN-LABEL: fp2si_v2bf16_v2i64:
+; ZVFBFMIN: # %bb.0:
+; ZVFBFMIN-NEXT: vsetivli zero, 2, e16, mf4, ta, ma
+; ZVFBFMIN-NEXT: vle16.v v8, (a0)
+; ZVFBFMIN-NEXT: vfwcvtbf16.f.f.v v9, v8
+; ZVFBFMIN-NEXT: vsetvli zero, zero, e32, mf2, ta, ma
+; ZVFBFMIN-NEXT: vfwcvt.rtz.x.f.v v8, v9
+; ZVFBFMIN-NEXT: vse64.v v8, (a1)
+; ZVFBFMIN-NEXT: ret
+;
+; ZVFBFA-LABEL: fp2si_v2bf16_v2i64:
+; ZVFBFA: # %bb.0:
+; ZVFBFA-NEXT: vsetivli zero, 2, e16alt, mf4, ta, ma
+; ZVFBFA-NEXT: vle16.v v8, (a0)
+; ZVFBFA-NEXT: vfwcvt.f.f.v v9, v8
+; ZVFBFA-NEXT: vsetvli zero, zero, e32, mf2, ta, ma
+; ZVFBFA-NEXT: vfwcvt.rtz.x.f.v v8, v9
+; ZVFBFA-NEXT: vse64.v v8, (a1)
+; ZVFBFA-NEXT: ret
%a = load <2 x bfloat>, ptr %x
%d = fptosi <2 x bfloat> %a to <2 x i64>
store <2 x i64> %d, ptr %y
@@ -435,15 +447,25 @@ define void @fp2si_v2bf16_v2i64(ptr %x, ptr %y) {
}
define void @fp2ui_v2bf16_v2i64(ptr %x, ptr %y) {
-; CHECK-LABEL: fp2ui_v2bf16_v2i64:
-; CHECK: # %bb.0:
-; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma
-; CHECK-NEXT: vle16.v v8, (a0)
-; CHECK-NEXT: vfwcvtbf16.f.f.v v9, v8
-; CHECK-NEXT: vsetvli zero, zero, e32, mf2, ta, ma
-; CHECK-NEXT: vfwcvt.rtz.xu.f.v v8, v9
-; CHECK-NEXT: vse64.v v8, (a1)
-; CHECK-NEXT: ret
+; ZVFBFMIN-LABEL: fp2ui_v2bf16_v2i64:
+; ZVFBFMIN: # %bb.0:
+; ZVFBFMIN-NEXT: vsetivli zero, 2, e16, mf4, ta, ma
+; ZVFBFMIN-NEXT: vle16.v v8, (a0)
+; ZVFBFMIN-NEXT: vfwcvtbf16.f.f.v v9, v8
+; ZVFBFMIN-NEXT: vsetvli zero, zero, e32, mf2, ta, ma
+; ZVFBFMIN-NEXT: vfwcvt.rtz.xu.f.v v8, v9
+; ZVFBFMIN-NEXT: vse64.v v8, (a1)
+; ZVFBFMIN-NEXT: ret
+;
+; ZVFBFA-LABEL: fp2ui_v2bf16_v2i64:
+; ZVFBFA: # %bb.0:
+; ZVFBFA-NEXT: vsetivli zero, 2, e16alt, mf4, ta, ma
+; ZVFBFA-NEXT: vle16.v v8, (a0)
+; ZVFBFA-NEXT: vfwcvt.f.f.v v9, v8
+; ZVFBFA-NEXT: vsetvli zero, zero, e32, mf2, ta, ma
+; ZVFBFA-NEXT: vfwcvt.rtz.xu.f.v v8, v9
+; ZVFBFA-NEXT: vse64.v v8, (a1)
+; ZVFBFA-NEXT: ret
%a = load <2 x bfloat>, ptr %x
%d = fptoui <2 x bfloat> %a to <2 x i64>
store <2 x i64> %d, ptr %y
@@ -451,48 +473,83 @@ define void @fp2ui_v2bf16_v2i64(ptr %x, ptr %y) {
}
define <2 x i1> @fp2si_v2bf16_v2i1(<2 x bfloat> %x) {
-; CHECK-LABEL: fp2si_v2bf16_v2i1:
-; CHECK: # %bb.0:
-; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma
-; CHECK-NEXT: vfwcvtbf16.f.f.v v9, v8
-; CHECK-NEXT: vfncvt.rtz.x.f.w v8, v9
-; CHECK-NEXT: vmsne.vi v0, v8, 0
-; CHECK-NEXT: ret
+; ZVFBFMIN-LABEL: fp2si_v2bf16_v2i1:
+; ZVFBFMIN: # %bb.0:
+; ZVFBFMIN-NEXT: vsetivli zero, 2, e16, mf4, ta, ma
+; ZVFBFMIN-NEXT: vfwcvtbf16.f.f.v v9, v8
+; ZVF...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/192287
More information about the llvm-commits
mailing list