Skip to content

Instantly share code, notes, and snippets.

@nikic

nikic/alive Secret

Created May 18, 2022 16:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nikic/82c3a9ee77141e813f7cd5362890c017 to your computer and use it in GitHub Desktop.
Save nikic/82c3a9ee77141e813f7cd5362890c017 to your computer and use it in GitHub Desktop.
----------------------------------------
define void @test10(i64 %trip, i64 %trip2) {
%entry:
br label %loop_header
%loop_header:
%iv = phi i64 [ 0, %entry ], [ %iv_next, %loop_latch ]
call void @bar()
%cmp_early = icmp ne i64 %iv, %trip2
br i1 %cmp_early, label %loop_latch, label %exit1
%loop_latch:
%iv_next = add i64 %iv, 1
%cmp = icmp ne i64 %iv_next, %trip
br i1 %cmp, label %loop_header, label %exit2
%exit2:
ret void
%exit1:
ret void
}
=>
define void @test10(i64 %trip, i64 %trip2) {
%entry:
%0 = add i64 %trip, -1
%1 = freeze i64 %trip
%2 = freeze i64 %0
%xtraiter = and i64 %1, 7
%3 = icmp ult i64 %2, 7
br i1 %3, label %exit2.unr-lcssa, label %entry.new
%entry.new:
%unroll_iter = sub i64 %1, %xtraiter
br label %loop_header
%loop_header:
%iv = phi i64 [ 0, %entry.new ], [ %iv_next.7, %loop_latch.7 ]
%niter = phi i64 [ 0, %entry.new ], [ %niter.next.7, %loop_latch.7 ]
call void @bar()
%cmp_early = icmp ne i64 %iv, %trip2
br i1 %cmp_early, label %loop_latch, label %exit1.loopexit
%loop_latch:
%iv_next = add nsw nuw i64 %iv, 1
%niter.next = add nsw nuw i64 %niter, 1
call void @bar()
%cmp_early.1 = icmp ne i64 %iv_next, %trip2
br i1 %cmp_early.1, label %loop_latch.1, label %exit1.loopexit
%loop_latch.1:
%iv_next.1 = add nsw nuw i64 %iv_next, 1
%niter.next.1 = add nsw nuw i64 %niter.next, 1
call void @bar()
%cmp_early.2 = icmp ne i64 %iv_next.1, %trip2
br i1 %cmp_early.2, label %loop_latch.2, label %exit1.loopexit
%loop_latch.2:
%iv_next.2 = add nsw nuw i64 %iv_next.1, 1
%niter.next.2 = add nsw nuw i64 %niter.next.1, 1
call void @bar()
%cmp_early.3 = icmp ne i64 %iv_next.2, %trip2
br i1 %cmp_early.3, label %loop_latch.3, label %exit1.loopexit
%loop_latch.3:
%iv_next.3 = add nsw nuw i64 %iv_next.2, 1
%niter.next.3 = add nsw nuw i64 %niter.next.2, 1
call void @bar()
%cmp_early.4 = icmp ne i64 %iv_next.3, %trip2
br i1 %cmp_early.4, label %loop_latch.4, label %exit1.loopexit
%loop_latch.4:
%iv_next.4 = add nsw nuw i64 %iv_next.3, 1
%niter.next.4 = add nsw nuw i64 %niter.next.3, 1
call void @bar()
%cmp_early.5 = icmp ne i64 %iv_next.4, %trip2
br i1 %cmp_early.5, label %loop_latch.5, label %exit1.loopexit
%loop_latch.5:
%iv_next.5 = add nsw nuw i64 %iv_next.4, 1
%niter.next.5 = add nsw nuw i64 %niter.next.4, 1
call void @bar()
%cmp_early.6 = icmp ne i64 %iv_next.5, %trip2
br i1 %cmp_early.6, label %loop_latch.6, label %exit1.loopexit
%loop_latch.6:
%iv_next.6 = add nsw nuw i64 %iv_next.5, 1
%niter.next.6 = add nsw nuw i64 %niter.next.5, 1
call void @bar()
%cmp_early.7 = icmp ne i64 %iv_next.6, %trip2
br i1 %cmp_early.7, label %loop_latch.7, label %exit1.loopexit
%loop_latch.7:
%iv_next.7 = add i64 %iv_next.6, 1
%niter.next.7 = add i64 %niter.next.6, 1
%niter.ncmp.7 = icmp ne i64 %niter.next.7, %unroll_iter
br i1 %niter.ncmp.7, label %loop_header, label %exit2.unr-lcssa.loopexit
%exit2.unr-lcssa.loopexit:
%iv.unr.ph = phi i64 [ %iv_next.7, %loop_latch.7 ]
br label %exit2.unr-lcssa
%exit1.loopexit:
br label %exit1
%exit2.unr-lcssa:
%iv.unr = phi i64 [ 0, %entry ], [ %iv.unr.ph, %exit2.unr-lcssa.loopexit ]
%lcmp.mod = icmp ne i64 %xtraiter, 0
br i1 %lcmp.mod, label %loop_header.epil.preheader, label %exit2
%loop_header.epil.preheader:
br label %loop_header.epil
%loop_header.epil:
%iv.epil = phi i64 [ %iv.unr, %loop_header.epil.preheader ], [ %iv_next.epil, %loop_latch.epil ]
%epil.iter = phi i64 [ 0, %loop_header.epil.preheader ], [ %epil.iter.next, %loop_latch.epil ]
call void @bar()
%cmp_early.epil = icmp ne i64 %iv.epil, %trip2
br i1 %cmp_early.epil, label %loop_latch.epil, label %exit1.loopexit1
%loop_latch.epil:
%iv_next.epil = add i64 %iv.epil, 1
%cmp.epil = icmp ne i64 %iv_next.epil, %trip
%epil.iter.next = add i64 %epil.iter, 1
%epil.iter.cmp = icmp ne i64 %epil.iter.next, %xtraiter
br i1 %epil.iter.cmp, label %loop_header.epil, label %exit2.epilog-lcssa
%exit2.epilog-lcssa:
br label %exit2
%exit1.loopexit1:
br label %exit1
%exit1:
ret void
%exit2:
ret void
}
Transformation doesn't verify!
ERROR: Source and target don't have the same return domain
Example:
i64 %trip = undef
i64 %trip2 = poison
Source:
>> Jump to %loop_header
i64 %iv = #x0000000000000000 (0)
void = UB triggered!
SOURCE MEMORY STATE
===================
NON-LOCAL BLOCKS:
Block 0 > size: 0 align: 1 alloc type: 0
Block 1 > size: 0 align: 1
Target:
i64 %0 = #x0000000000000003 (3)
i64 %1 = #x0000000000000000 (0)
i64 %2 = #x0000000000000003 (3)
i64 %xtraiter = #x0000000000000000 (0)
i1 %3 = #x1 (1)
>> Jump to %exit2.unr-lcssa
i64 %iv.unr = #x0000000000000000 (0)
i1 %lcmp.mod = #x0 (0)
>> Jump to %exit2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment