mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-02 08:46:37 +00:00
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:
parent
47c5188789
commit
1665b0a224
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user