brintos

brintos / llvm-project-archived public Read only

0
0
Text · 28.5 KiB · 9d28395 Raw
891 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=dse -S | FileCheck %s3; RUN: opt < %s -aa-pipeline=basic-aa -passes=dse -S | FileCheck %s4target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"5 6declare void @llvm.memset.p0.i64(ptr nocapture, i8, i64, i1) nounwind7declare void @llvm.memset.element.unordered.atomic.p0.i64(ptr nocapture, i8, i64, i32) nounwind8declare void @llvm.memcpy.p0.p0.i64(ptr nocapture, ptr nocapture, i64, i1) nounwind9declare void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr nocapture, ptr nocapture, i64, i32) nounwind10declare void @llvm.init.trampoline(ptr, ptr, ptr)11declare void @llvm.matrix.column.major.store(<6 x float>, ptr, i64, i1, i32, i32)12 13define void @test1(ptr %Q, ptr %P) {14; CHECK-LABEL: @test1(15; CHECK-NEXT:    store i32 0, ptr [[P:%.*]], align 416; CHECK-NEXT:    ret void17;18  %DEAD = load i32, ptr %Q19  store i32 %DEAD, ptr %P20  store i32 0, ptr %P21  ret void22}23 24; PR867725@g = global i32 126 27define i32 @test3(ptr %g_addr) nounwind {28; CHECK-LABEL: @test3(29; CHECK-NEXT:    [[G_VALUE:%.*]] = load i32, ptr [[G_ADDR:%.*]], align 430; CHECK-NEXT:    store i32 -1, ptr @g, align 431; CHECK-NEXT:    store i32 [[G_VALUE]], ptr [[G_ADDR]], align 432; CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr @g, align 433; CHECK-NEXT:    ret i32 [[TMP3]]34;35  %g_value = load i32, ptr %g_addr, align 436  store i32 -1, ptr @g, align 437  store i32 %g_value, ptr %g_addr, align 438  %tmp3 = load i32, ptr @g, align 439  ret i32 %tmp340}41 42 43define void @test4(ptr %Q) {44; CHECK-LABEL: @test4(45; CHECK-NEXT:    [[A:%.*]] = load i32, ptr [[Q:%.*]], align 446; CHECK-NEXT:    store volatile i32 [[A]], ptr [[Q]], align 447; CHECK-NEXT:    ret void48;49  %a = load i32, ptr %Q50  store volatile i32 %a, ptr %Q51  ret void52}53 54; PR8576 - Should delete store of 10 even though p/q are may aliases.55define void @test2(ptr %p, ptr %q) {56; CHECK-LABEL: @test2(57; CHECK-NEXT:    store i32 20, ptr [[Q:%.*]], align 458; CHECK-NEXT:    store i32 30, ptr [[P:%.*]], align 459; CHECK-NEXT:    ret void60;61  store i32 10, ptr %p, align 462  store i32 20, ptr %q, align 463  store i32 30, ptr %p, align 464  ret void65}66 67; Should delete store of 10 even though memset is a may-store to P (P and Q may68; alias).69define void @test6(ptr %p, ptr %q) {70; CHECK-LABEL: @test6(71; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr [[Q:%.*]], i8 42, i64 900, i1 false)72; CHECK-NEXT:    store i32 30, ptr [[P:%.*]], align 473; CHECK-NEXT:    ret void74;75  store i32 10, ptr %p, align 4       ;; dead.76  call void @llvm.memset.p0.i64(ptr %q, i8 42, i64 900, i1 false)77  store i32 30, ptr %p, align 478  ret void79}80 81; Should delete store of 10 even though memset is a may-store to P (P and Q may82; alias).83define void @test6_atomic(ptr align 4 %p, ptr align 4 %q) {84; CHECK-LABEL: @test6_atomic(85; CHECK-NEXT:    call void @llvm.memset.element.unordered.atomic.p0.i64(ptr align 4 [[Q:%.*]], i8 42, i64 900, i32 4)86; CHECK-NEXT:    store atomic i32 30, ptr [[P:%.*]] unordered, align 487; CHECK-NEXT:    ret void88;89  store atomic i32 10, ptr %p unordered, align 4       ;; dead.90  call void @llvm.memset.element.unordered.atomic.p0.i64(ptr align 4 %q, i8 42, i64 900, i32 4)91  store atomic i32 30, ptr %p unordered, align 492  ret void93}94 95; Should delete store of 10 even though memcpy is a may-store to P (P and Q may96; alias).97define void @test7(ptr %p, ptr %q, ptr noalias %r) {98; CHECK-LABEL: @test7(99; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr [[Q:%.*]], ptr [[R:%.*]], i64 900, i1 false)100; CHECK-NEXT:    store i32 30, ptr [[P:%.*]], align 4101; CHECK-NEXT:    ret void102;103  store i32 10, ptr %p, align 4       ;; dead.104  call void @llvm.memcpy.p0.p0.i64(ptr %q, ptr %r, i64 900, i1 false)105  store i32 30, ptr %p, align 4106  ret void107}108 109; Should delete store of 10 even though memcpy is a may-store to P (P and Q may110; alias).111define void @test7_atomic(ptr align 4 %p, ptr align 4 %q, ptr noalias align 4 %r) {112; CHECK-LABEL: @test7_atomic(113; CHECK-NEXT:    call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 4 [[Q:%.*]], ptr align 4 [[R:%.*]], i64 900, i32 4)114; CHECK-NEXT:    store atomic i32 30, ptr [[P:%.*]] unordered, align 4115; CHECK-NEXT:    ret void116;117  store atomic i32 10, ptr %p unordered, align 4       ;; dead.118  call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 4 %q, ptr align 4 %r, i64 900, i32 4)119  store atomic i32 30, ptr %p unordered, align 4120  ret void121}122 123; Do not delete stores that are only partially killed.124define i32 @test8() {125; CHECK-LABEL: @test8(126; CHECK-NEXT:    [[V:%.*]] = alloca i32, align 4127; CHECK-NEXT:    store i32 1234567, ptr [[V]], align 4128; CHECK-NEXT:    [[X:%.*]] = load i32, ptr [[V]], align 4129; CHECK-NEXT:    ret i32 [[X]]130;131  %V = alloca i32132  store i32 1234567, ptr %V133  store i8 0, ptr %V134  %X = load i32, ptr %V135  ret i32 %X136 137}138 139; Test for byval handling.140%struct.x = type { i32, i32, i32, i32 }141define void @test9(ptr byval(%struct.x)  %a) nounwind  {142; CHECK-LABEL: @test9(143; CHECK-NEXT:    ret void144;145  store i32 1, ptr %a, align 4146  ret void147}148 149; Test for inalloca handling.150define void @test9_2(ptr inalloca(%struct.x) %a) nounwind {151; CHECK-LABEL: @test9_2(152; CHECK-NEXT:    ret void153;154  store i32 1, ptr %a, align 4155  ret void156}157 158; Test for preallocated handling.159define void @test9_3(ptr preallocated(%struct.x)  %a) nounwind  {160; CHECK-LABEL: @test9_3(161; CHECK-NEXT:    ret void162;163  store i32 1, ptr %a, align 4164  ret void165}166 167; va_arg has fuzzy dependence, the store shouldn't be zapped.168define double @test10(ptr %X) {169; CHECK-LABEL: @test10(170; CHECK-NEXT:    [[X_ADDR:%.*]] = alloca ptr, align 8171; CHECK-NEXT:    store ptr [[X:%.*]], ptr [[X_ADDR]], align 8172; CHECK-NEXT:    [[TMP_0:%.*]] = va_arg ptr [[X_ADDR]], double173; CHECK-NEXT:    ret double [[TMP_0]]174;175  %X_addr = alloca ptr176  store ptr %X, ptr %X_addr177  %tmp.0 = va_arg ptr %X_addr, double178  ret double %tmp.0179}180 181; DSE should delete the dead trampoline.182declare void @test11f()183define void @test11() {184; CHECK-LABEL: @test11(185; CHECK-NEXT:    ret void186;187  %storage = alloca [10 x i8], align 16		; <ptr> [#uses=1]188  %cast = getelementptr [10 x i8], ptr %storage, i32 0, i32 0		; <ptr> [#uses=1]189  call void @llvm.init.trampoline( ptr %cast, ptr @test11f, ptr null )		; <ptr> [#uses=1]190  ret void191}192 193; Specialized store intrinsics should be removed if dead.194define void @test_matrix_store(i64 %stride) {195; CHECK-LABEL: @test_matrix_store(196; CHECK-NEXT:    ret void197;198  %a = alloca [6 x float]199  call void @llvm.matrix.column.major.store(<6 x float> zeroinitializer, ptr %a, i64 %stride, i1 false, i32 3, i32 2)200  ret void201}202 203; %P doesn't escape, the DEAD instructions should be removed.204declare void @may_unwind()205define ptr @test_malloc_no_escape_before_return() {206; CHECK-LABEL: @test_malloc_no_escape_before_return(207; CHECK-NEXT:    [[PTR:%.*]] = tail call ptr @malloc(i64 4)208; CHECK-NEXT:    call void @may_unwind()209; CHECK-NEXT:    store i32 0, ptr [[PTR]], align 4210; CHECK-NEXT:    ret ptr [[PTR]]211;212  %ptr = tail call ptr @malloc(i64 4)213  %DEAD = load i32, ptr %ptr214  %DEAD2 = add i32 %DEAD, 1215  store i32 %DEAD2, ptr %ptr216  call void @may_unwind()217  store i32 0, ptr %ptr218  ret ptr %ptr219}220 221define ptr @test_custom_malloc_no_escape_before_return() {222; CHECK-LABEL: @test_custom_malloc_no_escape_before_return(223; CHECK-NEXT:    [[PTR:%.*]] = tail call ptr @custom_malloc(i32 4)224; CHECK-NEXT:    call void @may_unwind()225; CHECK-NEXT:    store i32 0, ptr [[PTR]], align 4226; CHECK-NEXT:    ret ptr [[PTR]]227;228  %ptr = tail call ptr @custom_malloc(i32 4)229  %DEAD = load i32, ptr %ptr230  %DEAD2 = add i32 %DEAD, 1231  store i32 %DEAD2, ptr %ptr232  call void @may_unwind()233  store i32 0, ptr %ptr234  ret ptr %ptr235}236 237define ptr addrspace(1) @test13_addrspacecast() {238; CHECK-LABEL: @test13_addrspacecast(239; CHECK-NEXT:    [[P:%.*]] = tail call ptr @malloc(i64 4)240; CHECK-NEXT:    [[P_AC:%.*]] = addrspacecast ptr [[P]] to ptr addrspace(1)241; CHECK-NEXT:    call void @may_unwind()242; CHECK-NEXT:    store i32 0, ptr addrspace(1) [[P_AC]], align 4243; CHECK-NEXT:    ret ptr addrspace(1) [[P_AC]]244;245  %p = tail call ptr @malloc(i64 4)246  %p.ac = addrspacecast ptr %p to ptr addrspace(1)247  %DEAD = load i32, ptr addrspace(1) %p.ac248  %DEAD2 = add i32 %DEAD, 1249  store i32 %DEAD2, ptr addrspace(1) %p.ac250  call void @may_unwind()251  store i32 0, ptr addrspace(1) %p.ac252  ret ptr addrspace(1) %p.ac253}254 255 256declare noalias ptr @malloc(i64) willreturn allockind("alloc,uninitialized")257declare noalias ptr @custom_malloc(i32) willreturn258declare noalias ptr @calloc(i64, i64) willreturn allockind("alloc,zeroed")259 260define void @test14(ptr %Q) {261; CHECK-LABEL: @test14(262; CHECK-NEXT:    ret void263;264  %P = alloca i32265  %DEAD = load i32, ptr %Q266  store i32 %DEAD, ptr %P267  ret void268 269}270 271; The store here is not dead because the byval call reads it.272declare void @test19f(ptr byval({i32}) align 4 %P)273 274define void @test19(ptr nocapture byval({i32}) align 4 %arg5) nounwind ssp {275; CHECK-LABEL: @test19(276; CHECK-NEXT:  bb:277; CHECK-NEXT:    store i32 912, ptr [[ARG5:%.*]], align 4278; CHECK-NEXT:    call void @test19f(ptr byval({ i32 }) align 4 [[ARG5]])279; CHECK-NEXT:    ret void280;281bb:282  store i32 912, ptr %arg5283  call void @test19f(ptr byval({i32}) align 4 %arg5)284  ret void285 286}287 288define void @malloc_no_escape() {289; CHECK-LABEL: @malloc_no_escape(290; CHECK-NEXT:    ret void291;292  %m = call ptr @malloc(i64 24)293  store i8 0, ptr %m294  ret void295}296 297define void @custom_malloc_no_escape() {298; CHECK-LABEL: @custom_malloc_no_escape(299; CHECK-NEXT:    [[M:%.*]] = call ptr @custom_malloc(i32 24)300; CHECK-NEXT:    ret void301;302  %m = call ptr @custom_malloc(i32 24)303  store i8 0, ptr %m304  ret void305}306 307declare void @use.ptr(ptr)308 309define void @malloc_no_escape_via_attr() {310; CHECK-LABEL: @malloc_no_escape_via_attr(311; CHECK-NEXT:    [[M:%.*]] = call ptr @malloc(i64 24)312; CHECK-NEXT:    call void @use.ptr(ptr captures(none) [[M]])313; CHECK-NEXT:    ret void314;315  %m = call ptr @malloc(i64 24)316  call void @use.ptr(ptr captures(none) %m)317  store i8 0, ptr %m318  ret void319}320 321define void @malloc_address_only_escape() {322; CHECK-LABEL: @malloc_address_only_escape(323; CHECK-NEXT:    [[M:%.*]] = call ptr @malloc(i64 24)324; CHECK-NEXT:    call void @use.ptr(ptr captures(address) [[M]])325; CHECK-NEXT:    ret void326;327  %m = call ptr @malloc(i64 24)328  call void @use.ptr(ptr captures(address) %m)329  store i8 0, ptr %m330  ret void331}332 333define void @malloc_provenance_escape() {334; CHECK-LABEL: @malloc_provenance_escape(335; CHECK-NEXT:    [[M:%.*]] = call ptr @malloc(i64 24)336; CHECK-NEXT:    call void @use.ptr(ptr captures(provenance) [[M]])337; CHECK-NEXT:    store i8 0, ptr [[M]], align 1338; CHECK-NEXT:    ret void339;340  %m = call ptr @malloc(i64 24)341  call void @use.ptr(ptr captures(provenance) %m)342  store i8 0, ptr %m343  ret void344}345 346define void @malloc_read_provenance_escape() {347; CHECK-LABEL: @malloc_read_provenance_escape(348; CHECK-NEXT:    [[M:%.*]] = call ptr @malloc(i64 24)349; CHECK-NEXT:    call void @use.ptr(ptr captures(read_provenance) [[M]])350; CHECK-NEXT:    store i8 0, ptr [[M]], align 1351; CHECK-NEXT:    ret void352;353  %m = call ptr @malloc(i64 24)354  call void @use.ptr(ptr captures(read_provenance) %m)355  store i8 0, ptr %m356  ret void357}358 359define void @test21() {360; CHECK-LABEL: @test21(361; CHECK-NEXT:    ret void362;363  %m = call ptr @calloc(i64 9, i64 7)364  store i8 0, ptr %m365  ret void366}367 368; Currently elimination of stores at the end of a function is limited to a369; single underlying object, for compile-time. This case appears to not be370; very important in practice.371define void @test22(i1 %i, i32 %k, i32 %m) nounwind {372; CHECK-LABEL: @test22(373; CHECK-NEXT:    [[K_ADDR:%.*]] = alloca i32, align 4374; CHECK-NEXT:    [[M_ADDR:%.*]] = alloca i32, align 4375; CHECK-NEXT:    [[K_ADDR_M_ADDR:%.*]] = select i1 [[I:%.*]], ptr [[K_ADDR]], ptr [[M_ADDR]]376; CHECK-NEXT:    store i32 0, ptr [[K_ADDR_M_ADDR]], align 4377; CHECK-NEXT:    ret void378;379  %k.addr = alloca i32380  %m.addr = alloca i32381  %k.addr.m.addr = select i1 %i, ptr %k.addr, ptr %m.addr382  store i32 0, ptr %k.addr.m.addr, align 4383  ret void384}385 386; PR13547387declare noalias ptr @strdup(ptr nocapture) nounwind388define noalias ptr @test23() nounwind uwtable ssp {389; CHECK-LABEL: @test23(390; CHECK-NEXT:    [[X:%.*]] = alloca [2 x i8], align 1391; CHECK-NEXT:    store i8 97, ptr [[X]], align 1392; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds [2 x i8], ptr [[X]], i64 0, i64 1393; CHECK-NEXT:    store i8 0, ptr [[ARRAYIDX1]], align 1394; CHECK-NEXT:    [[CALL:%.*]] = call ptr @strdup(ptr [[X]]) #[[ATTR5:[0-9]+]]395; CHECK-NEXT:    ret ptr [[CALL]]396;397  %x = alloca [2 x i8], align 1398  store i8 97, ptr %x, align 1399  %arrayidx1 = getelementptr inbounds [2 x i8], ptr %x, i64 0, i64 1400  store i8 0, ptr %arrayidx1, align 1401  %call = call ptr @strdup(ptr %x) nounwind402  ret ptr %call403}404 405; Make sure same sized store to later element is deleted406define void @test24(ptr %a, i32 %b, i32 %c) nounwind {407; CHECK-LABEL: @test24(408; CHECK-NEXT:    store i32 [[B:%.*]], ptr [[A:%.*]], align 4409; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds [2 x i32], ptr [[A]], i64 0, i64 1410; CHECK-NEXT:    store i32 [[C:%.*]], ptr [[TMP1]], align 4411; CHECK-NEXT:    ret void412;413  store i32 0, ptr %a, align 4414  %1 = getelementptr inbounds [2 x i32], ptr %a, i64 0, i64 1415  store i32 0, ptr %1, align 4416  store i32 %b, ptr %a, align 4417  %2 = getelementptr inbounds [2 x i32], ptr %a, i64 0, i64 1418  store i32 %c, ptr %2, align 4419  ret void420}421 422; Check another case like PR13547 where strdup is not like malloc.423define ptr @test25(ptr %p) nounwind {424; CHECK-LABEL: @test25(425; CHECK-NEXT:    [[P_4:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 4426; CHECK-NEXT:    [[TMP:%.*]] = load i8, ptr [[P_4]], align 1427; CHECK-NEXT:    store i8 0, ptr [[P_4]], align 1428; CHECK-NEXT:    [[Q:%.*]] = call ptr @strdup(ptr [[P]]) #[[ATTR14:[0-9]+]]429; CHECK-NEXT:    store i8 [[TMP]], ptr [[P_4]], align 1430; CHECK-NEXT:    ret ptr [[Q]]431;432  %p.4 = getelementptr i8, ptr %p, i64 4433  %tmp = load i8, ptr %p.4, align 1434  store i8 0, ptr %p.4, align 1435  %q = call ptr @strdup(ptr %p) nounwind optsize436  store i8 %tmp, ptr %p.4, align 1437  ret ptr %q438}439 440; Don't remove redundant store because of may-aliased store.441define i32 @test28(i1 %c, ptr %p, ptr %p2, i32 %i) {442; CHECK-LABEL: @test28(443; CHECK-NEXT:  entry:444; CHECK-NEXT:    [[V:%.*]] = load i32, ptr [[P:%.*]], align 4445; CHECK-NEXT:    store i32 [[I:%.*]], ptr [[P2:%.*]], align 4446; CHECK-NEXT:    br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]447; CHECK:       bb1:448; CHECK-NEXT:    br label [[BB3:%.*]]449; CHECK:       bb2:450; CHECK-NEXT:    br label [[BB3]]451; CHECK:       bb3:452; CHECK-NEXT:    store i32 [[V]], ptr [[P]], align 4453; CHECK-NEXT:    ret i32 0454;455entry:456  %v = load i32, ptr %p, align 4457 458  ; Might overwrite value at %p459  store i32 %i, ptr %p2, align 4460  br i1 %c, label %bb1, label %bb2461bb1:462  br label %bb3463bb2:464  br label %bb3465bb3:466  store i32 %v, ptr %p, align 4467  ret i32 0468}469 470; Don't remove redundant store because of may-aliased store.471define i32 @test29(i1 %c, ptr %p, ptr %p2, i32 %i) {472; CHECK-LABEL: @test29(473; CHECK-NEXT:  entry:474; CHECK-NEXT:    [[V:%.*]] = load i32, ptr [[P:%.*]], align 4475; CHECK-NEXT:    br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]476; CHECK:       bb1:477; CHECK-NEXT:    br label [[BB3:%.*]]478; CHECK:       bb2:479; CHECK-NEXT:    store i32 [[I:%.*]], ptr [[P2:%.*]], align 4480; CHECK-NEXT:    br label [[BB3]]481; CHECK:       bb3:482; CHECK-NEXT:    store i32 [[V]], ptr [[P]], align 4483; CHECK-NEXT:    ret i32 0484;485entry:486  %v = load i32, ptr %p, align 4487  br i1 %c, label %bb1, label %bb2488bb1:489  br label %bb3490bb2:491  ; Might overwrite value at %p492  store i32 %i, ptr %p2, align 4493  br label %bb3494bb3:495  store i32 %v, ptr %p, align 4496  ret i32 0497}498 499declare void @unknown_func()500 501; Don't remove redundant store because of unknown call.502define i32 @test30(i1 %c, ptr %p, i32 %i) {503; CHECK-LABEL: @test30(504; CHECK-NEXT:  entry:505; CHECK-NEXT:    [[V:%.*]] = load i32, ptr [[P:%.*]], align 4506; CHECK-NEXT:    br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]507; CHECK:       bb1:508; CHECK-NEXT:    br label [[BB3:%.*]]509; CHECK:       bb2:510; CHECK-NEXT:    call void @unknown_func()511; CHECK-NEXT:    br label [[BB3]]512; CHECK:       bb3:513; CHECK-NEXT:    store i32 [[V]], ptr [[P]], align 4514; CHECK-NEXT:    ret i32 0515;516entry:517  %v = load i32, ptr %p, align 4518  br i1 %c, label %bb1, label %bb2519bb1:520  br label %bb3521bb2:522  ; Might overwrite value at %p523  call void @unknown_func()524  br label %bb3525bb3:526  store i32 %v, ptr %p, align 4527  ret i32 0528}529 530; Don't remove redundant store in a loop with a may-alias store.531define i32 @test32(i1 %c, ptr %p, i32 %i, i1 %arg) {532; CHECK-LABEL: @test32(533; CHECK-NEXT:  entry:534; CHECK-NEXT:    [[V:%.*]] = load i32, ptr [[P:%.*]], align 4535; CHECK-NEXT:    br label [[BB1:%.*]]536; CHECK:       bb1:537; CHECK-NEXT:    store i32 [[V]], ptr [[P]], align 4538; CHECK-NEXT:    call void @unknown_func()539; CHECK-NEXT:    br i1 [[ARG:%.*]], label [[BB1]], label [[BB2:%.*]]540; CHECK:       bb2:541; CHECK-NEXT:    ret i32 0542;543entry:544  %v = load i32, ptr %p, align 4545  br label %bb1546bb1:547  store i32 %v, ptr %p, align 4548  ; Might read and overwrite value at %p549  call void @unknown_func()550  br i1 %arg, label %bb1, label %bb2551bb2:552  ret i32 0553}554 555; We cannot remove any stores, because @unknown_func may unwind and the caller556; may read %p while unwinding.557define void @test34(ptr noalias %p) {558; CHECK-LABEL: @test34(559; CHECK-NEXT:    store i32 1, ptr [[P:%.*]], align 4560; CHECK-NEXT:    call void @unknown_func()561; CHECK-NEXT:    store i32 0, ptr [[P]], align 4562; CHECK-NEXT:    ret void563;564  store i32 1, ptr %p565  call void @unknown_func()566  store i32 0, ptr %p567  ret void568}569 570; Same as previous case, but with a dead_on_unwind argument.571define void @test34_dead_on_unwind(ptr noalias dead_on_unwind %p) {572; CHECK-LABEL: @test34_dead_on_unwind(573; CHECK-NEXT:    call void @unknown_func()574; CHECK-NEXT:    store i32 0, ptr [[P:%.*]], align 4575; CHECK-NEXT:    ret void576;577  store i32 1, ptr %p578  call void @unknown_func()579  store i32 0, ptr %p580  ret void581}582 583; Remove redundant store even with an unwinding function in the same block584define void @test35(ptr noalias %p) {585; CHECK-LABEL: @test35(586; CHECK-NEXT:    call void @unknown_func()587; CHECK-NEXT:    store i32 0, ptr [[P:%.*]], align 4588; CHECK-NEXT:    ret void589;590  call void @unknown_func()591  store i32 1, ptr %p592  store i32 0, ptr %p593  ret void594}595 596; We cannot optimize away the first memmove since %P could overlap with %Q.597define void @test36(ptr %P, ptr %Q) {598; CHECK-LABEL: @test36(599; CHECK-NEXT:    tail call void @llvm.memmove.p0.p0.i64(ptr [[P:%.*]], ptr [[Q:%.*]], i64 12, i1 false)600; CHECK-NEXT:    tail call void @llvm.memmove.p0.p0.i64(ptr [[P]], ptr [[Q]], i64 12, i1 false)601; CHECK-NEXT:    ret void602;603 604  tail call void @llvm.memmove.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)605  tail call void @llvm.memmove.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)606  ret void607}608 609define void @test36_atomic(ptr %P, ptr %Q) {610; CHECK-LABEL: @test36_atomic(611; CHECK-NEXT:    tail call void @llvm.memmove.element.unordered.atomic.p0.p0.i64(ptr align 1 [[P:%.*]], ptr align 1 [[Q:%.*]], i64 12, i32 1)612; CHECK-NEXT:    tail call void @llvm.memmove.element.unordered.atomic.p0.p0.i64(ptr align 1 [[P]], ptr align 1 [[Q]], i64 12, i32 1)613; CHECK-NEXT:    ret void614;615 616  tail call void @llvm.memmove.element.unordered.atomic.p0.p0.i64(ptr align 1 %P, ptr align 1 %Q, i64 12, i32 1)617  tail call void @llvm.memmove.element.unordered.atomic.p0.p0.i64(ptr align 1 %P, ptr align 1 %Q, i64 12, i32 1)618  ret void619}620 621define void @test37(ptr %P, ptr %Q, ptr %R) {622; CHECK-LABEL: @test37(623; CHECK-NEXT:    tail call void @llvm.memcpy.p0.p0.i64(ptr [[P:%.*]], ptr [[Q:%.*]], i64 12, i1 false)624; CHECK-NEXT:    tail call void @llvm.memmove.p0.p0.i64(ptr [[P]], ptr [[R:%.*]], i64 12, i1 false)625; CHECK-NEXT:    ret void626;627 628  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)629  tail call void @llvm.memmove.p0.p0.i64(ptr %P, ptr %R, i64 12, i1 false)630  ret void631}632 633define void @test37_atomic(ptr %P, ptr %Q, ptr %R) {634; CHECK-LABEL: @test37_atomic(635; CHECK-NEXT:    tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 1 [[P:%.*]], ptr align 1 [[Q:%.*]], i64 12, i32 1)636; CHECK-NEXT:    tail call void @llvm.memmove.element.unordered.atomic.p0.p0.i64(ptr align 1 [[P]], ptr align 1 [[R:%.*]], i64 12, i32 1)637; CHECK-NEXT:    ret void638;639 640  tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 1 %P, ptr align 1 %Q, i64 12, i32 1)641  tail call void @llvm.memmove.element.unordered.atomic.p0.p0.i64(ptr align 1 %P, ptr align 1 %R, i64 12, i32 1)642  ret void643}644 645; See PR11763 - LLVM allows memcpy's source and destination to be equal (but not646; inequal and overlapping).647define void @test38(ptr %P, ptr %Q, ptr %R) {648; CHECK-LABEL: @test38(649; CHECK-NEXT:    tail call void @llvm.memmove.p0.p0.i64(ptr [[P:%.*]], ptr [[Q:%.*]], i64 12, i1 false)650; CHECK-NEXT:    tail call void @llvm.memcpy.p0.p0.i64(ptr [[P]], ptr [[R:%.*]], i64 12, i1 false)651; CHECK-NEXT:    ret void652;653 654  tail call void @llvm.memmove.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)655  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %R, i64 12, i1 false)656  ret void657}658 659; See PR11763 - LLVM allows memcpy's source and destination to be equal (but not660; inequal and overlapping).661define void @test38_atomic(ptr %P, ptr %Q, ptr %R) {662; CHECK-LABEL: @test38_atomic(663; CHECK-NEXT:    tail call void @llvm.memmove.element.unordered.atomic.p0.p0.i64(ptr align 1 [[P:%.*]], ptr align 1 [[Q:%.*]], i64 12, i32 1)664; CHECK-NEXT:    tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 1 [[P]], ptr align 1 [[R:%.*]], i64 12, i32 1)665; CHECK-NEXT:    ret void666;667 668  tail call void @llvm.memmove.element.unordered.atomic.p0.p0.i64(ptr align 1 %P, ptr align 1 %Q, i64 12, i32 1)669  tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 1 %P, ptr align 1 %R, i64 12, i32 1)670  ret void671}672 673define void @test39(ptr %P, ptr %Q, ptr %R) {674; CHECK-LABEL: @test39(675; CHECK-NEXT:    tail call void @llvm.memcpy.p0.p0.i64(ptr [[P:%.*]], ptr [[Q:%.*]], i64 12, i1 false)676; CHECK-NEXT:    tail call void @llvm.memcpy.p0.p0.i64(ptr [[P]], ptr [[R:%.*]], i64 8, i1 false)677; CHECK-NEXT:    ret void678;679 680  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)681  tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %R, i64 8, i1 false)682  ret void683}684 685define void @test39_atomic(ptr %P, ptr %Q, ptr %R) {686; CHECK-LABEL: @test39_atomic(687; CHECK-NEXT:    tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 1 [[P:%.*]], ptr align 1 [[Q:%.*]], i64 12, i32 1)688; CHECK-NEXT:    tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 1 [[P]], ptr align 1 [[R:%.*]], i64 8, i32 1)689; CHECK-NEXT:    ret void690;691 692  tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 1 %P, ptr align 1 %Q, i64 12, i32 1)693  tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 1 %P, ptr align 1 %R, i64 8, i32 1)694  ret void695}696 697declare void @llvm.memmove.p0.p0.i64(ptr nocapture, ptr nocapture readonly, i64, i1)698declare void @llvm.memmove.element.unordered.atomic.p0.p0.i64(ptr nocapture, ptr nocapture readonly, i64, i32)699 700declare void @llvm.lifetime.start.p0(ptr nocapture) nounwind701declare void @llvm.lifetime.end.p0(ptr nocapture) nounwind702define void @test40(ptr noalias %Pp, ptr noalias %Q)  {703; CHECK-LABEL: @test40(704; CHECK-NEXT:  entry:705; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4706; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr nonnull [[A]])707; CHECK-NEXT:    [[PC:%.*]] = load ptr, ptr [[PP:%.*]], align 8708; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr nonnull align 4 [[A]], ptr align 4 [[Q:%.*]], i64 4, i1 false)709; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[PC]], ptr nonnull align 4 [[A]], i64 4, i1 true)710; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr nonnull [[A]])711; CHECK-NEXT:    ret void712;713entry:714  %A = alloca i32, align 4715  call void @llvm.lifetime.start.p0(ptr nonnull %A)716  %Pc = load ptr, ptr %Pp, align 8717  call void @llvm.memcpy.p0.p0.i64(ptr nonnull align 4 %A, ptr align 4 %Q, i64 4, i1 false)718  call void @llvm.memcpy.p0.p0.i64(ptr align 4 %Pc, ptr nonnull align 4 %A, i64 4, i1 true)719  call void @llvm.lifetime.end.p0(ptr nonnull %A)720  ret void721}722 723declare void @free(ptr nocapture) allockind("free")724 725; We cannot remove `store i32 1, ptr %p`, because @unknown_func may unwind726; and the caller may read %p while unwinding.727define void @test41(ptr noalias %P) {728; CHECK-LABEL: @test41(729; CHECK-NEXT:    store i32 1, ptr [[P:%.*]], align 4730; CHECK-NEXT:    call void @unknown_func()731; CHECK-NEXT:    call void @free(ptr [[P]])732; CHECK-NEXT:    ret void733;734  store i32 1, ptr %P735  call void @unknown_func()736  store i32 2, ptr %P737  call void @free(ptr %P)738  ret void739}740 741define void @test42(ptr %P, ptr %Q) {742; CHECK-LABEL: @test42(743; CHECK-NEXT:    store i32 1, ptr [[P:%.*]], align 4744; CHECK-NEXT:    store i32 2, ptr [[Q:%.*]], align 4745; CHECK-NEXT:    store i8 3, ptr [[P]], align 1746; CHECK-NEXT:    ret void747;748  store i32 1, ptr %P749  store i32 2, ptr %Q750  store i8 3, ptr %P751  ret void752}753 754define void @test42a(ptr %P, ptr %Q) {755; CHECK-LABEL: @test42a(756; CHECK-NEXT:    store atomic i32 1, ptr [[P:%.*]] unordered, align 4757; CHECK-NEXT:    store atomic i32 2, ptr [[Q:%.*]] unordered, align 4758; CHECK-NEXT:    store atomic i8 3, ptr [[P]] unordered, align 4759; CHECK-NEXT:    ret void760;761  store atomic i32 1, ptr %P unordered, align 4762  store atomic i32 2, ptr %Q unordered, align 4763  store atomic i8 3, ptr %P unordered, align 4764  ret void765}766 767define void @test43a(ptr %P, ptr noalias %Q) {768; CHECK-LABEL: @test43a(769; CHECK-NEXT:  entry:770; CHECK-NEXT:    store atomic i32 50331649, ptr [[P:%.*]] unordered, align 4771; CHECK-NEXT:    store atomic i32 2, ptr [[Q:%.*]] unordered, align 4772; CHECK-NEXT:    ret void773;774entry:775  store atomic i32 1, ptr %P unordered, align 4776  store atomic i32 2, ptr %Q unordered, align 4777  store atomic i8 3, ptr %P unordered, align 4778  ret void779}780 781; Some tests where volatile may block removing a store.782 783; Here we can remove the first non-volatile store. We cannot remove the784; volatile store.785define void @test44_volatile(ptr %P) {786; CHECK-LABEL: @test44_volatile(787; CHECK-NEXT:    store volatile i32 2, ptr [[P:%.*]], align 4788; CHECK-NEXT:    store i32 3, ptr [[P]], align 4789; CHECK-NEXT:    ret void790;791  store i32 1, ptr %P, align 4792  store volatile i32 2, ptr %P, align 4793  store i32 3, ptr %P, align 4794  ret void795}796 797define void @test45_volatile(ptr %P) {798; CHECK-LABEL: @test45_volatile(799; CHECK-NEXT:    store volatile i32 2, ptr [[P:%.*]], align 4800; CHECK-NEXT:    store volatile i32 3, ptr [[P]], align 4801; CHECK-NEXT:    ret void802;803  store i32 1, ptr %P, align 4804  store volatile i32 2, ptr %P, align 4805  store volatile i32 3, ptr %P, align 4806  ret void807}808 809define void @test46_volatile(ptr %P) {810; CHECK-LABEL: @test46_volatile(811; CHECK-NEXT:    store volatile i32 2, ptr [[P:%.*]], align 4812; CHECK-NEXT:    store volatile i32 3, ptr [[P]], align 4813; CHECK-NEXT:    ret void814;815  store volatile i32 2, ptr %P, align 4816  store i32 1, ptr %P, align 4817  store volatile i32 3, ptr %P, align 4818  ret void819}820 821define void @test47_volatile(ptr %P) {822; CHECK-LABEL: @test47_volatile(823; CHECK-NEXT:    store volatile i32 2, ptr [[P:%.*]], align 4824; CHECK-NEXT:    store volatile i32 3, ptr [[P]], align 4825; CHECK-NEXT:    ret void826;827  store volatile i32 2, ptr %P, align 4828  store volatile i32 3, ptr %P, align 4829  ret void830}831 832define i32 @test48(ptr %P, ptr noalias %Q, ptr %R) {833; CHECK-LABEL: @test48(834; CHECK-NEXT:    store i32 2, ptr [[P:%.*]], align 4835; CHECK-NEXT:    store i32 3, ptr [[Q:%.*]], align 4836; CHECK-NEXT:    [[L:%.*]] = load i32, ptr [[R:%.*]], align 4837; CHECK-NEXT:    ret i32 [[L]]838;839  store i32 1, ptr %Q840  store i32 2, ptr %P841  store i32 3, ptr %Q842  %l = load i32, ptr %R843  ret i32 %l844}845 846define void @test49() {847; CHECK-LABEL: @test49(848; CHECK-NEXT:  bb:849; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr readonly null, i8 0, i64 0, i1 false)850; CHECK-NEXT:    store ptr null, ptr null, align 8851; CHECK-NEXT:    ret void852;853bb:854  call void @llvm.memset.p0.i64(ptr readonly null, i8 0, i64 0, i1 false)855  store ptr null, ptr null, align 8856  ret void857}858 859define void @test_dead_on_return(ptr dead_on_return %p) {860; CHECK-LABEL: @test_dead_on_return(861; CHECK-NEXT:    ret void862;863  store i8 0, ptr %p864  ret void865}866 867define void @test_dead_on_return_maythrow(ptr dead_on_return %p) {868; CHECK-LABEL: @test_dead_on_return_maythrow(869; CHECK-NEXT:    call void @maythrow()870; CHECK-NEXT:    ret void871;872  store i8 0, ptr %p873  call void @maythrow()874  ret void875}876 877define ptr @test_dead_on_return_ptr_returned(ptr dead_on_return %p) {878; CHECK-LABEL: @test_dead_on_return_ptr_returned(879; CHECK-NEXT:    [[LOCAL_VAR:%.*]] = alloca ptr, align 8880; CHECK-NEXT:    call void @opaque(ptr [[LOCAL_VAR]])881; CHECK-NEXT:    ret ptr [[P:%.*]]882;883  %local.var = alloca ptr884  call void @opaque(ptr %local.var)885  store ptr %local.var, ptr %p886  ret ptr %p887}888 889declare void @opaque(ptr)890declare void @maythrow() memory(none)891