1; RUN: opt < %s -callsite-splitting -S | FileCheck %s 2; RUN: opt < %s -passes='function(callsite-splitting)' -S | FileCheck %s 3 4target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128" 5target triple = "aarch64-linaro-linux-gnueabi" 6 7;CHECK-LABEL: @test_eq_eq 8;CHECK-LABEL: Tail.predBB1.split: 9;CHECK: %[[CALL1:.*]] = call i32 @callee(i32* null, i32 %v, i32 1) 10;CHECK-LABEL: Tail.predBB2.split: 11;CHECK: %[[CALL2:.*]] = call i32 @callee(i32* nonnull %a, i32 1, i32 2) 12;CHECK-LABEL: Tail 13;CHECK: %p = phi i32 [ 1, %Tail.predBB1.split ], [ 2, %Tail.predBB2.split ] 14;CHECK: %[[MERGED:.*]] = phi i32 [ %[[CALL1]], %Tail.predBB1.split ], [ %[[CALL2]], %Tail.predBB2.split ] 15;CHECK: ret i32 %[[MERGED]] 16define i32 @test_eq_eq(i32* %a, i32 %v) { 17Header: 18 %tobool1 = icmp eq i32* %a, null 19 br i1 %tobool1, label %Tail, label %TBB 20 21TBB: 22 %cmp = icmp eq i32 %v, 1 23 br i1 %cmp, label %Tail, label %End 24 25Tail: 26 %p = phi i32[1,%Header], [2, %TBB] 27 %r = call i32 @callee(i32* %a, i32 %v, i32 %p) 28 ret i32 %r 29 30End: 31 ret i32 %v 32} 33 34;CHECK-LABEL: @test_ne_eq 35;CHECK-LABEL: Tail.predBB1.split: 36;CHECK: %[[CALL1:.*]] = call i32 @callee(i32* nonnull %a, i32 %v, i32 1) 37;CHECK-LABEL: Tail.predBB2.split: 38;CHECK: %[[CALL2:.*]] = call i32 @callee(i32* null, i32 1, i32 2) 39;CHECK-LABEL: Tail 40;CHECK: %p = phi i32 [ 1, %Tail.predBB1.split ], [ 2, %Tail.predBB2.split ] 41;CHECK: %[[MERGED:.*]] = phi i32 [ %[[CALL1]], %Tail.predBB1.split ], [ %[[CALL2]], %Tail.predBB2.split ] 42;CHECK: ret i32 %[[MERGED]] 43define i32 @test_ne_eq(i32* %a, i32 %v) { 44Header: 45 %tobool1 = icmp ne i32* %a, null 46 br i1 %tobool1, label %Tail, label %TBB 47 48TBB: 49 %cmp = icmp eq i32 %v, 1 50 br i1 %cmp, label %Tail, label %End 51 52Tail: 53 %p = phi i32[1,%Header], [2, %TBB] 54 %r = call i32 @callee(i32* %a, i32 %v, i32 %p) 55 ret i32 %r 56 57End: 58 ret i32 %v 59} 60 61;CHECK-LABEL: @test_ne_ne 62;CHECK-LABEL: Tail.predBB1.split: 63;CHECK: %[[CALL1:.*]] = call i32 @callee(i32* nonnull %a, i32 %v, i32 1) 64;CHECK-LABEL: Tail.predBB2.split: 65;CHECK: %[[CALL2:.*]] = call i32 @callee(i32* null, i32 %v, i32 2) 66;CHECK-LABEL: Tail 67;CHECK: %p = phi i32 [ 1, %Tail.predBB1.split ], [ 2, %Tail.predBB2.split ] 68;CHECK: %[[MERGED:.*]] = phi i32 [ %[[CALL1]], %Tail.predBB1.split ], [ %[[CALL2]], %Tail.predBB2.split ] 69;CHECK: ret i32 %[[MERGED]] 70define i32 @test_ne_ne(i32* %a, i32 %v) { 71Header: 72 %tobool1 = icmp ne i32* %a, null 73 br i1 %tobool1, label %Tail, label %TBB 74 75TBB: 76 %cmp = icmp ne i32 %v, 1 77 br i1 %cmp, label %Tail, label %End 78 79Tail: 80 %p = phi i32[1,%Header], [2, %TBB] 81 %r = call i32 @callee(i32* %a, i32 %v, i32 %p) 82 ret i32 %r 83 84End: 85 ret i32 %v 86} 87 88;CHECK-LABEL: @test_eq_eq_untaken 89;CHECK-LABEL: Tail.predBB1.split: 90;CHECK: %[[CALL1:.*]] = call i32 @callee(i32* nonnull %a, i32 %v, i32 1) 91;CHECK-LABEL: Tail.predBB2.split: 92;CHECK: %[[CALL2:.*]] = call i32 @callee(i32* null, i32 1, i32 2) 93;CHECK-LABEL: Tail 94;CHECK: %p = phi i32 [ 1, %Tail.predBB1.split ], [ 2, %Tail.predBB2.split ] 95;CHECK: %[[MERGED:.*]] = phi i32 [ %[[CALL1]], %Tail.predBB1.split ], [ %[[CALL2]], %Tail.predBB2.split ] 96;CHECK: ret i32 %[[MERGED]] 97define i32 @test_eq_eq_untaken(i32* %a, i32 %v) { 98Header: 99 %tobool1 = icmp eq i32* %a, null 100 br i1 %tobool1, label %TBB, label %Tail 101 102TBB: 103 %cmp = icmp eq i32 %v, 1 104 br i1 %cmp, label %Tail, label %End 105 106Tail: 107 %p = phi i32[1,%Header], [2, %TBB] 108 %r = call i32 @callee(i32* %a, i32 %v, i32 %p) 109 ret i32 %r 110 111End: 112 ret i32 %v 113} 114 115;CHECK-LABEL: @test_ne_eq_untaken 116;CHECK-LABEL: Tail.predBB1.split: 117;CHECK: %[[CALL1:.*]] = call i32 @callee(i32* null, i32 %v, i32 1) 118;CHECK-LABEL: Tail.predBB2.split: 119;CHECK: %[[CALL2:.*]] = call i32 @callee(i32* nonnull %a, i32 1, i32 2) 120;CHECK-LABEL: Tail 121;CHECK: %p = phi i32 [ 1, %Tail.predBB1.split ], [ 2, %Tail.predBB2.split ] 122;CHECK: %[[MERGED:.*]] = phi i32 [ %[[CALL1]], %Tail.predBB1.split ], [ %[[CALL2]], %Tail.predBB2.split ] 123;CHECK: ret i32 %[[MERGED]] 124define i32 @test_ne_eq_untaken(i32* %a, i32 %v) { 125Header: 126 %tobool1 = icmp ne i32* %a, null 127 br i1 %tobool1, label %TBB, label %Tail 128 129TBB: 130 %cmp = icmp eq i32 %v, 1 131 br i1 %cmp, label %Tail, label %End 132 133Tail: 134 %p = phi i32[1,%Header], [2, %TBB] 135 %r = call i32 @callee(i32* %a, i32 %v, i32 %p) 136 ret i32 %r 137 138End: 139 ret i32 %v 140} 141 142;CHECK-LABEL: @test_ne_ne_untaken 143;CHECK-LABEL: Tail.predBB1.split: 144;CHECK: %[[CALL1:.*]] = call i32 @callee(i32* null, i32 %v, i32 1) 145;CHECK-LABEL: Tail.predBB2.split: 146;CHECK: %[[CALL2:.*]] = call i32 @callee(i32* nonnull %a, i32 1, i32 2) 147;CHECK-LABEL: Tail 148;CHECK: %p = phi i32 [ 1, %Tail.predBB1.split ], [ 2, %Tail.predBB2.split ] 149;CHECK: %[[MERGED:.*]] = phi i32 [ %[[CALL1]], %Tail.predBB1.split ], [ %[[CALL2]], %Tail.predBB2.split ] 150;CHECK: ret i32 %[[MERGED]] 151define i32 @test_ne_ne_untaken(i32* %a, i32 %v) { 152Header: 153 %tobool1 = icmp ne i32* %a, null 154 br i1 %tobool1, label %TBB, label %Tail 155 156TBB: 157 %cmp = icmp ne i32 %v, 1 158 br i1 %cmp, label %End, label %Tail 159 160Tail: 161 %p = phi i32[1,%Header], [2, %TBB] 162 %r = call i32 @callee(i32* %a, i32 %v, i32 %p) 163 ret i32 %r 164 165End: 166 ret i32 %v 167} 168 169;CHECK-LABEL: @test_nonconst_const_phi 170;CHECK-LABEL: Tail.predBB1.split: 171;CHECK: %[[CALL1:.*]] = call i32 @callee(i32* %a, i32 %v, i32 1) 172;CHECK-LABEL: Tail.predBB2.split: 173;CHECK: %[[CALL2:.*]] = call i32 @callee(i32* %a, i32 1, i32 2) 174;CHECK-LABEL: Tail 175;CHECK: %p = phi i32 [ 1, %Tail.predBB1.split ], [ 2, %Tail.predBB2.split ] 176;CHECK: %[[MERGED:.*]] = phi i32 [ %[[CALL1]], %Tail.predBB1.split ], [ %[[CALL2]], %Tail.predBB2.split ] 177;CHECK: ret i32 %[[MERGED]] 178define i32 @test_nonconst_const_phi(i32* %a, i32* %b, i32 %v) { 179Header: 180 %tobool1 = icmp eq i32* %a, %b 181 br i1 %tobool1, label %Tail, label %TBB 182 183TBB: 184 %cmp = icmp eq i32 %v, 1 185 br i1 %cmp, label %Tail, label %End 186 187Tail: 188 %p = phi i32[1,%Header], [2, %TBB] 189 %r = call i32 @callee(i32* %a, i32 %v, i32 %p) 190 ret i32 %r 191 192End: 193 ret i32 %v 194} 195 196;CHECK-LABEL: @test_nonconst_nonconst_phi 197;CHECK-LABEL: Tail.predBB1.split: 198;CHECK: %[[CALL1:.*]] = call i32 @callee(i32* %a, i32 %v, i32 1) 199;CHECK-LABEL: Tail.predBB2.split: 200;CHECK: %[[CALL2:.*]] = call i32 @callee(i32* %a, i32 %v, i32 2) 201;CHECK-LABEL: Tail 202;CHECK: %p = phi i32 [ 1, %Tail.predBB1.split ], [ 2, %Tail.predBB2.split ] 203;CHECK: %[[MERGED:.*]] = phi i32 [ %[[CALL1]], %Tail.predBB1.split ], [ %[[CALL2]], %Tail.predBB2.split ] 204;CHECK: ret i32 %[[MERGED]] 205define i32 @test_nonconst_nonconst_phi(i32* %a, i32* %b, i32 %v, i32 %v2) { 206Header: 207 %tobool1 = icmp eq i32* %a, %b 208 br i1 %tobool1, label %Tail, label %TBB 209 210TBB: 211 %cmp = icmp eq i32 %v, %v2 212 br i1 %cmp, label %Tail, label %End 213 214Tail: 215 %p = phi i32[1,%Header], [2, %TBB] 216 %r = call i32 @callee(i32* %a, i32 %v, i32 %p) 217 ret i32 %r 218 219End: 220 ret i32 %v 221} 222 223;CHECK-LABEL: @test_nonconst_nonconst_phi_noncost 224;CHECK-NOT: Tail.predBB1.split: 225;CHECK-NOT: Tail.predBB2.split: 226;CHECK-LABEL: Tail: 227;CHECK: %r = call i32 @callee(i32* %a, i32 %v, i32 %p) 228;CHECK: ret i32 %r 229define i32 @test_nonconst_nonconst_phi_noncost(i32* %a, i32* %b, i32 %v, i32 %v2) { 230Header: 231 %tobool1 = icmp eq i32* %a, %b 232 br i1 %tobool1, label %Tail, label %TBB 233 234TBB: 235 %cmp = icmp eq i32 %v, %v2 236 br i1 %cmp, label %Tail, label %End 237 238Tail: 239 %p = phi i32[%v,%Header], [%v2, %TBB] 240 %r = call i32 @callee(i32* %a, i32 %v, i32 %p) 241 ret i32 %r 242 243End: 244 ret i32 %v 245} 246 247;CHECK-LABEL: @test_fisrtnonphi 248;CHECK-NOT: Tail.predBB1.split: 249;CHECK-NOT: Tail.predBB2.split: 250;CHECK-LABEL: Tail: 251;CHECK: %r = call i32 @callee(i32* %a, i32 %v, i32 %p) 252;CHECK: ret i32 %r 253define i32 @test_fisrtnonphi(i32* %a, i32 %v) { 254Header: 255 %tobool1 = icmp eq i32* %a, null 256 br i1 %tobool1, label %Tail, label %TBB 257 258TBB: 259 %cmp = icmp eq i32 %v, 1 260 br i1 %cmp, label %Tail, label %End 261 262Tail: 263 %p = phi i32[1,%Header], [2, %TBB] 264 store i32 %v, i32* %a 265 %r = call i32 @callee(i32* %a, i32 %v, i32 %p) 266 ret i32 %r 267 268End: 269 ret i32 %v 270} 271 272;CHECK-LABEL: @test_3preds_constphi 273;CHECK-NOT: Tail.predBB1.split: 274;CHECK-NOT: Tail.predBB2.split: 275;CHECK-LABEL: Tail: 276;CHECK: %r = call i32 @callee(i32* %a, i32 %v, i32 %p) 277;CHECK: ret i32 %r 278define i32 @test_3preds_constphi(i32* %a, i32 %v, i1 %c1, i1 %c2, i1 %c3) { 279Header: 280 br i1 %c1, label %Tail, label %TBB1 281 282TBB1: 283 br i1 %c2, label %Tail, label %TBB2 284 285TBB2: 286 br i1 %c3, label %Tail, label %End 287 288Tail: 289 %p = phi i32[1,%Header], [2, %TBB1], [3, %TBB2] 290 %r = call i32 @callee(i32* %a, i32 %v, i32 %p) 291 ret i32 %r 292 293End: 294 ret i32 %v 295} 296 297;CHECK-LABEL: @test_indirectbr_phi 298;CHECK-NOT: Tail.predBB1.split: 299;CHECK-NOT: Tail.predBB2.split: 300;CHECK-LABEL: Tail: 301;CHECK: %r = call i32 @callee(i32* %a, i32 %v, i32 %p) 302;CHECK: ret i32 %r 303define i32 @test_indirectbr_phi(i8* %address, i32* %a, i32* %b, i32 %v) { 304Header: 305 %indirect.goto.dest = select i1 undef, i8* blockaddress(@test_indirectbr_phi, %End), i8* %address 306 indirectbr i8* %indirect.goto.dest, [label %TBB, label %Tail] 307 308TBB: 309 %indirect.goto.dest2 = select i1 undef, i8* blockaddress(@test_indirectbr_phi, %End), i8* %address 310 indirectbr i8* %indirect.goto.dest2, [label %Tail, label %End] 311 312Tail: 313 %p = phi i32[1,%Header], [2, %TBB] 314 %r = call i32 @callee(i32* %a, i32 %v, i32 %p) 315 ret i32 %r 316 317End: 318 ret i32 %v 319} 320 321define i32 @callee(i32* %a, i32 %v, i32 %p) { 322entry: 323 %c = icmp ne i32* %a, null 324 br i1 %c, label %BB1, label %BB2 325 326BB1: 327 call void @dummy(i32* %a, i32 %p) 328 br label %End 329 330BB2: 331 call void @dummy2(i32 %v, i32 %p) 332 br label %End 333 334End: 335 ret i32 %p 336} 337 338declare void @dummy(i32*, i32) 339declare void @dummy2(i32, i32) 340