]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
aarch64: Use VNx16BI for svdupq_b*
authorRichard Sandiford <richard.sandiford@arm.com>
Mon, 4 Aug 2025 10:45:36 +0000 (11:45 +0100)
committerRichard Sandiford <richard.sandiford@arm.com>
Mon, 4 Aug 2025 10:45:36 +0000 (11:45 +0100)
This patch continues the work of making ACLE intrinsics use VNx16BI
for svbool_t results.  It deals with the predicate forms of svdupq.

The general predicate expansion builds an equivalent integer vector
and then compares it with zero.  This patch therefore relies on
the earlier patches to the comparison patterns.

gcc/
* config/aarch64/aarch64-protos.h
(aarch64_convert_sve_data_to_pred): Remove the mode argument.
* config/aarch64/aarch64.cc
(aarch64_sve_emit_int_cmp): Allow PRED_MODE to be VNx16BI or
the natural predicate mode for the data mode.
(aarch64_convert_sve_data_to_pred): Remove the mode argument
and instead always create a VNx16BI result.
(aarch64_expand_sve_const_pred): Update call accordingly.
* config/aarch64/aarch64-sve-builtins-base.cc
(svdupq_impl::expand): Likewise, ensuring that the result
has mode VNx16BI.

gcc/testsuite/
* gcc.target/aarch64/sve/acle/general/dupq_13.c: New test.

gcc/config/aarch64/aarch64-protos.h
gcc/config/aarch64/aarch64-sve-builtins-base.cc
gcc/config/aarch64/aarch64.cc
gcc/testsuite/gcc.target/aarch64/sve/acle/general/dupq_13.c [new file with mode: 0644]

index 87b3f4551b4f62f667713eb53cee73637248c5b9..36bd88593ffe8b2c2efe80a5ec95acf7e528673c 100644 (file)
@@ -1020,7 +1020,7 @@ void aarch64_err_no_fpadvsimd (machine_mode);
 void aarch64_expand_epilogue (rtx_call_insn *);
 rtx aarch64_ptrue_all (unsigned int);
 opt_machine_mode aarch64_ptrue_all_mode (rtx);
-rtx aarch64_convert_sve_data_to_pred (rtx, machine_mode, rtx);
+rtx aarch64_convert_sve_data_to_pred (rtx, rtx);
 rtx aarch64_expand_sve_dupq (rtx, machine_mode, rtx);
 void aarch64_expand_mov_immediate (rtx, rtx);
 rtx aarch64_stack_protect_canary_mem (machine_mode, rtx, aarch64_salt_type);
index 314d53ec9adc62b430395b84de34a11fb291c0ed..ecc06877cac52fc2f2383f185e162f26237edea6 100644 (file)
@@ -1215,8 +1215,7 @@ public:
     if (mode != e.vector_mode (0))
       {
        rtx data_dupq = aarch64_expand_sve_dupq (NULL, mode, vq_reg);
-       return aarch64_convert_sve_data_to_pred (e.possible_target,
-                                                e.vector_mode (0), data_dupq);
+       return aarch64_convert_sve_data_to_pred (e.possible_target, data_dupq);
       }
 
     return aarch64_expand_sve_dupq (e.possible_target, mode, vq_reg);
