https://gcc.gnu.org/g:060d50fe29d01c429320114a71a549c512219782
commit r17-4522-g060d50fe29d01c429320114a71a549c512219782 Author: Matt Turner <[email protected]> Date: Mon Sep 21 07:26:53 2026 -0600 [PATCH 2/5] aarch64: umov and smov require base Advanced SIMD The [r, w] alternatives of the SHORT extend patterns emit umov and smov, which are Advanced SIMD instructions, but they are guarded by the "fp" arch attribute. With -march=armv8-a+nosimd a 16-bit value in an FP register is therefore extended with an instruction the assembler rejects: unsigned int f (_Float16 x) { unsigned short s; __builtin_memcpy (&s, &x, sizeof (s)); return s; } Error: selected processor does not support `umov w0,v0.h[0]' Guard both alternatives with "base_simd" instead, so that without SIMD the value is extended from memory. gcc/ChangeLog: * config/aarch64/aarch64.md (*extend<SHORT:mode><GPI:mode>2_aarch64): Guard the smov alternative with base_simd rather than fp. (*zero_extend<SHORT:mode><GPI:mode>2_aarch64): Likewise for umov. gcc/testsuite/ChangeLog: * gcc.target/aarch64/nosimd-extend.c: New test. Diff: --- gcc/config/aarch64/aarch64.md | 18 +++++++++--------- gcc/testsuite/gcc.target/aarch64/nosimd-extend.c | 24 ++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index 302658c970d2..b299ef14283c 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -2666,10 +2666,10 @@ [(set (match_operand:GPI 0 "register_operand") (sign_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand")))] "" - {@ [ cons: =0 , 1 ; attrs: type , arch ] - [ r , r ; extend , * ] sxt<SHORT:extsize>\t%<GPI:w>0, %w1 - [ r , m ; load_4 , * ] ldrs<SHORT:extsize>\t%<GPI:w>0, %1 - [ r , w ; neon_to_gp , fp ] smov\t%<GPI:w>0, %1.<SHORT:size>[0] + {@ [ cons: =0 , 1 ; attrs: type , arch ] + [ r , r ; extend , * ] sxt<SHORT:extsize>\t%<GPI:w>0, %w1 + [ r , m ; load_4 , * ] ldrs<SHORT:extsize>\t%<GPI:w>0, %1 + [ r , w ; neon_to_gp , base_simd ] smov\t%<GPI:w>0, %1.<SHORT:size>[0] } ) @@ -2677,11 +2677,11 @@ [(set (match_operand:GPI 0 "register_operand") (zero_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand")))] "" - {@ [ cons: =0 , 1 ; attrs: type , arch ] - [ r , r ; logic_imm , * ] and\t%<GPI:w>0, %<GPI:w>1, <SHORT:short_mask> - [ r , m ; load_4 , * ] ldr<SHORT:size>\t%w0, %1 - [ w , m ; f_loads , fp ] ldr\t%<SHORT:size>0, %1 - [ r , w ; neon_to_gp , fp ] umov\t%w0, %1.<SHORT:size>[0] + {@ [ cons: =0 , 1 ; attrs: type , arch ] + [ r , r ; logic_imm , * ] and\t%<GPI:w>0, %<GPI:w>1, <SHORT:short_mask> + [ r , m ; load_4 , * ] ldr<SHORT:size>\t%w0, %1 + [ w , m ; f_loads , fp ] ldr\t%<SHORT:size>0, %1 + [ r , w ; neon_to_gp , base_simd ] umov\t%w0, %1.<SHORT:size>[0] } ) diff --git a/gcc/testsuite/gcc.target/aarch64/nosimd-extend.c b/gcc/testsuite/gcc.target/aarch64/nosimd-extend.c new file mode 100644 index 000000000000..ce5dce389f30 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/nosimd-extend.c @@ -0,0 +1,24 @@ +/* { dg-do assemble } */ +/* { dg-options "-O2 -march=armv8-a+nosimd -save-temps" } */ + +/* umov and smov are Advanced SIMD instructions, so they must not be used + to move a 16-bit value out of an FP register when SIMD is disabled. */ + +unsigned int +zext (_Float16 x) +{ + unsigned short s; + __builtin_memcpy (&s, &x, sizeof (s)); + return s; +} + +int +sext (_Float16 x) +{ + short s; + __builtin_memcpy (&s, &x, sizeof (s)); + return s; +} + +/* { dg-final { scan-assembler-not {\tumov\t} } } */ +/* { dg-final { scan-assembler-not {\tsmov\t} } } */
