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

Reply via email to