File size: 2,491 Bytes
a66a9c7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#!/bin/bash
# OldIron-AVX ISA gate: prove a CPU backend is AVX1 and nothing above it.
# Usage: isa-audit.sh <file-or-dir>...
#
# Why this file exists: a naive grep for "AVX2 opcodes" gives false positives both ways.
#   - vpmulld / vpblendvb / vpminsd / vpmaxsd / vpslld-q  are SSE4.1 instructions whose VEX.128
#     form is AVX1-legal, so their presence does NOT mean AVX2.
#   - unanchored patterns like  v(p[a-z]*|ps[a-z]*)  match the "vps" inside "vdivps"/"vpermilps".
# The only sound tests are (a) genuinely AVX2-only mnemonics and (b) integer-vector ops on %ymm
# registers - AVX1 has no 256-bit integer arithmetic at all.
set -uo pipefail
fails=0
audit_one() {
  local f="$1" asm
  asm=$(mktemp)
  objdump -d "$f" > "$asm" 2>/dev/null || { echo "  ! cannot disassemble $f"; return; }
  local avx2only ymminteger fma f16c zmm ymm
  avx2only=$(grep -cE '\bvpermd\b|\bpermq\b|\bvpermps\b|\bvpbroadcast[bwdq]\b|\bvpsllvd\b|\bvpsrlvd\b|\bvpsravd\b|\bvpgather[dq][dq]\b|\bvpmaskmov[dq]\b|\bvpblendd\b' "$asm")
  # integer-domain mnemonic with a ymm operand = AVX2, no exceptions on Sandy Bridge
  ymminteger=$(grep -E '\bv(padd|psub|pmul|pmin|pmax|pand|pandn|por|pxor|pcmp|punpck|pack|pshuf|palign|pblend|psll|psrl|psra|pabs|pavg|pmadd|psign|pmovs|pmovz)[a-z0-9]*\b' "$asm" | grep -c '%ymm')
  fma=$(grep -cE '\bvfmadd|\bvfnmadd|\bvfmsub|\bvfnmadd' "$asm")
  f16c=$(grep -c '\bvcvtph2ps\b\|\bvcvtps2ph\b' "$asm")
  zmm=$(grep -c '%zmm' "$asm")
  ymm=$(grep -c '%ymm' "$asm")
  # vm movdq* on ymm IS AVX1 (256-bit moves exist in AVX1), so it is deliberately not counted above.
  echo "  $f"
  printf '    AVX2-only mnemonics : %s\n    int-vector on %%ymm  : %s\n    FMA                 : %s\n    F16C                : %s\n    AVX-512 (%%zmm)      : %s\n    AVX1 %%ymm ops       : %s\n' \
    "$avx2only" "$ymminteger" "$fma" "$f16c" "$zmm" "$ymm"
  if [ "$avx2only" != "0" ] || [ "$ymminteger" != "0" ] || [ "$fma" != "0" ] || [ "$f16c" != "0" ] || [ "$zmm" != "0" ]; then
    echo "    VERDICT: FAIL - above the AVX1 floor"; fails=$((fails+1))
  elif [ "$ymm" = "0" ]; then
    echo "    VERDICT: AVX1-clean but NOT using 256-bit width (performance loss, not a crash)"
  else
    echo "    VERDICT: AVX1-clean and using 256-bit width"
  fi
  rm -f "$asm"
}
for arg in "$@"; do
  if [ -d "$arg" ]; then find "$arg" -name '*.o' -o -name '*.so*' | while read -r f; do audit_one "$f"; done
  else audit_one "$arg"; fi
done
echo "=== $fails file(s) above the AVX1 floor ==="
exit $((fails>0))