Test Failure: Transforms/SimpleLoopUnswitch/nontrivial-unswitch.ll

Test source: git

Log:

Source: <stdin>
ERROR: Unsupported instruction:   %2 = invoke i32 @a()
          to label %loop_latch unwind label %loop_catch

----------------------------------------
define void @test_no_unswitch_convergent(* %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, align 1
  br i1 %v, label %loop_begin, label %loop_exit

%loop_exit:
  ret void
}
=>
define void @test_no_unswitch_convergent(* %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, 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, 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, align 1
  br i1 %v, label %loop_begin, label %loop_exit

%loop_exit:
  ret void
}
=>
define void @test_no_unswitch_noduplicate(* %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, 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, 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, align 1
  br i1 %v, label %loop_begin, label %loop_exit

%loop_exit:
  ret i32 0
}
=>
define i32 @test1(* %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, 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, 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, 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, i1 %cond1, * %a.ptr, * %b.ptr, * %c.ptr) {
%entry:
  br label %loop_begin

%loop_begin:
  %v = load i1, * %ptr, align 1
  br i1 %cond1, label %loop_a, label %loop_b

%loop_a:
  %a = load i32, * %a.ptr, align 4
  %ac = load i32, * %c.ptr, align 4
  br i1 %v, label %loop_begin, label %loop_exit

%loop_b:
  %b = load i32, * %b.ptr, align 4
  %bc = load i32, * %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, i1 %cond1, * %a.ptr, * %b.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, align 1
  br label %loop_b

%loop_b:
  %b = load i32, * %b.ptr, align 4
  %bc = load i32, * %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, align 1
  br label %loop_a.us

%loop_a.us:
  %a.us = load i32, * %a.ptr, align 4
  %ac.us = load i32, * %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, i1 %cond1, * %a.ptr, * %b.ptr) {
%entry:
  br label %loop_begin

%loop_begin:
  %v = load i1, * %ptr, align 1
  %a = load i32, * %a.ptr, align 4
  br i1 %cond1, label %loop_exit, label %loop_b

%loop_b:
  %b = load i32, * %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, i1 %cond1, * %a.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, align 1
  %a = load i32, * %a.ptr, align 4
  br label %loop_b

%loop_b:
  %b = load i32, * %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, align 1
  %a.us = load i32, * %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, i1 %cond1, * %a.ptr, * %b.ptr) {
%entry:
  br label %loop_begin

%loop_begin:
  %v = load i1, * %ptr, align 1
  %a = load i32, * %a.ptr, align 4
  br i1 %cond1, label %loop_b, label %loop_exit

%loop_b:
  %b = load i32, * %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, i1 %cond1, * %a.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, align 1
  %a = load i32, * %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, align 1
  %a.us = load i32, * %a.ptr, align 4
  br label %loop_b.us

%loop_b.us:
  %b.us = load i32, * %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, i1 %cond1, * %a.ptr, * %b.ptr) {
%entry:
  br label %loop_begin

%loop_begin:
  %v = load i1, * %ptr, align 1
  %a = load i32, * %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, * %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, i1 %cond1, * %a.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, align 1
  %a = load i32, * %a.ptr, align 4
  br label %loop_b

%loop_b:
  %b = load i32, * %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, align 1
  %a.us = load i32, * %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, i1 %cond1, * %a.ptr, * %b.ptr) {
%entry:
  br label %loop_begin

%loop_begin:
  %v = load i1, * %ptr, align 1
  %a = load i32, * %a.ptr, align 4
  br i1 %cond1, label %loop_b, label %loop_exit1

%loop_b:
  %b = load i32, * %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, i1 %cond1, * %a.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, align 1
  %a = load i32, * %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, align 1
  %a.us = load i32, * %a.ptr, align 4
  br label %loop_b.us

%loop_b.us:
  %b.us = load i32, * %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, i1 %cond1, * %a.ptr, * %b.ptr) {
%entry:
  br label %loop_begin

%loop_begin:
  %v = load i1, * %ptr, align 1
  %a = load i32, * %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, * %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, i1 %cond1, * %a.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, align 1
  %a = load i32, * %a.ptr, align 4
  br label %loop_b

%loop_b:
  %b = load i32, * %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, align 1
  %a.us = load i32, * %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, i1 %cond1, * %a.ptr, * %b.ptr) {
%entry:
  br label %loop_begin

%loop_begin:
  br label %inner_loop_begin

%inner_loop_begin:
  %v = load i1, * %ptr, align 1
  %a = load i32, * %a.ptr, align 4
  br i1 %cond1, label %loop_exit, label %inner_loop_b

%inner_loop_b:
  %b = load i32, * %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, 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, i1 %cond1, * %a.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, align 1
  %a = load i32, * %a.ptr, align 4
  br label %inner_loop_b

%inner_loop_b:
  %b = load i32, * %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, 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, align 1
  %a.us = load i32, * %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, i1 %cond1, * %a.ptr, * %b.ptr) {
%entry:
  br label %loop_begin

%loop_begin:
  %v = load i1, * %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, align 1
  %a = load i32, * %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, align 1
  %b = load i32, * %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, i1 %cond1, * %a.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, align 1
  br label %loop_b

%loop_b:
  br label %loop_b_inner

%loop_b_inner:
  %vb = load i1, * %ptr, align 1
  %b = load i32, * %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, 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, align 1
  %a.us = load i32, * %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, * %cond.ptr, * %a.ptr, * %b.ptr) {
%entry:
  br label %loop_begin

%loop_begin:
  %a = load i32, * %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, * %cond.ptr, align 1
  %b = load i32, * %b.ptr, align 4
  br label %inner_inner_loop_begin

%inner_inner_loop_begin:
  %v1 = load i1, * %ptr, align 1
  br i1 %v1, label %inner_inner_loop_a, label %inner_inner_loop_b

%inner_inner_loop_a:
  %v2 = load i1, * %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, align 1
  br i1 %v3, label %inner_inner_loop_exit, label %inner_inner_loop_c

%inner_inner_loop_exit:
  %a2 = load i32, * %a.ptr, align 4
  %v5 = load i1, * %ptr, align 1
  br i1 %v5, label %inner_loop_exit, label %inner_loop_begin

%inner_inner_loop_c:
  %v4 = load i1, * %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, * %cond.ptr, * %a.ptr, * %b.ptr) {
%entry:
  br label %loop_begin

%loop_begin:
  %a = load i32, * %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, * %cond.ptr, align 1
  %b = load i32, * %b.ptr, align 4
  br i1 %cond, 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, 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, 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, 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, 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, align 1
  br i1 %v1, label %inner_inner_loop_a, label %inner_inner_loop_b

%inner_inner_loop_a:
  %v2 = load i1, * %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, 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, * %a.ptr, align 4
  %v5 = load i1, * %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, 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 doesn't verify!
ERROR: Source is more defined than target

Example:
* %ptr = pointer(non-local, block_id=1, offset=3)
* %cond.ptr = pointer(non-local, block_id=1, offset=6)
* %a.ptr = pointer(non-local, block_id=1, offset=0)
* %b.ptr = pointer(non-local, block_id=1, offset=0)

Source:
i32 %a = poison
i32 %a.phi = poison
i1 %cond = poison
i32 %b = poison
i1 %v1 = #x1 (1)
i1 %v2 = #x1 (1)
i32 %a.lcssa = poison
i32 %b.lcssa = poison
i32 %result = poison
i1 %v3 = #x1 (1)
i32 %a2 = poison
i1 %v5 = #x1 (1)
i1 %v4 = #x1 (1)

SOURCE MEMORY STATE
===================
NON-LOCAL BLOCKS:
Block 0 >	size: 0	align: 1	alloc type: 0
Block 1 >	size: 8	align: 4	alloc type: 0
Block 2 >	align: 1	alloc type: 0
Block 3 >	align: 2	alloc type: 0
Block 4 >	align: 2	alloc type: 0

Target:
i32 %a = poison
i32 %a.phi = poison
i1 %cond = poison
i32 %b = poison
i1 %v1.us = #x1 (1)
i32 %a.phi.lcssa10 = poison
i32 %b.lcssa6 = poison
i1 %v2.us = #x1 (1)
i32 %a.lcssa.us = poison
i32 %b.lcssa.us = poison
i1 %v3.us = #x1 (1)
i1 %v4.us = #x1 (1)
i1 %v1 = #x1 (1)
i1 %v2 = #x1 (1)
i32 %a.lcssa = poison
i32 %b.lcssa = poison
i32 %.us-phi = poison
i32 %.us-phi2 = poison
i32 %result = poison
i1 %v3 = #x1 (1)
i32 %a2 = poison
i1 %v5 = #x1 (1)
i1 %v4 = #x1 (1)



------------------- SMT STATS -------------------
Num queries: 41
Num invalid: 0
Num skips:   0
Num trivial: 62 (60.2%)
Num timeout: 0 (0.0%)
Num errors:  0 (0.0%)
Num SAT:     31 (75.6%)
Num UNSAT:   10 (24.4%)
Alive2: Transform doesn't verify; aborting!

stderr:

+ : 'RUN: at line 1'
+ /home/nlopes/alive2/build/opt-alive.sh '-passes=loop(simple-loop-unswitch<nontrivial>),verify<loops>' -S
+ /home/nlopes/llvm/build/bin/FileCheck /home/nlopes/llvm/llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch.ll

FileCheck error: '<stdin>' is empty.
FileCheck command line:  /home/nlopes/llvm/build/bin/FileCheck /home/nlopes/llvm/llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch.ll

 

<-- Back