diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index fef9084bd0e73..e5843477e04e5 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -19709,6 +19709,19 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N, if (SDValue V = combineToVCPOP(N, DAG, Subtarget)) return V; break; + case RISCVISD::VRGATHER_VX_VL: { + // Drop a redundant vrgather_vx. + // Note this assumes that out of bounds indices produce poison + // and can thus be replaced without having to prove them inbounds.. + SDValue Src = N->getOperand(0); + SDValue Passthru = N->getOperand(2); + SDValue VL = N->getOperand(4); + // TODO: Handle fmv.v.f? + if (Src.getOpcode() == RISCVISD::VMV_V_X_VL && Passthru.isUndef() && + VL == Src.getOperand(2)) + return Src; + break; + } } return SDValue(); diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.h b/llvm/lib/Target/RISCV/RISCVISelLowering.h index 5ebdbbd51f2b1..d624ee33d6a63 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.h +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.h @@ -388,7 +388,8 @@ enum NodeType : unsigned { VMSET_VL, // Matches the semantics of vrgather.vx and vrgather.vv with extra operands - // for passthru and VL. Operands are (src, index, mask, passthru, vl). + // for passthru and VL, except that out of bound indices result in a poison + // result not zero. Operands are (src, index, mask, passthru, vl). VRGATHER_VX_VL, VRGATHER_VV_VL, VRGATHEREI16_VV_VL, diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-int.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-int.ll index e6375e276d37f..185b8b6d03134 100644 --- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-int.ll +++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-int.ll @@ -1346,10 +1346,9 @@ define <4 x i16> @vmerge_2(<4 x i16> %x) { define <4 x i16> @vmerge_3(<4 x i16> %x) { ; CHECK-LABEL: vmerge_3: ; CHECK: # %bb.0: -; CHECK-NEXT: vsetivli zero, 4, e16, mf2, ta, mu +; CHECK-NEXT: vsetivli zero, 4, e16, mf2, ta, ma ; CHECK-NEXT: vmv.v.i v0, 6 -; CHECK-NEXT: vmv.v.i v9, 5 -; CHECK-NEXT: vrgather.vi v8, v9, 1, v0.t +; CHECK-NEXT: vmerge.vim v8, v8, 5, v0 ; CHECK-NEXT: ret %s = shufflevector <4 x i16> %x, <4 x i16> , <4 x i32> ret <4 x i16> %s