1 | // RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s -O1 -disable-llvm-passes | FileCheck %s --check-prefix=ALL --check-prefix=O1 |
2 | // RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s -O0 | FileCheck %s --check-prefix=ALL --check-prefix=O0 |
3 | |
4 | // In all tests, make sure that no expect is generated if optimizations are off. |
5 | // If optimizations are on, generate the correct expect and preserve other necessary operations. |
6 | |
7 | int expect_taken(int x) { |
8 | // ALL-LABEL: define i32 @expect_taken |
9 | // O1: call i64 @llvm.expect.i64(i64 {{%.*}}, i64 1) |
10 | // O0-NOT: @llvm.expect |
11 | |
12 | if (__builtin_expect (x, 1)) |
13 | return 0; |
14 | return x; |
15 | } |
16 | |
17 | |
18 | int expect_not_taken(int x) { |
19 | // ALL-LABEL: define i32 @expect_not_taken |
20 | // O1: call i64 @llvm.expect.i64(i64 {{%.*}}, i64 0) |
21 | // O0-NOT: @llvm.expect |
22 | |
23 | if (__builtin_expect (x, 0)) |
24 | return 0; |
25 | return x; |
26 | } |
27 | |
28 | |
29 | int x; |
30 | int y(void); |
31 | void foo(); |
32 | |
33 | void expect_value_side_effects() { |
34 | // ALL-LABEL: define void @expect_value_side_effects() |
35 | // ALL: [[CALL:%.*]] = call i32 @y |
36 | // O1: [[SEXT:%.*]] = sext i32 [[CALL]] to i64 |
37 | // O1: call i64 @llvm.expect.i64(i64 {{%.*}}, i64 [[SEXT]]) |
38 | // O0-NOT: @llvm.expect |
39 | |
40 | if (__builtin_expect (x, y())) |
41 | foo (); |
42 | } |
43 | |
44 | |
45 | // Make sure that issigprocmask() is called before bar()? |
46 | // There's no compare, so there's nothing to expect? |
47 | // rdar://9330105 |
48 | void isigprocmask(void); |
49 | long bar(); |
50 | |
51 | int main() { |
52 | // ALL-LABEL: define i32 @main() |
53 | // ALL: call void @isigprocmask() |
54 | // ALL: [[CALL:%.*]] = call i64 (...) @bar() |
55 | // O1: call i64 @llvm.expect.i64(i64 0, i64 [[CALL]]) |
56 | // O0-NOT: @llvm.expect |
57 | |
58 | (void) __builtin_expect((isigprocmask(), 0), bar()); |
59 | } |
60 | |
61 | |
62 | int switch_cond(int x) { |
63 | // ALL-LABEL: define i32 @switch_cond |
64 | // O1: call i64 @llvm.expect.i64(i64 {{%.*}}, i64 5) |
65 | // O0-NOT: @llvm.expect |
66 | |
67 | switch(__builtin_expect(x, 5)) { |
68 | default: |
69 | return 0; |
70 | case 0: |
71 | case 1: |
72 | case 2: |
73 | return 1; |
74 | case 5: |
75 | return 5; |
76 | }; |
77 | |
78 | return 0; |
79 | } |
80 | |
81 | int variable_expected(int stuff) { |
82 | // ALL-LABEL: define i32 @variable_expected( |
83 | // O1: call i64 @llvm.expect.i64(i64 {{%.*}}, i64 {{%.*}}) |
84 | // O0-NOT: @llvm.expect |
85 | |
86 | int res = 0; |
87 | |
88 | switch (__builtin_expect(stuff, stuff)) { |
89 | case 0: |
90 | res = 1; |
91 | break; |
92 | default: |
93 | break; |
94 | } |
95 | |
96 | return res; |
97 | } |
98 | |