[llvm] r292546 - [AliasAnalysis] Fences do not modify constant memory location

Anna Thomas via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 19 16:21:33 PST 2017


Author: annat
Date: Thu Jan 19 18:21:33 2017
New Revision: 292546

URL: http://llvm.org/viewvc/llvm-project?rev=292546&view=rev
Log:
[AliasAnalysis] Fences do not modify constant memory location

Summary:
Fence instructions are currently marked as `ModRef` for all memory locations.

We can improve this for constant memory locations (such as constant globals),
since fence instructions cannot modify these locations.

This helps us to forward constant loads across fences (added test case in GVN).
There were no changes in behaviour for similar test cases in early-cse and licm.

Reviewers: dberlin, sanjoy, reames

Subscribers: llvm-commits

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

Modified:
    llvm/trunk/include/llvm/Analysis/AliasAnalysis.h
    llvm/trunk/lib/Analysis/AliasAnalysis.cpp
    llvm/trunk/test/Transforms/GVN/fence.ll
    llvm/trunk/test/Transforms/NewGVN/fence.ll

Modified: llvm/trunk/include/llvm/Analysis/AliasAnalysis.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/AliasAnalysis.h?rev=292546&r1=292545&r2=292546&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/AliasAnalysis.h (original)
+++ llvm/trunk/include/llvm/Analysis/AliasAnalysis.h Thu Jan 19 18:21:33 2017
@@ -443,11 +443,7 @@ public:
 
   /// getModRefInfo (for fences) - Return information about whether
   /// a particular store modifies or reads the specified memory location.
-  ModRefInfo getModRefInfo(const FenceInst *S, const MemoryLocation &Loc) {
-    // Conservatively correct.  (We could possibly be a bit smarter if
-    // Loc is a alloca that doesn't escape.)
-    return MRI_ModRef;
-  }
+  ModRefInfo getModRefInfo(const FenceInst *S, const MemoryLocation &Loc);
 
   /// getModRefInfo (for fences) - A convenience wrapper.
   ModRefInfo getModRefInfo(const FenceInst *S, const Value *P, uint64_t Size) {

Modified: llvm/trunk/lib/Analysis/AliasAnalysis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/AliasAnalysis.cpp?rev=292546&r1=292545&r2=292546&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/AliasAnalysis.cpp (original)
+++ llvm/trunk/lib/Analysis/AliasAnalysis.cpp Thu Jan 19 18:21:33 2017
@@ -367,6 +367,14 @@ ModRefInfo AAResults::getModRefInfo(cons
   return MRI_Mod;
 }
 
+ModRefInfo AAResults::getModRefInfo(const FenceInst *S, const MemoryLocation &Loc) {
+  // If we know that the location is a constant memory location, the fence
+  // cannot modify this location.
+  if (Loc.Ptr && pointsToConstantMemory(Loc))
+    return MRI_Ref;
+  return MRI_ModRef;
+}
+
 ModRefInfo AAResults::getModRefInfo(const VAArgInst *V,
                                     const MemoryLocation &Loc) {
 

Modified: llvm/trunk/test/Transforms/GVN/fence.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GVN/fence.ll?rev=292546&r1=292545&r2=292546&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/GVN/fence.ll (original)
+++ llvm/trunk/test/Transforms/GVN/fence.ll Thu Jan 19 18:21:33 2017
@@ -1,5 +1,6 @@
 ; RUN: opt -S -basicaa -gvn < %s | FileCheck %s
 
+ at a = external constant i32
 ; We can value forward across the fence since we can (semantically) 
 ; reorder the following load before the fence.
 define i32 @test(i32* %addr.i) {
@@ -52,6 +53,25 @@ define i32 @test3(i32* noalias %addr.i,
   ret i32 %res
 }
 
+; We can forward the value forward the load
+; across both the fences, because the load is from
+; a constant memory location.
+define i32 @test4(i32* %addr) {
+; CHECK-LABEL: @test4
+; CHECK-NOT: load
+; CHECK: fence release
+; CHECK: store
+; CHECK: fence seq_cst
+; CHECK: ret i32 0
+  %var = load i32, i32* @a
+  fence release
+  store i32 42, i32* %addr, align 8
+  fence seq_cst
+  %var2 = load i32, i32* @a
+  %var3 = sub i32 %var, %var2
+  ret i32 %var3
+}
+
 ; Another example of why forwarding across an acquire fence is problematic
 ; can be seen in a normal locking operation.  Say we had:
 ; *p = 5; unlock(l); lock(l); use(p);

Modified: llvm/trunk/test/Transforms/NewGVN/fence.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/NewGVN/fence.ll?rev=292546&r1=292545&r2=292546&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/NewGVN/fence.ll (original)
+++ llvm/trunk/test/Transforms/NewGVN/fence.ll Thu Jan 19 18:21:33 2017
@@ -1,6 +1,7 @@
 ; XFAIL: *
 ; RUN: opt -S -basicaa -newgvn < %s | FileCheck %s
 
+ at a = external constant i32
 ; We can value forward across the fence since we can (semantically) 
 ; reorder the following load before the fence.
 define i32 @test(i32* %addr.i) {
@@ -53,6 +54,25 @@ define i32 @test3(i32* noalias %addr.i,
   ret i32 %res
 }
 
+; We can forward the value forward the load
+; across both the fences, because the load is from
+; a constant memory location.
+define i32 @test4(i32* %addr) {
+; CHECK-LABEL: @test4
+; CHECK-NOT: load
+; CHECK: fence release
+; CHECK: store
+; CHECK: fence seq_cst
+; CHECK: ret i32 0
+  %var = load i32, i32* @a
+  fence release
+  store i32 42, i32* %addr, align 8
+  fence seq_cst
+  %var2 = load i32, i32* @a
+  %var3 = sub i32 %var, %var2
+  ret i32 %var3
+}
+
 ; Another example of why forwarding across an acquire fence is problematic
 ; can be seen in a normal locking operation.  Say we had:
 ; *p = 5; unlock(l); lock(l); use(p);




More information about the llvm-commits mailing list