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. 11 define 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 24 define 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. 44 define 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. 62 define 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. 76 define 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