mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 19:23:23 +01:00
abebf8ad17
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
62 lines
1.9 KiB
LLVM
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}
|
|
|