brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.1 KiB · 55b9384 Raw
330 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes=dse -S < %s | FileCheck %s3 4target 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"5target triple = "x86_64-apple-macosx10.7.0"6 7; Basic correctness tests for atomic stores.8; Note that it turns out essentially every transformation DSE does is legal on9; atomic ops, just some transformations are not allowed across release-acquire pairs.10 11@x = common global i32 0, align 412@y = common global i32 0, align 413 14declare void @randomop(ptr)15 16; DSE across unordered store (allowed)17define void @test1() {18; CHECK-LABEL: @test1(19; CHECK-NEXT:    store atomic i32 0, ptr @y unordered, align 420; CHECK-NEXT:    store i32 1, ptr @x, align 421; CHECK-NEXT:    ret void22;23  store i32 0, ptr @x24  store atomic i32 0, ptr @y unordered, align 425  store i32 1, ptr @x26  ret void27}28 29; DSE remove unordered store (allowed)30define void @test4() {31; CHECK-LABEL: @test4(32; CHECK-NEXT:    store i32 1, ptr @x, align 433; CHECK-NEXT:    ret void34;35  store atomic i32 0, ptr @x unordered, align 436  store i32 1, ptr @x37  ret void38}39 40; DSE unordered store overwriting non-atomic store (allowed)41define void @test5() {42; CHECK-LABEL: @test5(43; CHECK-NEXT:    store atomic i32 1, ptr @x unordered, align 444; CHECK-NEXT:    ret void45;46  store i32 0, ptr @x47  store atomic i32 1, ptr @x unordered, align 448  ret void49}50 51; DSE no-op unordered atomic store (allowed)52define void @test6() {53; CHECK-LABEL: @test6(54; CHECK-NEXT:    ret void55;56  %x = load atomic i32, ptr @x unordered, align 457  store atomic i32 %x, ptr @x unordered, align 458  ret void59}60 61; DSE seq_cst store (be conservative; DSE doesn't have infrastructure62; to reason about atomic operations).63define void @test7() {64; CHECK-LABEL: @test7(65; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 466; CHECK-NEXT:    store atomic i32 0, ptr [[A]] seq_cst, align 467; CHECK-NEXT:    ret void68;69  %a = alloca i3270  store atomic i32 0, ptr %a seq_cst, align 471  ret void72}73 74; DSE and seq_cst load (be conservative; DSE doesn't have infrastructure75; to reason about atomic operations).76define i32 @test8() {77; CHECK-LABEL: @test8(78; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 479; CHECK-NEXT:    call void @randomop(ptr [[A]])80; CHECK-NEXT:    store i32 0, ptr [[A]], align 481; CHECK-NEXT:    [[X:%.*]] = load atomic i32, ptr @x seq_cst, align 482; CHECK-NEXT:    ret i32 [[X]]83;84  %a = alloca i3285  call void @randomop(ptr %a)86  store i32 0, ptr %a, align 487  %x = load atomic i32, ptr @x seq_cst, align 488  ret i32 %x89}90 91; DSE across monotonic store (allowed as long as the eliminated store isUnordered)92define void @test10() {93; CHECK-LABEL: test1094; CHECK-NOT: store i32 095; CHECK: store i32 196  store i32 0, ptr @x97  store atomic i32 42, ptr @y monotonic, align 498  store i32 1, ptr @x99  ret void100}101 102; DSE across monotonic load (forbidden since the eliminated store is atomic)103define i32 @test11() {104; CHECK-LABEL: @test11(105; CHECK-NEXT:    store atomic i32 0, ptr @x monotonic, align 4106; CHECK-NEXT:    [[X:%.*]] = load atomic i32, ptr @y monotonic, align 4107; CHECK-NEXT:    store atomic i32 1, ptr @x monotonic, align 4108; CHECK-NEXT:    ret i32 [[X]]109;110  store atomic i32 0, ptr @x monotonic, align 4111  %x = load atomic i32, ptr @y monotonic, align 4112  store atomic i32 1, ptr @x monotonic, align 4113  ret i32 %x114}115 116; DSE across monotonic store (forbidden since the eliminated store is atomic)117define void @test12() {118; CHECK-LABEL: @test12(119; CHECK-NEXT:    store atomic i32 0, ptr @x monotonic, align 4120; CHECK-NEXT:    store atomic i32 42, ptr @y monotonic, align 4121; CHECK-NEXT:    store atomic i32 1, ptr @x monotonic, align 4122; CHECK-NEXT:    ret void123;124  store atomic i32 0, ptr @x monotonic, align 4125  store atomic i32 42, ptr @y monotonic, align 4126  store atomic i32 1, ptr @x monotonic, align 4127  ret void128}129 130; But DSE is not allowed across a release-acquire pair.131define i32 @test15() {132; CHECK-LABEL: @test15(133; CHECK-NEXT:    store i32 0, ptr @x, align 4134; CHECK-NEXT:    store atomic i32 0, ptr @y release, align 4135; CHECK-NEXT:    [[X:%.*]] = load atomic i32, ptr @y acquire, align 4136; CHECK-NEXT:    store i32 1, ptr @x, align 4137; CHECK-NEXT:    ret i32 [[X]]138;139  store i32 0, ptr @x140  store atomic i32 0, ptr @y release, align 4141  %x = load atomic i32, ptr @y acquire, align 4142  store i32 1, ptr @x143  ret i32 %x144}145 146@z = common global i64 0, align 4147@a = common global i64 0, align 4148 149; Be conservative, do not kill regular store.150define i64 @test_atomicrmw_0() {151; CHECK-LABEL: @test_atomicrmw_0(152; CHECK-NEXT:    store i64 1, ptr @z, align 8153; CHECK-NEXT:    [[RES:%.*]] = atomicrmw add ptr @z, i64 -1 monotonic154; CHECK-NEXT:    ret i64 [[RES]]155;156  store i64 1, ptr @z157  %res = atomicrmw add ptr @z, i64 -1 monotonic158  ret i64 %res159}160 161; Be conservative, do not kill regular store.162define i64 @test_atomicrmw_1() {163; CHECK-LABEL: @test_atomicrmw_1(164; CHECK-NEXT:    store i64 1, ptr @z, align 8165; CHECK-NEXT:    [[RES:%.*]] = atomicrmw add ptr @z, i64 -1 acq_rel166; CHECK-NEXT:    ret i64 [[RES]]167;168  store i64 1, ptr @z169  %res = atomicrmw add ptr @z, i64 -1 acq_rel170  ret i64 %res171}172 173; Monotonic atomicrmw should not block eliminating no-aliasing stores.174define i64 @test_atomicrmw_2() {175; CHECK-LABEL: @test_atomicrmw_2(176; CHECK-NEXT:    [[RES:%.*]] = atomicrmw add ptr @a, i64 -1 monotonic177; CHECK-NEXT:    store i64 2, ptr @z, align 8178; CHECK-NEXT:    ret i64 [[RES]]179;180  store i64 1, ptr @z181  %res = atomicrmw add ptr @a, i64 -1 monotonic182  store i64 2, ptr @z183  ret i64 %res184}185 186; Be conservative, do not eliminate stores across atomic operations > monotonic.187define i64 @test_atomicrmw_3() {188; CHECK-LABEL: @test_atomicrmw_3(189; CHECK-NEXT:    store i64 1, ptr @z, align 8190; CHECK-NEXT:    [[RES:%.*]] = atomicrmw add ptr @a, i64 -1 release191; CHECK-NEXT:    store i64 2, ptr @z, align 8192; CHECK-NEXT:    ret i64 [[RES]]193;194  store i64 1, ptr @z195  %res = atomicrmw add ptr @a, i64 -1 release196  store i64 2, ptr @z197  ret i64 %res198}199 200; Be conservative, do not eliminate may-alias stores.201define i64 @test_atomicrmw_4(ptr %ptr) {202; CHECK-LABEL: @test_atomicrmw_4(203; CHECK-NEXT:    store i64 1, ptr @z, align 8204; CHECK-NEXT:    [[RES:%.*]] = atomicrmw add ptr [[PTR:%.*]], i64 -1 monotonic205; CHECK-NEXT:    store i64 2, ptr @z, align 8206; CHECK-NEXT:    ret i64 [[RES]]207;208  store i64 1, ptr @z209  %res = atomicrmw add ptr %ptr, i64 -1 monotonic210  store i64 2, ptr @z211  ret i64 %res212}213 214; Be conservative, do not eliminate aliasing stores.215define i64 @test_atomicrmw_5() {216; CHECK-LABEL: @test_atomicrmw_5(217; CHECK-NEXT:    store i64 1, ptr @z, align 8218; CHECK-NEXT:    [[RES:%.*]] = atomicrmw add ptr @z, i64 -1 monotonic219; CHECK-NEXT:    store i64 2, ptr @z, align 8220; CHECK-NEXT:    ret i64 [[RES]]221;222  store i64 1, ptr @z223  %res = atomicrmw add ptr @z, i64 -1 monotonic224  store i64 2, ptr @z225  ret i64 %res226}227 228; Be conservative, do not eliminate non-monotonic cmpxchg.229define { i32, i1} @test_cmpxchg_1() {230; CHECK-LABEL: @test_cmpxchg_1(231; CHECK-NEXT:    store i32 1, ptr @x, align 4232; CHECK-NEXT:    [[RET:%.*]] = cmpxchg volatile ptr @x, i32 10, i32 20 seq_cst monotonic233; CHECK-NEXT:    store i32 2, ptr @x, align 4234; CHECK-NEXT:    ret { i32, i1 } [[RET]]235;236  store i32 1, ptr @x237  %ret = cmpxchg volatile ptr @x, i32 10, i32 20 seq_cst monotonic238  store i32 2, ptr @x239  ret { i32, i1 } %ret240}241 242; Monotonic cmpxchg should not block DSE for non-aliasing stores.243define { i32, i1} @test_cmpxchg_2() {244; CHECK-LABEL: @test_cmpxchg_2(245; CHECK-NEXT:    [[RET:%.*]] = cmpxchg volatile ptr @y, i32 10, i32 20 monotonic monotonic246; CHECK-NEXT:    store i32 2, ptr @x, align 4247; CHECK-NEXT:    ret { i32, i1 } [[RET]]248;249  store i32 1, ptr @x250  %ret = cmpxchg volatile ptr @y, i32 10, i32 20 monotonic monotonic251  store i32 2, ptr @x252  ret { i32, i1 } %ret253}254 255; Be conservative, do not eliminate non-monotonic cmpxchg.256define { i32, i1} @test_cmpxchg_3() {257; CHECK-LABEL: @test_cmpxchg_3(258; CHECK-NEXT:    store i32 1, ptr @x, align 4259; CHECK-NEXT:    [[RET:%.*]] = cmpxchg volatile ptr @y, i32 10, i32 20 seq_cst seq_cst260; CHECK-NEXT:    store i32 2, ptr @x, align 4261; CHECK-NEXT:    ret { i32, i1 } [[RET]]262;263  store i32 1, ptr @x264  %ret = cmpxchg volatile ptr @y, i32 10, i32 20 seq_cst seq_cst265  store i32 2, ptr @x266  ret { i32, i1 } %ret267}268 269; Be conservative, do not eliminate may-alias stores.270define { i32, i1} @test_cmpxchg_4(ptr %ptr) {271; CHECK-LABEL: @test_cmpxchg_4(272; CHECK-NEXT:    store i32 1, ptr @x, align 4273; CHECK-NEXT:    [[RET:%.*]] = cmpxchg volatile ptr [[PTR:%.*]], i32 10, i32 20 monotonic monotonic274; CHECK-NEXT:    store i32 2, ptr @x, align 4275; CHECK-NEXT:    ret { i32, i1 } [[RET]]276;277  store i32 1, ptr @x278  %ret = cmpxchg volatile ptr %ptr, i32 10, i32 20 monotonic monotonic279  store i32 2, ptr @x280  ret { i32, i1 } %ret281}282 283; Be conservative, do not eliminate alias stores.284define { i32, i1} @test_cmpxchg_5(ptr %ptr) {285; CHECK-LABEL: @test_cmpxchg_5(286; CHECK-NEXT:    store i32 1, ptr @x, align 4287; CHECK-NEXT:    [[RET:%.*]] = cmpxchg volatile ptr @x, i32 10, i32 20 monotonic monotonic288; CHECK-NEXT:    store i32 2, ptr @x, align 4289; CHECK-NEXT:    ret { i32, i1 } [[RET]]290;291  store i32 1, ptr @x292  %ret = cmpxchg volatile ptr @x, i32 10, i32 20 monotonic monotonic293  store i32 2, ptr @x294  ret { i32, i1 } %ret295}296 297; **** Noop load->store tests **************************************************298 299; We can optimize unordered atomic loads or stores.300define void @test_load_atomic(ptr %Q) {301; CHECK-LABEL: @test_load_atomic(302; CHECK-NEXT:    ret void303;304  %a = load atomic i32, ptr %Q unordered, align 4305  store atomic i32 %a, ptr %Q unordered, align 4306  ret void307}308 309; We can optimize unordered atomic loads or stores.310define void @test_store_atomic(ptr %Q) {311; CHECK-LABEL: @test_store_atomic(312; CHECK-NEXT:    ret void313;314  %a = load i32, ptr %Q315  store atomic i32 %a, ptr %Q unordered, align 4316  ret void317}318 319; We can NOT optimize release atomic loads or stores.320define void @test_store_atomic_release(ptr %Q) {321; CHECK-LABEL: @test_store_atomic_release(322; CHECK-NEXT:    [[A:%.*]] = load i32, ptr [[Q:%.*]], align 4323; CHECK-NEXT:    store atomic i32 [[A]], ptr [[Q]] release, align 4324; CHECK-NEXT:    ret void325;326  %a = load i32, ptr %Q327  store atomic i32 %a, ptr %Q release, align 4328  ret void329}330