diff options
author | Logan Chien <loganchien@google.com> | 2013-01-03 18:24:21 +0800 |
---|---|---|
committer | Logan Chien <loganchien@google.com> | 2013-01-03 18:24:39 +0800 |
commit | 15775097a38477f54e745417614fac4fce3b37a4 (patch) | |
tree | 42315000df5a81739850b07a220c4cf7945b23ba | |
parent | 5d34cd7c61bb5dcfc7fea9ca14142b6b7653de9f (diff) | |
download | llvm-15775097a38477f54e745417614fac4fce3b37a4.tar.gz |
Fix LLVM error after loweriing thumb tMOVCCr_pseudo.
The physical register should not be used across the
machine basic block, because the register allocator
may spill or resue the register.
The previous fix for test-libstlport by adding live-ins
will not run correctly. This CL should address
the issue.
This reverts commit 95b8007dded354d15113cc0038f12ec62fa2b596.
-rw-r--r-- | lib/Target/ARM/ARMISelLowering.cpp | 50 | ||||
-rw-r--r-- | test/CodeGen/Thumb/movccr_pseudo-thumb.ll (renamed from test/CodeGen/ARM/ehselector.ll) | 20 |
2 files changed, 47 insertions, 23 deletions
diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index d1ba63ca87f..d8f354c7c96 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -6411,6 +6411,49 @@ ARMTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, BB->addSuccessor(copy0MBB); BB->addSuccessor(sinkMBB); + // Replace the live-ins physical register with virtual register, because + // physical register is not visible across the basic blocks. + MachineRegisterInfo &MRI = F->getRegInfo(); + const TargetRegisterInfo &TRI = *getTargetMachine().getRegisterInfo(); + + DenseMap<unsigned, unsigned> LiveInsToVReg; + for (MachineBasicBlock::livein_iterator LII = BB->livein_begin(), + LIE = BB->livein_end(); LII != LIE; ++LII) { + if (TargetRegisterInfo::isPhysicalRegister(*LII)) { + unsigned PReg = *LII; + unsigned VReg = MRI.createVirtualRegister(&ARM::GPRRegClass); + BuildMI(BB, dl, TII->get(TargetOpcode::COPY), VReg).addReg(PReg); + LiveInsToVReg[PReg] = VReg; + } + } + + for (MachineBasicBlock::iterator MII = sinkMBB->instr_begin(), + MIE = sinkMBB->instr_end(); MII != MIE; ++MII) { + SmallVector<DenseMap<unsigned, unsigned>::iterator, 4> RegKilled; + for (unsigned i = 0, e = MII->getNumOperands(); i != e; ++i) { + MachineOperand &MO = MII->getOperand(i); + if (!MO.isReg()) { + continue; + } + DenseMap<unsigned, unsigned>::iterator RegIter + = LiveInsToVReg.find(MO.getReg()); + if (RegIter != LiveInsToVReg.end()) { + if (MO.isDef()) { + // This machine instruction defines PReg. We should stop replacing + // PReg with VReg *after* this instruction. Note: the use of PReg + // *in* this instruction still need to be replaced. + RegKilled.push_back(RegIter); + } else { + // Replace the use of PReg with VReg + MO.substVirtReg(RegIter->second, MO.getSubReg(), TRI); + } + } + } + for (size_t i = 0; i < RegKilled.size(); ++i) { + LiveInsToVReg.erase(RegKilled[i]); + } + } + BuildMI(BB, dl, TII->get(ARM::tBcc)).addMBB(sinkMBB) .addImm(MI->getOperand(3).getImm()).addReg(MI->getOperand(4).getReg()); @@ -6431,13 +6474,6 @@ ARMTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, .addReg(MI->getOperand(1).getReg()).addMBB(copy0MBB) .addReg(MI->getOperand(2).getReg()).addMBB(thisMBB); - // Update the live-ins registers - for (MachineBasicBlock::livein_iterator I = thisMBB->livein_begin(), - E = thisMBB->livein_end(); I != E; ++I) { - copy0MBB->addLiveIn(*I); - sinkMBB->addLiveIn(*I); - } - MI->eraseFromParent(); // The pseudo instruction is gone now. return BB; } diff --git a/test/CodeGen/ARM/ehselector.ll b/test/CodeGen/Thumb/movccr_pseudo-thumb.ll index 5f931808aa7..951500f8391 100644 --- a/test/CodeGen/ARM/ehselector.ll +++ b/test/CodeGen/Thumb/movccr_pseudo-thumb.ll @@ -1,18 +1,13 @@ -; RUN: llc -o - -march thumb \ -; RUN: -arm-enable-ehabi -arm-enable-ehabi-descriptors %s\ -; RUN: | FileCheck %s +; RUN: llc %s -o /dev/null \ +; RUN: -march thumb -mcpu=cortex-a8 -mattr=-thumb2 \ +; RUN: -arm-enable-ehabi -arm-enable-ehabi-descriptors \ +; RUN: -verify-machineinstrs target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:64:128-a0:0:32-n32-S64" target triple = "thumb-none-linux-androideabi" %class.Stream = type { i8 } -define zeroext i1 @_Z8is_errori(i32 %ch) nounwind readnone { -entry: - %cmp = icmp eq i32 %ch, -1 - ret i1 %cmp -} - define zeroext i1 @_Z4testP6StreamS0_(%class.Stream* %f, %class.Stream* %t) { entry: br label %for.cond @@ -47,13 +42,6 @@ lpad4.thread: ; preds = %lpad1 %extract.t2541 = icmp ne i8 %result.0, 0 br label %catch20 -; CHECK: lpad4.thread -; CHECK: ands r7, r1 -; CHECK: movs r4, #1 -; CHECK: cmp r7 -; CHECK: bne -; CHECK: mov r4, r7 - if.then.i.i37: ; preds = %if.end %7 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) catch i8* null |