[llvm-branch-commits] [llvm] [SCEV] Add canonical SCEV pointer and use for SCEVUse cmps (NFC) (PR #185040)

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Fri Mar 6 08:49:13 PST 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-analysis

Author: Florian Hahn (fhahn)

<details>
<summary>Changes</summary>

Add canonical SCEV pointer, to be used in combination with SCEVUse. For now, SCEVUse with different flags (or their wrapped SCEVs are different due to different flags) are considered equal if they have the same canonical SCEV.

---
Full diff: https://github.com/llvm/llvm-project/pull/185040.diff


1 Files Affected:

- (modified) llvm/include/llvm/Analysis/ScalarEvolution.h (+35-4) 


``````````diff
diff --git a/llvm/include/llvm/Analysis/ScalarEvolution.h b/llvm/include/llvm/Analysis/ScalarEvolution.h
index c59a652509e27..77db49d44583a 100644
--- a/llvm/include/llvm/Analysis/ScalarEvolution.h
+++ b/llvm/include/llvm/Analysis/ScalarEvolution.h
@@ -78,10 +78,14 @@ struct SCEVUse : PointerIntPair<const SCEV *, 2> {
 
   void *getRawPointer() const { return getOpaqueValue(); }
 
+  bool isCanonical() const;
+
+  const SCEV *getCanonical() const;
+
   unsigned getFlags() const { return getInt(); }
 
   bool operator==(const SCEVUse &RHS) const {
-    return getRawPointer() == RHS.getRawPointer();
+    return getCanonical() == RHS.getCanonical();
   }
 
   bool operator==(const SCEV *RHS) const { return getRawPointer() == RHS; }
@@ -120,14 +124,24 @@ template <> struct DenseMapInfo<SCEVUse> {
   }
 
   static unsigned getHashValue(SCEVUse U) {
-    return hash_value(U.getRawPointer());
+    return hash_value(U.getCanonical());
   }
 
   static bool isEqual(const SCEVUse LHS, const SCEVUse RHS) {
-    return LHS.getRawPointer() == RHS.getRawPointer();
+    void *L = LHS.getRawPointer();
+    void *R = RHS.getRawPointer();
+    if (L == reinterpret_cast<void *>(-1) ||
+        L == reinterpret_cast<void *>(-2) ||
+        R == reinterpret_cast<void *>(-1) || R == reinterpret_cast<void *>(-2))
+      return L == R;
+    return LHS.getCanonical() == RHS.getCanonical();
   }
 };
 
+inline bool SCEVUse::isCanonical() const {
+  return getCanonical() == getPointer();
+}
+
 template <> struct simplify_type<SCEVUse> {
   using SimpleType = const SCEV *;
 
@@ -157,6 +171,11 @@ class SCEV : public FoldingSetNode {
   /// miscellaneous information.
   unsigned short SubclassData = 0;
 
+private:
+  /// Pointer to the canonical SCEV for this node. SCEVs that differ only in
+  /// no-wrap flags share the same canonical SCEV.
+  const SCEV *CanonicalSCEV;
+
 public:
   /// NoWrapFlags are bitfield indices into SubclassData.
   ///
@@ -204,7 +223,8 @@ class SCEV : public FoldingSetNode {
 
   explicit SCEV(const FoldingSetNodeIDRef ID, SCEVTypes SCEVTy,
                 unsigned short ExpressionSize)
-      : FastID(ID), SCEVType(SCEVTy), ExpressionSize(ExpressionSize) {}
+      : FastID(ID), SCEVType(SCEVTy), ExpressionSize(ExpressionSize),
+        CanonicalSCEV(this) {}
   SCEV(const SCEV &) = delete;
   SCEV &operator=(const SCEV &) = delete;
 
@@ -247,6 +267,8 @@ class SCEV : public FoldingSetNode {
 
   /// This method is used for debugging.
   LLVM_ABI void dump() const;
+
+  const SCEV *getCanonical() const { return CanonicalSCEV; }
 };
 
 // Specialize FoldingSetTrait for SCEV to avoid needing to compute
@@ -269,6 +291,11 @@ inline raw_ostream &operator<<(raw_ostream &OS, const SCEV &S) {
   return OS;
 }
 
+inline raw_ostream &operator<<(raw_ostream &OS, SCEVUse U) {
+  U.print(OS);
+  return OS;
+}
+
 /// An object of this class is returned by queries that could not be answered.
 /// For example, if you ask for the number of iterations of a linked-list
 /// traversal loop, you will get one of these.  None of the standard SCEV
@@ -2636,6 +2663,10 @@ template <> struct DenseMapInfo<ScalarEvolution::FoldID> {
   }
 };
 
+inline const SCEV *SCEVUse::getCanonical() const {
+  return getPointer()->getCanonical();
+}
+
 } // end namespace llvm
 
 #endif // LLVM_ANALYSIS_SCALAREVOLUTION_H

``````````

</details>


https://github.com/llvm/llvm-project/pull/185040


More information about the llvm-branch-commits mailing list