[PATCH] D61236: [NFC] Add a static function to do the endian check

Qing Shan Zhang via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sat Apr 27 23:18:22 PDT 2019


steven.zhang created this revision.
steven.zhang added reviewers: jsji, nemanjai, spatel, apilipenko, RKSimon, hfinkel.
Herald added a subscriber: hiraditya.
Herald added a project: LLVM.

Add a new function to do the endian check, as I will commit another patch later, which will also need the endian check. The coming patch is trying to combine several stores, as what MatchLoadCombine did. The opportunity is found from spec2017.


https://reviews.llvm.org/D61236

Files:
  llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp


Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
===================================================================
--- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -6121,6 +6121,36 @@
   return None;
 }
 
+// Check if the bytes offsets we are looking at match with either big or
+// little endian value loaded. If it returns true, the endian is set in
+// IsBigEndian, otherwise, the match failed.
+static bool matchEndian(const SmallVector<int64_t, 4> &ByteOffsets,
+                          int64_t FirstOffset, bool &IsBigEndian) {
+  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; };
+
+  // The endian can be decided only when it is 2 bytes at least.
+  unsigned Width = ByteOffsets.size();
+  if (Width < 2)
+    return false;
+
+  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 false;
+  }
+
+  assert((BigEndian != LittleEndian) && "It should be either big endian or"
+                                        "little endian");
+  IsBigEndian = BigEndian;
+  return true;
+}
+
 /// 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
 /// and a BSWAP if the targets supports it.
@@ -6168,13 +6198,13 @@
   if (LegalOperations && !TLI.isOperationLegal(ISD::LOAD, VT))
     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();
   auto MemoryByteOffset = [&] (ByteProvider P) {
+    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; };
+
     assert(P.isMemory() && "Must be a memory byte provider");
     unsigned LoadBitWidth = P.Load->getMemoryVT().getSizeInBits();
     assert(LoadBitWidth % 8 == 0 &&
@@ -6239,15 +6269,10 @@
 
   // Check if the bytes of the OR we are looking at match with either big or
   // little endian value load
-  bool BigEndian = true, LittleEndian = true;
-  for (unsigned i = 0; i < ByteWidth; i++) {
-    int64_t CurrentByteOffset = ByteOffsets[i] - FirstOffset;
-    LittleEndian &= CurrentByteOffset == LittleEndianByteAt(ByteWidth, i);
-    BigEndian &= CurrentByteOffset == BigEndianByteAt(ByteWidth, i);
-    if (!BigEndian && !LittleEndian)
-      return SDValue();
-  }
-  assert((BigEndian != LittleEndian) && "should be either or");
+  bool BigEndian = false;
+  if (!matchEndian(ByteOffsets, FirstOffset, BigEndian))
+    return SDValue();
+
   assert(FirstByteProvider && "must be set");
 
   // Ensure that the first byte is loaded from zero offset of the first load.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D61236.197001.patch
Type: text/x-patch
Size: 3423 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190428/b21d8296/attachment.bin>


More information about the llvm-commits mailing list