diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp @@ -1613,6 +1613,7 @@ case ISD::VSELECT: case ISD::SELECT: Res = PromoteIntOp_SELECT(N, OpNo); break; case ISD::SELECT_CC: Res = PromoteIntOp_SELECT_CC(N, OpNo); break; + case ISD::VP_SETCC: case ISD::SETCC: Res = PromoteIntOp_SETCC(N, OpNo); break; case ISD::SIGN_EXTEND: Res = PromoteIntOp_SIGN_EXTEND(N); break; case ISD::SINT_TO_FP: Res = PromoteIntOp_SINT_TO_FP(N); break; @@ -1930,7 +1931,15 @@ PromoteSetCCOperands(LHS, RHS, cast(N->getOperand(2))->get()); // The CC (#2) is always legal. - return SDValue(DAG.UpdateNodeOperands(N, LHS, RHS, N->getOperand(2)), 0); + if (N->getNumOperands() == 3) + return SDValue(DAG.UpdateNodeOperands(N, LHS, RHS, N->getOperand(2)), 0); + + assert(N->getNumOperands() == 5 && "Unexpected number of operands!"); + assert(N->getOpcode() == ISD::VP_SETCC && "Expected VP_SETCC opcode"); + + return SDValue(DAG.UpdateNodeOperands(N, LHS, RHS, N->getOperand(2), + N->getOperand(3), N->getOperand(4)), + 0); } SDValue DAGTypeLegalizer::PromoteIntOp_Shift(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,56 @@ ; 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 <8 x i1> @llvm.vp.icmp.v8i7(<8 x i7>, <8 x i7>, metadata, <8 x i1>, i32) + +define <8 x i1> @icmp_eq_vv_v8i7(<8 x i7> %va, <8 x i7> %vb, <8 x i1> %m, i32 zeroext %evl) { +; CHECK-LABEL: icmp_eq_vv_v8i7: +; CHECK: # %bb.0: +; CHECK-NEXT: li a1, 127 +; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, mu +; CHECK-NEXT: vand.vx v9, v9, a1 +; CHECK-NEXT: vand.vx v8, v8, a1 +; CHECK-NEXT: vsetvli zero, a0, e8, mf2, ta, ma +; CHECK-NEXT: vmseq.vv v0, v8, v9, v0.t +; CHECK-NEXT: ret + %v = call <8 x i1> @llvm.vp.icmp.v8i7(<8 x i7> %va, <8 x i7> %vb, metadata !"eq", <8 x i1> %m, i32 %evl) + ret <8 x i1> %v +} + +define <8 x i1> @icmp_eq_vx_v8i7(<8 x i7> %va, i7 %b, <8 x i1> %m, i32 zeroext %evl) { +; CHECK-LABEL: icmp_eq_vx_v8i7: +; CHECK: # %bb.0: +; CHECK-NEXT: li a2, 127 +; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, mu +; CHECK-NEXT: vand.vx v8, v8, a2 +; CHECK-NEXT: vmv.v.x v9, a0 +; CHECK-NEXT: vand.vx v9, v9, a2 +; CHECK-NEXT: vsetvli zero, a1, e8, mf2, ta, ma +; CHECK-NEXT: vmseq.vv v0, v8, v9, v0.t +; CHECK-NEXT: ret + %elt.head = insertelement <8 x i7> poison, i7 %b, i32 0 + %vb = shufflevector <8 x i7> %elt.head, <8 x i7> poison, <8 x i32> zeroinitializer + %v = call <8 x i1> @llvm.vp.icmp.v8i7(<8 x i7> %va, <8 x i7> %vb, metadata !"eq", <8 x i1> %m, i32 %evl) + ret <8 x i1> %v +} + +define <8 x i1> @icmp_eq_vx_swap_v8i7(<8 x i7> %va, i7 %b, <8 x i1> %m, i32 zeroext %evl) { +; CHECK-LABEL: icmp_eq_vx_swap_v8i7: +; CHECK: # %bb.0: +; CHECK-NEXT: li a2, 127 +; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, mu +; CHECK-NEXT: vand.vx v8, v8, a2 +; CHECK-NEXT: vmv.v.x v9, a0 +; CHECK-NEXT: vand.vx v9, v9, a2 +; CHECK-NEXT: vsetvli zero, a1, e8, mf2, ta, ma +; CHECK-NEXT: vmseq.vv v0, v9, v8, v0.t +; CHECK-NEXT: ret + %elt.head = insertelement <8 x i7> poison, i7 %b, i32 0 + %vb = shufflevector <8 x i7> %elt.head, <8 x i7> poison, <8 x i32> zeroinitializer + %v = call <8 x i1> @llvm.vp.icmp.v8i7(<8 x i7> %vb, <8 x i7> %va, metadata !"eq", <8 x i1> %m, i32 %evl) + ret <8 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 @@ -537,6 +537,56 @@ ret %v } +declare @llvm.vp.icmp.nxv8i7(, , metadata, , i32) + +define @icmp_eq_vv_nxv8i7( %va, %vb, %m, i32 zeroext %evl) { +; CHECK-LABEL: icmp_eq_vv_nxv8i7: +; CHECK: # %bb.0: +; CHECK-NEXT: li a1, 127 +; CHECK-NEXT: vsetvli a2, zero, e8, m1, ta, mu +; CHECK-NEXT: vand.vx v9, v9, a1 +; CHECK-NEXT: vand.vx v8, v8, a1 +; CHECK-NEXT: vsetvli zero, a0, e8, m1, ta, ma +; CHECK-NEXT: vmseq.vv v0, v8, v9, v0.t +; CHECK-NEXT: ret + %v = call @llvm.vp.icmp.nxv8i7( %va, %vb, metadata !"eq", %m, i32 %evl) + ret %v +} + +define @icmp_eq_vx_nxv8i7( %va, i7 %b, %m, i32 zeroext %evl) { +; CHECK-LABEL: icmp_eq_vx_nxv8i7: +; CHECK: # %bb.0: +; CHECK-NEXT: li a2, 127 +; CHECK-NEXT: vsetvli a3, zero, e8, m1, ta, mu +; CHECK-NEXT: vand.vx v8, v8, a2 +; CHECK-NEXT: vmv.v.x v9, a0 +; CHECK-NEXT: vand.vx v9, v9, a2 +; CHECK-NEXT: vsetvli zero, a1, e8, m1, ta, ma +; CHECK-NEXT: vmseq.vv v0, v8, v9, v0.t +; CHECK-NEXT: ret + %elt.head = insertelement poison, i7 %b, i32 0 + %vb = shufflevector %elt.head, poison, zeroinitializer + %v = call @llvm.vp.icmp.nxv8i7( %va, %vb, metadata !"eq", %m, i32 %evl) + ret %v +} + +define @icmp_eq_vx_swap_nxv8i7( %va, i7 %b, %m, i32 zeroext %evl) { +; CHECK-LABEL: icmp_eq_vx_swap_nxv8i7: +; CHECK: # %bb.0: +; CHECK-NEXT: li a2, 127 +; CHECK-NEXT: vsetvli a3, zero, e8, m1, ta, mu +; CHECK-NEXT: vand.vx v8, v8, a2 +; CHECK-NEXT: vmv.v.x v9, a0 +; CHECK-NEXT: vand.vx v9, v9, a2 +; CHECK-NEXT: vsetvli zero, a1, e8, m1, ta, ma +; CHECK-NEXT: vmseq.vv v0, v9, v8, v0.t +; CHECK-NEXT: ret + %elt.head = insertelement poison, i7 %b, i32 0 + %vb = shufflevector %elt.head, poison, zeroinitializer + %v = call @llvm.vp.icmp.nxv8i7( %vb, %va, metadata !"eq", %m, i32 %evl) + ret %v +} + declare @llvm.vp.icmp.nxv8i8(, , metadata, , i32) define @icmp_eq_vv_nxv8i8( %va, %vb, %m, i32 zeroext %evl) {