diff --git a/include/llvm/CodeGen/FunctionLoweringInfo.h b/include/llvm/CodeGen/FunctionLoweringInfo.h index 9636b51e303..057bd8f84fc 100644 --- a/include/llvm/CodeGen/FunctionLoweringInfo.h +++ b/include/llvm/CodeGen/FunctionLoweringInfo.h @@ -115,6 +115,7 @@ public: /// TODO: This isn't per-function state, it's per-basic-block state. But /// there's no other convenient place for it to live right now. std::vector > PHINodesToUpdate; + unsigned OrigNumPHINodesToUpdate; /// If the current MBB is a landing pad, the exception pointer and exception /// selector registers are copied into these virtual registers by diff --git a/lib/CodeGen/SelectionDAG/FastISel.cpp b/lib/CodeGen/SelectionDAG/FastISel.cpp index 1896c67d177..cd58c55cee8 100644 --- a/lib/CodeGen/SelectionDAG/FastISel.cpp +++ b/lib/CodeGen/SelectionDAG/FastISel.cpp @@ -1370,6 +1370,9 @@ FastISel::SelectInstruction(const Instruction *I) { removeDeadCode(FuncInfo.InsertPt, SavedInsertPt); DbgLoc = DebugLoc(); + // Undo phi node updates, because they will be added again by SelectionDAG. + if (isa(I)) + FuncInfo.PHINodesToUpdate.resize(FuncInfo.OrigNumPHINodesToUpdate); return false; } @@ -2004,7 +2007,7 @@ bool FastISel::HandlePHINodesInSuccessorBlocks(const BasicBlock *LLVMBB) { const TerminatorInst *TI = LLVMBB->getTerminator(); SmallPtrSet SuccsHandled; - unsigned OrigNumPHINodesToUpdate = FuncInfo.PHINodesToUpdate.size(); + FuncInfo.OrigNumPHINodesToUpdate = FuncInfo.PHINodesToUpdate.size(); // Check successor nodes' PHI nodes that expect a constant to be available // from this block. @@ -2040,7 +2043,7 @@ bool FastISel::HandlePHINodesInSuccessorBlocks(const BasicBlock *LLVMBB) { if (VT == MVT::i1 || VT == MVT::i8 || VT == MVT::i16) VT = TLI.getTypeToTransformTo(LLVMBB->getContext(), VT); else { - FuncInfo.PHINodesToUpdate.resize(OrigNumPHINodesToUpdate); + FuncInfo.PHINodesToUpdate.resize(FuncInfo.OrigNumPHINodesToUpdate); return false; } } @@ -2054,8 +2057,8 @@ bool FastISel::HandlePHINodesInSuccessorBlocks(const BasicBlock *LLVMBB) { DbgLoc = Inst->getDebugLoc(); unsigned Reg = getRegForValue(PHIOp); - if (Reg == 0) { - FuncInfo.PHINodesToUpdate.resize(OrigNumPHINodesToUpdate); + if (!Reg) { + FuncInfo.PHINodesToUpdate.resize(FuncInfo.OrigNumPHINodesToUpdate); return false; } FuncInfo.PHINodesToUpdate.push_back(std::make_pair(MBBI++, Reg)); diff --git a/test/CodeGen/AArch64/fast-isel-switch-phi.ll b/test/CodeGen/AArch64/fast-isel-switch-phi.ll new file mode 100644 index 00000000000..f2d8090aa0a --- /dev/null +++ b/test/CodeGen/AArch64/fast-isel-switch-phi.ll @@ -0,0 +1,26 @@ +; RUN: llc -mtriple=aarch64-apple-darwin -fast-isel -verify-machineinstrs < %s +; REQUIRES: asserts + +; Test that the Machine Instruction PHI node doesn't have more than one operand +; from the same predecessor. +define i32 @foo(i32 %a, i32 %b, i1 %c) { +entry: + br i1 %c, label %switch, label %direct + +switch: + switch i32 %a, label %exit [ + i32 43, label %continue + i32 45, label %continue + ] + +direct: + %var = add i32 %b, 1 + br label %continue + +continue: + %var.phi = phi i32 [ %var, %direct ], [ 0, %switch ], [ 0, %switch ] + ret i32 %var.phi + +exit: + ret i32 1 +}