summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
authorArtur Pilipenko <apilipenko@azulsystems.com>2017-02-09 12:06:01 +0000
committerArtur Pilipenko <apilipenko@azulsystems.com>2017-02-09 12:06:01 +0000
commit4a64031954b61e2f8a68f762bb3854d983dc5bb3 (patch)
tree5c9da5e287bc552a44f41e5b475e2e81eb16af6f /llvm/lib/CodeGen
parent563e23e66e5fd383147f5e0d9b4fa67f265a422a (diff)
downloadbcm5719-llvm-4a64031954b61e2f8a68f762bb3854d983dc5bb3.tar.gz
bcm5719-llvm-4a64031954b61e2f8a68f762bb3854d983dc5bb3.zip
[DAGCombiner] Support non-zero offset in load combine
Enable folding patterns which load the value from non-zero offset: i8 *a = ... i32 val = a[4] | (a[5] << 8) | (a[6] << 16) | (a[7] << 24) => i32 val = *((i32*)(a+4)) Reviewed By: RKSimon Differential Revision: https://reviews.llvm.org/D29394 llvm-svn: 294582
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp11
1 files changed, 8 insertions, 3 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index e3c15b77a26..3a71a5ddb0e 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -4533,6 +4533,7 @@ SDValue DAGCombiner::MatchLoadCombine(SDNode *N) {
SmallSet<LoadSDNode *, 8> Loads;
LoadSDNode *FirstLoad = nullptr;
+ int64_t FirstOffset = INT64_MAX;
bool IsBigEndianTarget = DAG.getDataLayout().isBigEndian();
auto ByteAt = IsBigEndianTarget ? BigEndianByteAt : LittleEndianByteAt;
@@ -4575,21 +4576,25 @@ SDValue DAGCombiner::MatchLoadCombine(SDNode *N) {
ByteOffsets[i] = ByteOffsetFromBase;
// Remember the first byte load
- if (ByteOffsetFromBase == 0)
+ if (ByteOffsetFromBase < FirstOffset) {
FirstLoad = L;
+ FirstOffset = ByteOffsetFromBase;
+ }
Loads.insert(L);
}
assert(Loads.size() > 0 && "All the bytes of the value must be loaded from "
"memory, so there must be at least one load which produces the value");
assert(Base && "Base address of the accessed memory location must be set");
+ assert(FirstOffset != INT64_MAX && "First byte offset must be set");
// 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++) {
- LittleEndian &= ByteOffsets[i] == LittleEndianByteAt(ByteWidth, i);
- BigEndian &= ByteOffsets[i] == BigEndianByteAt(ByteWidth, i);
+ int64_t CurrentByteOffset = ByteOffsets[i] - FirstOffset;
+ LittleEndian &= CurrentByteOffset == LittleEndianByteAt(ByteWidth, i);
+ BigEndian &= CurrentByteOffset == BigEndianByteAt(ByteWidth, i);
if (!BigEndian && !LittleEndian)
return SDValue();
}
OpenPOWER on IntegriCloud