xref: /llvm-project/llvm/test/Transforms/HotColdSplit/split-static-profile.ll (revision f061b131757bf710e21683f122a46c6cb83198c1)
1; Check that the unlikely branch is outlined. Override internal branch thresholds with -hotcoldsplit-cold-probability-denom
2
3; RUN: opt -S -passes=hotcoldsplit < %s | FileCheck %s --check-prefixes=CHECK-OUTLINE,CHECK-NOOUTLINE-BAZ
4; RUN: opt -S -passes=hotcoldsplit -hotcoldsplit-cold-probability-denom=50 < %s | FileCheck --check-prefixes=CHECK-OUTLINE,CHECK-PROB %s
5
6; int cold(const char*);
7; int hot(const char*);
8; void foo(int a, int b) {
9;   if (a == b) [[unlikely]] { // Should be outlined.
10;     cold("same");
11;     cold("same");
12;   } else {
13;     hot("different");
14;   }
15; }
16
17; void bar(int a, int b) {
18;   if (a == b) [[likely]] {
19;     hot("same");
20;   } else { // Should be outlined.
21;     cold("different");
22;     cold("different");
23;   }
24; }
25
26; void baz(int a, int b) {
27;   if (a == b) [[likely]] {
28;     hot("same");
29;   } else { // Should be outlined.
30;     cold("different");
31;     cold("different");
32;   }
33; }
34
35; All the outlined cold functions are emitted after the hot functions.
36; CHECK-OUTLINE: @foo
37; CHECK-OUTLINE: @bar
38; CHECK-OUTLINE: @baz
39
40; CHECK-OUTLINE: internal void @foo.cold.1() #[[ATTR0:[0-9]+]]
41; CHECK-OUTLINE-NEXT: newFuncRoot
42; CHECK-OUTLINE: tail call noundef i32 @cold
43; CHECK-OUTLINE: tail call noundef i32 @cold
44
45; CHECK-OUTLINE: internal void @bar.cold.1() #[[ATTR0:[0-9]+]]
46; CHECK-OUTLINE-NEXT: newFuncRoot
47; CHECK-OUTLINE: tail call noundef i32 @cold
48; CHECK-OUTLINE: tail call noundef i32 @cold
49
50; CHECK-NOOUTLINE-BAZ-NOT: internal void @baz.cold.1()
51
52; CHECK-PROB: internal void @baz.cold.1() #[[ATTR0:[0-9]+]]
53; CHECK-PROB-NEXT: newFuncRoot
54; CHECK-PROB: tail call noundef i32 @cold
55; CHECK-PROB: tail call noundef i32 @cold
56; CHECK-OUTLINE: attributes #[[ATTR0]] = { cold minsize }
57
58source_filename = "/app/example.cpp"
59target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
60target triple = "x86_64-unknown-linux-gnu"
61
62@.str = private unnamed_addr constant [5 x i8] c"same\00", align 1
63@.str.1 = private unnamed_addr constant [10 x i8] c"different\00", align 1
64
65define dso_local void @foo(i32 noundef %a, i32 noundef %b) local_unnamed_addr {
66entry:
67  %cmp = icmp eq i32 %a, %b
68  br i1 %cmp, label %if.then, label %if.else, !prof !1
69
70if.then:
71  %call = tail call noundef i32 @cold(ptr noundef nonnull @.str)
72  %call1 = tail call noundef i32 @cold(ptr noundef nonnull @.str)
73  br label %if.end
74
75if.else:
76  %call2 = tail call noundef i32 @hot(ptr noundef nonnull @.str.1)
77  br label %if.end
78
79if.end:
80  ret void
81}
82
83declare noundef i32 @cold(ptr noundef) local_unnamed_addr #1
84
85declare noundef i32 @hot(ptr noundef) local_unnamed_addr #1
86
87define dso_local void @bar(i32 noundef %a, i32 noundef %b) local_unnamed_addr {
88entry:
89  %cmp = icmp eq i32 %a, %b
90  br i1 %cmp, label %if.then, label %if.else, !prof !2
91
92if.then:
93  %call = tail call noundef i32 @hot(ptr noundef nonnull @.str)
94  br label %if.end
95
96if.else:
97  %call1 = tail call noundef i32 @cold(ptr noundef nonnull @.str.1)
98  %call2 = tail call noundef i32 @cold(ptr noundef nonnull @.str.1)
99  br label %if.end
100
101if.end:
102  ret void
103}
104
105define dso_local void @baz(i32 noundef %a, i32 noundef %b) local_unnamed_addr {
106entry:
107  %cmp = icmp eq i32 %a, %b
108  br i1 %cmp, label %if.then, label %if.else, !prof !3
109
110if.then:
111  %call = tail call noundef i32 @hot(ptr noundef nonnull @.str)
112  br label %if.end
113
114if.else:
115  %call1 = tail call noundef i32 @cold(ptr noundef nonnull @.str.1)
116  %call2 = tail call noundef i32 @cold(ptr noundef nonnull @.str.1)
117  br label %if.end
118
119if.end:
120  ret void
121}
122
123!1 = !{!"branch_weights", i32 1, i32 2000}
124!2 = !{!"branch_weights", i32 2000, i32 1}
125!3 = !{!"branch_weights", i32 50, i32 1}
126