411 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -S -passes=early-cse -earlycse-debug-hash | FileCheck %s3; RUN: opt < %s -S -passes='early-cse<memssa>' | FileCheck %s4; RUN: opt < %s -S -passes=early-cse | FileCheck %s5 6declare void @llvm.assume(i1) nounwind7 8define void @test1(i8 %V, ptr%P) {9; CHECK-LABEL: @test1(10; CHECK-NEXT: store i32 23, ptr [[P:%.*]], align 411; CHECK-NEXT: [[C:%.*]] = zext i8 [[V:%.*]] to i3212; CHECK-NEXT: store volatile i32 [[C]], ptr [[P]], align 413; CHECK-NEXT: store volatile i32 [[C]], ptr [[P]], align 414; CHECK-NEXT: [[E:%.*]] = add i32 [[C]], [[C]]15; CHECK-NEXT: store volatile i32 [[E]], ptr [[P]], align 416; CHECK-NEXT: store volatile i32 [[E]], ptr [[P]], align 417; CHECK-NEXT: store volatile i32 [[E]], ptr [[P]], align 418; CHECK-NEXT: ret void19;20 %A = bitcast i64 42 to double ;; dead21 %B = add i32 4, 19 ;; constant folds22 store i32 %B, ptr %P23 24 %C = zext i8 %V to i3225 %D = zext i8 %V to i32 ;; CSE26 store volatile i32 %C, ptr %P27 store volatile i32 %D, ptr %P28 29 %E = add i32 %C, %C30 %F = add i32 %C, %C31 store volatile i32 %E, ptr %P32 store volatile i32 %F, ptr %P33 34 %G = add nuw i32 %C, %C35 store volatile i32 %G, ptr %P36 ret void37}38 39 40;; Simple load value numbering.41define i32 @test2(ptr%P) {42; CHECK-LABEL: @test2(43; CHECK-NEXT: [[V1:%.*]] = load i32, ptr [[P:%.*]], align 444; CHECK-NEXT: ret i32 045;46 %V1 = load i32, ptr %P47 %V2 = load i32, ptr %P48 %Diff = sub i32 %V1, %V249 ret i32 %Diff50}51 52define i32 @test2a(ptr%P, i1 %b) {53; CHECK-LABEL: @test2a(54; CHECK-NEXT: [[V1:%.*]] = load i32, ptr [[P:%.*]], align 455; CHECK-NEXT: tail call void @llvm.assume(i1 [[B:%.*]])56; CHECK-NEXT: ret i32 057;58 %V1 = load i32, ptr %P59 tail call void @llvm.assume(i1 %b)60 %V2 = load i32, ptr %P61 %Diff = sub i32 %V1, %V262 ret i32 %Diff63}64 65;; Cross block load value numbering.66define i32 @test3(ptr%P, i1 %Cond) {67; CHECK-LABEL: @test3(68; CHECK-NEXT: [[V1:%.*]] = load i32, ptr [[P:%.*]], align 469; CHECK-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]]70; CHECK: T:71; CHECK-NEXT: store i32 4, ptr [[P]], align 472; CHECK-NEXT: ret i32 4273; CHECK: F:74; CHECK-NEXT: ret i32 075;76 %V1 = load i32, ptr %P77 br i1 %Cond, label %T, label %F78T:79 store i32 4, ptr %P80 ret i32 4281F:82 %V2 = load i32, ptr %P83 %Diff = sub i32 %V1, %V284 ret i32 %Diff85}86 87define i32 @test3a(ptr%P, i1 %Cond, i1 %b) {88; CHECK-LABEL: @test3a(89; CHECK-NEXT: [[V1:%.*]] = load i32, ptr [[P:%.*]], align 490; CHECK-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]]91; CHECK: T:92; CHECK-NEXT: store i32 4, ptr [[P]], align 493; CHECK-NEXT: ret i32 4294; CHECK: F:95; CHECK-NEXT: tail call void @llvm.assume(i1 [[B:%.*]])96; CHECK-NEXT: ret i32 097;98 %V1 = load i32, ptr %P99 br i1 %Cond, label %T, label %F100T:101 store i32 4, ptr %P102 ret i32 42103F:104 tail call void @llvm.assume(i1 %b)105 %V2 = load i32, ptr %P106 %Diff = sub i32 %V1, %V2107 ret i32 %Diff108}109 110;; Cross block load value numbering stops when stores happen.111define i32 @test4(ptr%P, i1 %Cond) {112; CHECK-LABEL: @test4(113; CHECK-NEXT: [[V1:%.*]] = load i32, ptr [[P:%.*]], align 4114; CHECK-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]]115; CHECK: T:116; CHECK-NEXT: ret i32 42117; CHECK: F:118; CHECK-NEXT: store i32 42, ptr [[P]], align 4119; CHECK-NEXT: [[DIFF:%.*]] = sub i32 [[V1]], 42120; CHECK-NEXT: ret i32 [[DIFF]]121;122 %V1 = load i32, ptr %P123 br i1 %Cond, label %T, label %F124T:125 ret i32 42126F:127 ; Clobbers V1128 store i32 42, ptr %P129 130 %V2 = load i32, ptr %P131 %Diff = sub i32 %V1, %V2132 ret i32 %Diff133}134 135declare i32 @func(ptr%P) readonly136 137;; Simple call CSE'ing.138define i32 @test5(ptr%P) {139; CHECK-LABEL: @test5(140; CHECK-NEXT: [[V1:%.*]] = call i32 @func(ptr [[P:%.*]]), !prof [[PROF0:![0-9]+]]141; CHECK-NEXT: ret i32 0142;143 %V1 = call i32 @func(ptr %P), !prof !0144 %V2 = call i32 @func(ptr %P), !prof !1145 %Diff = sub i32 %V1, %V2146 ret i32 %Diff147}148 149declare void @void_func()150 151define void @void_func_cse_readonly(ptr %P) {152; CHECK-LABEL: @void_func_cse_readonly(153; CHECK-NEXT: call void @void_func(ptr [[P:%.*]]) #[[ATTR1:[0-9]+]]154; CHECK-NEXT: ret void155;156 call void @void_func(ptr %P) memory(read)157 call void @void_func(ptr %P) memory(read)158 ret void159}160 161define void @void_func_cse_readnone(ptr %P) {162; CHECK-LABEL: @void_func_cse_readnone(163; CHECK-NEXT: call void @void_func(ptr [[P:%.*]]) #[[ATTR2:[0-9]+]]164; CHECK-NEXT: ret void165;166 call void @void_func(ptr %P) memory(none)167 call void @void_func(ptr %P) memory(none)168 ret void169}170 171!0 = !{!"branch_weights", i32 95}172!1 = !{!"branch_weights", i32 95}173 174;; Trivial Store->load forwarding175define i32 @test6(ptr%P) {176; CHECK-LABEL: @test6(177; CHECK-NEXT: store i32 42, ptr [[P:%.*]], align 4178; CHECK-NEXT: ret i32 42179;180 store i32 42, ptr %P181 %V1 = load i32, ptr %P182 ret i32 %V1183}184 185define i32 @test6a(ptr%P, i1 %b) {186; CHECK-LABEL: @test6a(187; CHECK-NEXT: store i32 42, ptr [[P:%.*]], align 4188; CHECK-NEXT: tail call void @llvm.assume(i1 [[B:%.*]])189; CHECK-NEXT: ret i32 42190;191 store i32 42, ptr %P192 tail call void @llvm.assume(i1 %b)193 %V1 = load i32, ptr %P194 ret i32 %V1195}196 197;; Trivial dead store elimination.198define void @test7(ptr%P) {199; CHECK-LABEL: @test7(200; CHECK-NEXT: store i32 45, ptr [[P:%.*]], align 4201; CHECK-NEXT: ret void202;203 store i32 42, ptr %P204 store i32 45, ptr %P205 ret void206}207 208;; Readnone functions aren't invalidated by stores.209define i32 @test8(ptr%P) {210; CHECK-LABEL: @test8(211; CHECK-NEXT: [[V1:%.*]] = call i32 @func(ptr [[P:%.*]]) #[[ATTR2]]212; CHECK-NEXT: store i32 4, ptr [[P]], align 4213; CHECK-NEXT: ret i32 0214;215 %V1 = call i32 @func(ptr %P) readnone216 store i32 4, ptr %P217 %V2 = call i32 @func(ptr %P) readnone218 %Diff = sub i32 %V1, %V2219 ret i32 %Diff220}221 222;; Trivial DSE can't be performed across a readonly call. The call223;; can observe the earlier write.224define i32 @test9(ptr%P) {225; CHECK-LABEL: @test9(226; CHECK-NEXT: store i32 4, ptr [[P:%.*]], align 4227; CHECK-NEXT: [[V1:%.*]] = call i32 @func(ptr [[P]]) #[[ATTR1]]228; CHECK-NEXT: store i32 5, ptr [[P]], align 4229; CHECK-NEXT: ret i32 [[V1]]230;231 store i32 4, ptr %P232 %V1 = call i32 @func(ptr %P) readonly233 store i32 5, ptr %P234 ret i32 %V1235}236 237;; Trivial DSE can be performed across a readnone nounwind call.238define i32 @test10(ptr%P) {239; CHECK-LABEL: @test10(240; CHECK-NEXT: [[V1:%.*]] = call i32 @func(ptr [[P:%.*]]) #[[ATTR3:[0-9]+]]241; CHECK-NEXT: store i32 5, ptr [[P]], align 4242; CHECK-NEXT: ret i32 [[V1]]243;244 store i32 4, ptr %P245 %V1 = call i32 @func(ptr %P) readnone nounwind246 store i32 5, ptr %P247 ret i32 %V1248}249 250; Trivial DSE can't be performed across a potentially unwinding readnone251; call, as the caller may read the memory on unwind.252define i32 @test_readnone_missing_nounwind(ptr %P) {253; CHECK-LABEL: @test_readnone_missing_nounwind(254; CHECK-NEXT: store i32 4, ptr [[P:%.*]], align 4255; CHECK-NEXT: [[V1:%.*]] = call i32 @func(ptr [[P]]) #[[ATTR2]]256; CHECK-NEXT: store i32 5, ptr [[P]], align 4257; CHECK-NEXT: ret i32 [[V1]]258;259 store i32 4, ptr %P260 %V1 = call i32 @func(ptr %P) readnone261 store i32 5, ptr %P262 ret i32 %V1263}264 265;; Trivial dead store elimination - should work for an entire series of dead stores too.266define void @test11(ptr%P) {267; CHECK-LABEL: @test11(268; CHECK-NEXT: store i32 45, ptr [[P:%.*]], align 4269; CHECK-NEXT: ret void270;271 store i32 42, ptr %P272 store i32 43, ptr %P273 store i32 44, ptr %P274 store i32 45, ptr %P275 ret void276}277 278define i32 @test12(i1 %B, ptr %P1, ptr %P2) {279; CHECK-LABEL: @test12(280; CHECK-NEXT: [[LOAD0:%.*]] = load i32, ptr [[P1:%.*]], align 4281; CHECK-NEXT: [[TMP1:%.*]] = load atomic i32, ptr [[P2:%.*]] seq_cst, align 4282; CHECK-NEXT: [[LOAD1:%.*]] = load i32, ptr [[P1]], align 4283; CHECK-NEXT: [[SEL:%.*]] = select i1 [[B:%.*]], i32 [[LOAD0]], i32 [[LOAD1]]284; CHECK-NEXT: ret i32 [[SEL]]285;286 %load0 = load i32, ptr %P1287 %1 = load atomic i32, ptr %P2 seq_cst, align 4288 %load1 = load i32, ptr %P1289 %sel = select i1 %B, i32 %load0, i32 %load1290 ret i32 %sel291}292 293define void @dse1(ptr%P) {294; CHECK-LABEL: @dse1(295; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[P:%.*]], align 4296; CHECK-NEXT: ret void297;298 %v = load i32, ptr %P299 store i32 %v, ptr %P300 ret void301}302 303define void @dse2(ptr%P) {304; CHECK-LABEL: @dse2(305; CHECK-NEXT: [[V:%.*]] = load atomic i32, ptr [[P:%.*]] seq_cst, align 4306; CHECK-NEXT: ret void307;308 %v = load atomic i32, ptr %P seq_cst, align 4309 store i32 %v, ptr %P310 ret void311}312 313define void @dse3(ptr%P) {314; CHECK-LABEL: @dse3(315; CHECK-NEXT: [[V:%.*]] = load atomic i32, ptr [[P:%.*]] seq_cst, align 4316; CHECK-NEXT: ret void317;318 %v = load atomic i32, ptr %P seq_cst, align 4319 store atomic i32 %v, ptr %P unordered, align 4320 ret void321}322 323define i32 @dse4(ptr%P, ptr%Q) {324; CHECK-LABEL: @dse4(325; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[Q:%.*]], align 4326; CHECK-NEXT: [[V:%.*]] = load atomic i32, ptr [[P:%.*]] unordered, align 4327; CHECK-NEXT: ret i32 0328;329 %a = load i32, ptr %Q330 %v = load atomic i32, ptr %P unordered, align 4331 store atomic i32 %v, ptr %P unordered, align 4332 %b = load i32, ptr %Q333 %res = sub i32 %a, %b334 ret i32 %res335}336 337; Note that in this example, %P and %Q could in fact be the same338; pointer. %v could be different than the value observed for %a339; and that's okay because we're using relaxed memory ordering.340; The only guarantee we have to provide is that each of the loads341; has to observe some value written to that location. We do342; not have to respect the order in which those writes were done.343define i32 @dse5(ptr%P, ptr%Q) {344; CHECK-LABEL: @dse5(345; CHECK-NEXT: [[V:%.*]] = load atomic i32, ptr [[P:%.*]] unordered, align 4346; CHECK-NEXT: [[A:%.*]] = load atomic i32, ptr [[Q:%.*]] unordered, align 4347; CHECK-NEXT: ret i32 0348;349 %v = load atomic i32, ptr %P unordered, align 4350 %a = load atomic i32, ptr %Q unordered, align 4351 store atomic i32 %v, ptr %P unordered, align 4352 %b = load atomic i32, ptr %Q unordered, align 4353 %res = sub i32 %a, %b354 ret i32 %res355}356 357 358define void @dse_neg1(ptr%P) {359; CHECK-LABEL: @dse_neg1(360; CHECK-NEXT: store i32 5, ptr [[P:%.*]], align 4361; CHECK-NEXT: ret void362;363 %v = load i32, ptr %P364 store i32 5, ptr %P365 ret void366}367 368; Could remove the store, but only if ordering was somehow369; encoded.370define void @dse_neg2(ptr%P) {371; CHECK-LABEL: @dse_neg2(372; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[P:%.*]], align 4373; CHECK-NEXT: store atomic i32 [[V]], ptr [[P]] seq_cst, align 4374; CHECK-NEXT: ret void375;376 %v = load i32, ptr %P377 store atomic i32 %v, ptr %P seq_cst, align 4378 ret void379}380 381@c = external global i32, align 4382declare i32 @reads_c(i32 returned)383define void @pr28763() {384; CHECK-LABEL: @pr28763(385; CHECK-NEXT: entry:386; CHECK-NEXT: store i32 0, ptr @c, align 4387; CHECK-NEXT: [[CALL:%.*]] = call i32 @reads_c(i32 0)388; CHECK-NEXT: store i32 2, ptr @c, align 4389; CHECK-NEXT: ret void390;391entry:392 %load = load i32, ptr @c, align 4393 store i32 0, ptr @c, align 4394 %call = call i32 @reads_c(i32 0)395 store i32 2, ptr @c, align 4396 ret void397}398 399define i1 @cse_freeze(i1 %a) {400; CHECK-LABEL: @cse_freeze(401; CHECK-NEXT: entry:402; CHECK-NEXT: [[B:%.*]] = freeze i1 [[A:%.*]]403; CHECK-NEXT: ret i1 [[B]]404;405entry:406 %b = freeze i1 %a407 %c = freeze i1 %a408 %and = and i1 %b, %c409 ret i1 %and410}411