Hi Richard,
The LDADD atomics do not support the zero register as an input, so there is no
need
to handle that as a special case early on, only to then disallow it in the
final instruction.
Doing integer operations on reinterpreted floating point values makes no sense
at all.
So FP should not be a supported type here.
If I compile without LSE, I get this instead of an error:
gcc/gcc/testsuite/gcc.target/aarch64/atomic_fetch_add_with_shuh.c:22:1: error:
unrecognizable insn:
22 | }
| ^
(insn 8 7 9 2 (parallel [
(set (reg:QI 105)
(mem:QI (reg:DI 104) [0 S1 A8]))
(set (mem:QI (reg:DI 104) [0 S1 A8])
(unspec_volatile:QI [
(mem:QI (reg:DI 104) [0 S1 A8])
(reg:QI 103)
(const_int 0 [0]) repeated x2
] UNSPECV_ATOMIC_LDOP_PLUS))
])
"gcc/gcc/testsuite/gcc.target/aarch64/atomic_fetch_add_with_shuh.c":21:10 -1
(nil))
during RTL pass: vregs
Another issue is that the intrinsic loses the signedness of the original
expression, eg:
long f1(int y, int x, int *p)
{
return __arm_atomic_fetch_add_with_hint (p, x, __ATOMIC_RELAXED, 1);
}
long f2(int y, int x, int *p)
{
return __atomic_fetch_add (p, x, __ATOMIC_RELAXED);
}
f1:
shuh ph
ldadd w1, w0, [x2]
uxtw x0, w0
ret
f2:
ldadd w1, w0, [x2]
sxtw x0, w0
ret
Cheers,
Wilco