[llvm] r327655 - [EarlyCSE] Don't hide earler invariant.scopes

Philip Reames via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 15 11:12:27 PDT 2018


Author: reames
Date: Thu Mar 15 11:12:27 2018
New Revision: 327655

URL: http://llvm.org/viewvc/llvm-project?rev=327655&view=rev
Log:
[EarlyCSE] Don't hide earler invariant.scopes

If we've already established an invariant scope with an earlier generation, we don't want to hide it in the scoped hash table with one with a later generation.  I noticed this when working on the invariant-load handling, but it also applies to the invariant.start case as well.

Without this change, my previous patch for invariant-load regresses some cases, so I'm pushing this without waiting for review.  This is why you don't make last minute tweaks to patches to catch "obvious cases" after it's already been reviewed.  Bad Philip!


Modified:
    llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp
    llvm/trunk/test/Transforms/EarlyCSE/invariant-loads.ll
    llvm/trunk/test/Transforms/EarlyCSE/invariant.start.ll

Modified: llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp?rev=327655&r1=327654&r2=327655&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/EarlyCSE.cpp Thu Mar 15 11:12:27 2018
@@ -799,7 +799,9 @@ bool EarlyCSE::processNode(DomTreeNode *
         continue;
       auto *CI = cast<CallInst>(Inst);
       MemoryLocation MemLoc = MemoryLocation::getForArgument(CI, 1, TLI);
-      AvailableInvariants.insert(MemLoc, CurrentGeneration);
+      // Don't start a scope if we already have a better one pushed
+      if (!AvailableInvariants.count(MemLoc))
+        AvailableInvariants.insert(MemLoc, CurrentGeneration);
       continue;
     }
 
@@ -888,9 +890,12 @@ bool EarlyCSE::processNode(DomTreeNode *
       if (MemInst.isInvariantLoad()) {
         // If we pass an invariant load, we know that memory location is
         // indefinitely constant from the moment of first dereferenceability.
-        // We conservatively treat the invariant_load as that moment.
+        // We conservatively treat the invariant_load as that moment.  If we
+        // pass a invariant load after already establishing a scope, don't
+        // restart it since we want to preserve the earliest point seen.
         auto MemLoc = MemoryLocation::get(Inst);
-        AvailableInvariants.insert(MemLoc, CurrentGeneration);
+        if (!AvailableInvariants.count(MemLoc))
+          AvailableInvariants.insert(MemLoc, CurrentGeneration);
       }
 
       // If we have an available version of this load, and if it is the right

Modified: llvm/trunk/test/Transforms/EarlyCSE/invariant-loads.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/EarlyCSE/invariant-loads.ll?rev=327655&r1=327654&r2=327655&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/EarlyCSE/invariant-loads.ll (original)
+++ llvm/trunk/test/Transforms/EarlyCSE/invariant-loads.ll Thu Mar 15 11:12:27 2018
@@ -135,3 +135,24 @@ define void @test_scope_start_without_lo
   call void @clobber_and_use(i32 %v3)
   ret void
 }
+
+; If we already have an invariant scope, don't want to start a new one
+; with a potentially greater generation.  This hides the earlier invariant
+; load
+define void @test_scope_restart(i32* %p) {
+; CHECK-LABEL: @test_scope_restart
+; CHECK:   %v1 = load i32, i32* %p
+; CHECK:   call void @clobber_and_use(i32 %v1)
+; CHECK:   %add = add i32 %v1, %v1
+; CHECK:   call void @clobber_and_use(i32 %add)
+; CHECK:   call void @clobber_and_use(i32 %v1)
+; CHECK:   ret void
+  %v1 = load i32, i32* %p, !invariant.load !{}
+  call void @clobber_and_use(i32 %v1)
+  %v2 = load i32, i32* %p, !invariant.load !{}
+  %add = add i32 %v1, %v2
+  call void @clobber_and_use(i32 %add)
+  %v3 = load i32, i32* %p
+  call void @clobber_and_use(i32 %v3)
+  ret void
+}

Modified: llvm/trunk/test/Transforms/EarlyCSE/invariant.start.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/EarlyCSE/invariant.start.ll?rev=327655&r1=327654&r2=327655&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/EarlyCSE/invariant.start.ll (original)
+++ llvm/trunk/test/Transforms/EarlyCSE/invariant.start.ll Thu Mar 15 11:12:27 2018
@@ -93,6 +93,18 @@ define i32 @test_before_clobber(i32* %p)
   ret i32 %sub
 }
 
+define i32 @test_duplicate_scope(i32* %p) {
+; CHECK-LABEL: @test_duplicate_scope
+; CHECK: ret i32 0
+  %v1 = load i32, i32* %p
+  call {}* @llvm.invariant.start.p0i32(i64 4, i32* %p)
+  call void @clobber()
+  call {}* @llvm.invariant.start.p0i32(i64 4, i32* %p)
+  %v2 = load i32, i32* %p
+  %sub = sub i32 %v1, %v2
+  ret i32 %sub
+}
+
 define i32 @test_unanalzyable_load(i32* %p) {
 ; CHECK-LABEL: @test_unanalzyable_load
 ; CHECK: ret i32 0




More information about the llvm-commits mailing list