Hi Tamar,

> On 18 Nov 2025, at 00:13, Tamar Christina <[email protected]> wrote:
> 
> The following example:
> 
> #define N 640
> int a[N] = {};
> int b[N] = {};
> int c[N] = {};
> 
> void f1 (int d)
> {
>  for (int i = 0; i < N; i++)
>    {
>      b[i] += a[i];
>      if (a[i] != d)
>        break;
>    }
> }
> 
> today generates with
> -Ofast -march=armv8-a+sve --param aarch64-autovec-preference=asimd-only
> 
> .L6:
>        ldr     q30, [x3, x1]
>        cmeq    v31.4s, v30.4s, v27.4s
>        not     v31.16b, v31.16b
>        umaxp   v31.4s, v31.4s, v31.4s
>        fmov    x4, d31
>        cbz     x4, .L2
> 
> Where an we use an Adv. SIMD compare and a reduction sequence to implement
> early break.  This patch implements the new optabs vec_cbranch_any and
> vec_cbranch_all in order to replace the Adv. SIMD compare and reduction with
> an SVE flag-setting compare.
> 
> With this patch the above generates:
> 
>        ptrue   p7.b, vl16
> .L6:
>        ldr     q30, [x3, x1]
>        cmpne   p15.s, p7/z, z30.s, z27.s
>        b.none  .L2
> 
> This optab could also be used for optimizing the Adv. SIMD Sequence when SVE
> is not available.  I have a separate patch for that and will send depending on
> if this approach is accepted or not.
> 
> Note that for floating-point we still need the ptest as floating point SVE
> compares don't set flags.  In addition because SVE doesn't have a CMTST
> equivalent instruction we have to do an explicit AND before the compares.
> 
> These two cases don't have a speed advantage, but do have a codesize one
> so I've left them enabled.
> 
> When compiling with -ffast-math we can however use an SVE
> integer comparison when comparing FP values for equality.  This then saves
> the PTEST there and equality is the most common form.
> 
> This patch also eliminated PTEST on normal SVE compare and branch through
> the introduction of new optabs cond_vec_cbranch_any and cond_vec_cbranch_all.
> 
> In the example
> 
> void f1 ()
> {
>  for (int i = 0; i < N; i++)
>    {
>      b[i] += a[i];
>      if (a[i] > 0)
> break;
>    }
> }
> 
> when compiled for SVE we generate:
> 
>        ld1w    z28.s, p7/z, [x4, x0, lsl 2]
>        cmpgt   p14.s, p7/z, z28.s, #0
>        ptest   p15, p14.b
>        b.none  .L3
> 
> Where the ptest isn't needed since the branch only cares about the Z and NZ
> flags.
> 
> GCC Today supports eliding this through the pattern *cmp<cmp_op><mode>_ptest
> however this pattern only supports the removal when the outermost context is a
> CMP where the predicate is inside the condition itself.
> 
> This typically only happens for an unpredicated CMP as a ptrue will be 
> generated
> during expand.
> 
> In the case about at the GIMPLE level we have
> 
>  mask_patt_14.15_57 = vect__2.11_52 > { 0, ... };
>  vec_mask_and_58 = loop_mask_48 & mask_patt_14.15_57;
>  if (vec_mask_and_58 != { 0, ... })
>    goto <bb 5>; [5.50%]
>  else
>    goto <bb 6>; [94.50%]
> 
> where the loop mask is applied to the compare as an AND.
> 
> The loop mask is moved into the compare by the pattern *cmp<cmp_op><mode>_and
> which moves the mask inside if the current mask is a ptrue since
> p && true -> p.
> 
> However this happens after combine, and so we can't both move the predicate
> inside AND eliminate the ptests.
> 
> To fix this the middle-end will now rewrite the mask into the compare optab
> and indicate that only the CC flags are required.  This allows us to simply
> not generate the ptest at all, rather than trying to eliminate it later on.
> 
> After this patch we generate
> 
>        ld1w    z28.s, p7/z, [x4, x0, lsl 2]
>        cmpgt   p14.s, p7/z, z28.s, #0
>        b.none  .L3
> 
> 
> Bootstrapped Regtested on aarch64-none-linux-gnu and no issues.
> 
> Ok for master?

Ok with some minor comments inline...

