-
Notifications
You must be signed in to change notification settings - Fork 129
Open
Labels
loopsLoopsLoops
Description
Nowadays, LLVM, at least nominally, does not assume that loops must progress,
but requires mustprogress annotation for that.
But it seems like alive2 doesn't deal with that.
For example,
; ModuleID = '/tmp/test.ll'
source_filename = "/tmp/test.ll"
target triple = "x86_64"
declare void @escape_inner(i8, i8, i8, i1, i8) #0
declare void @escape_outer(i8, i8, i8, i1, i8) #0
define i8 @src(i8 %val, i8 %start, i8 %extraoffset) {
entry:
br label %loop
loop:
%iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ]
%nbits = add nsw i8 %iv, %extraoffset
%val.shifted = ashr i8 %val, %nbits
%val.shifted.iszero = icmp eq i8 %val.shifted, 0
%iv.next = add i8 %iv, 1
call void @escape_inner(i8 %iv, i8 %nbits, i8 %val.shifted, i1 %val.shifted.iszero, i8 %iv.next)
br i1 %val.shifted.iszero, label %end, label %loop
end:
%iv.res = phi i8 [ %iv, %loop ]
%nbits.res = phi i8 [ %nbits, %loop ]
%val.shifted.res = phi i8 [ %val.shifted, %loop ]
%val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]
%iv.next.res = phi i8 [ %iv.next, %loop ]
call void @escape_outer(i8 %iv.res, i8 %nbits.res, i8 %val.shifted.res, i1 %val.shifted.iszero.res, i8 %iv.next.res)
ret i8 %iv.res
}
define i8 @tgt(i8 %val, i8 %start, i8 %extraoffset) #0 {
entry:
%val.numleadingzeros = call i8 @llvm.ctlz.i8(i8 %val, i1 false)
%val.numactivebits = sub nuw nsw i8 8, %val.numleadingzeros
%0 = sub i8 0, %extraoffset
%val.numactivebits.offset = add nsw i8 %val.numactivebits, %0
%iv.final = call i8 @llvm.smax.i8(i8 %val.numactivebits.offset, i8 %start)
%loop.backedgetakencount = sub nsw i8 %iv.final, %start
%loop.tripcount = add nuw nsw i8 %loop.backedgetakencount, 1
br label %loop
loop: ; preds = %loop, %entry
%loop.iv = phi i8 [ 0, %entry ], [ %loop.iv.next, %loop ]
%loop.iv.next = add nuw nsw i8 %loop.iv, 1
%loop.ivcheck = icmp eq i8 %loop.iv.next, %loop.tripcount
%iv = add nsw i8 %loop.iv, %start
%nbits = add nsw i8 %iv, %extraoffset
%val.shifted = ashr i8 %val, %nbits
%iv.next = add i8 %iv, 1
call void @escape_inner(i8 %iv, i8 %nbits, i8 %val.shifted, i1 %loop.ivcheck, i8 %iv.next)
br i1 %loop.ivcheck, label %end, label %loop
end: ; preds = %loop
%iv.res = phi i8 [ %iv.final, %loop ]
%nbits.res = phi i8 [ %nbits, %loop ]
%val.shifted.res = phi i8 [ %val.shifted, %loop ]
%val.shifted.iszero.res = phi i1 [ %loop.ivcheck, %loop ]
%iv.next.res = phi i8 [ %iv.next, %loop ]
call void @escape_outer(i8 %iv.res, i8 %nbits.res, i8 %val.shifted.res, i1 %val.shifted.iszero.res, i8 %iv.next.res)
ret i8 %iv.res
}
; Function Attrs: nofree nosync nounwind readnone speculatable willreturn
declare i8 @llvm.ctlz.i8(i8, i1 immarg) #1
; Function Attrs: nofree nosync nounwind readnone speculatable willreturn
declare i8 @llvm.smax.i8(i8, i8) #1
attributes #0 = { "target-cpu"="core-avx2" }
attributes #1 = { nofree nosync nounwind readnone speculatable willreturn }
presumably shouldn't be a valid refinement - the original loop is endless for negative %start,
while the new one is not.
Metadata
Metadata
Assignees
Labels
loopsLoopsLoops