I can't reproduce the issue you're seeing.  If I run
```
$ ./cc1 -O2 -o - ~/gnusrc/gcc/master/gcc/testsuite/gcc.dg/asm-hard-reg-6.c 
-mthumb -march=armv8.1-m.main -quiet
```
I get (stripping out some of the unnecessary verbiage):
```
        .arch armv8.1-m.main
        .fpu softvfp
        .eabi_attribute 20, 1
        .eabi_attribute 21, 1
        .eabi_attribute 23, 3
        .eabi_attribute 24, 1
        .eabi_attribute 25, 1
        .eabi_attribute 26, 1
        .eabi_attribute 30, 2
        .eabi_attribute 34, 1
        .eabi_attribute 18, 4
        .file   "asm-hard-reg-6.c"
        .text
        .align  1
        .p2align 2,,3
        .global test_reg_reg
        .syntax unified
        .thumb
        .thumb_func
        .type   test_reg_reg, %function
test_reg_reg:
        mov     r3, r1
        mov     r1, r0
        foo     r1,r3
        bx      lr
        .size   test_reg_reg, .-test_reg_reg
        .global test_reg_mem
        .syntax unified
        .thumb
        .thumb_func
        .type   test_reg_mem, %function
test_reg_mem:
        mov     r2, r0
        bar     r2,[r1]
        bx      lr
        .size   test_reg_mem, .-test_reg_mem
        .ident  "GCC: (master) 17.0.0 20260817 (experimental) [master 
r17-564-g10aa8833b04]"
```
Looking at the testcase itself, we have:
```
void
test_reg_mem (int x, long long *y)
{
  __asm__ ("bar\t%0,%1" :: GPR1"m,"GPR2 (x), GPR3",m" (*y));
}
```
Which, after preprocessing becomes:
```
void
test_reg_mem (int x, long long *y)
{
  __asm__ ("bar\t%0,%1" :: "{r1}""m,""{r2}" (x), "{r3}"",m" (*y));
}

```
or, more simply:
```
void
test_reg_mem (int x, long long *y)
{
  __asm__ ("bar\t%0,%1" :: "{r1}m,{r2}" (x), "{r3},m" (*y));
}

```
These constraints are strange, but I don't think illegal.  They're strange in 
that there are two alternatives.  The first alternative permits either a hard 
reg or a mem for operand `x` and a hard reg for `*y`; the second permits a hard 
reg for `x` and a mem (read 'load') for *y.  The compiler ends up picking the 
second alternative and then everything is happy as we never need to load the 
value into core registers.

But even if I tweak the testcase to remove the second alternative, the compiler 
is still producing correct output: it loads the value into an even pair, then 
shuffles values around to get the result into r3 --- ugly, but it's what the 
user asked for.
```
test_reg_mem:
        ldrd    r2, [r1]
        push    {r4}
        mov     r1, r0
        mov     r4, r3
        mov     r3, r2
        bar     r1,r3
        pop     {r4}
        bx      lr
```

--
https://forge.sourceware.org/gcc/gcc/pulls/217#issuecomment-7187

Reply via email to