Re: LLVM 22
Andres Freund <andres@anarazel.de>
From: Andres Freund <andres@anarazel.de>
To: Anthonin Bonnefoy <anthonin.bonnefoy@datadoghq.com>
Cc: Thomas Munro <thomas.munro@gmail.com>, PostgreSQL Hackers <pgsql-hackers@lists.postgresql.org>,
Matheus Alcantara <matheusssilv97@gmail.com>
Date: 2026-01-29T01:27:29Z
Lists: pgsql-hackers
Attachments
- test.ll (text/plain)
Hi,
On 2026-01-14 17:12:45 +0100, Anthonin Bonnefoy wrote:
> I've tried to generate multiple bitcode for a simple 'select aid % 2
> FROM pgbench_accounts limit 10;' query. To keep bitcode simple, I've
> modified the passes to use "default<O0>,mem2reg,inline" when we have
> JIT inline without optimization (as described in [0]). I've tried the
> following
> - LLVM21: With lifetime
> - LLVM21: Without lifetime
> - LLVM22: With Poison
> - LLVM22: Without Poison
>
> In the 4 scenarios, the generated bc were the same with the exact same
> instructions. Removing the lifetime end or the poison value doesn't
> seem to change anything at this level of optimisation.
>
> I'm not sure how to interpret this. Maybe the test is incorrect and a
> different function needs to be called to possibly trigger the issue?
> Or the poison/lifetime is only useful when going through the O3
> optimisation pass?
I think it's the latter - at -O0 there's nothing that could use the
information.
The goal of the lifetime annotations was to allow llvm to remove stores an
loads of FunctionCallInfo->{args,isnull}. After we stored e.g. fcinfo->isnull
before a function call and then checked it after the function call, we don't
need it anymore. I think that can only matter when the called function is
actually inlined, otherwise there's no way that LLVM can see the store is
unnecessary.
Unfortunately there's an issue with modern LLVM, regardless of lifetime or
poison. Generally it's able to eliminate stores that are followed by a
poison, but if there's a load inbetween, it fails. The odd part is that it
*is* able to eliminate the load (by forwarding the stored value).
It seems to be an ordering issue - instcombine is required to remove the load,
but also removes the poison, which in turn is required for dead store
elimination. Gngng.
I've attached a reproducer.
I'm not sure the llvm folks will be all that interested - there's no real C
correspondance to this. And, as it turns out, if I feed the memory to
something like free(), the analysis actually *does* figure out that it's not
needed anymore.
I think if / once we move most of this to a stack allocation, the problem
would also vanish.
Greetings,
Andres Freund
Commits
-
jit: No backport::SectionMemoryManager for LLVM 22.
- 9b354cfc5584 14.23 landed
- 963fccc09cc6 15.18 landed
- 8354cd7ff575 16.14 landed
- 0a2291b59f9b 17.10 landed
- 5c54e0f48fa2 18.4 landed
- be21341e13d9 19 (unreleased) landed
-
jit: Stop emitting lifetime.end for LLVM 22.
- b4e7cd428c00 14.23 landed
- c00ea2b5b4f1 15.18 landed
- 26f27c592c5d 16.14 landed
- b6d0cddbe27d 17.10 landed
- 78cea19bf7da 18.4 landed
- de6b80e5ff4b 19 (unreleased) landed