Test source: git
Source: <stdin> ERROR: Unsupported instruction: %2 = invoke i32 @a() to label %loop_latch unwind label %loop_catch ---------------------------------------- define void @test_no_unswitch_convergent(ptr %ptr, i1 %cond) { %entry: br label %loop_begin %loop_begin: br i1 %cond, label %loop_a, label %loop_b %loop_a: %0 = call i32 @a() br label %loop_latch %loop_b: %1 = call i32 @b() br label %loop_latch %loop_latch: %v = load i1, ptr %ptr, align 1 br i1 %v, label %loop_begin, label %loop_exit %loop_exit: ret void } => define void @test_no_unswitch_convergent(ptr %ptr, i1 %cond) { %entry: br label %loop_begin %loop_begin: br i1 %cond, label %loop_a, label %loop_b %loop_a: %0 = call i32 @a() br label %loop_latch %loop_b: %1 = call i32 @b() br label %loop_latch %loop_latch: %v = load i1, ptr %ptr, align 1 br i1 %v, label %loop_begin, label %loop_exit %loop_exit: ret void } Transformation seems to be correct! (syntactically equal) ---------------------------------------- define void @test_no_unswitch_noduplicate(ptr %ptr, i1 %cond) { %entry: br label %loop_begin %loop_begin: br i1 %cond, label %loop_a, label %loop_b %loop_a: %0 = call i32 @a() br label %loop_latch %loop_b: %1 = call i32 @b() br label %loop_latch %loop_latch: %v = load i1, ptr %ptr, align 1 br i1 %v, label %loop_begin, label %loop_exit %loop_exit: ret void } => define void @test_no_unswitch_noduplicate(ptr %ptr, i1 %cond) { %entry: br label %loop_begin %loop_begin: br i1 %cond, label %loop_a, label %loop_b %loop_a: %0 = call i32 @a() br label %loop_latch %loop_b: %1 = call i32 @b() br label %loop_latch %loop_latch: %v = load i1, ptr %ptr, align 1 br i1 %v, label %loop_begin, label %loop_exit %loop_exit: ret void } Transformation seems to be correct! (syntactically equal) ERROR: Unsupported instruction: %2 = invoke i32 @a() to label %loop_latch unwind label %loop_catch ---------------------------------------- define i32 @test1(ptr %ptr, i1 %cond1, i1 %cond2) { %entry: br label %loop_begin %loop_begin: br i1 %cond1, label %loop_a, label %loop_b %loop_a: %0 = call i32 @a() br label %latch %loop_b: br i1 %cond2, label %loop_b_a, label %loop_b_b %loop_b_a: %1 = call i32 @b() br label %latch %loop_b_b: %2 = call i32 @c() br label %latch %latch: %v = load i1, ptr %ptr, align 1 br i1 %v, label %loop_begin, label %loop_exit %loop_exit: ret i32 0 } => define i32 @test1(ptr %ptr, i1 %cond1, i1 %cond2) { %entry: br i1 %cond1, label %entry.split.us, label %entry.split %entry.split: br i1 %cond2, label %entry.split.split.us, label %entry.split.split %entry.split.split.us: br label %loop_begin.us1 %loop_begin.us1: br label %loop_b.us %loop_b.us: br label %loop_b_a.us %loop_b_a.us: %0 = call i32 @b() br label %latch.us2 %latch.us2: %v.us3 = load i1, ptr %ptr, align 1 br i1 %v.us3, label %loop_begin.us1, label %loop_exit.split.split.us %loop_exit.split.split.us: br label %loop_exit.split %entry.split.split: br label %loop_begin %loop_begin: br label %loop_b %loop_b: br label %loop_b_b %loop_b_b: %1 = call i32 @c() br label %latch %latch: %v = load i1, ptr %ptr, align 1 br i1 %v, label %loop_begin, label %loop_exit.split.split %loop_exit.split.split: br label %loop_exit.split %loop_exit.split: br label %loop_exit %entry.split.us: br label %loop_begin.us %loop_begin.us: br label %loop_a.us %loop_a.us: %2 = call i32 @a() br label %latch.us %latch.us: %v.us = load i1, ptr %ptr, align 1 br i1 %v.us, label %loop_begin.us, label %loop_exit.split.us %loop_exit.split.us: br label %loop_exit %loop_exit: ret i32 0 } Transformation seems to be correct! ---------------------------------------- define i32 @test2(ptr %ptr, i1 %cond1, ptr %a.ptr, ptr %b.ptr, ptr %c.ptr) { %entry: br label %loop_begin %loop_begin: %v = load i1, ptr %ptr, align 1 br i1 %cond1, label %loop_a, label %loop_b %loop_a: %a = load i32, ptr %a.ptr, align 4 %ac = load i32, ptr %c.ptr, align 4 br i1 %v, label %loop_begin, label %loop_exit %loop_b: %b = load i32, ptr %b.ptr, align 4 %bc = load i32, ptr %c.ptr, align 4 br i1 %v, label %loop_begin, label %loop_exit %loop_exit: %ab.phi = phi i32 [ %a, %loop_a ], [ %b, %loop_b ] %c.phi = phi i32 [ %ac, %loop_a ], [ %bc, %loop_b ] %result = add i32 %ab.phi, %c.phi ret i32 %result } => define i32 @test2(ptr %ptr, i1 %cond1, ptr %a.ptr, ptr %b.ptr, ptr %c.ptr) { %entry: br i1 %cond1, label %entry.split.us, label %entry.split %entry.split: br label %loop_begin %loop_begin: %v = load i1, ptr %ptr, align 1 br label %loop_b %loop_b: %b = load i32, ptr %b.ptr, align 4 %bc = load i32, ptr %c.ptr, align 4 br i1 %v, label %loop_begin.backedge, label %loop_exit.split %loop_begin.backedge: br label %loop_begin %loop_exit.split: %b.lcssa = phi i32 [ %b, %loop_b ] %bc.lcssa = phi i32 [ %bc, %loop_b ] br label %loop_exit %entry.split.us: br label %loop_begin.us %loop_begin.us: %v.us = load i1, ptr %ptr, align 1 br label %loop_a.us %loop_a.us: %a.us = load i32, ptr %a.ptr, align 4 %ac.us = load i32, ptr %c.ptr, align 4 br i1 %v.us, label %loop_begin.backedge.us, label %loop_exit.split.us %loop_begin.backedge.us: br label %loop_begin.us %loop_exit.split.us: %ab.phi.us = phi i32 [ %a.us, %loop_a.us ] %c.phi.us = phi i32 [ %ac.us, %loop_a.us ] br label %loop_exit %loop_exit: %.us-phi = phi i32 [ %b.lcssa, %loop_exit.split ], [ %ab.phi.us, %loop_exit.split.us ] %.us-phi1 = phi i32 [ %bc.lcssa, %loop_exit.split ], [ %c.phi.us, %loop_exit.split.us ] %result = add i32 %.us-phi, %.us-phi1 ret i32 %result } Transformation seems to be correct! ---------------------------------------- define i32 @test3a(ptr %ptr, i1 %cond1, ptr %a.ptr, ptr %b.ptr) { %entry: br label %loop_begin %loop_begin: %v = load i1, ptr %ptr, align 1 %a = load i32, ptr %a.ptr, align 4 br i1 %cond1, label %loop_exit, label %loop_b %loop_b: %b = load i32, ptr %b.ptr, align 4 br i1 %v, label %loop_begin, label %loop_exit %loop_exit: %ab.phi = phi i32 [ %a, %loop_begin ], [ %b, %loop_b ] ret i32 %ab.phi } => define i32 @test3a(ptr %ptr, i1 %cond1, ptr %a.ptr, ptr %b.ptr) { %entry: br i1 %cond1, label %entry.split.us, label %entry.split %entry.split: br label %loop_begin %loop_begin: %v = load i1, ptr %ptr, align 1 %a = load i32, ptr %a.ptr, align 4 br label %loop_b %loop_b: %b = load i32, ptr %b.ptr, align 4 br i1 %v, label %loop_begin, label %loop_exit.split %loop_exit.split: %ab.phi = phi i32 [ %b, %loop_b ] br label %loop_exit %entry.split.us: br label %loop_begin.us %loop_begin.us: %v.us = load i1, ptr %ptr, align 1 %a.us = load i32, ptr %a.ptr, align 4 br label %loop_exit.split.us %loop_exit.split.us: %ab.phi.us = phi i32 [ %a.us, %loop_begin.us ] br label %loop_exit %loop_exit: %.us-phi = phi i32 [ %ab.phi, %loop_exit.split ], [ %ab.phi.us, %loop_exit.split.us ] ret i32 %.us-phi } Transformation seems to be correct! ---------------------------------------- define i32 @test3b(ptr %ptr, i1 %cond1, ptr %a.ptr, ptr %b.ptr) { %entry: br label %loop_begin %loop_begin: %v = load i1, ptr %ptr, align 1 %a = load i32, ptr %a.ptr, align 4 br i1 %cond1, label %loop_b, label %loop_exit %loop_b: %b = load i32, ptr %b.ptr, align 4 br i1 %v, label %loop_begin, label %loop_exit %loop_exit: %ab.phi = phi i32 [ %b, %loop_b ], [ %a, %loop_begin ] ret i32 %ab.phi } => define i32 @test3b(ptr %ptr, i1 %cond1, ptr %a.ptr, ptr %b.ptr) { %entry: br i1 %cond1, label %entry.split.us, label %entry.split %entry.split: br label %loop_begin %loop_begin: %v = load i1, ptr %ptr, align 1 %a = load i32, ptr %a.ptr, align 4 br label %loop_exit.split %loop_exit.split: br label %loop_exit %entry.split.us: br label %loop_begin.us %loop_begin.us: %v.us = load i1, ptr %ptr, align 1 %a.us = load i32, ptr %a.ptr, align 4 br label %loop_b.us %loop_b.us: %b.us = load i32, ptr %b.ptr, align 4 br i1 %v.us, label %loop_begin.us, label %loop_exit.split.us %loop_exit.split.us: %ab.phi.us = phi i32 [ %b.us, %loop_b.us ] br label %loop_exit %loop_exit: %.us-phi = phi i32 [ %a, %loop_exit.split ], [ %ab.phi.us, %loop_exit.split.us ] ret i32 %.us-phi } Transformation seems to be correct! ---------------------------------------- define void @test4a(ptr %ptr, i1 %cond1, ptr %a.ptr, ptr %b.ptr) { %entry: br label %loop_begin %loop_begin: %v = load i1, ptr %ptr, align 1 %a = load i32, ptr %a.ptr, align 4 br i1 %cond1, label %loop_exit1, label %loop_b %loop_exit1: %a.phi = phi i32 [ %a, %loop_begin ] call void @sink1(i32 %a.phi) ret void %loop_b: %b = load i32, ptr %b.ptr, align 4 br i1 %v, label %loop_begin, label %loop_exit2 %loop_exit2: %b.phi = phi i32 [ %b, %loop_b ] call void @sink2(i32 %b.phi) ret void } => define void @test4a(ptr %ptr, i1 %cond1, ptr %a.ptr, ptr %b.ptr) { %entry: br i1 %cond1, label %entry.split.us, label %entry.split %entry.split: br label %loop_begin %loop_begin: %v = load i1, ptr %ptr, align 1 %a = load i32, ptr %a.ptr, align 4 br label %loop_b %loop_b: %b = load i32, ptr %b.ptr, align 4 br i1 %v, label %loop_begin, label %loop_exit2 %loop_exit2: %b.phi = phi i32 [ %b, %loop_b ] call void @sink2(i32 %b.phi) ret void %entry.split.us: br label %loop_begin.us %loop_begin.us: %v.us = load i1, ptr %ptr, align 1 %a.us = load i32, ptr %a.ptr, align 4 br label %loop_exit1.split.us %loop_exit1.split.us: %a.phi.us = phi i32 [ %a.us, %loop_begin.us ] br label %loop_exit1 %loop_exit1: call void @sink1(i32 %a.phi.us) ret void } Transformation seems to be correct! ---------------------------------------- define void @test4b(ptr %ptr, i1 %cond1, ptr %a.ptr, ptr %b.ptr) { %entry: br label %loop_begin %loop_begin: %v = load i1, ptr %ptr, align 1 %a = load i32, ptr %a.ptr, align 4 br i1 %cond1, label %loop_b, label %loop_exit1 %loop_b: %b = load i32, ptr %b.ptr, align 4 br i1 %v, label %loop_begin, label %loop_exit2 %loop_exit2: %b.phi = phi i32 [ %b, %loop_b ] call void @sink2(i32 %b.phi) ret void %loop_exit1: %a.phi = phi i32 [ %a, %loop_begin ] call void @sink1(i32 %a.phi) ret void } => define void @test4b(ptr %ptr, i1 %cond1, ptr %a.ptr, ptr %b.ptr) { %entry: br i1 %cond1, label %entry.split.us, label %entry.split %entry.split: br label %loop_begin %loop_begin: %v = load i1, ptr %ptr, align 1 %a = load i32, ptr %a.ptr, align 4 br label %loop_exit1 %loop_exit1: %a.phi = phi i32 [ %a, %loop_begin ] call void @sink1(i32 %a.phi) ret void %entry.split.us: br label %loop_begin.us %loop_begin.us: %v.us = load i1, ptr %ptr, align 1 %a.us = load i32, ptr %a.ptr, align 4 br label %loop_b.us %loop_b.us: %b.us = load i32, ptr %b.ptr, align 4 br i1 %v.us, label %loop_begin.us, label %loop_exit2.split.us %loop_exit2.split.us: %b.phi.us = phi i32 [ %b.us, %loop_b.us ] br label %loop_exit2 %loop_exit2: call void @sink2(i32 %b.phi.us) ret void } Transformation seems to be correct! ---------------------------------------- define void @test4c(ptr %ptr, i1 %cond1, ptr %a.ptr, ptr %b.ptr) { %entry: br label %loop_begin %loop_begin: %v = load i1, ptr %ptr, align 1 %a = load i32, ptr %a.ptr, align 4 br i1 %cond1, label %loop_exit1, label %loop_b %loop_exit1: %a.phi = phi i32 [ %a, %loop_begin ] call void @sink1(i32 %a.phi) br label %exit %loop_b: %b = load i32, ptr %b.ptr, align 4 br i1 %v, label %loop_begin, label %loop_exit2 %loop_exit2: %b.phi = phi i32 [ %b, %loop_b ] call void @sink2(i32 %b.phi) br label %exit %exit: ret void } => define void @test4c(ptr %ptr, i1 %cond1, ptr %a.ptr, ptr %b.ptr) { %entry: br i1 %cond1, label %entry.split.us, label %entry.split %entry.split: br label %loop_begin %loop_begin: %v = load i1, ptr %ptr, align 1 %a = load i32, ptr %a.ptr, align 4 br label %loop_b %loop_b: %b = load i32, ptr %b.ptr, align 4 br i1 %v, label %loop_begin, label %loop_exit2 %loop_exit2: %b.phi = phi i32 [ %b, %loop_b ] call void @sink2(i32 %b.phi) br label %exit %entry.split.us: br label %loop_begin.us %loop_begin.us: %v.us = load i1, ptr %ptr, align 1 %a.us = load i32, ptr %a.ptr, align 4 br label %loop_exit1.split.us %loop_exit1.split.us: %a.phi.us = phi i32 [ %a.us, %loop_begin.us ] br label %loop_exit1 %loop_exit1: call void @sink1(i32 %a.phi.us) br label %exit %exit: ret void } Transformation seems to be correct! ---------------------------------------- define i32 @test5(ptr %ptr, i1 %cond1, ptr %a.ptr, ptr %b.ptr) { %entry: br label %loop_begin %loop_begin: br label %inner_loop_begin %inner_loop_begin: %v = load i1, ptr %ptr, align 1 %a = load i32, ptr %a.ptr, align 4 br i1 %cond1, label %loop_exit, label %inner_loop_b %inner_loop_b: %b = load i32, ptr %b.ptr, align 4 br i1 %v, label %inner_loop_begin, label %loop_latch %loop_latch: %b.phi = phi i32 [ %b, %inner_loop_b ] %v2 = load i1, ptr %ptr, align 1 br i1 %v2, label %loop_begin, label %loop_exit %loop_exit: %ab.phi = phi i32 [ %a, %inner_loop_begin ], [ %b.phi, %loop_latch ] ret i32 %ab.phi } => define i32 @test5(ptr %ptr, i1 %cond1, ptr %a.ptr, ptr %b.ptr) { %entry: br i1 %cond1, label %loop_begin.split.us, label %entry.split %entry.split: br label %loop_begin %loop_begin: br label %loop_begin.split %loop_begin.split: br label %inner_loop_begin %inner_loop_begin: %v = load i1, ptr %ptr, align 1 %a = load i32, ptr %a.ptr, align 4 br label %inner_loop_b %inner_loop_b: %b = load i32, ptr %b.ptr, align 4 br i1 %v, label %inner_loop_begin, label %loop_latch %loop_latch: %b.phi = phi i32 [ %b, %inner_loop_b ] %v2 = load i1, ptr %ptr, align 1 br i1 %v2, label %loop_begin, label %loop_exit.loopexit1 %loop_exit.loopexit1: %b.phi.lcssa = phi i32 [ %b.phi, %loop_latch ] br label %loop_exit %loop_begin.split.us: br label %inner_loop_begin.us %inner_loop_begin.us: %v.us = load i1, ptr %ptr, align 1 %a.us = load i32, ptr %a.ptr, align 4 br label %loop_exit.loopexit.split.us %loop_exit.loopexit.split.us: %a.lcssa.us = phi i32 [ %a.us, %inner_loop_begin.us ] br label %loop_exit.loopexit %loop_exit.loopexit: br label %loop_exit %loop_exit: %ab.phi = phi i32 [ %a.lcssa.us, %loop_exit.loopexit ], [ %b.phi.lcssa, %loop_exit.loopexit1 ] ret i32 %ab.phi } Transformation seems to be correct! ---------------------------------------- define i32 @test6(ptr %ptr, i1 %cond1, ptr %a.ptr, ptr %b.ptr) { %entry: br label %loop_begin %loop_begin: %v = load i1, ptr %ptr, align 1 br i1 %cond1, label %loop_a, label %loop_b %loop_a: br label %loop_a_inner %loop_a_inner: %va = load i1, ptr %ptr, align 1 %a = load i32, ptr %a.ptr, align 4 br i1 %va, label %loop_a_inner, label %loop_a_inner_exit %loop_a_inner_exit: %a.lcssa = phi i32 [ %a, %loop_a_inner ] br label %latch %loop_b: br label %loop_b_inner %loop_b_inner: %vb = load i1, ptr %ptr, align 1 %b = load i32, ptr %b.ptr, align 4 br i1 %vb, label %loop_b_inner, label %loop_b_inner_exit %loop_b_inner_exit: %b.lcssa = phi i32 [ %b, %loop_b_inner ] br label %latch %latch: %ab.phi = phi i32 [ %a.lcssa, %loop_a_inner_exit ], [ %b.lcssa, %loop_b_inner_exit ] br i1 %v, label %loop_begin, label %loop_exit %loop_exit: %ab.lcssa = phi i32 [ %ab.phi, %latch ] ret i32 %ab.lcssa } => define i32 @test6(ptr %ptr, i1 %cond1, ptr %a.ptr, ptr %b.ptr) { %entry: br i1 %cond1, label %entry.split.us, label %entry.split %entry.split: br label %loop_begin %loop_begin: %v = load i1, ptr %ptr, align 1 br label %loop_b %loop_b: br label %loop_b_inner %loop_b_inner: %vb = load i1, ptr %ptr, align 1 %b = load i32, ptr %b.ptr, align 4 br i1 %vb, label %loop_b_inner, label %loop_b_inner_exit %loop_b_inner_exit: %b.lcssa = phi i32 [ %b, %loop_b_inner ] br label %latch %latch: br i1 %v, label %loop_begin, label %loop_exit.split %loop_exit.split: %ab.lcssa = phi i32 [ %b.lcssa, %latch ] br label %loop_exit %entry.split.us: br label %loop_begin.us %loop_begin.us: %v.us = load i1, ptr %ptr, align 1 br label %loop_a.us %loop_a.us: br label %loop_a_inner.us %loop_a_inner.us: %va.us = load i1, ptr %ptr, align 1 %a.us = load i32, ptr %a.ptr, align 4 br i1 %va.us, label %loop_a_inner.us, label %loop_a_inner_exit.us %loop_a_inner_exit.us: %a.lcssa.us = phi i32 [ %a.us, %loop_a_inner.us ] br label %latch.us %latch.us: %ab.phi.us = phi i32 [ %a.lcssa.us, %loop_a_inner_exit.us ] br i1 %v.us, label %loop_begin.us, label %loop_exit.split.us %loop_exit.split.us: %ab.lcssa.us = phi i32 [ %ab.phi.us, %latch.us ] br label %loop_exit %loop_exit: %.us-phi = phi i32 [ %ab.lcssa, %loop_exit.split ], [ %ab.lcssa.us, %loop_exit.split.us ] ret i32 %.us-phi } Transformation seems to be correct! ---------------------------------------- define i32 @test7a(ptr %ptr, ptr %cond.ptr, ptr %a.ptr, ptr %b.ptr) { %entry: br label %loop_begin %loop_begin: %a = load i32, ptr %a.ptr, align 4 br label %inner_loop_begin %inner_loop_begin: %a.phi = phi i32 [ %a, %loop_begin ], [ %a2, %inner_inner_loop_exit ] %cond = load i1, ptr %cond.ptr, align 1 %b = load i32, ptr %b.ptr, align 4 br label %inner_inner_loop_begin %inner_inner_loop_begin: %v1 = load i1, ptr %ptr, align 1 br i1 %v1, label %inner_inner_loop_a, label %inner_inner_loop_b %inner_inner_loop_a: %v2 = load i1, ptr %ptr, align 1 br i1 %v2, label %loop_exit, label %inner_inner_loop_c %loop_exit: %a.lcssa = phi i32 [ %a.phi, %inner_inner_loop_a ] %b.lcssa = phi i32 [ %b, %inner_inner_loop_a ] %result = add i32 %a.lcssa, %b.lcssa ret i32 %result %inner_inner_loop_b: %v3 = load i1, ptr %ptr, align 1 br i1 %v3, label %inner_inner_loop_exit, label %inner_inner_loop_c %inner_inner_loop_exit: %a2 = load i32, ptr %a.ptr, align 4 %v5 = load i1, ptr %ptr, align 1 br i1 %v5, label %inner_loop_exit, label %inner_loop_begin %inner_inner_loop_c: %v4 = load i1, ptr %ptr, align 1 br i1 %v4, label %inner_loop_exit, label %inner_inner_loop_d %inner_inner_loop_d: br i1 %cond, label %inner_loop_exit, label %inner_inner_loop_begin %inner_loop_exit: br label %loop_begin } => define i32 @test7a(ptr %ptr, ptr %cond.ptr, ptr %a.ptr, ptr %b.ptr) { %entry: br label %loop_begin %loop_begin: %a = load i32, ptr %a.ptr, align 4 br label %inner_loop_begin %inner_loop_begin: %a.phi = phi i32 [ %a, %loop_begin ], [ %a2, %inner_inner_loop_exit ] %cond = load i1, ptr %cond.ptr, align 1 %b = load i32, ptr %b.ptr, align 4 %cond.fr = freeze i1 %cond br i1 %cond.fr, label %inner_loop_begin.split.us, label %inner_loop_begin.split %inner_loop_begin.split.us: br label %inner_inner_loop_begin.us %inner_inner_loop_begin.us: %v1.us = load i1, ptr %ptr, align 1 br i1 %v1.us, label %inner_inner_loop_a.us, label %inner_inner_loop_b.us %inner_inner_loop_a.us: %a.phi.lcssa10 = phi i32 [ %a.phi, %inner_inner_loop_begin.us ] %b.lcssa6 = phi i32 [ %b, %inner_inner_loop_begin.us ] %v2.us = load i1, ptr %ptr, align 1 br i1 %v2.us, label %loop_exit.split.us, label %inner_inner_loop_c.us %loop_exit.split.us: %a.lcssa.us = phi i32 [ %a.phi.lcssa10, %inner_inner_loop_a.us ] %b.lcssa.us = phi i32 [ %b.lcssa6, %inner_inner_loop_a.us ] br label %loop_exit %inner_inner_loop_b.us: %v3.us = load i1, ptr %ptr, align 1 br i1 %v3.us, label %inner_inner_loop_exit.split.us, label %inner_inner_loop_c.us.loopexit %inner_inner_loop_exit.split.us: br label %inner_inner_loop_exit %inner_inner_loop_c.us.loopexit: br label %inner_inner_loop_c.us %inner_inner_loop_c.us: %v4.us = load i1, ptr %ptr, align 1 br i1 %v4.us, label %inner_loop_exit.loopexit.split.us, label %inner_inner_loop_d.us %inner_inner_loop_d.us: br label %inner_loop_exit.loopexit.split.us %inner_loop_exit.loopexit.split.us: br label %inner_loop_exit.loopexit %inner_loop_begin.split: br label %inner_inner_loop_begin %inner_inner_loop_begin: %v1 = load i1, ptr %ptr, align 1 br i1 %v1, label %inner_inner_loop_a, label %inner_inner_loop_b %inner_inner_loop_a: %v2 = load i1, ptr %ptr, align 1 br i1 %v2, label %loop_exit.split, label %inner_inner_loop_c %loop_exit.split: %a.lcssa = phi i32 [ %a.phi, %inner_inner_loop_a ] %b.lcssa = phi i32 [ %b, %inner_inner_loop_a ] br label %loop_exit %loop_exit: %.us-phi = phi i32 [ %a.lcssa, %loop_exit.split ], [ %a.lcssa.us, %loop_exit.split.us ] %.us-phi2 = phi i32 [ %b.lcssa, %loop_exit.split ], [ %b.lcssa.us, %loop_exit.split.us ] %result = add i32 %.us-phi, %.us-phi2 ret i32 %result %inner_inner_loop_b: %v3 = load i1, ptr %ptr, align 1 br i1 %v3, label %inner_inner_loop_exit.split, label %inner_inner_loop_c %inner_inner_loop_exit.split: br label %inner_inner_loop_exit %inner_inner_loop_exit: %a2 = load i32, ptr %a.ptr, align 4 %v5 = load i1, ptr %ptr, align 1 br i1 %v5, label %inner_loop_exit.loopexit1, label %inner_loop_begin %inner_loop_exit.loopexit1: br label %inner_loop_exit %inner_inner_loop_c: %v4 = load i1, ptr %ptr, align 1 br i1 %v4, label %inner_loop_exit.loopexit.split, label %inner_inner_loop_d %inner_loop_exit.loopexit.split: br label %inner_loop_exit.loopexit %inner_loop_exit.loopexit: br label %inner_loop_exit %inner_loop_exit: br label %loop_begin %inner_inner_loop_d: br label %inner_inner_loop_begin } Transformation seems to be correct! ---------------------------------------- define i32 @test7b(ptr %ptr, ptr %cond.ptr, ptr %a.ptr, ptr %b.ptr) { %entry: br label %loop_begin %loop_begin: %a = load i32, ptr %a.ptr, align 4 br label %inner_loop_begin %inner_loop_begin: %a.phi = phi i32 [ %a, %loop_begin ], [ %a2, %inner_inner_loop_exit ] %cond = load i1, ptr %cond.ptr, align 1 %b = load i32, ptr %b.ptr, align 4 br label %inner_inner_loop_begin %inner_inner_loop_begin: %v1 = load i1, ptr %ptr, align 1 br i1 %v1, label %inner_inner_loop_a, label %inner_inner_loop_b %inner_inner_loop_a: %v2 = load i1, ptr %ptr, align 1 br i1 %v2, label %loop_exit, label %inner_inner_loop_c %loop_exit: %a.lcssa = phi i32 [ %a.phi, %inner_inner_loop_a ] %b.lcssa = phi i32 [ %b, %inner_inner_loop_a ] %result = add i32 %a.lcssa, %b.lcssa ret i32 %result %inner_inner_loop_b: %v3 = load i1, ptr %ptr, align 1 br i1 %v3, label %inner_inner_loop_exit, label %inner_inner_loop_c %inner_inner_loop_exit: %a2 = load i32, ptr %a.ptr, align 4 %v5 = load i1, ptr %ptr, align 1 br i1 %v5, label %inner_loop_exit, label %inner_loop_begin %inner_inner_loop_c: %v4 = load i1, ptr %ptr, align 1 br i1 %v4, label %inner_loop_exit, label %inner_inner_loop_d %inner_inner_loop_d: br i1 %cond, label %inner_inner_loop_begin, label %inner_loop_exit %inner_loop_exit: br label %loop_begin } => define i32 @test7b(ptr %ptr, ptr %cond.ptr, ptr %a.ptr, ptr %b.ptr) { %entry: br label %loop_begin %loop_begin: %a = load i32, ptr %a.ptr, align 4 br label %inner_loop_begin %inner_loop_begin: %a.phi = phi i32 [ %a, %loop_begin ], [ %a2, %inner_inner_loop_exit ] %cond = load i1, ptr %cond.ptr, align 1 %b = load i32, ptr %b.ptr, align 4 %cond.fr = freeze i1 %cond br i1 %cond.fr, label %inner_loop_begin.split.us, label %inner_loop_begin.split %inner_loop_begin.split.us: br label %inner_inner_loop_begin.us %inner_inner_loop_begin.us: %v1.us = load i1, ptr %ptr, align 1 br i1 %v1.us, label %inner_inner_loop_a.us, label %inner_inner_loop_b.us %inner_inner_loop_a.us: %v2.us = load i1, ptr %ptr, align 1 br i1 %v2.us, label %loop_exit.split.us, label %inner_inner_loop_c.us %loop_exit.split.us: %a.lcssa.us = phi i32 [ %a.phi, %inner_inner_loop_a.us ] %b.lcssa.us = phi i32 [ %b, %inner_inner_loop_a.us ] br label %loop_exit %inner_inner_loop_b.us: %v3.us = load i1, ptr %ptr, align 1 br i1 %v3.us, label %inner_inner_loop_exit.split.us, label %inner_inner_loop_c.us %inner_inner_loop_exit.split.us: br label %inner_inner_loop_exit %inner_inner_loop_c.us: %v4.us = load i1, ptr %ptr, align 1 br i1 %v4.us, label %inner_loop_exit.loopexit.split.us, label %inner_inner_loop_d.us %inner_loop_exit.loopexit.split.us: br label %inner_loop_exit.loopexit %inner_inner_loop_d.us: br label %inner_inner_loop_begin.us %inner_loop_begin.split: br label %inner_inner_loop_begin %inner_inner_loop_begin: %v1 = load i1, ptr %ptr, align 1 br i1 %v1, label %inner_inner_loop_a, label %inner_inner_loop_b %inner_inner_loop_a: %a.phi.lcssa = phi i32 [ %a.phi, %inner_inner_loop_begin ] %b.lcssa3 = phi i32 [ %b, %inner_inner_loop_begin ] %v2 = load i1, ptr %ptr, align 1 br i1 %v2, label %loop_exit.split, label %inner_inner_loop_c %loop_exit.split: %a.lcssa = phi i32 [ %a.phi.lcssa, %inner_inner_loop_a ] %b.lcssa = phi i32 [ %b.lcssa3, %inner_inner_loop_a ] br label %loop_exit %loop_exit: %.us-phi = phi i32 [ %a.lcssa, %loop_exit.split ], [ %a.lcssa.us, %loop_exit.split.us ] %.us-phi2 = phi i32 [ %b.lcssa, %loop_exit.split ], [ %b.lcssa.us, %loop_exit.split.us ] %result = add i32 %.us-phi, %.us-phi2 ret i32 %result %inner_inner_loop_b: %v3 = load i1, ptr %ptr, align 1 br i1 %v3, label %inner_inner_loop_exit.split, label %inner_inner_loop_c.loopexit %inner_inner_loop_exit.split: br label %inner_inner_loop_exit %inner_inner_loop_exit: %a2 = load i32, ptr %a.ptr, align 4 %v5 = load i1, ptr %ptr, align 1 br i1 %v5, label %inner_loop_exit.loopexit1, label %inner_loop_begin %inner_loop_exit.loopexit1: br label %inner_loop_exit %inner_inner_loop_c.loopexit: br label %inner_inner_loop_c %inner_inner_loop_c: %v4 = load i1, ptr %ptr, align 1 br i1 %v4, label %inner_loop_exit.loopexit.split, label %inner_inner_loop_d %inner_inner_loop_d: br label %inner_loop_exit.loopexit.split %inner_loop_exit.loopexit.split: br label %inner_loop_exit.loopexit %inner_loop_exit.loopexit: br label %inner_loop_exit %inner_loop_exit: br label %loop_begin } Transformation seems to be correct! ---------------------------------------- define i32 @test8a(ptr %ptr, ptr %cond.ptr, ptr %a.ptr, ptr %b.ptr) { %entry: br label %loop_begin %loop_begin: %a = load i32, ptr %a.ptr, align 4 br label %inner_loop_begin %inner_loop_begin: %a.phi = phi i32 [ %a, %loop_begin ], [ %a2, %inner_inner_loop_exit ] %cond = load i1, ptr %cond.ptr, align 1 %b = load i32, ptr %b.ptr, align 4 br label %inner_inner_loop_begin %inner_inner_loop_begin: %v1 = load i1, ptr %ptr, align 1 br i1 %v1, label %inner_inner_loop_a, label %inner_inner_loop_b %inner_inner_loop_a: %v2 = load i1, ptr %ptr, align 1 br i1 %v2, label %inner_inner_loop_latch, label %inner_loop_exit %inner_inner_loop_b: br i1 %cond, label %inner_inner_loop_latch, label %inner_inner_loop_exit %inner_inner_loop_latch: br label %inner_inner_loop_begin %inner_inner_loop_exit: %a2 = load i32, ptr %a.ptr, align 4 %v4 = load i1, ptr %ptr, align 1 br i1 %v4, label %inner_loop_exit, label %inner_loop_begin %inner_loop_exit: %v5 = load i1, ptr %ptr, align 1 br i1 %v5, label %loop_exit, label %loop_begin %loop_exit: %a.lcssa = phi i32 [ %a.phi, %inner_loop_exit ] ret i32 %a.lcssa } => define i32 @test8a(ptr %ptr, ptr %cond.ptr, ptr %a.ptr, ptr %b.ptr) { %entry: br label %loop_begin %loop_begin: %a = load i32, ptr %a.ptr, align 4 br label %inner_loop_begin %inner_loop_begin: %a.phi = phi i32 [ %a, %loop_begin ], [ %a2, %inner_inner_loop_exit ] %cond = load i1, ptr %cond.ptr, align 1 %b = load i32, ptr %b.ptr, align 4 %cond.fr = freeze i1 %cond br i1 %cond.fr, label %inner_loop_begin.split.us, label %inner_loop_begin.split %inner_loop_begin.split.us: %a.phi.lcssa4 = phi i32 [ %a.phi, %inner_loop_begin ] br label %inner_inner_loop_begin.us %inner_inner_loop_begin.us: %v1.us = load i1, ptr %ptr, align 1 br i1 %v1.us, label %inner_inner_loop_a.us, label %inner_inner_loop_b.us %inner_inner_loop_a.us: %v2.us = load i1, ptr %ptr, align 1 br i1 %v2.us, label %inner_inner_loop_latch.us, label %inner_loop_exit.loopexit.split.us %inner_loop_exit.loopexit.split.us: %a.phi.lcssa2.us = phi i32 [ %a.phi.lcssa4, %inner_inner_loop_a.us ] br label %inner_loop_exit.loopexit %inner_inner_loop_b.us: br label %inner_inner_loop_latch.us %inner_inner_loop_latch.us: br label %inner_inner_loop_begin.us %inner_loop_begin.split: br label %inner_inner_loop_begin %inner_inner_loop_begin: %v1 = load i1, ptr %ptr, align 1 br i1 %v1, label %inner_inner_loop_a, label %inner_inner_loop_b %inner_inner_loop_a: %v2 = load i1, ptr %ptr, align 1 br i1 %v2, label %inner_inner_loop_latch, label %inner_loop_exit.loopexit.split %inner_inner_loop_latch: br label %inner_inner_loop_begin %inner_loop_exit.loopexit.split: %a.phi.lcssa2 = phi i32 [ %a.phi, %inner_inner_loop_a ] br label %inner_loop_exit.loopexit %inner_loop_exit.loopexit: %.us-phi = phi i32 [ %a.phi.lcssa2, %inner_loop_exit.loopexit.split ], [ %a.phi.lcssa2.us, %inner_loop_exit.loopexit.split.us ] br label %inner_loop_exit %inner_inner_loop_b: br label %inner_inner_loop_exit %inner_inner_loop_exit: %a2 = load i32, ptr %a.ptr, align 4 %v4 = load i1, ptr %ptr, align 1 br i1 %v4, label %inner_loop_exit.loopexit1, label %inner_loop_begin %inner_loop_exit.loopexit1: %a.phi.lcssa = phi i32 [ %a.phi, %inner_inner_loop_exit ] br label %inner_loop_exit %inner_loop_exit: %a.phi3 = phi i32 [ %a.phi.lcssa, %inner_loop_exit.loopexit1 ], [ %.us-phi, %inner_loop_exit.loopexit ] %v5 = load i1, ptr %ptr, align 1 br i1 %v5, label %loop_exit, label %loop_begin %loop_exit: %a.lcssa = phi i32 [ %a.phi3, %inner_loop_exit ] ret i32 %a.lcssa } Transformation doesn't verify! ERROR: The source program doesn't reach a return instruction. Consider increasing the unroll factor if it has loops ---------------------------------------- define i32 @test8b(ptr %ptr, ptr %cond.ptr, ptr %a.ptr, ptr %b.ptr) { %entry: br label %loop_begin %loop_begin: %a = load i32, ptr %a.ptr, align 4 br label %inner_loop_begin %inner_loop_begin: %a.phi = phi i32 [ %a, %loop_begin ], [ %a2, %inner_inner_loop_exit ] %cond = load i1, ptr %cond.ptr, align 1 %b = load i32, ptr %b.ptr, align 4 br label %inner_inner_loop_begin %inner_inner_loop_begin: %v1 = load i1, ptr %ptr, align 1 br i1 %v1, label %inner_inner_loop_a, label %inner_inner_loop_b %inner_inner_loop_a: %v2 = load i1, ptr %ptr, align 1 br i1 %v2, label %inner_inner_loop_latch, label %inner_loop_exit %inner_inner_loop_b: br i1 %cond, label %inner_inner_loop_exit, label %inner_inner_loop_latch %inner_inner_loop_exit: %a2 = load i32, ptr %a.ptr, align 4 %v4 = load i1, ptr %ptr, align 1 br i1 %v4, label %inner_loop_exit, label %inner_loop_begin %inner_loop_exit: %v5 = load i1, ptr %ptr, align 1 br i1 %v5, label %loop_exit, label %loop_begin %loop_exit: %a.lcssa = phi i32 [ %a.phi, %inner_loop_exit ] ret i32 %a.lcssa %inner_inner_loop_latch: br label %inner_inner_loop_begin } => define i32 @test8b(ptr %ptr, ptr %cond.ptr, ptr %a.ptr, ptr %b.ptr) { %entry: br label %loop_begin %loop_begin: %a = load i32, ptr %a.ptr, align 4 br label %inner_loop_begin %inner_loop_begin: %a.phi = phi i32 [ %a, %loop_begin ], [ %a2, %inner_inner_loop_exit ] %cond = load i1, ptr %cond.ptr, align 1 %b = load i32, ptr %b.ptr, align 4 %cond.fr = freeze i1 %cond br i1 %cond.fr, label %inner_loop_begin.split.us, label %inner_loop_begin.split %inner_loop_begin.split.us: br label %inner_inner_loop_begin.us %inner_inner_loop_begin.us: %v1.us = load i1, ptr %ptr, align 1 br i1 %v1.us, label %inner_inner_loop_a.us, label %inner_inner_loop_b.us %inner_inner_loop_a.us: %v2.us = load i1, ptr %ptr, align 1 br i1 %v2.us, label %inner_inner_loop_latch.us, label %inner_loop_exit.loopexit.split.us %inner_inner_loop_latch.us: br label %inner_inner_loop_begin.us %inner_loop_exit.loopexit.split.us: %a.phi.lcssa2.us = phi i32 [ %a.phi, %inner_inner_loop_a.us ] br label %inner_loop_exit.loopexit %inner_inner_loop_b.us: br label %inner_inner_loop_exit.split.us %inner_inner_loop_exit.split.us: br label %inner_inner_loop_exit %inner_inner_loop_exit: %a2 = load i32, ptr %a.ptr, align 4 %v4 = load i1, ptr %ptr, align 1 br i1 %v4, label %inner_loop_exit.loopexit1, label %inner_loop_begin %inner_loop_exit.loopexit1: %a.phi.lcssa = phi i32 [ %a.phi, %inner_inner_loop_exit ] br label %inner_loop_exit %inner_loop_begin.split: %a.phi.lcssa4 = phi i32 [ %a.phi, %inner_loop_begin ] br label %inner_inner_loop_begin %inner_inner_loop_begin: %v1 = load i1, ptr %ptr, align 1 br i1 %v1, label %inner_inner_loop_a, label %inner_inner_loop_b %inner_inner_loop_a: %v2 = load i1, ptr %ptr, align 1 br i1 %v2, label %inner_inner_loop_latch, label %inner_loop_exit.loopexit.split %inner_loop_exit.loopexit.split: %a.phi.lcssa2 = phi i32 [ %a.phi.lcssa4, %inner_inner_loop_a ] br label %inner_loop_exit.loopexit %inner_loop_exit.loopexit: %.us-phi = phi i32 [ %a.phi.lcssa2, %inner_loop_exit.loopexit.split ], [ %a.phi.lcssa2.us, %inner_loop_exit.loopexit.split.us ] br label %inner_loop_exit %inner_loop_exit: %a.phi3 = phi i32 [ %a.phi.lcssa, %inner_loop_exit.loopexit1 ], [ %.us-phi, %inner_loop_exit.loopexit ] %v5 = load i1, ptr %ptr, align 1 br i1 %v5, label %loop_exit, label %loop_begin %loop_exit: %a.lcssa = phi i32 [ %a.phi3, %inner_loop_exit ] ret i32 %a.lcssa %inner_inner_loop_b: br label %inner_inner_loop_latch %inner_inner_loop_latch: br label %inner_inner_loop_begin } Transformation doesn't verify! ERROR: The source program doesn't reach a return instruction. Consider increasing the unroll factor if it has loops ---------------------------------------- define i32 @test9a(ptr %ptr, ptr %cond.ptr, ptr %a.ptr, ptr %b.ptr) { %entry: br label %loop_begin %loop_begin: %b = load i32, ptr %b.ptr, align 4 %cond = load i1, ptr %cond.ptr, align 1 br label %inner_loop_begin %inner_loop_begin: %a = load i32, ptr %a.ptr, align 4 br i1 %cond, label %inner_loop_latch, label %inner_loop_exit %inner_loop_latch: call void @sink1(i32 %b) br label %inner_loop_begin %inner_loop_exit: %a.inner_lcssa = phi i32 [ %a, %inner_loop_begin ] %v = load i1, ptr %ptr, align 1 br i1 %v, label %loop_begin, label %loop_exit %loop_exit: %a.lcssa = phi i32 [ %a.inner_lcssa, %inner_loop_exit ] ret i32 %a.lcssa } => define i32 @test9a(ptr %ptr, ptr %cond.ptr, ptr %a.ptr, ptr %b.ptr) { %entry: br label %loop_begin %loop_begin: %b = load i32, ptr %b.ptr, align 4 %cond = load i1, ptr %cond.ptr, align 1 br i1 %cond, label %loop_begin.split.us, label %loop_begin.split %loop_begin.split.us: %b.lcssa = phi i32 [ %b, %loop_begin ] br label %inner_loop_begin.us %inner_loop_begin.us: %a.us = load i32, ptr %a.ptr, align 4 br label %inner_loop_latch.us %inner_loop_latch.us: call void @sink1(i32 %b.lcssa) br label %inner_loop_begin.us %loop_begin.split: br label %inner_loop_begin %inner_loop_begin: %a = load i32, ptr %a.ptr, align 4 br label %inner_loop_exit %inner_loop_exit: %a.inner_lcssa = phi i32 [ %a, %inner_loop_begin ] %v = load i1, ptr %ptr, align 1 br i1 %v, label %loop_begin, label %loop_exit %loop_exit: %a.lcssa = phi i32 [ %a.inner_lcssa, %inner_loop_exit ] ret i32 %a.lcssa } Transformation seems to be correct! ---------------------------------------- define i32 @test9b(ptr %ptr, ptr %cond.ptr, ptr %a.ptr, ptr %b.ptr) { %entry: br label %loop_begin %loop_begin: %b = load i32, ptr %b.ptr, align 4 %cond = load i1, ptr %cond.ptr, align 1 br label %inner_loop_begin %inner_loop_begin: %a = load i32, ptr %a.ptr, align 4 br i1 %cond, label %inner_loop_exit, label %inner_loop_latch %inner_loop_exit: %a.inner_lcssa = phi i32 [ %a, %inner_loop_begin ] %v = load i1, ptr %ptr, align 1 br i1 %v, label %loop_begin, label %loop_exit %loop_exit: %a.lcssa = phi i32 [ %a.inner_lcssa, %inner_loop_exit ] ret i32 %a.lcssa %inner_loop_latch: call void @sink1(i32 %b) br label %inner_loop_begin } => define i32 @test9b(ptr %ptr, ptr %cond.ptr, ptr %a.ptr, ptr %b.ptr) { %entry: br label %loop_begin %loop_begin: %b = load i32, ptr %b.ptr, align 4 %cond = load i1, ptr %cond.ptr, align 1 br i1 %cond, label %loop_begin.split.us, label %loop_begin.split %loop_begin.split.us: br label %inner_loop_begin.us %inner_loop_begin.us: %a.us = load i32, ptr %a.ptr, align 4 br label %inner_loop_exit.split.us %inner_loop_exit.split.us: %a.inner_lcssa.us = phi i32 [ %a.us, %inner_loop_begin.us ] br label %inner_loop_exit %inner_loop_exit: %v = load i1, ptr %ptr, align 1 br i1 %v, label %loop_begin, label %loop_exit %loop_exit: %a.lcssa = phi i32 [ %a.inner_lcssa.us, %inner_loop_exit ] ret i32 %a.lcssa %loop_begin.split: %b.lcssa = phi i32 [ %b, %loop_begin ] br label %inner_loop_begin %inner_loop_begin: %a = load i32, ptr %a.ptr, align 4 br label %inner_loop_latch %inner_loop_latch: call void @sink1(i32 %b.lcssa) br label %inner_loop_begin } Transformation seems to be correct! ---------------------------------------- define i32 @test10a(ptr %ptr, i1 %cond, ptr %a.ptr) { %entry: br label %loop_begin %loop_begin: %a = load i32, ptr %a.ptr, align 4 %v1 = load i1, ptr %ptr, align 1 br i1 %v1, label %loop_a, label %loop_b %loop_a: %v2 = load i1, ptr %ptr, align 1 br i1 %v2, label %loop_exit, label %loop_begin %loop_b: br i1 %cond, label %loop_exit, label %loop_begin %loop_exit: %a.lcssa = phi i32 [ %a, %loop_a ], [ %a, %loop_b ] ret i32 %a.lcssa } => define i32 @test10a(ptr %ptr, i1 %cond, ptr %a.ptr) { %entry: %cond.fr = freeze i1 %cond br i1 %cond.fr, label %entry.split.us, label %entry.split %entry.split: br label %loop_begin %loop_begin: %a = load i32, ptr %a.ptr, align 4 %v1 = load i1, ptr %ptr, align 1 br i1 %v1, label %loop_a, label %loop_b %loop_a: %v2 = load i1, ptr %ptr, align 1 br i1 %v2, label %loop_exit.split, label %loop_begin.backedge %loop_exit.split: %a.lcssa = phi i32 [ %a, %loop_a ] br label %loop_exit %loop_b: br label %loop_begin.backedge %loop_begin.backedge: br label %loop_begin %entry.split.us: br label %loop_begin.us %loop_begin.us: %a.us = load i32, ptr %a.ptr, align 4 %v1.us = load i1, ptr %ptr, align 1 br i1 %v1.us, label %loop_a.us, label %loop_b.us %loop_a.us: %v2.us = load i1, ptr %ptr, align 1 br i1 %v2.us, label %loop_exit.split.us.loopexit, label %loop_begin.backedge.us %loop_exit.split.us.loopexit: %a.lcssa.us.ph = phi i32 [ %a.us, %loop_a.us ] br label %loop_exit.split.us %loop_begin.backedge.us: br label %loop_begin.us %loop_b.us: %a.us.lcssa = phi i32 [ %a.us, %loop_begin.us ] br label %loop_exit.split.us %loop_exit.split.us: %a.lcssa.us = phi i32 [ %a.us.lcssa, %loop_b.us ], [ %a.lcssa.us.ph, %loop_exit.split.us.loopexit ] br label %loop_exit %loop_exit: %.us-phi = phi i32 [ %a.lcssa, %loop_exit.split ], [ %a.lcssa.us, %loop_exit.split.us ] ret i32 %.us-phi } Transformation seems to be correct! ---------------------------------------- define i32 @test10b(ptr %ptr, i1 %cond, ptr %a.ptr) { %entry: br label %loop_begin %loop_begin: %a = load i32, ptr %a.ptr, align 4 %v1 = load i1, ptr %ptr, align 1 br i1 %v1, label %loop_a, label %loop_b %loop_a: %v2 = load i1, ptr %ptr, align 1 br i1 %v2, label %loop_begin, label %loop_exit %loop_b: br i1 %cond, label %loop_begin, label %loop_exit %loop_exit: %a.lcssa = phi i32 [ %a, %loop_a ], [ %a, %loop_b ] ret i32 %a.lcssa } => define i32 @test10b(ptr %ptr, i1 %cond, ptr %a.ptr) { %entry: %cond.fr = freeze i1 %cond br i1 %cond.fr, label %entry.split.us, label %entry.split %entry.split: br label %loop_begin %loop_begin: %a = load i32, ptr %a.ptr, align 4 %v1 = load i1, ptr %ptr, align 1 br i1 %v1, label %loop_a, label %loop_b %loop_a: %v2 = load i1, ptr %ptr, align 1 br i1 %v2, label %loop_begin.backedge, label %loop_exit.split.loopexit %loop_begin.backedge: br label %loop_begin %loop_exit.split.loopexit: %a.lcssa.ph = phi i32 [ %a, %loop_a ] br label %loop_exit.split %loop_b: %a.lcssa1 = phi i32 [ %a, %loop_begin ] br label %loop_exit.split %loop_exit.split: %a.lcssa = phi i32 [ %a.lcssa1, %loop_b ], [ %a.lcssa.ph, %loop_exit.split.loopexit ] br label %loop_exit %entry.split.us: br label %loop_begin.us %loop_begin.us: %a.us = load i32, ptr %a.ptr, align 4 %v1.us = load i1, ptr %ptr, align 1 br i1 %v1.us, label %loop_a.us, label %loop_b.us %loop_a.us: %v2.us = load i1, ptr %ptr, align 1 br i1 %v2.us, label %loop_begin.backedge.us, label %loop_exit.split.us %loop_exit.split.us: %a.lcssa.us = phi i32 [ %a.us, %loop_a.us ] br label %loop_exit %loop_exit: %.us-phi = phi i32 [ %a.lcssa, %loop_exit.split ], [ %a.lcssa.us, %loop_exit.split.us ] ret i32 %.us-phi %loop_b.us: br label %loop_begin.backedge.us %loop_begin.backedge.us: br label %loop_begin.us } Transformation seems to be correct! ---------------------------------------- define i32 @test11a(ptr %ptr, ptr %cond.ptr, ptr %a.ptr, ptr %b.ptr) { %entry: br label %loop_begin %loop_begin: %b = load i32, ptr %b.ptr, align 4 %v1 = load i1, ptr %ptr, align 1 br i1 %v1, label %loop_latch, label %inner_loop_ph %inner_loop_ph: %cond = load i1, ptr %cond.ptr, align 1 br label %inner_loop_begin %inner_loop_begin: call void @sink1(i32 %b) %a = load i32, ptr %a.ptr, align 4 br i1 %cond, label %loop_exit, label %inner_loop_a %inner_loop_a: %v2 = load i1, ptr %ptr, align 1 br i1 %v2, label %inner_loop_exit, label %inner_loop_begin %inner_loop_exit: %a.inner_lcssa = phi i32 [ %a, %inner_loop_a ] %v3 = load i1, ptr %ptr, align 1 br i1 %v3, label %loop_latch, label %loop_exit %loop_latch: br label %loop_begin %loop_exit: %a.lcssa = phi i32 [ %a, %inner_loop_begin ], [ %a.inner_lcssa, %inner_loop_exit ] ret i32 %a.lcssa } => define i32 @test11a(ptr %ptr, ptr %cond.ptr, ptr %a.ptr, ptr %b.ptr) { %entry: br label %loop_begin %loop_begin: %b = load i32, ptr %b.ptr, align 4 %v1 = load i1, ptr %ptr, align 1 br i1 %v1, label %loop_latch, label %inner_loop_ph %inner_loop_ph: %cond = load i1, ptr %cond.ptr, align 1 %cond.fr = freeze i1 %cond br i1 %cond.fr, label %inner_loop_ph.split.us, label %inner_loop_ph.split %inner_loop_ph.split.us: %b.lcssa = phi i32 [ %b, %inner_loop_ph ] br label %inner_loop_begin.us %inner_loop_begin.us: call void @sink1(i32 %b.lcssa) %a.us = load i32, ptr %a.ptr, align 4 br label %loop_exit.loopexit.split.us %loop_exit.loopexit.split.us: %a.lcssa2.us = phi i32 [ %a.us, %inner_loop_begin.us ] br label %loop_exit.loopexit %loop_exit.loopexit: br label %loop_exit %inner_loop_ph.split: br label %inner_loop_begin %inner_loop_begin: call void @sink1(i32 %b) %a = load i32, ptr %a.ptr, align 4 br label %inner_loop_a %inner_loop_a: %v2 = load i1, ptr %ptr, align 1 br i1 %v2, label %inner_loop_exit, label %inner_loop_begin %inner_loop_exit: %a.inner_lcssa = phi i32 [ %a, %inner_loop_a ] %v3 = load i1, ptr %ptr, align 1 br i1 %v3, label %loop_latch, label %loop_exit.loopexit1 %loop_latch: br label %loop_begin %loop_exit.loopexit1: %a.inner_lcssa.lcssa = phi i32 [ %a.inner_lcssa, %inner_loop_exit ] br label %loop_exit %loop_exit: %a.lcssa = phi i32 [ %a.lcssa2.us, %loop_exit.loopexit ], [ %a.inner_lcssa.lcssa, %loop_exit.loopexit1 ] ret i32 %a.lcssa } Transformation seems to be correct! ---------------------------------------- define i32 @test11b(ptr %ptr, ptr %cond.ptr, ptr %a.ptr, ptr %b.ptr) { %entry: br label %loop_begin %loop_begin: %b = load i32, ptr %b.ptr, align 4 %v1 = load i1, ptr %ptr, align 1 br i1 %v1, label %loop_latch, label %inner_loop_ph %inner_loop_ph: %cond = load i1, ptr %cond.ptr, align 1 br label %inner_loop_begin %inner_loop_begin: call void @sink1(i32 %b) %a = load i32, ptr %a.ptr, align 4 br i1 %cond, label %inner_loop_a, label %loop_exit %inner_loop_a: %v2 = load i1, ptr %ptr, align 1 br i1 %v2, label %inner_loop_exit, label %inner_loop_begin %inner_loop_exit: %a.inner_lcssa = phi i32 [ %a, %inner_loop_a ] %v3 = load i1, ptr %ptr, align 1 br i1 %v3, label %loop_latch, label %loop_exit %loop_latch: br label %loop_begin %loop_exit: %a.lcssa = phi i32 [ %a, %inner_loop_begin ], [ %a.inner_lcssa, %inner_loop_exit ] ret i32 %a.lcssa } => define i32 @test11b(ptr %ptr, ptr %cond.ptr, ptr %a.ptr, ptr %b.ptr) { %entry: br label %loop_begin %loop_begin: %b = load i32, ptr %b.ptr, align 4 %v1 = load i1, ptr %ptr, align 1 br i1 %v1, label %loop_latch, label %inner_loop_ph %inner_loop_ph: %cond = load i1, ptr %cond.ptr, align 1 %cond.fr = freeze i1 %cond br i1 %cond.fr, label %inner_loop_ph.split.us, label %inner_loop_ph.split %inner_loop_ph.split.us: br label %inner_loop_begin.us %inner_loop_begin.us: call void @sink1(i32 %b) %a.us = load i32, ptr %a.ptr, align 4 br label %inner_loop_a.us %inner_loop_a.us: %v2.us = load i1, ptr %ptr, align 1 br i1 %v2.us, label %inner_loop_exit.split.us, label %inner_loop_begin.us %inner_loop_exit.split.us: %a.inner_lcssa.us = phi i32 [ %a.us, %inner_loop_a.us ] br label %inner_loop_exit %inner_loop_exit: %v3 = load i1, ptr %ptr, align 1 br i1 %v3, label %loop_latch, label %loop_exit.loopexit1 %loop_latch: br label %loop_begin %loop_exit.loopexit1: %a.inner_lcssa.lcssa = phi i32 [ %a.inner_lcssa.us, %inner_loop_exit ] br label %loop_exit %inner_loop_ph.split: %b.lcssa = phi i32 [ %b, %inner_loop_ph ] br label %inner_loop_begin %inner_loop_begin: call void @sink1(i32 %b.lcssa) %a = load i32, ptr %a.ptr, align 4 br label %loop_exit.loopexit %loop_exit.loopexit: %a.lcssa2 = phi i32 [ %a, %inner_loop_begin ] br label %loop_exit %loop_exit: %a.lcssa = phi i32 [ %a.lcssa2, %loop_exit.loopexit ], [ %a.inner_lcssa.lcssa, %loop_exit.loopexit1 ] ret i32 %a.lcssa } Transformation seems to be correct! ---------------------------------------- define i32 @test12a(ptr %ptr, ptr %cond.ptr, ptr %a.ptr, ptr %b.ptr) { %entry: br label %loop_begin %loop_begin: br label %inner_loop_begin %inner_loop_begin: %b = load i32, ptr %b.ptr, align 4 %v1 = load i1, ptr %ptr, align 1 br i1 %v1, label %inner_loop_latch, label %inner_inner_loop_ph %inner_inner_loop_ph: %cond = load i1, ptr %cond.ptr, align 1 br label %inner_inner_loop_begin %inner_inner_loop_begin: call void @sink1(i32 %b) %a = load i32, ptr %a.ptr, align 4 br i1 %cond, label %inner_loop_exit, label %inner_inner_loop_a %inner_inner_loop_a: %v2 = load i1, ptr %ptr, align 1 br i1 %v2, label %inner_inner_loop_exit, label %inner_inner_loop_begin %inner_inner_loop_exit: %a.inner_inner_lcssa = phi i32 [ %a, %inner_inner_loop_a ] %v3 = load i1, ptr %ptr, align 1 br i1 %v3, label %inner_loop_latch, label %inner_loop_exit %inner_loop_latch: br label %inner_loop_begin %inner_loop_exit: %a.inner_lcssa = phi i32 [ %a, %inner_inner_loop_begin ], [ %a.inner_inner_lcssa, %inner_inner_loop_exit ] %v4 = load i1, ptr %ptr, align 1 br i1 %v4, label %loop_begin, label %loop_exit %loop_exit: %a.lcssa = phi i32 [ %a.inner_lcssa, %inner_loop_exit ] ret i32 %a.lcssa } => define i32 @test12a(ptr %ptr, ptr %cond.ptr, ptr %a.ptr, ptr %b.ptr) { %entry: br label %loop_begin %loop_begin: br label %inner_loop_begin %inner_loop_begin: %b = load i32, ptr %b.ptr, align 4 %v1 = load i1, ptr %ptr, align 1 br i1 %v1, label %inner_loop_latch, label %inner_inner_loop_ph %inner_inner_loop_ph: %cond = load i1, ptr %cond.ptr, align 1 %cond.fr = freeze i1 %cond br i1 %cond.fr, label %inner_inner_loop_ph.split.us, label %inner_inner_loop_ph.split %inner_inner_loop_ph.split.us: %b.lcssa = phi i32 [ %b, %inner_inner_loop_ph ] br label %inner_inner_loop_begin.us %inner_inner_loop_begin.us: call void @sink1(i32 %b.lcssa) %a.us = load i32, ptr %a.ptr, align 4 br label %inner_loop_exit.loopexit.split.us %inner_loop_exit.loopexit.split.us: %a.lcssa2.us = phi i32 [ %a.us, %inner_inner_loop_begin.us ] br label %inner_loop_exit.loopexit %inner_loop_exit.loopexit: br label %inner_loop_exit %inner_inner_loop_ph.split: br label %inner_inner_loop_begin %inner_inner_loop_begin: call void @sink1(i32 %b) %a = load i32, ptr %a.ptr, align 4 br label %inner_inner_loop_a %inner_inner_loop_a: %v2 = load i1, ptr %ptr, align 1 br i1 %v2, label %inner_inner_loop_exit, label %inner_inner_loop_begin %inner_inner_loop_exit: %a.inner_inner_lcssa = phi i32 [ %a, %inner_inner_loop_a ] %v3 = load i1, ptr %ptr, align 1 br i1 %v3, label %inner_loop_latch, label %inner_loop_exit.loopexit1 %inner_loop_latch: br label %inner_loop_begin %inner_loop_exit.loopexit1: %a.inner_inner_lcssa.lcssa = phi i32 [ %a.inner_inner_lcssa, %inner_inner_loop_exit ] br label %inner_loop_exit %inner_loop_exit: %a.inner_lcssa = phi i32 [ %a.lcssa2.us, %inner_loop_exit.loopexit ], [ %a.inner_inner_lcssa.lcssa, %inner_loop_exit.loopexit1 ] %v4 = load i1, ptr %ptr, align 1 br i1 %v4, label %loop_begin, label %loop_exit %loop_exit: %a.lcssa = phi i32 [ %a.inner_lcssa, %inner_loop_exit ] ret i32 %a.lcssa } Transformation seems to be correct! ---------------------------------------- define i32 @test12b(ptr %ptr, ptr %cond.ptr, ptr %a.ptr, ptr %b.ptr) { %entry: br label %loop_begin %loop_begin: br label %inner_loop_begin %inner_loop_begin: %b = load i32, ptr %b.ptr, align 4 %v1 = load i1, ptr %ptr, align 1 br i1 %v1, label %inner_loop_latch, label %inner_inner_loop_ph %inner_inner_loop_ph: %cond = load i1, ptr %cond.ptr, align 1 br label %inner_inner_loop_begin %inner_inner_loop_begin: call void @sink1(i32 %b) %a = load i32, ptr %a.ptr, align 4 br i1 %cond, label %inner_inner_loop_a, label %inner_loop_exit %inner_inner_loop_a: %v2 = load i1, ptr %ptr, align 1 br i1 %v2, label %inner_inner_loop_exit, label %inner_inner_loop_begin %inner_inner_loop_exit: %a.inner_inner_lcssa = phi i32 [ %a, %inner_inner_loop_a ] %v3 = load i1, ptr %ptr, align 1 br i1 %v3, label %inner_loop_latch, label %inner_loop_exit %inner_loop_latch: br label %inner_loop_begin %inner_loop_exit: %a.inner_lcssa = phi i32 [ %a, %inner_inner_loop_begin ], [ %a.inner_inner_lcssa, %inner_inner_loop_exit ] %v4 = load i1, ptr %ptr, align 1 br i1 %v4, label %loop_begin, label %loop_exit %loop_exit: %a.lcssa = phi i32 [ %a.inner_lcssa, %inner_loop_exit ] ret i32 %a.lcssa } => define i32 @test12b(ptr %ptr, ptr %cond.ptr, ptr %a.ptr, ptr %b.ptr) { %entry: br label %loop_begin %loop_begin: br label %inner_loop_begin %inner_loop_begin: %b = load i32, ptr %b.ptr, align 4 %v1 = load i1, ptr %ptr, align 1 br i1 %v1, label %inner_loop_latch, label %inner_inner_loop_ph %inner_inner_loop_ph: %cond = load i1, ptr %cond.ptr, align 1 %cond.fr = freeze i1 %cond br i1 %cond.fr, label %inner_inner_loop_ph.split.us, label %inner_inner_loop_ph.split %inner_inner_loop_ph.split.us: br label %inner_inner_loop_begin.us %inner_inner_loop_begin.us: call void @sink1(i32 %b) %a.us = load i32, ptr %a.ptr, align 4 br label %inner_inner_loop_a.us %inner_inner_loop_a.us: %v2.us = load i1, ptr %ptr, align 1 br i1 %v2.us, label %inner_inner_loop_exit.split.us, label %inner_inner_loop_begin.us %inner_inner_loop_exit.split.us: %a.inner_inner_lcssa.us = phi i32 [ %a.us, %inner_inner_loop_a.us ] br label %inner_inner_loop_exit %inner_inner_loop_exit: %v3 = load i1, ptr %ptr, align 1 br i1 %v3, label %inner_loop_latch, label %inner_loop_exit.loopexit1 %inner_loop_latch: br label %inner_loop_begin %inner_loop_exit.loopexit1: %a.inner_inner_lcssa.lcssa = phi i32 [ %a.inner_inner_lcssa.us, %inner_inner_loop_exit ] br label %inner_loop_exit %inner_inner_loop_ph.split: %b.lcssa = phi i32 [ %b, %inner_inner_loop_ph ] br label %inner_inner_loop_begin %inner_inner_loop_begin: call void @sink1(i32 %b.lcssa) %a = load i32, ptr %a.ptr, align 4 br label %inner_loop_exit.loopexit %inner_loop_exit.loopexit: %a.lcssa2 = phi i32 [ %a, %inner_inner_loop_begin ] br label %inner_loop_exit %inner_loop_exit: %a.inner_lcssa = phi i32 [ %a.lcssa2, %inner_loop_exit.loopexit ], [ %a.inner_inner_lcssa.lcssa, %inner_loop_exit.loopexit1 ] %v4 = load i1, ptr %ptr, align 1 br i1 %v4, label %loop_begin, label %loop_exit %loop_exit: %a.lcssa = phi i32 [ %a.inner_lcssa, %inner_loop_exit ] ret i32 %a.lcssa } Transformation seems to be correct! ---------------------------------------- define i32 @test13a(ptr %ptr, i1 %cond, ptr %a.ptr, ptr %b.ptr) { %entry: br label %loop_begin %loop_begin: %a = load i32, ptr %a.ptr, align 4 %v1 = load i1, ptr %ptr, align 1 br i1 %v1, label %loop_a, label %loop_b %loop_a: %v2 = load i1, ptr %ptr, align 1 br i1 %v2, label %loop_exit, label %loop_latch %loop_b: %b = load i32, ptr %b.ptr, align 4 br i1 %cond, label %loop_b_inner_ph, label %loop_exit %loop_b_inner_ph: br label %loop_b_inner_header %loop_b_inner_header: %v3 = load i1, ptr %ptr, align 1 br i1 %v3, label %loop_b_inner_latch, label %loop_b_inner_body %loop_b_inner_body: %v4 = load i1, ptr %ptr, align 1 br i1 %v4, label %loop_b_inner_latch, label %loop_b_inner_exit %loop_b_inner_latch: br label %loop_b_inner_header %loop_b_inner_exit: br label %loop_latch %loop_latch: br label %loop_begin %loop_exit: %lcssa = phi i32 [ %a, %loop_a ], [ %b, %loop_b ] ret i32 %lcssa } => define i32 @test13a(ptr %ptr, i1 %cond, ptr %a.ptr, ptr %b.ptr) { %entry: %cond.fr = freeze i1 %cond br i1 %cond.fr, label %entry.split.us, label %entry.split %entry.split: br label %loop_begin %loop_begin: %a = load i32, ptr %a.ptr, align 4 %v1 = load i1, ptr %ptr, align 1 br i1 %v1, label %loop_a, label %loop_b %loop_a: %v2 = load i1, ptr %ptr, align 1 br i1 %v2, label %loop_exit.split.loopexit, label %loop_latch %loop_exit.split.loopexit: %lcssa.ph = phi i32 [ %a, %loop_a ] br label %loop_exit.split %loop_latch: br label %loop_begin %loop_b: %b = load i32, ptr %b.ptr, align 4 br label %loop_exit.split %loop_exit.split: %lcssa = phi i32 [ %b, %loop_b ], [ %lcssa.ph, %loop_exit.split.loopexit ] br label %loop_exit %entry.split.us: br label %loop_begin.us %loop_begin.us: %a.us = load i32, ptr %a.ptr, align 4 %v1.us = load i1, ptr %ptr, align 1 br i1 %v1.us, label %loop_a.us, label %loop_b.us %loop_a.us: %v2.us = load i1, ptr %ptr, align 1 br i1 %v2.us, label %loop_exit.split.us, label %loop_latch.us %loop_exit.split.us: %lcssa.us = phi i32 [ %a.us, %loop_a.us ] br label %loop_exit %loop_exit: %.us-phi = phi i32 [ %lcssa, %loop_exit.split ], [ %lcssa.us, %loop_exit.split.us ] ret i32 %.us-phi %loop_b.us: %b.us = load i32, ptr %b.ptr, align 4 br label %loop_b_inner_ph.us %loop_b_inner_ph.us: br label %loop_b_inner_header.us %loop_b_inner_header.us: %v3.us = load i1, ptr %ptr, align 1 br i1 %v3.us, label %loop_b_inner_latch.us, label %loop_b_inner_body.us %loop_b_inner_body.us: %v4.us = load i1, ptr %ptr, align 1 br i1 %v4.us, label %loop_b_inner_latch.us, label %loop_b_inner_exit.us %loop_b_inner_latch.us: br label %loop_b_inner_header.us %loop_b_inner_exit.us: br label %loop_latch.us %loop_latch.us: br label %loop_begin.us } Transformation seems to be correct! ---------------------------------------- define i32 @test13b(ptr %ptr, i1 %cond, ptr %a.ptr, ptr %b.ptr) { %entry: br label %loop_begin %loop_begin: %a = load i32, ptr %a.ptr, align 4 %v1 = load i1, ptr %ptr, align 1 br i1 %v1, label %loop_a, label %loop_b %loop_a: %v2 = load i1, ptr %ptr, align 1 br i1 %v2, label %loop_exit, label %loop_latch %loop_b: %b = load i32, ptr %b.ptr, align 4 br i1 %cond, label %loop_exit, label %loop_b_inner_ph %loop_exit: %lcssa = phi i32 [ %a, %loop_a ], [ %b, %loop_b ] ret i32 %lcssa %loop_b_inner_ph: br label %loop_b_inner_header %loop_b_inner_header: %v3 = load i1, ptr %ptr, align 1 br i1 %v3, label %loop_b_inner_latch, label %loop_b_inner_body %loop_b_inner_body: %v4 = load i1, ptr %ptr, align 1 br i1 %v4, label %loop_b_inner_latch, label %loop_b_inner_exit %loop_b_inner_latch: br label %loop_b_inner_header %loop_b_inner_exit: br label %loop_latch %loop_latch: br label %loop_begin } => define i32 @test13b(ptr %ptr, i1 %cond, ptr %a.ptr, ptr %b.ptr) { %entry: %cond.fr = freeze i1 %cond br i1 %cond.fr, label %entry.split.us, label %entry.split %entry.split: br label %loop_begin %loop_begin: %a = load i32, ptr %a.ptr, align 4 %v1 = load i1, ptr %ptr, align 1 br i1 %v1, label %loop_a, label %loop_b %loop_a: %v2 = load i1, ptr %ptr, align 1 br i1 %v2, label %loop_exit.split, label %loop_latch %loop_exit.split: %lcssa = phi i32 [ %a, %loop_a ] br label %loop_exit %loop_b: %b = load i32, ptr %b.ptr, align 4 br label %loop_b_inner_ph %loop_b_inner_ph: br label %loop_b_inner_header %loop_b_inner_header: %v3 = load i1, ptr %ptr, align 1 br i1 %v3, label %loop_b_inner_latch, label %loop_b_inner_body %loop_b_inner_body: %v4 = load i1, ptr %ptr, align 1 br i1 %v4, label %loop_b_inner_latch, label %loop_b_inner_exit %loop_b_inner_latch: br label %loop_b_inner_header %loop_b_inner_exit: br label %loop_latch %loop_latch: br label %loop_begin %entry.split.us: br label %loop_begin.us %loop_begin.us: %a.us = load i32, ptr %a.ptr, align 4 %v1.us = load i1, ptr %ptr, align 1 br i1 %v1.us, label %loop_a.us, label %loop_b.us %loop_a.us: %v2.us = load i1, ptr %ptr, align 1 br i1 %v2.us, label %loop_exit.split.us.loopexit, label %loop_latch.us %loop_exit.split.us.loopexit: %lcssa.us.ph = phi i32 [ %a.us, %loop_a.us ] br label %loop_exit.split.us %loop_latch.us: br label %loop_begin.us %loop_b.us: %b.us = load i32, ptr %b.ptr, align 4 br label %loop_exit.split.us %loop_exit.split.us: %lcssa.us = phi i32 [ %b.us, %loop_b.us ], [ %lcssa.us.ph, %loop_exit.split.us.loopexit ] br label %loop_exit %loop_exit: %.us-phi = phi i32 [ %lcssa, %loop_exit.split ], [ %lcssa.us, %loop_exit.split.us ] ret i32 %.us-phi } Transformation seems to be correct! ---------------------------------------- define i32 @test20(ptr %var, i32 %cond1, i32 %cond2) { %entry: br label %loop_begin %loop_begin: %var_val = load i32, ptr %var, align 4 switch i32 %cond2, label %loop_exit [ i32 0, label %loop_a i32 1, label %loop_a i32 13, label %loop_b i32 2, label %loop_a i32 42, label %loop_c ] %loop_exit: %lcssa = phi i32 [ %var_val, %loop_begin ] ret i32 %lcssa %loop_a: %0 = call i32 @a() br label %loop_latch %loop_b: %1 = call i32 @b() br label %loop_latch %loop_c: %2 = call i32 @c() noreturn br label %loop_latch %loop_latch: br label %loop_begin } => define i32 @test20(ptr %var, i32 %cond1, i32 %cond2) { %entry: switch i32 %cond2, label %entry.split [ i32 0, label %entry.split.us i32 1, label %entry.split.us i32 13, label %entry.split.us1 i32 2, label %entry.split.us i32 42, label %entry.split.us5 ] %entry.split.us5: br label %loop_begin.us6 %loop_begin.us6: %var_val.us7 = load i32, ptr %var, align 4 br label %loop_c.us %loop_c.us: %0 = call i32 @c() noreturn br label %loop_latch.us8 %loop_latch.us8: br label %loop_begin.us6 %entry.split.us1: br label %loop_begin.us2 %loop_begin.us2: %var_val.us3 = load i32, ptr %var, align 4 br label %loop_b.us %loop_b.us: %1 = call i32 @b() br label %loop_latch.us4 %loop_latch.us4: br label %loop_begin.us2 %entry.split.us: br label %loop_begin.us %loop_begin.us: %var_val.us = load i32, ptr %var, align 4 br label %loop_a.us %loop_a.us: %2 = call i32 @a() br label %loop_latch.us %loop_latch.us: br label %loop_begin.us %entry.split: br label %loop_begin %loop_begin: %var_val = load i32, ptr %var, align 4 br label %loop_exit %loop_exit: %lcssa = phi i32 [ %var_val, %loop_begin ] ret i32 %lcssa } Transformation seems to be correct! ---------------------------------------- define void @test_no_unswitch_unstructured_cfg(ptr %ptr, i1 %cond) { %entry: br label %loop_begin %loop_begin: br i1 %cond, label %loop_left, label %loop_right %loop_right: %v2 = load i1, ptr %ptr, align 1 br i1 %v2, label %loop_left, label %loop_merge %loop_left: %v1 = load i1, ptr %ptr, align 1 br i1 %v1, label %loop_right, label %loop_merge %loop_merge: %v3 = load i1, ptr %ptr, align 1 br i1 %v3, label %loop_latch, label %loop_exit %loop_latch: br label %loop_begin %loop_exit: ret void } => define void @test_no_unswitch_unstructured_cfg(ptr %ptr, i1 %cond) { %entry: br label %loop_begin %loop_begin: br i1 %cond, label %loop_left, label %loop_right %loop_right: %v2 = load i1, ptr %ptr, align 1 br i1 %v2, label %loop_left, label %loop_merge %loop_left: %v1 = load i1, ptr %ptr, align 1 br i1 %v1, label %loop_right, label %loop_merge %loop_merge: %v3 = load i1, ptr %ptr, align 1 br i1 %v3, label %loop_latch, label %loop_exit %loop_latch: br label %loop_begin %loop_exit: ret void } Transformation seems to be correct! (syntactically equal) ---------------------------------------- define void @test21(i1 %a, i1 %b) { %bb: br label %bb3 %bb3: %tmp1.0 = phi i32 [ 0, %bb ], [ %tmp1.3, %bb23 ] br label %bb7 %bb7: %tmp.0 = phi i1 [ 1, %bb3 ], [ 0, %bb19 ] %tmp1.1 = phi i32 [ %tmp1.0, %bb3 ], [ %tmp1.2.lcssa, %bb19 ] br i1 %tmp.0, label %bb11.preheader, label %bb23 %bb11.preheader: br i1 %a, label %bb19, label %bb14.lr.ph %bb14.lr.ph: br label %bb14 %bb14: %tmp2.02 = phi i32 [ 0, %bb14.lr.ph ], [ 1, %bb14 ] br i1 %b, label %bb11.bb19_crit_edge, label %bb14 %bb11.bb19_crit_edge: %split = phi i32 [ %tmp2.02, %bb14 ] br label %bb19 %bb19: %tmp1.2.lcssa = phi i32 [ %split, %bb11.bb19_crit_edge ], [ %tmp1.1, %bb11.preheader ] %tmp21 = icmp eq i32 %tmp1.2.lcssa, 0 br i1 %tmp21, label %bb23, label %bb7 %bb23: %tmp1.3 = phi i32 [ %tmp1.2.lcssa, %bb19 ], [ %tmp1.1, %bb7 ] br label %bb3 } => define void @test21(i1 %a, i1 %b) { %bb: br label %bb3 %bb3: %tmp1.0 = phi i32 [ 0, %bb ], [ %.us-phi, %bb23 ] %a.fr = freeze i1 %a br i1 %a.fr, label %bb3.split.us, label %bb3.split %bb3.split.us: br label %bb7.us %bb7.us: %tmp.0.us = phi i1 [ 1, %bb3.split.us ], [ 0, %bb19.us ] %tmp1.1.us = phi i32 [ %tmp1.0, %bb3.split.us ], [ %tmp1.2.lcssa.us, %bb19.us ] br i1 %tmp.0.us, label %bb11.preheader.us, label %bb23.split.us %bb11.preheader.us: br label %bb19.us %bb19.us: %tmp1.2.lcssa.us = phi i32 [ %tmp1.1.us, %bb11.preheader.us ] %tmp21.us = icmp eq i32 %tmp1.2.lcssa.us, 0, use_provenance br i1 %tmp21.us, label %bb23.split.us, label %bb7.us %bb23.split.us: %tmp1.3.us = phi i32 [ %tmp1.2.lcssa.us, %bb19.us ], [ %tmp1.1.us, %bb7.us ] br label %bb23 %bb3.split: %b.fr = freeze i1 %b br i1 %b.fr, label %bb3.split.split.us, label %bb3.split.split %bb3.split.split.us: br label %bb7.us1 %bb7.us1: %tmp.0.us2 = phi i1 [ 1, %bb3.split.split.us ], [ 0, %bb19.us5 ] %tmp1.1.us3 = phi i32 [ %tmp1.0, %bb3.split.split.us ], [ %tmp1.2.lcssa.us6, %bb19.us5 ] br i1 %tmp.0.us2, label %bb11.preheader.us4, label %bb23.split.split.us %bb11.preheader.us4: br label %bb14.lr.ph.us %bb14.lr.ph.us: br label %bb14.lr.ph.split.us.us %bb14.lr.ph.split.us.us: br label %bb14.us.us %bb14.us.us: %tmp2.02.us.us = phi i32 [ 0, %bb14.lr.ph.split.us.us ] br label %bb11.bb19_crit_edge.split.us.us %bb11.bb19_crit_edge.split.us.us: %split.us.us = phi i32 [ %tmp2.02.us.us, %bb14.us.us ] br label %bb11.bb19_crit_edge.us %bb11.bb19_crit_edge.us: br label %bb19.us5 %bb19.us5: %tmp1.2.lcssa.us6 = phi i32 [ %split.us.us, %bb11.bb19_crit_edge.us ] %tmp21.us7 = icmp eq i32 %tmp1.2.lcssa.us6, 0, use_provenance br i1 %tmp21.us7, label %bb23.split.split.us, label %bb7.us1 %bb23.split.split.us: %tmp1.3.us8 = phi i32 [ %tmp1.2.lcssa.us6, %bb19.us5 ], [ %tmp1.1.us3, %bb7.us1 ] br label %bb23.split %bb3.split.split: br label %bb7 %bb7: br i1 1, label %bb11.preheader, label %bb23.split.split %bb11.preheader: br label %bb14.lr.ph %bb14.lr.ph: br label %bb14.lr.ph.split %bb14.lr.ph.split: br label %bb14 %bb14: %tmp2.02 = phi i32 [ 0, %bb14.lr.ph.split ], [ 1, %bb14 ] br label %bb14 %bb23.split.split: br label %bb23.split %bb23.split: %.us-phi9 = phi i32 [ %tmp1.0, %bb23.split.split ], [ %tmp1.3.us8, %bb23.split.split.us ] br label %bb23 %bb23: %.us-phi = phi i32 [ %.us-phi9, %bb23.split ], [ %tmp1.3.us, %bb23.split.us ] br label %bb3 } Transformation doesn't verify! ERROR: The source program doesn't reach a return instruction. Consider increasing the unroll factor if it has loops ---------------------------------------- define void @test22(i32 %arg) { %entry: br label %loop1.header %loop1.header: %stop = phi i1 [ 1, %loop1.latch ], [ 0, %entry ] %i = phi i32 [ %i.lcssa, %loop1.latch ], [ %arg, %entry ] br i1 %stop, label %loop1.exit, label %loop1.body.loop2.ph %loop1.exit: call void @g() ret void %loop1.body.loop2.ph: br label %loop2.header %loop2.header: %i.inner = phi i32 [ %i, %loop1.body.loop2.ph ], [ %i.next, %loop2.latch ] br label %loop3.header %loop3.header: %sw = call i32 @h(i32 %i.inner) switch i32 %sw, label %loop3.exit [ i32 32, label %loop3.header i32 59, label %loop2.latch i32 36, label %loop1.latch ] %loop3.exit: call void @f() ret void %loop2.latch: %i.next = add i32 %i.inner, 1 br i1 %stop, label %loop2.exit, label %loop2.header %loop2.exit: call void @g() ret void %loop1.latch: %i.lcssa = phi i32 [ %i.inner, %loop3.header ] br label %loop1.header } => define void @test22(i32 %arg) { %entry: br label %loop1.header %loop1.header: %stop = phi i1 [ 1, %loop1.latch ], [ 0, %entry ] %i = phi i32 [ %.us-phi, %loop1.latch ], [ %arg, %entry ] br i1 %stop, label %loop1.exit, label %loop1.body.loop2.ph %loop1.exit: call void @g() ret void %loop1.body.loop2.ph: br i1 %stop, label %loop1.body.loop2.ph.split.us, label %loop1.body.loop2.ph.split %loop1.body.loop2.ph.split.us: br label %loop2.header.us %loop2.header.us: %i.inner.us = phi i32 [ %i, %loop1.body.loop2.ph.split.us ] br label %loop3.header.us %loop3.header.us: %sw.us = call i32 @h(i32 %i.inner.us) switch i32 %sw.us, label %loop3.exit.split.us [ i32 32, label %loop3.header.us i32 59, label %loop2.latch.us i32 36, label %loop1.latch.split.us ] %loop3.exit.split.us: br label %loop3.exit %loop2.latch.us: %i.inner.us.lcssa1 = phi i32 [ %i.inner.us, %loop3.header.us ] %i.next.us = add i32 %i.inner.us.lcssa1, 1 br label %loop2.exit.split.us %loop2.exit.split.us: br label %loop2.exit %loop2.exit: call void @g() ret void %loop1.latch.split.us: %i.lcssa.us = phi i32 [ %i.inner.us, %loop3.header.us ] br label %loop1.latch %loop1.body.loop2.ph.split: br label %loop2.header %loop2.header: %i.inner = phi i32 [ %i, %loop1.body.loop2.ph.split ], [ %i.next, %loop2.latch ] br label %loop3.header %loop3.header: %sw = call i32 @h(i32 %i.inner) switch i32 %sw, label %loop3.exit.split [ i32 32, label %loop3.header i32 59, label %loop2.latch i32 36, label %loop1.latch.split ] %loop3.exit.split: br label %loop3.exit %loop3.exit: call void @f() ret void %loop2.latch: %i.next = add i32 %i.inner, 1 br label %loop2.header %loop1.latch.split: %i.lcssa = phi i32 [ %i.inner, %loop3.header ] br label %loop1.latch %loop1.latch: %.us-phi = phi i32 [ %i.lcssa, %loop1.latch.split ], [ %i.lcssa.us, %loop1.latch.split.us ] br label %loop1.header } Transformation seems to be correct! ---------------------------------------- define void @test23(i1 %arg, ptr %ptr) { %entry: br label %outer.header %outer.header: br label %inner.header %inner.header: call void @f() br label %inner.latch %inner.latch: %inner.cond = load i1, ptr %ptr, align 1 br i1 %inner.cond, label %inner.header, label %outer.body %outer.body: br i1 %arg, label %outer.body.left, label %outer.body.right %outer.body.left: call void @f() br label %outer.latch %outer.body.right: call void @g() br label %outer.latch %outer.latch: %outer.cond = load i1, ptr %ptr, align 1 br i1 %outer.cond, label %outer.header, label %exit %exit: ret void } => define void @test23(i1 %arg, ptr %ptr) { %entry: %arg.fr = freeze i1 %arg br i1 %arg.fr, label %entry.split.us, label %entry.split %entry.split: br label %outer.header %outer.header: br label %inner.header %inner.header: call void @f() br label %inner.latch %inner.latch: %inner.cond = load i1, ptr %ptr, align 1 br i1 %inner.cond, label %inner.header, label %outer.body %outer.body: br label %outer.body.right %outer.body.right: call void @g() br label %outer.latch %outer.latch: %outer.cond = load i1, ptr %ptr, align 1 br i1 %outer.cond, label %outer.header, label %exit.split %exit.split: br label %exit %entry.split.us: br label %outer.header.us %outer.header.us: br label %inner.header.us %inner.header.us: call void @f() br label %inner.latch.us %inner.latch.us: %inner.cond.us = load i1, ptr %ptr, align 1 br i1 %inner.cond.us, label %inner.header.us, label %outer.body.us %outer.body.us: br label %outer.body.left.us %outer.body.left.us: call void @f() br label %outer.latch.us %outer.latch.us: %outer.cond.us = load i1, ptr %ptr, align 1 br i1 %outer.cond.us, label %outer.header.us, label %exit.split.us %exit.split.us: br label %exit %exit: ret void } Transformation seems to be correct! ---------------------------------------- define i32 @test24(ptr %ptr, i1 %cond1, i1 %cond2) { %entry: br label %loop_begin %loop_begin: br i1 %cond1, label %loop_a, label %loop_b %loop_a: br i1 %cond2, label %loop_a_a, label %loop_a_c %loop_a_a: %0 = call i32 @a() br label %latch %loop_a_c: %1 = call i32 @c() br label %latch %loop_b: %2 = call i32 @b() br label %latch %latch: %v = load i1, ptr %ptr, align 1 br i1 %v, label %loop_begin, label %loop_exit %loop_exit: ret i32 0 } => define i32 @test24(ptr %ptr, i1 %cond1, i1 %cond2) { %entry: br i1 %cond1, label %entry.split.us, label %entry.split %entry.split: br label %loop_begin %loop_begin: br label %loop_b %loop_b: %0 = call i32 @b() br label %latch %latch: %v = load i1, ptr %ptr, align 1 br i1 %v, label %loop_begin, label %loop_exit.split %loop_exit.split: br label %loop_exit %entry.split.us: br i1 %cond2, label %entry.split.us.split.us, label %entry.split.us.split %entry.split.us.split.us: br label %loop_begin.us.us %loop_begin.us.us: br label %loop_a.us.us %loop_a.us.us: br label %loop_a_a.us.us %loop_a_a.us.us: %1 = call i32 @a() br label %latch.us.us %latch.us.us: %v.us.us = load i1, ptr %ptr, align 1 br i1 %v.us.us, label %loop_begin.us.us, label %loop_exit.split.us.split.us %loop_exit.split.us.split.us: br label %loop_exit.split.us %entry.split.us.split: br label %loop_begin.us %loop_begin.us: br label %loop_a.us %loop_a.us: br label %loop_a_c.us %loop_a_c.us: %2 = call i32 @c() br label %latch.us %latch.us: %v.us = load i1, ptr %ptr, align 1 br i1 %v.us, label %loop_begin.us, label %loop_exit.split.us.split %loop_exit.split.us.split: br label %loop_exit.split.us %loop_exit.split.us: br label %loop_exit %loop_exit: ret i32 0 } Transformation seems to be correct! ---------------------------------------- define i32 @test25(ptr %ptr, i1 %cond) { %entry: br label %loop_begin %loop_begin: %v1 = load i1, ptr %ptr, align 1 %cond_or = or i1 %v1, %cond br i1 %cond_or, label %loop_a, label %loop_b %loop_a: %0 = call i32 @a() br label %latch %loop_b: %1 = call i32 @b() br label %latch %latch: %v2 = load i1, ptr %ptr, align 1 br i1 %v2, label %loop_begin, label %loop_exit %loop_exit: ret i32 0 } => define i32 @test25(ptr %ptr, i1 %cond) { %entry: br i1 %cond, label %entry.split.us, label %entry.split %entry.split: br label %loop_begin %loop_begin: %v1 = load i1, ptr %ptr, align 1 %cond_or = or i1 %v1, 0 br i1 %cond_or, label %loop_a, label %loop_b %loop_a: %0 = call i32 @a() br label %latch %loop_b: %1 = call i32 @b() br label %latch %latch: %v2 = load i1, ptr %ptr, align 1 br i1 %v2, label %loop_begin, label %loop_exit.split %loop_exit.split: br label %loop_exit %entry.split.us: br label %loop_begin.us %loop_begin.us: br label %loop_a.us %loop_a.us: %2 = call i32 @a() br label %latch.us %latch.us: %v2.us = load i1, ptr %ptr, align 1 br i1 %v2.us, label %loop_begin.us, label %loop_exit.split.us %loop_exit.split.us: br label %loop_exit %loop_exit: ret i32 0 } Transformation doesn't verify! ERROR: Source is more defined than target Example: ptr %ptr = pointer(non-local, block_id=1, offset=6) i1 %cond = undef Source: >> Jump to %loop_begin i1 %v1 = #x1 (1) i1 %cond_or = #x1 (1) >> Jump to %loop_a i32 %0 = UB triggered! SOURCE MEMORY STATE =================== NON-LOCAL BLOCKS: Block 0 > size: 0 align: 1 alloc type: 0 Block 1 > size: 8 align: 2 alloc type: 0 Block 2 > align: 1 alloc type: 0 Target: UB triggered on br ------------------- SMT STATS ------------------- Num queries: 132 Num invalid: 0 Num skips: 0 Num trivial: 104 (44.1%) Num timeout: 0 (0.0%) Num errors: 0 (0.0%) Num SAT: 79 (59.8%) Num UNSAT: 53 (40.2%) Alive2: Transform doesn't verify; aborting!
+ : 'RUN: at line 1' + /home/nuno/llvm/build/bin/FileCheck /home/nuno/llvm/llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch.ll + /home/nuno/alive2/build/opt-alive.sh '-passes=loop(simple-loop-unswitch<nontrivial>),verify<loops>' -S FileCheck error: '<stdin>' is empty. FileCheck command line: /home/nuno/llvm/build/bin/FileCheck /home/nuno/llvm/llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch.ll
NOTE: This test would pass if undef didn't exist!