diff options
| -rw-r--r-- | llvm/include/llvm/CodeGen/FunctionLoweringInfo.h | 1 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/FastISel.cpp | 11 | ||||
| -rw-r--r-- | llvm/test/CodeGen/AArch64/fast-isel-switch-phi.ll | 26 | 
3 files changed, 34 insertions, 4 deletions
diff --git a/llvm/include/llvm/CodeGen/FunctionLoweringInfo.h b/llvm/include/llvm/CodeGen/FunctionLoweringInfo.h index 9636b51e303..057bd8f84fc 100644 --- a/llvm/include/llvm/CodeGen/FunctionLoweringInfo.h +++ b/llvm/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<std::pair<MachineInstr*, unsigned> > 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/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp index 1896c67d177..cd58c55cee8 100644 --- a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp +++ b/llvm/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<TerminatorInst>(I)) +    FuncInfo.PHINodesToUpdate.resize(FuncInfo.OrigNumPHINodesToUpdate);    return false;  } @@ -2004,7 +2007,7 @@ bool FastISel::HandlePHINodesInSuccessorBlocks(const BasicBlock *LLVMBB) {    const TerminatorInst *TI = LLVMBB->getTerminator();    SmallPtrSet<MachineBasicBlock *, 4> 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/llvm/test/CodeGen/AArch64/fast-isel-switch-phi.ll b/llvm/test/CodeGen/AArch64/fast-isel-switch-phi.ll new file mode 100644 index 00000000000..f2d8090aa0a --- /dev/null +++ b/llvm/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 +}  | 

