https://gcc.gnu.org/g:756890d66cf4971fc11187ccdf5893681aa661a1

commit r15-4568-g756890d66cf4971fc11187ccdf5893681aa661a1
Author: Wilco Dijkstra <wilco.dijks...@arm.com>
Date:   Tue Oct 8 15:55:25 2024 +0000

    AArch64: Improve SIMD immediate generation (2/3)
    
    Allow use of SVE immediates when generating AdvSIMD code and SVE is 
available.
    First check for a valid AdvSIMD immediate, and if SVE is available, try 
using
    an SVE move or bitmask immediate.
    
    gcc/ChangeLog:
    
            * config/aarch64/aarch64-simd.md (ior<mode>3<vczle><vczbe>):
            Use aarch64_reg_or_orr_imm predicate.  Combine SVE/AdvSIMD 
immediates
            and use aarch64_output_simd_orr_imm.
            * config/aarch64/aarch64.cc (struct simd_immediate_info): Add 
SVE_MOV.
            (aarch64_sve_valid_immediate): Use SVE_MOV for SVE move immediates.
            (aarch64_simd_valid_imm): Enable SVE SIMD immediates when possible.
            (aarch64_output_simd_imm): Support emitting SVE SIMD immediates.
            * config/aarch64/predicates.md (aarch64_orr_imm_sve_advsimd): 
Remove.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.target/aarch64/sve/acle/asm/insr_s64.c: Allow SVE MOV imm.
            * gcc.target/aarch64/sve/acle/asm/insr_u64.c: Likewise.
            * gcc.target/aarch64/sve/fneg-abs_1.c: Update to check for ORRI.
            * gcc.target/aarch64/sve/fneg-abs_2.c: Likewise.
            * gcc.target/aarch64/sve/simd_imm_mov.c: New test.

Diff:
---
 gcc/config/aarch64/aarch64-simd.md                 | 10 +++---
 gcc/config/aarch64/aarch64.cc                      | 41 +++++++++++++++++-----
 gcc/config/aarch64/predicates.md                   |  5 ---
 .../gcc.target/aarch64/sve/acle/asm/insr_s64.c     |  4 +--
 .../gcc.target/aarch64/sve/acle/asm/insr_u64.c     |  4 +--
 gcc/testsuite/gcc.target/aarch64/sve/fneg-abs_1.c  |  6 ++--
 gcc/testsuite/gcc.target/aarch64/sve/fneg-abs_2.c  |  4 +--
 .../gcc.target/aarch64/sve/simd_imm_mov.c          | 39 ++++++++++++++++++++
 8 files changed, 85 insertions(+), 28 deletions(-)

diff --git a/gcc/config/aarch64/aarch64-simd.md 
b/gcc/config/aarch64/aarch64-simd.md
index b031b52c8fb1..bf4863441de1 100644
--- a/gcc/config/aarch64/aarch64-simd.md
+++ b/gcc/config/aarch64/aarch64-simd.md
@@ -1135,13 +1135,11 @@
 (define_insn "ior<mode>3<vczle><vczbe>"
   [(set (match_operand:VDQ_I 0 "register_operand")
        (ior:VDQ_I (match_operand:VDQ_I 1 "register_operand")
-                  (match_operand:VDQ_I 2 "aarch64_orr_imm_sve_advsimd")))]
+                  (match_operand:VDQ_I 2 "aarch64_reg_or_orr_imm")))]
   "TARGET_SIMD"
