Fix pr6111: Avoid using the LR register for the target address of an indirect

branch in ARM v4 code, since it gets clobbered by the return address before
it is used.  Instead of adding a new register class containing all the GPRs
except LR, just use the existing tGPR class.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@96360 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Bob Wilson 2010-02-16 17:24:15 +00:00
parent 47c5188789
commit 1665b0a224
3 changed files with 27 additions and 4 deletions

View File

@ -643,6 +643,13 @@ ARMBaseInstrInfo::copyRegToReg(MachineBasicBlock &MBB,
DebugLoc DL = DebugLoc::getUnknownLoc();
if (I != MBB.end()) DL = I->getDebugLoc();
// tGPR is used sometimes in ARM instructions that need to avoid using
// certain registers. Just treat it as GPR here.
if (DestRC == ARM::tGPRRegisterClass)
DestRC = ARM::GPRRegisterClass;
if (SrcRC == ARM::tGPRRegisterClass)
SrcRC = ARM::GPRRegisterClass;
if (DestRC != SrcRC) {
if (DestRC->getSize() != SrcRC->getSize())
return false;

View File

@ -828,9 +828,10 @@ let isCall = 1,
}
// ARMv4T
def BX : ABXIx2<(outs), (ins GPR:$func, variable_ops),
// Note: Restrict $func to the tGPR regclass to prevent it being in LR.
def BX : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
IIC_Br, "mov\tlr, pc\n\tbx\t$func",
[(ARMcall_nolink GPR:$func)]>,
[(ARMcall_nolink tGPR:$func)]>,
Requires<[IsARM, IsNotDarwin]> {
let Inst{7-4} = 0b0001;
let Inst{19-8} = 0b111111111111;
@ -865,9 +866,10 @@ let isCall = 1,
}
// ARMv4T
def BXr9 : ABXIx2<(outs), (ins GPR:$func, variable_ops),
// Note: Restrict $func to the tGPR regclass to prevent it being in LR.
def BXr9 : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
IIC_Br, "mov\tlr, pc\n\tbx\t$func",
[(ARMcall_nolink GPR:$func)]>, Requires<[IsARM, IsDarwin]> {
[(ARMcall_nolink tGPR:$func)]>, Requires<[IsARM, IsDarwin]> {
let Inst{7-4} = 0b0001;
let Inst{19-8} = 0b111111111111;
let Inst{27-20} = 0b00010010;

View File

@ -20,3 +20,17 @@ define void @g.upgrd.1() {
%tmp.upgrd.2 = tail call i32 %tmp( ) ; <i32> [#uses=0]
ret void
}
define i32* @m_231b(i32, i32, i32*, i32*, i32*) nounwind {
; CHECKV4: m_231b
; CHECKV4: bx r{{.*}}
BB0:
%5 = inttoptr i32 %0 to i32* ; <i32*> [#uses=1]
%t35 = volatile load i32* %5 ; <i32> [#uses=1]
%6 = inttoptr i32 %t35 to i32** ; <i32**> [#uses=1]
%7 = getelementptr i32** %6, i32 86 ; <i32**> [#uses=1]
%8 = load i32** %7 ; <i32*> [#uses=1]
%9 = bitcast i32* %8 to i32* (i32, i32*, i32, i32*, i32*, i32*)* ; <i32* (i32, i32*, i32, i32*, i32*, i32*)*> [#uses=1]
%10 = call i32* %9(i32 %0, i32* null, i32 %1, i32* %2, i32* %3, i32* %4) ; <i32*> [#uses=1]
ret i32* %10
}