1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 19:23:23 +01:00
llvm-mirror/test/Transforms/NewGVN/volatile-nonvolatile.ll
Daniel Berlin abebf8ad17 AliasAnalysis: Be less conservative about volatile than atomic.
Summary:
getModRefInfo is meant to answer the question "what impact does this
instruction have on a given memory location" (not even another
instruction).

Long debate on this on IRC comes to the conclusion the answer should be "nothing special".

That is, a noalias volatile store does not affect a memory location
just by being volatile.  Note: DSE and GVN and memdep currently
believe this, because memdep just goes behind AA's back after it says
"modref" right now.

see line 635 of memdep. Prior to this patch we would get modref there, then check aliasing,
and if it said noalias, we would continue.

getModRefInfo *already* has this same AA check, it just wasn't being used because volatile was
lumped in with ordering.

(I am separately testing whether this code in memdep is now dead except for the invariant load case)

Reviewers: jyknight, chandlerc

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D31726

llvm-svn: 299741
2017-04-07 01:28:36 +00:00

62 lines
1.9 KiB
LLVM

; RUN: opt -tbaa -newgvn -S < %s | FileCheck %s
%struct.t = type { i32* }
; The loaded address and the location of the address itself are not aliased,
; so the second reload is not necessary. Check that it can be eliminated.
; CHECK-LABEL: test1
; CHECK: load
; CHECK-NOT: load
define void @test1(%struct.t* nocapture readonly %p, i32 %v) #0 {
entry:
%m = getelementptr inbounds %struct.t, %struct.t* %p, i32 0, i32 0
%0 = load i32*, i32** %m, align 4, !tbaa !1
store volatile i32 %v, i32* %0, align 4, !tbaa !6
%1 = load i32*, i32** %m, align 4, !tbaa !1
store volatile i32 %v, i32* %1, align 4, !tbaa !6
ret void
}
; The store via the loaded address may overwrite the address itself.
; Make sure that both loads remain.
; CHECK-LABEL: test2
; CHECK: load
; CHECK: store
; CHECK: load
define void @test2(%struct.t* nocapture readonly %p, i32 %v) #0 {
entry:
%m = getelementptr inbounds %struct.t, %struct.t* %p, i32 0, i32 0
%0 = load i32*, i32** %m, align 4, !tbaa !1
store volatile i32 %v, i32* %0, align 4, !tbaa !1
%1 = load i32*, i32** %m, align 4, !tbaa !1
store volatile i32 %v, i32* %1, align 4, !tbaa !1
ret void
}
; The loads are ordered and non-monotonic. Although they are not aliased to
; the stores, make sure both are preserved.
; CHECK-LABEL: test3
; CHECK: load
; CHECK: store
; CHECK: load
define void @test3(%struct.t* nocapture readonly %p, i32 %v) #0 {
entry:
%m = getelementptr inbounds %struct.t, %struct.t* %p, i32 0, i32 0
%0 = load atomic i32*, i32** %m acquire, align 4, !tbaa !1
store volatile i32 %v, i32* %0, align 4, !tbaa !6
%1 = load atomic i32*, i32** %m acquire, align 4, !tbaa !1
store volatile i32 %v, i32* %1, align 4, !tbaa !6
ret void
}
attributes #0 = { norecurse nounwind }
!1 = !{!2, !3, i64 0}
!2 = !{!"", !3, i64 0}
!3 = !{!"any pointer", !4, i64 0}
!4 = !{!"omnipotent char", !5, i64 0}
!5 = !{!"Simple C/C++ TBAA"}
!6 = !{!7, !7, i64 0}
!7 = !{!"int", !4, i64 0}