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 @@ -1031,6 +1031,7 @@ setTargetDAGCombine(ISD::ROTL); setTargetDAGCombine(ISD::ROTR); setTargetDAGCombine(ISD::ANY_EXTEND); + setTargetDAGCombine(ISD::INTRINSIC_WO_CHAIN); if (Subtarget.hasStdExtZfh()) setTargetDAGCombine(ISD::SIGN_EXTEND_INREG); if (Subtarget.hasStdExtF()) { @@ -8474,6 +8475,32 @@ break; } + case ISD::INTRINSIC_WO_CHAIN: { + unsigned IntNo = N->getConstantOperandVal(0); + switch (IntNo) { + // By default we do not combine any intrinsic. + default: + return SDValue(); + case Intrinsic::riscv_vcpop: + case Intrinsic::riscv_vcpop_mask: + case Intrinsic::riscv_vfirst: + case Intrinsic::riscv_vfirst_mask: { + SDValue VL = N->getOperand(2); + if (IntNo == Intrinsic::riscv_vcpop_mask || + IntNo == Intrinsic::riscv_vfirst_mask) + VL = N->getOperand(3); + if (!isNullConstant(VL)) + return SDValue(); + // If VL is 0, vcpop -> li 0, vfirst -> li -1. + SDLoc DL(N); + EVT VT = N->getValueType(0); + if (IntNo == Intrinsic::riscv_vfirst || + IntNo == Intrinsic::riscv_vfirst_mask) + return DAG.getConstant(-1, DL, VT); + return DAG.getConstant(0, DL, VT); + } + } + } } return SDValue(); diff --git a/llvm/test/CodeGen/RISCV/rvv/vcpop.ll b/llvm/test/CodeGen/RISCV/rvv/vcpop.ll --- a/llvm/test/CodeGen/RISCV/rvv/vcpop.ll +++ b/llvm/test/CodeGen/RISCV/rvv/vcpop.ll @@ -24,8 +24,7 @@ define iXLen @intrinsic_vcpop_m_nxv1i1_zero( %0) nounwind { ; CHECK-LABEL: intrinsic_vcpop_m_nxv1i1_zero: ; CHECK: # %bb.0: # %entry -; CHECK-NEXT: vsetivli zero, 0, e8, mf8, ta, mu -; CHECK-NEXT: vcpop.m a0, v0 +; CHECK-NEXT: li a0, 0 ; CHECK-NEXT: ret entry: %a = call iXLen @llvm.riscv.vcpop.iXLen.nxv1i1( @@ -60,10 +59,7 @@ define iXLen @intrinsic_vcpop_mask_m_nxv1i1_zero( %0, %1) nounwind { ; CHECK-LABEL: intrinsic_vcpop_mask_m_nxv1i1_zero: ; CHECK: # %bb.0: # %entry -; CHECK-NEXT: vmv1r.v v9, v0 -; CHECK-NEXT: vsetivli zero, 0, e8, mf8, ta, mu -; CHECK-NEXT: vmv1r.v v0, v8 -; CHECK-NEXT: vcpop.m a0, v9, v0.t +; CHECK-NEXT: li a0, 0 ; CHECK-NEXT: ret entry: %a = call iXLen @llvm.riscv.vcpop.mask.iXLen.nxv1i1( diff --git a/llvm/test/CodeGen/RISCV/rvv/vfirst.ll b/llvm/test/CodeGen/RISCV/rvv/vfirst.ll --- a/llvm/test/CodeGen/RISCV/rvv/vfirst.ll +++ b/llvm/test/CodeGen/RISCV/rvv/vfirst.ll @@ -24,8 +24,7 @@ define iXLen @intrinsic_vfirst_m_nxv1i1_zero( %0) nounwind { ; CHECK-LABEL: intrinsic_vfirst_m_nxv1i1_zero: ; CHECK: # %bb.0: # %entry -; CHECK-NEXT: vsetivli zero, 0, e8, mf8, ta, mu -; CHECK-NEXT: vfirst.m a0, v0 +; CHECK-NEXT: li a0, -1 ; CHECK-NEXT: ret entry: %a = call iXLen @llvm.riscv.vfirst.iXLen.nxv1i1( @@ -60,10 +59,7 @@ define iXLen @intrinsic_vfirst_mask_m_nxv1i1_zero( %0, %1) nounwind { ; CHECK-LABEL: intrinsic_vfirst_mask_m_nxv1i1_zero: ; CHECK: # %bb.0: # %entry -; CHECK-NEXT: vmv1r.v v9, v0 -; CHECK-NEXT: vsetivli zero, 0, e8, mf8, ta, mu -; CHECK-NEXT: vmv1r.v v0, v8 -; CHECK-NEXT: vfirst.m a0, v9, v0.t +; CHECK-NEXT: li a0, -1 ; CHECK-NEXT: ret entry: %a = call iXLen @llvm.riscv.vfirst.mask.iXLen.nxv1i1(