> On 21 Oct 2025, at 10:33, Tamar Christina <[email protected]> wrote:
>
> Hi Kyrill,
>
>> -----Original Message-----
>> From: Kyrylo Tkachov <[email protected]>
>> Sent: 21 October 2025 09:31
>> To: Tamar Christina <[email protected]>
>> Cc: [email protected]; nd <[email protected]>; Richard Earnshaw
>> <[email protected]>; [email protected]; Alex Coplan
>> <[email protected]>; [email protected]; Wilco Dijkstra
>> <[email protected]>; Alice Carlotti <[email protected]>
>> Subject: Re: [PATCH 4/4]AArch64: Add support for boolean reductions for
>> Adv. SIMD using SVE
>>
>> Hi Tamar,
>>
>>> On 21 Oct 2025, at 08:24, Tamar Christina <[email protected]>
>> wrote:
>>>
>>> When doing boolean reductions for Adv. SIMD vectors and SVE is available
>>> we can use SVE instructions instead of Adv. SIMD ones to do the reduction.
>>>
>>> For instance OR-reductions are
>>>
>>>       umaxp v3.4s, v3.4s, v3.4s
>>>       fmov x1, d3
>>>       cmp x1, 0
>>>       cset w0, ne
>>>
>>> and with SVE we generate:
>>>
>>>       ptrue p1.b, vl16
>>>       cmpne p1.b, p1/z, z3.b, #0
>>>       cset w0, any
>>>
>>> Where the ptrue is normally executed much earlier so it's not a bottleneck 
>>> for
>>> the compare.
>>>
>>> For the remaining codegen see test vect-reduc-bool-18.c.
>>>
>>> Bootstrapped Regtested on aarch64-none-linux-gnu and no issues.
>>>
>>> Ok for master?
>>>
>>> Thanks,
>>> Tamar
>>>
>>> gcc/ChangeLog:
>>>
>>> * config/aarch64/aarch64-simd.md (reduc_sbool_and_scal_<mode>,
>>> reduc_sbool_ior_scal_<mode>, reduc_sbool_xor_scal_<mode>): Use SVE if
>>> available.
>>> * config/aarch64/aarch64-sve.md (*cmp<cmp_op><mode>_ptest): Rename
>> ...
>>> (@aarch64_pred_cmp<cmp_op><mode>_ptest): ... To this.
>>> (reduc_sbool_xor_scal_<mode>): Rename ...
>>> (@reduc_sbool_xor_scal_<mode>): ... To this.
>>>
>>> gcc/testsuite/ChangeLog:
>>>
>>> * gcc.target/aarch64/sve/vect-reduc-bool-10.c: New test.
>>> * gcc.target/aarch64/sve/vect-reduc-bool-11.c: New test.
>>> * gcc.target/aarch64/sve/vect-reduc-bool-12.c: New test.
>>> * gcc.target/aarch64/sve/vect-reduc-bool-13.c: New test.
>>> * gcc.target/aarch64/sve/vect-reduc-bool-14.c: New test.
>>> * gcc.target/aarch64/sve/vect-reduc-bool-15.c: New test.
>>> * gcc.target/aarch64/sve/vect-reduc-bool-16.c: New test.
>>> * gcc.target/aarch64/sve/vect-reduc-bool-17.c: New test.
>>> * gcc.target/aarch64/sve/vect-reduc-bool-18.c: New test.
>>>
>>> ---
>>> diff --git a/gcc/config/aarch64/aarch64-simd.md
>> b/gcc/config/aarch64/aarch64-simd.md
>>> index
>> 5eddc05b5749bbd080a085db2e15dbb9bbce3be3..87c2dc84bfe45f291509
>> 80117a8e4c180a0cd02b 100644
>>> --- a/gcc/config/aarch64/aarch64-simd.md
>>> +++ b/gcc/config/aarch64/aarch64-simd.md
>>> @@ -3478,6 +3478,29 @@ (define_expand
>> "reduc_sbool_and_scal_<mode>"
>>>   UNSPEC_ANDV))]
>>>  "TARGET_SIMD"
>>> {
>>> +  if (TARGET_SVE)
>>> +    {
>>> +      machine_mode full_mode = aarch64_full_sve_mode
>> (<VEL>mode).require ();
>>> +      rtx in = force_lowpart_subreg (full_mode, operands[1], <MODE>mode);
>>> +      unsigned lanes
>>> + = exact_div (GET_MODE_BITSIZE (<MODE>mode), 8).to_constant ();
>>> +       machine_mode pred_mode = aarch64_sve_pred_mode (full_mode);
>>
>> Indentation a bit off?
>>
>>> +      rtx pred_res = gen_reg_rtx (pred_mode);
>>> +      rtx gp = aarch64_ptrue_reg (VNx16BImode, lanes);
>>> +      rtx cast_gp = lowpart_subreg (pred_mode, gp, VNx16BImode);
>>> +      rtx gp_flag = gen_int_mode (SVE_MAYBE_NOT_PTRUE, SImode);
>>> +      emit_insn (
>>> + gen_aarch64_pred_cmp_ptest (EQ, full_mode, pred_res, gp, in,
>>> +    CONST0_RTX (full_mode), cast_gp,
>>> +    gp_flag, cast_gp, gp_flag));
>>> +      rtx cc_reg = gen_rtx_REG (CC_NZCmode, CC_REGNUM);
>>> +      rtx cmp = gen_rtx_fmt_ee (EQ, SImode, cc_reg, const0_rtx);
>>> +      rtx tmp2 = gen_reg_rtx (SImode);
>>> +      emit_insn (gen_aarch64_cstoresi (tmp2, cmp, cc_reg));
>>> +      emit_move_insn (operands[0], gen_lowpart (QImode, tmp2));
>>
>> Similar optional comment about generating QImode vs SImode values.
>>
>>> +      DONE;
>>> +    }
>>> +
>>>  rtx tmp = operands[1];
>>>  /* For 64-bit vectors we need no reductions.  */
>>>  if (known_eq (128, GET_MODE_BITSIZE (<MODE>mode)))
>>> @@ -3507,6 +3530,29 @@ (define_expand
>> "reduc_sbool_ior_scal_<mode>"
>>>   UNSPEC_IORV))]
>>>  "TARGET_SIMD"
>>> {
>>> +  if (TARGET_SVE)
>>> +    {
>>> +      machine_mode full_mode = aarch64_full_sve_mode
>> (<VEL>mode).require ();
>>> +      rtx in = force_lowpart_subreg (full_mode, operands[1], <MODE>mode);
>>> +      unsigned lanes
>>> + = exact_div (GET_MODE_BITSIZE (<MODE>mode), 8).to_constant ();
>>> +       machine_mode pred_mode = aarch64_sve_pred_mode (full_mode);
>>> +      rtx pred_res = gen_reg_rtx (pred_mode);
>>> +      rtx gp = aarch64_ptrue_reg (VNx16BImode, lanes);
>>> +      rtx cast_gp = lowpart_subreg (pred_mode, gp, VNx16BImode);
>>> +      rtx gp_flag = gen_int_mode (SVE_MAYBE_NOT_PTRUE, SImode);
>>> +      emit_insn (
>>> + gen_aarch64_pred_cmp_ptest (NE, full_mode, pred_res, gp, in,
>>> +    CONST0_RTX (full_mode), cast_gp,
>>> +    gp_flag, cast_gp, gp_flag));
>>> +      rtx cc_reg = gen_rtx_REG (CC_NZCmode, CC_REGNUM);
>>> +      rtx cmp = gen_rtx_fmt_ee (NE, SImode, cc_reg, const0_rtx);
>>> +      rtx tmp2 = gen_reg_rtx (SImode);
>>> +      emit_insn (gen_aarch64_cstoresi (tmp2, cmp, cc_reg));
>>> +      emit_move_insn (operands[0], gen_lowpart (QImode, tmp2));
>>> +      DONE;
>>> +    }
>>> +
>>>  rtx tmp = operands[1];
>>>  /* For 64-bit vectors we need no reductions.  */
>>>  if (known_eq (128, GET_MODE_BITSIZE (<MODE>mode)))
>>> @@ -3537,6 +3583,24 @@ (define_expand
>> "reduc_sbool_xor_scal_<mode>"
>>>   UNSPEC_XORV))]
>>>  "TARGET_SIMD"
>>> {
>>> +  if (TARGET_SVE)
>>> +    {
>>> +      machine_mode full_mode = aarch64_full_sve_mode
>> (<VEL>mode).require ();
>>> +      rtx in = force_lowpart_subreg (full_mode, operands[1], <MODE>mode);
>>> +      unsigned lanes
>>> + = exact_div (GET_MODE_BITSIZE (<MODE>mode), 8).to_constant ();
>>> +       machine_mode pred_mode = aarch64_sve_pred_mode (full_mode);
>>> +      rtx pred_res = gen_reg_rtx (pred_mode);
>>> +      rtx gp = aarch64_ptrue_reg (VNx16BImode, lanes);
>>> +      rtx cast_gp = lowpart_subreg (pred_mode, gp, VNx16BImode);
>>> +      rtx gp_flag = gen_int_mode (SVE_MAYBE_NOT_PTRUE, SImode);
>>> +      emit_insn (
>>> + gen_aarch64_pred_cmp (NE, full_mode, pred_res, cast_gp, gp_flag, in,
>>> +      CONST0_RTX (full_mode)));
>>> +      emit_insn (gen_reduc_sbool_xor_scal (pred_mode, operands[0],
>> pred_res));
>>> +      DONE;
>>> +    }
>>> +
>>>  rtx tmp = gen_reg_rtx (<MODE>mode);
>>>  rtx one_reg = force_reg (<MODE>mode, CONST1_RTX (<MODE>mode));
>>>  emit_move_insn (tmp, gen_rtx_AND (<MODE>mode, operands[1],
>> one_reg));
>>> diff --git a/gcc/config/aarch64/aarch64-sve.md
>> b/gcc/config/aarch64/aarch64-sve.md
>>> index
>> 808a0e8bc00d1c8e79d987c83d542211fc25f8e0..3e6672948b14aaed8138
>> b1852d997c29b8a5272f 100644
>>> --- a/gcc/config/aarch64/aarch64-sve.md
>>> +++ b/gcc/config/aarch64/aarch64-sve.md
>>> @@ -8745,7 +8745,7 @@ (define_insn_and_rewrite
>> "*cmp<cmp_op><mode>_acle_cc"
>>>
>>> ;; Predicated integer comparisons in which only the flags result is
>>> ;; interesting.
>>> -(define_insn_and_rewrite "*cmp<cmp_op><mode>_ptest"
>>> +(define_insn_and_rewrite "@aarch64_pred_cmp<cmp_op><mode>_ptest"
>>>  [(set (reg:CC_NZC CC_REGNUM)
>>> (unspec:CC_NZC
>>> [(match_operand:VNx16BI 1 "register_operand")
>>> @@ -9963,7 +9963,7 @@ (define_expand "reduc_sbool_ior_scal_<mode>"
>>> ;;   cntp    x0, p0, p0.b
>>> ;;   and     w0, w0, 1
>>> ;;
>>> -(define_expand "reduc_sbool_xor_scal_<mode>"
>>> +(define_expand "@reduc_sbool_xor_scal_<mode>"
>>>  [(set (match_dup 2)
>>> (zero_extend:DI
>>> (unspec:SI [(match_dup 1)
>>> diff --git a/gcc/testsuite/gcc.target/aarch64/sve/vect-reduc-bool-10.c
>> b/gcc/testsuite/gcc.target/aarch64/sve/vect-reduc-bool-10.c
>>> new file mode 100644
>>> index
>> 0000000000000000000000000000000000000000..c0ff50e914b79b36821
>> 725ab71474a919f6d22ce
>>> --- /dev/null
>>> +++ b/gcc/testsuite/gcc.target/aarch64/sve/vect-reduc-bool-10.c
>>> @@ -0,0 +1,52 @@
>>> +/* { dg-do run } */
>>> +/* { dg-require-effective-target aarch64_sve_hw } */
>>> +/* { dg-options "-O3 -march=armv8-a+sve -mautovec-preference=asimd-
>> only -fdump-tree-vect-details" }*/
>>> +
>>> +char p[128];
>>> +
>>> +bool __attribute__((noipa))
>>> +fand (int n)
>>> +{
>>> +  bool r = true;
>>> +  for (int i = 0; i < n; ++i)
>>> +    r &= (p[i] != 0);
>>> +  return r;
>>> +}
>>> +
>>> +bool __attribute__((noipa))
>>> +fior (int n)
>>> +{
>>> +  bool r = false;
>>> +  for (int i = 0; i < n; ++i)
>>> +    r |= (p[i] != 0);
>>> +  return r;
>>> +}
>>> +
>>> +int main()
>>> +{
>>> +  __builtin_memset (p, 1, sizeof(p));
>>> +
>>> +  for (int n = 0; n < 77; ++n)
>>> +    if (!fand (n))
>>> +      __builtin_abort ();
>>> +
>>> +  p[0] = 0;
>>> +  for (int n = 1; n < 77; ++n)
>>> +    if (fand (n))
>>> +      __builtin_abort ();
>>> +
>>> +  __builtin_memset (p, 0, sizeof(p));
>>> +
>>> +  for (int n = 0; n < 77; ++n)
>>> +    if (fior (n))
>>> +      __builtin_abort ();
>>> +
>>> +  p[0] = 1;
>>> +  for (int n = 1; n < 77; ++n)
>>> +    if (!fior (n))
>>> +      __builtin_abort ();
>>> +
>>> +  return 0;
>>> +}
>>> +
>>> +/* { dg-final { scan-tree-dump-times "optimized: loop vectorized" 2 "vect" 
>>> }
>> } */
>>
>> I think this test should have some assembly scan for the SVE sequences.
>> Otherwise this can already be vectorised for Advanced SIMD with patch 3/4.
>> Ok otherwise.
>
> The assembly scans are in test 18. 
> gcc/testsuite/gcc.target/aarch64/sve/vect-reduc-bool-18.c
>
> Here I'm just checking correctness under vectorization.

Ah ok, I didn’t pay enough attention to the tests.
Testing looks ok to me then.
Kyrill

>
> Thanks,
> Tamar
>
>> Thanks,
>> Kyrill
>>
>>
>>> diff --git a/gcc/testsuite/gcc.target/aarch64/sve/vect-reduc-bool-11.c
>> b/gcc/testsuite/gcc.target/aarch64/sve/vect-reduc-bool-11.c
>>> new file mode 100644
>>> index
>> 0000000000000000000000000000000000000000..3597fc4a456c1186e25
>> 7a188dd79888cd6466e56
>>> --- /dev/null
>>> +++ b/gcc/testsuite/gcc.target/aarch64/sve/vect-reduc-bool-11.c
>>> @@ -0,0 +1,52 @@
>>> +/* { dg-do run } */
>>> +/* { dg-require-effective-target aarch64_sve_hw } */
>>> +/* { dg-options "-O3 -march=armv8-a+sve -mautovec-preference=asimd-
>> only -fdump-tree-vect-details" }*/
>>> +
>>> +short p[128];
>>> +
>>> +bool __attribute__((noipa))
>>> +fand (int n)
>>> +{
>>> +  bool r = true;
>>> +  for (int i = 0; i < n; ++i)
>>> +    r &= (p[i] != 0);
>>> +  return r;
>>> +}
>>> +
>>> +bool __attribute__((noipa))
>>> +fior (int n)
>>> +{
>>> +  bool r = false;
>>> +  for (int i = 0; i < n; ++i)
>>> +    r |= (p[i] != 0);
>>> +  return r;
>>> +}
>>> +
>>> +int main()
>>> +{
>>> +  __builtin_memset (p, 1, sizeof(p));
>>> +
>>> +  for (int n = 0; n < 77; ++n)
>>> +    if (!fand (n))
>>> +      __builtin_abort ();
>>> +
>>> +  p[0] = 0;
>>> +  for (int n = 1; n < 77; ++n)
>>> +    if (fand (n))
>>> +      __builtin_abort ();
>>> +
>>> +  __builtin_memset (p, 0, sizeof(p));
>>> +
>>> +  for (int n = 0; n < 77; ++n)
>>> +    if (fior (n))
>>> +      __builtin_abort ();
>>> +
>>> +  p[0] = 1;
>>> +  for (int n = 1; n < 77; ++n)
>>> +    if (!fior (n))
>>> +      __builtin_abort ();
>>> +
>>> +  return 0;
>>> +}
>>> +
>>> +/* { dg-final { scan-tree-dump-times "optimized: loop vectorized" 2 "vect" 
>>> }
>> } */
>>> diff --git a/gcc/testsuite/gcc.target/aarch64/sve/vect-reduc-bool-12.c
>> b/gcc/testsuite/gcc.target/aarch64/sve/vect-reduc-bool-12.c
>>> new file mode 100644
>>> index
>> 0000000000000000000000000000000000000000..b1173627403d654bc0
>> e64bc141546f8f3889a8f6
>>> --- /dev/null
>>> +++ b/gcc/testsuite/gcc.target/aarch64/sve/vect-reduc-bool-12.c
>>> @@ -0,0 +1,52 @@
>>> +/* { dg-do run } */
>>> +/* { dg-require-effective-target aarch64_sve_hw } */
>>> +/* { dg-options "-O3 -march=armv8-a+sve -mautovec-preference=asimd-
>> only -fdump-tree-vect-details" }*/
>>> +
>>> +int p[128];
>>> +
>>> +bool __attribute__((noipa))
>>> +fand (int n)
>>> +{
>>> +  bool r = true;
>>> +  for (int i = 0; i < n; ++i)
>>> +    r &= (p[i] != 0);
>>> +  return r;
>>> +}
>>> +
>>> +bool __attribute__((noipa))
>>> +fior (int n)
>>> +{
>>> +  bool r = false;
>>> +  for (int i = 0; i < n; ++i)
>>> +    r |= (p[i] != 0);
>>> +  return r;
>>> +}
>>> +
>>> +int main()
>>> +{
>>> +  __builtin_memset (p, 1, sizeof(p));
>>> +
>>> +  for (int n = 0; n < 77; ++n)
>>> +    if (!fand (n))
>>> +      __builtin_abort ();
>>> +
>>> +  p[0] = 0;
>>> +  for (int n = 1; n < 77; ++n)
>>> +    if (fand (n))
>>> +      __builtin_abort ();
>>> +
>>> +  __builtin_memset (p, 0, sizeof(p));
>>> +
>>> +  for (int n = 0; n < 77; ++n)
>>> +    if (fior (n))
>>> +      __builtin_abort ();
>>> +
>>> +  p[0] = 1;
>>> +  for (int n = 1; n < 77; ++n)
>>> +    if (!fior (n))
>>> +      __builtin_abort ();
>>> +
>>> +  return 0;
>>> +}
>>> +
>>> +/* { dg-final { scan-tree-dump-times "optimized: loop vectorized" 2 "vect" 
>>> }
>> } */
>>> diff --git a/gcc/testsuite/gcc.target/aarch64/sve/vect-reduc-bool-13.c
>> b/gcc/testsuite/gcc.target/aarch64/sve/vect-reduc-bool-13.c
>>> new file mode 100644
>>> index
>> 0000000000000000000000000000000000000000..a2b8a712043459096f
>> df3357beb7e30467c959a2
>>> --- /dev/null
>>> +++ b/gcc/testsuite/gcc.target/aarch64/sve/vect-reduc-bool-13.c
>>> @@ -0,0 +1,52 @@
>>> +/* { dg-do run } */
>>> +/* { dg-require-effective-target aarch64_sve_hw } */
>>> +/* { dg-options "-O3 -march=armv8-a+sve -mautovec-preference=asimd-
>> only -fdump-tree-vect-details" }*/
>>> +
>>> +long long p[128];
>>> +
>>> +bool __attribute__((noipa))
>>> +fand (int n)
>>> +{
>>> +  bool r = true;
>>> +  for (int i = 0; i < n; ++i)
>>> +    r &= (p[i] != 0);
>>> +  return r;
>>> +}
>>> +
>>> +bool __attribute__((noipa))
>>> +fior (int n)
>>> +{
>>> +  bool r = false;
>>> +  for (int i = 0; i < n; ++i)
>>> +    r |= (p[i] != 0);
>>> +  return r;
>>> +}
>>> +
>>> +int main()
>>> +{
>>> +  __builtin_memset (p, 1, sizeof(p));
>>> +
>>> +  for (int n = 0; n < 77; ++n)
>>> +    if (!fand (n))
>>> +      __builtin_abort ();
>>> +
>>> +  p[0] = 0;
>>> +  for (int n = 1; n < 77; ++n)
>>> +    if (fand (n))
>>> +      __builtin_abort ();
>>> +
>>> +  __builtin_memset (p, 0, sizeof(p));
>>> +
>>> +  for (int n = 0; n < 77; ++n)
>>> +    if (fior (n))
>>> +      __builtin_abort ();
>>> +
>>> +  p[0] = 1;
>>> +  for (int n = 1; n < 77; ++n)
>>> +    if (!fior (n))
>>> +      __builtin_abort ();
>>> +
>>> +  return 0;
>>> +}
>>> +
>>> +/* { dg-final { scan-tree-dump-times "optimized: loop vectorized" 2 "vect" 
>>> }
>> } */
>>> diff --git a/gcc/testsuite/gcc.target/aarch64/sve/vect-reduc-bool-14.c
>> b/gcc/testsuite/gcc.target/aarch64/sve/vect-reduc-bool-14.c
>>> new file mode 100644
>>> index
>> 0000000000000000000000000000000000000000..c24e13294fe26daed85
>> fc390ee1e647ea2d80506
>>> --- /dev/null
>>> +++ b/gcc/testsuite/gcc.target/aarch64/sve/vect-reduc-bool-14.c
>>> @@ -0,0 +1,50 @@
>>> +/* { dg-do run } */
>>> +/* { dg-require-effective-target aarch64_sve_hw } */
>>> +/* { dg-options "-O3 -march=armv8-a+sve -mautovec-preference=asimd-
>> only -fdump-tree-vect-details" }*/
>>> +
>>> +char p[128];
>>> +
>>> +bool __attribute__((noipa))
>>> +fxort (int n)
>>> +{
>>> +  bool r = true;
>>> +  for (int i = 0; i < n; ++i)
>>> +    r ^= (p[i] != 0);
>>> +  return r;
>>> +}
>>> +
>>> +bool __attribute__((noipa))
>>> +fxorf (int n)
>>> +{
>>> +  bool r = false;
>>> +  for (int i = 0; i < n; ++i)
>>> +    r ^= (p[i] != 0);
>>> +  return r;
>>> +}
>>> +
>>> +int main()
>>> +{
>>> +  __builtin_memset (p, 1, sizeof(p));
>>> +
>>> +  for (int n = 0; n < 77; ++n)
>>> +    if (fxort (n) != !(n & 1))
>>> +      __builtin_abort ();
>>> +
>>> +  for (int n = 0; n < 77; ++n)
>>> +    if (fxorf (n) != (n & 1))
>>> +      __builtin_abort ();
>>> +
>>> +  __builtin_memset (p, 0, sizeof(p));
>>> +
>>> +  for (int n = 0; n < 77; ++n)
>>> +    if (!fxort (n))
>>> +      __builtin_abort ();
>>> +
>>> +  for (int n = 0; n < 77; ++n)
>>> +    if (fxorf (n))
>>> +      __builtin_abort ();
>>> +
>>> +  return 0;
>>> +}
>>> +
>>> +/* { dg-final { scan-tree-dump-times "optimized: loop vectorized" 2 "vect" 
>>> }
>> } */
>>> diff --git a/gcc/testsuite/gcc.target/aarch64/sve/vect-reduc-bool-15.c
>> b/gcc/testsuite/gcc.target/aarch64/sve/vect-reduc-bool-15.c
>>> new file mode 100644
>>> index
>> 0000000000000000000000000000000000000000..0233b8ae2338fe0c37
>> 27f5ae561699e520602d61
>>> --- /dev/null
>>> +++ b/gcc/testsuite/gcc.target/aarch64/sve/vect-reduc-bool-15.c
>>> @@ -0,0 +1,50 @@
>>> +/* { dg-do run } */
>>> +/* { dg-require-effective-target aarch64_sve_hw } */
>>> +/* { dg-options "-O3 -march=armv8-a+sve -mautovec-preference=asimd-
>> only -fdump-tree-vect-details" }*/
>>> +
>>> +short p[128];
>>> +
>>> +bool __attribute__((noipa))
>>> +fxort (int n)
>>> +{
>>> +  bool r = true;
>>> +  for (int i = 0; i < n; ++i)
>>> +    r ^= (p[i] != 0);
>>> +  return r;
>>> +}
>>> +
>>> +bool __attribute__((noipa))
>>> +fxorf (int n)
>>> +{
>>> +  bool r = false;
>>> +  for (int i = 0; i < n; ++i)
>>> +    r ^= (p[i] != 0);
>>> +  return r;
>>> +}
>>> +
>>> +int main()
>>> +{
>>> +  __builtin_memset (p, 1, sizeof(p));
>>> +
>>> +  for (int n = 0; n < 77; ++n)
>>> +    if (fxort (n) != !(n & 1))
>>> +      __builtin_abort ();
>>> +
>>> +  for (int n = 0; n < 77; ++n)
>>> +    if (fxorf (n) != (n & 1))
>>> +      __builtin_abort ();
>>> +
>>> +  __builtin_memset (p, 0, sizeof(p));
>>> +
>>> +  for (int n = 0; n < 77; ++n)
>>> +    if (!fxort (n))
>>> +      __builtin_abort ();
>>> +
>>> +  for (int n = 0; n < 77; ++n)
>>> +    if (fxorf (n))
>>> +      __builtin_abort ();
>>> +
>>> +  return 0;
>>> +}
>>> +
>>> +/* { dg-final { scan-tree-dump-times "optimized: loop vectorized" 2 "vect" 
>>> }
>> } */
>>> diff --git a/gcc/testsuite/gcc.target/aarch64/sve/vect-reduc-bool-16.c
>> b/gcc/testsuite/gcc.target/aarch64/sve/vect-reduc-bool-16.c
>>> new file mode 100644
>>> index
>> 0000000000000000000000000000000000000000..e731b556424f022a21
>> 8a484f0c22d2d8a7f79c62
>>> --- /dev/null
>>> +++ b/gcc/testsuite/gcc.target/aarch64/sve/vect-reduc-bool-16.c
>>> @@ -0,0 +1,50 @@
>>> +/* { dg-do run } */
>>> +/* { dg-require-effective-target aarch64_sve_hw } */
>>> +/* { dg-options "-O3 -march=armv8-a+sve -mautovec-preference=asimd-
>> only -fdump-tree-vect-details" }*/
>>> +
>>> +int p[128];
>>> +
>>> +bool __attribute__((noipa))
>>> +fxort (int n)
>>> +{
>>> +  bool r = true;
>>> +  for (int i = 0; i < n; ++i)
>>> +    r ^= (p[i] != 0);
>>> +  return r;
>>> +}
>>> +
>>> +bool __attribute__((noipa))
>>> +fxorf (int n)
>>> +{
>>> +  bool r = false;
>>> +  for (int i = 0; i < n; ++i)
>>> +    r ^= (p[i] != 0);
>>> +  return r;
>>> +}
>>> +
>>> +int main()
>>> +{
>>> +  __builtin_memset (p, 1, sizeof(p));
>>> +
>>> +  for (int n = 0; n < 77; ++n)
>>> +    if (fxort (n) != !(n & 1))
>>> +      __builtin_abort ();
>>> +
>>> +  for (int n = 0; n < 77; ++n)
>>> +    if (fxorf (n) != (n & 1))
>>> +      __builtin_abort ();
>>> +
>>> +  __builtin_memset (p, 0, sizeof(p));
>>> +
>>> +  for (int n = 0; n < 77; ++n)
>>> +    if (!fxort (n))
>>> +      __builtin_abort ();
>>> +
>>> +  for (int n = 0; n < 77; ++n)
>>> +    if (fxorf (n))
>>> +      __builtin_abort ();
>>> +
>>> +  return 0;
>>> +}
>>> +
>>> +/* { dg-final { scan-tree-dump-times "optimized: loop vectorized" 2 "vect" 
>>> }
>> } */
>>> diff --git a/gcc/testsuite/gcc.target/aarch64/sve/vect-reduc-bool-17.c
>> b/gcc/testsuite/gcc.target/aarch64/sve/vect-reduc-bool-17.c
>>> new file mode 100644
>>> index
>> 0000000000000000000000000000000000000000..efbec019bf7ad3e71b7
>> ade7940e0d796142694d6
>>> --- /dev/null
>>> +++ b/gcc/testsuite/gcc.target/aarch64/sve/vect-reduc-bool-17.c
>>> @@ -0,0 +1,50 @@
>>> +/* { dg-do run } */
>>> +/* { dg-require-effective-target aarch64_sve_hw } */
>>> +/* { dg-options "-O3 -march=armv8-a+sve -mautovec-preference=asimd-
>> only -fdump-tree-vect-details" }*/
>>> +
>>> +long long p[128];
>>> +
>>> +bool __attribute__((noipa))
>>> +fxort (int n)
>>> +{
>>> +  bool r = true;
>>> +  for (int i = 0; i < n; ++i)
>>> +    r ^= (p[i] != 0);
>>> +  return r;
>>> +}
>>> +
>>> +bool __attribute__((noipa))
>>> +fxorf (int n)
>>> +{
>>> +  bool r = false;
>>> +  for (int i = 0; i < n; ++i)
>>> +    r ^= (p[i] != 0);
>>> +  return r;
>>> +}
>>> +
>>> +int main()
>>> +{
>>> +  __builtin_memset (p, 1, sizeof(p));
>>> +
>>> +  for (int n = 0; n < 77; ++n)
>>> +    if (fxort (n) != !(n & 1))
>>> +      __builtin_abort ();
>>> +
>>> +  for (int n = 0; n < 77; ++n)
>>> +    if (fxorf (n) != (n & 1))
>>> +      __builtin_abort ();
>>> +
>>> +  __builtin_memset (p, 0, sizeof(p));
>>> +
>>> +  for (int n = 0; n < 77; ++n)
>>> +    if (!fxort (n))
>>> +      __builtin_abort ();
>>> +
>>> +  for (int n = 0; n < 77; ++n)
>>> +    if (fxorf (n))
>>> +      __builtin_abort ();
>>> +
>>> +  return 0;
>>> +}
>>> +
>>> +/* { dg-final { scan-tree-dump-times "optimized: loop vectorized" 2 "vect" 
>>> {
>> target { vect_int && vect_condition } } } } */
>>> diff --git a/gcc/testsuite/gcc.target/aarch64/sve/vect-reduc-bool-18.c
>> b/gcc/testsuite/gcc.target/aarch64/sve/vect-reduc-bool-18.c
>>> new file mode 100644
>>> index
>> 0000000000000000000000000000000000000000..a47c306e13c688e601
>> 4524bfb939dc46ed65b8a4
>>> --- /dev/null
>>> +++ b/gcc/testsuite/gcc.target/aarch64/sve/vect-reduc-bool-18.c
>>> @@ -0,0 +1,60 @@
>>> +/* { dg-do compile } */
>>> +/* { dg-options "-O3 -march=armv8-a+sve -mautovec-preference=asimd-
>> only -fno-schedule-insns -fno-reorder-blocks -fno-schedule-insns2 -fdump-
>> tree-vect-details" }*/
>>> +/* { dg-final { check-function-bodies "**" "" } } */
>>> +
>>> +char p[128];
>>> +
>>> +/*
>>> +** fand:
>>> +** ...
>>> +** ptrue p[0-9]+.b, vl16
>>> +** cmpeq p[0-9]+.b, p[0-9]+/z, z[0-9]+.b, #0
>>> +** cset w[0-9]+, none
>>> +** ...
>>> +*/
>>> +bool __attribute__((noipa))
>>> +fand (int n)
>>> +{
>>> +  bool r = true;
>>> +  for (int i = 0; i < n; ++i)
>>> +    r &= (p[i] != 0);
>>> +  return r;
>>> +}
>>> +
>>> +/*
>>> +** fior:
>>> +** ...
>>> +** ptrue p[0-9]+.b, vl16
>>> +** cmpne p[0-9]+.b, p[0-9]+/z, z[0-9]+.b, #0
>>> +** cset w[0-9]+, any
>>> +** ...
>>> +*/
>>> +bool __attribute__((noipa))
>>> +fior (int n)
>>> +{
>>> +  bool r = false;
>>> +  for (int i = 0; i < n; ++i)
>>> +    r |= (p[i] != 0);
>>> +  return r;
>>> +}
>>> +
>>> +/*
>>> +** fxor:
>>> +** ...
>>> +** ptrue p[0-9]+.b, vl16
>>> +** cmpne p[0-9]+.b, p[0-9]+/z, z[0-9]+.b, #0
>>> +** cntp x[0-9]+, p[0-9]+, p[0-9]+.b
>>> +** and w[0-9]+, w[0-9]+, 1
>>> +** ...
>>> +*/
>>> +bool __attribute__((noipa))
>>> +fxor (int n)
>>> +{
>>> +  bool r = false;
>>> +  for (int i = 0; i < n; ++i)
>>> +    r ^= (p[i] != 0);
>>> +  return r;
>>> +}
>>> +
>>> +/* { dg-final { scan-tree-dump-times "optimized: loop vectorized" 3 "vect" 
>>> }
>> } */
>>> +
>>>
>>>
>>> --
>>> <rb19936.patch>

Reply via email to