index f72db5f10a879a07f94a7701505ff1a7375be84d..d30c9c75e425a8f5f4cfbf7f2453982afc395b16 100644 (file)
@@ -3962,16 +3962,24 @@ aarch64_sve_emit_masked_fp_pred (machine_mode data_mode, rtx pred)
 
 /* Emit a comparison CMP between OP0 and OP1, both of which have mode
    DATA_MODE, and return the result in a predicate of mode PRED_MODE.
-   Use TARGET as the target register if nonnull and convenient.  */
+   Use TARGET as the target register if nonnull and convenient.
+
+   PRED_MODE can be either VNx16BI or the natural predicate mode for
+   DATA_MODE.  */
 
 static rtx
 aarch64_sve_emit_int_cmp (rtx target, machine_mode pred_mode, rtx_code cmp,
                          machine_mode data_mode, rtx op1, rtx op2)
 {
-  insn_code icode = code_for_aarch64_pred_cmp (cmp, data_mode);
+  auto src_pred_mode = aarch64_sve_pred_mode (data_mode);
+  insn_code icode;
+  if (known_eq (GET_MODE_NUNITS (pred_mode), GET_MODE_NUNITS (data_mode)))
+    icode = code_for_aarch64_pred_cmp (cmp, data_mode);
+  else
+    icode = code_for_aarch64_pred_cmp_acle (cmp, data_mode);
   expand_operand ops[5];
   create_output_operand (&ops[0], target, pred_mode);
-  create_input_operand (&ops[1], CONSTM1_RTX (pred_mode), pred_mode);
+  create_input_operand (&ops[1], CONSTM1_RTX (src_pred_mode), src_pred_mode);
   create_integer_operand (&ops[2], SVE_KNOWN_PTRUE);
   create_input_operand (&ops[3], op1, data_mode);
   create_input_operand (&ops[4], op2, data_mode);
@@ -3979,15 +3987,14 @@ aarch64_sve_emit_int_cmp (rtx target, machine_mode pred_mode, rtx_code cmp,
   return ops[0].value;
 }
 
-/* Use a comparison to convert integer vector SRC into MODE, which is
-   the corresponding SVE predicate mode.  Use TARGET for the result
-   if it's nonnull and convenient.  */
+/* Use a comparison to convert integer vector SRC into VNx16BI.
+   Use TARGET for the result if it's nonnull and convenient.  */
 
 rtx
-aarch64_convert_sve_data_to_pred (rtx target, machine_mode mode, rtx src)
+aarch64_convert_sve_data_to_pred (rtx target, rtx src)
 {
   machine_mode src_mode = GET_MODE (src);
-  return aarch64_sve_emit_int_cmp (target, mode, NE, src_mode,
+  return aarch64_sve_emit_int_cmp (target, VNx16BImode, NE, src_mode,
                                   src, CONST0_RTX (src_mode));
 }
 
@@ -6299,8 +6306,7 @@ aarch64_expand_sve_const_pred (rtx target, rtx_vector_builder &builder)
   for (unsigned int i = 0; i < builder.encoded_nelts (); ++i)
     int_builder.quick_push (INTVAL (builder.elt (i))
                            ? constm1_rtx : const0_rtx);
-  return aarch64_convert_sve_data_to_pred (target, VNx16BImode,
-                                          int_builder.build ());
+  return aarch64_convert_sve_data_to_pred (target, int_builder.build ());
 }
 
 /* Set DEST to immediate IMM.  */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general/dupq_13.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/dupq_13.c
new file mode 100644 (file)
index 0000000..6d702b8
--- /dev/null
@@ -0,0 +1,45 @@
+/* { dg-options "-O2" } */
+
+#include <arm_sve.h>
+
+svbool_t
+test1 (int x0, int x1)
+{
+  return svand_z (svptrue_b8 (), svdupq_b64 (x0, x1), svptrue_b16 ());
+}
+
+svbool_t
+test2 (int x0, int x1, int x2, int x3)
+{
+  return svand_z (svptrue_b8 (), svdupq_b32 (x0, x1, x2, x3), svptrue_b16 ());
+}
+
+svbool_t
+test3 (int x0, int x1, int x2, int x3)
+{
+  return svand_z (svptrue_b32 (), svdupq_b32 (x0, x1, x2, x3), svptrue_b16 ());
+}
+
+svbool_t
+test4 (int x0, int x1, int x2, int x3)
+{
+  return svand_z (svptrue_b32 (), svdupq_b32 (x0, x1, x2, x3), svptrue_b32 ());
+}
+
+svbool_t
+test5 (int x0, int x1, int x2, int x3)
+{
+  return svand_z (svptrue_b8 (),
+                 svdupq_b16 (x0, x1, x2, x3, x2, x0, x1, x3),
+                 svptrue_b32 ());
+}
+
+svbool_t
+test6 (int x0, int x1, int x2, int x3)
+{
+  return svand_z (svptrue_b64 (),
+                 svdupq_b16 (x0, x1, x2, x3, x2, x0, x1, x3),
+                 svptrue_b16 ());
+}
+
+/* { dg-final { scan-assembler-not {\tand\tp} } } */