Hi,
On Tue Jun 9, 2026 at 11:09 PM -03, Henson Choi wrote:
> While looking into Andres Freund's note that cfbot is failing with crashes
> inside the JIT on the Row Pattern Recognition patch [1], I found that the
> crash is not specific to that patch at all: on the CI's AddressSanitizer
> build with LLVM 19, any query that is pushed through the LLVM JIT code
> generator crashes the backend with SIGILL. It reproduces on plain master
> with a trivial aggregate, so I am reporting it as its own issue, separate
> from that feature.
>
> [ ... ]
>
I investigated this issue a bit and I may found the root cause.
The meson build passes get_option('c_args') directly to the clang
command that generates llvmjit_types.bc and other bitcode files used for
inlining. When building with -fsanitize=address, the sanitizer
instrumentation may change struct layouts in the generated LLVM IR.
This causes a mismatch between the field indices the JIT code expects
(defined via FIELDNO_* macros, e.g., FIELDNO_EXPRSTATE_PARENT = 11) and
the actual struct layout in the bitcode. The result is an assertion
failure when accessing struct fields:
Assertion failed: (indexValid(N)), function getElementType
LLVMStructGetTypeAtIndex(StructTy=..., i=11)
IIUC the SIGILL crash in decodeDiscriminator() reported initially was
likely a secondary effect of this struct layout corruption.
I think that the fix is to filter out sanitizer flags when generating
bitcode for the JIT code, see the attached diff.
With this fix, JIT works correctly under ASAN + LLVM 19 on my machine.
Can you please also test it on your side?
I'm also wondering if this happens only with LLVM 19 or other versions
too.
--
Matheus Alcantara
EDB: https://www.enterprisedb.com
diff --git a/src/backend/jit/llvm/meson.build b/src/backend/jit/llvm/meson.build
index 7df8453ad6f..12ee6a8d4f8 100644
--- a/src/backend/jit/llvm/meson.build
+++ b/src/backend/jit/llvm/meson.build
@@ -61,7 +61,16 @@ endif
# XXX: Need to determine proper version of the function cflags for clang
bitcode_cflags = ['-fno-strict-aliasing', '-fwrapv']
-bitcode_cflags += get_option('c_args')
+
+# Filter out sanitizer flags from c_args for bitcode generation.
+# Sanitizer instrumentation changes struct layouts in LLVM IR, which breaks
+# the JIT's assumptions about field offsets.
+foreach cflag : get_option('c_args')
+ if not cflag.contains('sanitize')
+ bitcode_cflags += cflag
+ endif
+endforeach
+
bitcode_cflags += cppflags
# XXX: Worth improving on the logic to find directories here