> -----Original Message-----
> From: Tejas Belagod <[email protected]>
> Sent: 04 November 2025 12:28
> To: [email protected]
> Cc: Tejas Belagod <[email protected]>; Tamar Christina
> <[email protected]>; [email protected]; [email protected]
> Subject: [PATCH v4 1/3] AArch64: Support C/C++ operations on svbool_t
> 
> Support a subset of C/C++ operations (bitwise, conditional etc.) on svbool_t.
> 
> gcc/ChangeLog:
> 
>       * c-family/c-common.cc (c_build_vec_convert): Support vector
> boolean
>       types for __builtin_convertvector ().
>       * c/c-typeck.cc (build_binary_op): Support vector boolean types.
>       * cp/typeck.cc (cp_build_binary_op): Likewise.
>       * config/aarch64/aarch64-sve-builtins.cc (register_builtin_types):
> Make
>       SVE vector boolean type equivalent to GNU vectors.
>       * config/aarch64/aarch64-sve.md (<optab>vnx16bivnx16qi2,
>       truncvnx16qivnx16bi2, vec_cmp<mode><mode>): New patterns to
> support
>       additional operations on predicate modes.
>       * config/aarch64/aarch64.cc (aarch64_valid_vector_boolean_op):
> New.
>       (aarch64_invalid_unary_op): Consider vector bool types.
>       (aarch64_invalid_binary_op): Likewise.
>       (aarch64_convert_to_type): Define target hook and handle standard
> to
>       non-standard bool conversion.
>       * cp/call.cc (build_conditional_expr): Support vector booleans.
>       * cp/cvt.cc (ocp_convert): Call target hook to resolve conversion
>       between standard and non-standard booleans.
> 
> gcc/testsuite/ChangeLog:
> 
>       * gcc.target/aarch64/sve/acle/general/cops_bool.c: New.
> ---
>  gcc/c-family/c-common.cc                      |   4 +-
>  gcc/c/c-typeck.cc                             |  26 +-
>  gcc/config/aarch64/aarch64-sve-builtins.cc    |   5 +-
>  gcc/config/aarch64/aarch64-sve.md             |  68 ++++
>  gcc/config/aarch64/aarch64.cc                 |  93 +++++-
>  gcc/cp/call.cc                                |   3 +-
>  gcc/cp/cvt.cc                                 |  11 +-
>  gcc/cp/typeck.cc                              |  26 +-
>  .../aarch64/sve/acle/general/cops_bool.c      | 301 ++++++++++++++++++
>  9 files changed, 503 insertions(+), 34 deletions(-)
>  create mode 100644
> gcc/testsuite/gcc.target/aarch64/sve/acle/general/cops_bool.c
> 
> diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
> index f2eed033706..1c382540b38 100644
> --- a/gcc/c-family/c-common.cc
> +++ b/gcc/c-family/c-common.cc
> @@ -1312,6 +1312,7 @@ c_build_vec_convert (location_t loc1, tree expr,
> location_t loc2, tree type,
> 
>    if (!gnu_vector_type_p (TREE_TYPE (expr))
>        || (!VECTOR_INTEGER_TYPE_P (TREE_TYPE (expr))
> +       && !VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (expr))
>         && !VECTOR_FLOAT_TYPE_P (TREE_TYPE (expr))))
>      {
>        if (complain)
> @@ -1321,7 +1322,8 @@ c_build_vec_convert (location_t loc1, tree expr,
> location_t loc2, tree type,
>      }
> 
>    if (!gnu_vector_type_p (type)
> -      || (!VECTOR_INTEGER_TYPE_P (type) && !VECTOR_FLOAT_TYPE_P
> (type)))
> +      || (!VECTOR_INTEGER_TYPE_P (type) && !VECTOR_FLOAT_TYPE_P (type)
> +       && !VECTOR_BOOLEAN_TYPE_P (type)))
>      {
>        if (complain)
>       error_at (loc2, "%<__builtin_convertvector%> second argument must
> "
> diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
> index 2cef4636bd7..e1d2d1173dc 100644
> --- a/gcc/c/c-typeck.cc
> +++ b/gcc/c/c-typeck.cc
> @@ -14693,18 +14693,24 @@ build_binary_op (location_t location, enum
> tree_code code,
>           }
> 
>            /* Always construct signed integer vector type.  */
> -          intt = c_common_type_for_size (GET_MODE_BITSIZE
> -                                      (SCALAR_TYPE_MODE
> -                                       (TREE_TYPE (type0))), 0);
> -       if (!intt)
> +       if (VECTOR_BOOLEAN_TYPE_P (type0) &&
> VECTOR_BOOLEAN_TYPE_P (type1))
> +         result_type = type0;
> +       else
>           {
> -           error_at (location, "could not find an integer type "
> -                               "of the same size as %qT",
> -                     TREE_TYPE (type0));
> -           return error_mark_node;
> +           auto nelts = TYPE_VECTOR_SUBPARTS (type0);
> +
> +           intt = c_common_type_for_size (GET_MODE_BITSIZE
> +                                          (SCALAR_TYPE_MODE
> +                                             (TREE_TYPE (type0))), 0);
> +           if (!intt)
> +             {
> +               error_at (location, "could not find an integer type "
> +                                   "of the same size as %qT",
> +                         TREE_TYPE (type0));
> +               return error_mark_node;
> +             }
> +           result_type = build_opaque_vector_type (intt, nelts);
>           }
> -          result_type = build_opaque_vector_type (intt,
> -                                               TYPE_VECTOR_SUBPARTS
> (type0));
>            converted = 1;
>         ret = build_vec_cmp (resultcode, result_type, op0, op1);
>         goto return_build_binary_op;
> diff --git a/gcc/config/aarch64/aarch64-sve-builtins.cc
> b/gcc/config/aarch64/aarch64-sve-builtins.cc
> index b2b03dc8cea..dbd80cab627 100644
> --- a/gcc/config/aarch64/aarch64-sve-builtins.cc
> +++ b/gcc/config/aarch64/aarch64-sve-builtins.cc
> @@ -4691,9 +4691,6 @@ register_builtin_types ()
>             vectype = build_truth_vector_type_for_mode
> (BYTES_PER_SVE_VECTOR,
>                                                         VNx16BImode);
>             num_pr = 1;
> -           /* Leave svbool_t as indivisible for now.  We don't yet support
> -              C/C++ operators on predicates.  */
> -           TYPE_INDIVISIBLE_P (vectype) = 1;
>           }
>         else
>           {
> @@ -4710,12 +4707,12 @@ register_builtin_types ()
>                         && TYPE_ALIGN (vectype) == 128
>                         && known_eq (size, BITS_PER_SVE_VECTOR));
>             num_zr = 1;
> -           TYPE_INDIVISIBLE_P (vectype) = 0;
>           }
>         vectype = build_distinct_type_copy (vectype);
>         gcc_assert (vectype == TYPE_MAIN_VARIANT (vectype));
>         SET_TYPE_STRUCTURAL_EQUALITY (vectype);
>         TYPE_ARTIFICIAL (vectype) = 1;
> +       TYPE_INDIVISIBLE_P (vectype) = 0;
>         make_type_sizeless (vectype);
>       }
>        if (num_pr)
> diff --git a/gcc/config/aarch64/aarch64-sve.md
> b/gcc/config/aarch64/aarch64-sve.md
> index f459f63d6bb..4648aa67e0c 100644
> --- a/gcc/config/aarch64/aarch64-sve.md
> +++ b/gcc/config/aarch64/aarch64-sve.md
> @@ -3520,6 +3520,47 @@
>    }
>  )
> 
> +;; Unpredicated sign and zero extension from a boolean mode.
> +(define_expand "extend<vpred><mode>2"
> +  [(set (match_operand:SVE_ALL 0 "register_operand")
> +     (unspec:SVE_ALL
> +       [(match_operand:<VPRED> 1 "register_operand")
> +        (match_dup 2)
> +        (match_dup 3)]
> +       UNSPEC_SEL))]
> +  "TARGET_SVE"
> +  {
> +    operands[2] = CONSTM1_RTX (<MODE>mode);
> +    operands[3] = CONST0_RTX (<MODE>mode);
> +  }
> +)
> +
> +(define_expand "zero_extend<vpred><mode>2"
> +  [(set (match_operand:SVE_ALL 0 "register_operand")
> +     (unspec:SVE_ALL
> +       [(match_operand:<VPRED> 1 "register_operand")
> +        (match_dup 2)
> +        (match_dup 3)]
> +       UNSPEC_SEL))]
> +  "TARGET_SVE"
> +  {
> +    operands[2] = CONST1_RTX (<MODE>mode);
> +    operands[3] = CONST0_RTX (<MODE>mode);
> +  }
> +)
> +
> +(define_expand "trunc<mode><vpred>2"
> +  [(match_operand:<VPRED> 0 "register_operand")
> +   (match_operand:SVE_I 1 "register_operand")]
> +  "TARGET_SVE"
> +  {
> +    rtx mone = CONSTM1_RTX (<MODE>mode);
> +    rtx cmp = gen_rtx_EQ (<MODE>mode, operands[1], mone);
> +    emit_insn (gen_vec_cmp<mode><vpred> (operands[0], cmp, operands[1],
> mone));
> +    DONE;
> +  }
> +)
> +
>  ;; Predicated sign and zero extension from a narrower mode.
>  (define_insn "*<optab><SVE_PARTIAL_I:mode><SVE_HSDI:mode>2"
>    [(set (match_operand:SVE_HSDI 0 "register_operand")
> @@ -8528,6 +8569,33 @@
>    }
>  )
> 
> +(define_expand "vec_cmp<mode><mode>"
> +  [(parallel
> +    [(set (match_operand:PRED_ALL 0 "register_operand")
> +       (match_operator:PRED_ALL 1 "aarch64_equality_operator"
> +         [(match_operand:PRED_ALL 2 "register_operand")
> +          (match_operand:PRED_ALL 3 "register_operand")]))])]
> +  "TARGET_SVE"
> +  {
> +    rtx ptrue = aarch64_ptrue_reg (<MODE>mode);
> +    if (GET_CODE (operands[1]) == EQ)
> +      {
> +     rtx tmp = gen_reg_rtx (<MODE>mode);
> +     emit_insn (gen_aarch64_pred_xor<mode>_z (tmp, ptrue,
> +                                              operands[2], operands[3]));
> +     emit_insn (gen_aarch64_pred_xor<mode>_z (operands[0], ptrue,
> +                                              tmp, ptrue));
> +      }
> +    else if (GET_CODE (operands[1]) == NE)
> +      emit_insn (gen_aarch64_pred_xor<mode>_z (operands[0], ptrue,
> +                                            operands[2], operands[3]));
> +    else
> +      gcc_unreachable ();
> +
> +    DONE;
> +  }
> +)

The else and the gcc_unreachable() aren't needed since the predicate
enforces this.  But I don't mind it.

The AArch64 parts are OK.

Thanks,
Tamar

> +
>  ;; Unsigned integer comparisons.  Don't enforce an immediate range here,
> since
>  ;; it depends on the comparison; leave it to
> aarch64_expand_sve_vec_cmp_int
>  ;; instead.
> diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
> index 6f6dea67e0d..d9e428de7b8 100644
> --- a/gcc/config/aarch64/aarch64.cc
> +++ b/gcc/config/aarch64/aarch64.cc
> @@ -23006,6 +23006,24 @@ aarch64_autovectorize_vector_modes
> (vector_modes *modes, bool)
>    return flags;
>  }
> 
> +/* Implement TARGET_CONVERT_TO_TYPE.  Convert EXPR to TYPE.  */
> +
> +static tree
> +aarch64_convert_to_type (tree type, tree expr)
> +{
> +  /* If TYPE is a non-standard boolean type invented by the target, check if
> +     EXPR can be converted to TYPE.  */
> +  if (TREE_CODE (type) == BOOLEAN_TYPE
> +      && TREE_CODE (TREE_TYPE (expr)) == BOOLEAN_TYPE
> +      && !VECTOR_TYPE_P (type)
> +      && !VECTOR_TYPE_P (TREE_TYPE (expr))
> +      && TYPE_CANONICAL (type) != TYPE_CANONICAL (TREE_TYPE (expr)))
> +    return build1 (VIEW_CONVERT_EXPR, type, expr);
> +
> +  /* Use standard rules.  */
> +  return NULL_TREE;
> +}
> +
>  /* Implement TARGET_MANGLE_TYPE.  */
> 
>  static const char *
> @@ -30299,11 +30317,58 @@ aarch64_stack_protect_guard (void)
>    return NULL_TREE;
>  }
> 
> -/* Implement TARGET_INVALID_UNARY_OP.  */
> +
> +static const char *
> +aarch64_valid_vector_boolean_op (int code)
> +{
> +  switch ((enum tree_code)code)
> +    {
> +    case PREINCREMENT_EXPR:
> +      return N_ ("preincrement operation not permitted on svbool_t");
> +    case PREDECREMENT_EXPR:
> +      return N_ ("predecrement operation not permitted on svbool_t");
> +    case POSTINCREMENT_EXPR:
> +      return N_ ("postincrement operation not permitted on svbool_t");
> +    case POSTDECREMENT_EXPR:
> +      return N_ ("postdecrement operation not permitted on svbool_t");
> +    case NEGATE_EXPR:
> +      return N_ ("negation operation not permitted on svbool_t");
> +    case PLUS_EXPR:
> +      return N_ ("plus operation not permitted on svbool_t");
> +    case MINUS_EXPR:
> +      return N_ ("minus operation not permitted on svbool_t");
> +    case MULT_EXPR:
> +      return N_ ("multiply operation not permitted on svbool_t");
> +    case TRUNC_DIV_EXPR:
> +      return N_ ("divide operation not permitted on svbool_t");
> +    case LSHIFT_EXPR:
> +    case RSHIFT_EXPR:
> +      return N_ ("shift operation not permitted on svbool_t");
> +    case LT_EXPR:
> +    case LE_EXPR:
> +    case GT_EXPR:
> +    case GE_EXPR:
> +      return N_ ("only == and != operations permitted on svbool_t");
> +    case ARRAY_REF:
> +      return N_ ("subscript operation not supported on svbool_t");
> +    default:
> +      /* Operation permitted.  */
> +      return NULL;
> +    }
> +}
> +
> +/* Implement TARGET_INVALID_BINARY_OP.
> +   Return the diagnostic message string if the unary operation OP is
> +   not permitted on TYPE, NULL otherwise.  */
> 
>  static const char *
>  aarch64_invalid_unary_op (int op, const_tree type)
>  {
> +  if (VECTOR_BOOLEAN_TYPE_P (type)
> +      && !TYPE_INDIVISIBLE_P (type)
> +      && aarch64_sve::builtin_type_p (type))
> +    return aarch64_valid_vector_boolean_op (op);
> +
>    /* Reject all single-operand operations on __mfp8 except for &.  */
>    if (TYPE_MAIN_VARIANT (type) == aarch64_mfp8_type_node && op !=
> ADDR_EXPR)
>      return N_ ("operation not permitted on type %<mfloat8_t%>");
> @@ -30312,19 +30377,29 @@ aarch64_invalid_unary_op (int op, const_tree
> type)
>    return NULL;
>  }
> 
> -/* Implement TARGET_INVALID_BINARY_OP.  */
> +/* Implement TARGET_INVALID_BINARY_OP.
> +   Return the diagnostic message string if the binary operation OP is
> +   not permitted on TYPE1 and TYPE2, NULL otherwise.  */
> 
>  static const char *
> -aarch64_invalid_binary_op (int op ATTRIBUTE_UNUSED, const_tree type1,
> +aarch64_invalid_binary_op (int op, const_tree type1,
>                          const_tree type2)
>  {
>    if (VECTOR_TYPE_P (type1)
>        && VECTOR_TYPE_P (type2)
>        && !TYPE_INDIVISIBLE_P (type1)
> -      && !TYPE_INDIVISIBLE_P (type2)
> -      && (aarch64_sve::builtin_type_p (type1)
> +      && !TYPE_INDIVISIBLE_P (type2))
> +    {
> +      if ((aarch64_sve::builtin_type_p (type1)
>         != aarch64_sve::builtin_type_p (type2)))
> -    return N_("cannot combine GNU and SVE vectors in a binary operation");
> +     return N_("cannot combine GNU and SVE vectors in a binary
> operation");
> +
> +      if (aarch64_sve::builtin_type_p (type1)
> +       && aarch64_sve::builtin_type_p (type2)
> +       && VECTOR_BOOLEAN_TYPE_P (type1)
> +       && VECTOR_BOOLEAN_TYPE_P (type2))
> +     return aarch64_valid_vector_boolean_op (op);
> +    }
> 
>    /* Reject all 2-operand operations on __mfp8.  */
>    if (TYPE_MAIN_VARIANT (type1) == aarch64_mfp8_type_node
> @@ -32412,6 +32487,9 @@ aarch64_libgcc_floating_mode_supported_p
>  #undef TARGET_INVALID_BINARY_OP
>  #define TARGET_INVALID_BINARY_OP aarch64_invalid_binary_op
> 
> +#undef TARGET_INVALID_UNARY_OP
> +#define TARGET_INVALID_UNARY_OP aarch64_invalid_unary_op
> +
>  #undef TARGET_VERIFY_TYPE_CONTEXT
>  #define TARGET_VERIFY_TYPE_CONTEXT aarch64_verify_type_context
> 
> @@ -32602,6 +32680,9 @@ aarch64_libgcc_floating_mode_supported_p
>  #define TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES \
>    aarch64_autovectorize_vector_modes
> 
> +#undef TARGET_CONVERT_TO_TYPE
> +#define TARGET_CONVERT_TO_TYPE aarch64_convert_to_type
> +
>  #undef TARGET_ATOMIC_ASSIGN_EXPAND_FENV
>  #define TARGET_ATOMIC_ASSIGN_EXPAND_FENV \
>    aarch64_atomic_assign_expand_fenv
> diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
> index 77dfa7d2982..f80d597b339 100644
> --- a/gcc/cp/call.cc
> +++ b/gcc/cp/call.cc
> @@ -5902,7 +5902,8 @@ build_conditional_expr (const op_location_t &loc,
>    orig_arg3 = arg3;
> 
>    if (gnu_vector_type_p (TREE_TYPE (arg1))
> -      && VECTOR_INTEGER_TYPE_P (TREE_TYPE (arg1)))
> +      && (VECTOR_INTEGER_TYPE_P (TREE_TYPE (arg1))
> +       || VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (arg1))))
>      {
>        tree arg1_type = TREE_TYPE (arg1);
> 
> diff --git a/gcc/cp/cvt.cc b/gcc/cp/cvt.cc
> index 55be12db951..68d51b61375 100644
> --- a/gcc/cp/cvt.cc
> +++ b/gcc/cp/cvt.cc
> @@ -885,15 +885,22 @@ ocp_convert (tree type, tree expr, int convtype, int
> flags,
>         if (SCOPED_ENUM_P (intype) && (convtype & CONV_STATIC))
>           e = build_nop (ENUM_UNDERLYING_TYPE (intype), e);
>         if (complain & tf_warning)
> -         return cp_truthvalue_conversion (e, complain);
> +         e = cp_truthvalue_conversion (e, complain);
>         else
>           {
>             /* Prevent bogus -Wint-in-bool-context warnings coming
>                from c_common_truthvalue_conversion down the line.  */
>             warning_sentinel w (warn_int_in_bool_context);
>             warning_sentinel c (warn_sign_compare);
> -           return cp_truthvalue_conversion (e, complain);
> +           e = cp_truthvalue_conversion (e, complain);
>           }
> +
> +       /* Sometimes boolean types don't match if a non-standard boolean
> +          type has been invented by the target.  */
> +       if (tree e2 = targetm.convert_to_type (type, e))
> +         return e2;
> +
> +       return e;
>       }
> 
>        converted = convert_to_integer_maybe_fold (type, e, dofold);
> diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
> index dbadeb77085..2ab45f3fff6 100644
> --- a/gcc/cp/typeck.cc
> +++ b/gcc/cp/typeck.cc
> @@ -6272,18 +6272,24 @@ cp_build_binary_op (const op_location_t
> &location,
>             return error_mark_node;
>           }
> 
> -       /* Always construct signed integer vector type.  */
> -       intt = c_common_type_for_size
> -         (GET_MODE_BITSIZE (SCALAR_TYPE_MODE (TREE_TYPE (type0))),
> 0);
> -       if (!intt)
> +       if (VECTOR_BOOLEAN_TYPE_P (type0) &&
> VECTOR_BOOLEAN_TYPE_P (type1))
> +         result_type = type0;
> +       else
>           {
> -           if (complain & tf_error)
> -             error_at (location, "could not find an integer type "
> -                       "of the same size as %qT", TREE_TYPE (type0));
> -           return error_mark_node;
> +           /* Always construct signed integer vector type.  */
> +           auto intmode = SCALAR_TYPE_MODE (TREE_TYPE (type0));
> +           auto nelts = TYPE_VECTOR_SUBPARTS (type0);
> +
> +           intt = c_common_type_for_size (GET_MODE_BITSIZE (intmode), 0);
> +           if (!intt)
> +             {
> +               if (complain & tf_error)
> +                 error_at (location, "could not find an integer type "
> +                             "of the same size as %qT", TREE_TYPE
> (type0));
> +               return error_mark_node;
> +             }
> +           result_type = build_opaque_vector_type (intt, nelts);
>           }
> -       result_type = build_opaque_vector_type (intt,
> -                                               TYPE_VECTOR_SUBPARTS
> (type0));
>         return build_vec_cmp (resultcode, result_type, op0, op1);
>       }
>        build_type = boolean_type_node;
> diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general/cops_bool.c
> b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/cops_bool.c
> new file mode 100644
> index 00000000000..53017ca9fa2
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/cops_bool.c
> @@ -0,0 +1,301 @@
> +/* { dg-do run { target aarch64_sve_hw } } */
> +/* { dg-options "-O2" } */
> +
> +#include <arm_sve.h>
> +
> +#ifdef __cplusplus
> +#define BOOL bool
> +#else
> +#define BOOL _Bool
> +#endif
> +
> +#define DECL_FUNC_UNARY(name, op, intr, n) \
> +  svbool_t __attribute__((noipa)) \
> +  func_ ## name ## _unary (svbool_t a) { \
> +    return op (a); \
> +  } \
> +  void __attribute__((noipa)) \
> +  checkfunc_ ## name ## _unary () { \
> +    svbool_t pg = svptrue_b8 (); \
> +    svbool_t data = svptrue_pat_b8 (SV_VL ## n); \
> +    svbool_t exp = intr (pg, data); \
> +    svbool_t actual = func_ ## name ## _unary (data); \
> +    svbool_t cmp = sveor_b_z (pg, exp, actual); \
> +    if (svptest_any (pg, cmp)) \
> +      __builtin_abort (); \
> +  }
> +
> +#define DECL_FUNC_UNARY_COND(name, op, n)  \
> +  svbool_t __attribute__ ((noipa)) \
> +  func_ ## name  ## _unary_cond (svbool_t a) { \
> +    return op (a); \
> +  } \
> +  svbool_t __attribute__ ((noipa)) \
> +  name (svbool_t t, svbool_t a) { \
> +    svbool_t pgl = sveor_b_z (t, a, svptrue_b8 ()); \
> +    return pgl; \
> +  } \
> +  void __attribute__((noipa)) \
> +  checkfunc_ ## name ## _unary_cond () { \
> +    svbool_t a = svptrue_pat_b8 (SV_VL ## n); \
> +    svbool_t all_true = svptrue_b8 (); \
> +    svbool_t cmp = func_ ## name ## _unary_cond (a); \
> +    svbool_t pgc = name (all_true, a) ; \
> +    svbool_t res = sveor_b_z (all_true, cmp, pgc); \
> +    if (svptest_any (all_true, res)) \
> +      __builtin_abort (); \
> +  }
> +
> +#define VECT_CST { -1, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1 } 
> /* { dg-
> warning "overflow in conversion from" "" { target c } }  */
> +#define VECT_CSTN { -1, t (), 0, -1, 0, f (), 0, 0, 0, -1, 0, -1, 0, -1, 0, 
> -1 } /* {
> dg-warning "overflow in conversion from" "" { target c } }  */
> +     /* { dg-warning "narrowing conversion of" "" { target c++ } .-1 }  */
> +
> +#define DECL_FUNC_INIT() \
> +  svbool_t __attribute__ ((noipa)) \
> +  func_init1 () { \
> +    svbool_t temp = VECT_CST; \
> +    return temp; \
> +  } \
> +  svbool_t __attribute__ ((noipa)) \
> +  func_init2 () { \
> +    svbool_t temp = { 0 }; \
> +    return temp; \
> +  } \
> +  svbool_t __attribute__ ((noipa)) \
> +  func_init3 () { \
> +    svbool_t temp = { }; \
> +    return temp; \
> +  } \
> +  int __attribute__ ((noipa)) \
> +  t () { \
> +    return -1; \
> +  } \
> +  int __attribute__ ((noipa)) \
> +  f () { \
> +    return 0; \
> +  } \
> +  svbool_t __attribute__ ((noipa)) \
> +  func_init4 () { \
> +    svbool_t temp = VECT_CSTN; \
> +    return temp; \
> +  } \
> +  void __attribute__((noipa)) \
> +  checkfunc_init() { \
> +    svbool_t all_true = svptrue_b8 (); \
> +    svbool_t v16_true = svptrue_pat_b8 (SV_VL16); \
> +    int8_t mem[] = VECT_CST; \
> +    int8_t memn[] = VECT_CSTN; \
> +    svint8_t t8 = svld1_s8 (v16_true, mem); \
> +    svbool_t init1 = __builtin_convertvector (t8, svbool_t); \
> +    svbool_t init2 = __builtin_convertvector (svindex_s8 (0, 0), svbool_t); \
> +    svbool_t init3 = __builtin_convertvector (svindex_s8 (0, 0), svbool_t); \
> +    svint8_t tn8 = svld1_s8 (v16_true, memn); \
> +    svbool_t init4 = __builtin_convertvector (tn8, svbool_t); \
> +     \
> +    svbool_t res_init1 = func_init1 (); \
> +    svbool_t cmp = sveor_b_z (all_true, init1, res_init1); \
> +    if (svptest_any (v16_true, cmp)) \
> +      __builtin_abort (); \
> +     \
> +    svbool_t res_init2 = func_init2 (); \
> +    cmp = sveor_b_z (all_true, init2, res_init2); \
> +    if (svptest_any (v16_true, cmp)) \
> +      __builtin_abort (); \
> +     \
> +    svbool_t res_init3 = func_init3 (); \
> +    cmp = sveor_b_z (all_true, init3, res_init3); \
> +    if (svptest_any (v16_true, cmp)) \
> +      __builtin_abort (); \
> +     \
> +    svbool_t res_init4 = func_init4 (); \
> +    cmp = sveor_b_z (all_true, init4, res_init4); \
> +    if (svptest_any (v16_true, cmp)) \
> +      __builtin_abort (); \
> +  }
> +
> +#define DECL_FUNC_BINARY(name, op, intr, n) \
> +  svbool_t __attribute__((noipa)) \
> +  func_ ## name ## _binary(svbool_t a, svbool_t b) { \
> +    return (a) op (b); \
> +  } \
> +  void __attribute__((noipa)) \
> +  checkfunc_ ## name ## _binary () { \
> +    svbool_t pg = svptrue_b8 (); \
> +    svbool_t data1 = svptrue_pat_b8 (SV_VL ## n); \
> +    svbool_t data2 = svnot_b_z (pg, data1); \
> +    svbool_t exp = intr (pg, data1, data2); \
> +    svbool_t actual = func_ ## name ## _binary (data1, data2); \
> +    svbool_t cmp = sveor_b_z (pg, exp, actual); \
> +    if (svptest_any (pg, cmp)) \
> +      __builtin_abort (); \
> +  }
> +
> +#define DECL_FUNC_BINARY_COND(name, op, intr, n) \
> +  svbool_t __attribute__ ((noipa)) \
> +  func_ ## name ## _binary_cond(svbool_t a, svbool_t b) { \
> +    return (a) op (b); \
> +  } \
> +  svbool_t __attribute__ ((noipa)) \
> +  name ## intr (svbool_t t, svbool_t a, svbool_t b) { \
> +    return sv ## intr ## _b_z (t, a, b); \
> +  } \
> +  void __attribute__((noipa)) \
> +  checkfunc_ ## name ## _binary_cond () { \
> +    svbool_t all_true = svptrue_b8 (); \
> +    svbool_t a = svptrue_pat_b8 (SV_VL ## n); \
> +    svbool_t b = svnot_b_z (all_true, a); \
> +    svbool_t cmp = func_ ## name ## _binary_cond (a, b); \
> +    svbool_t pgc = name ## intr (all_true, a, b) ; \
> +    svbool_t res = sveor_b_z (all_true, cmp, pgc); \
> +    if (svptest_any (all_true, res)) \
> +      __builtin_abort (); \
> +  }
> +
> +#define DECL_FUNC_BOOL_TERNARY(n) \
> +  svbool_t __attribute__((noipa)) \
> +  func_svbool_t_ternary_eq(svbool_t p, svbool_t q, svbool_t a, svbool_t b) {
> \
> +    return (p == q) ? a : b; \
> +  } \
> +  svbool_t __attribute__((noipa)) \
> +  func_svbool_t_ternary_ne(svbool_t p, svbool_t q, svbool_t a, svbool_t b) {
> \
> +    return (p != q) ? a : b; \
> +  } \
> +  svbool_t __attribute__((noipa)) \
> +  func_svbool_t_ternary_ex(svbool_t p, svbool_t a, svbool_t b) { \
> +    return (p) ? a : b; \
> +  } \
> +  void __attribute__((noipa)) \
> +  checkfunc_svbool_t_ternary () { \
> +    svbool_t pg = svptrue_b8 (); \
> +    svbool_t p = svptrue_pat_b8 (SV_VL ## n); \
> +    svbool_t q = svnot_b_z (pg, p); \
> +    svbool_t a = p; \
> +    svbool_t b = q; \
> +    svbool_t ne = sveor_b_z (pg, p, q); \
> +    svbool_t eq = svnot_b_z (pg, sveor_b_z (pg, p, q)); \
> +    svbool_t ex = p; \
> +    svbool_t expeq = svsel_b (eq, a, b); \
> +    svbool_t expne = svsel_b (ne, a, b); \
> +    svbool_t expex = svsel_b (ex, a, b); \
> +    svbool_t actualeq = func_svbool_t_ternary_eq (p, q, a, b); \
> +    svbool_t actualne = func_svbool_t_ternary_ne (p, q, a, b); \
> +    svbool_t actualex = func_svbool_t_ternary_ex (p, a, b); \
> +    svbool_t pgc_eq = sveor_b_z (pg, actualeq, expeq); \
> +    svbool_t pgc_ne = sveor_b_z (pg, actualne, expne); \
> +    svbool_t pgc_ex = sveor_b_z (pg, actualex, expex); \
> +    if (svptest_any (pg, pgc_eq)) \
> +      __builtin_abort (); \
> +    if (svptest_any (pg, pgc_ne)) \
> +      __builtin_abort (); \
> +    if (svptest_any (pg, pgc_ex)) \
> +      __builtin_abort (); \
> +  }
> +
> +svbool_t __attribute__((noipa))
> +my_svneor_b_z (svbool_t pg, svbool_t a, svbool_t b)
> +{
> +  return svnot_b_z (pg, sveor_b_z (pg, a, b));
> +}
> +
> +svbool_t  __attribute__((noipa))
> +func_svbool_t_bc (svint8_t a)
> +{
> +  return __builtin_convertvector (a, svbool_t);
> +}
> +
> +void __attribute__((noipa))
> +checkfunc_svbool_t_bc ()
> +{
> +  svbool_t pg = svptrue_b8 ();
> +  svint8_t data = { -1, -1, -1, -1 };
> +  svbool_t actual = func_svbool_t_bc (data);
> +  svbool_t exp = svptrue_pat_b8 (SV_VL4);
> +  svbool_t cmp = sveor_b_z (pg, exp, actual);
> +  if (svptest_any (pg, cmp))
> +    __builtin_abort ();
> +}
> +
> +svint8_t  __attribute__((noipa))
> +func_svint8_t_bc (svbool_t a)
> +{
> +  return __builtin_convertvector (a, svint8_t);
> +}
> +
> +void __attribute__((noipa))
> +checkfunc_svint8_t_bc ()
> +{
> +  svbool_t pg = svptrue_b8 ();
> +  svbool_t data = svptrue_pat_b8 (SV_VL4);
> +  svint8_t actual = func_svint8_t_bc (data);
> +  svint8_t exp = { -1, -1, -1, -1 };
> +  svbool_t cmp = svcmpne_s8 (pg, exp, actual);
> +  if (svptest_any (pg, cmp))
> +    __builtin_abort ();
> +}
> +
> +DECL_FUNC_UNARY (not, ~, svnot_b_z, 4)
> +DECL_FUNC_BINARY (and, &, svand_b_z, 8)
> +DECL_FUNC_BINARY (orr, |, svorr_b_z, 6)
> +DECL_FUNC_BINARY (eor, ^, sveor_b_z, 3)
> +
> +DECL_FUNC_BINARY (eq, ==, my_svneor_b_z, 4)
> +DECL_FUNC_BINARY (ne, !=, sveor_b_z, 4)
> +
> +DECL_FUNC_INIT ()
> +
> +#ifdef __cplusplus
> +DECL_FUNC_UNARY_COND (lnot, !, 8)
> +DECL_FUNC_BINARY_COND (and_and, &&, and, 8)
> +DECL_FUNC_BINARY_COND (or_or, ||, orr, 8)
> +DECL_FUNC_BOOL_TERNARY (3)
> +#endif
> +
> +#undef DECL_FUNC_UNARY
> +#define DECL_FUNC_UNARY(name, op, intr, n) \
> +  checkfunc_ ## name ## _unary ();
> +
> +#undef DECL_FUNC_UNARY_COND
> +#define DECL_FUNC_UNARY_COND(name, op, n)  \
> +  checkfunc_ ## name ## _unary_cond ();
> +
> +#undef DECL_FUNC_INIT
> +#define DECL_FUNC_INIT() \
> +  checkfunc_init ();
> +
> +#undef DECL_FUNC_BINARY
> +#define DECL_FUNC_BINARY(name, op, intr, n) \
> +  checkfunc_ ## name ## _binary ();
> +
> +#undef DECL_FUNC_BINARY_COND
> +#define DECL_FUNC_BINARY_COND(name, op, intr, n) \
> +  checkfunc_ ## name ## _binary_cond ();
> +
> +#undef  DECL_FUNC_BOOL_TERNARY
> +#define  DECL_FUNC_BOOL_TERNARY(n) \
> +  checkfunc_svbool_t_ternary ();
> +
> +int
> +main ()
> +{
> +  DECL_FUNC_UNARY (not, ~, svnot_b_z, 4)
> +  DECL_FUNC_BINARY (and, &, svand_b_z, 8)
> +  DECL_FUNC_BINARY (orr, |, svorr_b_z, 6)
> +  DECL_FUNC_BINARY (eor, ^, sveor_b_z, 3)
> +
> +  DECL_FUNC_BINARY (ne, !=, sveor_b_z, 4)
> +  DECL_FUNC_BINARY (eq, ==, my_svneor_b_z, 4)
> +
> +  DECL_FUNC_INIT ()
> +
> +  checkfunc_svbool_t_bc ();
> +  checkfunc_svint8_t_bc ();
> +
> +#ifdef __cplusplus
> +  DECL_FUNC_UNARY_COND (lnot, !, 8)
> +  DECL_FUNC_BINARY_COND (and_and, &&, and, 8)
> +  DECL_FUNC_BINARY_COND (or_or, ||, orr, 8)
> +  DECL_FUNC_BOOL_TERNARY (3)
> +#endif
> +
> +  return 0;
> +}
> --
> 2.34.1


Reply via email to