summaryrefslogtreecommitdiff
path: root/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
diff options
context:
space:
mode:
authorMichael Gottesman <mgottesman@apple.com>2013-09-24 01:50:26 +0000
committerMichael Gottesman <mgottesman@apple.com>2013-09-24 01:50:26 +0000
commiteed779ff68c9a4612ea229f4fbd23a5258458889 (patch)
tree31461d5c5380c25c77e0c926f8e82f30c0c88ce0 /lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
parent17f013265f00b8df07438a648c02873888477e36 (diff)
downloadllvm-eed779ff68c9a4612ea229f4fbd23a5258458889.tar.gz
llvm-eed779ff68c9a4612ea229f4fbd23a5258458889.tar.bz2
llvm-eed779ff68c9a4612ea229f4fbd23a5258458889.tar.xz
[stackprotector] Allow for copies from vreg -> vreg to be in a terminator sequence.
Sometimes a copy from a vreg -> vreg sneaks into the middle of a terminator sequence. It is safe to slice this into the stack protector success bb. This fixes PR16979. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191260 91177308-0d34-0410-b5e6-96231b3b80d8
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;