brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.7 KiB · da96961 Raw
307 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 5define i32 @test12(i1 %B, ptr %P1, ptr %P2) {6; CHECK-LABEL: @test12(7; CHECK-NEXT:    [[LOAD0:%.*]] = load i32, ptr [[P1:%.*]], align 48; CHECK-NEXT:    [[TMP1:%.*]] = load atomic i32, ptr [[P2:%.*]] seq_cst, align 49; CHECK-NEXT:    [[LOAD1:%.*]] = load i32, ptr [[P1]], align 410; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[B:%.*]], i32 [[LOAD0]], i32 [[LOAD1]]11; CHECK-NEXT:    ret i32 [[SEL]]12;13  %load0 = load i32, ptr %P114  %1 = load atomic i32, ptr %P2 seq_cst, align 415  %load1 = load i32, ptr %P116  %sel = select i1 %B, i32 %load0, i32 %load117  ret i32 %sel18}19 20; atomic to non-atomic forwarding is legal21define i32 @test13(i1 %B, ptr %P1) {22; CHECK-LABEL: @test13(23; CHECK-NEXT:    [[A:%.*]] = load atomic i32, ptr [[P1:%.*]] seq_cst, align 424; CHECK-NEXT:    ret i32 025;26  %a = load atomic i32, ptr %P1 seq_cst, align 427  %b = load i32, ptr %P128  %res = sub i32 %a, %b29  ret i32 %res30}31 32; atomic to unordered atomic forwarding is legal33define i32 @test14(i1 %B, ptr %P1) {34; CHECK-LABEL: @test14(35; CHECK-NEXT:    [[A:%.*]] = load atomic i32, ptr [[P1:%.*]] seq_cst, align 436; CHECK-NEXT:    ret i32 037;38  %a = load atomic i32, ptr %P1 seq_cst, align 439  %b = load atomic i32, ptr %P1 unordered, align 440  %res = sub i32 %a, %b41  ret i32 %res42}43 44; implementation restriction: can't forward to stonger45; than unordered46define i32 @test15(i1 %B, ptr %P1, ptr %P2) {47; CHECK-LABEL: @test15(48; CHECK-NEXT:    [[A:%.*]] = load atomic i32, ptr [[P1:%.*]] seq_cst, align 449; CHECK-NEXT:    [[B:%.*]] = load atomic i32, ptr [[P1]] seq_cst, align 450; CHECK-NEXT:    [[RES:%.*]] = sub i32 [[A]], [[B]]51; CHECK-NEXT:    ret i32 [[RES]]52;53  %a = load atomic i32, ptr %P1 seq_cst, align 454  %b = load atomic i32, ptr %P1 seq_cst, align 455  %res = sub i32 %a, %b56  ret i32 %res57}58 59; forwarding non-atomic to atomic is wrong! (However,60; it would be legal to use the later value in place of the61; former in this particular example.  We just don't62; do that right now.)63define i32 @test16(i1 %B, ptr %P1, ptr %P2) {64; CHECK-LABEL: @test16(65; CHECK-NEXT:    [[A:%.*]] = load i32, ptr [[P1:%.*]], align 466; CHECK-NEXT:    [[B:%.*]] = load atomic i32, ptr [[P1]] unordered, align 467; CHECK-NEXT:    [[RES:%.*]] = sub i32 [[A]], [[B]]68; CHECK-NEXT:    ret i32 [[RES]]69;70  %a = load i32, ptr %P1, align 471  %b = load atomic i32, ptr %P1 unordered, align 472  %res = sub i32 %a, %b73  ret i32 %res74}75 76; Can't DSE across a full fence77define void @fence_seq_cst_store(i1 %B, ptr %P1, ptr %P2) {78; CHECK-LABEL: @fence_seq_cst_store(79; CHECK-NEXT:    store i32 0, ptr [[P1:%.*]], align 480; CHECK-NEXT:    store atomic i32 0, ptr [[P2:%.*]] seq_cst, align 481; CHECK-NEXT:    store i32 0, ptr [[P1]], align 482; CHECK-NEXT:    ret void83;84  store i32 0, ptr %P1, align 485  store atomic i32 0, ptr %P2 seq_cst, align 486  store i32 0, ptr %P1, align 487  ret void88}89 90; Can't DSE across a full fence91define void @fence_seq_cst(i1 %B, ptr %P1, ptr %P2) {92; CHECK-LABEL: @fence_seq_cst(93; CHECK-NEXT:    store i32 0, ptr [[P1:%.*]], align 494; CHECK-NEXT:    fence seq_cst95; CHECK-NEXT:    store i32 0, ptr [[P1]], align 496; CHECK-NEXT:    ret void97;98  store i32 0, ptr %P1, align 499  fence seq_cst100  store i32 0, ptr %P1, align 4101  ret void102}103 104; Can't DSE across a full fence105define void @fence_asm_sideeffect(i1 %B, ptr %P1, ptr %P2) {106; CHECK-LABEL: @fence_asm_sideeffect(107; CHECK-NEXT:    store i32 0, ptr [[P1:%.*]], align 4108; CHECK-NEXT:    call void asm sideeffect "", ""()109; CHECK-NEXT:    store i32 0, ptr [[P1]], align 4110; CHECK-NEXT:    ret void111;112  store i32 0, ptr %P1, align 4113  call void asm sideeffect "", ""()114  store i32 0, ptr %P1, align 4115  ret void116}117 118; Can't DSE across a full fence119define void @fence_asm_memory(i1 %B, ptr %P1, ptr %P2) {120; CHECK-LABEL: @fence_asm_memory(121; CHECK-NEXT:    store i32 0, ptr [[P1:%.*]], align 4122; CHECK-NEXT:    call void asm "", "~{memory}"()123; CHECK-NEXT:    store i32 0, ptr [[P1]], align 4124; CHECK-NEXT:    ret void125;126  store i32 0, ptr %P1, align 4127  call void asm "", "~{memory}"()128  store i32 0, ptr %P1, align 4129  ret void130}131 132; Can't remove a volatile load133define i32 @volatile_load(i1 %B, ptr %P1, ptr %P2) {134; CHECK-LABEL: @volatile_load(135; CHECK-NEXT:    [[A:%.*]] = load i32, ptr [[P1:%.*]], align 4136; CHECK-NEXT:    [[B:%.*]] = load volatile i32, ptr [[P1]], align 4137; CHECK-NEXT:    [[RES:%.*]] = sub i32 [[A]], [[B]]138; CHECK-NEXT:    ret i32 [[RES]]139;140  %a = load i32, ptr %P1, align 4141  %b = load volatile i32, ptr %P1, align 4142  %res = sub i32 %a, %b143  ret i32 %res144}145 146; Can't remove redundant volatile loads147define i32 @redundant_volatile_load(i1 %B, ptr %P1, ptr %P2) {148; CHECK-LABEL: @redundant_volatile_load(149; CHECK-NEXT:    [[A:%.*]] = load volatile i32, ptr [[P1:%.*]], align 4150; CHECK-NEXT:    [[B:%.*]] = load volatile i32, ptr [[P1]], align 4151; CHECK-NEXT:    [[RES:%.*]] = sub i32 [[A]], [[B]]152; CHECK-NEXT:    ret i32 [[RES]]153;154  %a = load volatile i32, ptr %P1, align 4155  %b = load volatile i32, ptr %P1, align 4156  %res = sub i32 %a, %b157  ret i32 %res158}159 160; Can't DSE a volatile store161define void @volatile_store(i1 %B, ptr %P1, ptr %P2) {162; CHECK-LABEL: @volatile_store(163; CHECK-NEXT:    store volatile i32 0, ptr [[P1:%.*]], align 4164; CHECK-NEXT:    store i32 3, ptr [[P1]], align 4165; CHECK-NEXT:    ret void166;167  store volatile i32 0, ptr %P1, align 4168  store i32 3, ptr %P1, align 4169  ret void170}171 172; Can't DSE a redundant volatile store173define void @redundant_volatile_store(i1 %B, ptr %P1, ptr %P2) {174; CHECK-LABEL: @redundant_volatile_store(175; CHECK-NEXT:    store volatile i32 0, ptr [[P1:%.*]], align 4176; CHECK-NEXT:    store volatile i32 0, ptr [[P1]], align 4177; CHECK-NEXT:    ret void178;179  store volatile i32 0, ptr %P1, align 4180  store volatile i32 0, ptr %P1, align 4181  ret void182}183 184; Can value forward from volatiles185define i32 @test20(i1 %B, ptr %P1, ptr %P2) {186; CHECK-LABEL: @test20(187; CHECK-NEXT:    [[A:%.*]] = load volatile i32, ptr [[P1:%.*]], align 4188; CHECK-NEXT:    ret i32 0189;190  %a = load volatile i32, ptr %P1, align 4191  %b = load i32, ptr %P1, align 4192  %res = sub i32 %a, %b193  ret i32 %res194}195 196; Can DSE a non-volatile store in favor of a volatile one197; currently a missed optimization198define void @test21(i1 %B, ptr %P1, ptr %P2) {199; CHECK-LABEL: @test21(200; CHECK-NEXT:    store i32 0, ptr [[P1:%.*]], align 4201; CHECK-NEXT:    store volatile i32 3, ptr [[P1]], align 4202; CHECK-NEXT:    ret void203;204  store i32 0, ptr %P1, align 4205  store volatile i32 3, ptr %P1, align 4206  ret void207}208 209; Can DSE a normal store in favor of a unordered one210define void @test22(i1 %B, ptr %P1, ptr %P2) {211; CHECK-LABEL: @test22(212; CHECK-NEXT:    store atomic i32 3, ptr [[P1:%.*]] unordered, align 4213; CHECK-NEXT:    ret void214;215  store i32 0, ptr %P1, align 4216  store atomic i32 3, ptr %P1 unordered, align 4217  ret void218}219 220; Can also DSE a unordered store in favor of a normal one221define void @test23(i1 %B, ptr %P1, ptr %P2) {222; CHECK-LABEL: @test23(223; CHECK-NEXT:    store i32 0, ptr [[P1:%.*]], align 4224; CHECK-NEXT:    ret void225;226  store atomic i32 3, ptr %P1 unordered, align 4227  store i32 0, ptr %P1, align 4228  ret void229}230 231; As an implementation limitation, can't remove ordered stores232; Note that we could remove the earlier store if we could233; represent the required ordering.234define void @test24(i1 %B, ptr %P1, ptr %P2) {235; CHECK-LABEL: @test24(236; CHECK-NEXT:    store atomic i32 3, ptr [[P1:%.*]] release, align 4237; CHECK-NEXT:    store i32 0, ptr [[P1]], align 4238; CHECK-NEXT:    ret void239;240  store atomic i32 3, ptr %P1 release, align 4241  store i32 0, ptr %P1, align 4242  ret void243}244 245; Can't remove volatile stores - each is independently observable and246; the count of such stores is an observable program side effect.247define void @test25(i1 %B, ptr %P1, ptr %P2) {248; CHECK-LABEL: @test25(249; CHECK-NEXT:    store volatile i32 3, ptr [[P1:%.*]], align 4250; CHECK-NEXT:    store volatile i32 0, ptr [[P1]], align 4251; CHECK-NEXT:    ret void252;253  store volatile i32 3, ptr %P1, align 4254  store volatile i32 0, ptr %P1, align 4255  ret void256}257 258; Can DSE a unordered store in favor of a unordered one259define void @test26(i1 %B, ptr %P1, ptr %P2) {260; CHECK-LABEL: @test26(261; CHECK-NEXT:    store atomic i32 3, ptr [[P1:%.*]] unordered, align 4262; CHECK-NEXT:    ret void263;264  store atomic i32 0, ptr %P1 unordered, align 4265  store atomic i32 3, ptr %P1 unordered, align 4266  ret void267}268 269; Can DSE a unordered store in favor of a ordered one,270; but current don't due to implementation limits271define void @test27(i1 %B, ptr %P1, ptr %P2) {272; CHECK-LABEL: @test27(273; CHECK-NEXT:    store atomic i32 0, ptr [[P1:%.*]] unordered, align 4274; CHECK-NEXT:    store atomic i32 3, ptr [[P1]] release, align 4275; CHECK-NEXT:    ret void276;277  store atomic i32 0, ptr %P1 unordered, align 4278  store atomic i32 3, ptr %P1 release, align 4279  ret void280}281 282; Can DSE an unordered atomic store in favor of an283; ordered one, but current don't due to implementation limits284define void @test28(i1 %B, ptr %P1, ptr %P2) {285; CHECK-LABEL: @test28(286; CHECK-NEXT:    store atomic i32 0, ptr [[P1:%.*]] unordered, align 4287; CHECK-NEXT:    store atomic i32 3, ptr [[P1]] release, align 4288; CHECK-NEXT:    ret void289;290  store atomic i32 0, ptr %P1 unordered, align 4291  store atomic i32 3, ptr %P1 release, align 4292  ret void293}294 295; As an implementation limitation, can't remove ordered stores296; see also: @test24297define void @test29(i1 %B, ptr %P1, ptr %P2) {298; CHECK-LABEL: @test29(299; CHECK-NEXT:    store atomic i32 3, ptr [[P1:%.*]] release, align 4300; CHECK-NEXT:    store atomic i32 0, ptr [[P1]] unordered, align 4301; CHECK-NEXT:    ret void302;303  store atomic i32 3, ptr %P1 release, align 4304  store atomic i32 0, ptr %P1 unordered, align 4305  ret void306}307