[sanitizer] Improve FreeBSD ASLR detection
[llvm-project.git] / llvm / test / Transforms / GVN / PRE / volatile.ll
blob1a51388723f1dfdf2122b8f30a90334dd750e13e
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; Tests that check our handling of volatile instructions encountered
3 ; when scanning for dependencies
4 ; RUN: opt -basic-aa -gvn -S < %s | FileCheck %s
6 ; Check that we can bypass a volatile load when searching
7 ; for dependencies of a non-volatile load
8 define i32 @test1(i32* nocapture %p, i32* nocapture %q) {
9 ; CHECK-LABEL: @test1(
10 ; CHECK-NEXT:  entry:
11 ; CHECK-NEXT:    [[TMP0:%.*]] = load volatile i32, i32* [[Q:%.*]], align 4
12 ; CHECK-NEXT:    ret i32 0
14 entry:
15   %x = load i32, i32* %p
16   load volatile i32, i32* %q
17   %y = load i32, i32* %p
18   %add = sub i32 %y, %x
19   ret i32 %add
22 ; We can not value forward if the query instruction is
23 ; volatile, this would be (in effect) removing the volatile load
24 define i32 @test2(i32* nocapture %p, i32* nocapture %q) {
25 ; CHECK-LABEL: @test2(
26 ; CHECK-NEXT:  entry:
27 ; CHECK-NEXT:    [[X:%.*]] = load i32, i32* [[P:%.*]], align 4
28 ; CHECK-NEXT:    [[Y:%.*]] = load volatile i32, i32* [[P]], align 4
29 ; CHECK-NEXT:    [[ADD:%.*]] = sub i32 [[Y]], [[X]]
30 ; CHECK-NEXT:    ret i32 [[ADD]]
32 entry:
33   %x = load i32, i32* %p
34   %y = load volatile i32, i32* %p
35   %add = sub i32 %y, %x
36   ret i32 %add
39 ; If the query instruction is itself volatile, we *cannot*
40 ; reorder it even if p and q are noalias
41 define i32 @test3(i32* noalias nocapture %p, i32* noalias nocapture %q) {
42 ; CHECK-LABEL: @test3(
43 ; CHECK-NEXT:  entry:
44 ; CHECK-NEXT:    [[X:%.*]] = load i32, i32* [[P:%.*]], align 4
45 ; CHECK-NEXT:    [[TMP0:%.*]] = load volatile i32, i32* [[Q:%.*]], align 4
46 ; CHECK-NEXT:    [[Y:%.*]] = load volatile i32, i32* [[P]], align 4
47 ; CHECK-NEXT:    [[ADD:%.*]] = sub i32 [[Y]], [[X]]
48 ; CHECK-NEXT:    ret i32 [[ADD]]
50 entry:
51   %x = load i32, i32* %p
52   load volatile i32, i32* %q
53   %y = load volatile i32, i32* %p
54   %add = sub i32 %y, %x
55   ret i32 %add
58 ; If an encountered instruction is both volatile and ordered,
59 ; we need to use the strictest ordering of either.  In this
60 ; case, the ordering prevents forwarding.
61 define i32 @test4(i32* noalias nocapture %p, i32* noalias nocapture %q) {
62 ; CHECK-LABEL: @test4(
63 ; CHECK-NEXT:  entry:
64 ; CHECK-NEXT:    [[X:%.*]] = load i32, i32* [[P:%.*]], align 4
65 ; CHECK-NEXT:    [[TMP0:%.*]] = load atomic volatile i32, i32* [[Q:%.*]] seq_cst, align 4
66 ; CHECK-NEXT:    [[Y:%.*]] = load atomic i32, i32* [[P]] seq_cst, align 4
67 ; CHECK-NEXT:    [[ADD:%.*]] = sub i32 [[Y]], [[X]]
68 ; CHECK-NEXT:    ret i32 [[ADD]]
70 entry:
71   %x = load i32, i32* %p
72   load atomic volatile i32, i32* %q seq_cst, align 4
73   %y = load atomic i32, i32* %p seq_cst, align 4
74   %add = sub i32 %y, %x
75   ret i32 %add
78 ; Value forwarding from a volatile load is perfectly legal
79 define i32 @test5(i32* nocapture %p, i32* nocapture %q) {
80 ; CHECK-LABEL: @test5(
81 ; CHECK-NEXT:  entry:
82 ; CHECK-NEXT:    [[X:%.*]] = load volatile i32, i32* [[P:%.*]], align 4
83 ; CHECK-NEXT:    ret i32 0
85 entry:
86   %x = load volatile i32, i32* %p
87   %y = load i32, i32* %p
88   %add = sub i32 %y, %x
89   ret i32 %add
92 ; Does cross block redundancy elimination work with volatiles?
93 define i32 @test6(i32* noalias nocapture %p, i32* noalias nocapture %q) {
94 ; CHECK-LABEL: @test6(
95 ; CHECK-NEXT:  entry:
96 ; CHECK-NEXT:    [[Y1:%.*]] = load i32, i32* [[P:%.*]], align 4
97 ; CHECK-NEXT:    call void @use(i32 [[Y1]])
98 ; CHECK-NEXT:    br label [[HEADER:%.*]]
99 ; CHECK:       header:
100 ; CHECK-NEXT:    [[X:%.*]] = load volatile i32, i32* [[Q:%.*]], align 4
101 ; CHECK-NEXT:    [[ADD:%.*]] = sub i32 [[Y1]], [[X]]
102 ; CHECK-NEXT:    [[CND:%.*]] = icmp eq i32 [[ADD]], 0
103 ; CHECK-NEXT:    br i1 [[CND]], label [[EXIT:%.*]], label [[HEADER]]
104 ; CHECK:       exit:
105 ; CHECK-NEXT:    ret i32 0
107 entry:
108   %y1 = load i32, i32* %p
109   call void @use(i32 %y1)
110   br label %header
111 header:
112   %x = load volatile i32, i32* %q
113   %y = load i32, i32* %p
114   %add = sub i32 %y, %x
115   %cnd = icmp eq i32 %add, 0
116   br i1 %cnd, label %exit, label %header
117 exit:
118   ret i32 %add
121 ; Does cross block PRE work with volatiles?
122 define i32 @test7(i1 %c, i32* noalias nocapture %p, i32* noalias nocapture %q) {
123 ; CHECK-LABEL: @test7(
124 ; CHECK-NEXT:  entry:
125 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[ENTRY_HEADER_CRIT_EDGE:%.*]], label [[SKIP:%.*]]
126 ; CHECK:       entry.header_crit_edge:
127 ; CHECK-NEXT:    [[Y_PRE:%.*]] = load i32, i32* [[P:%.*]], align 4
128 ; CHECK-NEXT:    br label [[HEADER:%.*]]
129 ; CHECK:       skip:
130 ; CHECK-NEXT:    [[Y1:%.*]] = load i32, i32* [[P]], align 4
131 ; CHECK-NEXT:    call void @use(i32 [[Y1]])
132 ; CHECK-NEXT:    br label [[HEADER]]
133 ; CHECK:       header:
134 ; CHECK-NEXT:    [[Y:%.*]] = phi i32 [ [[Y_PRE]], [[ENTRY_HEADER_CRIT_EDGE]] ], [ [[Y]], [[HEADER]] ], [ [[Y1]], [[SKIP]] ]
135 ; CHECK-NEXT:    [[X:%.*]] = load volatile i32, i32* [[Q:%.*]], align 4
136 ; CHECK-NEXT:    [[ADD:%.*]] = sub i32 [[Y]], [[X]]
137 ; CHECK-NEXT:    [[CND:%.*]] = icmp eq i32 [[ADD]], 0
138 ; CHECK-NEXT:    br i1 [[CND]], label [[EXIT:%.*]], label [[HEADER]]
139 ; CHECK:       exit:
140 ; CHECK-NEXT:    ret i32 0
142 entry:
143   br i1 %c, label %header, label %skip
144 skip:
145   %y1 = load i32, i32* %p
146   call void @use(i32 %y1)
147   br label %header
148 header:
149   %x = load volatile i32, i32* %q
150   %y = load i32, i32* %p
151   %add = sub i32 %y, %x
152   %cnd = icmp eq i32 %add, 0
153   br i1 %cnd, label %exit, label %header
154 exit:
155   ret i32 %add
158 ; Another volatile PRE case - two paths through a loop
159 ; load in preheader, one path read only, one not
160 define i32 @test8(i1 %b, i1 %c, i32* noalias %p, i32* noalias %q) {
161 ; CHECK-LABEL: @test8(
162 ; CHECK-NEXT:  entry:
163 ; CHECK-NEXT:    [[Y1:%.*]] = load i32, i32* [[P:%.*]], align 4
164 ; CHECK-NEXT:    call void @use(i32 [[Y1]])
165 ; CHECK-NEXT:    br label [[HEADER:%.*]]
166 ; CHECK:       header:
167 ; CHECK-NEXT:    [[Y:%.*]] = phi i32 [ [[Y_PRE:%.*]], [[SKIP_HEADER_CRIT_EDGE:%.*]] ], [ [[Y]], [[HEADER]] ], [ [[Y1]], [[ENTRY:%.*]] ]
168 ; CHECK-NEXT:    [[X:%.*]] = load volatile i32, i32* [[Q:%.*]], align 4
169 ; CHECK-NEXT:    call void @use(i32 [[Y]])
170 ; CHECK-NEXT:    br i1 [[B:%.*]], label [[SKIP:%.*]], label [[HEADER]]
171 ; CHECK:       skip:
172 ; CHECK-NEXT:    call void @clobber(i32* [[P]], i32* [[Q]])
173 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[SKIP_HEADER_CRIT_EDGE]], label [[EXIT:%.*]]
174 ; CHECK:       skip.header_crit_edge:
175 ; CHECK-NEXT:    [[Y_PRE]] = load i32, i32* [[P]], align 4
176 ; CHECK-NEXT:    br label [[HEADER]]
177 ; CHECK:       exit:
178 ; CHECK-NEXT:    [[ADD:%.*]] = sub i32 [[Y]], [[X]]
179 ; CHECK-NEXT:    ret i32 [[ADD]]
181 entry:
182   %y1 = load i32, i32* %p
183   call void @use(i32 %y1)
184   br label %header
185 header:
186   %x = load volatile i32, i32* %q
187   %y = load i32, i32* %p
188   call void @use(i32 %y)
189   br i1 %b, label %skip, label %header
190 skip:
191   ; escaping the arguments is explicitly required since we marked
192   ; them noalias
193   call void @clobber(i32* %p, i32* %q)
194   br i1 %c, label %header, label %exit
195 exit:
196   %add = sub i32 %y, %x
197   ret i32 %add
200 ; This test checks that we don't optimize away instructions that are
201 ; simplified by SimplifyInstruction(), but are not trivially dead.
203 define i32 @test9(i32* %V) {
204 ; CHECK-LABEL: @test9(
205 ; CHECK-NEXT:  entry:
206 ; CHECK-NEXT:    [[LOAD:%.*]] = call i32 undef()
207 ; CHECK-NEXT:    ret i32 poison
209 entry:
210   %load = call i32 undef()
211   ret i32 %load
214 declare void @use(i32) readonly
215 declare void @clobber(i32* %p, i32* %q)
217 !0 = !{ i32 0, i32 1 }