[llvm] 4035cb7 - [SVE] Add new isKnownXX comparison functions to TypeSize

David Sherwood via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 24 02:23:23 PDT 2020


Author: David Sherwood
Date: 2020-09-24T10:22:57+01:00
New Revision: 4035cb7ac5755357222b6a83d76bdc4c2d718c54

URL: https://github.com/llvm/llvm-project/commit/4035cb7ac5755357222b6a83d76bdc4c2d718c54
DIFF: https://github.com/llvm/llvm-project/commit/4035cb7ac5755357222b6a83d76bdc4c2d718c54.diff

LOG: [SVE] Add new isKnownXX comparison functions to TypeSize

This patch introduces four new comparison functions:

  isKnownLT, isKnownLE, isKnownGT, isKnownGE

that return true if we know at compile time that a particular
condition is met, i.e. that one size is definitely greater than
another. The existing operators <,>,<=,>= remain in the code for
now, but over time we would like to remove them and change the
code to use the isKnownXY routines instead. These functions do
not assert like the existing operators because the caller is
expected to properly deal with cases where we return false by
analysing the scalable properties. I've made more of an effort
to deal with cases where there are mixed comparisons, i.e. between
fixed width and scalable types.

I've also added some knownBitsXY routines to the EVT and MVT
classes that call the equivalent TypeSize::isKnownXY routines.
I've changed the existing bitsXY functions to call their knownBitsXY
equivalents and added asserts that the scalable properties match.
Again, over time we expect to migrate callers to use knownBitsXY
and make the code more aware of the scalable nature of the sizes.

Differential revision: https://reviews.llvm.org/D88098

Added: 
    

Modified: 
    llvm/include/llvm/CodeGen/ValueTypes.h
    llvm/include/llvm/Support/MachineValueType.h
    llvm/include/llvm/Support/TypeSize.h

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/CodeGen/ValueTypes.h b/llvm/include/llvm/CodeGen/ValueTypes.h
index ad4083d428e5..164518faef22 100644
--- a/llvm/include/llvm/CodeGen/ValueTypes.h
+++ b/llvm/include/llvm/CodeGen/ValueTypes.h
@@ -232,28 +232,58 @@ namespace llvm {
       return getSizeInBits() == VT.getSizeInBits();
     }
 
+    /// Return true if we know at compile time this has more bits than VT.
+    bool knownBitsGT(EVT VT) const {
+      return TypeSize::isKnownGT(getSizeInBits(), VT.getSizeInBits());
+    }
+
+    /// Return true if we know at compile time this has more than or the same
+    /// bits as VT.
+    bool knownBitsGE(EVT VT) const {
+      return TypeSize::isKnownGE(getSizeInBits(), VT.getSizeInBits());
+    }
+
+    /// Return true if we know at compile time this has fewer bits than VT.
+    bool knownBitsLT(EVT VT) const {
+      return TypeSize::isKnownLT(getSizeInBits(), VT.getSizeInBits());
+    }
+
+    /// Return true if we know at compile time this has fewer than or the same
+    /// bits as VT.
+    bool knownBitsLE(EVT VT) const {
+      return TypeSize::isKnownLE(getSizeInBits(), VT.getSizeInBits());
+    }
+
     /// Return true if this has more bits than VT.
     bool bitsGT(EVT VT) const {
       if (EVT::operator==(VT)) return false;
-      return getSizeInBits() > VT.getSizeInBits();
+      assert(isScalableVector() == VT.isScalableVector() &&
+             "Comparison between scalable and fixed types");
+      return knownBitsGT(VT);
     }
 
     /// Return true if this has no less bits than VT.
     bool bitsGE(EVT VT) const {
       if (EVT::operator==(VT)) return true;
-      return getSizeInBits() >= VT.getSizeInBits();
+      assert(isScalableVector() == VT.isScalableVector() &&
+             "Comparison between scalable and fixed types");
+      return knownBitsGE(VT);
     }
 
     /// Return true if this has less bits than VT.
     bool bitsLT(EVT VT) const {
       if (EVT::operator==(VT)) return false;
-      return getSizeInBits() < VT.getSizeInBits();
+      assert(isScalableVector() == VT.isScalableVector() &&
+             "Comparison between scalable and fixed types");
+      return knownBitsLT(VT);
     }
 
     /// Return true if this has no more bits than VT.
     bool bitsLE(EVT VT) const {
       if (EVT::operator==(VT)) return true;
-      return getSizeInBits() <= VT.getSizeInBits();
+      assert(isScalableVector() == VT.isScalableVector() &&
+             "Comparison between scalable and fixed types");
+      return knownBitsLE(VT);
     }
 
     /// Return the SimpleValueType held in the specified simple EVT.

diff  --git a/llvm/include/llvm/Support/MachineValueType.h b/llvm/include/llvm/Support/MachineValueType.h
index aa1c9c9048b1..b0d16ba3ef82 100644
--- a/llvm/include/llvm/Support/MachineValueType.h
+++ b/llvm/include/llvm/Support/MachineValueType.h
@@ -954,24 +954,54 @@ namespace llvm {
       return getSizeInBits().isByteSized();
     }
 
+    /// Return true if we know at compile time this has more bits than VT.
+    bool knownBitsGT(MVT VT) const {
+      return TypeSize::isKnownGT(getSizeInBits(), VT.getSizeInBits());
+    }
+
+    /// Return true if we know at compile time this has more than or the same
+    /// bits as VT.
+    bool knownBitsGE(MVT VT) const {
+      return TypeSize::isKnownGE(getSizeInBits(), VT.getSizeInBits());
+    }
+
+    /// Return true if we know at compile time this has fewer bits than VT.
+    bool knownBitsLT(MVT VT) const {
+      return TypeSize::isKnownLT(getSizeInBits(), VT.getSizeInBits());
+    }
+
+    /// Return true if we know at compile time this has fewer than or the same
+    /// bits as VT.
+    bool knownBitsLE(MVT VT) const {
+      return TypeSize::isKnownLE(getSizeInBits(), VT.getSizeInBits());
+    }
+
     /// Return true if this has more bits than VT.
     bool bitsGT(MVT VT) const {
-      return getSizeInBits() > VT.getSizeInBits();
+      assert(isScalableVector() == VT.isScalableVector() &&
+             "Comparison between scalable and fixed types");
+      return knownBitsGT(VT);
     }
 
     /// Return true if this has no less bits than VT.
     bool bitsGE(MVT VT) const {
-      return getSizeInBits() >= VT.getSizeInBits();
+      assert(isScalableVector() == VT.isScalableVector() &&
+             "Comparison between scalable and fixed types");
+      return knownBitsGE(VT);
     }
 
     /// Return true if this has less bits than VT.
     bool bitsLT(MVT VT) const {
-      return getSizeInBits() < VT.getSizeInBits();
+      assert(isScalableVector() == VT.isScalableVector() &&
+             "Comparison between scalable and fixed types");
+      return knownBitsLT(VT);
     }
 
     /// Return true if this has no more bits than VT.
     bool bitsLE(MVT VT) const {
-      return getSizeInBits() <= VT.getSizeInBits();
+      assert(isScalableVector() == VT.isScalableVector() &&
+             "Comparison between scalable and fixed types");
+      return knownBitsLE(VT);
     }
 
     static MVT getFloatingPointVT(unsigned BitWidth) {

diff  --git a/llvm/include/llvm/Support/TypeSize.h b/llvm/include/llvm/Support/TypeSize.h
index 11ffdb470425..801151048302 100644
--- a/llvm/include/llvm/Support/TypeSize.h
+++ b/llvm/include/llvm/Support/TypeSize.h
@@ -157,23 +157,54 @@ class TypeSize {
   // Scalable vector types with the same minimum size as a fixed size type are
   // not guaranteed to be the same size at runtime, so they are never
   // considered to be equal.
-  friend bool operator==(const TypeSize &LHS, const TypeSize &RHS) {
-    return LHS.MinSize == RHS.MinSize && LHS.IsScalable == RHS.IsScalable;
+  bool operator==(const TypeSize &RHS) const {
+    return MinSize == RHS.MinSize && IsScalable == RHS.IsScalable;
   }
 
-  friend bool operator!=(const TypeSize &LHS, const TypeSize &RHS) {
-    return !(LHS == RHS);
-  }
+  bool operator!=(const TypeSize &RHS) const { return !(*this == RHS); }
 
-  // For many cases, size ordering between scalable and fixed size types cannot
+  // For some cases, size ordering between scalable and fixed size types cannot
   // be determined at compile time, so such comparisons aren't allowed.
   //
   // e.g. <vscale x 2 x i16> could be bigger than <4 x i32> with a runtime
   // vscale >= 5, equal sized with a vscale of 4, and smaller with
   // a vscale <= 3.
   //
-  // If the scalable flags match, just perform the requested comparison
-  // between the minimum sizes.
+  // All the functions below make use of the fact vscale is always >= 1, which
+  // means that <vscale x 4 x i32> is guaranteed to be >= <4 x i32>, etc.
+
+  static bool isKnownLT(const TypeSize &LHS, const TypeSize &RHS) {
+    if (!LHS.IsScalable || RHS.IsScalable)
+      return LHS.MinSize < RHS.MinSize;
+
+    // LHS.IsScalable = true, RHS.IsScalable = false
+    return false;
+  }
+
+  static bool isKnownGT(const TypeSize &LHS, const TypeSize &RHS) {
+    if (LHS.IsScalable || !RHS.IsScalable)
+      return LHS.MinSize > RHS.MinSize;
+
+    // LHS.IsScalable = false, RHS.IsScalable = true
+    return false;
+  }
+
+  static bool isKnownLE(const TypeSize &LHS, const TypeSize &RHS) {
+    if (!LHS.IsScalable || RHS.IsScalable)
+      return LHS.MinSize <= RHS.MinSize;
+
+    // LHS.IsScalable = true, RHS.IsScalable = false
+    return false;
+  }
+
+  static bool isKnownGE(const TypeSize &LHS, const TypeSize &RHS) {
+    if (LHS.IsScalable || !RHS.IsScalable)
+      return LHS.MinSize >= RHS.MinSize;
+
+    // LHS.IsScalable = false, RHS.IsScalable = true
+    return false;
+  }
+
   friend bool operator<(const TypeSize &LHS, const TypeSize &RHS) {
     assert(LHS.IsScalable == RHS.IsScalable &&
            "Ordering comparison of scalable and fixed types");


        


More information about the llvm-commits mailing list