Skip to content

Correctness bugs in instrset_detect.cpp #91

Open

Description

@HolyWu
  • instrset_detect.cpp:102 — AVX-512 check can crash on some systems. It reads CPUID leaf 0xD, which only says what the processor supports, not what the OS has enabled; it should use xgetbv(0). On an OS or VM that hasn't turned on AVX-512 state, the check still passes and the first AVX-512 instruction faults.
  • instrset_detect.cpp:103 — AVX-512 mask is incomplete. The mask 0x60 skips bit 7 (Hi16_ZMM, which covers registers zmm16–31); it should be 0xE0. If bits 5–6 are enabled but bit 7 isn't, code using zmm16–31 faults.
  • instrset_detect.cpp:106 — Undefined behavior before C++20. 1 << 31 shifts into the sign bit of a signed int; 1u << 31 fixes it.

Activity

  1. AgnerF commented on Sep 29, 2026

    @AgnerF
    Collaborator

    Are these bug reports AI generated? The code actually calls xgetbv(0).

  2. HolyWu commented on Sep 30, 2026

    @HolyWu
    ContributorAuthor

    Yes, they are.

    AVX512 needs three more XCR0 bits, and line 95 never looks at them:

    • Bit 5: opmask (k0-k7)
    • Bit 6: ZMM_Hi256 (upper halves of zmm0-15)
    • Bit 7: Hi16_ZMM (zmm16-31)

    An OS can enable YMM state but not those. Older kernels and some hypervisors do this. Then line 95 passes and AVX2 is correctly reported. But line 103 reads CPUID 0xD, which reports which XCR0 bits the CPU can enable, not which the OS did enable. So line 103 passes anyway. AVX512 code then hits #UD.

    Fix: replace line 102-103 with if ((xgetbv(0) & 0xE0) != 0xE0) return iset;. That also covers bit 7, which line 103's 0x60 mask skips.

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