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} } } */

Reply via email to