Test source: git
Source: <stdin> -- 1. ModuleToFunctionPassAdaptor ERROR: Unsupported instruction: %indirect.goto.dest = select i1 undef, ptr blockaddress(@test_indirectbr_phi, -- 1. PassManager<Function> : Skipping NOP -- 2. CallSiteSplittingPass ---------------------------------------- declare i32 @callee(ptr, i32, i32) define i32 @test_eq_eq(ptr %a, i32 %v) { Header: %tobool1 = icmp eq ptr %a, null br i1 %tobool1, label %Tail, label %TBB TBB: %cmp = icmp eq i32 %v, 1 br i1 %cmp, label %Tail, label %End End: ret i32 %v Tail: %p = phi i32 [ 1, %Header ], [ 2, %TBB ] %r = call i32 @callee(ptr %a, i32 %v, i32 %p) ret i32 %r } Transformation seems to be correct! (syntactically equal) -- 3. CallSiteSplittingPass ---------------------------------------- declare i32 @callee(ptr, i32, i32) define i32 @test_eq_eq(ptr %a, i32 %v) { Header: %tobool1 = icmp eq ptr %a, null br i1 %tobool1, label %Tail, label %TBB TBB: %cmp = icmp eq i32 %v, 1 br i1 %cmp, label %Tail, label %End End: ret i32 %v Tail: %p = phi i32 [ 1, %Header ], [ 2, %TBB ] %r = call i32 @callee(ptr %a, i32 %v, i32 %p) ret i32 %r } => declare i32 @callee(ptr, i32, i32) define i32 @test_eq_eq(ptr %a, i32 %v) { Header: %tobool1 = icmp eq ptr %a, null br i1 %tobool1, label %Header.split, label %TBB TBB: %cmp = icmp eq i32 %v, 1 br i1 %cmp, label %TBB.split, label %End TBB.split: %r2 = call i32 @callee(nonnull ptr %a, i32 1, i32 2) br label %Tail End: ret i32 %v Header.split: %r1 = call i32 @callee(ptr null, i32 %v, i32 1) br label %Tail Tail: %phi.call = phi i32 [ %r1, %Header.split ], [ %r2, %TBB.split ] ret i32 %phi.call } Transformation seems to be correct! -- 4. PassManager<Function> : Skipping NOP -- 5. PassManager<Function> : Skipping NOP -- 6. CallSiteSplittingPass ---------------------------------------- declare i32 @callee(ptr, i32, i32) define i32 @test_eq_eq_eq(ptr %a, i32 %v, i32 %p) { Header: %tobool1 = icmp eq ptr %a, null br i1 %tobool1, label %Header2, label %End Header2: %tobool2 = icmp eq i32 %p, 10 br i1 %tobool2, label %Tail, label %TBB TBB: %cmp = icmp eq i32 %v, 1 br i1 %cmp, label %Tail, label %End Tail: %r = call i32 @callee(ptr %a, i32 %v, i32 %p) ret i32 %r End: ret i32 %v } Transformation seems to be correct! (syntactically equal) -- 7. CallSiteSplittingPass ---------------------------------------- declare i32 @callee(ptr, i32, i32) define i32 @test_eq_eq_eq(ptr %a, i32 %v, i32 %p) { Header: %tobool1 = icmp eq ptr %a, null br i1 %tobool1, label %Header2, label %End Header2: %tobool2 = icmp eq i32 %p, 10 br i1 %tobool2, label %Tail, label %TBB TBB: %cmp = icmp eq i32 %v, 1 br i1 %cmp, label %Tail, label %End Tail: %r = call i32 @callee(ptr %a, i32 %v, i32 %p) ret i32 %r End: ret i32 %v } => declare i32 @callee(ptr, i32, i32) define i32 @test_eq_eq_eq(ptr %a, i32 %v, i32 %p) { Header: %tobool1 = icmp eq ptr %a, null br i1 %tobool1, label %Header2, label %End Header2: %tobool2 = icmp eq i32 %p, 10 br i1 %tobool2, label %Header2.split, label %TBB Header2.split: %r1 = call i32 @callee(ptr %a, i32 %v, i32 10) br label %Tail TBB: %cmp = icmp eq i32 %v, 1 br i1 %cmp, label %TBB.split, label %End TBB.split: %r2 = call i32 @callee(ptr %a, i32 1, i32 %p) br label %Tail Tail: %phi.call = phi i32 [ %r1, %Header2.split ], [ %r2, %TBB.split ] ret i32 %phi.call End: ret i32 %v } Transformation seems to be correct! -- 8. PassManager<Function> : Skipping NOP -- 9. PassManager<Function> : Skipping NOP -- 10. CallSiteSplittingPass ---------------------------------------- declare i32 @callee(ptr, i32, i32) define i32 @test_eq_eq_eq_constrain_same_i32_arg(ptr %a, i32 %v, i32 %p) { Header: %tobool1 = icmp eq i32 %v, 111 br i1 %tobool1, label %Header2, label %End Header2: %tobool2 = icmp eq i32 %v, 222 br i1 %tobool2, label %Tail, label %TBB TBB: %cmp = icmp eq i32 %v, 333 br i1 %cmp, label %Tail, label %End Tail: %r = call i32 @callee(ptr %a, i32 %v, i32 %p) ret i32 %r End: ret i32 %v } Transformation seems to be correct! (syntactically equal) -- 11. CallSiteSplittingPass ---------------------------------------- declare i32 @callee(ptr, i32, i32) define i32 @test_eq_eq_eq_constrain_same_i32_arg(ptr %a, i32 %v, i32 %p) { Header: %tobool1 = icmp eq i32 %v, 111 br i1 %tobool1, label %Header2, label %End Header2: %tobool2 = icmp eq i32 %v, 222 br i1 %tobool2, label %Tail, label %TBB TBB: %cmp = icmp eq i32 %v, 333 br i1 %cmp, label %Tail, label %End Tail: %r = call i32 @callee(ptr %a, i32 %v, i32 %p) ret i32 %r End: ret i32 %v } => declare i32 @callee(ptr, i32, i32) define i32 @test_eq_eq_eq_constrain_same_i32_arg(ptr %a, i32 %v, i32 %p) { Header: %tobool1 = icmp eq i32 %v, 111 br i1 %tobool1, label %Header2, label %End Header2: %tobool2 = icmp eq i32 %v, 222 br i1 %tobool2, label %Header2.split, label %TBB Header2.split: %r1 = call i32 @callee(ptr %a, i32 222, i32 %p) br label %Tail TBB: %cmp = icmp eq i32 %v, 333 br i1 %cmp, label %TBB.split, label %End TBB.split: %r2 = call i32 @callee(ptr %a, i32 333, i32 %p) br label %Tail Tail: %phi.call = phi i32 [ %r1, %Header2.split ], [ %r2, %TBB.split ] ret i32 %phi.call End: ret i32 %v } Transformation seems to be correct! -- 12. PassManager<Function> : Skipping NOP -- 13. PassManager<Function> : Skipping NOP -- 14. CallSiteSplittingPass ---------------------------------------- declare i32 @callee(ptr, i32, i32) define i32 @test_ne_eq(ptr %a, i32 %v) { Header: %tobool1 = icmp ne ptr %a, null br i1 %tobool1, label %Tail, label %TBB TBB: %cmp = icmp eq i32 %v, 1 br i1 %cmp, label %Tail, label %End End: ret i32 %v Tail: %p = phi i32 [ 1, %Header ], [ 2, %TBB ] %r = call i32 @callee(ptr %a, i32 %v, i32 %p) ret i32 %r } Transformation seems to be correct! (syntactically equal) -- 15. CallSiteSplittingPass ---------------------------------------- declare i32 @callee(ptr, i32, i32) define i32 @test_ne_eq(ptr %a, i32 %v) { Header: %tobool1 = icmp ne ptr %a, null br i1 %tobool1, label %Tail, label %TBB TBB: %cmp = icmp eq i32 %v, 1 br i1 %cmp, label %Tail, label %End End: ret i32 %v Tail: %p = phi i32 [ 1, %Header ], [ 2, %TBB ] %r = call i32 @callee(ptr %a, i32 %v, i32 %p) ret i32 %r } => declare i32 @callee(ptr, i32, i32) define i32 @test_ne_eq(ptr %a, i32 %v) { Header: %tobool1 = icmp ne ptr %a, null br i1 %tobool1, label %Header.split, label %TBB TBB: %cmp = icmp eq i32 %v, 1 br i1 %cmp, label %TBB.split, label %End TBB.split: %r2 = call i32 @callee(ptr null, i32 1, i32 2) br label %Tail End: ret i32 %v Header.split: %r1 = call i32 @callee(nonnull ptr %a, i32 %v, i32 1) br label %Tail Tail: %phi.call = phi i32 [ %r1, %Header.split ], [ %r2, %TBB.split ] ret i32 %phi.call } Transformation seems to be correct! -- 16. PassManager<Function> : Skipping NOP -- 17. PassManager<Function> : Skipping NOP -- 18. CallSiteSplittingPass ---------------------------------------- declare i32 @callee(ptr, i32, i32) define i32 @test_ne_eq_ne(ptr %a, i32 %v, i32 %p) { Header: %tobool1 = icmp ne ptr %a, null br i1 %tobool1, label %Header2, label %TBB Header2: %tobool2 = icmp eq i32 %p, 10 br i1 %tobool2, label %Tail, label %TBB TBB: %cmp = icmp ne i32 %v, 1 br i1 %cmp, label %Tail, label %End Tail: %r = call i32 @callee(ptr %a, i32 %v, i32 %p) ret i32 %r End: ret i32 %v } Transformation seems to be correct! (syntactically equal) -- 19. CallSiteSplittingPass ---------------------------------------- declare i32 @callee(ptr, i32, i32) define i32 @test_ne_eq_ne(ptr %a, i32 %v, i32 %p) { Header: %tobool1 = icmp ne ptr %a, null br i1 %tobool1, label %Header2, label %TBB Header2: %tobool2 = icmp eq i32 %p, 10 br i1 %tobool2, label %Tail, label %TBB TBB: %cmp = icmp ne i32 %v, 1 br i1 %cmp, label %Tail, label %End Tail: %r = call i32 @callee(ptr %a, i32 %v, i32 %p) ret i32 %r End: ret i32 %v } => declare i32 @callee(ptr, i32, i32) define i32 @test_ne_eq_ne(ptr %a, i32 %v, i32 %p) { Header: %tobool1 = icmp ne ptr %a, null br i1 %tobool1, label %Header2, label %TBB Header2: %tobool2 = icmp eq i32 %p, 10 br i1 %tobool2, label %Header2.split, label %TBB Header2.split: %r1 = call i32 @callee(nonnull ptr %a, i32 %v, i32 10) br label %Tail TBB: %cmp = icmp ne i32 %v, 1 br i1 %cmp, label %TBB.split, label %End TBB.split: %r2 = call i32 @callee(ptr %a, i32 %v, i32 %p) br label %Tail Tail: %phi.call = phi i32 [ %r1, %Header2.split ], [ %r2, %TBB.split ] ret i32 %phi.call End: ret i32 %v } Transformation seems to be correct! -- 20. PassManager<Function> : Skipping NOP -- 21. PassManager<Function> : Skipping NOP -- 22. CallSiteSplittingPass ---------------------------------------- declare i32 @callee(ptr, i32, i32) define i32 @test_ne_ne(ptr %a, i32 %v) { Header: %tobool1 = icmp ne ptr %a, null br i1 %tobool1, label %Tail, label %TBB TBB: %cmp = icmp ne i32 %v, 1 br i1 %cmp, label %Tail, label %End End: ret i32 %v Tail: %p = phi i32 [ 1, %Header ], [ 2, %TBB ] %r = call i32 @callee(ptr %a, i32 %v, i32 %p) ret i32 %r } Transformation seems to be correct! (syntactically equal) -- 23. CallSiteSplittingPass ---------------------------------------- declare i32 @callee(ptr, i32, i32) define i32 @test_ne_ne(ptr %a, i32 %v) { Header: %tobool1 = icmp ne ptr %a, null br i1 %tobool1, label %Tail, label %TBB TBB: %cmp = icmp ne i32 %v, 1 br i1 %cmp, label %Tail, label %End End: ret i32 %v Tail: %p = phi i32 [ 1, %Header ], [ 2, %TBB ] %r = call i32 @callee(ptr %a, i32 %v, i32 %p) ret i32 %r } => declare i32 @callee(ptr, i32, i32) define i32 @test_ne_ne(ptr %a, i32 %v) { Header: %tobool1 = icmp ne ptr %a, null br i1 %tobool1, label %Header.split, label %TBB TBB: %cmp = icmp ne i32 %v, 1 br i1 %cmp, label %TBB.split, label %End TBB.split: %r2 = call i32 @callee(ptr null, i32 %v, i32 2) br label %Tail End: ret i32 %v Header.split: %r1 = call i32 @callee(nonnull ptr %a, i32 %v, i32 1) br label %Tail Tail: %phi.call = phi i32 [ %r1, %Header.split ], [ %r2, %TBB.split ] ret i32 %phi.call } Transformation seems to be correct! -- 24. PassManager<Function> : Skipping NOP -- 25. PassManager<Function> : Skipping NOP -- 26. CallSiteSplittingPass ---------------------------------------- declare i32 @callee(ptr, i32, i32) define i32 @test_ne_ne_ne_constrain_same_pointer_arg(ptr %a, i32 %v, i32 %p, ptr %a2, ptr %a3) { Header: %tobool1 = icmp ne ptr %a, null br i1 %tobool1, label %Header2, label %TBB Header2: %tobool2 = icmp ne ptr %a, %a2 br i1 %tobool2, label %Tail, label %TBB TBB: %cmp = icmp ne ptr %a, %a3 br i1 %cmp, label %Tail, label %End Tail: %r = call i32 @callee(ptr %a, i32 %v, i32 %p) ret i32 %r End: ret i32 %v } Transformation seems to be correct! (syntactically equal) -- 27. CallSiteSplittingPass ---------------------------------------- declare i32 @callee(ptr, i32, i32) define i32 @test_ne_ne_ne_constrain_same_pointer_arg(ptr %a, i32 %v, i32 %p, ptr %a2, ptr %a3) { Header: %tobool1 = icmp ne ptr %a, null br i1 %tobool1, label %Header2, label %TBB Header2: %tobool2 = icmp ne ptr %a, %a2 br i1 %tobool2, label %Tail, label %TBB TBB: %cmp = icmp ne ptr %a, %a3 br i1 %cmp, label %Tail, label %End Tail: %r = call i32 @callee(ptr %a, i32 %v, i32 %p) ret i32 %r End: ret i32 %v } => declare i32 @callee(ptr, i32, i32) define i32 @test_ne_ne_ne_constrain_same_pointer_arg(ptr %a, i32 %v, i32 %p, ptr %a2, ptr %a3) { Header: %tobool1 = icmp ne ptr %a, null br i1 %tobool1, label %Header2, label %TBB Header2: %tobool2 = icmp ne ptr %a, %a2 br i1 %tobool2, label %Header2.split, label %TBB Header2.split: %r1 = call i32 @callee(nonnull ptr %a, i32 %v, i32 %p) br label %Tail TBB: %cmp = icmp ne ptr %a, %a3 br i1 %cmp, label %TBB.split, label %End TBB.split: %r2 = call i32 @callee(ptr %a, i32 %v, i32 %p) br label %Tail Tail: %phi.call = phi i32 [ %r1, %Header2.split ], [ %r2, %TBB.split ] ret i32 %phi.call End: ret i32 %v } Transformation doesn't verify! (not unsound) ERROR: Timeout -- 28. PassManager<Function> : Skipping NOP -- 29. PassManager<Function> : Skipping NOP -- 30. CallSiteSplittingPass ---------------------------------------- declare i32 @callee(ptr, i32, i32) define i32 @test_eq_eq_untaken(ptr %a, i32 %v) { Header: %tobool1 = icmp eq ptr %a, null br i1 %tobool1, label %TBB, label %Tail TBB: %cmp = icmp eq i32 %v, 1 br i1 %cmp, label %Tail, label %End Tail: %p = phi i32 [ 1, %Header ], [ 2, %TBB ] %r = call i32 @callee(ptr %a, i32 %v, i32 %p) ret i32 %r End: ret i32 %v } Transformation seems to be correct! (syntactically equal) -- 31. CallSiteSplittingPass ---------------------------------------- declare i32 @callee(ptr, i32, i32) define i32 @test_eq_eq_untaken(ptr %a, i32 %v) { Header: %tobool1 = icmp eq ptr %a, null br i1 %tobool1, label %TBB, label %Tail TBB: %cmp = icmp eq i32 %v, 1 br i1 %cmp, label %Tail, label %End Tail: %p = phi i32 [ 1, %Header ], [ 2, %TBB ] %r = call i32 @callee(ptr %a, i32 %v, i32 %p) ret i32 %r End: ret i32 %v } => declare i32 @callee(ptr, i32, i32) define i32 @test_eq_eq_untaken(ptr %a, i32 %v) { Header: %tobool1 = icmp eq ptr %a, null br i1 %tobool1, label %TBB, label %Header.split Header.split: %r1 = call i32 @callee(nonnull ptr %a, i32 %v, i32 1) br label %Tail TBB: %cmp = icmp eq i32 %v, 1 br i1 %cmp, label %TBB.split, label %End TBB.split: %r2 = call i32 @callee(ptr null, i32 1, i32 2) br label %Tail Tail: %phi.call = phi i32 [ %r1, %Header.split ], [ %r2, %TBB.split ] ret i32 %phi.call End: ret i32 %v } Transformation seems to be correct! -- 32. PassManager<Function> : Skipping NOP -- 33. PassManager<Function> : Skipping NOP -- 34. CallSiteSplittingPass ---------------------------------------- declare i32 @callee(ptr, i32, i32) define i32 @test_eq_eq_eq_untaken(ptr %a, i32 %v, i32 %p) { Header: %tobool1 = icmp eq ptr %a, null br i1 %tobool1, label %TBB, label %Header2 Header2: %tobool2 = icmp eq i32 %p, 10 br i1 %tobool2, label %Tail, label %TBB TBB: %cmp = icmp eq i32 %v, 1 br i1 %cmp, label %Tail, label %End Tail: %r = call i32 @callee(ptr %a, i32 %v, i32 %p) ret i32 %r End: ret i32 %v } Transformation seems to be correct! (syntactically equal) -- 35. CallSiteSplittingPass ---------------------------------------- declare i32 @callee(ptr, i32, i32) define i32 @test_eq_eq_eq_untaken(ptr %a, i32 %v, i32 %p) { Header: %tobool1 = icmp eq ptr %a, null br i1 %tobool1, label %TBB, label %Header2 Header2: %tobool2 = icmp eq i32 %p, 10 br i1 %tobool2, label %Tail, label %TBB TBB: %cmp = icmp eq i32 %v, 1 br i1 %cmp, label %Tail, label %End Tail: %r = call i32 @callee(ptr %a, i32 %v, i32 %p) ret i32 %r End: ret i32 %v } => declare i32 @callee(ptr, i32, i32) define i32 @test_eq_eq_eq_untaken(ptr %a, i32 %v, i32 %p) { Header: %tobool1 = icmp eq ptr %a, null br i1 %tobool1, label %TBB, label %Header2 Header2: %tobool2 = icmp eq i32 %p, 10 br i1 %tobool2, label %Header2.split, label %TBB Header2.split: %r1 = call i32 @callee(nonnull ptr %a, i32 %v, i32 10) br label %Tail TBB: %cmp = icmp eq i32 %v, 1 br i1 %cmp, label %TBB.split, label %End TBB.split: %r2 = call i32 @callee(ptr %a, i32 1, i32 %p) br label %Tail Tail: %phi.call = phi i32 [ %r1, %Header2.split ], [ %r2, %TBB.split ] ret i32 %phi.call End: ret i32 %v } Transformation seems to be correct! -- 36. PassManager<Function> : Skipping NOP -- 37. PassManager<Function> : Skipping NOP -- 38. CallSiteSplittingPass ---------------------------------------- declare i32 @callee(ptr, i32, i32) define i32 @test_ne_eq_untaken(ptr %a, i32 %v) { Header: %tobool1 = icmp ne ptr %a, null br i1 %tobool1, label %TBB, label %Tail TBB: %cmp = icmp eq i32 %v, 1 br i1 %cmp, label %Tail, label %End Tail: %p = phi i32 [ 1, %Header ], [ 2, %TBB ] %r = call i32 @callee(ptr %a, i32 %v, i32 %p) ret i32 %r End: ret i32 %v } Transformation seems to be correct! (syntactically equal) -- 39. CallSiteSplittingPass ---------------------------------------- declare i32 @callee(ptr, i32, i32) define i32 @test_ne_eq_untaken(ptr %a, i32 %v) { Header: %tobool1 = icmp ne ptr %a, null br i1 %tobool1, label %TBB, label %Tail TBB: %cmp = icmp eq i32 %v, 1 br i1 %cmp, label %Tail, label %End Tail: %p = phi i32 [ 1, %Header ], [ 2, %TBB ] %r = call i32 @callee(ptr %a, i32 %v, i32 %p) ret i32 %r End: ret i32 %v } => declare i32 @callee(ptr, i32, i32) define i32 @test_ne_eq_untaken(ptr %a, i32 %v) { Header: %tobool1 = icmp ne ptr %a, null br i1 %tobool1, label %TBB, label %Header.split Header.split: %r1 = call i32 @callee(ptr null, i32 %v, i32 1) br label %Tail TBB: %cmp = icmp eq i32 %v, 1 br i1 %cmp, label %TBB.split, label %End TBB.split: %r2 = call i32 @callee(nonnull ptr %a, i32 1, i32 2) br label %Tail Tail: %phi.call = phi i32 [ %r1, %Header.split ], [ %r2, %TBB.split ] ret i32 %phi.call End: ret i32 %v } Transformation seems to be correct! -- 40. PassManager<Function> : Skipping NOP -- 41. PassManager<Function> : Skipping NOP -- 42. CallSiteSplittingPass ---------------------------------------- declare i32 @callee(ptr, i32, i32) define i32 @test_ne_eq_ne_untaken(ptr %a, i32 %v, i32 %p) { Header: %tobool1 = icmp ne ptr %a, null br i1 %tobool1, label %TBB, label %Header2 Header2: %tobool2 = icmp eq i32 %p, 10 br i1 %tobool2, label %Tail, label %TBB TBB: %cmp = icmp ne i32 %v, 1 br i1 %cmp, label %Tail, label %End Tail: %r = call i32 @callee(ptr %a, i32 %v, i32 %p) ret i32 %r End: ret i32 %v } Transformation seems to be correct! (syntactically equal) -- 43. CallSiteSplittingPass ---------------------------------------- declare i32 @callee(ptr, i32, i32) define i32 @test_ne_eq_ne_untaken(ptr %a, i32 %v, i32 %p) { Header: %tobool1 = icmp ne ptr %a, null br i1 %tobool1, label %TBB, label %Header2 Header2: %tobool2 = icmp eq i32 %p, 10 br i1 %tobool2, label %Tail, label %TBB TBB: %cmp = icmp ne i32 %v, 1 br i1 %cmp, label %Tail, label %End Tail: %r = call i32 @callee(ptr %a, i32 %v, i32 %p) ret i32 %r End: ret i32 %v } => declare i32 @callee(ptr, i32, i32) define i32 @test_ne_eq_ne_untaken(ptr %a, i32 %v, i32 %p) { Header: %tobool1 = icmp ne ptr %a, null br i1 %tobool1, label %TBB, label %Header2 Header2: %tobool2 = icmp eq i32 %p, 10 br i1 %tobool2, label %Header2.split, label %TBB Header2.split: %r1 = call i32 @callee(ptr null, i32 %v, i32 10) br label %Tail TBB: %cmp = icmp ne i32 %v, 1 br i1 %cmp, label %TBB.split, label %End TBB.split: %r2 = call i32 @callee(ptr %a, i32 %v, i32 %p) br label %Tail Tail: %phi.call = phi i32 [ %r1, %Header2.split ], [ %r2, %TBB.split ] ret i32 %phi.call End: ret i32 %v } Transformation seems to be correct! -- 44. PassManager<Function> : Skipping NOP -- 45. PassManager<Function> : Skipping NOP -- 46. CallSiteSplittingPass ---------------------------------------- declare i32 @callee(ptr, i32, i32) define i32 @test_ne_ne_untaken(ptr %a, i32 %v) { Header: %tobool1 = icmp ne ptr %a, null br i1 %tobool1, label %TBB, label %Tail TBB: %cmp = icmp ne i32 %v, 1 br i1 %cmp, label %End, label %Tail End: ret i32 %v Tail: %p = phi i32 [ 1, %Header ], [ 2, %TBB ] %r = call i32 @callee(ptr %a, i32 %v, i32 %p) ret i32 %r } Transformation seems to be correct! (syntactically equal) -- 47. CallSiteSplittingPass ---------------------------------------- declare i32 @callee(ptr, i32, i32) define i32 @test_ne_ne_untaken(ptr %a, i32 %v) { Header: %tobool1 = icmp ne ptr %a, null br i1 %tobool1, label %TBB, label %Tail TBB: %cmp = icmp ne i32 %v, 1 br i1 %cmp, label %End, label %Tail End: ret i32 %v Tail: %p = phi i32 [ 1, %Header ], [ 2, %TBB ] %r = call i32 @callee(ptr %a, i32 %v, i32 %p) ret i32 %r } => declare i32 @callee(ptr, i32, i32) define i32 @test_ne_ne_untaken(ptr %a, i32 %v) { Header: %tobool1 = icmp ne ptr %a, null br i1 %tobool1, label %TBB, label %Header.split Header.split: %r1 = call i32 @callee(ptr null, i32 %v, i32 1) br label %Tail TBB: %cmp = icmp ne i32 %v, 1 br i1 %cmp, label %End, label %TBB.split End: ret i32 %v TBB.split: %r2 = call i32 @callee(nonnull ptr %a, i32 1, i32 2) br label %Tail Tail: %phi.call = phi i32 [ %r1, %Header.split ], [ %r2, %TBB.split ] ret i32 %phi.call } Transformation seems to be correct! -- 48. PassManager<Function> : Skipping NOP -- 49. PassManager<Function> : Skipping NOP -- 50. CallSiteSplittingPass ---------------------------------------- declare i32 @callee(ptr, i32, i32) define i32 @test_nonconst_const_phi(ptr %a, ptr %b, i32 %v) { Header: %tobool1 = icmp eq ptr %a, %b br i1 %tobool1, label %Tail, label %TBB TBB: %cmp = icmp eq i32 %v, 1 br i1 %cmp, label %Tail, label %End End: ret i32 %v Tail: %p = phi i32 [ 1, %Header ], [ 2, %TBB ] %r = call i32 @callee(ptr %a, i32 %v, i32 %p) ret i32 %r } Transformation seems to be correct! (syntactically equal) -- 51. CallSiteSplittingPass ---------------------------------------- declare i32 @callee(ptr, i32, i32) define i32 @test_nonconst_const_phi(ptr %a, ptr %b, i32 %v) { Header: %tobool1 = icmp eq ptr %a, %b br i1 %tobool1, label %Tail, label %TBB TBB: %cmp = icmp eq i32 %v, 1 br i1 %cmp, label %Tail, label %End End: ret i32 %v Tail: %p = phi i32 [ 1, %Header ], [ 2, %TBB ] %r = call i32 @callee(ptr %a, i32 %v, i32 %p) ret i32 %r } => declare i32 @callee(ptr, i32, i32) define i32 @test_nonconst_const_phi(ptr %a, ptr %b, i32 %v) { Header: %tobool1 = icmp eq ptr %a, %b br i1 %tobool1, label %Header.split, label %TBB TBB: %cmp = icmp eq i32 %v, 1 br i1 %cmp, label %TBB.split, label %End TBB.split: %r2 = call i32 @callee(ptr %a, i32 1, i32 2) br label %Tail End: ret i32 %v Header.split: %r1 = call i32 @callee(ptr %a, i32 %v, i32 1) br label %Tail Tail: %phi.call = phi i32 [ %r1, %Header.split ], [ %r2, %TBB.split ] ret i32 %phi.call } Transformation seems to be correct! -- 52. PassManager<Function> : Skipping NOP -- 53. PassManager<Function> : Skipping NOP -- 54. CallSiteSplittingPass ---------------------------------------- declare i32 @callee(ptr, i32, i32) define i32 @test_nonconst_nonconst_phi(ptr %a, ptr %b, i32 %v, i32 %v2) { Header: %tobool1 = icmp eq ptr %a, %b br i1 %tobool1, label %Tail, label %TBB TBB: %cmp = icmp eq i32 %v, %v2 br i1 %cmp, label %Tail, label %End End: ret i32 %v Tail: %p = phi i32 [ 1, %Header ], [ 2, %TBB ] %r = call i32 @callee(ptr %a, i32 %v, i32 %p) ret i32 %r } Transformation seems to be correct! (syntactically equal) -- 55. CallSiteSplittingPass ---------------------------------------- declare i32 @callee(ptr, i32, i32) define i32 @test_nonconst_nonconst_phi(ptr %a, ptr %b, i32 %v, i32 %v2) { Header: %tobool1 = icmp eq ptr %a, %b br i1 %tobool1, label %Tail, label %TBB TBB: %cmp = icmp eq i32 %v, %v2 br i1 %cmp, label %Tail, label %End End: ret i32 %v Tail: %p = phi i32 [ 1, %Header ], [ 2, %TBB ] %r = call i32 @callee(ptr %a, i32 %v, i32 %p) ret i32 %r } => declare i32 @callee(ptr, i32, i32) define i32 @test_nonconst_nonconst_phi(ptr %a, ptr %b, i32 %v, i32 %v2) { Header: %tobool1 = icmp eq ptr %a, %b br i1 %tobool1, label %Header.split, label %TBB TBB: %cmp = icmp eq i32 %v, %v2 br i1 %cmp, label %TBB.split, label %End TBB.split: %r1 = call i32 @callee(ptr %a, i32 %v, i32 2) br label %Tail End: ret i32 %v Header.split: %r2 = call i32 @callee(ptr %a, i32 %v, i32 1) br label %Tail Tail: %phi.call = phi i32 [ %r1, %TBB.split ], [ %r2, %Header.split ] ret i32 %phi.call } Transformation seems to be correct! -- 56. PassManager<Function> : Skipping NOP -- 57. PassManager<Function> : Skipping NOP -- 58. CallSiteSplittingPass ---------------------------------------- declare i32 @callee(ptr, i32, i32) define i32 @test_cfg_no_or_phi(ptr %a, i32 %v) { entry: br i1 undef, label %TBB0, label %TBB1 TBB1: br i1 undef, label %Tail, label %End TBB0: br i1 undef, label %Tail, label %End Tail: %p = phi i32 [ 1, %TBB0 ], [ 2, %TBB1 ] %r = call i32 @callee(ptr %a, i32 %v, i32 %p) ret i32 %r End: ret i32 %v } Transformation seems to be correct! (syntactically equal) -- 59. CallSiteSplittingPass ---------------------------------------- declare i32 @callee(ptr, i32, i32) define i32 @test_cfg_no_or_phi(ptr %a, i32 %v) { entry: br i1 undef, label %TBB0, label %TBB1 TBB1: br i1 undef, label %Tail, label %End TBB0: br i1 undef, label %Tail, label %End Tail: %p = phi i32 [ 1, %TBB0 ], [ 2, %TBB1 ] %r = call i32 @callee(ptr %a, i32 %v, i32 %p) ret i32 %r End: ret i32 %v } => declare i32 @callee(ptr, i32, i32) define i32 @test_cfg_no_or_phi(ptr %a, i32 %v) { entry: br i1 undef, label %TBB0, label %TBB1 TBB1: br i1 undef, label %TBB1.split, label %End TBB1.split: %r1 = call i32 @callee(ptr %a, i32 %v, i32 2) br label %Tail TBB0: br i1 undef, label %TBB0.split, label %End TBB0.split: %r2 = call i32 @callee(ptr %a, i32 %v, i32 1) br label %Tail Tail: %phi.call = phi i32 [ %r1, %TBB1.split ], [ %r2, %TBB0.split ] ret i32 %phi.call End: ret i32 %v } **************************************** WARNING: Source function is always UB. It can be refined by any target function. Please make sure this is what you wanted. **************************************** Transformation seems to be correct! -- 60. PassManager<Function> : Skipping NOP -- 61. PassManager<Function> : Skipping NOP -- 62. CallSiteSplittingPass ---------------------------------------- declare i32 @callee(ptr, i32, i32) define i32 @test_nonconst_nonconst_phi_noncost(ptr %a, ptr %b, i32 %v, i32 %v2) { Header: %tobool1 = icmp eq ptr %a, %b br i1 %tobool1, label %Tail, label %TBB TBB: %cmp = icmp eq i32 %v, %v2 br i1 %cmp, label %Tail, label %End End: ret i32 %v Tail: %p = phi i32 [ %v, %Header ], [ %v2, %TBB ] %r = call i32 @callee(ptr %a, i32 %v, i32 %p) ret i32 %r } Transformation seems to be correct! (syntactically equal) -- 63. CallSiteSplittingPass ---------------------------------------- declare i32 @callee(ptr, i32, i32) define i32 @test_nonconst_nonconst_phi_noncost(ptr %a, ptr %b, i32 %v, i32 %v2) { Header: %tobool1 = icmp eq ptr %a, %b br i1 %tobool1, label %Tail, label %TBB TBB: %cmp = icmp eq i32 %v, %v2 br i1 %cmp, label %Tail, label %End End: ret i32 %v Tail: %p = phi i32 [ %v, %Header ], [ %v2, %TBB ] %r = call i32 @callee(ptr %a, i32 %v, i32 %p) ret i32 %r } Transformation seems to be correct! (syntactically equal) -- 64. PassManager<Function> : Skipping NOP -- 65. PassManager<Function> : Skipping NOP -- 66. CallSiteSplittingPass ---------------------------------------- declare i32 @callee(ptr, i32, i32) define i32 @test_3preds_constphi(ptr %a, i32 %v, i1 %c1, i1 %c2, i1 %c3) { Header: br i1 %c1, label %Tail, label %TBB1 TBB1: br i1 %c2, label %Tail, label %TBB2 TBB2: br i1 %c3, label %Tail, label %End End: ret i32 %v Tail: %p = phi i32 [ 1, %Header ], [ 2, %TBB1 ], [ 3, %TBB2 ] %r = call i32 @callee(ptr %a, i32 %v, i32 %p) ret i32 %r } Transformation seems to be correct! (syntactically equal) -- 67. CallSiteSplittingPass ---------------------------------------- declare i32 @callee(ptr, i32, i32) define i32 @test_3preds_constphi(ptr %a, i32 %v, i1 %c1, i1 %c2, i1 %c3) { Header: br i1 %c1, label %Tail, label %TBB1 TBB1: br i1 %c2, label %Tail, label %TBB2 TBB2: br i1 %c3, label %Tail, label %End End: ret i32 %v Tail: %p = phi i32 [ 1, %Header ], [ 2, %TBB1 ], [ 3, %TBB2 ] %r = call i32 @callee(ptr %a, i32 %v, i32 %p) ret i32 %r } Transformation seems to be correct! (syntactically equal) -- 68. PassManager<Function> : Skipping NOP -- 69. PassManager<Function> : Skipping NOP ERROR: Unsupported instruction: %indirect.goto.dest = select i1 undef, ptr blockaddress(@test_indirectbr_phi, -- 70. CallSiteSplittingPass ERROR: Unsupported instruction: %indirect.goto.dest = select i1 undef, ptr blockaddress(@test_indirectbr_phi, -- 71. CallSiteSplittingPass ERROR: Unsupported instruction: %indirect.goto.dest = select i1 undef, ptr blockaddress(@test_indirectbr_phi, -- 72. PassManager<Function> : Skipping NOP ERROR: Unsupported instruction: %indirect.goto.dest = select i1 undef, ptr blockaddress(@test_indirectbr_phi, -- 73. PassManager<Function> : Skipping NOP -- 74. CallSiteSplittingPass ---------------------------------------- declare i32 @callee(ptr, i32, i32) define i32 @test_cond_no_effect(ptr %a, i32 %v) { Entry: %tobool1 = icmp eq ptr %a, null br i1 %tobool1, label %Header, label %End Header: br i1 undef, label %Tail, label %TBB TBB: br i1 undef, label %Tail, label %End Tail: %r = call i32 @callee(ptr %a, i32 %v, i32 0) ret i32 %r End: ret i32 %v } Transformation seems to be correct! (syntactically equal) -- 75. CallSiteSplittingPass ---------------------------------------- declare i32 @callee(ptr, i32, i32) define i32 @test_cond_no_effect(ptr %a, i32 %v) { Entry: %tobool1 = icmp eq ptr %a, null br i1 %tobool1, label %Header, label %End Header: br i1 undef, label %Tail, label %TBB TBB: br i1 undef, label %Tail, label %End Tail: %r = call i32 @callee(ptr %a, i32 %v, i32 0) ret i32 %r End: ret i32 %v } Transformation seems to be correct! (syntactically equal) -- 76. PassManager<Function> : Skipping NOP -- 77. PassManager<Function> : Skipping NOP -- 78. CallSiteSplittingPass ---------------------------------------- declare i32 @callee(ptr, i32, i32) define i32 @test_unreachable(ptr %a, i32 %v, i32 %p) { Entry: br label %End Header: %tobool2 = icmp eq i32 %p, 10 br i1 %tobool2, label %Tail, label %TBB TBB: %cmp = icmp eq i32 %v, 1 br i1 %cmp, label %Tail, label %Header Tail: %r = call i32 @callee(ptr %a, i32 %v, i32 %p) ret i32 %r End: ret i32 %v } Transformation seems to be correct! (syntactically equal) -- 79. CallSiteSplittingPass ---------------------------------------- declare i32 @callee(ptr, i32, i32) define i32 @test_unreachable(ptr %a, i32 %v, i32 %p) { Entry: br label %End End: ret i32 %v } => declare i32 @callee(ptr, i32, i32) define i32 @test_unreachable(ptr %a, i32 %v, i32 %p) { Entry: br label %End End: ret i32 %v } Transformation seems to be correct! -- 80. PassManager<Function> : Skipping NOP -- 81. PassManager<Function> : Skipping NOP -- 82. CallSiteSplittingPass ---------------------------------------- declare void @dummy2(i32, i32) declare void @dummy(ptr, i32) define i32 @callee(ptr %a, i32 %v, i32 %p) { entry: %c = icmp ne ptr %a, null br i1 %c, label %BB1, label %BB2 BB2: call void @dummy2(i32 %v, i32 %p) br label %End BB1: call void @dummy(ptr %a, i32 %p) br label %End End: ret i32 %p } Transformation seems to be correct! (syntactically equal) -- 83. CallSiteSplittingPass ---------------------------------------- declare void @dummy2(i32, i32) declare void @dummy(ptr, i32) define i32 @callee(ptr %a, i32 %v, i32 %p) { entry: %c = icmp ne ptr %a, null br i1 %c, label %BB1, label %BB2 BB2: call void @dummy2(i32 %v, i32 %p) br label %End BB1: call void @dummy(ptr %a, i32 %p) br label %End End: ret i32 %p } Transformation seems to be correct! (syntactically equal) -- 84. PassManager<Function> : Skipping NOP -- 85. PassManager<Function> : Skipping NOP -- 86. CallSiteSplittingPass ---------------------------------------- declare i32 @callee(ptr, i32, i32) define void @caller2(i32 %c, ptr %a_elt, ptr %b_elt) { entry: br label %Top0 Top0: %__constexpr_0 = int2ptr i64 4643 to ptr %tobool1 = icmp eq ptr %a_elt, %__constexpr_0 br i1 %tobool1, label %Top1, label %NextCond Top1: %tobool2 = icmp ne ptr %a_elt, null br i1 %tobool2, label %CallSiteBB, label %NextCond NextCond: %cmp = icmp ne ptr %b_elt, null br i1 %cmp, label %CallSiteBB, label %End CallSiteBB: %#0 = call i32 @callee(ptr %a_elt, i32 %c, i32 %c) br label %End End: ret void } Transformation seems to be correct! (syntactically equal) -- 87. CallSiteSplittingPass ---------------------------------------- declare i32 @callee(ptr, i32, i32) define void @caller2(i32 %c, ptr %a_elt, ptr %b_elt) { entry: br label %Top0 Top0: %__constexpr_0 = int2ptr i64 4643 to ptr %tobool1 = icmp eq ptr %a_elt, %__constexpr_0 br i1 %tobool1, label %Top1, label %NextCond Top1: %tobool2 = icmp ne ptr %a_elt, null br i1 %tobool2, label %CallSiteBB, label %NextCond NextCond: %cmp = icmp ne ptr %b_elt, null br i1 %cmp, label %CallSiteBB, label %End CallSiteBB: %#0 = call i32 @callee(ptr %a_elt, i32 %c, i32 %c) br label %End End: ret void } => declare i32 @callee(ptr, i32, i32) define void @caller2(i32 %c, ptr %a_elt, ptr %b_elt) { entry: br label %Top0 Top0: %__constexpr_0 = int2ptr i64 4643 to ptr %tobool1 = icmp eq ptr %a_elt, %__constexpr_0 br i1 %tobool1, label %Top1, label %NextCond Top1: %tobool2 = icmp ne ptr %a_elt, null br i1 %tobool2, label %Top1.split, label %NextCond Top1.split: %__constexpr_1 = int2ptr i64 4643 to ptr %#0 = call i32 @callee(ptr %__constexpr_1, i32 %c, i32 %c) br label %CallSiteBB NextCond: %cmp = icmp ne ptr %b_elt, null br i1 %cmp, label %NextCond.split, label %End NextCond.split: %#1 = call i32 @callee(ptr %a_elt, i32 %c, i32 %c) br label %CallSiteBB CallSiteBB: br label %End End: ret void } Transformation doesn't verify! (unsound) ERROR: Source is more defined than target Example: i32 %c = poison ptr %a_elt = pointer(non-local, block_id=0, offset=4643) / Address=#x0000000000001223 ptr %b_elt = null Source: >> Jump to %Top0 ptr %__constexpr_0 = phy-ptr(addr=4643) / Address=#x0000000000001223 i1 %tobool1 = #x1 (1) >> Jump to %Top1 i1 %tobool2 = #x1 (1) >> Jump to %CallSiteBB i32 %#0 = function did not return! SOURCE MEMORY STATE =================== NON-LOCAL BLOCKS: Block 0 > size: 0 align: 1 alloc type: 0 alive: false address: 0 Block 1 > size: 4 align: 1 alloc type: 0 alive: true address: 8 Block 2 > size: 3 align: 1 alloc type: 0 alive: true address: 4 Block 3 > size: 2 align: 1 alloc type: 0 alive: true address: 12 Block 4 > size: 1 align: 1 alloc type: 0 alive: true address: 14 Target: >> Jump to %Top0 ptr %__constexpr_0 = phy-ptr(addr=4643) / Address=#x0000000000001223 i1 %tobool1 = #x1 (1) >> Jump to %Top1 i1 %tobool2 = #x1 (1) >> Jump to %Top1.split ptr %__constexpr_1 = phy-ptr(addr=4643) / Address=#x0000000000001223 i32 %#0 = function did not return! Pass: CallSiteSplittingPass Command line: '/home/nlopes/llvm/build/bin/opt' '-load=/home/nlopes/alive2/build/tv/tv.so' '-load-pass-plugin=/home/nlopes/alive2/build/tv/tv.so' '-tv-exit-on-error' '-passes=callsite-splitting' '-S' '-tv-smt-to=20000' '-tv-report-dir=/home/nlopes/alive2/build/logs' '-tv-smt-stats' Wrote bitcode to: "/home/nlopes/alive2/build/logs/in_9QpunX1a_ZYXK.bc" ------------------- SMT STATS ------------------- Num queries: 158 Num invalid: 0 Num skips: 0 Num trivial: 24 (13.2%) Num timeout: 4 (2.5%) Num errors: 0 (0.0%) Num SAT: 62 (39.2%) Num UNSAT: 92 (58.2%) Alive2: Transform doesn't verify; aborting!
RUN: at line 1: /home/nlopes/alive2/build/opt-alive.sh < /bitbucket/nlopes/llvm/llvm/test/Transforms/CallSiteSplitting/callsite-split-or-phi.ll -passes=callsite-splitting -S | /bitbucket/nlopes/llvm/build/bin/FileCheck /bitbucket/nlopes/llvm/llvm/test/Transforms/CallSiteSplitting/callsite-split-or-phi.ll + /home/nlopes/alive2/build/opt-alive.sh -passes=callsite-splitting -S + /bitbucket/nlopes/llvm/build/bin/FileCheck /bitbucket/nlopes/llvm/llvm/test/Transforms/CallSiteSplitting/callsite-split-or-phi.ll FileCheck error: '<stdin>' is empty. FileCheck command line: /bitbucket/nlopes/llvm/build/bin/FileCheck /bitbucket/nlopes/llvm/llvm/test/Transforms/CallSiteSplitting/callsite-split-or-phi.ll