2 ; RUN: opt -S -passes=newgvn < %s | FileCheck %s
4 @a = external constant i32
5 ; We can value forward across the fence since we can (semantically)
6 ; reorder the following load before the fence.
7 define i32 @test(ptr %addr.i) {
13 store i32 5, ptr %addr.i, align 4
15 %a = load i32, ptr %addr.i, align 4
20 define i32 @test2(ptr %addr.i) {
25 %a = load i32, ptr %addr.i, align 4
27 %a2 = load i32, ptr %addr.i, align 4
28 %res = sub i32 %a, %a2
32 ; We can not value forward across an acquire barrier since we might
33 ; be syncronizing with another thread storing to the same variable
34 ; followed by a release fence. This is not so much enforcing an
35 ; ordering property (though it is that too), but a liveness
36 ; property. We expect to eventually see the value of store by
37 ; another thread when spinning on that location.
38 define i32 @test3(ptr noalias %addr.i, ptr noalias %otheraddr) {
44 ; the following code is intented to model the unrolling of
45 ; two iterations in a spin loop of the form:
46 ; do { fence acquire: tmp = *%addr.i; ) while (!tmp);
47 ; It's hopefully clear that allowing PRE to turn this into:
48 ; if (!*%addr.i) while(true) {} would be unfortunate
50 %a = load i32, ptr %addr.i, align 4
52 %a2 = load i32, ptr %addr.i, align 4
53 %res = sub i32 %a, %a2
57 ; We can forward the value forward the load
58 ; across both the fences, because the load is from
59 ; a constant memory location.
60 define i32 @test4(ptr %addr) {
63 ; CHECK: fence release
65 ; CHECK: fence seq_cst
67 %var = load i32, ptr @a
69 store i32 42, ptr %addr, align 8
71 %var2 = load i32, ptr @a
72 %var3 = sub i32 %var, %var2
76 ; Another example of why forwarding across an acquire fence is problematic
77 ; can be seen in a normal locking operation. Say we had:
78 ; *p = 5; unlock(l); lock(l); use(p);
79 ; forwarding the store to p would be invalid. A reasonable implementation
80 ; of unlock and lock might be:
81 ; unlock() { atomicrmw sub %l, 1 unordered; fence release }
84 ; %res = cmpxchg %p, 0, 1, monotonic monotonic
85 ; } while(!%res.success)
88 ; Given we chose to forward across the release fence, we clearly can't forward
89 ; across the acquire fence as well.