Hi Philip,
I have reduced the test case roughly as below.
declare i32 @foo(i8 *)
define void @test(i8* %s, i64 %a) {
entry:
%s.addr.a = getelementptr i8, i8* %s, i64 %a
br label %while.body.us
while.body.us:
%s.addr = phi i8* [ %incdec.ptr, %while.cond.backedge ], [ %s, %entry ]
%incdec.ptr = getelementptr inbounds i8, i8* %s.addr, i64 1
%incdec.val = load i8, i8* %s.addr, align 1
%cmp1 = icmp eq i8 %incdec.val, 10
br i1 %cmp1, label %if.end8.us, label %while.cond.backedge
if.end8.us:
%call9 = tail call i32 @foo(i8* nonnull %incdec.ptr)
%cmp2 = icmp ult i32 %call9, 0
br i1 %cmp2, label %while.cond.backedge, label %return.loopexit
while.cond.backedge:
%cmp3 = icmp eq i8* %incdec.ptr, %s.addr.a
br i1 %cmp3, label %return.loopexit, label %while.body.us
return.loopexit:
ret void
}
Roughly, I unrolled the loop manually 2 times as below and ignored the remaining loop simply.
define void @test(i8* %s, i64 %a) {
entry:
%s.addr.a = getelementptr i8, i8* %s, i64 %a
br label %while.body.us
while.body.us:
%s.addr = phi i8* [ %incdec.ptr, %while.cond.backedge ], [ %s, %entry ]
%incdec.ptr = getelementptr inbounds i8, i8* %s.addr, i64 1
%incdec.val = load i8, i8* %s.addr, align 1
%cmp1 = icmp eq i8 %incdec.val, 10
br i1 %cmp1, label %if.end8.us, label %while.body.us.1
while.body.us.1:
%incdec.ptr.1 = getelementptr inbounds i8, i8* %incdec.ptr, i64 1
%incdec.val.1 = load i8, i8* %incdec.ptr, align 1
%cmp1.1 = icmp eq i8 %incdec.val.1, 10
br i1 %cmp1.1, label %if.end8.us, label %while.cond.backedge
if.end8.us:
%incdec.ptr.phi = phi i8* [ %incdec.ptr, %while.body.us ], [ %incdec.ptr.1, %while.body.us.1 ]
%call9 = tail call i32 @foo(i8* nonnull %incdec.ptr.phi)
%cmp2 = icmp ult i32 %call9, 0
br i1 %cmp2, label %while.cond.backedge, label %return.loopexit
while.cond.backedge:
%cmp3 = icmp eq i8* %incdec.ptr.1, %s.addr.a
br i1 %cmp3, label %return.loopexit, label %while.body.us
return.loopexit:
ret void
}
If possible, can we make loop unroll pass handle this kind of cases please?
If I missed something, please let me know.
Thanks
JinGu Kang