Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit 4a76317

Browse files
committed
[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 <rdar://problem/18155224>. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@216640 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent d24494d commit 4a76317

File tree

3 files changed

+34
-4
lines changed

3 files changed

+34
-4
lines changed

include/llvm/CodeGen/FunctionLoweringInfo.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ class FunctionLoweringInfo {
115115
/// TODO: This isn't per-function state, it's per-basic-block state. But
116116
/// there's no other convenient place for it to live right now.
117117
std::vector<std::pair<MachineInstr*, unsigned> > PHINodesToUpdate;
118+
unsigned OrigNumPHINodesToUpdate;
118119

119120
/// If the current MBB is a landing pad, the exception pointer and exception
120121
/// selector registers are copied into these virtual registers by

lib/CodeGen/SelectionDAG/FastISel.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1370,6 +1370,9 @@ FastISel::SelectInstruction(const Instruction *I) {
13701370
removeDeadCode(FuncInfo.InsertPt, SavedInsertPt);
13711371

13721372
DbgLoc = DebugLoc();
1373+
// Undo phi node updates, because they will be added again by SelectionDAG.
1374+
if (isa<TerminatorInst>(I))
1375+
FuncInfo.PHINodesToUpdate.resize(FuncInfo.OrigNumPHINodesToUpdate);
13731376
return false;
13741377
}
13751378

@@ -2004,7 +2007,7 @@ bool FastISel::HandlePHINodesInSuccessorBlocks(const BasicBlock *LLVMBB) {
20042007
const TerminatorInst *TI = LLVMBB->getTerminator();
20052008

20062009
SmallPtrSet<MachineBasicBlock *, 4> SuccsHandled;
2007-
unsigned OrigNumPHINodesToUpdate = FuncInfo.PHINodesToUpdate.size();
2010+
FuncInfo.OrigNumPHINodesToUpdate = FuncInfo.PHINodesToUpdate.size();
20082011

20092012
// Check successor nodes' PHI nodes that expect a constant to be available
20102013
// from this block.
@@ -2040,7 +2043,7 @@ bool FastISel::HandlePHINodesInSuccessorBlocks(const BasicBlock *LLVMBB) {
20402043
if (VT == MVT::i1 || VT == MVT::i8 || VT == MVT::i16)
20412044
VT = TLI.getTypeToTransformTo(LLVMBB->getContext(), VT);
20422045
else {
2043-
FuncInfo.PHINodesToUpdate.resize(OrigNumPHINodesToUpdate);
2046+
FuncInfo.PHINodesToUpdate.resize(FuncInfo.OrigNumPHINodesToUpdate);
20442047
return false;
20452048
}
20462049
}
@@ -2054,8 +2057,8 @@ bool FastISel::HandlePHINodesInSuccessorBlocks(const BasicBlock *LLVMBB) {
20542057
DbgLoc = Inst->getDebugLoc();
20552058

20562059
unsigned Reg = getRegForValue(PHIOp);
2057-
if (Reg == 0) {
2058-
FuncInfo.PHINodesToUpdate.resize(OrigNumPHINodesToUpdate);
2060+
if (!Reg) {
2061+
FuncInfo.PHINodesToUpdate.resize(FuncInfo.OrigNumPHINodesToUpdate);
20592062
return false;
20602063
}
20612064
FuncInfo.PHINodesToUpdate.push_back(std::make_pair(MBBI++, Reg));
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
; RUN: llc -mtriple=aarch64-apple-darwin -fast-isel -verify-machineinstrs < %s
2+
; REQUIRES: asserts
3+
4+
; Test that the Machine Instruction PHI node doesn't have more than one operand
5+
; from the same predecessor.
6+
define i32 @foo(i32 %a, i32 %b, i1 %c) {
7+
entry:
8+
br i1 %c, label %switch, label %direct
9+
10+
switch:
11+
switch i32 %a, label %exit [
12+
i32 43, label %continue
13+
i32 45, label %continue
14+
]
15+
16+
direct:
17+
%var = add i32 %b, 1
18+
br label %continue
19+
20+
continue:
21+
%var.phi = phi i32 [ %var, %direct ], [ 0, %switch ], [ 0, %switch ]
22+
ret i32 %var.phi
23+
24+
exit:
25+
ret i32 1
26+
}

0 commit comments

Comments
 (0)