diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp @@ -279,7 +279,7 @@ // 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 @@ 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 @@ MachineFunction *MF = MBB.getParent(); MachineRegisterInfo &MRI = MF->getRegInfo(); - const auto &TM = static_cast(MF->getTarget()); - - if (TM.isPositionIndependent()) - report_fatal_error("Unable to insert indirect branch"); if (!isInt<32>(BrOffset)) report_fatal_error( @@ -399,15 +395,13 @@ 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 @@ 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 @@ case RISCV::JAL: case RISCV::PseudoBR: return isIntN(21, BrOffset); + case RISCV::PseudoJump: + return isIntN(32, SignExtend64(BrOffset + 0x800, XLen)); } } diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td @@ -1012,8 +1012,8 @@ 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"; } diff --git a/llvm/test/CodeGen/RISCV/branch-relaxation.ll b/llvm/test/CodeGen/RISCV/branch-relaxation.ll --- a/llvm/test/CodeGen/RISCV/branch-relaxation.ll +++ b/llvm/test/CodeGen/RISCV/branch-relaxation.ll @@ -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 @@ 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