[llvm] [LSR] Deduplicate cast instructions across ICmpZero fixups (PR #201970)
Timur Golubovich via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 8 06:34:36 PDT 2026
timurgol007 wrote:
So, regarding this patch, pre IR is:
```ll
define void @test_inttoptr_reuse(ptr %base1, ptr %base2, ptr %base3, i64 %n) {
entry:
%bound1 = getelementptr i64, ptr %base1, i64 %n
%bound2 = getelementptr i64, ptr %base2, i64 %n
%bound3 = getelementptr i64, ptr %base3, i64 %n
br label %loop
loop:
%p1 = phi ptr [ %base1, %entry ], [ %p1.next, %loop.latch ]
%p2 = phi ptr [ %base2, %entry ], [ %p2.next, %loop.latch ]
%p3 = phi ptr [ %base3, %entry ], [ %p3.next, %loop.latch ]
%cmp.exit = icmp eq ptr %p2, %bound2
br i1 %cmp.exit, label %check, label %body
check:
%cmp1 = icmp ne ptr %p1, %bound1
%cmp3 = icmp ne ptr %p3, %bound3
%sel = select i1 %cmp1, i1 true, i1 %cmp3
br i1 %sel, label %body, label %exit
body:
%v1 = load i64, ptr %p1, align 8
%v2 = load i64, ptr %p2, align 8
%sum = add i64 %v1, %v2
store i64 %sum, ptr %p3, align 8
br label %loop.latch
loop.latch:
%p1.next = getelementptr inbounds i8, ptr %p1, i64 8
%p2.next = getelementptr inbounds i8, ptr %p2, i64 8
%p3.next = getelementptr inbounds i8, ptr %p3, i64 8
br label %loop
exit:
ret void
}
```
Without this patch it optimizes to:
```ll
define void @test_inttoptr_reuse(ptr %base1, ptr %base2, ptr %base3, i64 %n) {
entry:
%0 = shl i64 %n, 3
%1 = inttoptr i64 %0 to ptr
br label %loop
loop: ; preds = %loop.latch, %entry
%lsr.iv = phi i64 [ %lsr.iv.next, %loop.latch ], [ 0, %entry ]
%scevgep = getelementptr i8, ptr %base1, i64 %lsr.iv
%scevgep3 = getelementptr i8, ptr %base2, i64 %lsr.iv
%scevgep4 = getelementptr i8, ptr %base3, i64 %lsr.iv
%tmp1 = inttoptr i64 %lsr.iv to ptr
%cmp.exit = icmp eq ptr %1, %tmp1
br i1 %cmp.exit, label %check, label %body
check: ; preds = %loop
%tmp = inttoptr i64 %lsr.iv to ptr
%cmp1 = icmp ne ptr %1, %tmp
%tmp2 = inttoptr i64 %lsr.iv to ptr
%cmp3 = icmp ne ptr %1, %tmp2
%sel = select i1 %cmp1, i1 true, i1 %cmp3
br i1 %sel, label %body, label %exit
body: ; preds = %check, %loop
%v1 = load i64, ptr %scevgep, align 8
%v2 = load i64, ptr %scevgep3, align 8
%sum = add i64 %v1, %v2
store i64 %sum, ptr %scevgep4, align 8
br label %loop.latch
loop.latch: ; preds = %body
%lsr.iv.next = add i64 %lsr.iv, 8
br label %loop
exit: ; preds = %check
ret void
}
```
And my changes cause this:
```ll
define void @test_inttoptr_reuse(ptr %base1, ptr %base2, ptr %base3, i64 %n) {
entry:
%0 = shl i64 %n, 3
%1 = inttoptr i64 %0 to ptr
br label %loop
loop: ; preds = %loop.latch, %entry
%lsr.iv = phi i64 [ %lsr.iv.next, %loop.latch ], [ 0, %entry ]
%scevgep = getelementptr i8, ptr %base1, i64 %lsr.iv
%scevgep1 = getelementptr i8, ptr %base2, i64 %lsr.iv
%scevgep2 = getelementptr i8, ptr %base3, i64 %lsr.iv
%tmp = inttoptr i64 %lsr.iv to ptr
%cmp.exit = icmp eq ptr %1, %tmp
br i1 %cmp.exit, label %check, label %body
check: ; preds = %loop
%cmp1 = icmp ne ptr %1, %tmp
%cmp3 = icmp ne ptr %1, %tmp
%sel = select i1 %cmp1, i1 true, i1 %cmp3
br i1 %sel, label %body, label %exit
body: ; preds = %check, %loop
%v1 = load i64, ptr %scevgep, align 8
%v2 = load i64, ptr %scevgep1, align 8
%sum = add i64 %v1, %v2
store i64 %sum, ptr %scevgep2, align 8
br label %loop.latch
loop.latch: ; preds = %body
%lsr.iv.next = add i64 %lsr.iv, 8
br label %loop
exit: ; preds = %check
ret void
}
```
After these we can remove one icmp (in the second PR with RewtittenInstrs, I haven;t created it yet as I am waiting this one to land) and simplify the branch condition (in this PR https://github.com/llvm/llvm-project/pull/201839).
https://github.com/llvm/llvm-project/pull/201970
More information about the llvm-commits
mailing list