aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLogan Chien <loganchien@google.com>2013-01-03 18:24:21 +0800
committerLogan Chien <loganchien@google.com>2013-01-03 18:24:39 +0800
commit15775097a38477f54e745417614fac4fce3b37a4 (patch)
tree42315000df5a81739850b07a220c4cf7945b23ba
parent5d34cd7c61bb5dcfc7fea9ca14142b6b7653de9f (diff)
downloadllvm-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.cpp50
-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