From b33a1cc05b4800ae9e8c7df097c4a76c9da28c94 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Wed, 22 Sep 2021 09:12:45 -0700 Subject: [PATCH] [RISCV] Optimize vp.store with an all ones mask to avoid a vmset. We can use riscv_vse intrinsic instead of riscv_vse_mask. The code here is based on similar code for handling masked.scatter and vp.scatter. Reviewed By: frasercrmck Differential Revision: https://reviews.llvm.org/D110206 --- llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 24 ++++++++++++++++------ .../CodeGen/RISCV/rvv/fixed-vectors-vpstore.ll | 12 +++++++++++ llvm/test/CodeGen/RISCV/rvv/vpstore.ll | 12 +++++++++++ 3 files changed, 42 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index af79b07..4cd1820 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -4741,25 +4741,37 @@ SDValue RISCVTargetLowering::lowerMaskedStore(SDValue Op, Mask = MStore->getMask(); } + bool IsUnmasked = ISD::isConstantSplatVectorAllOnes(Mask.getNode()); + MVT VT = Val.getSimpleValueType(); MVT XLenVT = Subtarget.getXLenVT(); MVT ContainerVT = VT; if (VT.isFixedLengthVector()) { ContainerVT = getContainerForFixedLengthVector(VT); - MVT MaskVT = MVT::getVectorVT(MVT::i1, ContainerVT.getVectorElementCount()); Val = convertToScalableVector(ContainerVT, Val, DAG, Subtarget); - Mask = convertToScalableVector(MaskVT, Mask, DAG, Subtarget); + if (!IsUnmasked) { + MVT MaskVT = + MVT::getVectorVT(MVT::i1, ContainerVT.getVectorElementCount()); + Mask = convertToScalableVector(MaskVT, Mask, DAG, Subtarget); + } } if (!VL) VL = getDefaultVLOps(VT, ContainerVT, DL, DAG, Subtarget).second; - SDValue IntID = DAG.getTargetConstant(Intrinsic::riscv_vse_mask, DL, XLenVT); - return DAG.getMemIntrinsicNode( - ISD::INTRINSIC_VOID, DL, DAG.getVTList(MVT::Other), - {Chain, IntID, Val, BasePtr, Mask, VL}, MemVT, MMO); + unsigned IntID = + IsUnmasked ? Intrinsic::riscv_vse : Intrinsic::riscv_vse_mask; + SmallVector Ops{Chain, DAG.getTargetConstant(IntID, DL, XLenVT)}; + Ops.push_back(Val); + Ops.push_back(BasePtr); + if (!IsUnmasked) + Ops.push_back(Mask); + Ops.push_back(VL); + + return DAG.getMemIntrinsicNode(ISD::INTRINSIC_VOID, DL, + DAG.getVTList(MVT::Other), Ops, MemVT, MMO); } SDValue diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vpstore.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vpstore.ll index 2a9889c..28e2dc8 100644 --- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vpstore.ll +++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vpstore.ll @@ -255,3 +255,15 @@ define void @vpstore_v8f64(<8 x double> %val, <8 x double>* %ptr, <8 x i1> %m, i call void @llvm.vp.store.v8f64(<8 x double> %val, <8 x double>* %ptr, <8 x i1> %m, i32 %evl) ret void } + +define void @vpstore_v2i8_allones_mask(<2 x i8> %val, <2 x i8>* %ptr, i32 zeroext %evl) { +; CHECK-LABEL: vpstore_v2i8_allones_mask: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli zero, a1, e8, mf8, ta, mu +; CHECK-NEXT: vse8.v v8, (a0) +; CHECK-NEXT: ret + %a = insertelement <2 x i1> undef, i1 true, i32 0 + %b = shufflevector <2 x i1> %a, <2 x i1> poison, <2 x i32> zeroinitializer + call void @llvm.vp.store.v2i8(<2 x i8> %val, <2 x i8>* %ptr, <2 x i1> %b, i32 %evl) + ret void +} diff --git a/llvm/test/CodeGen/RISCV/rvv/vpstore.ll b/llvm/test/CodeGen/RISCV/rvv/vpstore.ll index de40242..e9fdb94 100644 --- a/llvm/test/CodeGen/RISCV/rvv/vpstore.ll +++ b/llvm/test/CodeGen/RISCV/rvv/vpstore.ll @@ -339,3 +339,15 @@ define void @vpstore_nxv8f64( %val, * call void @llvm.vp.store.nxv8f64( %val, * %ptr, %m, i32 %evl) ret void } + +define void @vpstore_nxv1i8_allones_mask( %val, * %ptr, i32 zeroext %evl) { +; CHECK-LABEL: vpstore_nxv1i8_allones_mask: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli zero, a1, e8, mf8, ta, mu +; CHECK-NEXT: vse8.v v8, (a0) +; CHECK-NEXT: ret + %a = insertelement undef, i1 true, i32 0 + %b = shufflevector %a, poison, zeroinitializer + call void @llvm.vp.store.nxv1i8( %val, * %ptr, %b, i32 %evl) + ret void +} -- 2.7.4