diff options
-rw-r--r-- | lib/Target/ARM/NEONMoveFix.cpp | 30 | ||||
-rw-r--r-- | test/CodeGen/ARM/crash.ll | 21 |
2 files changed, 41 insertions, 10 deletions
diff --git a/lib/Target/ARM/NEONMoveFix.cpp b/lib/Target/ARM/NEONMoveFix.cpp index c85d1e9..bd8c882 100644 --- a/lib/Target/ARM/NEONMoveFix.cpp +++ b/lib/Target/ARM/NEONMoveFix.cpp @@ -40,6 +40,8 @@ namespace { typedef DenseMap<unsigned, const MachineInstr*> RegMap; bool InsertMoves(MachineBasicBlock &MBB); + + void TransferImpOps(MachineInstr &Old, MachineInstr &New); }; char NEONMoveFixPass::ID = 0; } @@ -49,6 +51,16 @@ static bool inNEONDomain(unsigned Domain, bool isA8) { (isA8 && (Domain & ARMII::DomainNEONA8)); } +/// Transfer implicit kill and def operands from Old to New. +void NEONMoveFixPass::TransferImpOps(MachineInstr &Old, MachineInstr &New) { + for (unsigned i = 0, e = Old.getNumOperands(); i != e; ++i) { + MachineOperand &MO = Old.getOperand(i); + if (!MO.isReg() || !MO.isImplicit()) + continue; + New.addOperand(MO); + } +} + bool NEONMoveFixPass::InsertMoves(MachineBasicBlock &MBB) { RegMap Defs; bool Modified = false; @@ -82,17 +94,15 @@ bool NEONMoveFixPass::InsertMoves(MachineBasicBlock &MBB) { DEBUG({errs() << "vmov convert: "; MI->dump();}); - // It's safe to ignore imp-defs / imp-uses here, since: - // - We're running late, no intelligent condegen passes should be run - // afterwards - // - The imp-defs / imp-uses are superregs only, we don't care about - // them. - AddDefaultPred(BuildMI(MBB, *MI, MI->getDebugLoc(), - TII->get(ARM::VORRd), DestReg) - .addReg(SrcReg).addReg(SrcReg)); + // We need to preserve imp-defs / imp-uses here. Following passes may + // use the register scavenger to update liveness. + MachineInstr *NewMI = + AddDefaultPred(BuildMI(MBB, *MI, MI->getDebugLoc(), + TII->get(ARM::VORRd), DestReg) + .addReg(SrcReg).addReg(SrcReg)); + TransferImpOps(*MI, *NewMI); MBB.erase(MI); - MachineBasicBlock::iterator I = prior(NextMII); - MI = &*I; + MI = NewMI; DEBUG({errs() << " into: "; MI->dump();}); diff --git a/test/CodeGen/ARM/crash.ll b/test/CodeGen/ARM/crash.ll index 979442a..0f6f33e 100644 --- a/test/CodeGen/ARM/crash.ll +++ b/test/CodeGen/ARM/crash.ll @@ -48,3 +48,24 @@ bb: store <4 x float> %tmp20, <4 x float>* undef, align 16 ret void } + +; PR10520, second bug. NEONMoveFixPass needs to preserve implicit operands. +define arm_aapcs_vfpcc void @pr10520_2() nounwind align 2 { +bb: + %tmp76 = shufflevector <2 x i64> zeroinitializer, <2 x i64> zeroinitializer, <1 x i32> <i32 1> + %tmp77 = bitcast <1 x i64> %tmp76 to <2 x float> + %tmp78 = shufflevector <2 x float> %tmp77, <2 x float> %tmp77, <4 x i32> zeroinitializer + %tmp81 = fmul <4 x float> undef, %tmp78 + %tmp82 = fadd <4 x float> %tmp81, undef + %tmp85 = fadd <4 x float> %tmp82, undef + %tmp86 = bitcast <4 x float> %tmp85 to i128 + %tmp136 = bitcast i128 %tmp86 to <4 x float> + %tmp137 = bitcast <4 x float> %tmp136 to i128 + %tmp138 = bitcast i128 %tmp137 to <4 x float> + %tmp139 = bitcast <4 x float> %tmp138 to i128 + %tmp152 = bitcast i128 %tmp139 to <4 x float> + %tmp153 = bitcast <4 x float> %tmp152 to i128 + %tmp154 = bitcast i128 %tmp153 to <4 x float> + store <4 x float> %tmp154, <4 x float>* undef, align 16 + ret void +} |