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

Reply via email to