diff options
author | Michael Gottesman <mgottesman@apple.com> | 2013-09-24 01:50:26 +0000 |
---|---|---|
committer | Michael Gottesman <mgottesman@apple.com> | 2013-09-24 01:50:26 +0000 |
commit | eed779ff68c9a4612ea229f4fbd23a5258458889 (patch) | |
tree | 31461d5c5380c25c77e0c926f8e82f30c0c88ce0 /lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | |
parent | 17f013265f00b8df07438a648c02873888477e36 (diff) | |
download | llvm-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.cpp | 32 |
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; |