@@ -99,11 +99,10 @@ exit:
99
99
ret i1 %res
100
100
}
101
101
102
-
103
102
; The code below exposed a bug similar to the one exposed by D60846, see the commit 6ea477590085.
104
103
; In a nutshell, we should not replace %result.0 with 0 here.
105
104
106
- define zeroext i8 @update_phi_query_loc_in_recursive_call (ptr nocapture readonly %p ){
105
+ define zeroext i8 @update_phi_query_loc_in_recursive_call (ptr nocapture readonly %p ) {
107
106
; CHECK-LABEL: @update_phi_query_loc_in_recursive_call(
108
107
; CHECK-NEXT: entry:
109
108
; CHECK-NEXT: br label [[FOR_COND:%.*]]
@@ -126,16 +125,16 @@ define zeroext i8 @update_phi_query_loc_in_recursive_call(ptr nocapture readonly
126
125
entry:
127
126
br label %for.cond
128
127
129
- for.cond: ; preds = %for.body, %entry
128
+ for.cond: ; preds = %for.body, %entry
130
129
%result.0 = phi i8 [ 0 , %entry ], [ %conv2 , %for.body ]
131
130
%shift.0 = phi i32 [ 0 , %entry ], [ 1 , %for.body ]
132
131
%cmp = icmp eq i32 %shift.0 , 0
133
132
br i1 %cmp , label %for.body , label %for.cond.cleanup
134
133
135
- for.cond.cleanup: ; preds = %for.cond
134
+ for.cond.cleanup: ; preds = %for.cond
136
135
ret i8 %result.0
137
136
138
- for.body: ; preds = %for.cond
137
+ for.body: ; preds = %for.cond
139
138
%0 = load i8 , ptr %p , align 1
140
139
%conv = zext i8 %0 to i32
141
140
%mul = shl nuw nsw i32 %shift.0 , 3
166
165
B:
167
166
ret i1 0
168
167
}
168
+
169
+ declare void @use.i1 (i1 )
170
+ declare void @use.i8 (i1 )
171
+ define i1 @extract_value_uadd (i8 %xx , i8 %yy ) {
172
+ ; CHECK-LABEL: @extract_value_uadd(
173
+ ; CHECK-NEXT: [[X:%.*]] = add nuw i8 [[XX:%.*]], 1
174
+ ; CHECK-NEXT: [[Y:%.*]] = add nuw i8 [[YY:%.*]], 1
175
+ ; CHECK-NEXT: [[X_LEMMA:%.*]] = icmp ult i8 [[X]], -128
176
+ ; CHECK-NEXT: [[Y_LEMMA:%.*]] = icmp ult i8 [[Y]], -128
177
+ ; CHECK-NEXT: call void @llvm.assume(i1 [[X_LEMMA]])
178
+ ; CHECK-NEXT: call void @llvm.assume(i1 [[Y_LEMMA]])
179
+ ; CHECK-NEXT: [[ADD_UOV:%.*]] = call { i8, i1 } @llvm.uadd.with.overflow.i8(i8 [[X]], i8 [[Y]])
180
+ ; CHECK-NEXT: [[ADD:%.*]] = extractvalue { i8, i1 } [[ADD_UOV]], 0
181
+ ; CHECK-NEXT: [[UOV:%.*]] = extractvalue { i8, i1 } [[ADD_UOV]], 1
182
+ ; CHECK-NEXT: call void @use.i1(i1 [[UOV]])
183
+ ; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[ADD]], 0
184
+ ; CHECK-NEXT: ret i1 [[R]]
185
+ ;
186
+ %x = add nuw i8 %xx , 1
187
+ %y = add nuw i8 %yy , 1
188
+ %x_lemma = icmp ult i8 %x , 128
189
+ %y_lemma = icmp ult i8 %y , 128
190
+ call void @llvm.assume (i1 %x_lemma )
191
+ call void @llvm.assume (i1 %y_lemma )
192
+
193
+ %add_uov = call { i8 , i1 } @llvm.uadd.with.overflow (i8 %x , i8 %y )
194
+ %add = extractvalue { i8 , i1 } %add_uov , 0
195
+ %uov = extractvalue { i8 , i1 } %add_uov , 1
196
+ call void @use.i1 (i1 %uov )
197
+ %r = icmp eq i8 %add , 0
198
+ ret i1 %r
199
+ }
200
+
201
+ define i1 @extract_value_uadd_fail (i8 %xx , i8 %yy ) {
202
+ ; CHECK-LABEL: @extract_value_uadd_fail(
203
+ ; CHECK-NEXT: [[X:%.*]] = add i8 [[XX:%.*]], 1
204
+ ; CHECK-NEXT: [[Y:%.*]] = add i8 [[YY:%.*]], 1
205
+ ; CHECK-NEXT: [[X_LEMMA:%.*]] = icmp ult i8 [[X]], -128
206
+ ; CHECK-NEXT: [[Y_LEMMA:%.*]] = icmp ult i8 [[Y]], -128
207
+ ; CHECK-NEXT: call void @llvm.assume(i1 [[X_LEMMA]])
208
+ ; CHECK-NEXT: call void @llvm.assume(i1 [[Y_LEMMA]])
209
+ ; CHECK-NEXT: [[ADD_UOV:%.*]] = call { i8, i1 } @llvm.uadd.with.overflow.i8(i8 [[X]], i8 [[Y]])
210
+ ; CHECK-NEXT: [[ADD:%.*]] = extractvalue { i8, i1 } [[ADD_UOV]], 0
211
+ ; CHECK-NEXT: [[UOV:%.*]] = extractvalue { i8, i1 } [[ADD_UOV]], 1
212
+ ; CHECK-NEXT: call void @use.i1(i1 [[UOV]])
213
+ ; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[ADD]], 0
214
+ ; CHECK-NEXT: ret i1 [[R]]
215
+ ;
216
+ %x = add i8 %xx , 1
217
+ %y = add i8 %yy , 1
218
+ %x_lemma = icmp ult i8 %x , 128
219
+ %y_lemma = icmp ult i8 %y , 128
220
+ call void @llvm.assume (i1 %x_lemma )
221
+ call void @llvm.assume (i1 %y_lemma )
222
+
223
+ %add_uov = call { i8 , i1 } @llvm.uadd.with.overflow (i8 %x , i8 %y )
224
+ %add = extractvalue { i8 , i1 } %add_uov , 0
225
+ %uov = extractvalue { i8 , i1 } %add_uov , 1
226
+ call void @use.i1 (i1 %uov )
227
+ %r = icmp eq i8 %add , 0
228
+ ret i1 %r
229
+ }
230
+
231
+ define i1 @extract_value_sadd (i8 %xx , i8 %yy ) {
232
+ ; CHECK-LABEL: @extract_value_sadd(
233
+ ; CHECK-NEXT: [[X:%.*]] = add nuw i8 [[XX:%.*]], 1
234
+ ; CHECK-NEXT: [[Y:%.*]] = add nuw i8 [[YY:%.*]], 1
235
+ ; CHECK-NEXT: [[X_LEMMA:%.*]] = icmp ult i8 [[X]], -128
236
+ ; CHECK-NEXT: [[Y_LEMMA:%.*]] = icmp ult i8 [[Y]], -128
237
+ ; CHECK-NEXT: call void @llvm.assume(i1 [[X_LEMMA]])
238
+ ; CHECK-NEXT: call void @llvm.assume(i1 [[Y_LEMMA]])
239
+ ; CHECK-NEXT: [[ADD_SOV:%.*]] = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[X]], i8 [[Y]])
240
+ ; CHECK-NEXT: [[ADD:%.*]] = extractvalue { i8, i1 } [[ADD_SOV]], 0
241
+ ; CHECK-NEXT: [[SOV:%.*]] = extractvalue { i8, i1 } [[ADD_SOV]], 1
242
+ ; CHECK-NEXT: call void @use.i1(i1 [[SOV]])
243
+ ; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[ADD]], 0
244
+ ; CHECK-NEXT: ret i1 [[R]]
245
+ ;
246
+ %x = add nuw i8 %xx , 1
247
+ %y = add nuw i8 %yy , 1
248
+ %x_lemma = icmp ult i8 %x , 128
249
+ %y_lemma = icmp ult i8 %y , 128
250
+ call void @llvm.assume (i1 %x_lemma )
251
+ call void @llvm.assume (i1 %y_lemma )
252
+
253
+ %add_sov = call { i8 , i1 } @llvm.sadd.with.overflow (i8 %x , i8 %y )
254
+ %add = extractvalue { i8 , i1 } %add_sov , 0
255
+ %sov = extractvalue { i8 , i1 } %add_sov , 1
256
+ call void @use.i1 (i1 %sov )
257
+ %r = icmp eq i8 %add , 0
258
+ ret i1 %r
259
+ }
260
+
261
+ define i1 @extract_value_sadd_fail (i8 %xx , i8 %yy ) {
262
+ ; CHECK-LABEL: @extract_value_sadd_fail(
263
+ ; CHECK-NEXT: [[X:%.*]] = add i8 [[XX:%.*]], 1
264
+ ; CHECK-NEXT: [[Y:%.*]] = add i8 [[YY:%.*]], 1
265
+ ; CHECK-NEXT: [[ADD_SOV:%.*]] = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[X]], i8 [[Y]])
266
+ ; CHECK-NEXT: [[ADD:%.*]] = extractvalue { i8, i1 } [[ADD_SOV]], 0
267
+ ; CHECK-NEXT: [[SOV:%.*]] = extractvalue { i8, i1 } [[ADD_SOV]], 1
268
+ ; CHECK-NEXT: call void @use.i1(i1 [[SOV]])
269
+ ; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[ADD]], 0
270
+ ; CHECK-NEXT: ret i1 [[R]]
271
+ ;
272
+ %x = add i8 %xx , 1
273
+ %y = add i8 %yy , 1
274
+
275
+ %add_sov = call { i8 , i1 } @llvm.sadd.with.overflow (i8 %x , i8 %y )
276
+ %add = extractvalue { i8 , i1 } %add_sov , 0
277
+ %sov = extractvalue { i8 , i1 } %add_sov , 1
278
+ call void @use.i1 (i1 %sov )
279
+ %r = icmp eq i8 %add , 0
280
+ ret i1 %r
281
+ }
282
+
283
+ define i1 @extract_value_usub (i8 %x , i8 %zz ) {
284
+ ; CHECK-LABEL: @extract_value_usub(
285
+ ; CHECK-NEXT: [[Z:%.*]] = add nuw i8 [[ZZ:%.*]], 1
286
+ ; CHECK-NEXT: [[Y:%.*]] = add i8 [[X:%.*]], [[Z]]
287
+ ; CHECK-NEXT: [[SUB_UOV:%.*]] = call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[X]], i8 [[Y]])
288
+ ; CHECK-NEXT: [[SUB:%.*]] = extractvalue { i8, i1 } [[SUB_UOV]], 0
289
+ ; CHECK-NEXT: [[UOV:%.*]] = extractvalue { i8, i1 } [[SUB_UOV]], 1
290
+ ; CHECK-NEXT: call void @use.i1(i1 [[UOV]])
291
+ ; CHECK-NEXT: call void @use.i8(i8 [[SUB]])
292
+ ; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[SUB]], 0
293
+ ; CHECK-NEXT: ret i1 [[R]]
294
+ ;
295
+ %z = add nuw i8 %zz , 1
296
+ %y = add i8 %x , %z
297
+
298
+ %sub_uov = call { i8 , i1 } @llvm.usub.with.overflow (i8 %x , i8 %y )
299
+ %sub = extractvalue { i8 , i1 } %sub_uov , 0
300
+ %uov = extractvalue { i8 , i1 } %sub_uov , 1
301
+ call void @use.i1 (i1 %uov )
302
+ call void @use.i8 (i8 %sub )
303
+ %r = icmp eq i8 %sub , 0
304
+ ret i1 %r
305
+ }
306
+
307
+ define i1 @extract_value_usub_fail (i8 %x , i8 %z ) {
308
+ ; CHECK-LABEL: @extract_value_usub_fail(
309
+ ; CHECK-NEXT: [[Y:%.*]] = add i8 [[X:%.*]], [[Z:%.*]]
310
+ ; CHECK-NEXT: [[SUB_UOV:%.*]] = call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[X]], i8 [[Y]])
311
+ ; CHECK-NEXT: [[SUB:%.*]] = extractvalue { i8, i1 } [[SUB_UOV]], 0
312
+ ; CHECK-NEXT: [[UOV:%.*]] = extractvalue { i8, i1 } [[SUB_UOV]], 1
313
+ ; CHECK-NEXT: call void @use.i1(i1 [[UOV]])
314
+ ; CHECK-NEXT: call void @use.i8(i8 [[SUB]])
315
+ ; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[SUB]], 0
316
+ ; CHECK-NEXT: ret i1 [[R]]
317
+ ;
318
+ %y = add i8 %x , %z
319
+ %sub_uov = call { i8 , i1 } @llvm.usub.with.overflow (i8 %x , i8 %y )
320
+ %sub = extractvalue { i8 , i1 } %sub_uov , 0
321
+ %uov = extractvalue { i8 , i1 } %sub_uov , 1
322
+ call void @use.i1 (i1 %uov )
323
+ call void @use.i8 (i8 %sub )
324
+ %r = icmp eq i8 %sub , 0
325
+ ret i1 %r
326
+ }
327
+
328
+ define i1 @extract_value_ssub (i8 %x , i8 %zz ) {
329
+ ; CHECK-LABEL: @extract_value_ssub(
330
+ ; CHECK-NEXT: [[Z:%.*]] = add nuw i8 [[ZZ:%.*]], 1
331
+ ; CHECK-NEXT: [[Y:%.*]] = add i8 [[X:%.*]], [[Z]]
332
+ ; CHECK-NEXT: [[SUB_SOV:%.*]] = call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[Y]], i8 [[X]])
333
+ ; CHECK-NEXT: [[SUB:%.*]] = extractvalue { i8, i1 } [[SUB_SOV]], 0
334
+ ; CHECK-NEXT: [[SOV:%.*]] = extractvalue { i8, i1 } [[SUB_SOV]], 1
335
+ ; CHECK-NEXT: call void @use.i1(i1 [[SOV]])
336
+ ; CHECK-NEXT: call void @use.i8(i8 [[SUB]])
337
+ ; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[SUB]], 0
338
+ ; CHECK-NEXT: ret i1 [[R]]
339
+ ;
340
+ %z = add nuw i8 %zz , 1
341
+ %y = add i8 %x , %z
342
+
343
+ %sub_sov = call { i8 , i1 } @llvm.ssub.with.overflow (i8 %y , i8 %x )
344
+ %sub = extractvalue { i8 , i1 } %sub_sov , 0
345
+ %sov = extractvalue { i8 , i1 } %sub_sov , 1
346
+ call void @use.i1 (i1 %sov )
347
+ call void @use.i8 (i8 %sub )
348
+ %r = icmp eq i8 %sub , 0
349
+ ret i1 %r
350
+ }
351
+
352
+ define i1 @extract_value_ssub_fail (i8 %x ) {
353
+ ; CHECK-LABEL: @extract_value_ssub_fail(
354
+ ; CHECK-NEXT: [[SUB_SOV:%.*]] = call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 10, i8 [[X:%.*]])
355
+ ; CHECK-NEXT: [[SUB:%.*]] = extractvalue { i8, i1 } [[SUB_SOV]], 0
356
+ ; CHECK-NEXT: [[SOV:%.*]] = extractvalue { i8, i1 } [[SUB_SOV]], 1
357
+ ; CHECK-NEXT: call void @use.i1(i1 [[SOV]])
358
+ ; CHECK-NEXT: call void @use.i8(i8 [[SUB]])
359
+ ; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[SUB]], 0
360
+ ; CHECK-NEXT: ret i1 [[R]]
361
+ ;
362
+ %sub_sov = call { i8 , i1 } @llvm.ssub.with.overflow (i8 10 , i8 %x )
363
+ %sub = extractvalue { i8 , i1 } %sub_sov , 0
364
+ %sov = extractvalue { i8 , i1 } %sub_sov , 1
365
+ call void @use.i1 (i1 %sov )
366
+ call void @use.i8 (i8 %sub )
367
+ %r = icmp eq i8 %sub , 0
368
+ ret i1 %r
369
+ }
370
+
371
+ define i1 @extract_value_umul (i8 %xx , i8 %yy ) {
372
+ ; CHECK-LABEL: @extract_value_umul(
373
+ ; CHECK-NEXT: [[X:%.*]] = or i8 [[XX:%.*]], 1
374
+ ; CHECK-NEXT: [[Y:%.*]] = add nuw i8 [[YY:%.*]], 1
375
+ ; CHECK-NEXT: [[MUL_UOV:%.*]] = call { i8, i1 } @llvm.umul.with.overflow.i8(i8 [[X]], i8 [[Y]])
376
+ ; CHECK-NEXT: [[MUL:%.*]] = extractvalue { i8, i1 } [[MUL_UOV]], 0
377
+ ; CHECK-NEXT: [[UOV:%.*]] = extractvalue { i8, i1 } [[MUL_UOV]], 1
378
+ ; CHECK-NEXT: call void @use.i1(i1 [[UOV]])
379
+ ; CHECK-NEXT: call void @use.i8(i8 [[MUL]])
380
+ ; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[MUL]], 0
381
+ ; CHECK-NEXT: ret i1 [[R]]
382
+ ;
383
+ %x = or i8 %xx , 1
384
+ %y = add nuw i8 %yy , 1
385
+
386
+ %mul_uov = call { i8 , i1 } @llvm.umul.with.overflow (i8 %x , i8 %y )
387
+ %mul = extractvalue { i8 , i1 } %mul_uov , 0
388
+ %uov = extractvalue { i8 , i1 } %mul_uov , 1
389
+ call void @use.i1 (i1 %uov )
390
+ call void @use.i8 (i8 %mul )
391
+ %r = icmp eq i8 %mul , 0
392
+ ret i1 %r
393
+ }
394
+
395
+ define i1 @extract_value_umul_fail (i8 %xx , i8 %yy ) {
396
+ ; CHECK-LABEL: @extract_value_umul_fail(
397
+ ; CHECK-NEXT: [[X:%.*]] = or i8 [[XX:%.*]], 2
398
+ ; CHECK-NEXT: [[Y:%.*]] = add nuw i8 [[YY:%.*]], 1
399
+ ; CHECK-NEXT: [[MUL_UOV:%.*]] = call { i8, i1 } @llvm.umul.with.overflow.i8(i8 [[X]], i8 [[Y]])
400
+ ; CHECK-NEXT: [[MUL:%.*]] = extractvalue { i8, i1 } [[MUL_UOV]], 0
401
+ ; CHECK-NEXT: [[UOV:%.*]] = extractvalue { i8, i1 } [[MUL_UOV]], 1
402
+ ; CHECK-NEXT: call void @use.i1(i1 [[UOV]])
403
+ ; CHECK-NEXT: call void @use.i8(i8 [[MUL]])
404
+ ; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[MUL]], 0
405
+ ; CHECK-NEXT: ret i1 [[R]]
406
+ ;
407
+ %x = or i8 %xx , 2
408
+ %y = add nuw i8 %yy , 1
409
+
410
+ %mul_uov = call { i8 , i1 } @llvm.umul.with.overflow (i8 %x , i8 %y )
411
+ %mul = extractvalue { i8 , i1 } %mul_uov , 0
412
+ %uov = extractvalue { i8 , i1 } %mul_uov , 1
413
+ call void @use.i1 (i1 %uov )
414
+ call void @use.i8 (i8 %mul )
415
+ %r = icmp eq i8 %mul , 0
416
+ ret i1 %r
417
+ }
418
+
419
+ define i1 @extract_value_smul (i8 %xx , i8 %yy ) {
420
+ ; CHECK-LABEL: @extract_value_smul(
421
+ ; CHECK-NEXT: [[X:%.*]] = or i8 [[XX:%.*]], 1
422
+ ; CHECK-NEXT: [[Y:%.*]] = add nuw i8 [[YY:%.*]], 1
423
+ ; CHECK-NEXT: [[MUL_SOV:%.*]] = call { i8, i1 } @llvm.smul.with.overflow.i8(i8 [[Y]], i8 [[X]])
424
+ ; CHECK-NEXT: [[MUL:%.*]] = extractvalue { i8, i1 } [[MUL_SOV]], 0
425
+ ; CHECK-NEXT: [[SOV:%.*]] = extractvalue { i8, i1 } [[MUL_SOV]], 1
426
+ ; CHECK-NEXT: call void @use.i1(i1 [[SOV]])
427
+ ; CHECK-NEXT: call void @use.i8(i8 [[MUL]])
428
+ ; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[MUL]], 0
429
+ ; CHECK-NEXT: ret i1 [[R]]
430
+ ;
431
+ %x = or i8 %xx , 1
432
+ %y = add nuw i8 %yy , 1
433
+
434
+ %mul_sov = call { i8 , i1 } @llvm.smul.with.overflow (i8 %y , i8 %x )
435
+ %mul = extractvalue { i8 , i1 } %mul_sov , 0
436
+ %sov = extractvalue { i8 , i1 } %mul_sov , 1
437
+ call void @use.i1 (i1 %sov )
438
+ call void @use.i8 (i8 %mul )
439
+ %r = icmp eq i8 %mul , 0
440
+ ret i1 %r
441
+ }
442
+
443
+ define i1 @extract_value_smul_fail (i8 %xx , i8 %yy ) {
444
+ ; CHECK-LABEL: @extract_value_smul_fail(
445
+ ; CHECK-NEXT: [[X:%.*]] = or i8 [[XX:%.*]], 1
446
+ ; CHECK-NEXT: [[Y:%.*]] = add i8 [[YY:%.*]], 1
447
+ ; CHECK-NEXT: [[MUL_SOV:%.*]] = call { i8, i1 } @llvm.smul.with.overflow.i8(i8 [[Y]], i8 [[X]])
448
+ ; CHECK-NEXT: [[MUL:%.*]] = extractvalue { i8, i1 } [[MUL_SOV]], 0
449
+ ; CHECK-NEXT: [[SOV:%.*]] = extractvalue { i8, i1 } [[MUL_SOV]], 1
450
+ ; CHECK-NEXT: call void @use.i1(i1 [[SOV]])
451
+ ; CHECK-NEXT: call void @use.i8(i8 [[MUL]])
452
+ ; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[MUL]], 0
453
+ ; CHECK-NEXT: ret i1 [[R]]
454
+ ;
455
+ %x = or i8 %xx , 1
456
+ %y = add i8 %yy , 1
457
+
458
+ %mul_sov = call { i8 , i1 } @llvm.smul.with.overflow (i8 %y , i8 %x )
459
+ %mul = extractvalue { i8 , i1 } %mul_sov , 0
460
+ %sov = extractvalue { i8 , i1 } %mul_sov , 1
461
+ call void @use.i1 (i1 %sov )
462
+ call void @use.i8 (i8 %mul )
463
+ %r = icmp eq i8 %mul , 0
464
+ ret i1 %r
465
+ }
0 commit comments