1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=dse -S | FileCheck %s 3; RUN: opt < %s -aa-pipeline=basic-aa -passes=dse -S | FileCheck %s 4target 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) nounwind 7declare void @llvm.memset.element.unordered.atomic.p0.i64(ptr nocapture, i8, i64, i32) nounwind 8declare void @llvm.memcpy.p0.p0.i64(ptr nocapture, ptr nocapture, i64, i1) nounwind 9declare void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr nocapture, ptr nocapture, i64, i32) nounwind 10declare 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 4 16; CHECK-NEXT: ret void 17; 18 %DEAD = load i32, ptr %Q 19 store i32 %DEAD, ptr %P 20 store i32 0, ptr %P 21 ret void 22} 23 24; PR8677 25@g = global i32 1 26 27define i32 @test3(ptr %g_addr) nounwind { 28; CHECK-LABEL: @test3( 29; CHECK-NEXT: [[G_VALUE:%.*]] = load i32, ptr [[G_ADDR:%.*]], align 4 30; CHECK-NEXT: store i32 -1, ptr @g, align 4 31; CHECK-NEXT: store i32 [[G_VALUE]], ptr [[G_ADDR]], align 4 32; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr @g, align 4 33; CHECK-NEXT: ret i32 [[TMP3]] 34; 35 %g_value = load i32, ptr %g_addr, align 4 36 store i32 -1, ptr @g, align 4 37 store i32 %g_value, ptr %g_addr, align 4 38 %tmp3 = load i32, ptr @g, align 4 39 ret i32 %tmp3 40} 41 42 43define void @test4(ptr %Q) { 44; CHECK-LABEL: @test4( 45; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[Q:%.*]], align 4 46; CHECK-NEXT: store volatile i32 [[A]], ptr [[Q]], align 4 47; CHECK-NEXT: ret void 48; 49 %a = load i32, ptr %Q 50 store volatile i32 %a, ptr %Q 51 ret void 52} 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 4 58; CHECK-NEXT: store i32 30, ptr [[P:%.*]], align 4 59; CHECK-NEXT: ret void 60; 61 store i32 10, ptr %p, align 4 62 store i32 20, ptr %q, align 4 63 store i32 30, ptr %p, align 4 64 ret void 65} 66 67; Should delete store of 10 even though memset is a may-store to P (P and Q may 68; 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 4 73; CHECK-NEXT: ret void 74; 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 4 78 ret void 79} 80 81; Should delete store of 10 even though memset is a may-store to P (P and Q may 82; 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 4 87; CHECK-NEXT: ret void 88; 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 4 92 ret void 93} 94 95; Should delete store of 10 even though memcpy is a may-store to P (P and Q may 96; 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 4 101; CHECK-NEXT: ret void 102; 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 4 106 ret void 107} 108 109; Should delete store of 10 even though memcpy is a may-store to P (P and Q may 110; 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 4 115; CHECK-NEXT: ret void 116; 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 4 120 ret void 121} 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 4 127; CHECK-NEXT: store i32 1234567, ptr [[V]], align 4 128; CHECK-NEXT: [[X:%.*]] = load i32, ptr [[V]], align 4 129; CHECK-NEXT: ret i32 [[X]] 130; 131 %V = alloca i32 132 store i32 1234567, ptr %V 133 store i8 0, ptr %V 134 %X = load i32, ptr %V 135 ret i32 %X 136 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 void 144; 145 store i32 1, ptr %a, align 4 146 ret void 147} 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 void 153; 154 store i32 1, ptr %a, align 4 155 ret void 156} 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 void 162; 163 store i32 1, ptr %a, align 4 164 ret void 165} 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 8 171; CHECK-NEXT: store ptr [[X:%.*]], ptr [[X_ADDR]], align 8 172; CHECK-NEXT: [[TMP_0:%.*]] = va_arg ptr [[X_ADDR]], double 173; CHECK-NEXT: ret double [[TMP_0]] 174; 175 %X_addr = alloca ptr 176 store ptr %X, ptr %X_addr 177 %tmp.0 = va_arg ptr %X_addr, double 178 ret double %tmp.0 179} 180 181; DSE should delete the dead trampoline. 182declare void @test11f() 183define void @test11() { 184; CHECK-LABEL: @test11( 185; CHECK-NEXT: ret void 186; 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 void 191} 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 void 197; 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 void 201} 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 4 210; CHECK-NEXT: ret ptr [[PTR]] 211; 212 %ptr = tail call ptr @malloc(i64 4) 213 %DEAD = load i32, ptr %ptr 214 %DEAD2 = add i32 %DEAD, 1 215 store i32 %DEAD2, ptr %ptr 216 call void @may_unwind() 217 store i32 0, ptr %ptr 218 ret ptr %ptr 219} 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 4 226; CHECK-NEXT: ret ptr [[PTR]] 227; 228 %ptr = tail call ptr @custom_malloc(i32 4) 229 %DEAD = load i32, ptr %ptr 230 %DEAD2 = add i32 %DEAD, 1 231 store i32 %DEAD2, ptr %ptr 232 call void @may_unwind() 233 store i32 0, ptr %ptr 234 ret ptr %ptr 235} 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 4 243; 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.ac 248 %DEAD2 = add i32 %DEAD, 1 249 store i32 %DEAD2, ptr addrspace(1) %p.ac 250 call void @may_unwind() 251 store i32 0, ptr addrspace(1) %p.ac 252 ret ptr addrspace(1) %p.ac 253} 254 255 256declare noalias ptr @malloc(i64) willreturn allockind("alloc,uninitialized") 257declare noalias ptr @custom_malloc(i32) willreturn 258declare noalias ptr @calloc(i64, i64) willreturn allockind("alloc,zeroed") 259 260define void @test14(ptr %Q) { 261; CHECK-LABEL: @test14( 262; CHECK-NEXT: ret void 263; 264 %P = alloca i32 265 %DEAD = load i32, ptr %Q 266 store i32 %DEAD, ptr %P 267 ret void 268 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 4 278; CHECK-NEXT: call void @test19f(ptr byval({ i32 }) align 4 [[ARG5]]) 279; CHECK-NEXT: ret void 280; 281bb: 282 store i32 912, ptr %arg5 283 call void @test19f(ptr byval({i32}) align 4 %arg5) 284 ret void 285 286} 287 288define void @malloc_no_escape() { 289; CHECK-LABEL: @malloc_no_escape( 290; CHECK-NEXT: ret void 291; 292 %m = call ptr @malloc(i64 24) 293 store i8 0, ptr %m 294 ret void 295} 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 void 301; 302 %m = call ptr @custom_malloc(i32 24) 303 store i8 0, ptr %m 304 ret void 305} 306 307define void @test21() { 308; CHECK-LABEL: @test21( 309; CHECK-NEXT: ret void 310; 311 %m = call ptr @calloc(i64 9, i64 7) 312 store i8 0, ptr %m 313 ret void 314} 315 316; Currently elimination of stores at the end of a function is limited to a 317; single underlying object, for compile-time. This case appears to not be 318; very important in practice. 319define void @test22(i1 %i, i32 %k, i32 %m) nounwind { 320; CHECK-LABEL: @test22( 321; CHECK-NEXT: [[K_ADDR:%.*]] = alloca i32, align 4 322; CHECK-NEXT: [[M_ADDR:%.*]] = alloca i32, align 4 323; CHECK-NEXT: [[K_ADDR_M_ADDR:%.*]] = select i1 [[I:%.*]], ptr [[K_ADDR]], ptr [[M_ADDR]] 324; CHECK-NEXT: store i32 0, ptr [[K_ADDR_M_ADDR]], align 4 325; CHECK-NEXT: ret void 326; 327 %k.addr = alloca i32 328 %m.addr = alloca i32 329 %k.addr.m.addr = select i1 %i, ptr %k.addr, ptr %m.addr 330 store i32 0, ptr %k.addr.m.addr, align 4 331 ret void 332} 333 334; PR13547 335declare noalias ptr @strdup(ptr nocapture) nounwind 336define noalias ptr @test23() nounwind uwtable ssp { 337; CHECK-LABEL: @test23( 338; CHECK-NEXT: [[X:%.*]] = alloca [2 x i8], align 1 339; CHECK-NEXT: store i8 97, ptr [[X]], align 1 340; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [2 x i8], ptr [[X]], i64 0, i64 1 341; CHECK-NEXT: store i8 0, ptr [[ARRAYIDX1]], align 1 342; CHECK-NEXT: [[CALL:%.*]] = call ptr @strdup(ptr [[X]]) #[[ATTR5:[0-9]+]] 343; CHECK-NEXT: ret ptr [[CALL]] 344; 345 %x = alloca [2 x i8], align 1 346 store i8 97, ptr %x, align 1 347 %arrayidx1 = getelementptr inbounds [2 x i8], ptr %x, i64 0, i64 1 348 store i8 0, ptr %arrayidx1, align 1 349 %call = call ptr @strdup(ptr %x) nounwind 350 ret ptr %call 351} 352 353; Make sure same sized store to later element is deleted 354define void @test24(ptr %a, i32 %b, i32 %c) nounwind { 355; CHECK-LABEL: @test24( 356; CHECK-NEXT: store i32 [[B:%.*]], ptr [[A:%.*]], align 4 357; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds [2 x i32], ptr [[A]], i64 0, i64 1 358; CHECK-NEXT: store i32 [[C:%.*]], ptr [[TMP1]], align 4 359; CHECK-NEXT: ret void 360; 361 store i32 0, ptr %a, align 4 362 %1 = getelementptr inbounds [2 x i32], ptr %a, i64 0, i64 1 363 store i32 0, ptr %1, align 4 364 store i32 %b, ptr %a, align 4 365 %2 = getelementptr inbounds [2 x i32], ptr %a, i64 0, i64 1 366 store i32 %c, ptr %2, align 4 367 ret void 368} 369 370; Check another case like PR13547 where strdup is not like malloc. 371define ptr @test25(ptr %p) nounwind { 372; CHECK-LABEL: @test25( 373; CHECK-NEXT: [[P_4:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 4 374; CHECK-NEXT: [[TMP:%.*]] = load i8, ptr [[P_4]], align 1 375; CHECK-NEXT: store i8 0, ptr [[P_4]], align 1 376; CHECK-NEXT: [[Q:%.*]] = call ptr @strdup(ptr [[P]]) #[[ATTR13:[0-9]+]] 377; CHECK-NEXT: store i8 [[TMP]], ptr [[P_4]], align 1 378; CHECK-NEXT: ret ptr [[Q]] 379; 380 %p.4 = getelementptr i8, ptr %p, i64 4 381 %tmp = load i8, ptr %p.4, align 1 382 store i8 0, ptr %p.4, align 1 383 %q = call ptr @strdup(ptr %p) nounwind optsize 384 store i8 %tmp, ptr %p.4, align 1 385 ret ptr %q 386} 387 388; Don't remove redundant store because of may-aliased store. 389define i32 @test28(i1 %c, ptr %p, ptr %p2, i32 %i) { 390; CHECK-LABEL: @test28( 391; CHECK-NEXT: entry: 392; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[P:%.*]], align 4 393; CHECK-NEXT: store i32 [[I:%.*]], ptr [[P2:%.*]], align 4 394; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] 395; CHECK: bb1: 396; CHECK-NEXT: br label [[BB3:%.*]] 397; CHECK: bb2: 398; CHECK-NEXT: br label [[BB3]] 399; CHECK: bb3: 400; CHECK-NEXT: store i32 [[V]], ptr [[P]], align 4 401; CHECK-NEXT: ret i32 0 402; 403entry: 404 %v = load i32, ptr %p, align 4 405 406 ; Might overwrite value at %p 407 store i32 %i, ptr %p2, align 4 408 br i1 %c, label %bb1, label %bb2 409bb1: 410 br label %bb3 411bb2: 412 br label %bb3 413bb3: 414 store i32 %v, ptr %p, align 4 415 ret i32 0 416} 417 418; Don't remove redundant store because of may-aliased store. 419define i32 @test29(i1 %c, ptr %p, ptr %p2, i32 %i) { 420; CHECK-LABEL: @test29( 421; CHECK-NEXT: entry: 422; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[P:%.*]], align 4 423; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] 424; CHECK: bb1: 425; CHECK-NEXT: br label [[BB3:%.*]] 426; CHECK: bb2: 427; CHECK-NEXT: store i32 [[I:%.*]], ptr [[P2:%.*]], align 4 428; CHECK-NEXT: br label [[BB3]] 429; CHECK: bb3: 430; CHECK-NEXT: store i32 [[V]], ptr [[P]], align 4 431; CHECK-NEXT: ret i32 0 432; 433entry: 434 %v = load i32, ptr %p, align 4 435 br i1 %c, label %bb1, label %bb2 436bb1: 437 br label %bb3 438bb2: 439 ; Might overwrite value at %p 440 store i32 %i, ptr %p2, align 4 441 br label %bb3 442bb3: 443 store i32 %v, ptr %p, align 4 444 ret i32 0 445} 446 447declare void @unknown_func() 448 449; Don't remove redundant store because of unknown call. 450define i32 @test30(i1 %c, ptr %p, i32 %i) { 451; CHECK-LABEL: @test30( 452; CHECK-NEXT: entry: 453; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[P:%.*]], align 4 454; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] 455; CHECK: bb1: 456; CHECK-NEXT: br label [[BB3:%.*]] 457; CHECK: bb2: 458; CHECK-NEXT: call void @unknown_func() 459; CHECK-NEXT: br label [[BB3]] 460; CHECK: bb3: 461; CHECK-NEXT: store i32 [[V]], ptr [[P]], align 4 462; CHECK-NEXT: ret i32 0 463; 464entry: 465 %v = load i32, ptr %p, align 4 466 br i1 %c, label %bb1, label %bb2 467bb1: 468 br label %bb3 469bb2: 470 ; Might overwrite value at %p 471 call void @unknown_func() 472 br label %bb3 473bb3: 474 store i32 %v, ptr %p, align 4 475 ret i32 0 476} 477 478; Don't remove redundant store in a loop with a may-alias store. 479define i32 @test32(i1 %c, ptr %p, i32 %i, i1 %arg) { 480; CHECK-LABEL: @test32( 481; CHECK-NEXT: entry: 482; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[P:%.*]], align 4 483; CHECK-NEXT: br label [[BB1:%.*]] 484; CHECK: bb1: 485; CHECK-NEXT: store i32 [[V]], ptr [[P]], align 4 486; CHECK-NEXT: call void @unknown_func() 487; CHECK-NEXT: br i1 %arg, label [[BB1]], label [[BB2:%.*]] 488; CHECK: bb2: 489; CHECK-NEXT: ret i32 0 490; 491entry: 492 %v = load i32, ptr %p, align 4 493 br label %bb1 494bb1: 495 store i32 %v, ptr %p, align 4 496 ; Might read and overwrite value at %p 497 call void @unknown_func() 498 br i1 %arg, label %bb1, label %bb2 499bb2: 500 ret i32 0 501} 502 503; We cannot remove any stores, because @unknown_func may unwind and the caller 504; may read %p while unwinding. 505define void @test34(ptr noalias %p) { 506; CHECK-LABEL: @test34( 507; CHECK-NEXT: store i32 1, ptr [[P:%.*]], align 4 508; CHECK-NEXT: call void @unknown_func() 509; CHECK-NEXT: store i32 0, ptr [[P]], align 4 510; CHECK-NEXT: ret void 511; 512 store i32 1, ptr %p 513 call void @unknown_func() 514 store i32 0, ptr %p 515 ret void 516} 517 518; Same as previous case, but with a dead_on_unwind argument. 519define void @test34_dead_on_unwind(ptr noalias dead_on_unwind %p) { 520; CHECK-LABEL: @test34_dead_on_unwind( 521; CHECK-NEXT: call void @unknown_func() 522; CHECK-NEXT: store i32 0, ptr [[P:%.*]], align 4 523; CHECK-NEXT: ret void 524; 525 store i32 1, ptr %p 526 call void @unknown_func() 527 store i32 0, ptr %p 528 ret void 529} 530 531; Remove redundant store even with an unwinding function in the same block 532define void @test35(ptr noalias %p) { 533; CHECK-LABEL: @test35( 534; CHECK-NEXT: call void @unknown_func() 535; CHECK-NEXT: store i32 0, ptr [[P:%.*]], align 4 536; CHECK-NEXT: ret void 537; 538 call void @unknown_func() 539 store i32 1, ptr %p 540 store i32 0, ptr %p 541 ret void 542} 543 544; We cannot optimize away the first memmove since %P could overlap with %Q. 545define void @test36(ptr %P, ptr %Q) { 546; CHECK-LABEL: @test36( 547; CHECK-NEXT: tail call void @llvm.memmove.p0.p0.i64(ptr [[P:%.*]], ptr [[Q:%.*]], i64 12, i1 false) 548; CHECK-NEXT: tail call void @llvm.memmove.p0.p0.i64(ptr [[P]], ptr [[Q]], i64 12, i1 false) 549; CHECK-NEXT: ret void 550; 551 552 tail call void @llvm.memmove.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false) 553 tail call void @llvm.memmove.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false) 554 ret void 555} 556 557define void @test36_atomic(ptr %P, ptr %Q) { 558; CHECK-LABEL: @test36_atomic( 559; 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) 560; 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) 561; CHECK-NEXT: ret void 562; 563 564 tail call void @llvm.memmove.element.unordered.atomic.p0.p0.i64(ptr align 1 %P, ptr align 1 %Q, i64 12, i32 1) 565 tail call void @llvm.memmove.element.unordered.atomic.p0.p0.i64(ptr align 1 %P, ptr align 1 %Q, i64 12, i32 1) 566 ret void 567} 568 569define void @test37(ptr %P, ptr %Q, ptr %R) { 570; CHECK-LABEL: @test37( 571; CHECK-NEXT: tail call void @llvm.memcpy.p0.p0.i64(ptr [[P:%.*]], ptr [[Q:%.*]], i64 12, i1 false) 572; CHECK-NEXT: tail call void @llvm.memmove.p0.p0.i64(ptr [[P]], ptr [[R:%.*]], i64 12, i1 false) 573; CHECK-NEXT: ret void 574; 575 576 tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false) 577 tail call void @llvm.memmove.p0.p0.i64(ptr %P, ptr %R, i64 12, i1 false) 578 ret void 579} 580 581define void @test37_atomic(ptr %P, ptr %Q, ptr %R) { 582; CHECK-LABEL: @test37_atomic( 583; 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) 584; 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) 585; CHECK-NEXT: ret void 586; 587 588 tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 1 %P, ptr align 1 %Q, i64 12, i32 1) 589 tail call void @llvm.memmove.element.unordered.atomic.p0.p0.i64(ptr align 1 %P, ptr align 1 %R, i64 12, i32 1) 590 ret void 591} 592 593; See PR11763 - LLVM allows memcpy's source and destination to be equal (but not 594; inequal and overlapping). 595define void @test38(ptr %P, ptr %Q, ptr %R) { 596; CHECK-LABEL: @test38( 597; CHECK-NEXT: tail call void @llvm.memmove.p0.p0.i64(ptr [[P:%.*]], ptr [[Q:%.*]], i64 12, i1 false) 598; CHECK-NEXT: tail call void @llvm.memcpy.p0.p0.i64(ptr [[P]], ptr [[R:%.*]], i64 12, i1 false) 599; CHECK-NEXT: ret void 600; 601 602 tail call void @llvm.memmove.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false) 603 tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %R, i64 12, i1 false) 604 ret void 605} 606 607; See PR11763 - LLVM allows memcpy's source and destination to be equal (but not 608; inequal and overlapping). 609define void @test38_atomic(ptr %P, ptr %Q, ptr %R) { 610; CHECK-LABEL: @test38_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.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 1 [[P]], ptr align 1 [[R:%.*]], i64 12, i32 1) 613; CHECK-NEXT: ret void 614; 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.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 1 %P, ptr align 1 %R, i64 12, i32 1) 618 ret void 619} 620 621define void @test39(ptr %P, ptr %Q, ptr %R) { 622; CHECK-LABEL: @test39( 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.memcpy.p0.p0.i64(ptr [[P]], ptr [[R:%.*]], i64 8, i1 false) 625; CHECK-NEXT: ret void 626; 627 628 tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false) 629 tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %R, i64 8, i1 false) 630 ret void 631} 632 633define void @test39_atomic(ptr %P, ptr %Q, ptr %R) { 634; CHECK-LABEL: @test39_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.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 1 [[P]], ptr align 1 [[R:%.*]], i64 8, i32 1) 637; CHECK-NEXT: ret void 638; 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.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 1 %P, ptr align 1 %R, i64 8, i32 1) 642 ret void 643} 644 645declare void @llvm.memmove.p0.p0.i64(ptr nocapture, ptr nocapture readonly, i64, i1) 646declare void @llvm.memmove.element.unordered.atomic.p0.p0.i64(ptr nocapture, ptr nocapture readonly, i64, i32) 647 648declare void @llvm.lifetime.start.p0(i64, ptr nocapture) nounwind 649declare void @llvm.lifetime.end.p0(i64, ptr nocapture) nounwind 650define void @test40(ptr noalias %Pp, ptr noalias %Q) { 651; CHECK-LABEL: @test40( 652; CHECK-NEXT: entry: 653; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 654; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr nonnull [[A]]) 655; CHECK-NEXT: [[PC:%.*]] = load ptr, ptr [[PP:%.*]], align 8 656; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr nonnull align 4 [[A]], ptr align 4 [[Q:%.*]], i64 4, i1 false) 657; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[PC]], ptr nonnull align 4 [[A]], i64 4, i1 true) 658; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr nonnull [[A]]) 659; CHECK-NEXT: ret void 660; 661entry: 662 %A = alloca i32, align 4 663 call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %A) 664 %Pc = load ptr, ptr %Pp, align 8 665 call void @llvm.memcpy.p0.p0.i64(ptr nonnull align 4 %A, ptr align 4 %Q, i64 4, i1 false) 666 call void @llvm.memcpy.p0.p0.i64(ptr align 4 %Pc, ptr nonnull align 4 %A, i64 4, i1 true) 667 call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %A) 668 ret void 669} 670 671declare void @free(ptr nocapture) allockind("free") 672 673; We cannot remove `store i32 1, ptr %p`, because @unknown_func may unwind 674; and the caller may read %p while unwinding. 675define void @test41(ptr noalias %P) { 676; CHECK-LABEL: @test41( 677; CHECK-NEXT: store i32 1, ptr [[P:%.*]], align 4 678; CHECK-NEXT: call void @unknown_func() 679; CHECK-NEXT: call void @free(ptr [[P]]) 680; CHECK-NEXT: ret void 681; 682 store i32 1, ptr %P 683 call void @unknown_func() 684 store i32 2, ptr %P 685 call void @free(ptr %P) 686 ret void 687} 688 689define void @test42(ptr %P, ptr %Q) { 690; CHECK-LABEL: @test42( 691; CHECK-NEXT: store i32 1, ptr [[P:%.*]], align 4 692; CHECK-NEXT: store i32 2, ptr [[Q:%.*]], align 4 693; CHECK-NEXT: store i8 3, ptr [[P]], align 1 694; CHECK-NEXT: ret void 695; 696 store i32 1, ptr %P 697 store i32 2, ptr %Q 698 store i8 3, ptr %P 699 ret void 700} 701 702define void @test42a(ptr %P, ptr %Q) { 703; CHECK-LABEL: @test42a( 704; CHECK-NEXT: store atomic i32 1, ptr [[P:%.*]] unordered, align 4 705; CHECK-NEXT: store atomic i32 2, ptr [[Q:%.*]] unordered, align 4 706; CHECK-NEXT: store atomic i8 3, ptr [[P]] unordered, align 4 707; CHECK-NEXT: ret void 708; 709 store atomic i32 1, ptr %P unordered, align 4 710 store atomic i32 2, ptr %Q unordered, align 4 711 store atomic i8 3, ptr %P unordered, align 4 712 ret void 713} 714 715define void @test43a(ptr %P, ptr noalias %Q) { 716; CHECK-LABEL: @test43a( 717; CHECK-NEXT: entry: 718; CHECK-NEXT: store atomic i32 50331649, ptr [[P:%.*]] unordered, align 4 719; CHECK-NEXT: store atomic i32 2, ptr [[Q:%.*]] unordered, align 4 720; CHECK-NEXT: ret void 721; 722entry: 723 store atomic i32 1, ptr %P unordered, align 4 724 store atomic i32 2, ptr %Q unordered, align 4 725 store atomic i8 3, ptr %P unordered, align 4 726 ret void 727} 728 729; Some tests where volatile may block removing a store. 730 731; Here we can remove the first non-volatile store. We cannot remove the 732; volatile store. 733define void @test44_volatile(ptr %P) { 734; CHECK-LABEL: @test44_volatile( 735; CHECK-NEXT: store volatile i32 2, ptr [[P:%.*]], align 4 736; CHECK-NEXT: store i32 3, ptr [[P]], align 4 737; CHECK-NEXT: ret void 738; 739 store i32 1, ptr %P, align 4 740 store volatile i32 2, ptr %P, align 4 741 store i32 3, ptr %P, align 4 742 ret void 743} 744 745define void @test45_volatile(ptr %P) { 746; CHECK-LABEL: @test45_volatile( 747; CHECK-NEXT: store volatile i32 2, ptr [[P:%.*]], align 4 748; CHECK-NEXT: store volatile i32 3, ptr [[P]], align 4 749; CHECK-NEXT: ret void 750; 751 store i32 1, ptr %P, align 4 752 store volatile i32 2, ptr %P, align 4 753 store volatile i32 3, ptr %P, align 4 754 ret void 755} 756 757define void @test46_volatile(ptr %P) { 758; CHECK-LABEL: @test46_volatile( 759; CHECK-NEXT: store volatile i32 2, ptr [[P:%.*]], align 4 760; CHECK-NEXT: store volatile i32 3, ptr [[P]], align 4 761; CHECK-NEXT: ret void 762; 763 store volatile i32 2, ptr %P, align 4 764 store i32 1, ptr %P, align 4 765 store volatile i32 3, ptr %P, align 4 766 ret void 767} 768 769define void @test47_volatile(ptr %P) { 770; CHECK-LABEL: @test47_volatile( 771; CHECK-NEXT: store volatile i32 2, ptr [[P:%.*]], align 4 772; CHECK-NEXT: store volatile i32 3, ptr [[P]], align 4 773; CHECK-NEXT: ret void 774; 775 store volatile i32 2, ptr %P, align 4 776 store volatile i32 3, ptr %P, align 4 777 ret void 778} 779 780define i32 @test48(ptr %P, ptr noalias %Q, ptr %R) { 781; CHECK-LABEL: @test48( 782; CHECK-NEXT: store i32 2, ptr [[P:%.*]], align 4 783; CHECK-NEXT: store i32 3, ptr [[Q:%.*]], align 4 784; CHECK-NEXT: [[L:%.*]] = load i32, ptr [[R:%.*]], align 4 785; CHECK-NEXT: ret i32 [[L]] 786; 787 store i32 1, ptr %Q 788 store i32 2, ptr %P 789 store i32 3, ptr %Q 790 %l = load i32, ptr %R 791 ret i32 %l 792} 793 794define void @test49() { 795; CHECK-LABEL: @test49( 796; CHECK-NEXT: bb: 797; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr readonly null, i8 0, i64 0, i1 false) 798; CHECK-NEXT: store ptr null, ptr null, align 8 799; CHECK-NEXT: ret void 800; 801bb: 802 call void @llvm.memset.p0.i64(ptr readonly null, i8 0, i64 0, i1 false) 803 store ptr null, ptr null, align 8 804 ret void 805} 806