1; RUN: opt -tbaa -gvn -S < %s | FileCheck %s 2 3%struct.t = type { i32* } 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(%struct.t* nocapture readonly %p, i32 %v) #0 { 11entry: 12 %m = getelementptr inbounds %struct.t, %struct.t* %p, i32 0, i32 0 13 %0 = load i32*, i32** %m, align 4, !tbaa !1 14 store volatile i32 %v, i32* %0, align 4, !tbaa !6 15 %1 = load i32*, i32** %m, align 4, !tbaa !1 16 store volatile i32 %v, i32* %1, align 4, !tbaa !6 17 ret void 18} 19 20; The store via the loaded address may overwrite the address itself. 21; Make sure that both loads remain. 22; CHECK-LABEL: test2 23; CHECK: load 24; CHECK: store 25; CHECK: load 26define void @test2(%struct.t* nocapture readonly %p, i32 %v) #0 { 27entry: 28 %m = getelementptr inbounds %struct.t, %struct.t* %p, i32 0, i32 0 29 %0 = load i32*, i32** %m, align 4, !tbaa !1 30 store volatile i32 %v, i32* %0, align 4, !tbaa !1 31 %1 = load i32*, i32** %m, align 4, !tbaa !1 32 store volatile i32 %v, i32* %1, align 4, !tbaa !1 33 ret void 34} 35 36; The loads are ordered and non-monotonic. Although they are not aliased to 37; the stores, make sure both are preserved. 38; CHECK-LABEL: test3 39; CHECK: load 40; CHECK: store 41; CHECK: load 42define void @test3(%struct.t* nocapture readonly %p, i32 %v) #0 { 43entry: 44 %m = getelementptr inbounds %struct.t, %struct.t* %p, i32 0, i32 0 45 %0 = load atomic i32*, i32** %m acquire, align 4, !tbaa !1 46 store volatile i32 %v, i32* %0, align 4, !tbaa !6 47 %1 = load atomic i32*, i32** %m acquire, align 4, !tbaa !1 48 store volatile i32 %v, i32* %1, align 4, !tbaa !6 49 ret void 50} 51 52attributes #0 = { norecurse nounwind } 53 54!1 = !{!2, !3, i64 0} 55!2 = !{!"", !3, i64 0} 56!3 = !{!"any pointer", !4, i64 0} 57!4 = !{!"omnipotent char", !5, i64 0} 58!5 = !{!"Simple C/C++ TBAA"} 59!6 = !{!7, !7, i64 0} 60!7 = !{!"int", !4, i64 0} 61 62