-  {@ [ cons: =0 , 1 , 2; attrs: arch ]
-     [ w        , w , w  ; simd      ] orr\t%0.<Vbtype>, %1.<Vbtype>, 
%2.<Vbtype>
-     [ w        , 0 , vsl; sve       ] orr\t%Z0.<Vetype>, %Z0.<Vetype>, #%2
-     [ w        , 0 , Do ; simd      ] \
-       << aarch64_output_simd_orr_imm (operands[2], <bitsize>);
+  {@ [ cons: =0 , 1 , 2  ]
+     [ w        , w , w  ] orr\t%0.<Vbtype>, %1.<Vbtype>, %2.<Vbtype>
+     [ w        , 0 , Do ] << aarch64_output_simd_orr_imm (operands[2], 
<bitsize>);
   }
   [(set_attr "type" "neon_logic<q>")]
 )
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 4db224ff0421..614f99e799ca 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -140,7 +140,7 @@ enum simd_immediate_check {
 /* Information about a legitimate vector immediate operand.  */
 struct simd_immediate_info
 {
-  enum insn_type { MOV, MVN, INDEX, PTRUE };
+  enum insn_type { MOV, MVN, INDEX, PTRUE, SVE_MOV };
   enum modifier_type { LSL, MSL };
 
   simd_immediate_info () {}
@@ -22982,14 +22982,16 @@ aarch64_sve_valid_immediate (unsigned HOST_WIDE_INT 
ival, scalar_int_mode mode,
        {
          /* DUP with no shift.  */
          if (info)
-           *info = simd_immediate_info (mode, val);
+           *info = simd_immediate_info (mode, val,
+                                        simd_immediate_info::SVE_MOV);
          return true;
        }
       if ((val & 0xff) == 0 && IN_RANGE (val, -0x8000, 0x7f00))
        {
          /* DUP with LSL #8.  */
          if (info)
-           *info = simd_immediate_info (mode, val);
+           *info = simd_immediate_info (mode, val,
+                                        simd_immediate_info::SVE_MOV);
          return true;
        }
     }
@@ -22997,7 +22999,7 @@ aarch64_sve_valid_immediate (unsigned HOST_WIDE_INT 
ival, scalar_int_mode mode,
     {
       /* DUPM.  */
       if (info)
-       *info = simd_immediate_info (mode, val);
+       *info = simd_immediate_info (mode, val, simd_immediate_info::SVE_MOV);
       return true;
     }
   return false;
@@ -23322,8 +23324,13 @@ aarch64_simd_valid_imm (rtx op, simd_immediate_info 
*info,
 
   if (vec_flags & VEC_SVE_DATA)
     return aarch64_sve_valid_immediate (ival, imode, info, which);
-  else
-    return aarch64_advsimd_valid_immediate (val64, imode, info, which);
+
+  if (aarch64_advsimd_valid_immediate (val64, imode, info, which))
+    return true;
+
+  if (TARGET_SVE)
+    return aarch64_sve_valid_immediate (ival, imode, info, which);
+  return false;
 }
 
 /* Return true if OP is a valid SIMD move immediate for SVE or AdvSIMD.  */
@@ -25427,6 +25434,14 @@ aarch64_output_simd_imm (rtx const_vector, unsigned 
width,
          return templ;
        }
 
+      if (info.insn == simd_immediate_info::SVE_MOV)
+       {
+         gcc_assert (TARGET_SVE);
+         snprintf (templ, sizeof (templ), "mov\t%%Z0.%c, #" 
HOST_WIDE_INT_PRINT_DEC,
+                   element_char, INTVAL (info.u.mov.value));
+         return templ;
+       }
+
       mnemonic = info.insn == simd_immediate_info::MVN ? "mvni" : "movi";
       shift_op = (info.u.mov.modifier == simd_immediate_info::MSL
                  ? "msl" : "lsl");
@@ -25446,8 +25461,18 @@ aarch64_output_simd_imm (rtx const_vector, unsigned 
width,
   else
     {
       /* AARCH64_CHECK_ORR or AARCH64_CHECK_AND.  */
-      mnemonic = info.insn == simd_immediate_info::MVN ? "bic" : "orr";
-      if (info.u.mov.shift)
+      mnemonic = "orr";
+      if (which == AARCH64_CHECK_AND)
+       mnemonic = info.insn == simd_immediate_info::MVN ? "bic" : "and";
+
+      if (info.insn == simd_immediate_info::SVE_MOV)
+       {
+         gcc_assert (TARGET_SVE);
+         snprintf (templ, sizeof (templ), "%s\t%%Z0.%c, %%Z0.%c, "
+                   HOST_WIDE_INT_PRINT_DEC, mnemonic, element_char,
+                   element_char, INTVAL (info.u.mov.value));
+       }
+      else if (info.u.mov.shift)
        snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, #"
                  HOST_WIDE_INT_PRINT_DEC ", %s #%d", mnemonic, lane_count,
                  element_char, UINTVAL (info.u.mov.value), "lsl",
diff --git a/gcc/config/aarch64/predicates.md b/gcc/config/aarch64/predicates.md
index 0a171387b1a7..2c18af94b8ec 100644
--- a/gcc/config/aarch64/predicates.md
+++ b/gcc/config/aarch64/predicates.md
@@ -943,11 +943,6 @@
   (ior (match_operand 0 "register_operand")
        (match_operand 0 "aarch64_sve_logical_immediate")))
 
-(define_predicate "aarch64_orr_imm_sve_advsimd"
-  (ior (match_operand 0 "aarch64_reg_or_orr_imm")
-       (and (match_test "TARGET_SVE")
-           (match_operand 0 "aarch64_sve_logical_operand"))))
-
 (define_predicate "aarch64_sve_gather_offset_b"
   (ior (match_operand 0 "register_operand")
        (match_operand 0 "aarch64_sve_gather_immediate_b")))
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/insr_s64.c 
b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/insr_s64.c
index 32cdc8263d19..6f36f32415ac 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/insr_s64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/insr_s64.c
@@ -43,8 +43,8 @@ TEST_UNIFORM_Z (insr_0_s64_untied, svint64_t,
 /*
 ** insr_1_s64:
 ** (
-**     mov     (x[0-9]+), #?1
-**     insr    z0\.d, \1
+**     mov     z([0-9]+)\.d, #?1
+**     insr    z0\.d, d\1
 ** |
 **     movi    v([0-9]+)\.2d, 0x1
 **     insr    z0\.d, d\2
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/insr_u64.c 
b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/insr_u64.c
index ab23f677d4fc..f92059a97f57 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/insr_u64.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/insr_u64.c
@@ -43,8 +43,8 @@ TEST_UNIFORM_Z (insr_0_u64_untied, svuint64_t,
 /*
 ** insr_1_u64:
 ** (
-**     mov     (x[0-9]+), #?1
-**     insr    z0\.d, \1
+**     mov     z([0-9]+)\.d, #?1
+**     insr    z0\.d, d\1
 ** |
 **     movi    v([0-9]+)\.2d, 0x1
 **     insr    z0\.d, d\2
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/fneg-abs_1.c 
b/gcc/testsuite/gcc.target/aarch64/sve/fneg-abs_1.c
index a8b27199ff83..03560008fda1 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/fneg-abs_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/fneg-abs_1.c
@@ -6,7 +6,7 @@
 
 /*
 ** t1:
-**     orr     z[0-9]+.s, z[0-9]+.s, #-2147483648
+**     orr     v0.2s, #?128, lsl #?24
 **     ret
 */
 float32x2_t t1 (float32x2_t a)
@@ -16,7 +16,7 @@ float32x2_t t1 (float32x2_t a)
 
 /*
 ** t2:
-**     orr     z[0-9]+.s, z[0-9]+.s, #-2147483648
+**     orr     v0.4s, #?128, lsl #?24
 **     ret
 */
 float32x4_t t2 (float32x4_t a)
@@ -26,7 +26,7 @@ float32x4_t t2 (float32x4_t a)
 
 /*
 ** t3:
-**     orr     z[0-9]+.d, z[0-9]+.d, #-9223372036854775808
+**     orr     z[0-9]+.d, z[0-9]+.d, #?-9223372036854775808
 **     ret
 */
 float64x2_t t3 (float64x2_t a)
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/fneg-abs_2.c 
b/gcc/testsuite/gcc.target/aarch64/sve/fneg-abs_2.c
index 19a7695e605b..fe08fe31fe87 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/fneg-abs_2.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/fneg-abs_2.c
@@ -7,7 +7,7 @@
 
 /*
 ** f1:
-**     orr     z0.s, z0.s, #-2147483648
+**     orr     v0.2s, #?128, lsl #?24
 **     ret
 */
 float32_t f1 (float32_t a)
@@ -17,7 +17,7 @@ float32_t f1 (float32_t a)
 
 /*
 ** f2:
-**     orr     z0.d, z0.d, #-9223372036854775808
+**     orr     z0.d, z0.d, #?-9223372036854775808
 **     ret
 */
 float64_t f2 (float64_t a)
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/simd_imm_mov.c 
b/gcc/testsuite/gcc.target/aarch64/sve/simd_imm_mov.c
new file mode 100644
index 000000000000..57aa9807e6ab
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/simd_imm_mov.c
@@ -0,0 +1,39 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+#include <arm_neon.h>
+
+typedef short v8hi __attribute__((vector_size(16)));
+typedef int v4si __attribute__((vector_size(16)));
+typedef long v2di __attribute__((vector_size(16)));
+
+/*
+** t1:
+**     mov     z0.s, #?4092
+**     ret
+*/
+v4si t1 ()
+{
+  return (v4si) { 0xffc, 0xffc, 0xffc, 0xffc };
+}
+
+/*
+** t2:
+**     mov     z0.h, #?510
+**     ret
+*/
+v8hi t2 ()
+{
+  return (v8hi) { 510, 510, 510, 510, 510, 510, 510, 510 };
+}
+
+/*
+** t3:
+**     mov     z0.d, #?1
+**     ret
+*/
+v2di t3 ()
+{
+  return (v2di) { 1, 1 };
+}

Reply via email to