mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
[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
This commit is contained in:
parent
9f25cd59a2
commit
f6f274223b
@ -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.
|
||||
|
@ -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) {
|
||||
|
@ -157,23 +157,54 @@ public:
|
||||
// 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");
|
||||
|
Loading…
x
Reference in New Issue
Block a user