@@ -91,8 +91,151 @@ for.end: ; preds = %for.cond.cleanup
91
91
ret i32 %9
92
92
}
93
93
94
+ %"class.std::__1::span" = type { ptr , i64 }
95
+ %"class.std::__1::__wrap_iter" = type { ptr }
96
+
97
+ define dso_local noundef i32 @sum_prefix_with_sum (ptr %s.coerce0 , i64 %s.coerce1 , i64 noundef %n ) {
98
+ ; CHECK-LABEL: define dso_local noundef i32 @sum_prefix_with_sum(
99
+ ; CHECK-SAME: ptr nocapture readonly [[S_COERCE0:%.*]], i64 [[S_COERCE1:%.*]], i64 noundef [[N:%.*]]) local_unnamed_addr #[[ATTR0]] {
100
+ ; CHECK-NEXT: entry:
101
+ ; CHECK-NEXT: [[CMP5_NOT:%.*]] = icmp eq i64 [[N]], 0
102
+ ; CHECK-NEXT: br i1 [[CMP5_NOT]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY_PREHEADER:%.*]]
103
+ ; CHECK: for.body.preheader:
104
+ ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[N]], -1
105
+ ; CHECK-NEXT: [[DOTNOT_NOT:%.*]] = icmp ult i64 [[TMP0]], [[S_COERCE1]]
106
+ ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
107
+ ; CHECK: for.cond.cleanup:
108
+ ; CHECK-NEXT: [[RET_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD:%.*]], [[SPAN_CHECKED_ACCESS_EXIT:%.*]] ]
109
+ ; CHECK-NEXT: ret i32 [[RET_0_LCSSA]]
110
+ ; CHECK: for.body:
111
+ ; CHECK-NEXT: [[I_07:%.*]] = phi i64 [ [[INC:%.*]], [[SPAN_CHECKED_ACCESS_EXIT]] ], [ 0, [[FOR_BODY_PREHEADER]] ]
112
+ ; CHECK-NEXT: [[RET_06:%.*]] = phi i32 [ [[ADD]], [[SPAN_CHECKED_ACCESS_EXIT]] ], [ 0, [[FOR_BODY_PREHEADER]] ]
113
+ ; CHECK-NEXT: br i1 [[DOTNOT_NOT]], label [[SPAN_CHECKED_ACCESS_EXIT]], label [[COND_FALSE_I:%.*]], !prof [[PROF0:![0-9]+]]
114
+ ; CHECK: cond.false.i:
115
+ ; CHECK-NEXT: tail call void @llvm.trap()
116
+ ; CHECK-NEXT: unreachable
117
+ ; CHECK: span_checked_access.exit:
118
+ ; CHECK-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds i32, ptr [[S_COERCE0]], i64 [[I_07]]
119
+ ; CHECK-NEXT: [[TMP7:%.*]] = load i32, ptr [[ARRAYIDX_I]], align 4
120
+ ; CHECK-NEXT: [[ADD]] = add nsw i32 [[TMP7]], [[RET_06]]
121
+ ; CHECK-NEXT: [[INC]] = add nuw i64 [[I_07]], 1
122
+ ; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[INC]], [[N]]
123
+ ; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[FOR_COND_CLEANUP]], label [[FOR_BODY]]
124
+ ;
125
+ entry:
126
+ %s = alloca %"class.std::__1::span" , align 8
127
+ %n.addr = alloca i64 , align 8
128
+ %ret = alloca i32 , align 4
129
+ %i = alloca i64 , align 8
130
+ %0 = getelementptr inbounds { ptr , i64 }, ptr %s , i32 0 , i32 0
131
+ store ptr %s.coerce0 , ptr %0 , align 8
132
+ %1 = getelementptr inbounds { ptr , i64 }, ptr %s , i32 0 , i32 1
133
+ store i64 %s.coerce1 , ptr %1 , align 8
134
+ store i64 %n , ptr %n.addr , align 8
135
+ call void @llvm.lifetime.start.p0 (i64 4 , ptr %ret ) #7
136
+ store i32 0 , ptr %ret , align 4
137
+ call void @llvm.lifetime.start.p0 (i64 8 , ptr %i ) #7
138
+ store i64 0 , ptr %i , align 8
139
+ br label %for.cond
140
+
141
+ for.cond: ; preds = %for.inc, %entry
142
+ %2 = load i64 , ptr %i , align 8
143
+ %3 = load i64 , ptr %n.addr , align 8
144
+ %cmp = icmp ult i64 %2 , %3
145
+ br i1 %cmp , label %for.body , label %for.cond.cleanup
146
+
147
+ for.cond.cleanup: ; preds = %for.cond
148
+ call void @llvm.lifetime.end.p0 (i64 8 , ptr %i ) #7
149
+ br label %for.end
150
+
151
+ for.body: ; preds = %for.cond
152
+ %4 = load i64 , ptr %i , align 8
153
+ %call = call noundef nonnull align 4 dereferenceable (4 ) ptr @span_checked_access (ptr noundef nonnull align 8 dereferenceable (16 ) %s , i64 noundef %4 ) #7
154
+ %5 = load i32 , ptr %call , align 4
155
+ %6 = load i32 , ptr %ret , align 4
156
+ %add = add nsw i32 %6 , %5
157
+ store i32 %add , ptr %ret , align 4
158
+ br label %for.inc
159
+
160
+ for.inc: ; preds = %for.body
161
+ %7 = load i64 , ptr %i , align 8
162
+ %inc = add i64 %7 , 1
163
+ store i64 %inc , ptr %i , align 8
164
+ br label %for.cond
165
+
166
+ for.end: ; preds = %for.cond.cleanup
167
+ %8 = load i32 , ptr %ret , align 4
168
+ call void @llvm.lifetime.end.p0 (i64 4 , ptr %ret )
169
+ ret i32 %8
170
+ }
171
+
172
+ define hidden noundef nonnull align 4 dereferenceable (4 ) ptr @span_checked_access (ptr noundef nonnull align 8 dereferenceable (16 ) %this , i64 noundef %__idx ) {
173
+ ; CHECK-LABEL: define hidden noundef nonnull align 4 dereferenceable(4) ptr @span_checked_access(
174
+ ; CHECK-SAME: ptr nocapture noundef nonnull readonly align 8 dereferenceable(16) [[THIS:%.*]], i64 noundef [[__IDX:%.*]]) local_unnamed_addr #[[ATTR0]] {
175
+ ; CHECK-NEXT: entry:
176
+ ; CHECK-NEXT: [[__SIZE__I:%.*]] = getelementptr inbounds i8, ptr [[THIS]], i64 8
177
+ ; CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr [[__SIZE__I]], align 8
178
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i64 [[TMP0]], [[__IDX]]
179
+ ; CHECK-NEXT: br i1 [[CMP]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]], !prof [[PROF0]]
180
+ ; CHECK: cond.false:
181
+ ; CHECK-NEXT: tail call void @llvm.trap()
182
+ ; CHECK-NEXT: unreachable
183
+ ; CHECK: cond.end:
184
+ ; CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[THIS]], align 8
185
+ ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i64 [[__IDX]]
186
+ ; CHECK-NEXT: ret ptr [[ARRAYIDX]]
187
+ ;
188
+ entry:
189
+ %this.addr = alloca ptr , align 8
190
+ %__idx.addr = alloca i64 , align 8
191
+ store ptr %this , ptr %this.addr , align 8
192
+ store i64 %__idx , ptr %__idx.addr , align 8
193
+ %this1 = load ptr , ptr %this.addr , align 8
194
+ %0 = load i64 , ptr %__idx.addr , align 8
195
+ %call = call noundef i64 @span_access (ptr noundef nonnull align 8 dereferenceable (16 ) %this1 )
196
+ %cmp = icmp ult i64 %0 , %call
197
+ %conv = zext i1 %cmp to i64
198
+ %expval = call i64 @llvm.expect.i64 (i64 %conv , i64 1 )
199
+ %tobool = icmp ne i64 %expval , 0
200
+ br i1 %tobool , label %cond.true , label %cond.false
201
+
202
+ cond.true: ; preds = %entry
203
+ br label %cond.end
204
+
205
+ cond.false: ; preds = %entry
206
+ call void @llvm.trap ()
207
+ br label %cond.end
208
+
209
+ cond.end: ; preds = %cond.false, %cond.true
210
+ %__data_ = getelementptr inbounds %"class.std::__1::span" , ptr %this1 , i32 0 , i32 0
211
+ %1 = load ptr , ptr %__data_ , align 8
212
+ %2 = load i64 , ptr %__idx.addr , align 8
213
+ %arrayidx = getelementptr inbounds i32 , ptr %1 , i64 %2
214
+ ret ptr %arrayidx
215
+ }
216
+
217
+ define hidden noundef i64 @span_access (ptr noundef nonnull align 8 dereferenceable (16 ) %this ) {
218
+ ; CHECK-LABEL: define hidden noundef i64 @span_access(
219
+ ; CHECK-SAME: ptr nocapture noundef nonnull readonly align 8 dereferenceable(16) [[THIS:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] {
220
+ ; CHECK-NEXT: entry:
221
+ ; CHECK-NEXT: [[__SIZE_:%.*]] = getelementptr inbounds i8, ptr [[THIS]], i64 8
222
+ ; CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr [[__SIZE_]], align 8
223
+ ; CHECK-NEXT: ret i64 [[TMP0]]
224
+ ;
225
+ entry:
226
+ %this.addr = alloca ptr , align 8
227
+ store ptr %this , ptr %this.addr , align 8
228
+ %this1 = load ptr , ptr %this.addr , align 8
229
+ %__size_ = getelementptr inbounds %"class.std::__1::span" , ptr %this1 , i32 0 , i32 1
230
+ %0 = load i64 , ptr %__size_ , align 8
231
+ ret i64 %0
232
+ }
233
+
94
234
declare void @llvm.lifetime.start.p0 (i64 immarg, ptr nocapture )
95
235
96
236
declare void @llvm.trap ()
97
237
98
238
declare void @llvm.lifetime.end.p0 (i64 immarg, ptr nocapture )
239
+ ;.
240
+ ; CHECK: [[PROF0]] = !{!"branch_weights", i32 2000, i32 1}
241
+ ;.
0 commit comments