From 4a76317ebb880d4ea3d5fc9e80e9c02a2f69cee3 Mon Sep 17 00:00:00 2001 From: Juergen Ributzka Date: Thu, 28 Aug 2014 02:06:55 +0000 Subject: [PATCH] [FastISel] Undo phi node updates when falling-back to SelectionDAG. The included test case would fail, because the MI PHI node would have two operands from the same predecessor. This problem occurs when a switch instruction couldn't be selected. This happens always, because there is no default switch support for FastISel to begin with. The problem was that FastISel would first add the operand to the PHI nodes and then fall-back to SelectionDAG, which would then in turn add the same operands to the PHI nodes again. This fix removes these duplicate PHI node operands by reseting the PHINodesToUpdate to its original state before FastISel tried to select the instruction. This fixes . git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@216640 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/FunctionLoweringInfo.h | 1 + lib/CodeGen/SelectionDAG/FastISel.cpp | 11 ++++++--- test/CodeGen/AArch64/fast-isel-switch-phi.ll | 26 ++++++++++++++++++++ 3 files changed, 34 insertions(+), 4 deletions(-) create mode 100644 test/CodeGen/AArch64/fast-isel-switch-phi.ll 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 +} -- 2.34.1