> 
> Thanks,
> Tamar
> 
> gcc/ChangeLog:
> 
> PR target/118974
> * config/aarch64/aarch64-simd.md (xor<mode>3<vczle><vczbe>): Rename ...
> (@xor<mode>3<vczle><vczbe>): .. to this.
> (cbranch<mode>4): Update comments.
> (<optab><mode>): New.
> * config/aarch64/aarch64-sve.md (cbranch<mode>4): Update comment.
> (<optab><mode>): New.
> (aarch64_ptest<mode>): Rename to ...
> (@aarch64_ptest<mode>): .. this.
> * config/aarch64/iterators.md (UNSPEC_CMP_ALL, UNSPEC_CMP_ANY,
> UNSPEC_COND_CMP_ALL, UNSPEC_COND_CMP_ANY): New.
> (optabs): Add them.
> (CBRANCH_CMP, COND_CBRANCH_CMP, cbranch_op): New.
> * config/aarch64/predicates.md (aarch64_cbranch_compare_operation): New.
> 
> gcc/testsuite/ChangeLog:
> 
> PR target/118974
> * gcc.target/aarch64/sve/pr119351.c: Update codegen.
> * gcc.target/aarch64/sve/vect-early-break-cbranch.c: Likewise.
> * gcc.target/aarch64/vect-early-break-cbranch.c: Likewise.
> * gcc.target/aarch64/sve/vect-early-break-cbranch_2.c: New test.
> * gcc.target/aarch64/sve/vect-early-break-cbranch_3.c: New test.
> * gcc.target/aarch64/sve/vect-early-break-cbranch_4.c: New test.
> * gcc.target/aarch64/sve/vect-early-break-cbranch_5.c: New test.
> * gcc.target/aarch64/sve/vect-early-break-cbranch_7.c: New test.
> * gcc.target/aarch64/sve/vect-early-break-cbranch_8.c: New test.
> * gcc.target/aarch64/vect-early-break-cbranch_2.c: New test.
> * gcc.target/aarch64/vect-early-break-cbranch_3.c: New test.
> 
> ---
> diff --git a/gcc/config/aarch64/aarch64-simd.md 
> b/gcc/config/aarch64/aarch64-simd.md
> index 
> e7c459dceb3a9d5aa05501278d85f9cc7ac0eeab..3aecef7470b4309f42831228f8cdf0f684cd22fe
>  100644
> --- a/gcc/config/aarch64/aarch64-simd.md
> +++ b/gcc/config/aarch64/aarch64-simd.md
> @@ -1155,7 +1155,7 @@ (define_insn "ior<mode>3<vczle><vczbe>"
> )
> 
> ;; For EOR (vector, register) and SVE EOR (vector, immediate)
> -(define_insn "xor<mode>3<vczle><vczbe>"
> +(define_insn "@xor<mode>3<vczle><vczbe>"
>   [(set (match_operand:VDQ_I 0 "register_operand")
>         (xor:VDQ_I (match_operand:VDQ_I 1 "register_operand")
>                    (match_operand:VDQ_I 2 "aarch64_reg_or_xor_imm")))]
> @@ -4156,6 +4156,8 @@ (define_expand "vcond_mask_<mode><v_int_equiv>"
> 
> ;; Patterns comparing two vectors and conditionally jump
> 
> +;; Define cbranch on masks.  This optab is only called for 
> BOOLEAN_VECTOR_TYPE_P
> +;; which allows optimizing compares with zero.
> (define_expand "cbranch<mode>4"
>   [(set (pc)
>         (if_then_else
> @@ -4196,6 +4198,89 @@ (define_expand "cbranch<mode>4"
>   DONE;
> })
> 
> +;; Define vec_cbranch_any and vec_cbranch_all
> +;; Vector comparison and branch for Adv. SIMD Integer types using SVE
> +;; instructions.
> +(define_expand "<optab><mode>"
> +  [(set (pc)
> + (unspec:VALL
> +  [(if_then_else
> +    (match_operator 0 "aarch64_cbranch_compare_operation"
> +      [(match_operand:VALL 1 "register_operand")
> +       (match_operand:VALL 2 "aarch64_simd_reg_or_zero")])
> +    (label_ref (match_operand 3 ""))
> +    (pc))]
> + CBRANCH_CMP))]
> +  "TARGET_SIMD"
> +{
> +  auto code = GET_CODE (operands[0]);
> +  if (TARGET_SVE)
> +    {
> +      machine_mode full_mode = aarch64_full_sve_mode (<VEL>mode).require ();
> +
> +      /* Since SVE Vector FP compares don't set flags, when comparing against
> + equality we can use the integer variant which sets flags since
> + IEEE equality is just bitwise equality.  */
> +      if (FLOAT_MODE_P (full_mode)
> +  && aarch64_equality_operator (operands[0], <MODE>mode))
> + full_mode = related_int_vector_mode (full_mode).require ();
> +      rtx in1 = force_lowpart_subreg (full_mode, operands[1], <MODE>mode);
> +      rtx in2;
> +      if (CONST0_RTX (<MODE>mode) == operands[2])
> + in2 = CONST0_RTX (full_mode);
> +      else
> + in2 = force_lowpart_subreg (full_mode, operands[2], <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 ptrue = aarch64_ptrue_reg (VNx16BImode, lanes);
> +      rtx hint = gen_int_mode (SVE_MAYBE_NOT_PTRUE, SImode);
> +
> +      rtx tmp = gen_reg_rtx (pred_mode);
> +      rtx cast_ptrue = gen_lowpart (pred_mode, ptrue);
> +
> +      if (FLOAT_MODE_P (full_mode))
> + {
> +  aarch64_expand_sve_vec_cmp<sve_cmp_suff> (tmp, code, in1, in2);
> +  emit_insn (gen_and3 (pred_mode, tmp, tmp, cast_ptrue));
> +  emit_insn (gen_aarch64_ptest (pred_mode, ptrue, cast_ptrue, hint,
> + tmp));
> + }
> +      else
> + emit_insn (gen_aarch64_pred_cmp_ptest (code, full_mode, tmp, ptrue, in1,
> +       in2, cast_ptrue, hint,
> +       cast_ptrue, hint));
> +
> +      rtx cc_reg = gen_rtx_REG (CC_NZCmode, CC_REGNUM);
> +      rtx cmp_reg = gen_rtx_<cbranch_op> (VOIDmode, cc_reg, const0_rtx);
> +      emit_jump_insn (gen_aarch64_bcond (cmp_reg, cc_reg, operands[3]));
> +      DONE;
> +    }
> +
> +  rtx tmp = gen_reg_rtx (<V_INT_EQUIV>mode);
> +  emit_insn (gen_vec_cmp<mode><v_int_equiv> (tmp, operands[0], operands[1],
> +     operands[2]));
> +
> +  /* For 128-bit vectors we need a reduction to 64-bit first.  */
> +  if (known_eq (128, GET_MODE_BITSIZE (<MODE>mode)))
> +    {
> +      /* Always reduce using a V4SI.  */
> +      rtx reduc = gen_lowpart (V4SImode, tmp);
> +      rtx res = gen_reg_rtx (V4SImode);
> +      emit_insn (gen_aarch64_umaxpv4si (res, reduc, reduc));
> +      emit_move_insn (tmp, gen_lowpart (<V_INT_EQUIV>mode, res));
> +    }
> +
> +  rtx val = gen_reg_rtx (DImode);
> +  emit_move_insn (val, gen_lowpart (DImode, tmp));
> +
> +  rtx cc_reg = aarch64_gen_compare_reg (<cbranch_op>, val, const0_rtx);
> +  rtx cmp_rtx = gen_rtx_fmt_ee (<cbranch_op>, DImode, cc_reg, const0_rtx);
> +  emit_jump_insn (gen_aarch64_bcond (cmp_rtx, cc_reg, operands[3]));
> +  DONE;
> +})
> +
> ;; Patterns comparing two vectors to produce a mask.
> 
> (define_expand "vec_cmp<mode><mode>"
> diff --git a/gcc/config/aarch64/aarch64-sve.md 
> b/gcc/config/aarch64/aarch64-sve.md
> index 
> 4648aa67e0c360076cf4444c4e0ac55babda34e6..2a2caa2066ce07959fc97ccf4a78632551dda07a
>  100644
> --- a/gcc/config/aarch64/aarch64-sve.md
> +++ b/gcc/config/aarch64/aarch64-sve.md
> @@ -9761,7 +9761,8 @@ (define_insn "@vcond_mask_<mode><mode>"
> ;; - PTEST
> ;; -------------------------------------------------------------------------
> 
> -;; Branch based on predicate equality or inequality.
> +;; Branch based on predicate equality or inequality.  This allows PTEST to be
> +;; combined with other flag setting instructions like ORR -> ORRS.
> (define_expand "cbranch<mode>4"
>   [(set (pc)
> (if_then_else
> @@ -9790,8 +9791,120 @@ (define_expand "cbranch<mode>4"
>   }
> )
> 
> +;; Define vec_cbranch_any and vec_cbranch_all
> +;; Branch based on predicate equality or inequality.
> +(define_expand "<optab><mode>"
> +  [(set (pc)
> + (unspec:PRED_ALL
> +  [(if_then_else
> +    (match_operator 0 "aarch64_equality_operator"
> +      [(match_operand:PRED_ALL 1 "register_operand")
> +       (match_operand:PRED_ALL 2 "aarch64_simd_reg_or_zero")])
> +    (label_ref (match_operand 3 ""))
> +    (pc))]
> + CBRANCH_CMP))]
> +  ""
> +  {
> +    rtx ptrue = force_reg (VNx16BImode, aarch64_ptrue_all (<data_bytes>));
> +    rtx cast_ptrue = gen_lowpart (<MODE>mode, ptrue);
> +    rtx ptrue_flag = gen_int_mode (SVE_KNOWN_PTRUE, SImode);
> +    rtx pred;
> +    if (operands[2] == CONST0_RTX (<MODE>mode))
> +      pred = operands[1];
> +    else
> +      {
> + pred = gen_reg_rtx (<MODE>mode);
> + emit_insn (gen_aarch64_pred_xor<mode>_z (pred, cast_ptrue, operands[1],
> + operands[2]));
> +      }
> +    emit_insn (gen_aarch64_ptest<mode> (ptrue, cast_ptrue, ptrue_flag, 
> pred));
> +
> +    rtx cc_reg = gen_rtx_REG (CC_NZCmode, CC_REGNUM);
> +    rtx cmp_reg = gen_rtx_<cbranch_op> (VOIDmode, cc_reg, const0_rtx);
> +    emit_jump_insn (gen_aarch64_bcond (cmp_reg, cc_reg, operands[3]));
> +    DONE;
> +  }
> +)
> +
> +;; Define cond_vec_cbranch_any and cond_vec_cbranch_all
> +;; Vector comparison and branch for SVE Floating point types instructions
> +;; using Integer operations.
> +(define_expand "<optab><mode>"
> +  [(set (pc)
> + (unspec:SVE_F
> +  [(if_then_else
> +    (match_operator 0 "aarch64_equality_operator"
> +      [(match_operand:<VPRED> 1 "register_operand")
> +       (match_operand:SVE_F 2 "register_operand")
> +       (match_operand:SVE_F 3 "aarch64_simd_reg_or_zero")
> +       (match_operand:<VPRED> 4 "aarch64_simd_imm_zero")])
> +    (label_ref (match_operand 5 ""))
> +    (pc))]
> + COND_CBRANCH_CMP))]
> +  "flag_unsafe_math_optimizations"
> +{
> +  auto code = GET_CODE (operands[0]);
> +  machine_mode full_mode = related_int_vector_mode (<MODE>mode).require ();
> +  rtx in1 = force_lowpart_subreg (full_mode, operands[2], <MODE>mode);
> +  rtx in2;
> +  if (CONST0_RTX (<MODE>mode) == operands[3])
> +    in2 = CONST0_RTX (full_mode);
> +  else
> +    in2 = force_lowpart_subreg (full_mode, operands[3], <MODE>mode);
> +
> +  rtx res = gen_reg_rtx (<VPRED>mode);
> +  rtx gp = gen_lowpart (VNx16BImode, operands[1]);
> +  rtx cast_gp = operands[1];
> +  rtx flag = gen_int_mode (SVE_KNOWN_PTRUE, SImode);
> +
> +  emit_insn (gen_aarch64_pred_cmp_ptest (code, full_mode, res, gp, in1, in2,
> + cast_gp, flag, cast_gp, flag));
> +
> +  rtx cc_reg = gen_rtx_REG (CC_NZCmode, CC_REGNUM);
> +  rtx cmp_reg = gen_rtx_<cbranch_op> (VOIDmode, cc_reg, const0_rtx);
> +  emit_jump_insn (gen_aarch64_bcond (cmp_reg, cc_reg, operands[5]));
> +  DONE;
> +})
> +
> +
> +;; Define cond_vec_cbranch_any and cond_vec_cbranch_all
> +;; Vector comparison and branch for SVE Floating points types instructions.
> +;; But only on EQ or NE comparisons, which allows us to use integer compares
> +;; instead and about the ptest.
> +(define_expand "<optab><mode>"
> +  [(set (pc)
> + (unspec:SVE_I
> +  [(if_then_else
> +    (match_operator 0 "aarch64_comparison_operator"
> +      [(match_operand:<VPRED> 1 "register_operand")
> +       (match_operand:SVE_I 2 "register_operand")
> +       (match_operand:SVE_I 3 "aarch64_simd_reg_or_zero")
> +       (match_operand:<VPRED> 4 "aarch64_simd_imm_zero")])
> +    (label_ref (match_operand 5 ""))
> +    (pc))]
> + COND_CBRANCH_CMP))]
> +  ""
> +{
> +  auto code = GET_CODE (operands[0]);
> +  rtx in1 = operands[2];
> +  rtx in2 = operands[3];
> +
> +  rtx res = gen_reg_rtx (<VPRED>mode);
> +  rtx gp = gen_lowpart (VNx16BImode, operands[1]);
> +  rtx cast_gp = operands[1];
> +  rtx flag = gen_int_mode (SVE_KNOWN_PTRUE, SImode);
> +
> +  emit_insn (gen_aarch64_pred_cmp_ptest (code, <MODE>mode, res, gp, in1, in2,
> + cast_gp, flag, cast_gp, flag));
> +
> +  rtx cc_reg = gen_rtx_REG (CC_NZCmode, CC_REGNUM);
> +  rtx cmp_reg = gen_rtx_<cbranch_op> (VOIDmode, cc_reg, const0_rtx);
> +  emit_jump_insn (gen_aarch64_bcond (cmp_reg, cc_reg, operands[5]));
> +  DONE;
> +})
> +
> ;; See "Description of UNSPEC_PTEST" above for details.
> -(define_insn "aarch64_ptest<mode>"
> +(define_insn "@aarch64_ptest<mode>"
>   [(set (reg:CC_NZC CC_REGNUM)
> (unspec:CC_NZC [(match_operand:VNx16BI 0 "register_operand" "Upa")
> (match_operand 1)
> diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md
> index 
> 517b2808b5f725db81709122848817aaafff1f34..7a1f8e7aed4a56dec70c1a056c1512bd0da7ff56
>  100644
> --- a/gcc/config/aarch64/iterators.md
> +++ b/gcc/config/aarch64/iterators.md
> @@ -837,6 +837,10 @@ (define_c_enum "unspec"
>     UNSPEC_SSHLL ; Used in aarch64-simd.md.
>     UNSPEC_USHLL ; Used in aarch64-simd.md.
>     UNSPEC_ADDP ; Used in aarch64-simd.md.
> +    UNSPEC_CMP_ALL ; Used in aarch64-simd.md.
> +    UNSPEC_CMP_ANY ; Used in aarch64-simd.md.
> +    UNSPEC_COND_CMP_ALL ; Used in aarch64-simd.md.
> +    UNSPEC_COND_CMP_ANY ; Used in aarch64-simd.md.
>     UNSPEC_TBL ; Used in vector permute patterns.
>     UNSPEC_TBLQ ; Used in vector permute patterns.
>     UNSPEC_TBX ; Used in vector permute patterns.
> @@ -2612,6 +2616,12 @@ (define_mode_attr vpred [(VNx16QI "vnx16bi") (VNx8QI 
> "vnx8bi")
> (VNx16SI "vnx4bi") (VNx16SF "vnx4bi")
> (VNx8DI "vnx2bi") (VNx8DF "vnx2bi")])
> 
> +;; Map mode to suffix for using an SVE comparison
> +(define_mode_attr sve_cmp_suff [(V8QI "_int") (V16QI "_int")
> +       (V4HI "_int") (V8HI "_int") (V2SI "_int")
> +       (V4SI "_int") (V2DI "_int")
> +       (V2SF "_float") (V4SF "_float") (V2DF "_float")])
> +
> (define_mode_attr VDOUBLE [(VNx16QI "VNx32QI")
>   (VNx8HI "VNx16HI") (VNx8HF "VNx16HF")
>   (VNx8BF "VNx16BF")
> @@ -3272,6 +3282,9 @@ (define_int_iterator HADD [UNSPEC_SHADD UNSPEC_UHADD])
> 
> (define_int_iterator RHADD [UNSPEC_SRHADD UNSPEC_URHADD])
> 
> +(define_int_iterator CBRANCH_CMP [UNSPEC_CMP_ALL UNSPEC_CMP_ANY])
> +(define_int_iterator COND_CBRANCH_CMP [UNSPEC_COND_CMP_ALL 
> UNSPEC_COND_CMP_ANY])
> +
> (define_int_iterator BSL_DUP [1 2])
> 
> (define_int_iterator DOTPROD [UNSPEC_SDOT UNSPEC_UDOT])
> @@ -4215,7 +4228,16 @@ (define_int_attr optab [(UNSPEC_ANDF "and")
> (UNSPEC_COND_SCVTF "float")
> (UNSPEC_COND_SMAX "smax")
> (UNSPEC_COND_SMIN "smin")
> - (UNSPEC_COND_UCVTF "floatuns")])
> + (UNSPEC_COND_UCVTF "floatuns")
> + (UNSPEC_CMP_ALL "vec_cbranch_all")
> + (UNSPEC_CMP_ANY "vec_cbranch_any")
> + (UNSPEC_COND_CMP_ALL "cond_vec_cbranch_all")
> + (UNSPEC_COND_CMP_ANY "cond_vec_cbranch_any")])
> +
> +(define_int_attr cbranch_op [(UNSPEC_CMP_ALL "EQ")
> +     (UNSPEC_CMP_ANY "NE")
> +     (UNSPEC_COND_CMP_ALL "EQ")
> +     (UNSPEC_COND_CMP_ANY "NE")])
> 
> (define_int_attr fmaxmin [(UNSPEC_FMAX "fmax_nan")
>  (UNSPEC_FMAXNM "fmax")
> diff --git a/gcc/config/aarch64/predicates.md 
> b/gcc/config/aarch64/predicates.md
> index 
> 42304cef4391e15598bcd22da590c8663f3ffaa5..4b0a4f79253fcc28192cb70ce46d487875b25a7a
>  100644
> --- a/gcc/config/aarch64/predicates.md
> +++ b/gcc/config/aarch64/predicates.md
> @@ -462,6 +462,19 @@ (define_special_predicate "aarch64_comparison_operation"
> (define_special_predicate "aarch64_equality_operator"
>   (match_code "eq,ne"))
> 
> +(define_special_predicate "aarch64_cbranch_compare_operation"
> +  (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu,unordered,
> +       ordered,unlt,unle,unge,ungt")
> +{
> +  if (TARGET_SVE)
> +    return true;
> +
> +  if (!TARGET_SIMD)
> +    return false;
> +
> +  return true;


Isn’t this condition just effectively TARGET_SIMD? If TARGET_SIMD this will 
return true regardless of TARGET_SVE and if !TARGET_SIMD you can’t have 
TARGET_SVE anyway because of how the arch features are dependent so this will 
return false.

> +})
> +
> (define_special_predicate "aarch64_carry_operation"
>   (match_code "ltu,geu")
> {
> diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pr119351.c 
> b/gcc/testsuite/gcc.target/aarch64/sve/pr119351.c
> index 
> 85aab355f95f83e1fa65d280f14fb8ade7f7e658..1ebc735a82f4a59d8eccff39346e46a449b4729a
>  100644
> --- a/gcc/testsuite/gcc.target/aarch64/sve/pr119351.c
> +++ b/gcc/testsuite/gcc.target/aarch64/sve/pr119351.c
> @@ -14,7 +14,6 @@ int x[N] __attribute__((aligned(32)));
> ** ...
> ** ld1w z[0-9]+.s, p[0-9]+/z, \[x[0-9], x[0-9], lsl 2\]
> ** cmple p[0-9]+.s, p[0-9]+/z, z[0-9]+.s, #0
> -** ptest p[0-9]+, p[0-9]+.b
> ** ...
> */
> 
> diff --git a/gcc/testsuite/gcc.target/aarch64/sve/vect-early-break-cbranch.c 
> b/gcc/testsuite/gcc.target/aarch64/sve/vect-early-break-cbranch.c
> index 
> d7cef1105410be04ed67d1d3b800746267f205a8..48fb407ccee769b008e0de87e25dda71fe235d20
>  100644
> --- a/gcc/testsuite/gcc.target/aarch64/sve/vect-early-break-cbranch.c
> +++ b/gcc/testsuite/gcc.target/aarch64/sve/vect-early-break-cbranch.c
> @@ -8,8 +8,7 @@ int b[N] = {0};
> ** f1:
> ** ...
> ** cmpgt p[0-9]+.s, p[0-9]+/z, z[0-9]+.s, #0
> -** ptest p[0-9]+, p[0-9]+.b
> -** b.(any|none) \.L[0-9]+
> +** b(\.?eq|\.none) \.L[0-9]+
> ** ...
> */
> void f1 ()
> @@ -25,8 +24,7 @@ void f1 ()
> ** f2:
> ** ...
> ** cmpge p[0-9]+.s, p[0-9]+/z, z[0-9]+.s, #0
> -** ptest p[0-9]+, p[0-9]+.b
> -** b.(any|none) \.L[0-9]+
> +** b(\.?eq|\.none) \.L[0-9]+
> ** ...
> */
> void f2 ()
> @@ -42,8 +40,7 @@ void f2 ()
> ** f3:
> ** ...
> ** cmpeq p[0-9]+.s, p[0-9]+/z, z[0-9]+.s, #0
> -** ptest p[0-9]+, p[0-9]+.b
> -** b.(any|none) \.L[0-9]+
> +** b(\.?eq|\.none) \.L[0-9]+
> ** ...
> */
> void f3 ()
> @@ -59,8 +56,7 @@ void f3 ()
> ** f4:
> ** ...
> ** cmpne p[0-9]+.s, p[0-9]+/z, z[0-9]+.s, #0
> -** ptest p[0-9]+, p[0-9]+.b
> -** b.(any|none) \.L[0-9]+
> +** b(\.?eq|\.none) \.L[0-9]+
> ** ...
> */
> void f4 ()
> @@ -76,8 +72,7 @@ void f4 ()
> ** f5:
> ** ...
> ** cmplt p[0-9]+.s, p7/z, z[0-9]+.s, #0
> -** ptest p[0-9]+, p[0-9]+.b
> -** b.(any|none) .L[0-9]+
> +** b(\.?eq|\.none) .L[0-9]+
> ** ...
> */
> void f5 ()
> @@ -93,8 +88,7 @@ void f5 ()
> ** f6:
> ** ...
> ** cmple p[0-9]+.s, p[0-9]+/z, z[0-9]+.s, #0
> -** ptest p[0-9]+, p[0-9]+.b
> -** b.(any|none) \.L[0-9]+
> +** b(\.?eq|\.none) \.L[0-9]+
> ** ...
> */
> void f6 ()
> diff --git 
> a/gcc/testsuite/gcc.target/aarch64/sve/vect-early-break-cbranch_2.c 
> b/gcc/testsuite/gcc.target/aarch64/sve/vect-early-break-cbranch_2.c
> new file mode 100644
> index 
> 0000000000000000000000000000000000000000..7c996a893d99f7462c980140d12ab2711738597c
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/sve/vect-early-break-cbranch_2.c
> @@ -0,0 +1,132 @@
> +/* { dg-do run { target aarch64_sve_hw } } */
> +/* { dg-options "-O3 -fno-schedule-insns -fno-reorder-blocks 
> -fno-schedule-insns2 --param aarch64-autovec-preference=asimd-only" } */

As this is a runtime test and you don’t do any assembly scanning the 
-fno-schedule* and -fno-reorder options aren’t needed.
Thanks,
Kyrill

> +/* { dg-require-effective-target lp64 } */
> +
> +#include <stdio.h>
> +
> +#define N 640
> +#ifndef TYPE
> +#define TYPE int
> +#endif
> +#ifndef FMT
> +#define FMT "d"
> +#endif
> +
> +
> +TYPE a[N] = {0};
> +TYPE b[N] = {0};
> +
> +char *curr_test;
> +
> +/* Macro to define a function with a specific comparison */
> +#define DEFINE_TEST_FUNC(NAME, OP)            \
> +  __attribute__((noipa))      \
> +  void NAME(void) {                           \
> +    for (int i = 0; i < N; i++) {             \
> +      b[i] += a[i];                           \
> +      if (a[i] OP 0)                          \
> +        break;                                \
> +    }                                         \
> +  }
> +
> +/* Generate the six comparisons functions using the macro.  */
> +DEFINE_TEST_FUNC(f1, >)
> +DEFINE_TEST_FUNC(f2, >=)
> +DEFINE_TEST_FUNC(f3, ==)
> +DEFINE_TEST_FUNC(f4, !=)
> +DEFINE_TEST_FUNC(f5, <)
> +DEFINE_TEST_FUNC(f6, <=)
> +
> +__attribute__((noreturn))
> +static inline void __abort_trace (const char *m, int i, TYPE result, TYPE 
> expected)
> +{
> +   printf ("*** [%s] FAIL AT %s:%d in %s - expected %" FMT " but got %" FMT 
> " at pos %d\n",
> +           m, __FILE__, __LINE__, curr_test, expected, result, i);
> +   __builtin_abort ();
> +}
> +
> +/* Array setup macro.  */
> +#define RESET_ARRAYS(_aval, _idx, _force, _bval)         \
> +  do {                                                   \
> +    _Pragma("GCC novector") \
> +    for (int i = 0; i < N; ++i) {                        \
> +      a[i] = _aval;                                      \
> +      b[i] = _bval;                                      \
> +    }                                                    \
> +    if (_idx >= 0 && _idx < N)                           \
> +      a[_idx] = _force;                                  \
> +  } while (0)
> +
> +/* Value check macros.  */
> +#define CHECK_EQ(_i, _val)                        \
> +  do {                                            \
> +    if (b[_i] != _val)                            \
> +      __abort_trace ("single", _i, b[_i], _val);  \
> +  } while (0)
> +
> +#define CHECK_RANGE_EQ(_start, _end, _val)               \
> +  do {                                                   \
> +    _Pragma("GCC novector") \
> +    for (int i = _start; i < _end; ++i)                  \
> +      if (b[i] != _val)                                  \
> +        __abort_trace ("range", i, b[i], _val);          \
> +  } while (0)
> +
> +#define str(s) #s
> +#define TEST_FUNC(_func, _aval, _idx, _force, _bval, _check_stmt)  \
> +  do {                                                             \
> +    curr_test = str (_func);                                       \
> +    RESET_ARRAYS((_aval), (_idx), (_force), (_bval));              \
> +    _func();                                                       \
> +    _check_stmt;                                                   \
> +  } while (0)
> +
> +int main(void) {
> +  /* Break on random intervals.  */
> +  TEST_FUNC (f1, 1, 0, 1, 10, CHECK_EQ (0, 11); CHECK_EQ (1, 10));
> +  TEST_FUNC (f2, -1, 5, 0, 10, CHECK_EQ (0, 9); CHECK_EQ (5, 10));
> +  TEST_FUNC (f3, 3, 3, 0, 0, CHECK_EQ (0, 3); CHECK_EQ (3, 0));
> +  TEST_FUNC (f4, 0, 4, 1, 1, CHECK_EQ (4, 2); CHECK_EQ (5, 1));
> +  TEST_FUNC (f5, 1, 6, -1, 5, CHECK_EQ (6, 4); CHECK_EQ (7, 5));
> +  TEST_FUNC (f6, 2, 10, 0, 7, CHECK_EQ (10, 7); CHECK_EQ (11, 7));
> +
> +  /* Break on last iteration.  */
> +  TEST_FUNC (f1, 0, N-1, 1, 1,
> +    CHECK_RANGE_EQ (0, N-1, 1); CHECK_EQ (N-1, 2));
> +
> +  TEST_FUNC (f2, -5, N-1, 0, 9,
> +    CHECK_RANGE_EQ (0, N-1, 4); CHECK_EQ (N-1, 9));
> +
> +  TEST_FUNC (f3, 2, N-1, 0, 0,
> +    CHECK_RANGE_EQ(0, N-1, 2); CHECK_EQ (N-1, 0));
> +
> +  TEST_FUNC (f4, 0, N-1, 2, 1,
> +    CHECK_RANGE_EQ (0, N-1, 1); CHECK_EQ (N-1, 3));
> +
> +  TEST_FUNC (f5, 2, N-1, -3, 6,
> +    CHECK_RANGE_EQ (0, N-1, 8); CHECK_EQ (N-1, 3));
> +
> +  TEST_FUNC (f6, 5, N-1, 0, 7,
> +    CHECK_RANGE_EQ (0, N-1, 12); CHECK_EQ (N-1, 7));
> +
> +  /* Condition never met — full loop executes.  */
> +  TEST_FUNC (f1, 0, -1, 0, 2,
> +    CHECK_RANGE_EQ (0, N, 2));
> +
> +  TEST_FUNC (f2, -2, -1, 0, 5,
> +    CHECK_RANGE_EQ (0, N, 3));
> +
> +  TEST_FUNC (f3, 1, -1, 0, 0,
> +    CHECK_RANGE_EQ (0, N, 1));
> +
> +  TEST_FUNC (f4, 0, -1, 0, 7,
> +    CHECK_RANGE_EQ (0, N, 7));
> +
> +  TEST_FUNC (f5, 1, -1, 0, 4,
> +    CHECK_RANGE_EQ (0, N, 5));
> +
> +  TEST_FUNC (f6, 5, -1, 0, 3,
> +    CHECK_RANGE_EQ (0, N, 8));
> +
> +  return 0;
> +}
> diff --git 
> a/gcc/testsuite/gcc.target/aarch64/sve/vect-early-break-cbranch_3.c 
> b/gcc/testsuite/gcc.target/aarch64/sve/vect-early-break-cbranch_3.c
> new file mode 100644
> index 
> 0000000000000000000000000000000000000000..75927abb09479712760a60b0f6a11135d9be9502
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/sve/vect-early-break-cbranch_3.c
> @@ -0,0 +1,132 @@
> +/* { dg-do run { target aarch64_sve_hw } } */
> +/* { dg-options "-O3 -fno-schedule-insns -fno-reorder-blocks 
> -fno-schedule-insns2 --param aarch64-autovec-preference=sve-only" } */
> +/* { dg-require-effective-target lp64 } */
> +
> +#include <stdio.h>
> +
> +#define N 640
> +#ifndef TYPE
> +#define TYPE int
> +#endif
> +#ifndef FMT
> +#define FMT "d"
> +#endif
> +
> +
> +TYPE a[N] = {0};
> +TYPE b[N] = {0};
> +
> +char *curr_test;
> +
> +/* Macro to define a function with a specific comparison */
> +#define DEFINE_TEST_FUNC(NAME, OP)            \
> +  __attribute__((noipa))      \
> +  void NAME(void) {                           \
> +    for (int i = 0; i < N; i++) {             \
> +      b[i] += a[i];                           \
> +      if (a[i] OP 0)                          \
> +        break;                                \
> +    }                                         \
> +  }
> +
> +/* Generate the six comparisons functions using the macro.  */
> +DEFINE_TEST_FUNC(f1, >)
> +DEFINE_TEST_FUNC(f2, >=)
> +DEFINE_TEST_FUNC(f3, ==)
> +DEFINE_TEST_FUNC(f4, !=)
> +DEFINE_TEST_FUNC(f5, <)
> +DEFINE_TEST_FUNC(f6, <=)
> +
> +__attribute__((noreturn))
> +static inline void __abort_trace (const char *m, int i, TYPE result, TYPE 
> expected)
> +{
> +   printf ("*** [%s] FAIL AT %s:%d in %s - expected %" FMT " but got %" FMT 
> " at pos %d\n",
> +           m, __FILE__, __LINE__, curr_test, expected, result, i);
> +   __builtin_abort ();
> +}
> +
> +/* Array setup macro.  */
> +#define RESET_ARRAYS(_aval, _idx, _force, _bval)         \
> +  do {                                                   \
> +    _Pragma("GCC novector") \
> +    for (int i = 0; i < N; ++i) {                        \
> +      a[i] = _aval;                                      \
> +      b[i] = _bval;                                      \
> +    }                                                    \
> +    if (_idx >= 0 && _idx < N)                           \
> +      a[_idx] = _force;                                  \
> +  } while (0)
> +
> +/* Value check macros.  */
> +#define CHECK_EQ(_i, _val)                        \
> +  do {                                            \
> +    if (b[_i] != _val)                            \
> +      __abort_trace ("single", _i, b[_i], _val);  \
> +  } while (0)
> +
> +#define CHECK_RANGE_EQ(_start, _end, _val)               \
> +  do {                                                   \
> +    _Pragma("GCC novector") \
> +    for (int i = _start; i < _end; ++i)                  \
> +      if (b[i] != _val)                                  \
> +        __abort_trace ("range", i, b[i], _val);          \
> +  } while (0)
> +
> +#define str(s) #s
> +#define TEST_FUNC(_func, _aval, _idx, _force, _bval, _check_stmt)  \
> +  do {                                                             \
> +    curr_test = str (_func);                                       \
> +    RESET_ARRAYS((_aval), (_idx), (_force), (_bval));              \
> +    _func();                                                       \
> +    _check_stmt;                                                   \
> +  } while (0)
> +
> +int main(void) {
> +  /* Break on random intervals.  */
> +  TEST_FUNC (f1, 1, 0, 1, 10, CHECK_EQ (0, 11); CHECK_EQ (1, 10));
> +  TEST_FUNC (f2, -1, 5, 0, 10, CHECK_EQ (0, 9); CHECK_EQ (5, 10));
> +  TEST_FUNC (f3, 3, 3, 0, 0, CHECK_EQ (0, 3); CHECK_EQ (3, 0));
> +  TEST_FUNC (f4, 0, 4, 1, 1, CHECK_EQ (4, 2); CHECK_EQ (5, 1));
> +  TEST_FUNC (f5, 1, 6, -1, 5, CHECK_EQ (6, 4); CHECK_EQ (7, 5));
> +  TEST_FUNC (f6, 2, 10, 0, 7, CHECK_EQ (10, 7); CHECK_EQ (11, 7));
> +
> +  /* Break on last iteration.  */
> +  TEST_FUNC (f1, 0, N-1, 1, 1,
> +    CHECK_RANGE_EQ (0, N-1, 1); CHECK_EQ (N-1, 2));
> +
> +  TEST_FUNC (f2, -5, N-1, 0, 9,
> +    CHECK_RANGE_EQ (0, N-1, 4); CHECK_EQ (N-1, 9));
> +
> +  TEST_FUNC (f3, 2, N-1, 0, 0,
> +    CHECK_RANGE_EQ(0, N-1, 2); CHECK_EQ (N-1, 0));
> +
> +  TEST_FUNC (f4, 0, N-1, 2, 1,
> +    CHECK_RANGE_EQ (0, N-1, 1); CHECK_EQ (N-1, 3));
> +
> +  TEST_FUNC (f5, 2, N-1, -3, 6,
> +    CHECK_RANGE_EQ (0, N-1, 8); CHECK_EQ (N-1, 3));
> +
> +  TEST_FUNC (f6, 5, N-1, 0, 7,
> +    CHECK_RANGE_EQ (0, N-1, 12); CHECK_EQ (N-1, 7));
> +
> +  /* Condition never met — full loop executes.  */
> +  TEST_FUNC (f1, 0, -1, 0, 2,
> +    CHECK_RANGE_EQ (0, N, 2));
> +
> +  TEST_FUNC (f2, -2, -1, 0, 5,
> +    CHECK_RANGE_EQ (0, N, 3));
> +
> +  TEST_FUNC (f3, 1, -1, 0, 0,
> +    CHECK_RANGE_EQ (0, N, 1));
> +
> +  TEST_FUNC (f4, 0, -1, 0, 7,
> +    CHECK_RANGE_EQ (0, N, 7));
> +
> +  TEST_FUNC (f5, 1, -1, 0, 4,
> +    CHECK_RANGE_EQ (0, N, 5));
> +
> +  TEST_FUNC (f6, 5, -1, 0, 3,
> +    CHECK_RANGE_EQ (0, N, 8));
> +
> +  return 0;
> +}
> diff --git 
> a/gcc/testsuite/gcc.target/aarch64/sve/vect-early-break-cbranch_4.c 
> b/gcc/testsuite/gcc.target/aarch64/sve/vect-early-break-cbranch_4.c
> new file mode 100644
> index 
> 0000000000000000000000000000000000000000..68a5d0a09fdfd5664562e1bac3b5e586a37b3a6f
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/sve/vect-early-break-cbranch_4.c
> @@ -0,0 +1,132 @@
> +/* { dg-do run { target aarch64_sve_hw } } */
> +/* { dg-options "-O3 -fno-schedule-insns -fno-reorder-blocks 
> -fno-schedule-insns2 --param aarch64-autovec-preference=asimd-only" } */
> +/* { dg-require-effective-target lp64 } */
> +
> +#include <stdio.h>
> +
> +#define N 640
> +#ifndef TYPE
> +#define TYPE float
> +#endif
> +#ifndef FMT
> +#define FMT ".6f"
> +#endif
> +
> +
> +TYPE a[N] = {0};
> +TYPE b[N] = {0};
> +
> +char *curr_test;
> +
> +/* Macro to define a function with a specific comparison */
> +#define DEFINE_TEST_FUNC(NAME, OP)            \
> +  __attribute__((noipa))      \
> +  void NAME(void) {                           \
> +    for (int i = 0; i < N; i++) {             \
> +      b[i] += a[i];                           \
> +      if (a[i] OP 0)                          \
> +        break;                                \
> +    }                                         \
> +  }
> +
> +/* Generate the six comparisons functions using the macro.  */
> +DEFINE_TEST_FUNC(f1, >)
> +DEFINE_TEST_FUNC(f2, >=)
> +DEFINE_TEST_FUNC(f3, ==)
> +DEFINE_TEST_FUNC(f4, !=)
> +DEFINE_TEST_FUNC(f5, <)
> +DEFINE_TEST_FUNC(f6, <=)
> +
> +__attribute__((noreturn))
> +static inline void __abort_trace (const char *m, int i, TYPE result, TYPE 
> expected)
> +{
> +   printf ("*** [%s] FAIL AT %s:%d in %s - expected %" FMT " but got %" FMT 
> " at pos %d\n",
> +           m, __FILE__, __LINE__, curr_test, expected, result, i);
> +   __builtin_abort ();
> +}
> +
> +/* Array setup macro.  */
> +#define RESET_ARRAYS(_aval, _idx, _force, _bval)         \
> +  do {                                                   \
> +    _Pragma("GCC novector") \
> +    for (int i = 0; i < N; ++i) {                        \
> +      a[i] = _aval;                                      \
> +      b[i] = _bval;                                      \
> +    }                                                    \
> +    if (_idx >= 0 && _idx < N)                           \
> +      a[_idx] = _force;                                  \
> +  } while (0)
> +
> +/* Value check macros.  */
> +#define CHECK_EQ(_i, _val)                        \
> +  do {                                            \
> +    if (b[_i] != _val)                            \
> +      __abort_trace ("single", _i, b[_i], _val);  \
> +  } while (0)
> +
> +#define CHECK_RANGE_EQ(_start, _end, _val)               \
> +  do {                                                   \
> +    _Pragma("GCC novector") \
> +    for (int i = _start; i < _end; ++i)                  \
> +      if (b[i] != _val)                                  \
> +        __abort_trace ("range", i, b[i], _val);          \
> +  } while (0)
> +
> +#define str(s) #s
> +#define TEST_FUNC(_func, _aval, _idx, _force, _bval, _check_stmt)  \
> +  do {                                                             \
> +    curr_test = str (_func);                                       \
> +    RESET_ARRAYS((_aval), (_idx), (_force), (_bval));              \
> +    _func();                                                       \
> +    _check_stmt;                                                   \
> +  } while (0)
> +
> +int main(void) {
> +  /* Break on random intervals.  */
> +  TEST_FUNC (f1, 1, 0, 1, 10, CHECK_EQ (0, 11); CHECK_EQ (1, 10));
> +  TEST_FUNC (f2, -1, 5, 0, 10, CHECK_EQ (0, 9); CHECK_EQ (5, 10));
> +  TEST_FUNC (f3, 3, 3, 0, 0, CHECK_EQ (0, 3); CHECK_EQ (3, 0));
> +  TEST_FUNC (f4, 0, 4, 1, 1, CHECK_EQ (4, 2); CHECK_EQ (5, 1));
> +  TEST_FUNC (f5, 1, 6, -1, 5, CHECK_EQ (6, 4); CHECK_EQ (7, 5));
> +  TEST_FUNC (f6, 2, 10, 0, 7, CHECK_EQ (10, 7); CHECK_EQ (11, 7));
> +
> +  /* Break on last iteration.  */
> +  TEST_FUNC (f1, 0, N-1, 1, 1,
> +    CHECK_RANGE_EQ (0, N-1, 1); CHECK_EQ (N-1, 2));
> +
> +  TEST_FUNC (f2, -5, N-1, 0, 9,
> +    CHECK_RANGE_EQ (0, N-1, 4); CHECK_EQ (N-1, 9));
> +
> +  TEST_FUNC (f3, 2, N-1, 0, 0,
> +    CHECK_RANGE_EQ(0, N-1, 2); CHECK_EQ (N-1, 0));
> +
> +  TEST_FUNC (f4, 0, N-1, 2, 1,
> +    CHECK_RANGE_EQ (0, N-1, 1); CHECK_EQ (N-1, 3));
> +
> +  TEST_FUNC (f5, 2, N-1, -3, 6,
> +    CHECK_RANGE_EQ (0, N-1, 8); CHECK_EQ (N-1, 3));
> +
> +  TEST_FUNC (f6, 5, N-1, 0, 7,
> +    CHECK_RANGE_EQ (0, N-1, 12); CHECK_EQ (N-1, 7));
> +
> +  /* Condition never met — full loop executes.  */
> +  TEST_FUNC (f1, 0, -1, 0, 2,
> +    CHECK_RANGE_EQ (0, N, 2));
> +
> +  TEST_FUNC (f2, -2, -1, 0, 5,
> +    CHECK_RANGE_EQ (0, N, 3));
> +
> +  TEST_FUNC (f3, 1, -1, 0, 0,
> +    CHECK_RANGE_EQ (0, N, 1));
> +
> +  TEST_FUNC (f4, 0, -1, 0, 7,
> +    CHECK_RANGE_EQ (0, N, 7));
> +
> +  TEST_FUNC (f5, 1, -1, 0, 4,
> +    CHECK_RANGE_EQ (0, N, 5));
> +
> +  TEST_FUNC (f6, 5, -1, 0, 3,
> +    CHECK_RANGE_EQ (0, N, 8));
> +
> +  return 0;
> +}
> diff --git 
> a/gcc/testsuite/gcc.target/aarch64/sve/vect-early-break-cbranch_5.c 
> b/gcc/testsuite/gcc.target/aarch64/sve/vect-early-break-cbranch_5.c
> new file mode 100644
> index 
> 0000000000000000000000000000000000000000..52d95e9a71b7999376731e47a224936d4253ac2f
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/sve/vect-early-break-cbranch_5.c
> @@ -0,0 +1,132 @@
> +/* { dg-do run { target aarch64_sve_hw } } */
> +/* { dg-options "-O3 -fno-schedule-insns -fno-reorder-blocks 
> -fno-schedule-insns2 --param aarch64-autovec-preference=sve-only" } */
> +/* { dg-require-effective-target lp64 } */
> +
> +#include <stdio.h>
> +
> +#define N 640
> +#ifndef TYPE
> +#define TYPE float
> +#endif
> +#ifndef FMT
> +#define FMT ".6f"
> +#endif
> +
> +
> +TYPE a[N] = {0};
> +TYPE b[N] = {0};
> +
> +char *curr_test;
> +
> +/* Macro to define a function with a specific comparison */
> +#define DEFINE_TEST_FUNC(NAME, OP)            \
> +  __attribute__((noipa))      \
> +  void NAME(void) {                           \
> +    for (int i = 0; i < N; i++) {             \
> +      b[i] += a[i];                           \
> +      if (a[i] OP 0)                          \
> +        break;                                \
> +    }                                         \
> +  }
> +
> +/* Generate the six comparisons functions using the macro.  */
> +DEFINE_TEST_FUNC(f1, >)
> +DEFINE_TEST_FUNC(f2, >=)
> +DEFINE_TEST_FUNC(f3, ==)
> +DEFINE_TEST_FUNC(f4, !=)
> +DEFINE_TEST_FUNC(f5, <)
> +DEFINE_TEST_FUNC(f6, <=)
> +
> +__attribute__((noreturn))
> +static inline void __abort_trace (const char *m, int i, TYPE result, TYPE 
> expected)
> +{
> +   printf ("*** [%s] FAIL AT %s:%d in %s - expected %" FMT " but got %" FMT 
> " at pos %d\n",
> +           m, __FILE__, __LINE__, curr_test, expected, result, i);
> +   __builtin_abort ();
> +}
> +
> +/* Array setup macro.  */
> +#define RESET_ARRAYS(_aval, _idx, _force, _bval)         \
> +  do {                                                   \
> +    _Pragma("GCC novector") \
> +    for (int i = 0; i < N; ++i) {                        \
> +      a[i] = _aval;                                      \
> +      b[i] = _bval;                                      \
> +    }                                                    \
> +    if (_idx >= 0 && _idx < N)                           \
> +      a[_idx] = _force;                                  \
> +  } while (0)
> +
> +/* Value check macros.  */
> +#define CHECK_EQ(_i, _val)                        \
> +  do {                                            \
> +    if (b[_i] != _val)                            \
> +      __abort_trace ("single", _i, b[_i], _val);  \
> +  } while (0)
> +
> +#define CHECK_RANGE_EQ(_start, _end, _val)               \
> +  do {                                                   \
> +    _Pragma("GCC novector") \
> +    for (int i = _start; i < _end; ++i)                  \
> +      if (b[i] != _val)                                  \
> +        __abort_trace ("range", i, b[i], _val);          \
> +  } while (0)
> +
> +#define str(s) #s
> +#define TEST_FUNC(_func, _aval, _idx, _force, _bval, _check_stmt)  \
> +  do {                                                             \
> +    curr_test = str (_func);                                       \
> +    RESET_ARRAYS((_aval), (_idx), (_force), (_bval));              \
> +    _func();                                                       \
> +    _check_stmt;                                                   \
> +  } while (0)
> +
> +int main(void) {
> +  /* Break on random intervals.  */
> +  TEST_FUNC (f1, 1, 0, 1, 10, CHECK_EQ (0, 11); CHECK_EQ (1, 10));
> +  TEST_FUNC (f2, -1, 5, 0, 10, CHECK_EQ (0, 9); CHECK_EQ (5, 10));
> +  TEST_FUNC (f3, 3, 3, 0, 0, CHECK_EQ (0, 3); CHECK_EQ (3, 0));
> +  TEST_FUNC (f4, 0, 4, 1, 1, CHECK_EQ (4, 2); CHECK_EQ (5, 1));
> +  TEST_FUNC (f5, 1, 6, -1, 5, CHECK_EQ (6, 4); CHECK_EQ (7, 5));
> +  TEST_FUNC (f6, 2, 10, 0, 7, CHECK_EQ (10, 7); CHECK_EQ (11, 7));
> +
> +  /* Break on last iteration.  */
> +  TEST_FUNC (f1, 0, N-1, 1, 1,
> +    CHECK_RANGE_EQ (0, N-1, 1); CHECK_EQ (N-1, 2));
> +
> +  TEST_FUNC (f2, -5, N-1, 0, 9,
> +    CHECK_RANGE_EQ (0, N-1, 4); CHECK_EQ (N-1, 9));
> +
> +  TEST_FUNC (f3, 2, N-1, 0, 0,
> +    CHECK_RANGE_EQ(0, N-1, 2); CHECK_EQ (N-1, 0));
> +
> +  TEST_FUNC (f4, 0, N-1, 2, 1,
> +    CHECK_RANGE_EQ (0, N-1, 1); CHECK_EQ (N-1, 3));
> +
> +  TEST_FUNC (f5, 2, N-1, -3, 6,
> +    CHECK_RANGE_EQ (0, N-1, 8); CHECK_EQ (N-1, 3));
> +
> +  TEST_FUNC (f6, 5, N-1, 0, 7,
> +    CHECK_RANGE_EQ (0, N-1, 12); CHECK_EQ (N-1, 7));
> +
> +  /* Condition never met — full loop executes.  */
> +  TEST_FUNC (f1, 0, -1, 0, 2,
> +    CHECK_RANGE_EQ (0, N, 2));
> +
> +  TEST_FUNC (f2, -2, -1, 0, 5,
> +    CHECK_RANGE_EQ (0, N, 3));
> +
> +  TEST_FUNC (f3, 1, -1, 0, 0,
> +    CHECK_RANGE_EQ (0, N, 1));
> +
> +  TEST_FUNC (f4, 0, -1, 0, 7,
> +    CHECK_RANGE_EQ (0, N, 7));
> +
> +  TEST_FUNC (f5, 1, -1, 0, 4,
> +    CHECK_RANGE_EQ (0, N, 5));
> +
> +  TEST_FUNC (f6, 5, -1, 0, 3,
> +    CHECK_RANGE_EQ (0, N, 8));
> +
> +  return 0;
> +}
> diff --git 
> a/gcc/testsuite/gcc.target/aarch64/sve/vect-early-break-cbranch_7.c 
> b/gcc/testsuite/gcc.target/aarch64/sve/vect-early-break-cbranch_7.c
> new file mode 100644
> index 
> 0000000000000000000000000000000000000000..20cbb685b17a3312b30ce0124a36cdfaf3b3a02d
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/sve/vect-early-break-cbranch_7.c
> @@ -0,0 +1,147 @@
> +/* { dg-do run { target aarch64_sve_hw } } */
> +/* { dg-options "-Ofast -fno-schedule-insns -fno-reorder-blocks 
> -fno-schedule-insns2 --param aarch64-autovec-preference=asimd-only" } */
> +/* { dg-require-effective-target lp64 } */
> +
> +#include <stdio.h>
> +#include <math.h>
> +
> +#define N 640
> +#ifndef TYPE
> +#define TYPE float
> +#endif
> +#ifndef FMT
> +#define FMT ".6f"
> +#endif
> +
> +TYPE a[N] = {0};
> +TYPE b[N] = {0};
> +
> +char *curr_test;
> +
> +/* Macro to define a function with a specific comparison */
> +#define DEFINE_TEST_FUNC(NAME, OP)            \
> +  __attribute__((noipa))      \
> +  void NAME(void) {                           \
> +    for (int i = 0; i < N; i++) {             \
> +      b[i] += a[i];                           \
> +      if (a[i] OP 0)                          \
> +        break;                                \
> +    }                                         \
> +  }
> +
> +/* Generate comparison functions */
> +DEFINE_TEST_FUNC(f1, >)
> +DEFINE_TEST_FUNC(f2, >=)
> +DEFINE_TEST_FUNC(f3, ==)
> +DEFINE_TEST_FUNC(f4, !=)
> +DEFINE_TEST_FUNC(f5, <)
> +DEFINE_TEST_FUNC(f6, <=)
> +
> +/* Example unordered-sensitive loop: breaks if a[i] is unordered with 0 */
> +__attribute__((noipa))
> +void f7(void) {
> +  for (int i = 0; i < N; i++) {
> +    b[i] += a[i];
> +    if (__builtin_isunordered(a[i], 0.0f))
> +      break;
> +  }
> +}
> +
> +__attribute__((noreturn))
> +static inline void __abort_trace(const char *m, int i, TYPE result, TYPE 
> expected) {
> +  printf("*** [%s] FAIL AT %s:%d in %s - expected %" FMT " but got %" FMT " 
> at pos %d\n",
> +         m, __FILE__, __LINE__, curr_test, expected, result, i);
> +  __builtin_abort();
> +}
> +
> +/* Array setup */
> +#define RESET_ARRAYS(_aval, _idx, _force, _bval)         \
> +  do {                                                   \
> +    _Pragma("GCC novector") \
> +    for (int i = 0; i < N; ++i) {                        \
> +      a[i] = _aval;                                      \
> +      b[i] = _bval;                                      \
> +    }                                                    \
> +    if (_idx >= 0 && _idx < N)                           \
> +      a[_idx] = _force;                                  \
> +  } while (0)
> +
> +/* Floating-point comparison macros (with unordered handling) */
> +#define CHECK_EQ(_i, _val) do {                                  \
> +  if (__builtin_isnan (_val) != __builtin_isnan (b[_i])          \
> +      && b[_i] != _val)                                          \
> +    __abort_trace ("single", _i, b[_i], _val);                   \
> +} while (0)
> +
> +#define CHECK_RANGE_EQ(_start, _end, _val) do {                  \
> +  _Pragma("GCC novector")                                        \
> +  for (int i = _start; i < _end; ++i)                            \
> +    if (__builtin_isnan (_val) != __builtin_isnan (b[i])         \
> + && b[i] != _val)                                         \
> +      __abort_trace ("range", i, b[i], _val);                    \
> +} while (0)
> +
> +#define str(s) #s
> +#define TEST_FUNC(_func, _aval, _idx, _force, _bval, _check_stmt)  \
> +  do {                                                             \
> +    curr_test = str (_func);                                       \
> +    RESET_ARRAYS((_aval), (_idx), (_force), (_bval));              \
> +    _func();                                                       \
> +    _check_stmt;                                                   \
> +  } while (0)
> +
> +int main(void) {
> +  /* Break on random intervals.  */
> +  TEST_FUNC(f1, 1.0f, 0, 1.0f, 10.0f, CHECK_EQ(0, 11.0f); CHECK_EQ(1, 
> 10.0f));
> +  TEST_FUNC(f2, -1.0f, 5, 0.0f, 10.0f, CHECK_EQ(0, 9.0f); CHECK_EQ(5, 
> 10.0f));
> +  TEST_FUNC(f3, 3.0f, 3, 0.0f, 0.0f, CHECK_EQ(0, 3.0f); CHECK_EQ(3, 0.0f));
> +  TEST_FUNC(f4, 0.0f, 4, 1.0f, 1.0f, CHECK_EQ(4, 2.0f); CHECK_EQ(5, 1.0f));
> +  TEST_FUNC(f5, 1.0f, 6, -1.0f, 5.0f, CHECK_EQ(6, 4.0f); CHECK_EQ(7, 5.0f));
> +  TEST_FUNC(f6, 2.0f, 10, 0.0f, 7.0f, CHECK_EQ(10, 7.0f); CHECK_EQ(11, 
> 7.0f));
> +
> +  /* Break on last iteration.  */
> +  TEST_FUNC(f1, 0.0f, N - 1, 1.0f, 1.0f,
> +    CHECK_RANGE_EQ(0, N - 1, 1.0f); CHECK_EQ(N - 1, 2.0f));
> +
> +  TEST_FUNC(f2, -5.0f, N - 1, 0.0f, 9.0f,
> +    CHECK_RANGE_EQ(0, N - 1, 4.0f); CHECK_EQ(N - 1, 9.0f));
> +
> +  TEST_FUNC(f3, 2.0f, N - 1, 0.0f, 0.0f,
> +    CHECK_RANGE_EQ(0, N - 1, 2.0f); CHECK_EQ(N - 1, 0.0f));
> +
> +  TEST_FUNC(f4, 0.0f, N - 1, 2.0f, 1.0f,
> +    CHECK_RANGE_EQ(0, N - 1, 1.0f); CHECK_EQ(N - 1, 3.0f));
> +
> +  TEST_FUNC(f5, 2.0f, N - 1, -3.0f, 6.0f,
> +    CHECK_RANGE_EQ(0, N - 1, 8.0f); CHECK_EQ(N - 1, 3.0f));
> +
> +  TEST_FUNC(f6, 5.0f, N - 1, 0.0f, 7.0f,
> +    CHECK_RANGE_EQ(0, N - 1, 12.0f); CHECK_EQ(N - 1, 7.0f));
> +
> +  /* Condition never met — full loop executes.  */
> +  TEST_FUNC(f1, 0.0f, -1, 0.0f, 2.0f,
> +    CHECK_RANGE_EQ(0, N, 2.0f));
> +
> +  TEST_FUNC(f2, -2.0f, -1, 0.0f, 5.0f,
> +    CHECK_RANGE_EQ(0, N, 3.0f));
> +
> +  TEST_FUNC(f3, 1.0f, -1, 0.0f, 0.0f,
> +    CHECK_RANGE_EQ(0, N, 1.0f));
> +
> +  TEST_FUNC(f4, 0.0f, -1, 0.0f, 7.0f,
> +    CHECK_RANGE_EQ(0, N, 7.0f));
> +
> +  TEST_FUNC(f5, 1.0f, -1, 0.0f, 4.0f,
> +    CHECK_RANGE_EQ(0, N, 5.0f));
> +
> +  TEST_FUNC(f6, 5.0f, -1, 0.0f, 3.0f,
> +    CHECK_RANGE_EQ(0, N, 8.0f));
> +
> +#if !defined(__FAST_MATH__)
> +  /* Unordered break (NAN in a[i]) */
> +  TEST_FUNC(f7, 1.0f, 123, NAN, 2.0f,
> +    CHECK_RANGE_EQ(0, 123, 3.0f); CHECK_EQ(123, NAN));
> +#endif
> +
> +  return 0;
> +}
> diff --git 
> a/gcc/testsuite/gcc.target/aarch64/sve/vect-early-break-cbranch_8.c 
> b/gcc/testsuite/gcc.target/aarch64/sve/vect-early-break-cbranch_8.c
> new file mode 100644
> index 
> 0000000000000000000000000000000000000000..d951d649ac6d3c3030f7b5e04055f8065908d87b
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/sve/vect-early-break-cbranch_8.c
> @@ -0,0 +1,132 @@
> +/* { dg-do run { target aarch64_sve_hw } } */
> +/* { dg-options "-Ofast -fno-schedule-insns -fno-reorder-blocks 
> -fno-schedule-insns2 --param aarch64-autovec-preference=asimd-only" } */
> +/* { dg-require-effective-target lp64 } */
> +
> +#include <stdio.h>
> +
> +#define N 640
> +#ifndef TYPE
> +#define TYPE float
> +#endif
> +#ifndef FMT
> +#define FMT ".6f"
> +#endif
> +
> +
> +TYPE a[N] = {0};
> +TYPE b[N] = {0};
> +
> +char *curr_test;
> +
> +/* Macro to define a function with a specific comparison */
> +#define DEFINE_TEST_FUNC(NAME, OP)            \
> +  __attribute__((noipa))      \
> +  void NAME(void) {                           \
> +    for (int i = 0; i < N; i++) {             \
> +      b[i] += a[i];                           \
> +      if (a[i] OP 0)                          \
> +        break;                                \
> +    }                                         \
> +  }
> +
> +/* Generate the six comparisons functions using the macro.  */
> +DEFINE_TEST_FUNC(f1, >)
> +DEFINE_TEST_FUNC(f2, >=)
> +DEFINE_TEST_FUNC(f3, ==)
> +DEFINE_TEST_FUNC(f4, !=)
> +DEFINE_TEST_FUNC(f5, <)
> +DEFINE_TEST_FUNC(f6, <=)
> +
> +__attribute__((noreturn))
> +static inline void __abort_trace (const char *m, int i, TYPE result, TYPE 
> expected)
> +{
> +   printf ("*** [%s] FAIL AT %s:%d in %s - expected %" FMT " but got %" FMT 
> " at pos %d\n",
> +           m, __FILE__, __LINE__, curr_test, expected, result, i);
> +   __builtin_abort ();
> +}
> +
> +/* Array setup macro.  */
> +#define RESET_ARRAYS(_aval, _idx, _force, _bval)         \
> +  do {                                                   \
> +    _Pragma("GCC novector") \
> +    for (int i = 0; i < N; ++i) {                        \
> +      a[i] = _aval;                                      \
> +      b[i] = _bval;                                      \
> +    }                                                    \
> +    if (_idx >= 0 && _idx < N)                           \
> +      a[_idx] = _force;                                  \
> +  } while (0)
> +
> +/* Value check macros.  */
> +#define CHECK_EQ(_i, _val)                        \
> +  do {                                            \
> +    if (b[_i] != _val)                            \
> +      __abort_trace ("single", _i, b[_i], _val);  \
> +  } while (0)
> +
> +#define CHECK_RANGE_EQ(_start, _end, _val)               \
> +  do {                                                   \
> +    _Pragma("GCC novector") \
> +    for (int i = _start; i < _end; ++i)                  \
> +      if (b[i] != _val)                                  \
> +        __abort_trace ("range", i, b[i], _val);          \
> +  } while (0)
> +
> +#define str(s) #s
> +#define TEST_FUNC(_func, _aval, _idx, _force, _bval, _check_stmt)  \
> +  do {                                                             \
> +    curr_test = str (_func);                                       \
> +    RESET_ARRAYS((_aval), (_idx), (_force), (_bval));              \
> +    _func();                                                       \
> +    _check_stmt;                                                   \
> +  } while (0)
> +
> +int main(void) {
> +  /* Break on random intervals.  */
> +  TEST_FUNC (f1, 1, 0, 1, 10, CHECK_EQ (0, 11); CHECK_EQ (1, 10));
> +  TEST_FUNC (f2, -1, 5, 0, 10, CHECK_EQ (0, 9); CHECK_EQ (5, 10));
> +  TEST_FUNC (f3, 3, 3, 0, 0, CHECK_EQ (0, 3); CHECK_EQ (3, 0));
> +  TEST_FUNC (f4, 0, 4, 1, 1, CHECK_EQ (4, 2); CHECK_EQ (5, 1));
> +  TEST_FUNC (f5, 1, 6, -1, 5, CHECK_EQ (6, 4); CHECK_EQ (7, 5));
> +  TEST_FUNC (f6, 2, 10, 0, 7, CHECK_EQ (10, 7); CHECK_EQ (11, 7));
> +
> +  /* Break on last iteration.  */
> +  TEST_FUNC (f1, 0, N-1, 1, 1,
> +    CHECK_RANGE_EQ (0, N-1, 1); CHECK_EQ (N-1, 2));
> +
> +  TEST_FUNC (f2, -5, N-1, 0, 9,
> +    CHECK_RANGE_EQ (0, N-1, 4); CHECK_EQ (N-1, 9));
> +
> +  TEST_FUNC (f3, 2, N-1, 0, 0,
> +    CHECK_RANGE_EQ(0, N-1, 2); CHECK_EQ (N-1, 0));
> +
> +  TEST_FUNC (f4, 0, N-1, 2, 1,
> +    CHECK_RANGE_EQ (0, N-1, 1); CHECK_EQ (N-1, 3));
> +
> +  TEST_FUNC (f5, 2, N-1, -3, 6,
> +    CHECK_RANGE_EQ (0, N-1, 8); CHECK_EQ (N-1, 3));
> +
> +  TEST_FUNC (f6, 5, N-1, 0, 7,
> +    CHECK_RANGE_EQ (0, N-1, 12); CHECK_EQ (N-1, 7));
> +
> +  /* Condition never met — full loop executes.  */
> +  TEST_FUNC (f1, 0, -1, 0, 2,
> +    CHECK_RANGE_EQ (0, N, 2));
> +
> +  TEST_FUNC (f2, -2, -1, 0, 5,
> +    CHECK_RANGE_EQ (0, N, 3));
> +
> +  TEST_FUNC (f3, 1, -1, 0, 0,
> +    CHECK_RANGE_EQ (0, N, 1));
> +
> +  TEST_FUNC (f4, 0, -1, 0, 7,
> +    CHECK_RANGE_EQ (0, N, 7));
> +
> +  TEST_FUNC (f5, 1, -1, 0, 4,
> +    CHECK_RANGE_EQ (0, N, 5));
> +
> +  TEST_FUNC (f6, 5, -1, 0, 3,
> +    CHECK_RANGE_EQ (0, N, 8));
> +
> +  return 0;
> +}
> diff --git a/gcc/testsuite/gcc.target/aarch64/vect-early-break-cbranch.c 
> b/gcc/testsuite/gcc.target/aarch64/vect-early-break-cbranch.c
> index 
> 673b781eb6d092f6311409797b20a971f4fae247..ca4ef498485f68dbb8a178750db3f552cf7a66d0
>  100644
> --- a/gcc/testsuite/gcc.target/aarch64/vect-early-break-cbranch.c
> +++ b/gcc/testsuite/gcc.target/aarch64/vect-early-break-cbranch.c
> @@ -50,7 +50,6 @@ void f2 ()
> /*
> ** f3:
> ** ...
> -** cmeq v[0-9]+.4s, v[0-9]+.4s, #0
> ** umaxp v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s
> ** fmov x[0-9]+, d[0-9]+
> ** cbn?z x[0-9]+, \.L[0-9]+
> @@ -69,7 +68,6 @@ void f3 ()
> /*
> ** f4:
> ** ...
> -** cmtst v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s
> ** umaxp v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s
> ** fmov x[0-9]+, d[0-9]+
> ** cbn?z x[0-9]+, \.L[0-9]+
> diff --git a/gcc/testsuite/gcc.target/aarch64/vect-early-break-cbranch_2.c 
> b/gcc/testsuite/gcc.target/aarch64/vect-early-break-cbranch_2.c
> new file mode 100644
> index 
> 0000000000000000000000000000000000000000..d5cb1946873f5e720c6e12e0dd4991582764f18f
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/vect-early-break-cbranch_2.c
> @@ -0,0 +1,105 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O3 -fno-schedule-insns -fno-reorder-blocks 
> -fno-schedule-insns2 --param aarch64-autovec-preference=asimd-only" } */
> +/* { dg-final { check-function-bodies "**" "" "" { target lp64 } } } */
> +
> +#pragma GCC target "+sve"
> +
> +#define N 640
> +int a[N] = {0};
> +int b[N] = {0};
> +/*
> +** f1:
> +** ...
> +** cmpgt p[0-9]+.s, p[0-9]+/z, z[0-9]+.s, #0
> +** b(\.?eq|\.none) \.L[0-9]+
> +** ...
> +*/
> +void f1 ()
> +{
> +  for (int i = 0; i < N; i++)
> +    {
> +      b[i] += a[i];
> +      if (a[i] > 0)
> + break;
> +    }
> +}
> +/*
> +** f2:
> +** ...
> +** cmpge p[0-9]+.s, p[0-9]+/z, z[0-9]+.s, #0
> +** b(\.?eq|\.none) \.L[0-9]+
> +** ...
> +*/
> +void f2 ()
> +{
> +  for (int i = 0; i < N; i++)
> +    {
> +      b[i] += a[i];
> +      if (a[i] >= 0)
> + break;
> +    }
> +}
> +/*
> +** f3:
> +** ...
> +** cmpeq p[0-9]+.s, p[0-9]+/z, z[0-9]+.s, #0
> +** b(\.?eq|\.none) \.L[0-9]+
> +** ...
> +*/
> +void f3 ()
> +{
> +  for (int i = 0; i < N; i++)
> +    {
> +      b[i] += a[i];
> +      if (a[i] == 0)
> + break;
> +    }
> +}
> +/*
> +** f4:
> +** ...
> +** cmpne p[0-9]+.s, p[0-9]+/z, z[0-9]+.s, #0
> +** b(\.?eq|\.none) \.L[0-9]+
> +** ...
> +*/
> +void f4 ()
> +{
> +  for (int i = 0; i < N; i++)
> +    {
> +      b[i] += a[i];
> +      if (a[i] != 0)
> + break;
> +    }
> +}
> +/*
> +** f5:
> +** ...
> +** cmplt p[0-9]+.s, p7/z, z[0-9]+.s, #0
> +** b(\.?eq|\.none) .L[0-9]+
> +** ...
> +*/
> +void f5 ()
> +{
> +  for (int i = 0; i < N; i++)
> +    {
> +      b[i] += a[i];
> +      if (a[i] < 0)
> + break;
> +    }
> +}
> +/*
> +** f6:
> +** ...
> +** cmple p[0-9]+.s, p[0-9]+/z, z[0-9]+.s, #0
> +** b(\.?eq|\.none) \.L[0-9]+
> +** ...
> +*/
> +void f6 ()
> +{
> +  for (int i = 0; i < N; i++)
> +    {
> +      b[i] += a[i];
> +      if (a[i] <= 0)
> + break;
> +    }
> +}
> diff --git a/gcc/testsuite/gcc.target/aarch64/vect-early-break-cbranch_3.c 
> b/gcc/testsuite/gcc.target/aarch64/vect-early-break-cbranch_3.c
> new file mode 100644
> index 
> 0000000000000000000000000000000000000000..9312db675eb428fc2fb775ec45e9e71e636fabdf
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/vect-early-break-cbranch_3.c
> @@ -0,0 +1,110 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O3 -fno-schedule-insns -fno-reorder-blocks 
> -fno-schedule-insns2 --param aarch64-autovec-preference=asimd-only" } */
> +/* { dg-final { check-function-bodies "**" "" "" { target lp64 } } } */
> +
> +#pragma GCC target "+sve"
> +
> +#define N 640
> +float a[N] = {0};
> +float b[N] = {0};
> +
> +/*
> +** f1:
> +** ...
> +** fcmgt p[0-9]+.s, p[0-9]+/z, z[0-9]+.s, #0.0
> +** ptest p[0-9]+, p[0-9]+\.b
> +** b(\.?eq|\.none) \.L[0-9]+
> +** ...
> +*/
> +void f1 ()
> +{
> +  for (int i = 0; i < N; i++)
> +    {
> +      b[i] += a[i];
> +      if (a[i] > 0)
> + break;
> +    }
> +}
> +/*
> +** f2:
> +** ...
> +** fcmge p[0-9]+.s, p[0-9]+/z, z[0-9]+.s, #0.0
> +** ptest p[0-9]+, p[0-9]+\.b
> +** b(\.?eq|\.none) \.L[0-9]+
> +** ...
> +*/
> +void f2 ()
> +{
> +  for (int i = 0; i < N; i++)
> +    {
> +      b[i] += a[i];
> +      if (a[i] >= 0)
> + break;
> +    }
> +}
> +/*
> +** f3:
> +** ...
> +** cmpeq p[0-9]+.s, p[0-9]+/z, z[0-9]+.s, #0
> +** b(\.?eq|\.none) \.L[0-9]+
> +** ...
> +*/
> +void f3 ()
> +{
> +  for (int i = 0; i < N; i++)
> +    {
> +      b[i] += a[i];
> +      if (a[i] == 0)
> + break;
> +    }
> +}
> +/*
> +** f4:
> +** ...
> +** cmpne p[0-9]+.s, p[0-9]+/z, z[0-9]+.s, #0
> +** b(\.?eq|\.none) \.L[0-9]+
> +** ...
> +*/
> +void f4 ()
> +{
> +  for (int i = 0; i < N; i++)
> +    {
> +      b[i] += a[i];
> +      if (a[i] != 0)
> + break;
> +    }
> +}
> +/*
> +** f5:
> +** ...
> +** fcmlt p[0-9]+.s, p7/z, z[0-9]+.s, #0.0
> +** ptest p[0-9]+, p[0-9]+\.b
> +** b(\.?eq|\.none) .L[0-9]+
> +** ...
> +*/
> +void f5 ()
> +{
> +  for (int i = 0; i < N; i++)
> +    {
> +      b[i] += a[i];
> +      if (a[i] < 0)
> + break;
> +    }
> +}
> +/*
> +** f6:
> +** ...
> +** fcmle p[0-9]+.s, p[0-9]+/z, z[0-9]+.s, #0.0
> +** ptest p[0-9]+, p[0-9]+\.b
> +** b(\.?eq|\.none) \.L[0-9]+
> +** ...
> +*/
> +void f6 ()
> +{
> +  for (int i = 0; i < N; i++)
> +    {
> +      b[i] += a[i];
> +      if (a[i] <= 0)
> + break;
> +    }
> +}
> 
> 
> -- 
> <rb20053.patch>

Reply via email to