xref: /llvm-project/llvm/test/Transforms/GVN/volatile-nonvolatile.ll (revision 23abf931386002fb9d2c11d026846475c224c641)
1; RUN: opt -passes=gvn -S < %s | FileCheck %s
2
3%struct.t = type { ptr }
4
5; The loaded address and the location of the address itself are not aliased,
6; so the second reload is not necessary. Check that it can be eliminated.
7; CHECK-LABEL: test1
8; CHECK: load
9; CHECK-NOT: load
10define void @test1(ptr nocapture readonly %p, i32 %v) #0 {
11entry:
12  %0 = load ptr, ptr %p, align 4, !tbaa !1
13  store volatile i32 %v, ptr %0, align 4, !tbaa !6
14  %1 = load ptr, ptr %p, align 4, !tbaa !1
15  store volatile i32 %v, ptr %1, align 4, !tbaa !6
16  ret void
17}
18
19; The store via the loaded address may overwrite the address itself.
20; Make sure that both loads remain.
21; CHECK-LABEL: test2
22; CHECK: load
23; CHECK: store
24; CHECK: load
25define void @test2(ptr nocapture readonly %p, i32 %v) #0 {
26entry:
27  %0 = load ptr, ptr %p, align 4, !tbaa !1
28  store volatile i32 %v, ptr %0, align 4, !tbaa !1
29  %1 = load ptr, ptr %p, align 4, !tbaa !1
30  store volatile i32 %v, ptr %1, align 4, !tbaa !1
31  ret void
32}
33
34; The loads are ordered and non-monotonic. Although they are not aliased to
35; the stores, make sure both are preserved.
36; CHECK-LABEL: test3
37; CHECK: load
38; CHECK: store
39; CHECK: load
40define void @test3(ptr nocapture readonly %p, i32 %v) #0 {
41entry:
42  %0 = load atomic ptr, ptr %p acquire, align 4, !tbaa !1
43  store volatile i32 %v, ptr %0, align 4, !tbaa !6
44  %1 = load atomic ptr, ptr %p acquire, align 4, !tbaa !1
45  store volatile i32 %v, ptr %1, align 4, !tbaa !6
46  ret void
47}
48
49attributes #0 = { norecurse nounwind }
50
51!1 = !{!2, !3, i64 0}
52!2 = !{!"", !3, i64 0}
53!3 = !{!"any pointer", !4, i64 0}
54!4 = !{!"omnipotent char", !5, i64 0}
55!5 = !{!"Simple C/C++ TBAA"}
56!6 = !{!7, !7, i64 0}
57!7 = !{!"int", !4, i64 0}
58
59