-
-
Notifications
You must be signed in to change notification settings - Fork 427
Description
The LLVM 21 upgrade introduced a bug where FFI functions that write through pointer parameters have their writes optimized away in release builds.
The root cause: genfun_param_attrs maps Pony's tag capability to LLVM's readonly parameter attribute. This tells LLVM the function won't write through the pointer. That's incorrect when the pointer gets passed to an FFI function that does write through it (e.g., getsockname filling in a sockaddr).
This worked before LLVM 21 because older LLVM versions weren't as aggressive about exploiting readonly to eliminate loads. With LLVM 21, after inlining a Pony wrapper around an FFI call, the optimizer sees: memset to zero → call with readonly pointer → load, and concludes the load must return zero.
The symptom: lori's ListenerLocalAddress test fails in release mode because local_address() always returns port 0. It passes with --debug because the optimizer doesn't run.
A temporary fix that moves TK_TAG from the readonly group to the no-attribute group (with trn and ref) is up in #4926. val and box have real immutability/read-only guarantees that make readonly correct. tag only means identity-comparison-only in Pony, which doesn't imply the pointed-to memory won't be written through other paths.
This needs discussion about whether the temporary fix is the right long-term approach, or whether we need something more nuanced.