xref: /llvm-project/clang/test/CodeGenCXX/attr-likelihood-iteration-stmt.cpp (revision 7eca38ce76d5d1915f4ab7e665964062c0b37697)
1 // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
2 // RUN: %clang_cc1 -O1 -disable-llvm-passes -emit-llvm %s -o - -triple=x86_64-linux-gnu -verify
3 // RUN: %clang_cc1 -O1 -disable-llvm-passes -emit-llvm %s -o - -triple=x86_64-linux-gnu | FileCheck %s
4 
5 // CHECK-LABEL: @_Z2wli(
6 // CHECK-NEXT:  entry:
7 // CHECK-NEXT:    [[E_ADDR:%.*]] = alloca i32, align 4
8 // CHECK-NEXT:    store i32 [[E:%.*]], ptr [[E_ADDR]], align 4, !tbaa [[TBAA2:![0-9]+]]
9 // CHECK-NEXT:    br label [[WHILE_COND:%.*]]
10 // CHECK:       while.cond:
11 // CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[E_ADDR]], align 4, !tbaa [[TBAA2]]
12 // CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0
13 // CHECK-NEXT:    [[TOBOOL_EXPVAL:%.*]] = call i1 @llvm.expect.i1(i1 [[TOBOOL]], i1 true)
14 // CHECK-NEXT:    br i1 [[TOBOOL_EXPVAL]], label [[WHILE_BODY:%.*]], label [[WHILE_END:%.*]]
15 // CHECK:       while.body:
16 // CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[E_ADDR]], align 4, !tbaa [[TBAA2]]
17 // CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP1]], 1
18 // CHECK-NEXT:    store i32 [[INC]], ptr [[E_ADDR]], align 4, !tbaa [[TBAA2]]
19 // CHECK-NEXT:    br label [[WHILE_COND]], !llvm.loop [[LOOP6:![0-9]+]]
20 // CHECK:       while.end:
21 // CHECK-NEXT:    ret void
22 //
23 void wl(int e){
24   while(e) [[likely]] ++e;
25 }
26 
27 // CHECK-LABEL: @_Z2wui(
28 // CHECK-NEXT:  entry:
29 // CHECK-NEXT:    [[E_ADDR:%.*]] = alloca i32, align 4
30 // CHECK-NEXT:    store i32 [[E:%.*]], ptr [[E_ADDR]], align 4, !tbaa [[TBAA2]]
31 // CHECK-NEXT:    br label [[WHILE_COND:%.*]]
32 // CHECK:       while.cond:
33 // CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[E_ADDR]], align 4, !tbaa [[TBAA2]]
34 // CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0
35 // CHECK-NEXT:    [[TOBOOL_EXPVAL:%.*]] = call i1 @llvm.expect.i1(i1 [[TOBOOL]], i1 false)
36 // CHECK-NEXT:    br i1 [[TOBOOL_EXPVAL]], label [[WHILE_BODY:%.*]], label [[WHILE_END:%.*]]
37 // CHECK:       while.body:
38 // CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[E_ADDR]], align 4, !tbaa [[TBAA2]]
39 // CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP1]], 1
40 // CHECK-NEXT:    store i32 [[INC]], ptr [[E_ADDR]], align 4, !tbaa [[TBAA2]]
41 // CHECK-NEXT:    br label [[WHILE_COND]], !llvm.loop [[LOOP9:![0-9]+]]
42 // CHECK:       while.end:
43 // CHECK-NEXT:    ret void
44 //
45 void wu(int e){
46   while(e) [[unlikely]] ++e;
47 }
48 
49 // CHECK-LABEL: @_Z15w_branch_elidedj(
50 // CHECK-NEXT:  entry:
51 // CHECK-NEXT:    [[E_ADDR:%.*]] = alloca i32, align 4
52 // CHECK-NEXT:    store i32 [[E:%.*]], ptr [[E_ADDR]], align 4, !tbaa [[TBAA2]]
53 // CHECK-NEXT:    br label [[WHILE_BODY:%.*]]
54 // CHECK:       while.body:
55 // CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[E_ADDR]], align 4, !tbaa [[TBAA2]]
56 // CHECK-NEXT:    [[INC:%.*]] = add i32 [[TMP0]], 1
57 // CHECK-NEXT:    store i32 [[INC]], ptr [[E_ADDR]], align 4, !tbaa [[TBAA2]]
58 // CHECK-NEXT:    br label [[WHILE_BODY]], !llvm.loop [[LOOP10:![0-9]+]]
59 //
60 void w_branch_elided(unsigned e){
61   // expected-warning@+2 {{attribute 'likely' has no effect when annotating an infinite loop}}
62   // expected-note@+1 {{annotating the infinite loop here}}
63   while(1) [[likely]] ++e;
64 }
65 
66 // CHECK-LABEL: @_Z2flj(
67 // CHECK-NEXT:  entry:
68 // CHECK-NEXT:    [[E_ADDR:%.*]] = alloca i32, align 4
69 // CHECK-NEXT:    [[I:%.*]] = alloca i32, align 4
70 // CHECK-NEXT:    store i32 [[E:%.*]], ptr [[E_ADDR]], align 4, !tbaa [[TBAA2]]
71 // CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 4, ptr [[I]]) #[[ATTR3:[0-9]+]]
72 // CHECK-NEXT:    store i32 0, ptr [[I]], align 4, !tbaa [[TBAA2]]
73 // CHECK-NEXT:    br label [[FOR_COND:%.*]]
74 // CHECK:       for.cond:
75 // CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[I]], align 4, !tbaa [[TBAA2]]
76 // CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[E_ADDR]], align 4, !tbaa [[TBAA2]]
77 // CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[TMP0]], [[TMP1]]
78 // CHECK-NEXT:    [[CMP_EXPVAL:%.*]] = call i1 @llvm.expect.i1(i1 [[CMP]], i1 true)
79 // CHECK-NEXT:    br i1 [[CMP_EXPVAL]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]]
80 // CHECK:       for.cond.cleanup:
81 // CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 4, ptr [[I]]) #[[ATTR3]]
82 // CHECK-NEXT:    br label [[FOR_END:%.*]]
83 // CHECK:       for.body:
84 // CHECK-NEXT:    br label [[FOR_INC:%.*]]
85 // CHECK:       for.inc:
86 // CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[E_ADDR]], align 4, !tbaa [[TBAA2]]
87 // CHECK-NEXT:    [[INC:%.*]] = add i32 [[TMP2]], 1
88 // CHECK-NEXT:    store i32 [[INC]], ptr [[E_ADDR]], align 4, !tbaa [[TBAA2]]
89 // CHECK-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP11:![0-9]+]]
90 // CHECK:       for.end:
91 // CHECK-NEXT:    ret void
92 //
93 void fl(unsigned e)
94 {
95   for(int i = 0; i != e; ++e) [[likely]];
96 }
97 
98 // CHECK-LABEL: @_Z2fui(
99 // CHECK-NEXT:  entry:
100 // CHECK-NEXT:    [[E_ADDR:%.*]] = alloca i32, align 4
101 // CHECK-NEXT:    [[I:%.*]] = alloca i32, align 4
102 // CHECK-NEXT:    store i32 [[E:%.*]], ptr [[E_ADDR]], align 4, !tbaa [[TBAA2]]
103 // CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 4, ptr [[I]]) #[[ATTR3]]
104 // CHECK-NEXT:    store i32 0, ptr [[I]], align 4, !tbaa [[TBAA2]]
105 // CHECK-NEXT:    br label [[FOR_COND:%.*]]
106 // CHECK:       for.cond:
107 // CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[I]], align 4, !tbaa [[TBAA2]]
108 // CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[E_ADDR]], align 4, !tbaa [[TBAA2]]
109 // CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[TMP0]], [[TMP1]]
110 // CHECK-NEXT:    [[CMP_EXPVAL:%.*]] = call i1 @llvm.expect.i1(i1 [[CMP]], i1 false)
111 // CHECK-NEXT:    br i1 [[CMP_EXPVAL]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]]
112 // CHECK:       for.cond.cleanup:
113 // CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 4, ptr [[I]]) #[[ATTR3]]
114 // CHECK-NEXT:    br label [[FOR_END:%.*]]
115 // CHECK:       for.body:
116 // CHECK-NEXT:    br label [[FOR_INC:%.*]]
117 // CHECK:       for.inc:
118 // CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[E_ADDR]], align 4, !tbaa [[TBAA2]]
119 // CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP2]], 1
120 // CHECK-NEXT:    store i32 [[INC]], ptr [[E_ADDR]], align 4, !tbaa [[TBAA2]]
121 // CHECK-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP12:![0-9]+]]
122 // CHECK:       for.end:
123 // CHECK-NEXT:    ret void
124 //
125 void fu(int e)
126 {
127   for(int i = 0; i != e; ++e) [[unlikely]];
128 }
129 
130 // CHECK-LABEL: @_Z15f_branch_elidedv(
131 // CHECK-NEXT:  entry:
132 // CHECK-NEXT:    br label [[FOR_COND:%.*]]
133 // CHECK:       for.cond:
134 // CHECK-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP13:![0-9]+]]
135 //
136 void f_branch_elided()
137 {
138   for(;;) [[likely]];
139 }
140 
141 // CHECK-LABEL: @_Z3frlOA4_i(
142 // CHECK-NEXT:  entry:
143 // CHECK-NEXT:    [[E_ADDR:%.*]] = alloca ptr, align 8
144 // CHECK-NEXT:    [[__RANGE1:%.*]] = alloca ptr, align 8
145 // CHECK-NEXT:    [[__BEGIN1:%.*]] = alloca ptr, align 8
146 // CHECK-NEXT:    [[__END1:%.*]] = alloca ptr, align 8
147 // CHECK-NEXT:    [[I:%.*]] = alloca i32, align 4
148 // CHECK-NEXT:    store ptr [[E:%.*]], ptr [[E_ADDR]], align 8, !tbaa [[TBAA14:![0-9]+]]
149 // CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 8, ptr [[__RANGE1]]) #[[ATTR3]]
150 // CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[E_ADDR]], align 8, !tbaa [[TBAA14]]
151 // CHECK-NEXT:    store ptr [[TMP0]], ptr [[__RANGE1]], align 8, !tbaa [[TBAA14]]
152 // CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 8, ptr [[__BEGIN1]]) #[[ATTR3]]
153 // CHECK-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[__RANGE1]], align 8, !tbaa [[TBAA14]]
154 // CHECK-NEXT:    [[ARRAYDECAY:%.*]] = getelementptr inbounds [4 x i32], ptr [[TMP1]], i64 0, i64 0
155 // CHECK-NEXT:    store ptr [[ARRAYDECAY]], ptr [[__BEGIN1]], align 8, !tbaa [[TBAA14]]
156 // CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 8, ptr [[__END1]]) #[[ATTR3]]
157 // CHECK-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[__RANGE1]], align 8, !tbaa [[TBAA14]]
158 // CHECK-NEXT:    [[ARRAYDECAY1:%.*]] = getelementptr inbounds [4 x i32], ptr [[TMP2]], i64 0, i64 0
159 // CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAYDECAY1]], i64 4
160 // CHECK-NEXT:    store ptr [[ADD_PTR]], ptr [[__END1]], align 8, !tbaa [[TBAA14]]
161 // CHECK-NEXT:    br label [[FOR_COND:%.*]]
162 // CHECK:       for.cond:
163 // CHECK-NEXT:    [[TMP3:%.*]] = load ptr, ptr [[__BEGIN1]], align 8, !tbaa [[TBAA14]]
164 // CHECK-NEXT:    [[TMP4:%.*]] = load ptr, ptr [[__END1]], align 8, !tbaa [[TBAA14]]
165 // CHECK-NEXT:    [[CMP:%.*]] = icmp ne ptr [[TMP3]], [[TMP4]]
166 // CHECK-NEXT:    [[CMP_EXPVAL:%.*]] = call i1 @llvm.expect.i1(i1 [[CMP]], i1 true)
167 // CHECK-NEXT:    br i1 [[CMP_EXPVAL]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]]
168 // CHECK:       for.cond.cleanup:
169 // CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 8, ptr [[__END1]]) #[[ATTR3]]
170 // CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 8, ptr [[__BEGIN1]]) #[[ATTR3]]
171 // CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 8, ptr [[__RANGE1]]) #[[ATTR3]]
172 // CHECK-NEXT:    br label [[FOR_END:%.*]]
173 // CHECK:       for.body:
174 // CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 4, ptr [[I]]) #[[ATTR3]]
175 // CHECK-NEXT:    [[TMP5:%.*]] = load ptr, ptr [[__BEGIN1]], align 8, !tbaa [[TBAA14]]
176 // CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[TMP5]], align 4, !tbaa [[TBAA2]]
177 // CHECK-NEXT:    store i32 [[TMP6]], ptr [[I]], align 4, !tbaa [[TBAA2]]
178 // CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 4, ptr [[I]]) #[[ATTR3]]
179 // CHECK-NEXT:    br label [[FOR_INC:%.*]]
180 // CHECK:       for.inc:
181 // CHECK-NEXT:    [[TMP7:%.*]] = load ptr, ptr [[__BEGIN1]], align 8, !tbaa [[TBAA14]]
182 // CHECK-NEXT:    [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP7]], i32 1
183 // CHECK-NEXT:    store ptr [[INCDEC_PTR]], ptr [[__BEGIN1]], align 8, !tbaa [[TBAA14]]
184 // CHECK-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP16:![0-9]+]]
185 // CHECK:       for.end:
186 // CHECK-NEXT:    ret void
187 //
188 void frl(int (&&e) [4])
189 {
190   for(int i : e) [[likely]];
191 }
192 
193 // CHECK-LABEL: @_Z3fruOA4_i(
194 // CHECK-NEXT:  entry:
195 // CHECK-NEXT:    [[E_ADDR:%.*]] = alloca ptr, align 8
196 // CHECK-NEXT:    [[__RANGE1:%.*]] = alloca ptr, align 8
197 // CHECK-NEXT:    [[__BEGIN1:%.*]] = alloca ptr, align 8
198 // CHECK-NEXT:    [[__END1:%.*]] = alloca ptr, align 8
199 // CHECK-NEXT:    [[I:%.*]] = alloca i32, align 4
200 // CHECK-NEXT:    store ptr [[E:%.*]], ptr [[E_ADDR]], align 8, !tbaa [[TBAA14]]
201 // CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 8, ptr [[__RANGE1]]) #[[ATTR3]]
202 // CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[E_ADDR]], align 8, !tbaa [[TBAA14]]
203 // CHECK-NEXT:    store ptr [[TMP0]], ptr [[__RANGE1]], align 8, !tbaa [[TBAA14]]
204 // CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 8, ptr [[__BEGIN1]]) #[[ATTR3]]
205 // CHECK-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[__RANGE1]], align 8, !tbaa [[TBAA14]]
206 // CHECK-NEXT:    [[ARRAYDECAY:%.*]] = getelementptr inbounds [4 x i32], ptr [[TMP1]], i64 0, i64 0
207 // CHECK-NEXT:    store ptr [[ARRAYDECAY]], ptr [[__BEGIN1]], align 8, !tbaa [[TBAA14]]
208 // CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 8, ptr [[__END1]]) #[[ATTR3]]
209 // CHECK-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[__RANGE1]], align 8, !tbaa [[TBAA14]]
210 // CHECK-NEXT:    [[ARRAYDECAY1:%.*]] = getelementptr inbounds [4 x i32], ptr [[TMP2]], i64 0, i64 0
211 // CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAYDECAY1]], i64 4
212 // CHECK-NEXT:    store ptr [[ADD_PTR]], ptr [[__END1]], align 8, !tbaa [[TBAA14]]
213 // CHECK-NEXT:    br label [[FOR_COND:%.*]]
214 // CHECK:       for.cond:
215 // CHECK-NEXT:    [[TMP3:%.*]] = load ptr, ptr [[__BEGIN1]], align 8, !tbaa [[TBAA14]]
216 // CHECK-NEXT:    [[TMP4:%.*]] = load ptr, ptr [[__END1]], align 8, !tbaa [[TBAA14]]
217 // CHECK-NEXT:    [[CMP:%.*]] = icmp ne ptr [[TMP3]], [[TMP4]]
218 // CHECK-NEXT:    [[CMP_EXPVAL:%.*]] = call i1 @llvm.expect.i1(i1 [[CMP]], i1 false)
219 // CHECK-NEXT:    br i1 [[CMP_EXPVAL]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]]
220 // CHECK:       for.cond.cleanup:
221 // CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 8, ptr [[__END1]]) #[[ATTR3]]
222 // CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 8, ptr [[__BEGIN1]]) #[[ATTR3]]
223 // CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 8, ptr [[__RANGE1]]) #[[ATTR3]]
224 // CHECK-NEXT:    br label [[FOR_END:%.*]]
225 // CHECK:       for.body:
226 // CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 4, ptr [[I]]) #[[ATTR3]]
227 // CHECK-NEXT:    [[TMP5:%.*]] = load ptr, ptr [[__BEGIN1]], align 8, !tbaa [[TBAA14]]
228 // CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[TMP5]], align 4, !tbaa [[TBAA2]]
229 // CHECK-NEXT:    store i32 [[TMP6]], ptr [[I]], align 4, !tbaa [[TBAA2]]
230 // CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 4, ptr [[I]]) #[[ATTR3]]
231 // CHECK-NEXT:    br label [[FOR_INC:%.*]]
232 // CHECK:       for.inc:
233 // CHECK-NEXT:    [[TMP7:%.*]] = load ptr, ptr [[__BEGIN1]], align 8, !tbaa [[TBAA14]]
234 // CHECK-NEXT:    [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP7]], i32 1
235 // CHECK-NEXT:    store ptr [[INCDEC_PTR]], ptr [[__BEGIN1]], align 8, !tbaa [[TBAA14]]
236 // CHECK-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP17:![0-9]+]]
237 // CHECK:       for.end:
238 // CHECK-NEXT:    ret void
239 //
240 void fru(int (&&e) [4])
241 {
242   for(int i : e) [[unlikely]];
243 }
244