235
235
}
236
236
237
237
; Make sure the store in %bb3 won't be eliminated because it may be clobbered before.
238
- define void @test8 (i32* noalias %P ) {
238
+ define void @test8 (i32* %P ) {
239
239
; CHECK-LABEL: @test8(
240
240
; CHECK-NEXT: store i32 0, i32* [[P:%.*]], align 4
241
241
; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
@@ -287,6 +287,197 @@ bb3:
287
287
ret void
288
288
}
289
289
290
+ ; The store in bb3 can be eliminated, because the store in bb1 cannot alias it.
291
+ define void @test10 (i32* noalias %P , i32* %Q , i1 %c ) {
292
+ ; CHECK-LABEL: @test10(
293
+ ; CHECK-NEXT: store i32 0, i32* [[P:%.*]], align 4
294
+ ; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
295
+ ; CHECK: bb1:
296
+ ; CHECK-NEXT: store i32 10, i32* [[Q:%.*]], align 4
297
+ ; CHECK-NEXT: br label [[BB3:%.*]]
298
+ ; CHECK: bb2:
299
+ ; CHECK-NEXT: ret void
300
+ ; CHECK: bb3:
301
+ ; CHECK-NEXT: store i32 0, i32* [[P]], align 4
302
+ ; CHECK-NEXT: ret void
303
+ ;
304
+ store i32 0 , i32* %P
305
+ br i1 %c , label %bb1 , label %bb2
306
+
307
+ bb1:
308
+ store i32 10 , i32* %Q
309
+ br label %bb3
310
+
311
+ bb2:
312
+ ret void
313
+
314
+ bb3:
315
+ store i32 0 , i32* %P
316
+ ret void
317
+ }
318
+
319
+ define void @test11_smaller_later_store (i32* noalias %P , i32* %Q , i1 %c ) {
320
+ ; CHECK-LABEL: @test11_smaller_later_store(
321
+ ; CHECK-NEXT: store i32 0, i32* [[P:%.*]], align 4
322
+ ; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
323
+ ; CHECK: bb1:
324
+ ; CHECK-NEXT: br label [[BB3:%.*]]
325
+ ; CHECK: bb2:
326
+ ; CHECK-NEXT: ret void
327
+ ; CHECK: bb3:
328
+ ; CHECK-NEXT: [[BC:%.*]] = bitcast i32* [[P]] to i8*
329
+ ; CHECK-NEXT: store i8 0, i8* [[BC]], align 1
330
+ ; CHECK-NEXT: ret void
331
+ ;
332
+ store i32 0 , i32* %P
333
+ br i1 %c , label %bb1 , label %bb2
334
+
335
+ bb1:
336
+ br label %bb3
337
+
338
+ bb2:
339
+ ret void
340
+
341
+ bb3:
342
+ %bc = bitcast i32* %P to i8*
343
+ store i8 0 , i8* %bc
344
+ ret void
345
+ }
346
+
347
+ define void @test11_smaller_earlier_store (i32* noalias %P , i32* %Q , i1 %c ) {
348
+ ; CHECK-LABEL: @test11_smaller_earlier_store(
349
+ ; CHECK-NEXT: [[BC:%.*]] = bitcast i32* [[P:%.*]] to i8*
350
+ ; CHECK-NEXT: store i8 0, i8* [[BC]], align 1
351
+ ; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
352
+ ; CHECK: bb1:
353
+ ; CHECK-NEXT: br label [[BB3:%.*]]
354
+ ; CHECK: bb2:
355
+ ; CHECK-NEXT: ret void
356
+ ; CHECK: bb3:
357
+ ; CHECK-NEXT: store i32 0, i32* [[P]], align 4
358
+ ; CHECK-NEXT: ret void
359
+ ;
360
+ %bc = bitcast i32* %P to i8*
361
+ store i8 0 , i8* %bc
362
+ br i1 %c , label %bb1 , label %bb2
363
+
364
+ bb1:
365
+ br label %bb3
366
+
367
+ bb2:
368
+ ret void
369
+
370
+ bb3:
371
+ store i32 0 , i32* %P
372
+ ret void
373
+ }
374
+
375
+ declare void @llvm.memset.p0i8.i64 (i8* nocapture writeonly , i8 , i64 , i1 immarg) #1
376
+
377
+ define void @test12_memset_simple (i8* %ptr ) {
378
+ ; CHECK-LABEL: @test12_memset_simple(
379
+ ; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[PTR:%.*]], i8 0, i64 10, i1 false)
380
+ ; CHECK-NEXT: [[PTR_5:%.*]] = getelementptr i8, i8* [[PTR]], i64 4
381
+ ; CHECK-NEXT: store i8 0, i8* [[PTR_5]], align 1
382
+ ; CHECK-NEXT: ret void
383
+ ;
384
+ call void @llvm.memset.p0i8.i64 (i8* %ptr , i8 0 , i64 10 , i1 false )
385
+ %ptr.5 = getelementptr i8 , i8* %ptr , i64 4
386
+ store i8 0 , i8* %ptr.5
387
+ ret void
388
+ }
389
+
390
+ define void @test12_memset_other_store_in_between (i8* %ptr ) {
391
+ ; CHECK-LABEL: @test12_memset_other_store_in_between(
392
+ ; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[PTR:%.*]], i8 0, i64 10, i1 false)
393
+ ; CHECK-NEXT: [[PTR_4:%.*]] = getelementptr i8, i8* [[PTR]], i64 4
394
+ ; CHECK-NEXT: store i8 8, i8* [[PTR_4]], align 1
395
+ ; CHECK-NEXT: [[PTR_5:%.*]] = getelementptr i8, i8* [[PTR]], i64 5
396
+ ; CHECK-NEXT: store i8 0, i8* [[PTR_5]], align 1
397
+ ; CHECK-NEXT: ret void
398
+ ;
399
+ call void @llvm.memset.p0i8.i64 (i8* %ptr , i8 0 , i64 10 , i1 false )
400
+ %ptr.4 = getelementptr i8 , i8* %ptr , i64 4
401
+ store i8 8 , i8* %ptr.4
402
+ %ptr.5 = getelementptr i8 , i8* %ptr , i64 5
403
+ store i8 0 , i8* %ptr.5
404
+ ret void
405
+ }
406
+
407
+ define void @test12_memset_other_store_in_between_partial_overlap (i8* %ptr ) {
408
+ ; CHECK-LABEL: @test12_memset_other_store_in_between_partial_overlap(
409
+ ; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[PTR:%.*]], i8 0, i64 10, i1 false)
410
+ ; CHECK-NEXT: [[PTR_4:%.*]] = getelementptr i8, i8* [[PTR]], i64 4
411
+ ; CHECK-NEXT: [[BC_4:%.*]] = bitcast i8* [[PTR_4]] to i16*
412
+ ; CHECK-NEXT: store i16 8, i16* [[BC_4]], align 2
413
+ ; CHECK-NEXT: [[PTR_5:%.*]] = getelementptr i8, i8* [[PTR]], i64 5
414
+ ; CHECK-NEXT: [[BC_5:%.*]] = bitcast i8* [[PTR_5]] to i16*
415
+ ; CHECK-NEXT: store i16 0, i16* [[BC_5]], align 2
416
+ ; CHECK-NEXT: ret void
417
+ ;
418
+ call void @llvm.memset.p0i8.i64 (i8* %ptr , i8 0 , i64 10 , i1 false )
419
+ %ptr.4 = getelementptr i8 , i8* %ptr , i64 4
420
+ %bc.4 = bitcast i8* %ptr.4 to i16*
421
+ store i16 8 , i16* %bc.4
422
+ %ptr.5 = getelementptr i8 , i8* %ptr , i64 5
423
+ %bc.5 = bitcast i8* %ptr.5 to i16*
424
+ store i16 0 , i16* %bc.5
425
+ ret void
426
+ }
427
+
428
+ define void @test12_memset_later_store_exceeds_memset (i8* %ptr ) {
429
+ ; CHECK-LABEL: @test12_memset_later_store_exceeds_memset(
430
+ ; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 1 [[PTR:%.*]], i8 0, i64 8, i1 false)
431
+ ; CHECK-NEXT: [[PTR_4:%.*]] = getelementptr i8, i8* [[PTR]], i64 4
432
+ ; CHECK-NEXT: store i8 8, i8* [[PTR_4]], align 1
433
+ ; CHECK-NEXT: [[PTR_5:%.*]] = getelementptr i8, i8* [[PTR]], i64 8
434
+ ; CHECK-NEXT: [[BC:%.*]] = bitcast i8* [[PTR_5]] to i64*
435
+ ; CHECK-NEXT: store i64 0, i64* [[BC]], align 8
436
+ ; CHECK-NEXT: ret void
437
+ ;
438
+ call void @llvm.memset.p0i8.i64 (i8* %ptr , i8 0 , i64 10 , i1 false )
439
+ %ptr.4 = getelementptr i8 , i8* %ptr , i64 4
440
+ store i8 8 , i8* %ptr.4
441
+ %ptr.5 = getelementptr i8 , i8* %ptr , i64 8
442
+ %bc = bitcast i8* %ptr.5 to i64*
443
+ store i64 0 , i64* %bc
444
+ ret void
445
+ }
446
+
447
+ define void @test12_memset_later_store_before_memset (i8* %ptr ) {
448
+ ; CHECK-LABEL: @test12_memset_later_store_before_memset(
449
+ ; CHECK-NEXT: [[PTR_1:%.*]] = getelementptr i8, i8* [[PTR:%.*]], i64 1
450
+ ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, i8* [[PTR_1]], i64 7
451
+ ; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 1 [[TMP1]], i8 0, i64 3, i1 false)
452
+ ; CHECK-NEXT: [[BC:%.*]] = bitcast i8* [[PTR]] to i64*
453
+ ; CHECK-NEXT: store i64 0, i64* [[BC]], align 8
454
+ ; CHECK-NEXT: ret void
455
+ ;
456
+ %ptr.1 = getelementptr i8 , i8* %ptr , i64 1
457
+ call void @llvm.memset.p0i8.i64 (i8* %ptr.1 , i8 0 , i64 10 , i1 false )
458
+ %ptr.4 = getelementptr i8 , i8* %ptr , i64 4
459
+ store i8 8 , i8* %ptr.4
460
+ %bc = bitcast i8* %ptr to i64*
461
+ store i64 0 , i64* %bc
462
+ ret void
463
+ }
464
+
465
+ ; The memset will be shortened and the store will not be redundant afterwards.
466
+ ; It cannot be eliminated.
467
+ define void @test13_memset_shortened (i64* %ptr ) {
468
+ ; CHECK-LABEL: @test13_memset_shortened(
469
+ ; CHECK-NEXT: [[PTR_I8:%.*]] = bitcast i64* [[PTR:%.*]] to i8*
470
+ ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, i8* [[PTR_I8]], i64 8
471
+ ; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 1 [[TMP1]], i8 0, i64 16, i1 false)
472
+ ; CHECK-NEXT: store i64 0, i64* [[PTR]], align 8
473
+ ; CHECK-NEXT: ret void
474
+ ;
475
+ %ptr.i8 = bitcast i64* %ptr to i8*
476
+ call void @llvm.memset.p0i8.i64 (i8* %ptr.i8 , i8 0 , i64 24 , i1 false )
477
+ store i64 0 , i64* %ptr
478
+ ret void
479
+ }
480
+
290
481
define void @pr49927 (i32* %q , i32* %p ) {
291
482
; CHECK-LABEL: @pr49927(
292
483
; CHECK-NEXT: [[V:%.*]] = load i32, i32* [[P:%.*]], align 4
@@ -301,7 +492,6 @@ define void @pr49927(i32* %q, i32* %p) {
301
492
ret void
302
493
}
303
494
304
-
305
495
define void @pr50339 (i8* nocapture readonly %0 ) {
306
496
; CHECK-LABEL: @pr50339(
307
497
; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* noundef nonnull align 16 dereferenceable(16) getelementptr inbounds ([32 x i8], [32 x i8]* @a, i64 0, i64 0), i8* noundef nonnull align 1 dereferenceable(16) [[TMP0:%.*]], i64 16, i1 false)
0 commit comments