diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp --- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp @@ -942,6 +942,26 @@ // By default we do not custom select any intrinsic. default: break; + case Intrinsic::riscv_vcpop: + case Intrinsic::riscv_vcpop_mask: + case Intrinsic::riscv_vfirst: + case Intrinsic::riscv_vfirst_mask: { + SDValue VL = Node->getOperand(2); + if (IntNo == Intrinsic::riscv_vcpop_mask || + IntNo == Intrinsic::riscv_vfirst_mask) + VL = Node->getOperand(3); + auto *C = dyn_cast(VL); + if (!C || !C->isZero()) + break; + // If VL is 0, vcpop expend to li 0, vfirst expend to li -1. + SDValue Imm = CurDAG->getTargetConstant(0, DL, XLenVT); + if (IntNo == Intrinsic::riscv_vfirst || + IntNo == Intrinsic::riscv_vfirst_mask) + Imm = CurDAG->getTargetConstant(-1, DL, XLenVT); + ReplaceNode(Node, + CurDAG->getMachineNode(RISCV::PseudoLI, DL, XLenVT, Imm)); + return; + } case Intrinsic::riscv_vmsgeu: case Intrinsic::riscv_vmsge: { SDValue Src1 = Node->getOperand(1); 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(