[llvm] [IR][LangRef] Add partial reduction add intrinsic (PR #94499)

Graham Hunter via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 25 06:59:43 PDT 2024


================
@@ -7914,6 +7914,46 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
     setValue(&I, Trunc);
     return;
   }
+  case Intrinsic::experimental_vector_partial_reduce_add: {
+    auto DL = getCurSDLoc();
+    auto ReducedTy = EVT::getEVT(I.getType());
+    auto OpNode = getValue(I.getOperand(1));
+    auto FullTy = OpNode.getValueType();
+
+    unsigned Stride = ReducedTy.getVectorMinNumElements();
+    unsigned ScaleFactor = FullTy.getVectorMinNumElements() / Stride;
+
+    // Collect all of the subvectors
+    SmallVector<SDValue> Subvectors;
+    Subvectors.push_back(getValue(I.getOperand(0)));
+    for(unsigned i = 0; i < ScaleFactor; i++) {
+      auto SourceIndex = DAG.getVectorIdxConstant(i * Stride, DL);
+      Subvectors.push_back(DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, ReducedTy, {OpNode, SourceIndex}));
+    }
+
+    while(Subvectors.size() >= 2) {
----------------
huntergr-arm wrote:

I think this could be improved a little by using a std::deque instead of a SmallVector. You can push_back the operands as above, but then use a smaller loop like the following to compute the result:

```
while (Subvectors.size() > 1) {
  Subvectors.push_back(DAG.getNode(ISD::ADD, DL, ReducedTy, {Subvectors[0], Subvectors[1]});
  Subvectors.pop_front();
  Subvectors.pop_front();
}
```

Sadly there's no `pop_front_val()` that gives you the value when removing it, but it is shorter.

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


More information about the llvm-commits mailing list