1; RUN: opt -S -early-cse < %s | FileCheck %s 2; RUN: opt < %s -S -basicaa -early-cse-memssa | FileCheck %s 3; NOTE: This file is testing the current implementation. Some of 4; the transforms used as negative tests below would be legal, but 5; only if reached through a chain of logic which EarlyCSE is incapable 6; of performing. To say it differently, this file tests a conservative 7; version of the memory model. If we want to extend EarlyCSE to be more 8; aggressive in the future, we may need to relax some of the negative tests. 9 10; We can value forward across the fence since we can (semantically) 11; reorder the following load before the fence. 12define i32 @test(i32* %addr.i) { 13; CHECK-LABEL: @test 14; CHECK: store 15; CHECK: fence 16; CHECK-NOT: load 17; CHECK: ret 18 store i32 5, i32* %addr.i, align 4 19 fence release 20 %a = load i32, i32* %addr.i, align 4 21 ret i32 %a 22} 23 24; Same as above 25define i32 @test2(i32* noalias %addr.i, i32* noalias %otheraddr) { 26; CHECK-LABEL: @test2 27; CHECK: load 28; CHECK: fence 29; CHECK-NOT: load 30; CHECK: ret 31 %a = load i32, i32* %addr.i, align 4 32 fence release 33 %a2 = load i32, i32* %addr.i, align 4 34 %res = sub i32 %a, %a2 35 ret i32 %a 36} 37 38; We can not value forward across an acquire barrier since we might 39; be syncronizing with another thread storing to the same variable 40; followed by a release fence. If this thread observed the release 41; had happened, we must present a consistent view of memory at the 42; fence. Note that it would be legal to reorder '%a' after the fence 43; and then remove '%a2'. The current implementation doesn't know how 44; to do this, but if it learned, this test will need revised. 45define i32 @test3(i32* noalias %addr.i, i32* noalias %otheraddr) { 46; CHECK-LABEL: @test3 47; CHECK: load 48; CHECK: fence 49; CHECK: load 50; CHECK: sub 51; CHECK: ret 52 %a = load i32, i32* %addr.i, align 4 53 fence acquire 54 %a2 = load i32, i32* %addr.i, align 4 55 %res = sub i32 %a, %a2 56 ret i32 %res 57} 58 59; We can not dead store eliminate accross the fence. We could in 60; principal reorder the second store above the fence and then DSE either 61; store, but this is beyond the simple last-store DSE which EarlyCSE 62; implements. 63define void @test4(i32* %addr.i) { 64; CHECK-LABEL: @test4 65; CHECK: store 66; CHECK: fence 67; CHECK: store 68; CHECK: ret 69 store i32 5, i32* %addr.i, align 4 70 fence release 71 store i32 5, i32* %addr.i, align 4 72 ret void 73} 74 75; We *could* DSE across this fence, but don't. No other thread can 76; observe the order of the acquire fence and the store. 77define void @test5(i32* %addr.i) { 78; CHECK-LABEL: @test5 79; CHECK: store 80; CHECK: fence 81; CHECK: store 82; CHECK: ret 83 store i32 5, i32* %addr.i, align 4 84 fence acquire 85 store i32 5, i32* %addr.i, align 4 86 ret void 87} 88