brintos

brintos / llvm-project-archived public Read only

0
0
Text · 26.7 KiB · 4f38027 Raw
789 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes=dse -dse-optimize-memoryssa=false -S %s | FileCheck --check-prefixes=CHECK,UNOPT %s3; RUN: opt -passes=dse -dse-optimize-memoryssa -S %s | FileCheck --check-prefixes=CHECK,OPT %s4; RUN: opt -passes=dse -S %s | FileCheck --check-prefixes=CHECK,OPT %s5 6target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"7 8@a = external global [32 x i8], align 169 10declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg)11 12; Test case for PR16520. The store in %if.then is redundant, because the same value13; has been stored earlier to the same location.14define void @test1_pr16520(i1 %b, ptr nocapture %r) {15; CHECK-LABEL: @test1_pr16520(16; CHECK-NEXT:  entry:17; CHECK-NEXT:    store i8 1, ptr [[R:%.*]], align 118; CHECK-NEXT:    br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]19; CHECK:       if.then:20; CHECK-NEXT:    tail call void @fn_mayread_or_clobber()21; CHECK-NEXT:    br label [[IF_END:%.*]]22; CHECK:       if.else:23; CHECK-NEXT:    tail call void @fn_mayread_or_clobber()24; CHECK-NEXT:    br label [[IF_END]]25; CHECK:       if.end:26; CHECK-NEXT:    ret void27;28entry:29  store i8 1, ptr %r, align 130  br i1 %b, label %if.then, label %if.else31 32if.then:                                          ; preds = %entry33  store i8 1, ptr %r, align 134  tail call void @fn_mayread_or_clobber()35  br label %if.end36 37if.else:                                          ; preds = %entry38  tail call void @fn_mayread_or_clobber()39  br label %if.end40 41if.end:                                           ; preds = %if.else, %if.then42  ret void43}44 45declare void @fn_mayread_or_clobber()46declare void @fn_readonly() readonly47 48define void @test2(i1 %b, ptr nocapture %r) {49; CHECK-LABEL: @test2(50; CHECK-NEXT:  entry:51; CHECK-NEXT:    store i8 1, ptr [[R:%.*]], align 152; CHECK-NEXT:    br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]53; CHECK:       if.then:54; CHECK-NEXT:    tail call void @fn_readonly()55; CHECK-NEXT:    br label [[IF_END:%.*]]56; CHECK:       if.else:57; CHECK-NEXT:    tail call void @fn_readonly()58; CHECK-NEXT:    br label [[IF_END]]59; CHECK:       if.end:60; CHECK-NEXT:    ret void61;62entry:63  store i8 1, ptr %r, align 164  br i1 %b, label %if.then, label %if.else65 66if.then:                                          ; preds = %entry67  tail call void @fn_readonly()68  br label %if.end69 70if.else:                                          ; preds = %entry71  tail call void @fn_readonly()72  br label %if.end73 74if.end:                                           ; preds = %if.else, %if.then75  store i8 1, ptr %r, align 176  ret void77}78 79; Make sure volatile stores are not removed.80define void @test2_volatile(i1 %b, ptr nocapture %r) {81; CHECK-LABEL: @test2_volatile(82; CHECK-NEXT:  entry:83; CHECK-NEXT:    store volatile i8 1, ptr [[R:%.*]], align 184; CHECK-NEXT:    br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]85; CHECK:       if.then:86; CHECK-NEXT:    tail call void @fn_readonly()87; CHECK-NEXT:    br label [[IF_END:%.*]]88; CHECK:       if.else:89; CHECK-NEXT:    tail call void @fn_readonly()90; CHECK-NEXT:    br label [[IF_END]]91; CHECK:       if.end:92; CHECK-NEXT:    store volatile i8 1, ptr [[R]], align 193; CHECK-NEXT:    ret void94;95entry:96  store volatile i8 1, ptr %r, align 197  br i1 %b, label %if.then, label %if.else98 99if.then:                                          ; preds = %entry100  tail call void @fn_readonly()101  br label %if.end102 103if.else:                                          ; preds = %entry104  tail call void @fn_readonly()105  br label %if.end106 107if.end:                                           ; preds = %if.else, %if.then108  store volatile i8 1, ptr %r, align 1109  ret void110}111 112define void @test3(i1 %b, ptr nocapture %r) {113; CHECK-LABEL: @test3(114; CHECK-NEXT:  entry:115; CHECK-NEXT:    store i8 1, ptr [[R:%.*]], align 1116; CHECK-NEXT:    br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]117; CHECK:       if.then:118; CHECK-NEXT:    tail call void @fn_mayread_or_clobber()119; CHECK-NEXT:    br label [[IF_END:%.*]]120; CHECK:       if.else:121; CHECK-NEXT:    tail call void @fn_readonly()122; CHECK-NEXT:    br label [[IF_END]]123; CHECK:       if.end:124; CHECK-NEXT:    store i8 1, ptr [[R]], align 1125; CHECK-NEXT:    ret void126;127entry:128  store i8 1, ptr %r, align 1129  br i1 %b, label %if.then, label %if.else130 131if.then:                                          ; preds = %entry132  tail call void @fn_mayread_or_clobber()133  br label %if.end134 135if.else:                                          ; preds = %entry136  tail call void @fn_readonly()137  br label %if.end138 139if.end:                                           ; preds = %if.else, %if.then140  store i8 1, ptr %r, align 1141  ret void142}143 144define void @test4(i1 %b, ptr nocapture %r) {145; CHECK-LABEL: @test4(146; CHECK-NEXT:  entry:147; CHECK-NEXT:    store i8 1, ptr [[R:%.*]], align 1148; CHECK-NEXT:    br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]149; CHECK:       if.then:150; CHECK-NEXT:    tail call void @fn_readonly()151; CHECK-NEXT:    br label [[IF_END:%.*]]152; CHECK:       if.else:153; CHECK-NEXT:    tail call void @fn_mayread_or_clobber()154; CHECK-NEXT:    br label [[IF_END]]155; CHECK:       if.end:156; CHECK-NEXT:    store i8 1, ptr [[R]], align 1157; CHECK-NEXT:    ret void158;159entry:160  store i8 1, ptr %r, align 1161  br i1 %b, label %if.then, label %if.else162 163if.then:                                          ; preds = %entry164  tail call void @fn_readonly()165  br label %if.end166 167if.else:                                          ; preds = %entry168  tail call void @fn_mayread_or_clobber()169  br label %if.end170 171if.end:                                           ; preds = %if.else, %if.then172  store i8 1, ptr %r, align 1173  ret void174}175 176define void @test5(i1 %b, ptr nocapture %r) {177; CHECK-LABEL: @test5(178; CHECK-NEXT:  entry:179; CHECK-NEXT:    store i8 1, ptr [[R:%.*]], align 1180; CHECK-NEXT:    br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]181; CHECK:       if.then:182; CHECK-NEXT:    tail call void @fn_readonly()183; CHECK-NEXT:    br label [[IF_END:%.*]]184; CHECK:       if.else:185; CHECK-NEXT:    tail call void @fn_mayread_or_clobber()186; CHECK-NEXT:    br label [[IF_END]]187; CHECK:       if.end:188; CHECK-NEXT:    store i8 1, ptr [[R]], align 1189; CHECK-NEXT:    ret void190;191entry:192  store i8 1, ptr %r, align 1193  br i1 %b, label %if.then, label %if.else194 195if.then:                                          ; preds = %entry196  tail call void @fn_readonly()197  br label %if.end198 199if.else:                                          ; preds = %entry200  tail call void @fn_mayread_or_clobber()201  br label %if.end202 203if.end:                                           ; preds = %if.else, %if.then204  store i8 1, ptr %r, align 1205  ret void206}207 208declare i1 @cond() readnone209 210define void @test6(ptr noalias %P) {211; CHECK-LABEL: @test6(212; CHECK-NEXT:  entry:213; CHECK-NEXT:    br label [[FOR_HEADER:%.*]]214; CHECK:       for.header:215; CHECK-NEXT:    store i32 1, ptr [[P:%.*]], align 4216; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()217; CHECK-NEXT:    br i1 [[C1]], label [[FOR_BODY:%.*]], label [[END:%.*]]218; CHECK:       for.body:219; CHECK-NEXT:    [[LV:%.*]] = load i32, ptr [[P]], align 4220; CHECK-NEXT:    br label [[FOR_HEADER]]221; CHECK:       end:222; CHECK-NEXT:    store i32 3, ptr [[P]], align 4223; CHECK-NEXT:    ret void224;225entry:226  br label %for.header227 228for.header:229  store i32 1, ptr %P, align 4230  %c1 = call i1 @cond()231  br i1 %c1, label %for.body, label %end232 233for.body:234  store i32 1, ptr %P, align 4235  %lv = load i32, ptr %P236  br label %for.header237 238end:239  store i32 3, ptr %P, align 4240  ret void241}242 243; Make sure the store in %bb3 can be eliminated in the presences of early returns.244define void @test7(ptr noalias %P) {245; CHECK-LABEL: @test7(246; CHECK-NEXT:    store i32 0, ptr [[P:%.*]], align 4247; CHECK-NEXT:    br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]248; CHECK:       bb1:249; CHECK-NEXT:    br label [[BB3:%.*]]250; CHECK:       bb2:251; CHECK-NEXT:    ret void252; CHECK:       bb3:253; CHECK-NEXT:    ret void254;255  store i32 0, ptr %P256  br i1 true, label %bb1, label %bb2257bb1:258  br label %bb3259bb2:260  ret void261bb3:262  store i32 0, ptr %P263  ret void264}265 266; Make sure the store in %bb3 won't be eliminated because it may be clobbered before.267define void @test8(ptr %P) {268; CHECK-LABEL: @test8(269; CHECK-NEXT:    store i32 0, ptr [[P:%.*]], align 4270; CHECK-NEXT:    br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]271; CHECK:       bb1:272; CHECK-NEXT:    call void @fn_mayread_or_clobber()273; CHECK-NEXT:    br label [[BB3:%.*]]274; CHECK:       bb2:275; CHECK-NEXT:    ret void276; CHECK:       bb3:277; CHECK-NEXT:    store i32 0, ptr [[P]], align 4278; CHECK-NEXT:    ret void279;280  store i32 0, ptr %P281  br i1 true, label %bb1, label %bb2282bb1:283  call void @fn_mayread_or_clobber()284  br label %bb3285bb2:286  ret void287bb3:288  store i32 0, ptr %P289  ret void290}291 292; Make sure the store in %bb3 will be eliminated because only the early exit path293; may be clobbered.294define void @test9(ptr noalias %P) {295; CHECK-LABEL: @test9(296; CHECK-NEXT:    store i32 0, ptr [[P:%.*]], align 4297; CHECK-NEXT:    br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]298; CHECK:       bb1:299; CHECK-NEXT:    br label [[BB3:%.*]]300; CHECK:       bb2:301; CHECK-NEXT:    call void @fn_mayread_or_clobber()302; CHECK-NEXT:    ret void303; CHECK:       bb3:304; CHECK-NEXT:    ret void305;306  store i32 0, ptr %P307  br i1 true, label %bb1, label %bb2308bb1:309  br label %bb3310bb2:311  call void @fn_mayread_or_clobber()312  ret void313bb3:314  store i32 0, ptr %P315  ret void316}317 318; The store in bb3 can be eliminated, because the store in bb1 cannot alias it.319define void @test10(ptr noalias %P, ptr %Q, i1 %c) {320; UNOPT-LABEL: @test10(321; UNOPT-NEXT:    store i32 0, ptr [[P:%.*]], align 4322; UNOPT-NEXT:    br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]323; UNOPT:       bb1:324; UNOPT-NEXT:    store i32 10, ptr [[Q:%.*]], align 4325; UNOPT-NEXT:    br label [[BB3:%.*]]326; UNOPT:       bb2:327; UNOPT-NEXT:    ret void328; UNOPT:       bb3:329; UNOPT-NEXT:    store i32 0, ptr [[P]], align 4330; UNOPT-NEXT:    ret void331;332; OPT-LABEL: @test10(333; OPT-NEXT:    store i32 0, ptr [[P:%.*]], align 4334; OPT-NEXT:    br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]335; OPT:       bb1:336; OPT-NEXT:    store i32 10, ptr [[Q:%.*]], align 4337; OPT-NEXT:    br label [[BB3:%.*]]338; OPT:       bb2:339; OPT-NEXT:    ret void340; OPT:       bb3:341; OPT-NEXT:    ret void342;343  store i32 0, ptr %P344  br i1 %c, label %bb1, label %bb2345 346bb1:347  store i32 10, ptr %Q348  br label %bb3349 350bb2:351  ret void352 353bb3:354  store i32 0, ptr %P355  ret void356}357 358define void @test11_smaller_later_store(ptr noalias %P, ptr %Q, i1 %c) {359; CHECK-LABEL: @test11_smaller_later_store(360; CHECK-NEXT:    store i32 0, ptr [[P:%.*]], align 4361; CHECK-NEXT:    br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]362; CHECK:       bb1:363; CHECK-NEXT:    br label [[BB3:%.*]]364; CHECK:       bb2:365; CHECK-NEXT:    ret void366; CHECK:       bb3:367; CHECK-NEXT:    store i8 0, ptr [[P]], align 1368; CHECK-NEXT:    ret void369;370  store i32 0, ptr %P371  br i1 %c, label %bb1, label %bb2372 373bb1:374  br label %bb3375 376bb2:377  ret void378 379bb3:380  store i8 0, ptr %P381  ret void382}383 384define void @test11_smaller_earlier_store(ptr noalias %P, ptr %Q, i1 %c) {385; CHECK-LABEL: @test11_smaller_earlier_store(386; CHECK-NEXT:    store i8 0, ptr [[P:%.*]], align 1387; CHECK-NEXT:    br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]388; CHECK:       bb1:389; CHECK-NEXT:    br label [[BB3:%.*]]390; CHECK:       bb2:391; CHECK-NEXT:    ret void392; CHECK:       bb3:393; CHECK-NEXT:    store i32 0, ptr [[P]], align 4394; CHECK-NEXT:    ret void395;396  store i8 0, ptr %P397  br i1 %c, label %bb1, label %bb2398 399bb1:400  br label %bb3401 402bb2:403  ret void404 405bb3:406  store i32 0, ptr %P407  ret void408}409 410declare void @llvm.memset.p0.i64(ptr nocapture writeonly, i8, i64, i1 immarg) #1411 412define void @test12_memset_simple(ptr %ptr) {413; CHECK-LABEL: @test12_memset_simple(414; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr [[PTR:%.*]], i8 0, i64 10, i1 false)415; CHECK-NEXT:    ret void416;417  call void @llvm.memset.p0.i64(ptr %ptr, i8 0, i64 10, i1 false)418  %ptr.5 = getelementptr i8, ptr %ptr, i64 4419  store i8 0, ptr %ptr.5420  ret void421}422 423define void @test12_memset_other_store_in_between(ptr %ptr) {424; UNOPT-LABEL: @test12_memset_other_store_in_between(425; UNOPT-NEXT:    call void @llvm.memset.p0.i64(ptr [[PTR:%.*]], i8 0, i64 10, i1 false)426; UNOPT-NEXT:    [[PTR_4:%.*]] = getelementptr i8, ptr [[PTR]], i64 4427; UNOPT-NEXT:    store i8 8, ptr [[PTR_4]], align 1428; UNOPT-NEXT:    [[PTR_5:%.*]] = getelementptr i8, ptr [[PTR]], i64 5429; UNOPT-NEXT:    store i8 0, ptr [[PTR_5]], align 1430; UNOPT-NEXT:    ret void431;432; OPT-LABEL: @test12_memset_other_store_in_between(433; OPT-NEXT:    call void @llvm.memset.p0.i64(ptr [[PTR:%.*]], i8 0, i64 10, i1 false)434; OPT-NEXT:    [[PTR_4:%.*]] = getelementptr i8, ptr [[PTR]], i64 4435; OPT-NEXT:    store i8 8, ptr [[PTR_4]], align 1436; OPT-NEXT:    ret void437;438  call void @llvm.memset.p0.i64(ptr %ptr, i8 0, i64 10, i1 false)439  %ptr.4 = getelementptr i8, ptr %ptr, i64 4440  store i8 8, ptr %ptr.4441  %ptr.5 = getelementptr i8, ptr %ptr, i64 5442  store i8 0, ptr %ptr.5443  ret void444}445 446declare ptr @__memset_chk(ptr writeonly, i32, i64, i64) argmemonly writeonly nofree nounwind447 448define void @test12_memset_chk_other_store_in_between(ptr %ptr) {449; CHECK-LABEL: @test12_memset_chk_other_store_in_between(450; CHECK-NEXT:    [[CALL:%.*]] = tail call ptr @__memset_chk(ptr [[PTR:%.*]], i32 0, i64 10, i64 -1)451; CHECK-NEXT:    [[PTR_4:%.*]] = getelementptr i8, ptr [[PTR]], i64 4452; CHECK-NEXT:    store i8 8, ptr [[PTR_4]], align 1453; CHECK-NEXT:    [[PTR_5:%.*]] = getelementptr i8, ptr [[PTR]], i64 5454; CHECK-NEXT:    store i8 0, ptr [[PTR_5]], align 1455; CHECK-NEXT:    ret void456;457  %call = tail call ptr @__memset_chk(ptr %ptr, i32 0, i64 10, i64 -1)458  %ptr.4 = getelementptr i8, ptr %ptr, i64 4459  store i8 8, ptr %ptr.4460  %ptr.5 = getelementptr i8, ptr %ptr, i64 5461  store i8 0, ptr %ptr.5462  ret void463}464 465declare void @use(ptr)466 467define void @test12_memset_chk_other_store_in_between_stack_obj_escape_after(i64 %n) {468; CHECK-LABEL: @test12_memset_chk_other_store_in_between_stack_obj_escape_after(469; CHECK-NEXT:    [[OBJ:%.*]] = alloca [200 x i8], align 1470; CHECK-NEXT:    [[CALL:%.*]] = tail call ptr @__memset_chk(ptr [[OBJ]], i32 0, i64 10, i64 [[N:%.*]])471; CHECK-NEXT:    [[PTR_4:%.*]] = getelementptr i8, ptr [[OBJ]], i64 4472; CHECK-NEXT:    store i8 8, ptr [[PTR_4]], align 1473; CHECK-NEXT:    [[PTR_5:%.*]] = getelementptr i8, ptr [[OBJ]], i64 5474; CHECK-NEXT:    store i8 0, ptr [[PTR_5]], align 1475; CHECK-NEXT:    call void @use(ptr [[OBJ]])476; CHECK-NEXT:    ret void477;478  %obj = alloca [200 x i8]479  %call = tail call ptr @__memset_chk(ptr %obj, i32 0, i64 10, i64 %n)480  %ptr.4 = getelementptr i8, ptr %obj, i64 4481  store i8 8, ptr %ptr.4482  %ptr.5 = getelementptr i8, ptr %obj, i64 5483  store i8 0, ptr %ptr.5484  call void @use(ptr %obj)485  ret void486}487 488define void @test12_memset_chk_other_store_in_between_stack_obj_escape_before(i64 %n) {489; CHECK-LABEL: @test12_memset_chk_other_store_in_between_stack_obj_escape_before(490; CHECK-NEXT:    [[OBJ:%.*]] = alloca [200 x i8], align 1491; CHECK-NEXT:    call void @use(ptr [[OBJ]])492; CHECK-NEXT:    [[CALL:%.*]] = tail call ptr @__memset_chk(ptr [[OBJ]], i32 0, i64 10, i64 [[N:%.*]])493; CHECK-NEXT:    [[PTR_4:%.*]] = getelementptr i8, ptr [[OBJ]], i64 4494; CHECK-NEXT:    store i8 8, ptr [[PTR_4]], align 1495; CHECK-NEXT:    [[PTR_5:%.*]] = getelementptr i8, ptr [[OBJ]], i64 5496; CHECK-NEXT:    store i8 0, ptr [[PTR_5]], align 1497; CHECK-NEXT:    [[PTR_10:%.*]] = getelementptr i8, ptr [[OBJ]], i64 10498; CHECK-NEXT:    store i8 0, ptr [[PTR_10]], align 1499; CHECK-NEXT:    call void @use(ptr [[OBJ]])500; CHECK-NEXT:    ret void501;502  %obj = alloca [200 x i8]503  call void @use(ptr %obj)504  %call = tail call ptr @__memset_chk(ptr %obj, i32 0, i64 10, i64 %n)505  %ptr.4 = getelementptr i8, ptr %obj, i64 4506  store i8 8, ptr %ptr.4507  %ptr.5 = getelementptr i8, ptr %obj, i64 5508  store i8 0, ptr %ptr.5509  %ptr.10 = getelementptr i8, ptr %obj, i64 10510  store i8 0, ptr %ptr.10511  call void @use(ptr %obj)512  ret void513}514 515define void @test12_memset_other_store_in_between_partial_overlap(ptr %ptr) {516; CHECK-LABEL: @test12_memset_other_store_in_between_partial_overlap(517; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr [[PTR:%.*]], i8 0, i64 10, i1 false)518; CHECK-NEXT:    [[PTR_4:%.*]] = getelementptr i8, ptr [[PTR]], i64 4519; CHECK-NEXT:    store i16 8, ptr [[PTR_4]], align 2520; CHECK-NEXT:    [[PTR_5:%.*]] = getelementptr i8, ptr [[PTR]], i64 5521; CHECK-NEXT:    store i16 0, ptr [[PTR_5]], align 2522; CHECK-NEXT:    ret void523;524  call void @llvm.memset.p0.i64(ptr %ptr, i8 0, i64 10, i1 false)525  %ptr.4 = getelementptr i8, ptr %ptr, i64 4526  store i16 8, ptr %ptr.4527  %ptr.5 = getelementptr i8, ptr %ptr, i64 5528  store i16 0, ptr %ptr.5529  ret void530}531 532define void @test12_memset_later_store_exceeds_memset(ptr %ptr) {533; CHECK-LABEL: @test12_memset_later_store_exceeds_memset(534; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr align 1 [[PTR:%.*]], i8 0, i64 8, i1 false)535; CHECK-NEXT:    [[PTR_4:%.*]] = getelementptr i8, ptr [[PTR]], i64 4536; CHECK-NEXT:    store i8 8, ptr [[PTR_4]], align 1537; CHECK-NEXT:    [[PTR_5:%.*]] = getelementptr i8, ptr [[PTR]], i64 8538; CHECK-NEXT:    store i64 0, ptr [[PTR_5]], align 8539; CHECK-NEXT:    ret void540;541  call void @llvm.memset.p0.i64(ptr %ptr, i8 0, i64 10, i1 false)542  %ptr.4 = getelementptr i8, ptr %ptr, i64 4543  store i8 8, ptr %ptr.4544  %ptr.5 = getelementptr i8, ptr %ptr, i64 8545  store i64 0, ptr %ptr.5546  ret void547}548 549define void @test12_memset_later_store_before_memset(ptr %ptr) {550; CHECK-LABEL: @test12_memset_later_store_before_memset(551; CHECK-NEXT:    [[PTR_1:%.*]] = getelementptr i8, ptr [[PTR:%.*]], i64 1552; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[PTR_1]], i64 7553; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr align 1 [[TMP1]], i8 0, i64 3, i1 false)554; CHECK-NEXT:    store i64 0, ptr [[PTR]], align 8555; CHECK-NEXT:    ret void556;557  %ptr.1 = getelementptr i8, ptr %ptr, i64 1558  call void @llvm.memset.p0.i64(ptr %ptr.1, i8 0, i64 10, i1 false)559  %ptr.4 = getelementptr i8, ptr %ptr, i64 4560  store i8 8, ptr %ptr.4561  store i64 0, ptr %ptr562  ret void563}564 565; The memset will be shortened and the store will not be redundant afterwards.566; It cannot be eliminated.567define void @test13_memset_shortened(ptr %ptr) {568; CHECK-LABEL: @test13_memset_shortened(569; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[PTR:%.*]], i64 8570; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr align 1 [[TMP1]], i8 0, i64 16, i1 false)571; CHECK-NEXT:    store i64 0, ptr [[PTR]], align 8572; CHECK-NEXT:    ret void573;574  call void @llvm.memset.p0.i64(ptr %ptr, i8 0, i64 24, i1 false)575  store i64 0, ptr %ptr576  ret void577}578 579declare ptr @strcat(ptr, ptr) nounwind argmemonly580 581define void @test14_strcat(ptr noalias %P, ptr noalias %Q) {582; CHECK-LABEL: @test14_strcat(583; CHECK-NEXT:    [[CALL1:%.*]] = call ptr @strcat(ptr [[P:%.*]], ptr [[Q:%.*]])584; CHECK-NEXT:    [[CALL2:%.*]] = call ptr @strcat(ptr [[P]], ptr [[Q]])585; CHECK-NEXT:    ret void586;587  %call1 = call ptr @strcat(ptr %P, ptr %Q)588  ; FIXME: Eliminate the second strcat as a "store of existing value" for this particular case, where both strcat's are identical (same source, not just same dest).589  %call2 = call ptr @strcat(ptr %P, ptr %Q)590  ret void591}592 593define void @pr49927(ptr %q, ptr %p) {594; CHECK-LABEL: @pr49927(595; CHECK-NEXT:    [[V:%.*]] = load i32, ptr [[P:%.*]], align 4596; CHECK-NEXT:    store i32 [[V]], ptr [[Q:%.*]], align 4597; CHECK-NEXT:    store i32 [[V]], ptr [[P]], align 4598; CHECK-NEXT:    ret void599;600  %v = load i32, ptr %p, align 4601  store i32 %v, ptr %q, align 4602  store i32 %v, ptr %p, align 4603  ret void604}605 606define void @pr50339(ptr nocapture readonly %0) {607; CHECK-LABEL: @pr50339(608; CHECK-NEXT:    tail call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 16 dereferenceable(16) @a, ptr noundef nonnull align 1 dereferenceable(16) [[TMP0:%.*]], i64 16, i1 false)609; CHECK-NEXT:    tail call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 16 dereferenceable(16) @a, ptr noundef nonnull align 1 dereferenceable(16) [[TMP0]], i64 16, i1 false)610; CHECK-NEXT:    ret void611;612  tail call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 16 dereferenceable(16) @a, ptr noundef nonnull align 1 dereferenceable(16) %0, i64 16, i1 false)613  ; FIXME: Eliminate the second memcpy as a "store of existing value" for this particular case, where both memcpy's are identical (same source, not just same dest).614  tail call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 16 dereferenceable(16) @a, ptr noundef nonnull align 1 dereferenceable(16) %0, i64 16, i1 false)615  ret void616}617 618; Cannot remove the second memcpy as redundant store, because %src is modified619; in between.620define i8 @memset_optimized_access(ptr noalias %dst, ptr noalias %src) {621; CHECK-LABEL: @memset_optimized_access(622; CHECK-NEXT:    tail call void @llvm.memcpy.p0.p0.i64(ptr [[DST:%.*]], ptr [[SRC:%.*]], i64 16, i1 false)623; CHECK-NEXT:    store i8 99, ptr [[SRC]], align 1624; CHECK-NEXT:    [[L:%.*]] = load i8, ptr [[DST]], align 1625; CHECK-NEXT:    tail call void @llvm.memcpy.p0.p0.i64(ptr [[DST]], ptr [[SRC]], i64 16, i1 false)626; CHECK-NEXT:    ret i8 [[L]]627;628  tail call void @llvm.memcpy.p0.p0.i64(ptr %dst, ptr %src, i64 16, i1 false)629  store i8 99, ptr %src630  %l = load i8, ptr %dst631  tail call void @llvm.memcpy.p0.p0.i64(ptr %dst, ptr %src, i64 16, i1 false)632  ret i8 %l633}634 635; The @use() call is a later non-removable store, but should not affect the636; removal of the store in the if block.637define void @later_non_removable_store(i1 %c, ptr %p) {638; CHECK-LABEL: @later_non_removable_store(639; CHECK-NEXT:    store i8 1, ptr [[P:%.*]], align 1640; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF:%.*]], label [[EXIT:%.*]]641; CHECK:       if:642; CHECK-NEXT:    br label [[EXIT]]643; CHECK:       exit:644; CHECK-NEXT:    call void @use(ptr [[P]]) #[[ATTR7:[0-9]+]]645; CHECK-NEXT:    ret void646;647  store i8 1, ptr %p648  br i1 %c, label %if, label %exit649 650if:651  store i8 1, ptr %p652  br label %exit653 654exit:655  call void @use(ptr %p) argmemonly656  ret void657}658 659define void @scalable_scalable_redundant_store(ptr %ptr) {660; CHECK-LABEL: @scalable_scalable_redundant_store(661; CHECK-NEXT:    [[GEP_PTR_2:%.*]] = getelementptr i64, ptr [[PTR:%.*]], i64 2662; CHECK-NEXT:    store <vscale x 2 x i64> zeroinitializer, ptr [[GEP_PTR_2]], align 16663; CHECK-NEXT:    store <vscale x 4 x i64> zeroinitializer, ptr [[PTR]], align 32664; CHECK-NEXT:    ret void665;666  %gep.ptr.2 = getelementptr i64, ptr %ptr, i64 2667  store <vscale x 2 x i64> zeroinitializer, ptr %gep.ptr.2668  store <vscale x 4 x i64> zeroinitializer, ptr %ptr669  ret void670}671 672define void @scalable_scalable_neg(ptr %ptr) {673; CHECK-LABEL: @scalable_scalable_neg(674; CHECK-NEXT:    [[GEP_PTR_8:%.*]] = getelementptr i64, ptr [[PTR:%.*]], i64 8675; CHECK-NEXT:    store <vscale x 4 x i64> zeroinitializer, ptr [[GEP_PTR_8]], align 32676; CHECK-NEXT:    store <vscale x 2 x i64> zeroinitializer, ptr [[PTR]], align 16677; CHECK-NEXT:    ret void678;679  %gep.ptr.8 = getelementptr i64, ptr %ptr, i64 8680  store <vscale x 4 x i64> zeroinitializer, ptr %gep.ptr.8681  store <vscale x 2 x i64> zeroinitializer, ptr %ptr682  ret void683}684 685define void @scalable_scalable_nonconst_offset_neg(ptr %ptr, i64 %i) {686; CHECK-LABEL: @scalable_scalable_nonconst_offset_neg(687; CHECK-NEXT:    [[GEP_PTR_I:%.*]] = getelementptr i64, ptr [[PTR:%.*]], i64 [[I:%.*]]688; CHECK-NEXT:    store <vscale x 2 x i64> zeroinitializer, ptr [[GEP_PTR_I]], align 16689; CHECK-NEXT:    store <vscale x 4 x i64> zeroinitializer, ptr [[PTR]], align 32690; CHECK-NEXT:    ret void691;692  %gep.ptr.i = getelementptr i64, ptr %ptr, i64 %i693  store <vscale x 2 x i64> zeroinitializer, ptr %gep.ptr.i694  store <vscale x 4 x i64> zeroinitializer, ptr %ptr695  ret void696}697 698define void @scalable_fixed_redundant_store(ptr %ptr) vscale_range(1, 2) {699; CHECK-LABEL: @scalable_fixed_redundant_store(700; CHECK-NEXT:    [[GEP_PTR_2:%.*]] = getelementptr i64, ptr [[PTR:%.*]], i64 2701; CHECK-NEXT:    store <2 x i64> zeroinitializer, ptr [[GEP_PTR_2]], align 16702; CHECK-NEXT:    store <vscale x 4 x i64> zeroinitializer, ptr [[PTR]], align 32703; CHECK-NEXT:    ret void704;705  %gep.ptr.2 = getelementptr i64, ptr %ptr, i64 2706  store <2 x i64> zeroinitializer, ptr %gep.ptr.2707  store <vscale x 4 x i64> zeroinitializer, ptr %ptr708  ret void709}710 711define void @scalable_fixed_neg(ptr %ptr) vscale_range(1, 2) {712; CHECK-LABEL: @scalable_fixed_neg(713; CHECK-NEXT:    [[GEP_PTR_16:%.*]] = getelementptr i64, ptr [[PTR:%.*]], i64 16714; CHECK-NEXT:    store <2 x i64> zeroinitializer, ptr [[GEP_PTR_16]], align 16715; CHECK-NEXT:    store <vscale x 4 x i64> zeroinitializer, ptr [[PTR]], align 32716; CHECK-NEXT:    ret void717;718  %gep.ptr.16 = getelementptr i64, ptr %ptr, i64 16719  store <2 x i64> zeroinitializer, ptr %gep.ptr.16720  store <vscale x 4 x i64> zeroinitializer, ptr %ptr721  ret void722}723 724define void @fixed_scalable_redundant_store(ptr %ptr) vscale_range(1, 2) {725; CHECK-LABEL: @fixed_scalable_redundant_store(726; CHECK-NEXT:    [[GEP_PTR_2:%.*]] = getelementptr i64, ptr [[PTR:%.*]], i64 2727; CHECK-NEXT:    store <vscale x 2 x i64> zeroinitializer, ptr [[GEP_PTR_2]], align 16728; CHECK-NEXT:    store <8 x i64> zeroinitializer, ptr [[PTR]], align 64729; CHECK-NEXT:    ret void730;731  %gep.ptr.2 = getelementptr i64, ptr %ptr, i64 2732  store <vscale x 2 x i64> zeroinitializer, ptr %gep.ptr.2733  store <8 x i64> zeroinitializer, ptr %ptr734  ret void735}736 737define void @fixed_scalable_neg(ptr %ptr) vscale_range(1, 2) {738; CHECK-LABEL: @fixed_scalable_neg(739; CHECK-NEXT:    [[GEP_PTR_2:%.*]] = getelementptr i64, ptr [[PTR:%.*]], i64 2740; CHECK-NEXT:    store <vscale x 2 x i64> zeroinitializer, ptr [[GEP_PTR_2]], align 16741; CHECK-NEXT:    store <4 x i64> zeroinitializer, ptr [[PTR]], align 32742; CHECK-NEXT:    ret void743;744  %gep.ptr.2 = getelementptr i64, ptr %ptr, i64 2745  store <vscale x 2 x i64> zeroinitializer, ptr %gep.ptr.2746  store <4 x i64> zeroinitializer, ptr %ptr747  ret void748}749 750define void @memset_different_attributes_1(i1 %c, ptr %ptr) {751; CHECK-LABEL: @memset_different_attributes_1(752; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr [[PTR:%.*]], i8 0, i64 20, i1 false)753; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF:%.*]], label [[END:%.*]]754; CHECK:       if:755; CHECK-NEXT:    br label [[END]]756; CHECK:       end:757; CHECK-NEXT:    ret void758;759  call void @llvm.memset.p0.i64(ptr %ptr, i8 0, i64 20, i1 false)760  br i1 %c, label %if, label %end761 762if:763  call void @llvm.memset.p0.i64(ptr dereferenceable(20) %ptr, i8 0, i64 20, i1 false)764  br label %end765 766end:767  ret void768}769 770define void @memset_different_attributes_2(i1 %c, ptr %ptr) {771; CHECK-LABEL: @memset_different_attributes_2(772; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr dereferenceable(20) [[PTR:%.*]], i8 0, i64 20, i1 false)773; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF:%.*]], label [[END:%.*]]774; CHECK:       if:775; CHECK-NEXT:    br label [[END]]776; CHECK:       end:777; CHECK-NEXT:    ret void778;779  call void @llvm.memset.p0.i64(ptr dereferenceable(20) %ptr, i8 0, i64 20, i1 false)780  br i1 %c, label %if, label %end781 782if:783  call void @llvm.memset.p0.i64(ptr %ptr, i8 0, i64 20, i1 false)784  br label %end785 786end:787  ret void788}789