diff options
| -rw-r--r-- | llvm/lib/CodeGen/TwoAddressInstructionPass.cpp | 54 | ||||
| -rw-r--r-- | llvm/test/CodeGen/ARM/twoaddrinstr.ll | 21 | 
2 files changed, 53 insertions, 22 deletions
diff --git a/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp b/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp index 196e06ea519..e4c011901ed 100644 --- a/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp +++ b/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp @@ -1451,28 +1451,34 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &MF) {          TiedOperands[regB].push_back(std::make_pair(SrcIdx, DstIdx));        } +      // If the instruction has a single pair of tied operands, try some +      // transformations that may either eliminate the tied operands or +      // improve the opportunities for coalescing away the register copy. +      if (TiedOperands.size() == 1) { +        SmallVector<std::pair<unsigned, unsigned>, 4> &TiedPairs +          = TiedOperands.begin()->second; +        if (TiedPairs.size() == 1) { +          unsigned SrcIdx = TiedPairs[0].first; +          unsigned DstIdx = TiedPairs[0].second; +          unsigned SrcReg = mi->getOperand(SrcIdx).getReg(); +          unsigned DstReg = mi->getOperand(DstIdx).getReg(); +          if (SrcReg != DstReg && +              TryInstructionTransform(mi, nmi, mbbi, SrcIdx, DstIdx, Dist, +                                      Processed)) { +            // The tied operands have been eliminated or shifted further down the +            // block to ease elimination. Continue processing with 'nmi'. +            TiedOperands.clear(); +            mi = nmi; +            continue; +          } +        } +      } +        // Now iterate over the information collected above.        for (TiedOperandMap::iterator OI = TiedOperands.begin(),               OE = TiedOperands.end(); OI != OE; ++OI) {          SmallVector<std::pair<unsigned, unsigned>, 4> &TiedPairs = OI->second; -        // If the instruction has a single pair of tied operands, try some -        // transformations that may either eliminate the tied operands or -        // improve the opportunities for coalescing away the register copy. -        if (TiedOperands.size() == 1 && TiedPairs.size() == 1) { -          unsigned SrcIdx = TiedPairs[0].first; -          unsigned DstIdx = TiedPairs[0].second; - -          // If the registers are already equal, nothing needs to be done. -          if (mi->getOperand(SrcIdx).getReg() == -              mi->getOperand(DstIdx).getReg()) -            break; // Done with this instruction. - -          if (TryInstructionTransform(mi, nmi, mbbi, SrcIdx, DstIdx, Dist, -                                      Processed)) -            break; // The tied operands have been eliminated. -        } -          bool IsEarlyClobber = false;          bool RemovedKillFlag = false;          bool AllUsesCopied = true; @@ -1593,12 +1599,16 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &MF) {            }          } -        // Schedule the source copy / remat inserted to form two-address -        // instruction. FIXME: Does it matter the distance map may not be -        // accurate after it's scheduled? -        TII->scheduleTwoAddrSource(prior(mi), mi, *TRI); +        // We didn't change anything if there was a single tied pair, and that +        // pair didn't require copies. +        if (AllUsesCopied || TiedPairs.size() > 1) { +          MadeChange = true; -        MadeChange = true; +          // Schedule the source copy / remat inserted to form two-address +          // instruction. FIXME: Does it matter the distance map may not be +          // accurate after it's scheduled? +          TII->scheduleTwoAddrSource(prior(mi), mi, *TRI); +        }          DEBUG(dbgs() << "\t\trewrite to:\t" << *mi);        } diff --git a/llvm/test/CodeGen/ARM/twoaddrinstr.ll b/llvm/test/CodeGen/ARM/twoaddrinstr.ll new file mode 100644 index 00000000000..4e227dd5be3 --- /dev/null +++ b/llvm/test/CodeGen/ARM/twoaddrinstr.ll @@ -0,0 +1,21 @@ +; Tests for the two-address instruction pass. +; RUN: llc -march=arm -mcpu=cortex-a9 < %s | FileCheck %s + +define void @PR13378() nounwind { +; This was orriginally a crasher trying to schedule the instructions. +; CHECK:      PR13378: +; CHECK:        vldmia +; CHECK-NEXT:   vmov.f32 +; CHECK-NEXT:   vstmia +; CHECK-NEXT:   vstmia +; CHECK-NEXT:   vmov.f32 +; CHECK-NEXT:   vstmia + +entry: +  %0 = load <4 x float>* undef +  store <4 x float> zeroinitializer, <4 x float>* undef +  store <4 x float> %0, <4 x float>* undef +  %1 = insertelement <4 x float> %0, float 1.000000e+00, i32 3 +  store <4 x float> %1, <4 x float>* undef +  unreachable +}  | 

