diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -4435,6 +4435,8 @@ if (Check & fcNegZero) TDCMask |= RISCV::FPMASK_Negative_Zero; + bool IsOneBitMask = isPowerOf2_32(TDCMask); + SDValue TDCMaskV = DAG.getConstant(TDCMask, DL, XLenVT); if (VT.isVector()) { @@ -4446,6 +4448,10 @@ auto [Mask, VL] = getDefaultScalableVLOps(VT0, DL, DAG, Subtarget); SDValue FPCLASS = DAG.getNode(RISCVISD::FCLASS_VL, DL, DstVT, Op0, Mask, VL, Op->getFlags()); + if (IsOneBitMask) + return DAG.getSetCC(DL, VT, FPCLASS, + DAG.getConstant(TDCMask, DL, DstVT), + ISD::CondCode::SETEQ); SDValue AND = DAG.getNode(ISD::AND, DL, DstVT, FPCLASS, DAG.getConstant(TDCMask, DL, DstVT)); return DAG.getSetCC(DL, VT, AND, DAG.getConstant(0, DL, DstVT), @@ -4464,6 +4470,13 @@ TDCMaskV = DAG.getNode(RISCVISD::VMV_V_X_VL, DL, ContainerDstVT, DAG.getUNDEF(ContainerDstVT), TDCMaskV, VL); + if (IsOneBitMask) { + SDValue VMSEQ = + DAG.getNode(RISCVISD::SETCC_VL, DL, ContainerVT, + {FPCLASS, TDCMaskV, DAG.getCondCode(ISD::SETEQ), + DAG.getUNDEF(ContainerVT), Mask, VL}); + return convertFromScalableVector(VT, VMSEQ, DAG, Subtarget); + } SDValue AND = DAG.getNode(RISCVISD::AND_VL, DL, ContainerDstVT, FPCLASS, TDCMaskV, DAG.getUNDEF(ContainerDstVT), Mask, VL); diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vfclass.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vfclass.ll --- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vfclass.ll +++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vfclass.ll @@ -50,8 +50,7 @@ ; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, ma ; CHECK-NEXT: vfclass.v v8, v8 ; CHECK-NEXT: li a0, 512 -; CHECK-NEXT: vand.vx v8, v8, a0 -; CHECK-NEXT: vmsne.vi v0, v8, 0 +; CHECK-NEXT: vmseq.vx v0, v8, a0 ; CHECK-NEXT: ret %1 = call <8 x i1> @llvm.is.fpclass.v8f32(<8 x float> %x, i32 2) ret <8 x i1> %1 @@ -63,8 +62,7 @@ ; CHECK-NEXT: vsetivli zero, 16, e32, m4, ta, ma ; CHECK-NEXT: vfclass.v v8, v8 ; CHECK-NEXT: li a0, 256 -; CHECK-NEXT: vand.vx v8, v8, a0 -; CHECK-NEXT: vmsne.vi v0, v8, 0 +; CHECK-NEXT: vmseq.vx v0, v8, a0 ; CHECK-NEXT: ret %1 = call <16 x i1> @llvm.is.fpclass.v16f32(<16 x float> %x, i32 1) ret <16 x i1> %1 @@ -89,8 +87,7 @@ ; CHECK-NEXT: vsetivli zero, 4, e64, m2, ta, ma ; CHECK-NEXT: vfclass.v v8, v8 ; CHECK-NEXT: li a0, 128 -; CHECK-NEXT: vand.vx v8, v8, a0 -; CHECK-NEXT: vmsne.vi v0, v8, 0 +; CHECK-NEXT: vmseq.vx v0, v8, a0 ; CHECK-NEXT: ret %1 = call <4 x i1> @llvm.is.fpclass.v4f64(<4 x double> %x, i32 512) ; 0x200 = "+inf" ret <4 x i1> %1 @@ -101,8 +98,7 @@ ; CHECK: # %bb.0: ; CHECK-NEXT: vsetivli zero, 8, e64, m4, ta, ma ; CHECK-NEXT: vfclass.v v8, v8 -; CHECK-NEXT: vand.vi v8, v8, 1 -; CHECK-NEXT: vmsne.vi v0, v8, 0 +; CHECK-NEXT: vmseq.vi v0, v8, 1 ; CHECK-NEXT: ret %1 = call <8 x i1> @llvm.is.fpclass.v8f64(<8 x double> %x, i32 4) ; "-inf" ret <8 x i1> %1 diff --git a/llvm/test/CodeGen/RISCV/rvv/vfclass-sdnode.ll b/llvm/test/CodeGen/RISCV/rvv/vfclass-sdnode.ll --- a/llvm/test/CodeGen/RISCV/rvv/vfclass-sdnode.ll +++ b/llvm/test/CodeGen/RISCV/rvv/vfclass-sdnode.ll @@ -50,8 +50,7 @@ ; CHECK-NEXT: vsetvli a0, zero, e32, m4, ta, ma ; CHECK-NEXT: vfclass.v v8, v8 ; CHECK-NEXT: li a0, 512 -; CHECK-NEXT: vand.vx v8, v8, a0 -; CHECK-NEXT: vmsne.vi v0, v8, 0 +; CHECK-NEXT: vmseq.vx v0, v8, a0 ; CHECK-NEXT: ret %1 = call @llvm.is.fpclass.nxv8f32( %x, i32 2) ret %1 @@ -63,8 +62,7 @@ ; CHECK-NEXT: vsetvli a0, zero, e32, m8, ta, ma ; CHECK-NEXT: vfclass.v v8, v8 ; CHECK-NEXT: li a0, 256 -; CHECK-NEXT: vand.vx v8, v8, a0 -; CHECK-NEXT: vmsne.vi v0, v8, 0 +; CHECK-NEXT: vmseq.vx v0, v8, a0 ; CHECK-NEXT: ret %1 = call @llvm.is.fpclass.nxv16f32( %x, i32 1) ret %1 @@ -89,8 +87,7 @@ ; CHECK-NEXT: vsetvli a0, zero, e64, m4, ta, ma ; CHECK-NEXT: vfclass.v v8, v8 ; CHECK-NEXT: li a0, 128 -; CHECK-NEXT: vand.vx v8, v8, a0 -; CHECK-NEXT: vmsne.vi v0, v8, 0 +; CHECK-NEXT: vmseq.vx v0, v8, a0 ; CHECK-NEXT: ret %1 = call @llvm.is.fpclass.nxv4f64( %x, i32 512) ; 0x200 = "+inf" ret %1 @@ -101,8 +98,7 @@ ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a0, zero, e64, m8, ta, ma ; CHECK-NEXT: vfclass.v v8, v8 -; CHECK-NEXT: vand.vi v8, v8, 1 -; CHECK-NEXT: vmsne.vi v0, v8, 0 +; CHECK-NEXT: vmseq.vi v0, v8, 1 ; CHECK-NEXT: ret %1 = call @llvm.is.fpclass.nxv8f64( %x, i32 4) ; "-inf" ret %1