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 | 5e3600c1cea79627da1ac4f64af16615cf40b916 (patch) | |
| tree | de698083441bc84671444b19e8b7b8e8edfc5633 /llvm/lib/CodeGen/SelectionDAG | |
| parent | 12c0d773fe1c85b2d0130bb0f59ae17b0497289c (diff) | |
| download | bcm5719-llvm-5e3600c1cea79627da1ac4f64af16615cf40b916.tar.gz bcm5719-llvm-5e3600c1cea79627da1ac4f64af16615cf40b916.zip | |
[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.
llvm-svn: 191260
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG')
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 32 |
1 files changed, 26 insertions, 6 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 9b15c88156f..fed9f661c2d 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/llvm/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; |

