From: Krzysztof Parzyszek Date: Tue, 27 Jun 2017 21:30:46 +0000 (+0000) Subject: Create a PHI value when merging with a known undef live-in X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a432d58a0fe7617d95eb04accf24ff8dd9016410;p=llvm Create a PHI value when merging with a known undef live-in Differential Revision: https://reviews.llvm.org/D34640 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@306466 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/LiveRangeCalc.cpp b/lib/CodeGen/LiveRangeCalc.cpp index 65448937e4c..2455a714c58 100644 --- a/lib/CodeGen/LiveRangeCalc.cpp +++ b/lib/CodeGen/LiveRangeCalc.cpp @@ -20,6 +20,9 @@ using namespace llvm; #define DEBUG_TYPE "regalloc" +// Reserve an address that indicates a value that is known to be "undef". +static VNInfo UndefVNI(0xbad, SlotIndex()); + void LiveRangeCalc::resetLiveOutMap() { unsigned NumBlocks = MF->getNumBlockIDs(); Seen.clear(); @@ -283,8 +286,11 @@ bool LiveRangeCalc::isDefOnEntry(LiveRange &LR, ArrayRef Undefs, // Determine if the exit from the block is reached by some def. unsigned N = WorkList[i]; MachineBasicBlock &B = *MF->getBlockNumbered(N); - if (Seen[N] && Map[&B].first != nullptr) - return MarkDefined(B); + if (Seen[N]) { + const LiveOutPair &LOB = Map[&B]; + if (LOB.first != nullptr && LOB.first != &UndefVNI) + return MarkDefined(B); + } SlotIndex Begin, End; std::tie(Begin, End) = Indexes->getMBBRange(&B); // Treat End as not belonging to B. @@ -387,7 +393,7 @@ bool LiveRangeCalc::findReachingDefs(LiveRange &LR, MachineBasicBlock &UseMBB, auto EP = LR.extendInBlock(Undefs, Start, End); VNInfo *VNI = EP.first; FoundUndef |= EP.second; - setLiveOutValue(Pred, VNI); + setLiveOutValue(Pred, EP.second ? &UndefVNI : VNI); if (VNI) { if (TheVNI && TheVNI != VNI) UniqueVNI = false; @@ -417,7 +423,7 @@ bool LiveRangeCalc::findReachingDefs(LiveRange &LR, MachineBasicBlock &UseMBB, // If a unique reaching def was found, blit in the live ranges immediately. if (UniqueVNI) { - assert(TheVNI != nullptr); + assert(TheVNI != nullptr && TheVNI != &UndefVNI); LiveRangeUpdater Updater(&LR); for (unsigned BN : WorkList) { SlotIndex Start, End; @@ -494,15 +500,20 @@ void LiveRangeCalc::updateSSA() { IDomValue = Map[IDom->getBlock()]; // Cache the DomTree node that defined the value. - if (IDomValue.first && !IDomValue.second) - Map[IDom->getBlock()].second = IDomValue.second = - DomTree->getNode(Indexes->getMBBFromIndex(IDomValue.first->def)); + if (IDomValue.first && IDomValue.first != &UndefVNI) + if (!IDomValue.second) + Map[IDom->getBlock()].second = IDomValue.second = + DomTree->getNode(Indexes->getMBBFromIndex(IDomValue.first->def)); for (MachineBasicBlock::pred_iterator PI = MBB->pred_begin(), PE = MBB->pred_end(); PI != PE; ++PI) { LiveOutPair &Value = Map[*PI]; if (!Value.first || Value.first == IDomValue.first) continue; + if (Value.first == &UndefVNI) { + needPHI = true; + break; + } // Cache the DomTree node that defined the value. if (!Value.second) @@ -545,7 +556,7 @@ void LiveRangeCalc::updateSSA() { LR.addSegment(LiveInterval::Segment(Start, End, VNI)); LOP = LiveOutPair(VNI, Node); } - } else if (IDomValue.first) { + } else if (IDomValue.first && IDomValue.first != &UndefVNI) { // No phi-def here. Remember incoming value. I.Value = IDomValue.first; diff --git a/test/CodeGen/Hexagon/regalloc-liveout-undef.mir b/test/CodeGen/Hexagon/regalloc-liveout-undef.mir new file mode 100644 index 00000000000..6a41514b060 --- /dev/null +++ b/test/CodeGen/Hexagon/regalloc-liveout-undef.mir @@ -0,0 +1,35 @@ +# RUN: llc -march=hexagon -run-pass liveintervals -run-pass machineverifier -run-pass simple-register-coalescing %s -o - | FileCheck %s +# +# If there is no consumer of the live intervals, the live intervals pass +# will be freed immediately after it runs, before the verifier. Add a +# user (register coalescer in this case), so that the verification will +# cover live intervals as well. +# +# Make sure that this compiles successfully. +# CHECK: undef %1.isub_lo = A2_addi %1.isub_lo, 1 + +--- +name: fred +tracksRegLiveness: true + +registers: + - { id: 0, class: intregs } + - { id: 1, class: doubleregs } + - { id: 2, class: predregs } + - { id: 3, class: doubleregs } +body: | + bb.0: + liveins: %d0 + successors: %bb.1 + %0 = IMPLICIT_DEF + %1 = COPY %d0 + + bb.1: + successors: %bb.1 + %2 = C2_cmpgt %0, %1.isub_lo + %3 = COPY %1 + %1 = COPY %3 + undef %1.isub_lo = A2_addi %1.isub_lo, 1 + J2_jump %bb.1, implicit-def %pc +... +