Test Failure: Transforms/CallSiteSplitting/callsite-split-or-phi.ll

Test source: git

Log:

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!

stderr:

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

 

<-- Back