llvm / llvm/llvm-project

[SLP] Matching nodes are costed twice after trimming

Open
#219,030 0 comments 0 reactions 1 assignee Claimed by @bababuck View on GitHub
llvm:SLPVectorizer
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

**For** a diamond merge pattern, the duplicate node is costed as `0`. However, after trimming, we re-calculate the cost for this node and assign it the cost of a full gather. From my understanding, we currently don't handle gathers that have overlapping values super well and this ties into that. The simple solution would be to handle the exact diamond match case and punt on the rest.

Relates to #213034.

In the following, we trim the tree to remove the `shl/lshr` node, which transforms the bundle of [v0, v1, v2, v3] into a gather. Even though this gather is identical to the other gather of `[v0, v1, v2, v3]`, we cost them as two separate gathers after trimming.

`opt -passes=slp-vectorizer -S -mtriple=riscv64 --mattr=+v,+zvl256b -slp-threshold=0`

```llvm
define void @trim_at(ptr %A, ptr %B, ptr %C, ptr %D, ptr %S) {
entry:
%A0 = load i64, ptr %A, align 8
%B0 = load i64, ptr %B, align 8
%C0 = load i64, ptr %B, align 8
%D0 = load i64, ptr %B, align 8

%v0 = shl i64 1, %A0
%v1 = lshr i64 1, %B0
%v2 = shl i64 1, %A0
%v3 = lshr i64 1, %B0

%Add0 = add i64 %v0, %v0
%Add1 = add i64 %v1, %v1
%Add2 = add i64 %v2, %v2
%Add3 = sub i64 %v3, %v3

%idxS1 = getelementptr inbounds i64, ptr %S, i64 1
%idxS2 = getelementptr inbounds i64, ptr %S, i64 2
%idxS3 = getelementptr inbounds i64, ptr %S, i64 3

store i64 %Add0, ptr %S, align 8
store i64 %Add1, ptr %idxS1, align 8
store i64 %Add2, ptr %idxS2, align 8
store i64 %Add3, ptr %idxS3, align 8
ret void
}
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.