1; RUN: opt < %s -callsite-splitting -S | FileCheck %s 2; RUN: opt < %s -passes='function(callsite-splitting)' -S | FileCheck %s 3 4; CHECK-LABEL: @test_simple 5; CHECK-LABEL: Header: 6; CHECK-NEXT: br i1 undef, label %Header.split 7; CHECK-LABEL: Header.split: 8; CHECK: %[[CALL1:.*]] = call i32 @callee(i32* %a, i32 %v, i32 %p) 9; CHECK-LABEL: TBB: 10; CHECK: br i1 %cmp, label %TBB.split 11; CHECK-LABEL: TBB.split: 12; CHECK: %[[CALL2:.*]] = call i32 @callee(i32* null, i32 %v, i32 %p) 13; CHECK-LABEL: Tail 14; CHECK: %[[MERGED:.*]] = phi i32 [ %[[CALL1]], %Header.split ], [ %[[CALL2]], %TBB.split ] 15; CHECK: ret i32 %[[MERGED]] 16define i32 @test_simple(i32* %a, i32 %v, i32 %p) { 17Header: 18 br i1 undef, label %Tail, label %End 19 20TBB: 21 %cmp = icmp eq i32* %a, null 22 br i1 %cmp, label %Tail, label %End 23 24Tail: 25 %r = call i32 @callee(i32* %a, i32 %v, i32 %p) 26 ret i32 %r 27 28End: 29 ret i32 %v 30} 31 32; CHECK-LABEL: @test_eq_eq_eq_untaken 33; CHECK-LABEL: Header: 34; CHECK: br i1 %tobool1, label %TBB1, label %Header.split 35; CHECK-LABEL: Header.split: 36; CHECK: %[[CALL1:.*]] = call i32 @callee(i32* nonnull %a, i32 %v, i32 %p) 37; CHECK-LABEL: TBB2: 38; CHECK: br i1 %cmp2, label %TBB2.split, label %End 39; CHECK-LABEL: TBB2.split: 40; CHECK: %[[CALL2:.*]] = call i32 @callee(i32* null, i32 1, i32 99) 41; CHECK-LABEL: Tail 42; CHECK: %[[MERGED:.*]] = phi i32 [ %[[CALL1]], %Header.split ], [ %[[CALL2]], %TBB2.split ] 43; CHECK: ret i32 %[[MERGED]] 44define i32 @test_eq_eq_eq_untaken2(i32* %a, i32 %v, i32 %p) { 45Header: 46 %tobool1 = icmp eq i32* %a, null 47 br i1 %tobool1, label %TBB1, label %Tail 48 49TBB1: 50 %cmp1 = icmp eq i32 %v, 1 51 br i1 %cmp1, label %TBB2, label %End 52 53TBB2: 54 %cmp2 = icmp eq i32 %p, 99 55 br i1 %cmp2, label %Tail, label %End 56 57Tail: 58 %r = call i32 @callee(i32* %a, i32 %v, i32 %p) 59 ret i32 %r 60 61End: 62 ret i32 %v 63} 64 65; CHECK-LABEL: @test_eq_ne_eq_untaken 66; CHECK-LABEL: Header: 67; CHECK: br i1 %tobool1, label %TBB1, label %Header.split 68; CHECK-LABEL: Header.split: 69; CHECK: %[[CALL1:.*]] = call i32 @callee(i32* nonnull %a, i32 %v, i32 %p) 70; CHECK-LABEL: TBB2: 71; CHECK: br i1 %cmp2, label %TBB2.split, label %End 72; CHECK-LABEL: TBB2.split: 73; CHECK: %[[CALL2:.*]] = call i32 @callee(i32* null, i32 %v, i32 99) 74; CHECK-LABEL: Tail 75; CHECK: %[[MERGED:.*]] = phi i32 [ %[[CALL1]], %Header.split ], [ %[[CALL2]], %TBB2.split ] 76; CHECK: ret i32 %[[MERGED]] 77define i32 @test_eq_ne_eq_untaken(i32* %a, i32 %v, i32 %p) { 78Header: 79 %tobool1 = icmp eq i32* %a, null 80 br i1 %tobool1, label %TBB1, label %Tail 81 82TBB1: 83 %cmp1 = icmp ne i32 %v, 1 84 br i1 %cmp1, label %TBB2, label %End 85 86TBB2: 87 %cmp2 = icmp eq i32 %p, 99 88 br i1 %cmp2, label %Tail, label %End 89 90Tail: 91 %r = call i32 @callee(i32* %a, i32 %v, i32 %p) 92 ret i32 %r 93 94End: 95 ret i32 %v 96} 97 98; CHECK-LABEL: @test_header_header2_tbb 99; CHECK: Header2: 100; CHECK:br i1 %tobool2, label %Header2.split, label %TBB1 101; CHECK-LABEL: Header2.split: 102; CHECK: %[[CALL1:.*]] = call i32 @callee(i32* nonnull %a, i32 %v, i32 10) 103; CHECK-LABEL: TBB2: 104; CHECK: br i1 %cmp2, label %TBB2.split, label %End 105; CHECK-LABEL: TBB2.split: 106; NOTE: CallSiteSplitting cannot infer that %a is null here, as it currently 107; only supports recording conditions along a single predecessor path. 108; CHECK: %[[CALL2:.*]] = call i32 @callee(i32* %a, i32 1, i32 99) 109; CHECK-LABEL: Tail 110; CHECK: %[[MERGED:.*]] = phi i32 [ %[[CALL1]], %Header2.split ], [ %[[CALL2]], %TBB2.split ] 111; CHECK: ret i32 %[[MERGED]] 112define i32 @test_header_header2_tbb(i32* %a, i32 %v, i32 %p) { 113Header: 114 %tobool1 = icmp eq i32* %a, null 115 br i1 %tobool1, label %TBB1, label %Header2 116 117Header2: 118 %tobool2 = icmp eq i32 %p, 10 119 br i1 %tobool2, label %Tail, label %TBB1 120 121TBB1: 122 %cmp1 = icmp eq i32 %v, 1 123 br i1 %cmp1, label %TBB2, label %End 124 125TBB2: 126 %cmp2 = icmp eq i32 %p, 99 127 br i1 %cmp2, label %Tail, label %End 128 129Tail: 130 %r = call i32 @callee(i32* %a, i32 %v, i32 %p) 131 ret i32 %r 132 133End: 134 ret i32 %v 135} 136 137define i32 @callee(i32* %a, i32 %v, i32 %p) { 138 ret i32 10 139} 140