Skip to content

Instantly share code, notes, and snippets.

@vsivsi
Last active November 4, 2021 20:48
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vsivsi/fff8618ace4b02eb410dd8792779bf32 to your computer and use it in GitHub Desktop.
Save vsivsi/fff8618ace4b02eb410dd8792779bf32 to your computer and use it in GitHub Desktop.
Reproduction of AVX512 opmask clobbering

Maskcheck is a repro of opmask clobbering by golang async preemption

A GNU C / Asm implementation is here: https://gist.github.com/vsivsi/8511aca1bac528f49fbb45a636afa4b5

NOTE! This must be run on an Intel processor supporting AVX512F/DQ

To test: go test -count 1 -timeout 15m -run '^TestMask$' gist.github.com/vsivsi/fff8618ace4b02eb410dd8792779bf32

This should fail with something like:

% go test -count 1 -timeout 15m -run '^TestMask$' gist.github.com/vsivsi/fff8618ace4b02eb410dd8792779bf32
--- FAIL: TestMask (0.44s)
    maskcheck_test.go:16: Failed for iteration: 0 with return value: 69247732
    maskcheck_test.go:16: Failed for iteration: 1 with return value: 42154190
    maskcheck_test.go:16: Failed for iteration: 2 with return value: 43317668
    maskcheck_test.go:16: Failed for iteration: 3 with return value: 41575878
    maskcheck_test.go:16: Failed for iteration: 4 with return value: 38750998
    maskcheck_test.go:16: Failed for iteration: 5 with return value: 42730788
    maskcheck_test.go:16: Failed for iteration: 6 with return value: 41721686
    maskcheck_test.go:16: Failed for iteration: 7 with return value: 40051735
    maskcheck_test.go:16: Failed for iteration: 8 with return value: 40951907
    maskcheck_test.go:16: Failed for iteration: 9 with return value: 41829708
    maskcheck_test.go:16: Failed for iteration: 10 with return value: 33994560
    maskcheck_test.go:16: Failed for iteration: 11 with return value: 31676633
    maskcheck_test.go:16: Failed for iteration: 12 with return value: 32128705
    maskcheck_test.go:16: Failed for iteration: 13 with return value: 41683214
    maskcheck_test.go:16: Failed for iteration: 14 with return value: 38697082
    maskcheck_test.go:16: Failed for iteration: 15 with return value: 35869348
    maskcheck_test.go:16: Failed for iteration: 16 with return value: 37629503
    maskcheck_test.go:16: Failed for iteration: 17 with return value: 32931377
    maskcheck_test.go:16: Failed for iteration: 18 with return value: 44475243
    maskcheck_test.go:16: Failed for iteration: 19 with return value: 42445948
FAIL
FAIL    gist.github.com/vsivsi/fff8618ace4b02eb410dd8792779bf32 0.744s
FAIL

Disabling async preemption rescues it: GODEBUG=asyncpreemptoff=1 go test -count 1 -timeout 15m -run '^TestMask$' gist.github.com/vsivsi/fff8618ace4b02eb410dd8792779bf32

% GODEBUG=asyncpreemptoff=1 go test -count 1 -timeout 15m -run '^TestMask$' gist.github.com/vsivsi/fff8618ace4b02eb410dd8792779bf32 
ok      gist.github.com/vsivsi/fff8618ace4b02eb410dd8792779bf32 0.858s
module gist.github.com/vsivsi/fff8618ace4b02eb410dd8792779bf32
go 1.17
require golang.org/x/sys v0.0.0-20211029165221-6e7872819dc8
golang.org/x/sys v0.0.0-20211029165221-6e7872819dc8 h1:M69LAlWZCshgp0QSzyDcSsSIejIEeuaCVpmwcKwyLMk=
golang.org/x/sys v0.0.0-20211029165221-6e7872819dc8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
// +build !gccgo,!purego
#include "textflag.h"
// func maskCheck8(x uint64) uint64
// Requires: AVX512DQ
TEXT ·maskCheck8(SB), NOSPLIT, $0-16
MOVQ x+0(FP), AX
MOVB $0xfb, CL
KMOVB CX, K1
loop:
KMOVB K1, DX
CMPB DL, CL
JNE fail
DECQ AX
JNZ loop
fail:
MOVQ AX, ret+8(FP)
RET
package maskcheck
import (
"testing"
"golang.org/x/sys/cpu"
)
// Stub: Check if AVX512 Opmasks are being clobbered.
func maskCheck8(x uint64) uint64
func TestMask(t *testing.T) {
if !(cpu.X86.HasAVX512 && cpu.X86.HasAVX512DQ) {
t.Fatalf("No AVX512F/DQ support present!")
}
fail := false
for x := 0; x < 20; x++ {
r := maskCheck8(100000000)
if r != 0 {
fail = true
t.Logf("Failed for iteration: %d with return value: %d", x, r)
}
}
if fail {
t.Fail()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment