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?

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;
+    }
+}


-- 
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;
+    }
+}

Reply via email to