From c6dcce3ba5bd22325ecf1dbdfddf8136b50d4838 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Mon, 17 May 2010 23:24:12 +0000 Subject: [PATCH] Fix PR7175. Insert copies of a REG_SEQUENCE source if it is used by other REG_SEQUENCE instructions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@103994 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/TwoAddressInstructionPass.cpp | 16 ++++++++++- test/CodeGen/ARM/reg_sequence.ll | 35 +++++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/lib/CodeGen/TwoAddressInstructionPass.cpp b/lib/CodeGen/TwoAddressInstructionPass.cpp index 2d43fba4bfa..fdecc5f14af 100644 --- a/lib/CodeGen/TwoAddressInstructionPass.cpp +++ b/lib/CodeGen/TwoAddressInstructionPass.cpp @@ -134,6 +134,7 @@ namespace { /// of the de-ssa process. This replaces sources of REG_SEQUENCE as /// sub-register references of the register defined by REG_SEQUENCE. bool EliminateRegSequences(); + public: static char ID; // Pass identification, replacement for typeid TwoAddressInstructionPass() : MachineFunctionPass(&ID) {} @@ -1216,6 +1217,17 @@ TwoAddressInstructionPass::CoalesceExtSubRegs(SmallVector &Srcs, } } +static bool HasOtherRegSequenceUses(unsigned Reg, MachineInstr *RegSeq, + MachineRegisterInfo *MRI) { + for (MachineRegisterInfo::use_iterator UI = MRI->use_begin(Reg), + UE = MRI->use_end(); UI != UE; ++UI) { + MachineInstr *UseMI = &*UI; + if (UseMI != RegSeq && UseMI->isRegSequence()) + return true; + } + return false; +} + /// EliminateRegSequences - Eliminate REG_SEQUENCE instructions as part /// of the de-ssa process. This replaces sources of REG_SEQUENCE as /// sub-register references of the register defined by REG_SEQUENCE. e.g. @@ -1261,7 +1273,9 @@ bool TwoAddressInstructionPass::EliminateRegSequences() { if (DefMI->isExtractSubreg()) RealSrcs.push_back(DefMI->getOperand(1).getReg()); - if (!Seen.insert(SrcReg) || MI->getParent() != DefMI->getParent()) { + if (!Seen.insert(SrcReg) || + MI->getParent() != DefMI->getParent() || + HasOtherRegSequenceUses(SrcReg, MI, MRI)) { // REG_SEQUENCE cannot have duplicated operands, add a copy. // Also add an copy if the source if live-in the block. We don't want // to end up with a partial-redef of a livein, e.g. diff --git a/test/CodeGen/ARM/reg_sequence.ll b/test/CodeGen/ARM/reg_sequence.ll index cc75a13436a..f74f8da0864 100644 --- a/test/CodeGen/ARM/reg_sequence.ll +++ b/test/CodeGen/ARM/reg_sequence.ll @@ -229,6 +229,41 @@ bb14: ; preds = %bb6 ret i32 0 } +%0 = type { %1, %1, %1, %1 } +%1 = type { %2 } +%2 = type { <4 x float> } +%3 = type { %0, %1 } + +; PR7157 +define arm_aapcs_vfpcc float @t9(%0* nocapture, %3* nocapture) nounwind { +; CHECK: t9: +; CHECK: vldr.64 +; CHECK-NEXT: vstmia r0, {d0,d1} +; CHECK-NEXT: vmov.i8 d1 +; CHECK-NEXT: vstmia r0, {d0,d1} + %3 = bitcast double 0.000000e+00 to <2 x float> ; <<2 x float>> [#uses=2] + %4 = shufflevector <2 x float> %3, <2 x float> undef, <4 x i32> ; <<4 x float>> [#uses=1] + store <4 x float> %4, <4 x float>* undef, align 16 + %5 = shufflevector <2 x float> %3, <2 x float> zeroinitializer, <4 x i32> ; <<4 x float>> [#uses=1] + store <4 x float> %5, <4 x float>* undef, align 16 + br label %8 + +;