1b49ee01fSZhi Zhuang; RUN: opt -S -passes='function(lower-expect),strip-dead-prototypes' -likely-branch-weight=2147483647 -unlikely-branch-weight=1 < %s | FileCheck %s 2b49ee01fSZhi Zhuang 3b49ee01fSZhi Zhuang; The C case 4b49ee01fSZhi Zhuang; if (__builtin_expect_with_probability(((a0 == 1) || (a1 == 1) || (a2 == 1)), 1, 0)) 5b49ee01fSZhi Zhuang; For the above case, all 3 branches should be annotated 6b49ee01fSZhi Zhuang; which should be equivalent to if (__builtin_expect(((a0 == 1) || (a1 == 1) || (a2 == 1)), 0)) 7b49ee01fSZhi Zhuang 8b49ee01fSZhi Zhuang; The C case 9b49ee01fSZhi Zhuang; if (__builtin_expect_with_probability(((a0 == 1) || (a1 == 1) || (a2 == 1)), 1, 1)) 10b49ee01fSZhi Zhuang; For the above case, we do not have enough information, so only the last branch could be annotated 11b49ee01fSZhi Zhuang; which should be equivalent to if (__builtin_expect(((a0 == 1) || (a1 == 1) || (a2 == 1)), 1)) 12b49ee01fSZhi Zhuang 13b49ee01fSZhi Zhuangdeclare void @foo() 14b49ee01fSZhi Zhuang 15b49ee01fSZhi Zhuangdeclare i64 @llvm.expect.i64(i64, i64) nounwind readnone 16b49ee01fSZhi Zhuangdeclare i64 @llvm.expect.with.probability.i64(i64, i64, double) nounwind readnone 17b49ee01fSZhi Zhuang 18b49ee01fSZhi Zhuang; CHECK-LABEL: @test1_expect_1( 19b49ee01fSZhi Zhuang; CHECK: block0: 20b49ee01fSZhi Zhuang; CHECK-NOT: prof 21b49ee01fSZhi Zhuang; CHECK: block1: 22b49ee01fSZhi Zhuang; CHECK-NOT: prof 23b49ee01fSZhi Zhuang; CHECK: block3: 24b49ee01fSZhi Zhuang; CHECK: br i1 %tobool, label %block4, label %block5, !prof !0 25b49ee01fSZhi Zhuangdefine void @test1_expect_1(i8 %a0, i8 %a1, i8 %a2) { 26b49ee01fSZhi Zhuangblock0: 27b49ee01fSZhi Zhuang %c0 = icmp eq i8 %a0, 1 28b49ee01fSZhi Zhuang br i1 %c0, label %block3, label %block1 29b49ee01fSZhi Zhuang 30b49ee01fSZhi Zhuangblock1: 31b49ee01fSZhi Zhuang %c1 = icmp eq i8 %a1, 1 32b49ee01fSZhi Zhuang br i1 %c1, label %block3, label %block2 33b49ee01fSZhi Zhuang 34b49ee01fSZhi Zhuangblock2: 35b49ee01fSZhi Zhuang %c2 = icmp eq i8 %a2, 1 36b49ee01fSZhi Zhuang br label %block3 37b49ee01fSZhi Zhuang 38b49ee01fSZhi Zhuangblock3: 39b49ee01fSZhi Zhuang %cond0 = phi i1 [ true, %block0 ], [ true, %block1 ], [ %c2, %block2 ] 40b49ee01fSZhi Zhuang %cond1 = zext i1 %cond0 to i32 41b49ee01fSZhi Zhuang %cond2 = sext i32 %cond1 to i64 42b49ee01fSZhi Zhuang %expval = call i64 @llvm.expect.i64(i64 %cond2, i64 1) 43b49ee01fSZhi Zhuang %tobool = icmp ne i64 %expval, 0 44b49ee01fSZhi Zhuang br i1 %tobool, label %block4, label %block5 45b49ee01fSZhi Zhuang 46b49ee01fSZhi Zhuangblock4: 47b49ee01fSZhi Zhuang call void @foo() 48b49ee01fSZhi Zhuang br label %block5 49b49ee01fSZhi Zhuang 50b49ee01fSZhi Zhuangblock5: 51b49ee01fSZhi Zhuang ret void 52b49ee01fSZhi Zhuang} 53b49ee01fSZhi Zhuang 54b49ee01fSZhi Zhuang; should have exactly the same behavior as test1 55b49ee01fSZhi Zhuang; CHECK-LABEL: @test2_expect_with_prob_1_1( 56b49ee01fSZhi Zhuang; CHECK: block0: 57b49ee01fSZhi Zhuang; CHECK-NOT: prof 58b49ee01fSZhi Zhuang; CHECK: block1: 59b49ee01fSZhi Zhuang; CHECK-NOT: prof 60b49ee01fSZhi Zhuang; CHECK: block3: 61b49ee01fSZhi Zhuang; CHECK: br i1 %tobool, label %block4, label %block5, !prof !0 62b49ee01fSZhi Zhuangdefine void @test2_expect_with_prob_1_1(i8 %a0, i8 %a1, i8 %a2) { 63b49ee01fSZhi Zhuangblock0: 64b49ee01fSZhi Zhuang %c0 = icmp eq i8 %a0, 1 65b49ee01fSZhi Zhuang br i1 %c0, label %block3, label %block1 66b49ee01fSZhi Zhuang 67b49ee01fSZhi Zhuangblock1: 68b49ee01fSZhi Zhuang %c1 = icmp eq i8 %a1, 1 69b49ee01fSZhi Zhuang br i1 %c1, label %block3, label %block2 70b49ee01fSZhi Zhuang 71b49ee01fSZhi Zhuangblock2: 72b49ee01fSZhi Zhuang %c2 = icmp eq i8 %a2, 1 73b49ee01fSZhi Zhuang br label %block3 74b49ee01fSZhi Zhuang 75b49ee01fSZhi Zhuangblock3: 76b49ee01fSZhi Zhuang %cond0 = phi i1 [ true, %block0 ], [ true, %block1 ], [ %c2, %block2 ] 77b49ee01fSZhi Zhuang %cond1 = zext i1 %cond0 to i32 78b49ee01fSZhi Zhuang %cond2 = sext i32 %cond1 to i64 79b49ee01fSZhi Zhuang %expval = call i64 @llvm.expect.with.probability.i64(i64 %cond2, i64 1, double 1.0) 80b49ee01fSZhi Zhuang %tobool = icmp ne i64 %expval, 0 81b49ee01fSZhi Zhuang br i1 %tobool, label %block4, label %block5 82b49ee01fSZhi Zhuang 83b49ee01fSZhi Zhuangblock4: 84b49ee01fSZhi Zhuang call void @foo() 85b49ee01fSZhi Zhuang br label %block5 86b49ee01fSZhi Zhuang 87b49ee01fSZhi Zhuangblock5: 88b49ee01fSZhi Zhuang ret void 89b49ee01fSZhi Zhuang} 90b49ee01fSZhi Zhuang 91b49ee01fSZhi Zhuang; should have exactly the same behavior as test1 92b49ee01fSZhi Zhuang; CHECK-LABEL: @test3_expect_with_prob_0_0( 93b49ee01fSZhi Zhuang; CHECK: block0: 94b49ee01fSZhi Zhuang; CHECK-NOT: prof 95b49ee01fSZhi Zhuang; CHECK: block1: 96b49ee01fSZhi Zhuang; CHECK-NOT: prof 97b49ee01fSZhi Zhuang; CHECK: block3: 98b49ee01fSZhi Zhuang; CHECK: br i1 %tobool, label %block4, label %block5, !prof !0 99b49ee01fSZhi Zhuangdefine void @test3_expect_with_prob_0_0(i8 %a0, i8 %a1, i8 %a2) { 100b49ee01fSZhi Zhuangblock0: 101b49ee01fSZhi Zhuang %c0 = icmp eq i8 %a0, 1 102b49ee01fSZhi Zhuang br i1 %c0, label %block3, label %block1 103b49ee01fSZhi Zhuang 104b49ee01fSZhi Zhuangblock1: 105b49ee01fSZhi Zhuang %c1 = icmp eq i8 %a1, 1 106b49ee01fSZhi Zhuang br i1 %c1, label %block3, label %block2 107b49ee01fSZhi Zhuang 108b49ee01fSZhi Zhuangblock2: 109b49ee01fSZhi Zhuang %c2 = icmp eq i8 %a2, 1 110b49ee01fSZhi Zhuang br label %block3 111b49ee01fSZhi Zhuang 112b49ee01fSZhi Zhuangblock3: 113b49ee01fSZhi Zhuang %cond0 = phi i1 [ true, %block0 ], [ true, %block1 ], [ %c2, %block2 ] 114b49ee01fSZhi Zhuang %cond1 = zext i1 %cond0 to i32 115b49ee01fSZhi Zhuang %cond2 = sext i32 %cond1 to i64 116b49ee01fSZhi Zhuang %expval = call i64 @llvm.expect.with.probability.i64(i64 %cond2, i64 0, double 0.0) 117b49ee01fSZhi Zhuang %tobool = icmp ne i64 %expval, 0 118b49ee01fSZhi Zhuang br i1 %tobool, label %block4, label %block5 119b49ee01fSZhi Zhuang 120b49ee01fSZhi Zhuangblock4: 121b49ee01fSZhi Zhuang call void @foo() 122b49ee01fSZhi Zhuang br label %block5 123b49ee01fSZhi Zhuang 124b49ee01fSZhi Zhuangblock5: 125b49ee01fSZhi Zhuang ret void 126b49ee01fSZhi Zhuang} 127b49ee01fSZhi Zhuang 128b49ee01fSZhi Zhuang; CHECK-LABEL: @test4_expect_0( 129b49ee01fSZhi Zhuang; CHECK: block0: 130b49ee01fSZhi Zhuang; CHECK: br i1 %c0, label %block3, label %block1, !prof !1 131b49ee01fSZhi Zhuang; CHECK: block1: 132b49ee01fSZhi Zhuang; CHECK: br i1 %c1, label %block3, label %block2, !prof !1 133b49ee01fSZhi Zhuang; CHECK: block3: 134b49ee01fSZhi Zhuang; CHECK: br i1 %tobool, label %block4, label %block5, !prof !1 135b49ee01fSZhi Zhuangdefine void @test4_expect_0(i8 %a0, i8 %a1, i8 %a2) { 136b49ee01fSZhi Zhuangblock0: 137b49ee01fSZhi Zhuang %c0 = icmp eq i8 %a0, 1 138b49ee01fSZhi Zhuang br i1 %c0, label %block3, label %block1 139b49ee01fSZhi Zhuang 140b49ee01fSZhi Zhuangblock1: 141b49ee01fSZhi Zhuang %c1 = icmp eq i8 %a1, 1 142b49ee01fSZhi Zhuang br i1 %c1, label %block3, label %block2 143b49ee01fSZhi Zhuang 144b49ee01fSZhi Zhuangblock2: 145b49ee01fSZhi Zhuang %c2 = icmp eq i8 %a2, 1 146b49ee01fSZhi Zhuang br label %block3 147b49ee01fSZhi Zhuang 148b49ee01fSZhi Zhuangblock3: 149b49ee01fSZhi Zhuang %cond0 = phi i1 [ true, %block0 ], [ true, %block1 ], [ %c2, %block2 ] 150b49ee01fSZhi Zhuang %cond1 = zext i1 %cond0 to i32 151b49ee01fSZhi Zhuang %cond2 = sext i32 %cond1 to i64 152b49ee01fSZhi Zhuang %expval = call i64 @llvm.expect.i64(i64 %cond2, i64 0) 153b49ee01fSZhi Zhuang %tobool = icmp ne i64 %expval, 0 154b49ee01fSZhi Zhuang br i1 %tobool, label %block4, label %block5 155b49ee01fSZhi Zhuang 156b49ee01fSZhi Zhuangblock4: 157b49ee01fSZhi Zhuang call void @foo() 158b49ee01fSZhi Zhuang br label %block5 159b49ee01fSZhi Zhuang 160b49ee01fSZhi Zhuangblock5: 161b49ee01fSZhi Zhuang ret void 162b49ee01fSZhi Zhuang} 163b49ee01fSZhi Zhuang 164b49ee01fSZhi Zhuang; should have exactly the same behavior as test4 165b49ee01fSZhi Zhuang; CHECK-LABEL: @test5_expect_with_prob_1_0( 166b49ee01fSZhi Zhuang; CHECK: block0: 167b49ee01fSZhi Zhuang; CHECK: br i1 %c0, label %block3, label %block1, !prof !1 168b49ee01fSZhi Zhuang; CHECK: block1: 169b49ee01fSZhi Zhuang; CHECK: br i1 %c1, label %block3, label %block2, !prof !1 170b49ee01fSZhi Zhuang; CHECK: block3: 171b49ee01fSZhi Zhuang; CHECK: br i1 %tobool, label %block4, label %block5, !prof !1 172b49ee01fSZhi Zhuangdefine void @test5_expect_with_prob_1_0(i8 %a0, i8 %a1, i8 %a2) { 173b49ee01fSZhi Zhuangblock0: 174b49ee01fSZhi Zhuang %c0 = icmp eq i8 %a0, 1 175b49ee01fSZhi Zhuang br i1 %c0, label %block3, label %block1 176b49ee01fSZhi Zhuang 177b49ee01fSZhi Zhuangblock1: 178b49ee01fSZhi Zhuang %c1 = icmp eq i8 %a1, 1 179b49ee01fSZhi Zhuang br i1 %c1, label %block3, label %block2 180b49ee01fSZhi Zhuang 181b49ee01fSZhi Zhuangblock2: 182b49ee01fSZhi Zhuang %c2 = icmp eq i8 %a2, 1 183b49ee01fSZhi Zhuang br label %block3 184b49ee01fSZhi Zhuang 185b49ee01fSZhi Zhuangblock3: 186b49ee01fSZhi Zhuang %cond0 = phi i1 [ true, %block0 ], [ true, %block1 ], [ %c2, %block2 ] 187b49ee01fSZhi Zhuang %cond1 = zext i1 %cond0 to i32 188b49ee01fSZhi Zhuang %cond2 = sext i32 %cond1 to i64 189b49ee01fSZhi Zhuang %expval = call i64 @llvm.expect.with.probability.i64(i64 %cond2, i64 1, double 0.0) 190b49ee01fSZhi Zhuang %tobool = icmp ne i64 %expval, 0 191b49ee01fSZhi Zhuang br i1 %tobool, label %block4, label %block5 192b49ee01fSZhi Zhuang 193b49ee01fSZhi Zhuangblock4: 194b49ee01fSZhi Zhuang call void @foo() 195b49ee01fSZhi Zhuang br label %block5 196b49ee01fSZhi Zhuang 197b49ee01fSZhi Zhuangblock5: 198b49ee01fSZhi Zhuang ret void 199b49ee01fSZhi Zhuang} 200b49ee01fSZhi Zhuang 201b49ee01fSZhi Zhuang; should have exactly the same behavior as test4 202b49ee01fSZhi Zhuang; CHECK-LABEL: @test6_expect_with_prob_0_1( 203b49ee01fSZhi Zhuang; CHECK: block0: 204b49ee01fSZhi Zhuang; CHECK: br i1 %c0, label %block3, label %block1, !prof !1 205b49ee01fSZhi Zhuang; CHECK: block1: 206b49ee01fSZhi Zhuang; CHECK: br i1 %c1, label %block3, label %block2, !prof !1 207b49ee01fSZhi Zhuang; CHECK: block3: 208b49ee01fSZhi Zhuang; CHECK: br i1 %tobool, label %block4, label %block5, !prof !1 209b49ee01fSZhi Zhuangdefine void @test6_expect_with_prob_0_1(i8 %a0, i8 %a1, i8 %a2) { 210b49ee01fSZhi Zhuangblock0: 211b49ee01fSZhi Zhuang %c0 = icmp eq i8 %a0, 1 212b49ee01fSZhi Zhuang br i1 %c0, label %block3, label %block1 213b49ee01fSZhi Zhuang 214b49ee01fSZhi Zhuangblock1: 215b49ee01fSZhi Zhuang %c1 = icmp eq i8 %a1, 1 216b49ee01fSZhi Zhuang br i1 %c1, label %block3, label %block2 217b49ee01fSZhi Zhuang 218b49ee01fSZhi Zhuangblock2: 219b49ee01fSZhi Zhuang %c2 = icmp eq i8 %a2, 1 220b49ee01fSZhi Zhuang br label %block3 221b49ee01fSZhi Zhuang 222b49ee01fSZhi Zhuangblock3: 223b49ee01fSZhi Zhuang %cond0 = phi i1 [ true, %block0 ], [ true, %block1 ], [ %c2, %block2 ] 224b49ee01fSZhi Zhuang %cond1 = zext i1 %cond0 to i32 225b49ee01fSZhi Zhuang %cond2 = sext i32 %cond1 to i64 226b49ee01fSZhi Zhuang %expval = call i64 @llvm.expect.with.probability.i64(i64 %cond2, i64 0, double 1.0) 227b49ee01fSZhi Zhuang %tobool = icmp ne i64 %expval, 0 228b49ee01fSZhi Zhuang br i1 %tobool, label %block4, label %block5 229b49ee01fSZhi Zhuang 230b49ee01fSZhi Zhuangblock4: 231b49ee01fSZhi Zhuang call void @foo() 232b49ee01fSZhi Zhuang br label %block5 233b49ee01fSZhi Zhuang 234b49ee01fSZhi Zhuangblock5: 235b49ee01fSZhi Zhuang ret void 236b49ee01fSZhi Zhuang} 237b49ee01fSZhi Zhuang 238*294f3ce5SPaul Kirth; CHECK: !0 = !{!"branch_weights", !"expected", i32 2147483647, i32 1} 239*294f3ce5SPaul Kirth; CHECK: !1 = !{!"branch_weights", !"expected", i32 1, i32 2147483647} 240