On Wed, 26 Nov 2025, Tamar Christina wrote:

> Hi All,
> 
> In emit_cmp_and_jump_insns I tried to detect if the operation is signed or
> unsigned in order to conver the condition code into an unsigned code.
> 
> However I did this based on the incoming tree compare, which is done on the
> boolean result.  Since booleans are always signed in tree the result was that
> we never used an unsigned compare when needed.
> 
> This checks one of the arguments of the compare instead.
> 
> Bootstrapped Regtested on aarch64-none-linux-gnu,
> arm-none-linux-gnueabihf, x86_64-pc-linux-gnu
> -m32, -m64 and no issues.
> Ok for master?
> 
> Ok for master?

OK.

> Thanks,
> Tamar
> 
> gcc/ChangeLog:
> 
>       * optabs.cc (emit_cmp_and_jump_insns): Check argument instead of result.
> 
> gcc/testsuite/ChangeLog:
> 
>       PR tree-optimization/122861
>       * gcc.target/aarch64/sve/vect-early-break-cbranch_10.c: New test.
>       * gcc.target/aarch64/sve/vect-early-break-cbranch_11.c: New test.
>       * gcc.target/aarch64/sve/vect-early-break-cbranch_12.c: New test.
>       * gcc.target/aarch64/sve/vect-early-break-cbranch_13.c: New test.
>       * gcc.target/aarch64/sve/vect-early-break-cbranch_14.c: New test.
>       * gcc.target/aarch64/sve/vect-early-break-cbranch_15.c: New test.
>       * gcc.target/aarch64/sve/vect-early-break-cbranch_9.c: New test.
>       * gcc.target/aarch64/vect-early-break-cbranch_4.c: New test.
>       * gcc.target/aarch64/vect-early-break-cbranch_5.c: New test.
> 
> ---
> diff --git a/gcc/optabs.cc b/gcc/optabs.cc
> index 
> 10989a29c514e70ff80bee95de48215721ca2baa..9882aac0ba9a377fcedfab2beb5871159e39bd02
>  100644
> --- a/gcc/optabs.cc
> +++ b/gcc/optabs.cc
> @@ -4902,8 +4902,10 @@ emit_cmp_and_jump_insns (rtx x, rtx y, enum rtx_code 
> comparison, rtx size,
>             class expand_operand ops[5];
>             rtx_insn *tmp = NULL;
>             start_sequence ();
> -           rtx op0c = expand_normal (gimple_assign_rhs1 (def_stmt));
> -           rtx op1c = expand_normal (gimple_assign_rhs2 (def_stmt));
> +           tree t_op0 = gimple_assign_rhs1 (def_stmt);
> +           tree t_op1 = gimple_assign_rhs2 (def_stmt);
> +           rtx op0c = expand_normal (t_op0);
> +           rtx op1c = expand_normal (t_op1);
>             machine_mode mode2 = GET_MODE (op0c);
>  
>             int nops = masked_op ? 3 : (len_op ? 5 : 2);
> @@ -4929,7 +4931,7 @@ emit_cmp_and_jump_insns (rtx x, rtx y, enum rtx_code 
> comparison, rtx size,
>                                       GET_MODE (len_bias_rtx));
>               }
>  
> -           int unsignedp2 = TYPE_UNSIGNED (TREE_TYPE (val));
> +           int unsignedp2 = TYPE_UNSIGNED (TREE_TYPE (t_op0));
>             auto inner_code = gimple_assign_rhs_code (def_stmt);
>             rtx test2 = NULL_RTX;
>  
> diff --git 
> a/gcc/testsuite/gcc.target/aarch64/sve/vect-early-break-cbranch_10.c 
> b/gcc/testsuite/gcc.target/aarch64/sve/vect-early-break-cbranch_10.c
> new file mode 100644
> index 
> 0000000000000000000000000000000000000000..e74f1fa5bd0dc4a3c0790e27658e5e1bcfb4c2c8
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/sve/vect-early-break-cbranch_10.c
> @@ -0,0 +1,132 @@
> +/* { dg-do run { target aarch64_sve_hw } } */
> +/* { dg-options "-O3 --param aarch64-autovec-preference=asimd-only" } */
> +/* { dg-require-effective-target lp64 } */
> +
> +#include <stdio.h>
> +
> +#define N 640
> +#ifndef TYPE
> +#define TYPE unsigned int
> +#endif
> +#ifndef FMT
> +#define FMT "u"
> +#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, 6, 5, 0, 10, CHECK_EQ (0, 16); 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, 2, 6, 0, 5, CHECK_EQ (6, 5); CHECK_EQ (7, 7));
> +  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, 0, N-1, 0, 4,
> +    CHECK_RANGE_EQ (0, N-1, 4); CHECK_EQ (N-1, 4));
> +
> +  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, 4, N-1, 1, 6,
> +    CHECK_RANGE_EQ (0, N-1, 10); CHECK_EQ (N-1, 7));
> +
> +  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, 0, -1, 0, 3,
> +    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_11.c 
> b/gcc/testsuite/gcc.target/aarch64/sve/vect-early-break-cbranch_11.c
> new file mode 100644
> index 
> 0000000000000000000000000000000000000000..72423279f4c61f8a6f51633635a2e9e834b6cde0
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/sve/vect-early-break-cbranch_11.c
> @@ -0,0 +1,132 @@
> +/* { dg-do run { target aarch64_sve_hw } } */
> +/* { dg-options "-O3 --param aarch64-autovec-preference=sve-only" } */
> +/* { dg-require-effective-target lp64 } */
> +
> +#include <stdio.h>
> +
> +#define N 640
> +#ifndef TYPE
> +#define TYPE unsigned int
> +#endif
> +#ifndef FMT
> +#define FMT "u"
> +#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, 6, 5, 0, 10, CHECK_EQ (0, 16); 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, 2, 6, 0, 5, CHECK_EQ (6, 5); CHECK_EQ (7, 7));
> +  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, 0, N-1, 0, 4,
> +    CHECK_RANGE_EQ (0, N-1, 4); CHECK_EQ (N-1, 4));
> +
> +  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, 4, N-1, 1, 6,
> +    CHECK_RANGE_EQ (0, N-1, 10); CHECK_EQ (N-1, 7));
> +
> +  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, 0, -1, 0, 3,
> +    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_12.c 
> b/gcc/testsuite/gcc.target/aarch64/sve/vect-early-break-cbranch_12.c
> new file mode 100644
> index 
> 0000000000000000000000000000000000000000..e2290e9161cf0c095daa6bbddd8a6a061ac5bfe7
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/sve/vect-early-break-cbranch_12.c
> @@ -0,0 +1,132 @@
> +/* { dg-do run { target aarch64_sve_hw } } */
> +/* { dg-options "-O3 --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_13.c 
> b/gcc/testsuite/gcc.target/aarch64/sve/vect-early-break-cbranch_13.c
> new file mode 100644
> index 
> 0000000000000000000000000000000000000000..eb2295f8ea939c8b136c4ee39b3004b9d067232b
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/sve/vect-early-break-cbranch_13.c
> @@ -0,0 +1,132 @@
> +/* { dg-do run { target aarch64_sve_hw } } */
> +/* { dg-options "-O3 --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_14.c 
> b/gcc/testsuite/gcc.target/aarch64/sve/vect-early-break-cbranch_14.c
> new file mode 100644
> index 
> 0000000000000000000000000000000000000000..5cc4d6a3858dbe050b611df75141f618ca2e50b9
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/sve/vect-early-break-cbranch_14.c
> @@ -0,0 +1,147 @@
> +/* { dg-do run { target aarch64_sve_hw } } */
> +/* { dg-options "-Ofast --param aarch64-autovec-preference=asimd-only" } */
> +/* { dg-require-effective-target lp64 } */
> +
> +#include <stdio.h>
> +#include <math.h>
> +
> +#define N 640
> +#ifndef TYPE
> +#define TYPE double
> +#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.0))
> +      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.0, 0, 1.0, 10.0, CHECK_EQ(0, 11.0); CHECK_EQ(1, 10.0));
> +  TEST_FUNC(f2, -1.0, 5, 0.0, 10.0, CHECK_EQ(0, 9.0); CHECK_EQ(5, 10.0));
> +  TEST_FUNC(f3, 3.0, 3, 0.0, 0.0, CHECK_EQ(0, 3.0); CHECK_EQ(3, 0.0));
> +  TEST_FUNC(f4, 0.0, 4, 1.0, 1.0, CHECK_EQ(4, 2.0); CHECK_EQ(5, 1.0));
> +  TEST_FUNC(f5, 1.0, 6, -1.0, 5.0, CHECK_EQ(6, 4.0); CHECK_EQ(7, 5.0));
> +  TEST_FUNC(f6, 2.0, 10, 0.0, 7.0, CHECK_EQ(10, 7.0); CHECK_EQ(11, 7.0));
> +
> +  /* Break on last iteration.  */
> +  TEST_FUNC(f1, 0.0, N - 1, 1.0, 1.0,
> +    CHECK_RANGE_EQ(0, N - 1, 1.0); CHECK_EQ(N - 1, 2.0));
> +
> +  TEST_FUNC(f2, -5.0, N - 1, 0.0, 9.0,
> +    CHECK_RANGE_EQ(0, N - 1, 4.0); CHECK_EQ(N - 1, 9.0));
> +
> +  TEST_FUNC(f3, 2.0, N - 1, 0.0, 0.0,
> +    CHECK_RANGE_EQ(0, N - 1, 2.0); CHECK_EQ(N - 1, 0.0));
> +
> +  TEST_FUNC(f4, 0.0, N - 1, 2.0, 1.0,
> +    CHECK_RANGE_EQ(0, N - 1, 1.0); CHECK_EQ(N - 1, 3.0));
> +
> +  TEST_FUNC(f5, 2.0, N - 1, -3.0, 6.0,
> +    CHECK_RANGE_EQ(0, N - 1, 8.0); CHECK_EQ(N - 1, 3.0));
> +
> +  TEST_FUNC(f6, 5.0, N - 1, 0.0, 7.0,
> +    CHECK_RANGE_EQ(0, N - 1, 12.0); CHECK_EQ(N - 1, 7.0));
> +
> +  /* Condition never met — full loop executes.  */
> +  TEST_FUNC(f1, 0.0, -1, 0.0, 2.0,
> +    CHECK_RANGE_EQ(0, N, 2.0));
> +
> +  TEST_FUNC(f2, -2.0, -1, 0.0, 5.0,
> +    CHECK_RANGE_EQ(0, N, 3.0));
> +
> +  TEST_FUNC(f3, 1.0, -1, 0.0, 0.0,
> +    CHECK_RANGE_EQ(0, N, 1.0));
> +
> +  TEST_FUNC(f4, 0.0, -1, 0.0, 7.0,
> +    CHECK_RANGE_EQ(0, N, 7.0));
> +
> +  TEST_FUNC(f5, 1.0, -1, 0.0, 4.0,
> +    CHECK_RANGE_EQ(0, N, 5.0));
> +
> +  TEST_FUNC(f6, 5.0, -1, 0.0, 3.0,
> +    CHECK_RANGE_EQ(0, N, 8.0));
> +
> +#if !defined(__FAST_MATH__)
> +  /* Unordered break (NAN in a[i]) */
> +  TEST_FUNC(f7, 1.0, 123, NAN, 2.0,
> +    CHECK_RANGE_EQ(0, 123, 3.0); CHECK_EQ(123, NAN));
> +#endif
> +
> +  return 0;
> +}
> diff --git 
> a/gcc/testsuite/gcc.target/aarch64/sve/vect-early-break-cbranch_15.c 
> b/gcc/testsuite/gcc.target/aarch64/sve/vect-early-break-cbranch_15.c
> new file mode 100644
> index 
> 0000000000000000000000000000000000000000..3dd7a60225e0aad2850a22fa6fc0a1330473aa86
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/sve/vect-early-break-cbranch_15.c
> @@ -0,0 +1,132 @@
> +/* { dg-do run { target aarch64_sve_hw } } */
> +/* { dg-options "-Ofast --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_9.c 
> b/gcc/testsuite/gcc.target/aarch64/sve/vect-early-break-cbranch_9.c
> new file mode 100644
> index 
> 0000000000000000000000000000000000000000..ec4f7a647c658d579f7793a796ad7eda2a02effc
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/sve/vect-early-break-cbranch_9.c
> @@ -0,0 +1,102 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O3 -fno-schedule-insns -fno-reorder-blocks 
> -fno-schedule-insns2" } */
> +/* { dg-final { check-function-bodies "**" "" "" { target lp64 } } } */
> +#define N 640
> +unsigned int a[N] = {0};
> +unsigned int b[N] = {0};
> +/*
> +** f1:
> +**   ...
> +**   cmphi   p[0-9]+.s, p[0-9]+/z, z[0-9]+.s, #1
> +**   b(\.?eq|\.none) \.L[0-9]+
> +**   ...
> +*/
> +void f1 ()
> +{
> +  for (int i = 0; i < N; i++)
> +    {
> +      b[i] += a[i];
> +      if (a[i] > 1)
> +     break;
> +    }
> +}
> +/*
> +** f2:
> +**   ...
> +**   cmphi   p[0-9]+.s, p[0-9]+/z, z[0-9]+.s, #1
> +**   b(\.?eq|\.none) \.L[0-9]+
> +**   ...
> +*/
> +void f2 ()
> +{
> +  for (int i = 0; i < N; i++)
> +    {
> +      b[i] += a[i];
> +      if (a[i] >= 2)
> +     break;
> +    }
> +}
> +/*
> +** f3:
> +**   ...
> +**   cmpeq   p[0-9]+.s, p[0-9]+/z, z[0-9]+.s, #1
> +**   b(\.?eq|\.none) \.L[0-9]+
> +**   ...
> +*/
> +void f3 ()
> +{
> +  for (int i = 0; i < N; i++)
> +    {
> +      b[i] += a[i];
> +      if (a[i] == 1)
> +     break;
> +    }
> +}
> +/*
> +** f4:
> +**   ...
> +**   cmpne   p[0-9]+.s, p[0-9]+/z, z[0-9]+.s, #1
> +**   b(\.?eq|\.none) \.L[0-9]+
> +**   ...
> +*/
> +void f4 ()
> +{
> +  for (int i = 0; i < N; i++)
> +    {
> +      b[i] += a[i];
> +      if (a[i] != 1)
> +     break;
> +    }
> +}
> +/*
> +** f5:
> +**   ...
> +**   cmpls   p[0-9]+.s, p7/z, z[0-9]+.s, #1
> +**   b(\.?eq|\.none) .L[0-9]+
> +**   ...
> +*/
> +void f5 ()
> +{
> +  for (int i = 0; i < N; i++)
> +    {
> +      b[i] += a[i];
> +      if (a[i] < 2)
> +     break;
> +    }
> +}
> +/*
> +** f6:
> +**   ...
> +**   cmpls   p[0-9]+.s, p[0-9]+/z, z[0-9]+.s, #1
> +**   b(\.?eq|\.none) \.L[0-9]+
> +**   ...
> +*/
> +void f6 ()
> +{
> +  for (int i = 0; i < N; i++)
> +    {
> +      b[i] += a[i];
> +      if (a[i] <= 1)
> +     break;
> +    }
> +}
> diff --git a/gcc/testsuite/gcc.target/aarch64/vect-early-break-cbranch_4.c 
> b/gcc/testsuite/gcc.target/aarch64/vect-early-break-cbranch_4.c
> new file mode 100644
> index 
> 0000000000000000000000000000000000000000..a49e7963cfa1afdce4bb1bf33224a1d79eb7b874
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/vect-early-break-cbranch_4.c
> @@ -0,0 +1,122 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O3 -fno-schedule-insns -fno-reorder-blocks 
> -fno-schedule-insns2" } */
> +/* { dg-final { check-function-bodies "**" "" "" { target lp64 } } } */
> +
> +#pragma GCC target "+nosve"
> +
> +#define N 640
> +unsigned int a[N] = {0};
> +unsigned int b[N] = {0};
> +
> +
> +/*
> +** f1:
> +**   ...
> +**   cmhi    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]+
> +**   ...
> +*/
> +void f1 ()
> +{
> +  for (int i = 0; i < N; i++)
> +    {
> +      b[i] += a[i];
> +      if (a[i] > 1)
> +     break;
> +    }
> +}
> +
> +/*
> +** f2:
> +**   ...
> +**   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]+
> +**   ...
> +*/
> +void f2 ()
> +{
> +  for (int i = 0; i < N; i++)
> +    {
> +      b[i] += a[i];
> +      if (a[i] >= 1)
> +     break;
> +    }
> +}
> +
> +/*
> +** f3:
> +**   ...
> +**   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]+
> +**   ...
> +*/
> +void f3 ()
> +{
> +  for (int i = 0; i < N; i++)
> +    {
> +      b[i] += a[i];
> +      if (a[i] == 1)
> +     break;
> +    }
> +}
> +
> +/*
> +** f4:
> +**   ...
> +**   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]+
> +**   ...
> +*/
> +void f4 ()
> +{
> +  for (int i = 0; i < N; i++)
> +    {
> +      b[i] += a[i];
> +      if (a[i] != 1)
> +     break;
> +    }
> +}
> +
> +/*
> +** f5:
> +**   ...
> +**   cmhs    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]+
> +**   ...
> +*/
> +void f5 ()
> +{
> +  for (int i = 0; i < N; i++)
> +    {
> +      b[i] += a[i];
> +      if (a[i] < 2)
> +     break;
> +    }
> +}
> +
> +/*
> +** f6:
> +**   ...
> +**   cmhs    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]+
> +**   ...
> +*/
> +void f6 ()
> +{
> +  for (int i = 0; i < N; i++)
> +    {
> +      b[i] += a[i];
> +      if (a[i] <= 2)
> +     break;
> +    }
> +}
> diff --git a/gcc/testsuite/gcc.target/aarch64/vect-early-break-cbranch_5.c 
> b/gcc/testsuite/gcc.target/aarch64/vect-early-break-cbranch_5.c
> new file mode 100644
> index 
> 0000000000000000000000000000000000000000..c28969dde1ff24872a5c3d9c236808f215cfdaa2
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/vect-early-break-cbranch_5.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
> +unsigned int a[N] = {0};
> +unsigned int b[N] = {0};
> +/*
> +** f1:
> +**   ...
> +**   cmphi   p[0-9]+.s, p[0-9]+/z, z[0-9]+.s, #2
> +**   b(\.?eq|\.none) \.L[0-9]+
> +**   ...
> +*/
> +void f1 ()
> +{
> +  for (int i = 0; i < N; i++)
> +    {
> +      b[i] += a[i];
> +      if (a[i] > 2)
> +     break;
> +    }
> +}
> +/*
> +** f2:
> +**   ...
> +**   cmphi   p[0-9]+.s, p[0-9]+/z, z[0-9]+.s, #1
> +**   b(\.?eq|\.none) \.L[0-9]+
> +**   ...
> +*/
> +void f2 ()
> +{
> +  for (int i = 0; i < N; i++)
> +    {
> +      b[i] += a[i];
> +      if (a[i] >= 2)
> +     break;
> +    }
> +}
> +/*
> +** f3:
> +**   ...
> +**   cmpeq   p[0-9]+.s, p[0-9]+/z, z[0-9]+.s, #1
> +**   b(\.?eq|\.none) \.L[0-9]+
> +**   ...
> +*/
> +void f3 ()
> +{
> +  for (int i = 0; i < N; i++)
> +    {
> +      b[i] += a[i];
> +      if (a[i] == 1)
> +     break;
> +    }
> +}
> +/*
> +** f4:
> +**   ...
> +**   cmpne   p[0-9]+.s, p[0-9]+/z, z[0-9]+.s, #1
> +**   b(\.?eq|\.none) \.L[0-9]+
> +**   ...
> +*/
> +void f4 ()
> +{
> +  for (int i = 0; i < N; i++)
> +    {
> +      b[i] += a[i];
> +      if (a[i] != 1)
> +     break;
> +    }
> +}
> +/*
> +** f5:
> +**   ...
> +**   cmpls   p[0-9]+.s, p7/z, z[0-9]+.s, #1
> +**   b(\.?eq|\.none) .L[0-9]+
> +**   ...
> +*/
> +void f5 ()
> +{
> +  for (int i = 0; i < N; i++)
> +    {
> +      b[i] += a[i];
> +      if (a[i] < 2)
> +     break;
> +    }
> +}
> +/*
> +** f6:
> +**   ...
> +**   cmpls   p[0-9]+.s, p[0-9]+/z, z[0-9]+.s, #1
> +**   b(\.?eq|\.none) \.L[0-9]+
> +**   ...
> +*/
> +void f6 ()
> +{
> +  for (int i = 0; i < N; i++)
> +    {
> +      b[i] += a[i];
> +      if (a[i] <= 1)
> +     break;
> +    }
> +}
> 
> 
> 

-- 
Richard Biener <[email protected]>
SUSE Software Solutions Germany GmbH,
Frankenstrasse 146, 90461 Nuernberg, Germany;
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)

Reply via email to