summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/LiveIntervals.cpp
diff options
context:
space:
mode:
authorMatt Arsenault <Matthew.Arsenault@amd.com>2019-10-18 23:24:25 +0000
committerMatt Arsenault <Matthew.Arsenault@amd.com>2019-10-18 23:24:25 +0000
commitd4274f0174ff152490195fa2a65e4087deae3dd4 (patch)
treeea5078ee34a2f8f96fe89b1d34affcfcc32f9705 /llvm/lib/CodeGen/LiveIntervals.cpp
parent3b113a2be6dc9a614bd5c95138a6c34d44fe67d9 (diff)
downloadbcm5719-llvm-d4274f0174ff152490195fa2a65e4087deae3dd4.tar.gz
bcm5719-llvm-d4274f0174ff152490195fa2a65e4087deae3dd4.zip
LiveIntervals: Fix handleMoveUp with subreg def moving across a def
If a subregister def was moved across another subregister def and another use, the main range was not correctly updated. The end point of the moved interval ended too early and missed the use from theh other lanes in the subreg def. llvm-svn: 375300
Diffstat (limited to 'llvm/lib/CodeGen/LiveIntervals.cpp')
-rw-r--r--llvm/lib/CodeGen/LiveIntervals.cpp17
1 files changed, 16 insertions, 1 deletions
diff --git a/llvm/lib/CodeGen/LiveIntervals.cpp b/llvm/lib/CodeGen/LiveIntervals.cpp
index 9d85fc3e08d..2989930ad09 100644
--- a/llvm/lib/CodeGen/LiveIntervals.cpp
+++ b/llvm/lib/CodeGen/LiveIntervals.cpp
@@ -1288,6 +1288,20 @@ private:
const SlotIndex SplitPos = NewIdxDef;
OldIdxVNI = OldIdxIn->valno;
+ SlotIndex NewDefEndPoint = std::next(NewIdxIn)->end;
+ LiveRange::iterator Prev = std::prev(OldIdxIn);
+ if (OldIdxIn != LR.begin() &&
+ SlotIndex::isEarlierInstr(NewIdx, Prev->end)) {
+ // If the segment before OldIdx read a value defined earlier than
+ // NewIdx, the moved instruction also reads and forwards that
+ // value. Extend the lifetime of the new def point.
+
+ // Extend to where the previous range started, unless there is
+ // another redef first.
+ NewDefEndPoint = std::min(OldIdxIn->start,
+ std::next(NewIdxOut)->start);
+ }
+
// Merge the OldIdxIn and OldIdxOut segments into OldIdxOut.
OldIdxOut->valno->def = OldIdxIn->start;
*OldIdxOut = LiveRange::Segment(OldIdxIn->start, OldIdxOut->end,
@@ -1305,7 +1319,8 @@ private:
// There is no gap between NewSegment and its predecessor.
*NewSegment = LiveRange::Segment(Next->start, SplitPos,
Next->valno);
- *Next = LiveRange::Segment(SplitPos, Next->end, OldIdxVNI);
+
+ *Next = LiveRange::Segment(SplitPos, NewDefEndPoint, OldIdxVNI);
Next->valno->def = SplitPos;
} else {
// There is a gap between NewSegment and its predecessor
OpenPOWER on IntegriCloud