mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 10:42:39 +01:00
[RISCV] Indirect branch generation in position independent code
This fixes the "Unable to insert indirect branch" fatal error sometimes seen when generating position-independent code. Patch by msizanoen1 Reviewed By: jrtc27 Differential Revision: https://reviews.llvm.org/D84833 (cherry picked from commit 5f9ecc5d857fa5d95f6ea36153be19db40576f8a)
This commit is contained in:
parent
fc50dce591
commit
71c87ee018
@ -279,7 +279,7 @@ bool RISCVInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
|
||||
|
||||
// Handle a single unconditional branch.
|
||||
if (NumTerminators == 1 && I->getDesc().isUnconditionalBranch()) {
|
||||
TBB = I->getOperand(0).getMBB();
|
||||
TBB = getBranchDestBlock(*I);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -293,7 +293,7 @@ bool RISCVInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
|
||||
if (NumTerminators == 2 && std::prev(I)->getDesc().isConditionalBranch() &&
|
||||
I->getDesc().isUnconditionalBranch()) {
|
||||
parseCondBranch(*std::prev(I), TBB, Cond);
|
||||
FBB = I->getOperand(0).getMBB();
|
||||
FBB = getBranchDestBlock(*I);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -384,10 +384,6 @@ unsigned RISCVInstrInfo::insertIndirectBranch(MachineBasicBlock &MBB,
|
||||
|
||||
MachineFunction *MF = MBB.getParent();
|
||||
MachineRegisterInfo &MRI = MF->getRegInfo();
|
||||
const auto &TM = static_cast<const RISCVTargetMachine &>(MF->getTarget());
|
||||
|
||||
if (TM.isPositionIndependent())
|
||||
report_fatal_error("Unable to insert indirect branch");
|
||||
|
||||
if (!isInt<32>(BrOffset))
|
||||
report_fatal_error(
|
||||
@ -399,15 +395,13 @@ unsigned RISCVInstrInfo::insertIndirectBranch(MachineBasicBlock &MBB,
|
||||
Register ScratchReg = MRI.createVirtualRegister(&RISCV::GPRRegClass);
|
||||
auto II = MBB.end();
|
||||
|
||||
MachineInstr &LuiMI = *BuildMI(MBB, II, DL, get(RISCV::LUI), ScratchReg)
|
||||
.addMBB(&DestBB, RISCVII::MO_HI);
|
||||
BuildMI(MBB, II, DL, get(RISCV::PseudoBRIND))
|
||||
.addReg(ScratchReg, RegState::Kill)
|
||||
.addMBB(&DestBB, RISCVII::MO_LO);
|
||||
MachineInstr &MI = *BuildMI(MBB, II, DL, get(RISCV::PseudoJump))
|
||||
.addReg(ScratchReg, RegState::Define | RegState::Dead)
|
||||
.addMBB(&DestBB, RISCVII::MO_CALL);
|
||||
|
||||
RS->enterBasicBlockEnd(MBB);
|
||||
unsigned Scav = RS->scavengeRegisterBackwards(RISCV::GPRRegClass,
|
||||
LuiMI.getIterator(), false, 0);
|
||||
MI.getIterator(), false, 0);
|
||||
MRI.replaceRegWith(ScratchReg, Scav);
|
||||
MRI.clearVirtRegs();
|
||||
RS->setRegUsed(Scav);
|
||||
@ -431,6 +425,7 @@ RISCVInstrInfo::getBranchDestBlock(const MachineInstr &MI) const {
|
||||
|
||||
bool RISCVInstrInfo::isBranchOffsetInRange(unsigned BranchOp,
|
||||
int64_t BrOffset) const {
|
||||
unsigned XLen = STI.getXLen();
|
||||
// Ideally we could determine the supported branch offset from the
|
||||
// RISCVII::FormMask, but this can't be used for Pseudo instructions like
|
||||
// PseudoBR.
|
||||
@ -447,6 +442,8 @@ bool RISCVInstrInfo::isBranchOffsetInRange(unsigned BranchOp,
|
||||
case RISCV::JAL:
|
||||
case RISCV::PseudoBR:
|
||||
return isIntN(21, BrOffset);
|
||||
case RISCV::PseudoJump:
|
||||
return isIntN(32, SignExtend64(BrOffset + 0x800, XLen));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1012,8 +1012,8 @@ def : Pat<(riscv_tail (iPTR tglobaladdr:$dst)),
|
||||
def : Pat<(riscv_tail (iPTR texternalsym:$dst)),
|
||||
(PseudoTAIL texternalsym:$dst)>;
|
||||
|
||||
let isCall = 0, isBarrier = 0, isCodeGenOnly = 0, hasSideEffects = 0,
|
||||
mayStore = 0, mayLoad = 0 in
|
||||
let isCall = 0, isBarrier = 1, isBranch = 1, isTerminator = 1,
|
||||
isCodeGenOnly = 0, hasSideEffects = 0, mayStore = 0, mayLoad = 0 in
|
||||
def PseudoJump : Pseudo<(outs GPR:$rd), (ins pseudo_jump_symbol:$target), []> {
|
||||
let AsmString = "jump\t$target, $rd";
|
||||
}
|
||||
|
@ -1,7 +1,11 @@
|
||||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: llc -mtriple=riscv32 -verify-machineinstrs -filetype=obj < %s \
|
||||
; RUN: -o /dev/null 2>&1
|
||||
; RUN: llc -mtriple=riscv32 -relocation-model=pic -verify-machineinstrs \
|
||||
; RUN: -filetype=obj < %s -o /dev/null 2>&1
|
||||
; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s | FileCheck %s
|
||||
; RUN: llc -mtriple=riscv32 -relocation-model=pic -verify-machineinstrs < %s \
|
||||
; RUN: | FileCheck %s
|
||||
|
||||
define void @relax_bcc(i1 %a) nounwind {
|
||||
; CHECK-LABEL: relax_bcc:
|
||||
@ -25,15 +29,13 @@ tail:
|
||||
ret void
|
||||
}
|
||||
|
||||
; TODO: Extend simm12's MCOperandPredicate so the jalr zero is printed as a jr.
|
||||
define i32 @relax_jal(i1 %a) nounwind {
|
||||
; CHECK-LABEL: relax_jal:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: andi a0, a0, 1
|
||||
; CHECK-NEXT: bnez a0, .LBB1_1
|
||||
; CHECK-NEXT: # %bb.3:
|
||||
; CHECK-NEXT: lui a0, %hi(.LBB1_2)
|
||||
; CHECK-NEXT: jalr zero, %lo(.LBB1_2)(a0)
|
||||
; CHECK-NEXT: jump .LBB1_2, a0
|
||||
; CHECK-NEXT: .LBB1_1: # %iftrue
|
||||
; CHECK-NEXT: #APP
|
||||
; CHECK-NEXT: #NO_APP
|
||||
|
Loading…
Reference in New Issue
Block a user