[Mlir-commits] [mlir] [mlir][vector] Refine select uses on uniform reduction paths (PR #235640)
Kazu Hirata
llvmlistbot at llvm.org
Mon Oct 26 01:40:13 PDT 2026
================
@@ -8692,6 +8694,108 @@ DeinterleaveOp::getIterationShapeToUnroll() {
return llvm::to_vector<4>(getResultVectorType().getShape());
}
+//===----------------------------------------------------------------------===//
+// VectorDialect canonicalization
+//===----------------------------------------------------------------------===//
+
+namespace {
+/// Conservatively compute the regions reachable from an operation entry.
+/// Region-to-region edges are included: an entry-only check is insufficient for
+/// loops and operations that enter one region through another.
+static bool isRegionReachable(RegionBranchOpInterface branch, Region *target,
+ ArrayRef<Attribute> operands) {
+ SmallVector<RegionSuccessor> successors;
+ branch.getEntrySuccessorRegions(operands, successors);
+ SmallVector<Region *> worklist;
+ llvm::SmallPtrSet<Region *, 4> visited;
+ auto append = [&] {
+ for (RegionSuccessor successor : successors)
+ if (Region *region = successor.getSuccessor())
+ if (region->getParentOp() == branch.getOperation() &&
+ visited.insert(region).second)
+ worklist.push_back(region);
+ };
+ append();
+ while (!worklist.empty()) {
+ Region *region = worklist.pop_back_val();
+ if (region == target)
+ return true;
+ successors.clear();
+ branch.getSuccessorRegions(*region, successors);
+ append();
+ }
+ return false;
+}
+
+/// Infer a reduction's value only when the opposite value cannot reach the use.
+struct SelectReductionBranch : OpRewritePattern<arith::SelectOp> {
+ using OpRewritePattern::OpRewritePattern;
+ LogicalResult matchAndRewrite(arith::SelectOp select,
+ PatternRewriter &rewriter) const override {
+ if (!isa<VectorType>(select.getCondition().getType()))
+ return failure();
+ DenseMap<Region *, Value> replacements;
+ bool changed = false;
+ for (OpOperand &use :
+ llvm::make_early_inc_range(select.getResult().getUses())) {
+ for (Operation *child = use.getOwner();
+ auto *parent = child->getParentOp(); child = parent) {
+ auto branch = dyn_cast<RegionBranchOpInterface>(parent);
+ if (!branch)
+ continue;
+ Region *useRegion = child->getParentRegion();
+ if (!replacements.contains(useRegion)) {
+ replacements[useRegion] = Value();
----------------
kazutakahirata wrote:
May I suggest using `try_emplace` here to avoid performing up to four separate lookups on `replacements` for `useRegion`?
```cpp
auto [it, inserted] = replacements.try_emplace(useRegion);
if (inserted) {
for (Value operand : parent->getOperands()) {
...
it->second = replacement;
break;
}
}
if (Value replacement = it->second) {
```
https://github.com/llvm/llvm-project/pull/235640
More information about the Mlir-commits
mailing list