diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp @@ -3585,6 +3585,7 @@ Res = WidenVecRes_Select(N); break; case ISD::SELECT_CC: Res = WidenVecRes_SELECT_CC(N); break; + case ISD::VP_SETCC: case ISD::SETCC: Res = WidenVecRes_SETCC(N); break; case ISD::UNDEF: Res = WidenVecRes_UNDEF(N); break; case ISD::VECTOR_SHUFFLE: @@ -5248,8 +5249,17 @@ InOp2.getValueType() == WidenInVT && "Input not widened to expected type!"); (void)WidenInVT; - return DAG.getNode(ISD::SETCC, SDLoc(N), - WidenVT, InOp1, InOp2, N->getOperand(2)); + if (N->getNumOperands() == 3) + return DAG.getNode(ISD::SETCC, SDLoc(N), WidenVT, InOp1, InOp2, + N->getOperand(2)); + + assert(N->getNumOperands() == 5 && "Unexpected number of operands!"); + assert((N->getOpcode() == ISD::VP_SETCC) && "Expected VP_SETCC opcode"); + + SDValue Mask = + GetWidenedMask(N->getOperand(3), WidenVT.getVectorElementCount()); + return DAG.getNode(ISD::VP_SETCC, SDLoc(N), WidenVT, InOp1, InOp2, + N->getOperand(2), Mask, N->getOperand(4)); } SDValue DAGTypeLegalizer::WidenVecRes_STRICT_FSETCC(SDNode *N) { diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-setcc-int-vp.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-setcc-int-vp.ll --- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-setcc-int-vp.ll +++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-setcc-int-vp.ll @@ -7,6 +7,42 @@ ; FIXME: We're missing canonicalizations of ISD::VP_SETCC equivalent to those ; for ISD::SETCC, e.g., splats aren't moved to the RHS. +declare <5 x i1> @llvm.vp.icmp.v5i8(<5 x i8>, <5 x i8>, metadata, <5 x i1>, i32) + +define <5 x i1> @icmp_eq_vv_v5i8(<5 x i8> %va, <5 x i8> %vb, <5 x i1> %m, i32 zeroext %evl) { +; CHECK-LABEL: icmp_eq_vv_v5i8: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli zero, a0, e8, mf2, ta, ma +; CHECK-NEXT: vmseq.vv v0, v8, v9, v0.t +; CHECK-NEXT: ret + %v = call <5 x i1> @llvm.vp.icmp.v5i8(<5 x i8> %va, <5 x i8> %vb, metadata !"eq", <5 x i1> %m, i32 %evl) + ret <5 x i1> %v +} + +define <5 x i1> @icmp_eq_vx_v5i8(<5 x i8> %va, i8 %b, <5 x i1> %m, i32 zeroext %evl) { +; CHECK-LABEL: icmp_eq_vx_v5i8: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli zero, a1, e8, mf2, ta, ma +; CHECK-NEXT: vmseq.vx v0, v8, a0, v0.t +; CHECK-NEXT: ret + %elt.head = insertelement <5 x i8> poison, i8 %b, i32 0 + %vb = shufflevector <5 x i8> %elt.head, <5 x i8> poison, <5 x i32> zeroinitializer + %v = call <5 x i1> @llvm.vp.icmp.v5i8(<5 x i8> %va, <5 x i8> %vb, metadata !"eq", <5 x i1> %m, i32 %evl) + ret <5 x i1> %v +} + +define <5 x i1> @icmp_eq_vx_swap_v5i8(<5 x i8> %va, i8 %b, <5 x i1> %m, i32 zeroext %evl) { +; CHECK-LABEL: icmp_eq_vx_swap_v5i8: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli zero, a1, e8, mf2, ta, ma +; CHECK-NEXT: vmseq.vx v0, v8, a0, v0.t +; CHECK-NEXT: ret + %elt.head = insertelement <5 x i8> poison, i8 %b, i32 0 + %vb = shufflevector <5 x i8> %elt.head, <5 x i8> poison, <5 x i32> zeroinitializer + %v = call <5 x i1> @llvm.vp.icmp.v5i8(<5 x i8> %vb, <5 x i8> %va, metadata !"eq", <5 x i1> %m, i32 %evl) + ret <5 x i1> %v +} + declare <8 x i1> @llvm.vp.icmp.v8i8(<8 x i8>, <8 x i8>, metadata, <8 x i1>, i32) define <8 x i1> @icmp_eq_vv_v8i8(<8 x i8> %va, <8 x i8> %vb, <8 x i1> %m, i32 zeroext %evl) { diff --git a/llvm/test/CodeGen/RISCV/rvv/setcc-int-vp.ll b/llvm/test/CodeGen/RISCV/rvv/setcc-int-vp.ll --- a/llvm/test/CodeGen/RISCV/rvv/setcc-int-vp.ll +++ b/llvm/test/CodeGen/RISCV/rvv/setcc-int-vp.ll @@ -7,6 +7,42 @@ ; FIXME: We're missing canonicalizations of ISD::VP_SETCC equivalent to those ; for ISD::SETCC, e.g., splats aren't moved to the RHS. +declare @llvm.vp.icmp.nxv3i8(, , metadata, , i32) + +define @icmp_eq_vv_nxv3i8( %va, %vb, %m, i32 zeroext %evl) { +; CHECK-LABEL: icmp_eq_vv_nxv3i8: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli zero, a0, e8, mf2, ta, ma +; CHECK-NEXT: vmseq.vv v0, v8, v9, v0.t +; CHECK-NEXT: ret + %v = call @llvm.vp.icmp.nxv3i8( %va, %vb, metadata !"eq", %m, i32 %evl) + ret %v +} + +define @icmp_eq_vx_nxv3i8( %va, i8 %b, %m, i32 zeroext %evl) { +; CHECK-LABEL: icmp_eq_vx_nxv3i8: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli zero, a1, e8, mf2, ta, ma +; CHECK-NEXT: vmseq.vx v0, v8, a0, v0.t +; CHECK-NEXT: ret + %elt.head = insertelement poison, i8 %b, i32 0 + %vb = shufflevector %elt.head, poison, zeroinitializer + %v = call @llvm.vp.icmp.nxv3i8( %va, %vb, metadata !"eq", %m, i32 %evl) + ret %v +} + +define @icmp_eq_vx_swap_nxv3i8( %va, i8 %b, %m, i32 zeroext %evl) { +; CHECK-LABEL: icmp_eq_vx_swap_nxv3i8: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli zero, a1, e8, mf2, ta, ma +; CHECK-NEXT: vmseq.vx v0, v8, a0, v0.t +; CHECK-NEXT: ret + %elt.head = insertelement poison, i8 %b, i32 0 + %vb = shufflevector %elt.head, poison, zeroinitializer + %v = call @llvm.vp.icmp.nxv3i8( %vb, %va, metadata !"eq", %m, i32 %evl) + ret %v +} + declare @llvm.vp.icmp.nxv1i8(, , metadata, , i32) define @icmp_eq_vv_nxv1i8( %va, %vb, %m, i32 zeroext %evl) {