llvm / llvm/llvm-project

[X86][AVX] Unknown Token expression for Inline Asm Code that works fine with GCC.

Open
#182,728 2 comments 0 reactions 0 assignees View on GitHub
backend:X86 inline-asm
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

Following code throws errors that is incomprehensible and works fine with GCC-15.2
https://godbolt.org/z/1cTeYMeGx , I have tested with and without `-fasm-blocks` ( I am not aware if this should apply to non-MS context, May be we need to add explicit information on page https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-fasm-blocks)

```cpp
// RUN0: g++ -O3 -march=sapphirerapids -fno-exceptions -fno-rtti vpdpbusd_bench.cpp -o bench
// RUN1:clang++ -O3 -march=sapphirerapids vpdpbusd_bench.cpp -o bench
// TEST:taskset -c 2 ./bench

#include
#include
#include

static inline uint64_t tsc_start() {
unsigned aux;
_mm_mfence(); _mm_lfence();
uint64_t t = __rdtscp(&aux);
_mm_lfence();
return t;
}
static inline uint64_t tsc_stop() {
unsigned aux;
_mm_lfence();
uint64_t t = __rdtscp(&aux);
_mm_lfence(); _mm_mfence();
return t;
}

static double bench_lat_zmm(int iters) {
uint64_t t0 = tsc_start();
asm volatile(
".intel_syntax noprefix\n\t"
"vpxord zmm0, zmm0, zmm0\n\t"
"vpxord zmm1, zmm1, zmm1\n\t"
"vpxord zmm2, zmm2, zmm2\n\t"
"mov ecx, %[n]\n\t"
"1:\n\t"
"vpdpbusd zmm0, zmm1, zmm2\n\t"
"dec ecx\n\t"
"jnz 1b\n\t"
".att_syntax prefix\n\t"
:
: [n] "r"(iters)
: "ecx", "zmm0", "zmm1", "zmm2", "cc");
uint64_t t1 = tsc_stop();
return double(t1 - t0) / iters;
}

int main(){
printf("%lf",bench_lat_zmm(100));
return 0;
}
```
Error:
```bash
:33:31: error: unknown token in expression
33 | "vpxord zmm2, zmm2, zmm2\n\t"
| ^
:5:11: note: instantiated into assembly here
5 | mov ecx, %eax

```
If I remove "\t" from line 33 (offending line) error moves to next line. This is weird since compiler skipped first two same lines with same instruction and same structure.

GAS works fine.
```cpp
static double lat_zmm_gnu(int iters) {
uint64_t t0 = tsc_start();
asm volatile(
"vpxord %%zmm0, %%zmm0, %%zmm0\n\t"
"vpxord %%zmm1, %%zmm1, %%zmm1\n\t"
"vpxord %%zmm2, %%zmm2, %%zmm2\n\t"
"mov %[n], %%ecx\n\t"
"1:\n\t"
// GAS AT&T operand order: src2, src1, dst
"vpdpbusd %%zmm2, %%zmm1, %%zmm0\n\t"
"dec %%ecx\n\t"
"jnz 1b\n\t"
:
: [n] "r"(iters)
: "ecx", "zmm0", "zmm1", "zmm2", "cc");
uint64_t t1 = tsc_stop();
return double(t1 - t0) / iters;
}
```
Is this bug or know limitation?

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.