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