mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
[NFC] Add a static function to do the endian check
Add a new function to do the endian check, as I will commit another patch later, which will also need the endian check. Differential Revision: https://reviews.llvm.org/D61236 llvm-svn: 360226
This commit is contained in:
parent
9c8d2303ce
commit
6308b254fc
@ -6120,6 +6120,38 @@ calculateByteProvider(SDValue Op, unsigned Index, unsigned Depth,
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned LittleEndianByteAt(unsigned BW, unsigned i) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned BigEndianByteAt(unsigned BW, unsigned i) {
|
||||||
|
return BW - i - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the bytes offsets we are looking at match with either big or
|
||||||
|
// little endian value loaded. Return true for big endian, false for little
|
||||||
|
// endian, and None if match failed.
|
||||||
|
static Optional<bool> isBigEndian(const SmallVector<int64_t, 4> &ByteOffsets,
|
||||||
|
int64_t FirstOffset) {
|
||||||
|
// The endian can be decided only when it is 2 bytes at least.
|
||||||
|
unsigned Width = ByteOffsets.size();
|
||||||
|
if (Width < 2)
|
||||||
|
return None;
|
||||||
|
|
||||||
|
bool BigEndian = true, LittleEndian = true;
|
||||||
|
for (unsigned i = 0; i < Width; i++) {
|
||||||
|
int64_t CurrentByteOffset = ByteOffsets[i] - FirstOffset;
|
||||||
|
LittleEndian &= CurrentByteOffset == LittleEndianByteAt(Width, i);
|
||||||
|
BigEndian &= CurrentByteOffset == BigEndianByteAt(Width, i);
|
||||||
|
if (!BigEndian && !LittleEndian)
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert((BigEndian != LittleEndian) && "It should be either big endian or"
|
||||||
|
"little endian");
|
||||||
|
return BigEndian;
|
||||||
|
}
|
||||||
|
|
||||||
/// Match a pattern where a wide type scalar value is loaded by several narrow
|
/// Match a pattern where a wide type scalar value is loaded by several narrow
|
||||||
/// loads and combined by shifts and ors. Fold it into a single load or a load
|
/// loads and combined by shifts and ors. Fold it into a single load or a load
|
||||||
/// and a BSWAP if the targets supports it.
|
/// and a BSWAP if the targets supports it.
|
||||||
@ -6167,11 +6199,6 @@ SDValue DAGCombiner::MatchLoadCombine(SDNode *N) {
|
|||||||
if (LegalOperations && !TLI.isOperationLegal(ISD::LOAD, VT))
|
if (LegalOperations && !TLI.isOperationLegal(ISD::LOAD, VT))
|
||||||
return SDValue();
|
return SDValue();
|
||||||
|
|
||||||
std::function<unsigned(unsigned, unsigned)> LittleEndianByteAt = [](
|
|
||||||
unsigned BW, unsigned i) { return i; };
|
|
||||||
std::function<unsigned(unsigned, unsigned)> BigEndianByteAt = [](
|
|
||||||
unsigned BW, unsigned i) { return BW - i - 1; };
|
|
||||||
|
|
||||||
bool IsBigEndianTarget = DAG.getDataLayout().isBigEndian();
|
bool IsBigEndianTarget = DAG.getDataLayout().isBigEndian();
|
||||||
auto MemoryByteOffset = [&] (ByteProvider P) {
|
auto MemoryByteOffset = [&] (ByteProvider P) {
|
||||||
assert(P.isMemory() && "Must be a memory byte provider");
|
assert(P.isMemory() && "Must be a memory byte provider");
|
||||||
@ -6238,15 +6265,10 @@ SDValue DAGCombiner::MatchLoadCombine(SDNode *N) {
|
|||||||
|
|
||||||
// Check if the bytes of the OR we are looking at match with either big or
|
// Check if the bytes of the OR we are looking at match with either big or
|
||||||
// little endian value load
|
// little endian value load
|
||||||
bool BigEndian = true, LittleEndian = true;
|
Optional<bool> IsBigEndian = isBigEndian(ByteOffsets, FirstOffset);
|
||||||
for (unsigned i = 0; i < ByteWidth; i++) {
|
if (!IsBigEndian.hasValue())
|
||||||
int64_t CurrentByteOffset = ByteOffsets[i] - FirstOffset;
|
return SDValue();
|
||||||
LittleEndian &= CurrentByteOffset == LittleEndianByteAt(ByteWidth, i);
|
|
||||||
BigEndian &= CurrentByteOffset == BigEndianByteAt(ByteWidth, i);
|
|
||||||
if (!BigEndian && !LittleEndian)
|
|
||||||
return SDValue();
|
|
||||||
}
|
|
||||||
assert((BigEndian != LittleEndian) && "should be either or");
|
|
||||||
assert(FirstByteProvider && "must be set");
|
assert(FirstByteProvider && "must be set");
|
||||||
|
|
||||||
// Ensure that the first byte is loaded from zero offset of the first load.
|
// Ensure that the first byte is loaded from zero offset of the first load.
|
||||||
@ -6259,7 +6281,7 @@ SDValue DAGCombiner::MatchLoadCombine(SDNode *N) {
|
|||||||
// replace it with a single load and bswap if needed.
|
// replace it with a single load and bswap if needed.
|
||||||
|
|
||||||
// If the load needs byte swap check if the target supports it
|
// If the load needs byte swap check if the target supports it
|
||||||
bool NeedsBswap = IsBigEndianTarget != BigEndian;
|
bool NeedsBswap = IsBigEndianTarget != *IsBigEndian;
|
||||||
|
|
||||||
// Before legalize we can introduce illegal bswaps which will be later
|
// Before legalize we can introduce illegal bswaps which will be later
|
||||||
// converted to an explicit bswap sequence. This way we end up with a single
|
// converted to an explicit bswap sequence. This way we end up with a single
|
||||||
|
Loading…
Reference in New Issue
Block a user