Open kraj opened 4 days ago
@llvm/issue-subscribers-backend-risc-v
Author: Khem Raj (kraj)
Reduced compilation flags: clang++ -target riscv64-gnu-linux -O2 -std=c++11 -Xclang -mrelax-all -fsized-deallocation -c test.cpp
.
Looks like the call to Fixups.clear() in RISCVMCCodeEmitter::expandLongCondBr
erased every fixup in the function instead of just the fixups for the branch.
Possible fix
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
index 75323632dd53..a54d0996b74a 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
@@ -283,13 +283,17 @@ void RISCVMCCodeEmitter::expandLongCondBr(const MCInst &MI,
Offset = 4;
}
+ size_t N = Fixups.size();
+
// Emit an unconditional jump to the destination.
MCInst TmpInst =
MCInstBuilder(RISCV::JAL).addReg(RISCV::X0).addOperand(SrcSymbol);
uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
support::endian::write(CB, Binary, llvm::endianness::little);
- Fixups.clear();
+ if (Fixups.size() > N)
+ Fixups.pop_back();
+
if (SrcSymbol.isExpr()) {
Fixups.push_back(MCFixup::create(Offset, SrcSymbol.getExpr(),
MCFixupKind(RISCV::fixup_riscv_jal)
@kraj did you add -mrelax-all to the command line yourself?
I am working to provide a reproducer.
@kraj did you add -mrelax-all to the command line yourself?
See https://github.com/libjxl/libjxl/blob/7609879f3d9071506dea8f537ad56d744ee83617/CMakeLists.txt#L339
Looks like the call to Fixups.clear() in
RISCVMCCodeEmitter::expandLongCondBr
erased every fixup in the function instead of just the fixups for the branch.
So it exists for a long time?
Looks like the call to Fixups.clear() in
RISCVMCCodeEmitter::expandLongCondBr
erased every fixup in the function instead of just the fixups for the branch.So it exists for a long time?
Yes. And -mrelax-all is broken on RISC-V. See https://github.com/llvm/llvm-project/issues/87127 for more details.
Reproducer:
; bin/clang++ -target riscv64-gnu-linux -O2 -std=c++11 -Xclang -mrelax-all -c test.cpp
struct b {
using c = char *;
};
template <class d> struct e {
using ab = d;
ab ac() { return f; }
d f;
};
template <class ad, class g> class h : e<ad> {
public:
using i = e<ad>;
using j = e<g>;
typename i::ab ae() { return (*this).ac(); }
typename j::ab af();
};
template <class ag> class k {
h<b::c, ag> aj;
public:
~k() {
b::c a = aj.ae();
if (a)
aj.af()(a);
}
};
enum al { am };
template <typename aq> class m {
public:
~m() {
if (ap == am)
at.au.~aq();
}
struct {
aq au;
} at;
al ap;
};
struct n {
void operator()(char *);
};
using ax = k<n>;
struct o {
ax a;
};
m<o> l;
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
0. Program arguments: bin/clang++ -target riscv64-gnu-linux -O2 -std=c++11 -Xclang -mrelax-all -c test.cpp
1. <eof> parser at end of file
2. Code generation
3. Running pass 'Function Pass Manager' on module 'test.cpp'.
4. Running pass 'RISC-V Assembly Printer' on function '@_ZN1mI1oED2Ev'
#0 0x00007d7131c14572 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/libLLVMSupport.so.20.0git+0x214572)
#1 0x00007d7131c1143f llvm::sys::RunSignalHandlers() (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/libLLVMSupport.so.20.0git+0x21143f)
#2 0x00007d7131b00108 CrashRecoverySignalHandler(int) CrashRecoveryContext.cpp:0:0
#3 0x00007d7131242520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520)
#4 0x00007d71341197d0 llvm::MCELFStreamer::emitInstToData(llvm::MCInst const&, llvm::MCSubtargetInfo const&) (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/libLLVMMC.so.20.0git+0x8e7d0)
#5 0x00007d71341350bf llvm::MCObjectStreamer::emitInstructionImpl(llvm::MCInst const&, llvm::MCSubtargetInfo const&) (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/libLLVMMC.so.20.0git+0xaa0bf)
#6 0x00007d7139e75edc (anonymous namespace)::RISCVAsmPrinter::EmitToStreamer(llvm::MCStreamer&, llvm::MCInst const&) (.constprop.0) RISCVAsmPrinter.cpp:0:0
#7 0x00007d7139e7d8b3 (anonymous namespace)::RISCVAsmPrinter::emitInstruction(llvm::MachineInstr const*) RISCVAsmPrinter.cpp:0:0
#8 0x00007d71330dcf2f llvm::AsmPrinter::emitFunctionBody() (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/../lib/libLLVMAsmPrinter.so.20.0git+0x67f2f)
#9 0x00007d7139e7a90a (anonymous namespace)::RISCVAsmPrinter::runOnMachineFunction(llvm::MachineFunction&) RISCVAsmPrinter.cpp:0:0
#10 0x00007d7135e3bf96 llvm::MachineFunctionPass::runOnFunction(llvm::Function&) (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/libLLVMCodeGen.so.20.0git+0x43bf96)
#11 0x00007d71320fc368 llvm::FPPassManager::runOnFunction(llvm::Function&) (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/libLLVMCore.so.20.0git+0x2fc368)
#12 0x00007d71320fc981 llvm::FPPassManager::runOnModule(llvm::Module&) (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/libLLVMCore.so.20.0git+0x2fc981)
#13 0x00007d71320fd2c7 llvm::legacy::PassManagerImpl::run(llvm::Module&) (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/libLLVMCore.so.20.0git+0x2fd2c7)
#14 0x00007d713674d219 (anonymous namespace)::EmitAssemblyHelper::EmitAssembly(clang::BackendAction, std::unique_ptr<llvm::raw_pwrite_stream, std::default_delete<llvm::raw_pwrite_stream>>, clang::BackendConsumer*) BackendUtil.cpp:0:0
#15 0x00007d713674d6bd clang::EmitBackendOutput(clang::DiagnosticsEngine&, clang::HeaderSearchOptions const&, clang::CodeGenOptions const&, clang::TargetOptions const&, clang::LangOptions const&, llvm::StringRef, llvm::Module*, clang::BackendAction, llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>, std::unique_ptr<llvm::raw_pwrite_stream, std::default_delete<llvm::raw_pwrite_stream>>, clang::BackendConsumer*) (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/libclangCodeGen.so.20.0git+0x14d6bd)
#16 0x00007d7136c9d43e clang::BackendConsumer::HandleTranslationUnit(clang::ASTContext&) (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/libclangCodeGen.so.20.0git+0x69d43e)
#17 0x00007d7131081a4d clang::ParseAST(clang::Sema&, bool, bool) (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/../lib/libclangParse.so.20.0git+0x4aa4d)
#18 0x00007d7134d53ef1 clang::FrontendAction::Execute() (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/libclangFrontend.so.20.0git+0x153ef1)
#19 0x00007d7134cc3f1e clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/libclangFrontend.so.20.0git+0xc3f1e)
#20 0x00007d713b170ad9 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/libclangFrontendTool.so.20.0git+0x5ad9)
#21 0x00005bb55f36ae0c cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (bin/clang+++0x17e0c)
#22 0x00005bb55f362d44 ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&, llvm::ToolContext const&) driver.cpp:0:0
#23 0x00007d71346f380d void llvm::function_ref<void ()>::callback_fn<clang::driver::CC1Command::Execute(llvm::ArrayRef<std::optional<llvm::StringRef>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, bool*) const::'lambda'()>(long) Job.cpp:0:0
#24 0x00007d7131b005ee llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/libLLVMSupport.so.20.0git+0x1005ee)
#25 0x00007d71346f6dc8 clang::driver::CC1Command::Execute(llvm::ArrayRef<std::optional<llvm::StringRef>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, bool*) const (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/libclangDriver.so.20.0git+0xf6dc8)
#26 0x00007d71346afd5f clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&, bool) const (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/libclangDriver.so.20.0git+0xafd5f)
#27 0x00007d71346b095d clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&, bool) const (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/libclangDriver.so.20.0git+0xb095d)
#28 0x00007d71346c11e4 clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&) (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/libclangDriver.so.20.0git+0xc11e4)
#29 0x00005bb55f365ce9 clang_main(int, char**, llvm::ToolContext const&) (bin/clang+++0x12ce9)
#30 0x00005bb55f36130a main (bin/clang+++0xe30a)
#31 0x00007d7131229d90 __libc_start_call_main ./csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#32 0x00007d7131229e40 call_init ./csu/../csu/libc-start.c:128:20
#33 0x00007d7131229e40 __libc_start_main ./csu/../csu/libc-start.c:379:5
#34 0x00005bb55f361375 _start (bin/clang+++0xe375)
clang++: error: clang frontend command failed with exit code 139 (use -v to see invocation)
clang version 20.0.0git
Target: riscv64-unknown-linux-gnu
Thread model: posix
InstalledDir: /home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin
Build config: +assertions
clang++: note: diagnostic msg:
********************
PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:
Preprocessed source(s) and associated run script(s) are located at:
clang++: note: diagnostic msg: /tmp/test-f078d6.cpp
clang++: note: diagnostic msg: /tmp/test-f078d6.sh
clang++: note: diagnostic msg:
********************
LLVM version: 387bee91f095c197270b4d0a9e19cc86b2edea73
IR reproducer: https://godbolt.org/z/nchh5qdo9
@kraj did you add -mrelax-all to the command line yourself?
No, infact on the contrary we use to use -mno-relax-all
in Yocto until clang-15 on RISCV since lld did not support relaxation but have removed it since.
@topperc I could trace this issue happening to this commit f15266e9d5d87a291a515064f8f0dd5f0c412ed3
f15266e9d5d87a291a515064f8f0dd5f0c412ed3 is the first bad commit
commit f15266e9d5d87a291a515064f8f0dd5f0c412ed3
Author: Alexis Engelke <engelke@in.tum.de>
Date: Thu Jul 4 16:46:31 2024 +0200
[MC][ELF] Emit instructions directly into fragment (#94950)
Avoid needless copying of instructions and fixups and directly emit into
the fragment small vectors.
This (optionally, second commit) also removes the single use of the
MCCompactEncodedInstFragment to simplify code.
llvm/lib/MC/MCELFStreamer.cpp | 33 +++++++---------------
llvm/lib/MC/MCObjectStreamer.cpp | 6 ++--
.../SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp | 1 -
3 files changed, 12 insertions(+), 28 deletions(-)
~/llvm-project/build
No, infact on the contrary we use to use -mno-relax-all in Yocto until clang-15 on RISCV since lld did not support relaxation but have removed it since.
I suspect you might have meant -mno-relax. -mno-relax disables generating RISCV_RELAX relocations.
-m[no-]relax-all is for branch relaxation not linker relaxation. For RISC-V -mrelax-all causes the assembler stage to convert all conditional branches into
bcc reg, reg, tmplabel
jmp target
tmplabel:
Unconditional jmp can reach targets a lot further than a conditional branch.
Unfortunately, jmp also has a limited range so sometimes needs to be converted to an indirect jump which requires a scratch register. We do all branch relaxation early for RISC-V during the compilation stage so we can allocate the scratch register.
If the assembler also does branch relaxation it will increase the size of the function and may cause unconditional jmps to go out of range. If this happens, linking will fail.
For some reason, libjxl is forcing -mrelax-all in its CMakeLists.txt. It's been there for at least 5 years and I was unable to find any explanation for it. Whatever the reason, it might have been X86 specific. I highly recommend not using -mrelax-all for RISC-V.
attached testcase reproduces the following problem on latest from
release/19.x
branchac_strategy-555195.zip