diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp --- a/llvm/lib/CodeGen/MachineVerifier.cpp +++ b/llvm/lib/CodeGen/MachineVerifier.cpp @@ -135,6 +135,10 @@ // defined. Map value is the user. RegMap vregsLiveIn; + // Key is the src MO in PHI node, Value is the MBB which the MO is from. + std::multimap PHIVarFrom; + // Regs killed in MBB. They may be defined again, and will then be in both // regsKilled and regsLiveOut. RegSet regsKilled; @@ -1451,6 +1455,13 @@ if (FirstNonPHI) report("Found PHI instruction after non-PHI", MI); + + // Record the MBB which the src MO of PHI node is from. + for (unsigned i = 1, e = MI->getNumOperands(); i != e; i += 2) { + BBInfo &MInfo = MBBInfoMap[MI->getParent()]; + MInfo.PHIVarFrom.insert(std::make_pair(&MI->getOperand(i), + MI->getOperand(i + 1).getMBB())); + } } else if (FirstNonPHI == nullptr) FirstNonPHI = MI; @@ -2290,6 +2301,25 @@ if (PInfo.addRequired(MInfo.vregsLiveIn)) todo.insert(Pred); } + + // Handle the PHI node. + for (const auto &I : MInfo.PHIVarFrom) { + unsigned Reg = I.first->getReg(); + + // If the Reg is in MInfo.vregsLiveIn, it has been added to vregsRequired. + if (MInfo.vregsLiveIn.find(Reg) == MInfo.vregsLiveIn.end() && + Register::isVirtualRegister(Reg) && + I.first->readsReg()) { + const MachineBasicBlock *FromMBB = I.second; + BBInfo &PInfo = MBBInfoMap[FromMBB]; + + // For the src Reg in PHI node, its DefBlock of LiveVariable should be + // different with its FromMBB. + if (MRI->getVRegDef(Reg)->getParent() != FromMBB && + PInfo.addRequired(Reg)) + todo.insert(FromMBB); + } + } } // Iteratively push vregsRequired to predecessors. This will converge to the diff --git a/llvm/test/CodeGen/PowerPC/livevars-crash1.mir b/llvm/test/CodeGen/PowerPC/livevars-crash1.mir --- a/llvm/test/CodeGen/PowerPC/livevars-crash1.mir +++ b/llvm/test/CodeGen/PowerPC/livevars-crash1.mir @@ -1,6 +1,6 @@ -# RUN: not --crash llc -mtriple powerpc64le-unknown-linux-gnu %s -o - 2>&1 \ -# RUN: -run-pass=livevars,phi-node-elimination -verify-machineinstrs \ -# RUN: | FileCheck %s +# RUN: llc -mtriple powerpc64le-unknown-linux-gnu %s -o - 2>&1 \ +# RUN: -run-pass=livevars,phi-node-elimination -verify-machineinstrs | \ +# RUN: FileCheck %s --- | ; Function Attrs: noreturn nounwind @@ -82,9 +82,46 @@ STD %3, 0, %4 :: (store 8 into %ir.p) B %bb.1 + ; CHECK-LABEL: name: zext_free + ; CHECK: bb.0.entry: + ; CHECK: successors: %bb.1(0x80000000) + ; CHECK: liveins: $x3 + + ; CHECK: %4:g8rc_and_g8rc_nox0 = COPY killed $x3 + ; CHECK: %0:g8rc = LD 0, %4 :: (dereferenceable load 8 from %ir.p) + ; CHECK: %12:g8rc_and_g8rc_nox0 = COPY killed %0 + + ; CHECK: bb.1.loop: + ; CHECK: successors: %bb.1(0x20000000), %bb.2(0x60000000) + + ; CHECK: %1:g8rc_and_g8rc_nox0 = COPY killed %12 + ; CHECK: %5:gprc = LBZ 0, %1 :: (load 1 from %ir.0) + ; CHECK: %6:crrc = CMPWI killed %5, 0 + ; CHEXK: %7:crbitrc = COPY killed %6.sub_eq + ; CHECK: %2:g8rc = nuw ADDI8 %1, 1 + ; CHECK: STD %2, 0, %4 :: (store 8 into %ir.p) + ; CHECK: %8:gprc = LBZ 1, %1 :: (load 1 from %ir.incdec.ptr) + ; CHECK: %12:g8rc_and_g8rc_nox0 = COPY %2 + ; CHECK: BCn killed %7, %bb.1 + ; CHECK: B %bb.2 + + ; CHECK: bb.2.loop: + ; CHECK: successors: %bb.3(0x55555555), %bb.1(0x2aaaaaab) + + ; CHECK: %9:crrc = CMPWI killed %8, 0 + ; CHECK: %10:crbitrc = COPY killed %9.sub_eq + ; CHECK: %12:g8rc_and_g8rc_nox0 = COPY killed %2 + ; CHECK: BC killed %10, %bb.1 + ; CHECK: B %bb.3 + + ; CHECK: bb.3.if.then3: + ; CHECK: successors: %bb.1(0x80000000) + + ; CHECK: %3:g8rc = nuw ADDI8 killed %1, 2 + ; CHECK: STD %3, 0, %4 :: (store 8 into %ir.p) + ; CHECK: %12:g8rc_and_g8rc_nox0 = COPY killed %3 + ; CHECK: B %bb.1 + + ... -# CHECK-LABEL: Bad machine code: LiveVariables: Block should not be in AliveBlocks -# CHECK-NEXT: - function: zext_free -# CHECK-NEXT: - basic block: %bb.2 loop -# CHECK-NEXT: Virtual register %2 is not needed live through the block. -# CHECK-NEXT: LLVM ERROR: Found 1 machine code errors. + diff --git a/llvm/test/CodeGen/PowerPC/livevars-crash2.mir b/llvm/test/CodeGen/PowerPC/livevars-crash2.mir --- a/llvm/test/CodeGen/PowerPC/livevars-crash2.mir +++ b/llvm/test/CodeGen/PowerPC/livevars-crash2.mir @@ -1,6 +1,6 @@ -# RUN: not --crash llc -mtriple powerpc64le-unknown-linux-gnu %s -o - 2>&1 \ -# RUN: -run-pass=livevars,phi-node-elimination -verify-machineinstrs \ -# RUN: | FileCheck %s +# RUN: llc -mtriple powerpc64le-unknown-linux-gnu %s -o - 2>&1 \ +# RUN: -run-pass=livevars,phi-node-elimination -verify-machineinstrs | \ +# RUN: FileCheck %s --- | define float @testfloatslt(float %c1, float %c2, float %c3, float %c4, float %a1, float %a2) { @@ -176,20 +176,44 @@ STD %3, 0, %4 :: (store 8 into %ir.p) B %bb.1 -... + ; CHECK-LABEL: name: testfloatslt + ; CHECK: bb.0.entry: + ; CHECK: successors: %bb.1(0x80000000) + ; CHECK: liveins: $x3 + + ; CHECK: %4:g8rc_and_g8rc_nox0 = COPY killed $x3 + ; CHECK: %0:g8rc = LD 0, %4 :: (dereferenceable load 8 from %ir.p) + ; CHECK: %12:g8rc_and_g8rc_nox0 = COPY killed %0 + + ; CHECK: bb.1.loop: + ; CHECK: successors: %bb.1(0x20000000), %bb.2(0x60000000) + + ; CHECK: %1:g8rc_and_g8rc_nox0 = COPY killed %12 + ; CHECK: %5:gprc = LBZ 0, %1 :: (load 1 from %ir.0) + ; CHECK: %6:crrc = CMPWI killed %5, 0 + ; CEHCK: %7:crbitrc = COPY killed %6.sub_eq + ; CHECK: %2:g8rc = nuw ADDI8 %1, 1 + ; CHECK: STD %2, 0, %4 :: (store 8 into %ir.p) + ; CHECK: %8:gprc = LBZ 1, %1 :: (load 1 from %ir.incdec.ptr) + ; CHECK: %12:g8rc_and_g8rc_nox0 = COPY %2 + ; CHECK: BCn killed %7, %bb.1 + ; CHECK: B %bb.2 -# CHECK-LABEL: Bad machine code: LiveVariables: Block should not be in AliveBlocks -# CHECK-NEXT: - function: testfloatslt -# CHECK-NEXT: - basic block: %bb.1 entry -# CHECK-NEXT: Virtual register %4 is not needed live through the block. + ; CHECK: bb.2.loop: + ; CHECK: successors: %bb.3(0x55555555), %bb.1(0x2aaaaaab) -# CHECK-LABEL: Bad machine code: LiveVariables: Block should not be in AliveBlocks -# CHECK-NEXT: - function: testfloatslt -# CHECK-NEXT: - basic block: %bb.1 entry -# CHECK-NEXT: Virtual register %5 is not needed live through the block. + ; CHECK: %9:crrc = CMPWI killed %8, 0 + ; CHECK: %10:crbitrc = COPY killed %9.sub_eq + ; CHECK: %12:g8rc_and_g8rc_nox0 = COPY killed %2 + ; CHECK: BC killed %10, %bb.1 + ; CHECK: B %bb.3 -# CHECK-LABEL: Bad machine code: LiveVariables: Block should not be in AliveBlocks -# CHECK-NEXT: - function: testfloatslt -# CHECK-NEXT: - basic block: %bb.2 entry -# CHECK-NEXT: Virtual register %5 is not needed live through the block. -# CHECK-NEXT: LLVM ERROR: Found 3 machine code errors. + ; CHECK: bb.3.if.then3: + ; CHECK: successors: %bb.1(0x80000000) + + ; CHECK: %3:g8rc = nuw ADDI8 killed %1, 2 + ; CHECK: STD %3, 0, %4 :: (store 8 into %ir.p) + ; CHECK: %12:g8rc_and_g8rc_nox0 = COPY killed %3 + ; CHECK: B %bb.1 + +... diff --git a/llvm/test/MachineVerifier/test_phis_precede_nonphis.mir b/llvm/test/MachineVerifier/test_phis_precede_nonphis.mir --- a/llvm/test/MachineVerifier/test_phis_precede_nonphis.mir +++ b/llvm/test/MachineVerifier/test_phis_precede_nonphis.mir @@ -81,4 +81,8 @@ # CHECK-NEXT: - function: broken # CHECK-NEXT: - basic block: %bb.2 exit # CHECK-NEXT: - instruction: %6:_(s8) = G_PHI %5:_(s8), %bb.0, %4:_(s8), %bb.1 + +# CHECK-LABEL: Bad machine code: Virtual register defs don't dominate all uses. +# CHECK-NEXT: - function: broken +# CHECK-NEXT: - v. register: %5 # CHECK-NOT: Bad machine code