[llvm] [InstCombine][RISCV] Convert VPIntrinsics with splat operands to splats (PR #65706)

Luke Lau via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 12 10:28:48 PDT 2023


================
@@ -729,6 +730,99 @@ bool VectorCombine::foldBitcastShuf(Instruction &I) {
   return true;
 }
 
+/// VP Intrinsics whose vector operands are both splat values may be simplified
+/// into the scalar version of the operation and the result is splatted. This
+/// can lead to scalarization down the line.
+bool VectorCombine::scalarizeVPIntrinsic(VPIntrinsic &VPI) {
+  Value *Op0 = VPI.getArgOperand(0);
+  Value *Op1 = VPI.getArgOperand(1);
+
+  if (!isSplatValue(Op0) || !isSplatValue(Op1))
+    return false;
+
+  // For the binary VP intrinsics supported here, the result on disabled lanes
+  // is a poison value. For now, only do this simplification if all lanes
+  // are active.
+  // TODO: Relax the condition that all lanes are active by using insertelement
+  // on inactive lanes.
+  auto IsAllTrueMask = [](Value *MaskVal) {
+    if (Value *SplattedVal = getSplatValue(MaskVal))
+      if (auto *ConstValue = dyn_cast<Constant>(SplattedVal))
+        return ConstValue->isAllOnesValue();
+    return false;
+  };
+  if (!IsAllTrueMask(VPI.getArgOperand(2)))
+    return false;
+
+  // Check to make sure we support scalarization of the intrinsic
+  std::set<Intrinsic::ID> SupportedIntrinsics(
+      {Intrinsic::vp_add, Intrinsic::vp_sub, Intrinsic::vp_mul,
+       Intrinsic::vp_ashr, Intrinsic::vp_lshr, Intrinsic::vp_shl,
+       Intrinsic::vp_or, Intrinsic::vp_and, Intrinsic::vp_xor,
+       Intrinsic::vp_fadd, Intrinsic::vp_fsub, Intrinsic::vp_fmul,
+       Intrinsic::vp_sdiv, Intrinsic::vp_udiv, Intrinsic::vp_srem,
+       Intrinsic::vp_urem});
+  Intrinsic::ID IntrID = VPI.getIntrinsicID();
+  if (!SupportedIntrinsics.count(IntrID))
+    return false;
----------------
lukel97 wrote:

I just remembered, we have a property in `VPIntrinsics.def` that marks a VP intrinsic as a binary-op, `VP_PROPERTY_BINARYOP`, I think we can reuse it here. There's a function `VPReductionIntrinsic::isVPReduction` in `IntrinsicInst.cpp` that shows how to check for `VP_PROPERTY_REDUCTION`, we could copy it for binary ops and then call it from VectorCombine.

>From a quick scan, it would include `vp_{s,u}{min,max}`, `vp_{min,max}num` ,`vp_f{min,max}` `vp_copysign` and `vp_fdiv` and `vp_frem`. For the latter two *I think* we need to add the latter two to `MustHaveNonZeroVL` if any of the fast-math flags that can introduce poison are set? That would be nnan/ninf https://llvm.org/docs/LangRef.html#fast-math-flags


https://github.com/llvm/llvm-project/pull/65706


More information about the llvm-commits mailing list