[SCEV] Fix ValuesAtScopesUsers consistency
authorNikita Popov <npopov@redhat.com>
Fri, 3 Dec 2021 08:58:42 +0000 (09:58 +0100)
committerNikita Popov <npopov@redhat.com>
Fri, 3 Dec 2021 09:03:10 +0000 (10:03 +0100)
Fixes verification failure reported at:
https://reviews.llvm.org/rGc9f9be0381d1

The issue is that getSCEVAtScope() might compute a result without
inserting it in the ValuesAtScopes map in degenerate cases,
specifically if the ValuesAtScopes entry is invalidated during the
calculation. Arguably we should still insert the result if no
existing placeholder is found, but for now just tweak the logic
to only update ValuesAtScopesUsers if ValuesAtScopes is updated.

llvm/lib/Analysis/ScalarEvolution.cpp
llvm/test/Analysis/ScalarEvolution/values-at-scopes-consistency.ll [new file with mode: 0644]

index 7dc7f9904c709d1dd9b0e72e6dfd749cfbfe33b7..2e2aa76329debf510fd1d64447df13ce449c9e41 100644 (file)
@@ -8829,11 +8829,10 @@ const SCEV *ScalarEvolution::getSCEVAtScope(const SCEV *V, const Loop *L) {
   for (auto &LS : reverse(ValuesAtScopes[V]))
     if (LS.first == L) {
       LS.second = C;
+      if (!isa<SCEVConstant>(C))
+        ValuesAtScopesUsers[C].push_back({L, V});
       break;
     }
-
-  if (!isa<SCEVConstant>(C))
-    ValuesAtScopesUsers[C].push_back({L, V});
   return C;
 }
 
@@ -13122,7 +13121,7 @@ void ScalarEvolution::verify() const {
             is_contained(It->second, std::make_pair(L, Value)))
           continue;
         dbgs() << "Value: " << *Value << ", Loop: " << *L << ", ValueAtScope: "
-               << ValueAtScope << " missing in ValuesAtScopesUsers\n";
+               << *ValueAtScope << " missing in ValuesAtScopesUsers\n";
         std::abort();
       }
     }
@@ -13139,7 +13138,7 @@ void ScalarEvolution::verify() const {
           is_contained(It->second, std::make_pair(L, ValueAtScope)))
         continue;
       dbgs() << "Value: " << *Value << ", Loop: " << *L << ", ValueAtScope: "
-             << ValueAtScope << " missing in ValuesAtScopes\n";
+             << *ValueAtScope << " missing in ValuesAtScopes\n";
       std::abort();
     }
   }
diff --git a/llvm/test/Analysis/ScalarEvolution/values-at-scopes-consistency.ll b/llvm/test/Analysis/ScalarEvolution/values-at-scopes-consistency.ll
new file mode 100644 (file)
index 0000000..2aba1c7
--- /dev/null
@@ -0,0 +1,30 @@
+; RUN: opt -S -passes='verify<scalar-evolution>' < %s
+
+; Make sure this does not fail ValuesAtScopes consistency verification.
+; This used to register a ValuesAtScopes user, even though nothing was
+; added to ValuesAtScope due to a prior invalidation.
+
+define void @main(i8* %p) {
+entry:
+  br label %loop1
+
+loop1:
+  br label %loop2
+
+loop2:
+  %i = phi i64 [ 0, %loop1 ], [ %i.next, %loop2.latch ]
+  %i.next = add nuw nsw i64 %i, 1
+  %gep = getelementptr i8, i8* %p, i64 %i
+  %val = load i8, i8* %gep
+  %c = icmp eq i8 %val, 0
+  br i1 %c, label %loop2.latch, label %exit
+
+loop2.latch:
+  br i1 false, label %loop2, label %loop1.latch
+
+loop1.latch:
+  br label %loop1
+
+exit:
+  ret void
+}