Fix PR7175. Insert copies of a REG_SEQUENCE source if it is used by other REG_SEQUENCE instructions.

llvm-svn: 103994
This commit is contained in:
Evan Cheng 2010-05-17 23:24:12 +00:00
parent 47b92a2cc4
commit 1e4f55200d
2 changed files with 50 additions and 1 deletions

View File

@ -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<unsigned,4> &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.

View File

@ -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> <i32 0, i32 1, i32 2, i32 3> ; <<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> <i32 0, i32 1, i32 2, i32 3> ; <<4 x float>> [#uses=1]
store <4 x float> %5, <4 x float>* undef, align 16
br label %8
; <label>:6 ; preds = %8
br i1 undef, label %7, label %10
; <label>:7 ; preds = %6
br label %8
; <label>:8 ; preds = %7, %2
br i1 undef, label %6, label %9
; <label>:9 ; preds = %8
ret float undef
; <label>:10 ; preds = %6
ret float 9.990000e+02
}
declare <4 x i32> @llvm.arm.neon.vld1.v4i32(i8*) nounwind readonly
declare <8 x i16> @llvm.arm.neon.vld1.v8i16(i8*) nounwind readonly