This is a summary of discussions relative to the merge request created by 
Torbjörn Svensson (azoff) <[email protected]> titled
testsuite: use valid ARM GPR pair in asm-hard-reg-6.c [PR124328]
since its creation.

Description: I've tested this change on top of r17-2833-g32657f29f91871 and 
r16-9480-g967a69a03886ebd6.

Ok for trunk and releases/gcc-16?

--

CC: [email protected]

The full and up to date discussion can be found at 
https://forge.sourceware.org/gcc/gcc/pulls/217

The merge request has been closed without being merged directly on the forge 
repository.


On 2026-08-17 15:13:02+00:00, Richard Earnshaw (rearnsha) wrote:

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
```


On 2026-08-17 15:32:41+00:00, Richard Earnshaw (rearnsha) wrote:

Ah, the missing information was that to trip the error, you need 
`-march=armv8.1-m.main+mve`.  armv8.1-m.main is not enough on its own.


On 2026-08-17 15:57:43+00:00, Richard Earnshaw (rearnsha) wrote:

I want to think about this case for a bit.  I'm wondering if the restriction 
here should be considered an ABI break.  We do want to encourage the compiler 
to use even numbered register pairs as it can generate better code for both Arm 
state (using LDRD/STRD) and MVE; but I'm not sure we should require this for 
user assembly code.


On 2026-08-28 13:49:08+00:00, Torbjörn Svensson (azoff) wrote:

Gentle ping! :)


On 2026-09-01 16:34:28+00:00, Richard Earnshaw (rearnsha) wrote:

I'm going to reject this.  I think the code in the test is OK and the problem 
is in the compiler rejecting it for certain architecture settings.  I've 
commented on the PR. Note that clang does seem to allow this register 
allocation for the same settings.

Reply via email to