Issue |
129863
|
Summary |
[LoongArch][Inlineasm] Operand modifier 'u' and 'w' cause compilation error
|
Labels |
new issue
|
Assignees |
SixWeining
|
Reporter |
SixWeining
|
## Background
When I read llama.cpp, I find code like this:
https://github.com/ggml-org/llama.cpp/blob/master/ggml/src/ggml-cpu/ggml-cpu-quants.c#L395-L409
```
#ifdef __clang__
#define VREGS_PREFIX "$vr"
#define XREGS_PREFIX "$xr"
#else // GCC
#define VREGS_PREFIX "$f"
#define XREGS_PREFIX "$f"
#endif
#define __ALL_REGS "0,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"
// Convert __m128i to __m256i
static inline __m256i ____m256i(__m128i in) {
__m256i out = __lasx_xvldi(0);
__asm__ volatile (
".irp i," __ALL_REGS "\n\t"
" .ifc %[out], " XREGS_PREFIX"\\i \n\t"
" .irp j," __ALL_REGS "\n\t"
" .ifc %[in], " VREGS_PREFIX "\\j \n\t"
" xvpermi.q $xr\\i, $xr\\j, 0x20 \n\t"
" .endif \n\t"
" .endr \n\t"
" .endif \n\t"
".endr \n\t"
: [out] "+f" (out) : [in] "f" (in)
);
return out;
}
```
which uses too many assembler directives to convert a `__m128i` to `__m256i`. And I try to simplify it by using inline assembly operand modifier [`u` and `w`](https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#LoongArch-Operand-Modifiers). But I find gcc works while clang not because clang requires the operand type must exactly matches the modifiers (i.e. `u` requires a 256-bits vector and `w` requires a 128-bits vector).
## Testcase
```
// cat 2.c
#include <lsxintrin.h>
#include <lasxintrin.h>
// Convert __m128i to __m256i
__m256i ____m256i(__m128i in) {
__m256i out = __lasx_xvldi(0);
__asm__ volatile (
"xvpermi.q %u[out], %u[in], 0x20 \n\t"
: [out] "+f" (out) : [in] "f" (in)
);
return out;
}
```
## Compile
```
$ clang --target=loongarch64 -mlasx -O2 2.c -c
2.c:8:9: error: invalid operand in inline asm: 'xvpermi.q ${0:u}, ${1:u}, 0x20
'
"xvpermi.q %u[out], %u[in], 0x20 \n\t"
^
2.c:8:9: error: unknown operand
<inline asm>:1:18: note: instantiated into assembly here
xvpermi.q $xr1, , 0x20
^
2 errors generated.
```
## gcc is ok
```
vinsgr2vr.d $vr1, $a1, 0x0
xvldi $xr0, 0
vinsgr2vr.d $vr1, $a2, 0x1
xvpermi.q $xr0, $xr1, 0x20
xvst $xr0, $a0, 0
ret
```
@MQ-mengqing
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs