-
Notifications
You must be signed in to change notification settings - Fork 12.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
⬆️ rust-analyzer #74813
⬆️ rust-analyzer #74813
Conversation
📌 Commit 480f8e6 has been approved by |
⌛ Testing commit 480f8e6 with merge 20a46d60e8f1773eb4fd6098f333cb4ba41e46b9... |
💔 Test failed - checks-actions |
Urgh, so the failure seems legit, but it also looks like a bug in rustc/LLVM on riscv64:
|
@msizanoen1 any idea what's happening here? It doesn't seem to happen locally (we're hitting linker errors, which means that LLVM has already run). Is CI using a different setup than what we get with rustup? |
Have you tried using the Docker containers?
will give you a build environment that is closest as possible to CI. |
@rustbot ping risc-v |
Error: Only Rust team members can ping teams. Please let |
@jonas-schievink Can you provide more information about the linker error? |
@rustbot ping risc-v (can I do this?) Linker error looks like this:
which is understandable: what we did is just |
Error: This team ( Please let |
Have you reproduced it using the Docker containers? |
No, I haven't tried that. Probably won't get to this myself short-term :( |
@matklad Even after merging master changes and using prebuilt images, I cannot reproduce this. |
@bors retry |
⌛ Testing commit 480f8e6 with merge 0f9caffa0b197d090635b3b760df644b6b220bfb... |
💔 Test failed - checks-actions |
I managed to reproduce it without docker using |
It should be possible to work-around it by reducing inlining e.g. by using lower optimization levels or more codegen units and it is possible to fix it in the LLVM backend by making it use more than one instructions for jump by loading the higher bits and the lower bits of the address separately and then do a jump instead of only using a single instruction when branching within a function. |
Can reproduce locally as well. Even |
Urgh, that's a nasty bug. I'll see how much we can prioritize a fix for it. |
IMO, we should either temporarily disable rust analyzer for riscv or riscv entirely while that gets patched, blocking this on fixing riscv seems unreasonable given that it's presumably somewhat non-trivial to fix (requires at least LLVM updates). |
Yes, it will need LLVM fixes, which will then need backporting. If you can disable rust-analyzer on the risc-v platform in the short term, that would be helpful. |
…acrum Enable to ping RISC-V group via triagebot We have the RISC-V group (https://github.com/rust-lang/team/blob/master/teams/risc-v.toml) but don't enable to ping on this repository (rust-lang#74813 (comment)). We don't have the instructions on the rustc-dev-guide yet but I'll create it soonish.
LLVM already tries to do this in the BranchRelaxation pass but it seems like something after that pass still causes out of range branches. |
Also actually BranchRelaxation is not supported on RISC-V with |
@lenary I believe that I have a fix for this: diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index f6bc52968a3..32c09674ed4 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -386,9 +386,6 @@ unsigned RISCVInstrInfo::insertIndirectBranch(MachineBasicBlock &MBB,
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(
"Branch offsets outside of the signed 32-bit range not supported");
@@ -398,16 +395,29 @@ unsigned RISCVInstrInfo::insertIndirectBranch(MachineBasicBlock &MBB,
// uses the same workaround).
Register ScratchReg = MRI.createVirtualRegister(&RISCV::GPRRegClass);
auto II = MBB.end();
+ unsigned Scav;
+
+ if (TM.isPositionIndependent()) {
+ MBB.setLabelMustBeEmitted();
+ MachineInstr &AuipcMI = *BuildMI(MBB, II, DL, get(RISCV::AUIPC), ScratchReg)
+ .addMBB(&DestBB, RISCVII::MO_PCREL_HI);
+ BuildMI(MBB, II, DL, get(RISCV::PseudoBRIND))
+ .addReg(ScratchReg, RegState::Kill)
+ .addMBB(&MBB, RISCVII::MO_PCREL_LO);
+ RS->enterBasicBlockEnd(MBB);
+ Scav = RS->scavengeRegisterBackwards(RISCV::GPRRegClass,
+ AuipcMI.getIterator(), false, 0);
+ } else {
+ 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);
+ RS->enterBasicBlockEnd(MBB);
+ Scav = RS->scavengeRegisterBackwards(RISCV::GPRRegClass,
+ LuiMI.getIterator(), false, 0);
+ }
- 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);
-
- RS->enterBasicBlockEnd(MBB);
- unsigned Scav = RS->scavengeRegisterBackwards(RISCV::GPRRegClass,
- LuiMI.getIterator(), false, 0);
MRI.replaceRegWith(ScratchReg, Scav);
MRI.clearVirtRegs();
RS->setRegUsed(Scav);
diff --git a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
index de71c01753d..9b1bd7f28ec 100644
--- a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
+++ b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
@@ -32,6 +32,11 @@
#include "llvm/Target/TargetOptions.h"
using namespace llvm;
+static cl::opt<bool>
+ BranchRelaxation("riscv-enable-branch-relax", cl::Hidden, cl::init(true),
+ cl::desc("Relax out of range conditional branches"));
+
+
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVTarget() {
RegisterTargetMachine<RISCVTargetMachine> X(getTheRISCV32Target());
RegisterTargetMachine<RISCVTargetMachine> Y(getTheRISCV64Target());
@@ -126,7 +131,6 @@ public:
bool addLegalizeMachineIR() override;
bool addRegBankSelect() override;
bool addGlobalInstructionSelect() override;
- void addPreEmitPass() override;
void addPreEmitPass2() override;
void addPreRegAlloc() override;
};
@@ -167,13 +171,14 @@ bool RISCVPassConfig::addGlobalInstructionSelect() {
return false;
}
-void RISCVPassConfig::addPreEmitPass() { addPass(&BranchRelaxationPassID); }
-
void RISCVPassConfig::addPreEmitPass2() {
// Schedule the expansion of AMOs at the last possible moment, avoiding the
// possibility for other passes to break the requirements for forward
// progress in the LR/SC block.
addPass(createRISCVExpandPseudoPass());
+
+ if (BranchRelaxation)
+ addPass(&BranchRelaxationPassID);
}
void RISCVPassConfig::addPreRegAlloc() { This patch does 2 things:
I don't have much experience with LLVM so I would like to hear your review for this patch. |
I'm not sure of the correctness of relaxing branches after the expand pseudo pass, as there are reasons the expand pseudo pass has to come last (due to the atomic instructions that are inserted). Please can you file the patch on reviews.llvm.org and tag me as a reviewer (I use the same username there). If you point out this is a backport to fix a bug in LLVM 10 that should make it clearer to other reviewers that they shouldn't ask for a rebase (though we will need to forward-port this patch too). |
@matklad Until LLVM is fixed, can you remove the |
I don't think we should use remove the expect, rather, we should skip the build on risc-v entirely. I'll try too look into that some time soonish |
@lenary Assuming that values here are correct, instead of pass reordering we can simply backport this to https://github.com/rust-lang/llvm-project fork. |
Yes, the PIC indirect branch implementation is needed in all cases, I agree. I also agree that branch relaxation is needed after expanding some pseudos. In trunk LLVM we split the expand pseudos so we dealt with the atomic ones separately to the non-atomic (mostly branchy) ones - this means we can insert branch relaxation between them, leaving atomic pseudo expansion to last, which makes it easier to prove forward progress guarantees needed for the atomic expansions. |
Update on patching the issue:
|
…r=matklad Disable building rust-analyzer on riscv64 riscv64 has an LLVM bug that makes rust-analyzer not build. Should permit future rust-analyzer ups (e.g., rust-lang#74813) to land.
…r=matklad Disable building rust-analyzer on riscv64 riscv64 has an LLVM bug that makes rust-analyzer not build. Should permit future rust-analyzer ups (e.g., rust-lang#74813) to land.
…r=matklad Disable building rust-analyzer on riscv64 riscv64 has an LLVM bug that makes rust-analyzer not build. Should permit future rust-analyzer ups (e.g., rust-lang#74813) to land.
…r=matklad Disable building rust-analyzer on riscv64 riscv64 has an LLVM bug that makes rust-analyzer not build. Should permit future rust-analyzer ups (e.g., rust-lang#74813) to land.
r? @ghost