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.

Passes bootstrap & regress, OK for commit?

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 
enum.
        (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.

---

diff --git a/gcc/config/aarch64/aarch64-simd.md 
b/gcc/config/aarch64/aarch64-simd.md
index 
6eeb5aa4871eceabb8e46e52bd63f0aa634b9f3d..2e9f30b9bf50eec7a575f4e5037d3350f7ebc95a
 100644
--- a/gcc/config/aarch64/aarch64-simd.md
+++ b/gcc/config/aarch64/aarch64-simd.md
@@ -1135,13 +1135,11 @@ (define_insn "and<mode>3<vczle><vczbe>"
 (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 
d38345770ebab15cf872c24b3ec8ab8cc5cce3e7..7c656476c4974529ae71a6d73328a0cd68dd5ef8
 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 () {}
@@ -22987,14 +22987,16 @@ aarch64_sve_valid_immediate (unsigned HOST_WIDE_INT 
val64,
        {
          /* 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;
        }
     }
@@ -23002,7 +23004,7 @@ aarch64_sve_valid_immediate (unsigned HOST_WIDE_INT 
val64,
     {
       /* DUPM.  */
       if (info)
-       *info = simd_immediate_info (mode, val);
+       *info = simd_immediate_info (mode, val, simd_immediate_info::SVE_MOV);
       return true;
     }
   return false;
@@ -23209,8 +23211,13 @@ aarch64_simd_valid_imm (rtx op, simd_immediate_info 
*info,
 
   if (vec_flags & VEC_SVE_DATA)
     return aarch64_sve_valid_immediate (val64, info, which);
-  else
-    return aarch64_advsimd_valid_immediate (val64, info, which);
+
+  if (aarch64_advsimd_valid_immediate (val64, info, which))
+    return true;
+
+  if (TARGET_SVE)
+    return aarch64_sve_valid_immediate (val64, info, which);
+  return false;
 }
 
 /* Return true if OP is a valid SIMD move immediate for SVE or AdvSIMD.  */
@@ -25391,6 +25398,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");
@@ -25410,8 +25425,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 
0a171387b1a73b85db0ae2ccbc788a3d7f28a082..2c18af94b8eca7a7985a238a4de8c5d0b3766acb
 100644
--- a/gcc/config/aarch64/predicates.md
+++ b/gcc/config/aarch64/predicates.md
@@ -943,11 +943,6 @@ (define_predicate "aarch64_sve_logical_operand"
   (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 
32cdc8263d194729e4a89023c7602c7e3b80d022..6f36f32415ac92c2638c317844d8e62ecda7e484
 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 
ab23f677d4fc93487affc2c9095e38df36371a4b..f92059a97f576f9d4e8a03cbfcac0985c1baa489
 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 
a8b27199ff83d0eebadfc7dcf03f94e1229d76b8..03560008fda16b1d7c62fe2daaed8cad98127827
 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 
19a7695e605bc8aced486a9c450d1cdc6be4691a..fe08fe31fe87aab4a7ce8497d05488a42fe9ae21
 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)

Reply via email to