diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp --- a/llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp @@ -723,13 +723,17 @@ // Fixup edge offsets and kinds. Delta = 0; - for (auto [I, E] : llvm::enumerate(Aux.RelaxEdges)) { - E->setOffset(E->getOffset() - Delta); + size_t I = 0; + for (auto &E : Block.edges()) { + E.setOffset(E.getOffset() - Delta); - if (Aux.EdgeKinds[I] != Edge::Invalid) - E->setKind(Aux.EdgeKinds[I]); + if (I < Aux.RelaxEdges.size() && Aux.RelaxEdges[I] == &E) { + if (Aux.EdgeKinds[I] != Edge::Invalid) + E.setKind(Aux.EdgeKinds[I]); - Delta = Aux.RelocDeltas[I]; + Delta = Aux.RelocDeltas[I]; + ++I; + } } // Remove AlignRelaxable edges: all other relaxable edges got modified and diff --git a/llvm/test/ExecutionEngine/JITLink/RISCV/ELF_relax_nonrelaxable.s b/llvm/test/ExecutionEngine/JITLink/RISCV/ELF_relax_nonrelaxable.s new file mode 100644 --- /dev/null +++ b/llvm/test/ExecutionEngine/JITLink/RISCV/ELF_relax_nonrelaxable.s @@ -0,0 +1,35 @@ +## Test that non-relaxable edges have their offset adjusted by relaxation + +# RUN: rm -rf %t && mkdir %t && cd %t + +# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+relax %s -o %t.rv32 +# RUN: llvm-jitlink -noexec \ +# RUN: -slab-allocate 100Kb -slab-address 0x0 -slab-page-size 4096 \ +# RUN: -check %s %t.rv32 + +# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+relax %s -o %t.rv64 +# RUN: llvm-jitlink -noexec \ +# RUN: -slab-allocate 100Kb -slab-address 0x0 -slab-page-size 4096 \ +# RUN: -check %s %t.rv64 + + .globl main,nonrelaxable,nonrelaxable_target + .size nonrelaxable, 4 + .size nonrelaxable_target, 4 +main: + call f +nonrelaxable: + ## Non-relaxable R_RISCV_BRANCH edge after a relaxable R_RISCV_CALL edge. + ## Even though this edge isn't relaxable, its offset should still be + ## adjusted. + beq zero, zero, nonrelaxable_target +nonrelaxable_target: + ret + .size main, .-main + + .globl f +f: + ret + .size f, .-f + +# jitlink-check: decode_operand(nonrelaxable, 2) = (nonrelaxable_target - nonrelaxable) +