• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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