From: Eduard Zingerman <eddyz87@gmail.com>
To: Yonghong Song <yonghong.song@linux.dev>,
Alexei Starovoitov <ast@kernel.org>
Cc: Daniel Borkmann <daniel@iogearbox.net>,
Andrii Nakryiko <andrii@kernel.org>,
Martin KaFai Lau <martin.lau@kernel.org>,
bpf <bpf@vger.kernel.org>
Subject: Re: bpf selftest pyperf180.c compilation failure with latest last llvm18 (in development)
Date: Wed, 08 Nov 2023 04:13:50 +0200 [thread overview]
Message-ID: <ba9076bfb983ef96ca78d584ca751b1fef3a06b9.camel@gmail.com> (raw)
In-Reply-To: <3e3a8a30-dde0-43a1-981e-2274962780ef@linux.dev>
On Mon, 2023-10-30 at 20:58 -0700, Yonghong Song wrote:
> With latest llvm18 (main branch of llvm-project repo), when building bpf selftests,
> [~/work/bpf-next (master)]$ make -C tools/testing/selftests/bpf LLVM=1 -j
>
> The following compilation error happens:
> fatal error: error in backend: Branch target out of insn range
> 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: clang -g -Wall -Werror -D__TARGET_ARCH_x86 -mlittle-endian -I/home/yhs/work/bpf-next/tools/testing/selftests/bpf/tools/include -I/home/yhs
> /work/bpf-next/tools/testing/selftests/bpf -I/home/yhs/work/bpf-next/tools/include/uapi -I/home/yhs/work/bpf-next/tools/testing/selftests/usr/include -idirafter /hom
> e/yhs/work/llvm-project/llvm/build.18/install/lib/clang/18/include -idirafter /usr/local/include -idirafter /usr/include -Wno-compare-distinct-pointer-types -DENABLE
> _ATOMICS_TESTS -O2 --target=bpf -c progs/pyperf180.c -mcpu=v3 -o /home/yhs/work/bpf-next/tools/testing/selftests/bpf/pyperf180.bpf.o
> 1. <eof> parser at end of file
> 2. Code generation
> .....
>
> The compilation failure only happens to cpu=v2 and cpu=v3. cpu=v4 is okay
> since cpu=v4 supports 32-bit branch target offset.
>
> The above failure is due to upstream llvm patch
> https://reviews.llvm.org/D143624
> where some inlining ordering are changed in the compiler.
Hi Yonghong, Alexei,
This is a followup for the off-list discussion. I think I have a
relatively simple two pass algorithm that allows to replace jumps
longer than 2**16 by series of shorter jumps using "trampoline"
goto instructions.
The basic idea of the algorithm is to:
- Visit basic blocks sequentially from first to last (after LLVM is
done with figuring BB ordering), effectively splitting basic blocks
in two parts: "processed" and "unexplored".
- Insert "trampoline" jumps only at "unexplored" side, thus
guaranteeing that distances between basic blocks on "processed" side
never change.
- Maintain the list of "pending jumps":
- Whenever a basic block is picked from "unexplored" side
information about edges coming to and from this basic block is
added as pending jumps:
- backward edges are added before basic block is processed;
- forward edges are added after basic block is processed.
- Pending jump is a tuple (off,src,dst,backedge):
- 'src', 'dst' - basic blocks (swapped for backedges);
- 'off' - current distance from 'src'.
- When a basic block is picked from "unexplored" side:
- discard all pending jumps that have this basic block as 'dst';
- peek a pending jump for which jmp.off + bb.size > MAX_JUMP_DISTANCE;
- if such jump is present:
- split basic block;
- insert trampoline instruction;
- discard pending jump and schedule new pending jump with
trampoline src, original dst, and off=0;
- if such jump is not present move basic block from "unexplored" to
"processed";
- when basic block is moved from "unexplored" side to "processed",
bump 'off' field of each pending jump by the size of the basic
block.
So, the main part is to keep 'off' fields of pending jumps smaller
than MAX_JUMP_DISTANCE by inserting trampoline jumps.
I have a Python model for this algorithm at [0]. It passes a few
hand-coded tests but I still need to do some property-based testing.
I think I need another day to finish with testing, after that it
should be possible to translate this code to LLVM/C++ in a couple of days.
Please let me know if this is interesting.
Thanks,
Eduard
[0] https://gist.github.com/eddyz87/7e8d162b2bb2071769a9b3d960898405
[...]
next prev parent reply other threads:[~2023-11-08 2:13 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-10-31 3:58 bpf selftest pyperf180.c compilation failure with latest last llvm18 (in development) Yonghong Song
2023-11-08 2:13 ` Eduard Zingerman [this message]
2023-11-08 20:05 ` Alexei Starovoitov
2023-11-09 1:20 ` Eduard Zingerman
2023-11-09 2:58 ` Yonghong Song
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ba9076bfb983ef96ca78d584ca751b1fef3a06b9.camel@gmail.com \
--to=eddyz87@gmail.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=martin.lau@kernel.org \
--cc=yonghong.song@linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox