summaryrefslogtreecommitdiff
path: root/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp')
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp32
1 files changed, 26 insertions, 6 deletions
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 9b15c88156..fed9f661c2 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -1165,13 +1165,33 @@ static bool MIIsInTerminatorSequence(const MachineInstr *MI) {
// sequence, so we return true in that case.
return MI->isDebugValue();
- // If we are not defining a register that is a physical register via a copy or
- // are defining a register via an implicit def, we have left the terminator
- // sequence.
- MachineInstr::const_mop_iterator OPI = MI->operands_begin();
- if (!OPI->isReg() || !OPI->isDef() ||
+ // We have left the terminator sequence if we are not doing one of the
+ // following:
+ //
+ // 1. Copying a vreg into a physical register.
+ // 2. Copying a vreg into a vreg.
+ // 3. Defining a register via an implicit def.
+
+ // OPI should always be a register definition...
+ MachineInstr::const_mop_iterator OPI = MI->operands_begin();
+ if (!OPI->isReg() || !OPI->isDef())
+ return false;
+
+ // Defining any register via an implicit def is always ok.
+ if (MI->isImplicitDef())
+ return true;
+
+ // Grab the copy source...
+ MachineInstr::const_mop_iterator OPI2 = OPI;
+ ++OPI2;
+ assert(OPI2 != MI->operands_end()
+ && "Should have a copy implying we should have 2 arguments.");
+
+ // Make sure that the copy dest is not a vreg when the copy source is a
+ // physical register.
+ if (!OPI2->isReg() ||
(!TargetRegisterInfo::isPhysicalRegister(OPI->getReg()) &&
- !MI->isImplicitDef()))
+ TargetRegisterInfo::isPhysicalRegister(OPI2->getReg())))
return false;
return true;