[llvm] [GVNHoist] - Split Parent when profitable to do so. (PR #106842)
Pawan Nirpal via llvm-commits
llvm-commits at lists.llvm.org
Sat Aug 31 03:31:46 PDT 2024
pawan-nirpal-031 wrote:
for the below input
```
define dso_local void @B(i32 noundef %x, i32 noundef %y) local_unnamed_addr {
entry:
switch i32 %x, label %sw.epilog [
i32 1, label %sw.bb
i32 2, label %sw.bb1
i32 3, label %sw.bb2
i32 4, label %sw.bb4
]
sw.bb:
%sub = sub nsw i32 1, %y
tail call void @foo(i32 noundef %sub) #2
br label %sw.epilog
sw.bb1:
%div = sdiv i32 2, %y
tail call void @bar(i32 noundef %div) #2
br label %sw.epilog
sw.bb2:
%div3 = sdiv i32 2, %y
tail call void @baz(i32 noundef %div3) #2
br label %sw.epilog
sw.bb4:
%div5 = sdiv i32 2, %y
tail call void @bal(i32 noundef %div5) #2
br label %sw.epilog
sw.epilog:
ret void
}
declare void @foo(i32 noundef) local_unnamed_addr #1
declare void @bar(i32 noundef) local_unnamed_addr #1
declare void @baz(i32 noundef) local_unnamed_addr #1
declare void @bal(i32 noundef) local_unnamed_addr #1
```
it generates ```hoist.block``` out of place, it does not look at the right place control flow wise.
```
define dso_local void @B(i32 noundef %x, i32 noundef %y) local_unnamed_addr {
entry:
br label %hoist.block
sw.bb: ; No predecessors!
%sub = sub nsw i32 1, %y
tail call void @foo(i32 noundef %sub)
br label %sw.epilog
sw.bb1: ; preds = %hoist.block
%0 = phi i32 [ %3, %hoist.block ]
%div = sdiv i32 2, %y
tail call void @bar(i32 noundef %0)
br label %sw.epilog
sw.bb2: ; preds = %hoist.block
%1 = phi i32 [ %3, %hoist.block ]
%div3 = sdiv i32 2, %y
tail call void @baz(i32 noundef %1)
br label %sw.epilog
sw.bb4: ; preds = %hoist.block
%2 = phi i32 [ %3, %hoist.block ]
%div5 = sdiv i32 2, %y
tail call void @bal(i32 noundef %2)
br label %sw.epilog
sw.epilog: ; preds = %hoist.block, %sw.bb4, %sw.bb2, %sw.bb1, %sw.bb
ret void
hoist.block: ; preds = %entry
%3 = sdiv i32 2, %y
switch i32 %x, label %sw.epilog [
i32 2, label %sw.bb1
i32 3, label %sw.bb2
i32 4, label %sw.bb4
]
}
```
and for a test like the one below
```
define dso_local void @B(i32 noundef %x, i32 noundef %y) local_unnamed_addr {
entry:
switch i32 %x, label %sw.epilog [
i32 1, label %sw.bb
i32 2, label %sw.bb1
i32 3, label %sw.bb2
i32 4, label %sw.bb4
]
sw.bb:
%bb.sub = sub nsw i32 1, %y
%bb.div = sdiv i32 2, %y
%bb.add = add nsw i32 4, %y
%bb.sub2 = sub nsw i32 3, %y
tail call void @foo(i32 noundef %bb.sub) #2
tail call void @foo(i32 noundef %bb.div) #2
tail call void @foo(i32 noundef %bb.add) #2
tail call void @foo(i32 noundef %bb.sub2) #2
br label %sw.epilog
sw.bb1:
%bb1.sub = sub nsw i32 1, %y
%bb1.div = sdiv i32 2, %y
%bb1.add = add nsw i32 4, %y
%bb1.sub2 = sub nsw i32 3, %y
tail call void @bar(i32 noundef %bb1.div) #2
tail call void @bar(i32 noundef %bb1.add) #2
tail call void @bar(i32 noundef %bb1.sub) #2
tail call void @bar(i32 noundef %bb1.sub2) #2
br label %sw.epilog
sw.bb2:
%bb2.sub = sub nsw i32 1, %y
%bb2.add = add nsw i32 4, %y
%bb2.sub2 = sub nsw i32 3, %y
tail call void @baz(i32 noundef %bb2.sub) #2
tail call void @baz(i32 noundef %bb2.add) #2
tail call void @baz(i32 noundef %bb2.sub2) #2
br label %sw.epilog
sw.bb4:
%bb4.sub = sub nsw i32 1, %y
%bb4.div = sdiv i32 2, %y
%bb4.sub2 = sub nsw i32 3, %y
tail call void @bal(i32 noundef %bb4.sub) #2
tail call void @bal(i32 noundef %bb4.div) #2
tail call void @bal(i32 noundef %bb4.sub2) #2
br label %sw.epilog
sw.epilog:
ret void
}
```
it does weirder things, 3 same predecessors and out of control flow.
```
define dso_local void @B(i32 noundef %x, i32 noundef %y) local_unnamed_addr {
entry:
switch i32 %x, label %sw.epilog [
i32 1, label %hoist.block
i32 2, label %hoist.block
i32 3, label %hoist.block
i32 4, label %sw.bb4
]
sw.bb: ; preds = %hoist.block
%0 = phi i32 [ %11, %hoist.block ]
%1 = phi i32 [ %10, %hoist.block ]
%2 = phi i32 [ %9, %hoist.block ]
%bb.div = sdiv i32 2, %y
tail call void @foo(i32 noundef %2)
tail call void @foo(i32 noundef %bb.div)
tail call void @foo(i32 noundef %1)
tail call void @foo(i32 noundef %0)
br label %sw.epilog
sw.bb1: ; preds = %hoist.block
%3 = phi i32 [ %11, %hoist.block ]
%4 = phi i32 [ %10, %hoist.block ]
%5 = phi i32 [ %9, %hoist.block ]
%bb1.div = sdiv i32 2, %y
tail call void @bar(i32 noundef %bb1.div)
tail call void @bar(i32 noundef %4)
tail call void @bar(i32 noundef %5)
tail call void @bar(i32 noundef %3)
br label %sw.epilog
sw.bb2: ; preds = %hoist.block
%6 = phi i32 [ %11, %hoist.block ]
%7 = phi i32 [ %10, %hoist.block ]
%8 = phi i32 [ %9, %hoist.block ]
tail call void @baz(i32 noundef %8)
tail call void @baz(i32 noundef %7)
tail call void @baz(i32 noundef %6)
br label %sw.epilog
sw.bb4: ; preds = %entry
%bb4.sub = sub nsw i32 1, %y
%bb4.div = sdiv i32 2, %y
%bb4.sub2 = sub nsw i32 3, %y
tail call void @bal(i32 noundef %bb4.sub)
tail call void @bal(i32 noundef %bb4.div)
tail call void @bal(i32 noundef %bb4.sub2)
br label %sw.epilog
sw.epilog: ; preds = %hoist.block, %sw.bb4, %sw.bb2, %sw.bb1, %sw.bb, %entry
ret void
hoist.block: ; preds = %entry, %entry, %entry
%9 = sub nsw i32 1, %y
%10 = add nsw i32 4, %y
%11 = sub nsw i32 3, %y
switch i32 %x, label %sw.epilog [
i32 1, label %sw.bb
i32 2, label %sw.bb1
i32 3, label %sw.bb2
]
}
```
https://github.com/llvm/llvm-project/pull/106842
More information about the llvm-commits
mailing list