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)