Skip to content

amd64 parser drops .zero directives from constant pools, causing VMOVDQA SIGSEGV #80

Description

@zhangzhenghao

Bug description

GoAT's amd64 parser drops .zero directives from Clang local constant pools. The generated Go assembly therefore emits a shorter data symbol than the SIMD load expects. An aligned VMOVDQA then reads a truncated/insufficiently aligned symbol and crashes with SIGSEGV.

This is a follow-up to #78: local .LCPI* labels are now retained, but zero-filled ranges inside those pools are still lost.

The bug was found while generating the AVX512 INT4 batch kernel in gorse-io/xvec#79.

Reproduction

Source:

https://github.com/gorse-io/xvec/blob/905592d356ee3b2abdcee5f09620439ad7d2a5cb/internal/ailego/math_batch/src/inner_product_batch_int4_avx512.c

Generate it with the GoAT version currently used by xvec:

go tool goat \
  internal/ailego/math_batch/src/inner_product_batch_int4_avx512.c \
  --target amd64 -O3 -mavx2 -mavx512f -mavx512bw \
  -e=-fno-vectorize -e=-fno-slp-vectorize \
  -o .goat/mathbatch

Clang emits this 16-byte constant pool:

.LCPI0_4:
    .zero   4
    .zero   4
    .long   0
    .long   16

GoAT drops both .zero directives and emits only eight bytes:

DATA __goat_data_2e4c435049305f34<>+0x000(SB)/8, $0x0000001000000000
GLOBL __goat_data_2e4c435049305f34<>(SB), 8, $8

The generated function still performs a 16-byte aligned load:

VMOVDQA __goat_data_2e4c435049305f34<>(SB), X5

Running the generated kernel under qemu-x86_64 -cpu max or on the GitHub Actions AVX512 host crashes at that VMOVDQA. The xvec CI failure is visible in PR #79.

A representative failure is:

unexpected return pc for ...xvec_avx512_batch_inner_products_int4_4
...
inner_product_batch_int4_avx512.s:45
fatal error: unknown caller pc

The unexpected return pc output is secondary: Clang's generated prologue temporarily changes SP, so Go's panic unwinder cannot produce a normal traceback after the SIMD load faults. The first faulting instruction is the VMOVDQA referencing the truncated constant pool.

Expected behavior

GoAT should preserve .zero N as N zero bytes when converting Clang constant pools, so that:

  • the generated GLOBL size matches the original constant-pool size;
  • subsequent fields retain their original offsets;
  • the symbol satisfies the alignment required by aligned SIMD loads.

Alternatively, GoAT should reject unsupported constant-pool directives rather than emit a silently truncated symbol.

Environment

  • GoAT: v0.2.2-0.20260924112123-4875656d2845
  • Go: go1.27.0 linux/amd64
  • Clang: 21.1.8 (6ubuntu1)
  • objdump: GNU Binutils 2.46
  • Reproduced with qemu-x86_64 -cpu max and in xvec GitHub Actions

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions