1 ; Tests that check our handling of volatile instructions encountered
2 ; when scanning for dependencies
3 ; RUN: opt -basicaa -gvn -S < %s | FileCheck %s
5 ; Check that we can bypass a volatile load when searching
6 ; for dependencies of a non-volatile load
7 define i32 @test1(i32* nocapture %p, i32* nocapture %q) {
9 ; CHECK: %0 = load volatile i32, i32* %q
10 ; CHECK-NEXT: ret i32 0
12 %x = load i32, i32* %p
13 load volatile i32, i32* %q
14 %y = load i32, i32* %p
19 ; We can not value forward if the query instruction is
20 ; volatile, this would be (in effect) removing the volatile load
21 define i32 @test2(i32* nocapture %p, i32* nocapture %q) {
23 ; CHECK: %x = load i32, i32* %p
24 ; CHECK-NEXT: %y = load volatile i32, i32* %p
25 ; CHECK-NEXT: %add = sub i32 %y, %x
27 %x = load i32, i32* %p
28 %y = load volatile i32, i32* %p
33 ; If the query instruction is itself volatile, we *cannot*
34 ; reorder it even if p and q are noalias
35 define i32 @test3(i32* noalias nocapture %p, i32* noalias nocapture %q) {
37 ; CHECK: %x = load i32, i32* %p
38 ; CHECK-NEXT: %0 = load volatile i32, i32* %q
39 ; CHECK-NEXT: %y = load volatile i32, i32* %p
41 %x = load i32, i32* %p
42 load volatile i32, i32* %q
43 %y = load volatile i32, i32* %p
48 ; If an encountered instruction is both volatile and ordered,
49 ; we need to use the strictest ordering of either. In this
50 ; case, the ordering prevents forwarding.
51 define i32 @test4(i32* noalias nocapture %p, i32* noalias nocapture %q) {
53 ; CHECK: %x = load i32, i32* %p
54 ; CHECK-NEXT: %0 = load atomic volatile i32, i32* %q seq_cst
55 ; CHECK-NEXT: %y = load atomic i32, i32* %p seq_cst
57 %x = load i32, i32* %p
58 load atomic volatile i32, i32* %q seq_cst, align 4
59 %y = load atomic i32, i32* %p seq_cst, align 4
64 ; Value forwarding from a volatile load is perfectly legal
65 define i32 @test5(i32* nocapture %p, i32* nocapture %q) {
67 ; CHECK: %x = load volatile i32, i32* %p
68 ; CHECK-NEXT: ret i32 0
70 %x = load volatile i32, i32* %p
71 %y = load i32, i32* %p
76 ; Does cross block redundancy elimination work with volatiles?
77 define i32 @test6(i32* noalias nocapture %p, i32* noalias nocapture %q) {
79 ; CHECK: %y1 = load i32, i32* %p
81 ; CHECK: %x = load volatile i32, i32* %q
82 ; CHECK-NEXT: %add = sub i32 %y1, %x
84 %y1 = load i32, i32* %p
85 call void @use(i32 %y1)
88 %x = load volatile i32, i32* %q
89 %y = load i32, i32* %p
91 %cnd = icmp eq i32 %add, 0
92 br i1 %cnd, label %exit, label %header
97 ; Does cross block PRE work with volatiles?
98 define i32 @test7(i1 %c, i32* noalias nocapture %p, i32* noalias nocapture %q) {
100 ; CHECK-LABEL: entry.header_crit_edge:
101 ; CHECK: %y.pre = load i32, i32* %p
103 ; CHECK: %y1 = load i32, i32* %p
104 ; CHECK-LABEL: header:
105 ; CHECK: %y = phi i32
106 ; CHECK-NEXT: %x = load volatile i32, i32* %q
107 ; CHECK-NEXT: %add = sub i32 %y, %x
109 br i1 %c, label %header, label %skip
111 %y1 = load i32, i32* %p
112 call void @use(i32 %y1)
115 %x = load volatile i32, i32* %q
116 %y = load i32, i32* %p
117 %add = sub i32 %y, %x
118 %cnd = icmp eq i32 %add, 0
119 br i1 %cnd, label %exit, label %header
124 ; Another volatile PRE case - two paths through a loop
125 ; load in preheader, one path read only, one not
126 define i32 @test8(i1 %b, i1 %c, i32* noalias %p, i32* noalias %q) {
129 ; CHECK: %y1 = load i32, i32* %p
130 ; CHECK-LABEL: header:
131 ; CHECK: %y = phi i32
132 ; CHECK-NEXT: %x = load volatile i32, i32* %q
134 ; CHECK-LABEL: skip.header_crit_edge:
135 ; CHECK: %y.pre = load i32, i32* %p
137 %y1 = load i32, i32* %p
138 call void @use(i32 %y1)
141 %x = load volatile i32, i32* %q
142 %y = load i32, i32* %p
143 call void @use(i32 %y)
144 br i1 %b, label %skip, label %header
146 ; escaping the arguments is explicitly required since we marked
148 call void @clobber(i32* %p, i32* %q)
149 br i1 %c, label %header, label %exit
151 %add = sub i32 %y, %x
155 define i32 @test9(i32* %V) {
157 %load = load volatile i32, i32* %V, !range !0
161 ; CHECK: load volatile
164 declare void @use(i32) readonly
165 declare void @clobber(i32* %p, i32* %q)
167 !0 = !{ i32 0, i32 1 }