On Sun, Nov 1, 2026 at 1:48 AM Torbjorn SVENSSON
<[email protected]> wrote:
>
> Hi,
>
> The new test is failing for MVE enabled targets on arm-none-eabi.
>
> These are the errors produced for 
> thumb/arch=armv8.1-m.main+mve.fp+fp.dp/cpu=cortex-m55/float-abi=hard/fpu=auto:
>
> /build/gcc_src/gcc/testsuite/gcc.dg/tree-ssa/vect-cmp-cmp-1.c: In function 
> 'a':
> /build/gcc_src/gcc/testsuite/gcc.dg/tree-ssa/vect-cmp-cmp-1.c:10:14: error: 
> incompatible types when initializing type 'v4sib' {aka '__vector(4) signed 
> char:4'} using type '__vector(4) int'
> /build/gcc_src/gcc/testsuite/gcc.dg/tree-ssa/vect-cmp-cmp-1.c:11:14: error: 
> incompatible types when initializing type 'v4sib' {aka '__vector(4) signed 
> char:4'} using type '__vector(4) int'
> /build/gcc_src/gcc/testsuite/gcc.dg/tree-ssa/vect-cmp-cmp-1.c:12:3: error: 
> cannot convert a value of type '__vector(4) signed char' to vector type 
> '__vector(4) int' which has different size
> /build/gcc_src/gcc/testsuite/gcc.dg/tree-ssa/vect-cmp-cmp-1.c: In function 
> 'b':
> /build/gcc_src/gcc/testsuite/gcc.dg/tree-ssa/vect-cmp-cmp-1.c:17:14: error: 
> incompatible types when initializing type 'v4sib' {aka '__vector(4) signed 
> char:4'} using type '__vector(4) int'
> /build/gcc_src/gcc/testsuite/gcc.dg/tree-ssa/vect-cmp-cmp-1.c:18:14: error: 
> incompatible types when initializing type 'v4sib' {aka '__vector(4) signed 
> char:4'} using type '__vector(4) int'
> /build/gcc_src/gcc/testsuite/gcc.dg/tree-ssa/vect-cmp-cmp-1.c:19:3: error: 
> cannot convert a value of type '__vector(4) signed char' to vector type 
> '__vector(4) int' which has different size
>
> Any idea how to fix?

Yes, the best option is just to have it tested for x86_64/i386 and
aarch64.  vector_mask is not very portable.

>
> Kind regards,
> Torbjörn
>
> On 2026-10-25 18:54, Andrea Pinski wrote:
> > r17-4001-gbbc2517fe41 added support to combine_comparisons for LT/LE/GT/GE
> > but it assumed unsigned boolean types ([0,1]) which is wrong for signed
> > boolean types ([0,-1]). For an example, for signed boolean types,
> > LT is the same as GT for unsigned boolean types.  So this was combining
> > incorrectly and getting the incorrect answer.
> > This fixes the problem by adding support for signed boolean. Since we
> > need to pass in a new argument to combine_comparisons, this updates
> > all of the uses of combine_comparisons which makes the patch
> > look bigger than it really is.
> >
> > Bootstrapped and tested on x86_64-linux-gnu with no regressions.
> >
> >       PR tree-optimization/128123
> >
> > gcc/ChangeLog:
> >
> >       * fold-const.cc (combine_comparisons): Take new argument,
> >       inner_truth_type and look to see if it is signed boolean
> >       and support that for LT/LE/GT/GE.
> >       (fold_truth_andor_1): Update call to combine_comparisons.
> >       * fold-const.h (combine_comparisons): Add new argument.
> >       * gimple-fold.cc (and_comparisons_1): Update call to
> >       combine_comparisons.
> >       (or_comparisons_1): Likewise.
> >       * tree-ssa-ifcombine.cc (ifcombine_ifandif): Likewise.
> >       * tree-ssa-phiopt.cc (comparison_combine): Likewise.
> >       * match.pd (`(CMP) OP (CMP)`): Update call to
> >       combine_comparisons.
> >
> > gcc/testsuite/ChangeLog:
> >
> >       * gcc.dg/tree-ssa/vect-cmp-cmp-1.c: New test.
> >
> > Signed-off-by: Andrea Pinski <[email protected]>
> > ---
> >   gcc/fold-const.cc                             | 54 ++++++++++++++-----
> >   gcc/fold-const.h                              |  4 +-
> >   gcc/gimple-fold.cc                            |  8 +--
> >   gcc/match.pd                                  |  5 +-
> >   .../gcc.dg/tree-ssa/vect-cmp-cmp-1.c          | 34 ++++++++++++
> >   gcc/tree-ssa-ifcombine.cc                     | 15 ++++--
> >   gcc/tree-ssa-phiopt.cc                        |  2 +-
> >   7 files changed, 95 insertions(+), 27 deletions(-)
> >   create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/vect-cmp-cmp-1.c
> >
> > diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc
> > index 1fc4941b481..047c7dcada4 100644
> > --- a/gcc/fold-const.cc
> > +++ b/gcc/fold-const.cc
> > @@ -3010,13 +3010,21 @@ inverse_conditions_p (const_tree cond1, const_tree 
> > cond2)
> >
> >   enum tree_code
> >   combine_comparisons (enum tree_code code, enum tree_code lcode,
> > -                    enum tree_code rcode, tree truth_type,
> > -                    bool honor_nans, tree *res)
> > +                  enum tree_code rcode, tree truth_type,
> > +                  tree inner_truth_type,
> > +                  bool honor_nans, tree *res)
> >   {
> >     enum comparison_code lcompcode = comparison_to_compcode (lcode);
> >     enum comparison_code rcompcode = comparison_to_compcode (rcode);
> >     int compcode;
> >     *res = NULL_TREE;
> > +  if (TREE_CODE (inner_truth_type) == VECTOR_TYPE)
> > +    inner_truth_type = TREE_TYPE (inner_truth_type);
> > +  bool signed_bool = false;
> > +  if (TYPE_SIGN (inner_truth_type) == SIGNED
> > +      && (TREE_CODE (inner_truth_type) == BOOLEAN_TYPE
> > +          || TYPE_PRECISION (inner_truth_type) == 1))
> > +    signed_bool = true;
> >
> >     switch (code)
> >       {
> > @@ -3039,24 +3047,40 @@ combine_comparisons (enum tree_code code, enum 
> > tree_code lcode,
> >         compcode = ~(lcompcode ^ rcompcode);
> >         break;
> >
> > -    //`bool0 < bool1` is `!bool0 & bool1`
> > +    //`bool0 < bool1` is `!bool0 & bool1` for unsigned
> > +    //`bool0 < bool1` is `bool0 & !bool1` for signed
> >       case LT_EXPR:
> > -      compcode = ~lcompcode & rcompcode;
> > +      if (signed_bool)
> > +        compcode = lcompcode & ~rcompcode;
> > +      else
> > +        compcode = ~lcompcode & rcompcode;
> >         break;
> >
> > -    //`bool0 > bool1` is `bool0 & !bool1`
> > +    //`bool0 > bool1` is `bool0 & !bool1` for unsigned
> > +    //`bool0 > bool1` is `!bool0 & bool1` for signed
> >       case GT_EXPR:
> > -      compcode = lcompcode & ~rcompcode;
> > +      if (signed_bool)
> > +        compcode = ~lcompcode & rcompcode;
> > +      else
> > +        compcode = lcompcode & ~rcompcode;
> >         break;
> >
> > -    // `bool0 <= bool1` as !bool0 | bool1
> > +    // `bool0 <= bool1` as !bool0 | bool1 for unsigned
> > +    // `bool0 <= bool1` as bool0 | !bool1 for signed
> >       case LE_EXPR:
> > -      compcode = ~lcompcode | rcompcode;
> > +      if (signed_bool)
> > +        compcode = lcompcode | ~rcompcode;
> > +      else
> > +        compcode = ~lcompcode | rcompcode;
> >         break;
> >
> > -    //`bool0 >= bool1` is `bool0 | !bool1`
> > +    //`bool0 >= bool1` is `bool0 | !bool1` for unsigned
> > +    //`bool0 >= bool1` is `bool0 | !bool1` for signed
> >       case GE_EXPR:
> > -      compcode = lcompcode | ~rcompcode;
> > +      if (signed_bool)
> > +        compcode = ~lcompcode | rcompcode;
> > +      else
> > +        compcode = lcompcode | ~rcompcode;
> >         break;
> >
> >       default:
> > @@ -3136,12 +3160,14 @@ tree
> >   combine_comparisons (location_t loc,
> >                    enum tree_code code, enum tree_code lcode,
> >                    enum tree_code rcode, tree truth_type,
> > +                  tree inner_truth_type,
> >                    tree ll_arg, tree lr_arg)
> >   {
> >     bool honor_nans = HONOR_NANS (ll_arg);
> >     tree_code rescode;
> >     tree res;
> > -  rescode = combine_comparisons (code, lcode, rcode, truth_type,
> > +  rescode = combine_comparisons (code, lcode, rcode,
> > +                              truth_type, inner_truth_type,
> >                                honor_nans, &res);
> >     if (rescode == ERROR_MARK)
> >       return NULL_TREE;
> > @@ -6504,7 +6530,8 @@ fold_truth_andor_1 (location_t loc, enum tree_code 
> > code, tree truth_type,
> >             && operand_equal_p (lr_arg, rr_arg, 0))
> >       {
> >             result = combine_comparisons (loc, code, lcode, rcode,
> > -                                     truth_type, ll_arg, lr_arg);
> > +                                     truth_type, TREE_TYPE (lhs),
> > +                                     ll_arg, lr_arg);
> >         if (result)
> >           return result;
> >       }
> > @@ -6513,7 +6540,8 @@ fold_truth_andor_1 (location_t loc, enum tree_code 
> > code, tree truth_type,
> >       {
> >             result = combine_comparisons (loc, code, lcode,
> >                                       swap_tree_comparison (rcode),
> > -                                     truth_type, ll_arg, lr_arg);
> > +                                     truth_type,  TREE_TYPE (lhs),
> > +                                     ll_arg, lr_arg);
> >         if (result)
> >           return result;
> >       }
> > diff --git a/gcc/fold-const.h b/gcc/fold-const.h
> > index 437d8ece021..4e640de725f 100644
> > --- a/gcc/fold-const.h
> > +++ b/gcc/fold-const.h
> > @@ -180,9 +180,9 @@ extern bool fold_cmp_float_cst_p (const wide_int &lo, 
> > const wide_int &hi,
> >                                 const wide_int &i, signop isign);
> >
> >   extern tree combine_comparisons (location_t, enum tree_code, enum 
> > tree_code,
> > -                              enum tree_code, tree, tree, tree);
> > +                              enum tree_code, tree, tree, tree, tree);
> >   extern tree_code combine_comparisons (enum tree_code, enum tree_code,
> > -                                   enum tree_code, tree, bool, tree*);
> > +                                   enum tree_code, tree, tree, bool, 
> > tree*);
> >   extern void debug_fold_checksum (const_tree);
> >   extern bool may_negate_without_overflow_p (const_tree);
> >   #define round_up(T,N) round_up_loc (UNKNOWN_LOCATION, T, N)
> > diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc
> > index e0197edece6..ed84dab7f37 100644
> > --- a/gcc/gimple-fold.cc
> > +++ b/gcc/gimple-fold.cc
> > @@ -7602,7 +7602,7 @@ and_comparisons_1 (tree type, enum tree_code code1, 
> > tree op1a, tree op1b,
> >         /* Result will be either NULL_TREE, or a combined comparison.  */
> >         tree t = combine_comparisons (UNKNOWN_LOCATION,
> >                                   TRUTH_ANDIF_EXPR, code1, code2,
> > -                                 truth_type, op1a, op1b);
> > +                                 truth_type, truth_type, op1a, op1b);
> >         if (t)
> >       return t;
> >       }
> > @@ -7615,7 +7615,7 @@ and_comparisons_1 (tree type, enum tree_code code1, 
> > tree op1a, tree op1b,
> >         tree t = combine_comparisons (UNKNOWN_LOCATION,
> >                                   TRUTH_ANDIF_EXPR, code1,
> >                                   swap_tree_comparison (code2),
> > -                                 truth_type, op1a, op1b);
> > +                                 truth_type, truth_type, op1a, op1b);
> >         if (t)
> >       return t;
> >       }
> > @@ -9574,7 +9574,7 @@ or_comparisons_1 (tree type, enum tree_code code1, 
> > tree op1a, tree op1b,
> >         /* Result will be either NULL_TREE, or a combined comparison.  */
> >         tree t = combine_comparisons (UNKNOWN_LOCATION,
> >                                   TRUTH_ORIF_EXPR, code1, code2,
> > -                                 truth_type, op1a, op1b);
> > +                                 truth_type, truth_type, op1a, op1b);
> >         if (t)
> >       return t;
> >       }
> > @@ -9587,7 +9587,7 @@ or_comparisons_1 (tree type, enum tree_code code1, 
> > tree op1a, tree op1b,
> >         tree t = combine_comparisons (UNKNOWN_LOCATION,
> >                                   TRUTH_ORIF_EXPR, code1,
> >                                   swap_tree_comparison (code2),
> > -                                 truth_type, op1a, op1b);
> > +                                 truth_type, truth_type, op1a, op1b);
> >         if (t)
> >       return t;
> >       }
> > diff --git a/gcc/match.pd b/gcc/match.pd
> > index 696e69fd980..02941a7dacf 100644
> > --- a/gcc/match.pd
> > +++ b/gcc/match.pd
> > @@ -3771,14 +3771,15 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
> >    (for cmp1 (tcc_comparison)
> >     (for cmp2 (tcc_comparison)
> >      (simplify
> > -    (bitop (cmp1 @0 @1) (cmp2 @0 @1))
> > +    (bitop (cmp1@2 @0 @1) (cmp2 @0 @1))
> >       (with rescmpcode (tcc_comparison)
> >         {
> >           tree_code rescmpcode;
> >           tree res;
> >           bool honor_nans = HONOR_NANS (@0);
> >           rescmpcode = combine_comparisons (bitop, cmp1, cmp2,
> > -                                       type, honor_nans, &res);
> > +                                       type, TREE_TYPE (@2),
> > +                                       honor_nans, &res);
> >         }
> >        (if (rescmpcode == INTEGER_CST)
> >         { res; }
> > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vect-cmp-cmp-1.c 
> > b/gcc/testsuite/gcc.dg/tree-ssa/vect-cmp-cmp-1.c
> > new file mode 100644
> > index 00000000000..8ccf94df274
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.dg/tree-ssa/vect-cmp-cmp-1.c
> > @@ -0,0 +1,34 @@
> > +/* { dg-do run } */
> > +/* { dg-options "-O -fgimple" } */
> > +/* PR tree-optimization/128123 */
> > +
> > +typedef int v4si __attribute__((vector_size (4*sizeof(int))));
> > +typedef v4si v4sib __attribute__((vector_mask));
> > +
> > +__attribute__((noipa)) void a(v4si *x, v4si *y, v4si *res)
> > +{
> > +  v4sib m1 = *x < *y;
> > +  v4sib m2 = *x > *y;
> > +  *res = (v4si) (m1 < m2);
> > +}
> > +
> > +__attribute__((noipa)) void b(v4si *x, v4si *y, v4si *res)
> > +{
> > +  v4sib m1 = *x < *y;
> > +  v4sib m2 = *x > *y;
> > +  *res = (v4si) (m1 <= m2);
> > +}
> > +
> > +int main (void)
> > +{
> > +  v4si x = { 1, 2, 3, 4 }, y = { 2, 2, 2, 5 };
> > +  v4si r;
> > +  a(&x, &y, &r);
> > +  v4si s;
> > +  b(&x, &y, &s);
> > +  for (int i = 0; i < 4; i++)
> > +    if (r[i] != -(x[i] < y[i]) || s[i] != -(x[i] <= y[i]))
> > +      __builtin_abort();
> > +  return 0;
> > +}
> > +
> > diff --git a/gcc/tree-ssa-ifcombine.cc b/gcc/tree-ssa-ifcombine.cc
> > index 28bb5bf0998..0d663f4130b 100644
> > --- a/gcc/tree-ssa-ifcombine.cc
> > +++ b/gcc/tree-ssa-ifcombine.cc
> > @@ -865,14 +865,16 @@ ifcombine_ifandif (basic_block inner_cond_bb, bool 
> > inner_inv,
> >        if (!inner_inv && !outer_inv)
> >       res = combine_comparisons (UNKNOWN_LOCATION, TRUTH_ANDIF_EXPR,
> >                                  outer_cond_code, inner_cond_code,
> > -                                boolean_type_node, larg, rarg);
> > +                                boolean_type_node, boolean_type_node,
> > +                                larg, rarg);
> >         // If both are inverse, `!a && !b`, then handle it as `!(a || b)`
> >         // As that !a or !b are most likely not producing a comparison code.
> >         else if (inner_inv && outer_inv)
> >       {
> >         res = combine_comparisons (UNKNOWN_LOCATION, TRUTH_ORIF_EXPR,
> >                                    outer_cond_code, inner_cond_code,
> > -                                  boolean_type_node, larg, rarg);
> > +                                  boolean_type_node, boolean_type_node,
> > +                                  larg, rarg);
> >         if (res)
> >           res = fold_build1 (TRUTH_NOT_EXPR, TREE_TYPE (res), res);
> >       }
> > @@ -891,7 +893,8 @@ ifcombine_ifandif (basic_block inner_cond_bb, bool 
> > inner_inv,
> >         if (inner_cond_code1 != ERROR_MARK && outer_cond_code1 != 
> > ERROR_MARK)
> >           res = combine_comparisons (UNKNOWN_LOCATION, TRUTH_ANDIF_EXPR,
> >                                      outer_cond_code1, inner_cond_code1,
> > -                                    boolean_type_node, larg, rarg);
> > +                                    boolean_type_node, boolean_type_node,
> > +                                    larg, rarg);
> >         // Otherwise, we need to try `!(!a || b)
> >         else if (inner_cond_code1 == ERROR_MARK)
> >           {
> > @@ -901,7 +904,8 @@ ifcombine_ifandif (basic_block inner_cond_bb, bool 
> > inner_inv,
> >             if (outer_cond_code1 != ERROR_MARK)
> >               res = combine_comparisons (UNKNOWN_LOCATION, TRUTH_ORIF_EXPR,
> >                                          outer_cond_code1, inner_cond_code,
> > -                                        boolean_type_node, larg, rarg);
> > +                                        boolean_type_node, 
> > boolean_type_node,
> > +                                        larg, rarg);
> >             if (res)
> >               res = fold_build1 (TRUTH_NOT_EXPR, TREE_TYPE (res), res);
> >           }
> > @@ -914,7 +918,8 @@ ifcombine_ifandif (basic_block inner_cond_bb, bool 
> > inner_inv,
> >             if (inner_cond_code1 != ERROR_MARK)
> >               res = combine_comparisons (UNKNOWN_LOCATION, TRUTH_ORIF_EXPR,
> >                                          outer_cond_code, inner_cond_code1,
> > -                                        boolean_type_node, larg, rarg);
> > +                                        boolean_type_node, 
> > boolean_type_node,
> > +                                        larg, rarg);
> >             if (res)
> >               res = fold_build1 (TRUTH_NOT_EXPR, TREE_TYPE (res), res);
> >           }
> > diff --git a/gcc/tree-ssa-phiopt.cc b/gcc/tree-ssa-phiopt.cc
> > index 08b40897a60..51553484226 100644
> > --- a/gcc/tree-ssa-phiopt.cc
> > +++ b/gcc/tree-ssa-phiopt.cc
> > @@ -1651,7 +1651,7 @@ comparison_combine (basic_block cond_bb, basic_block 
> > middle_bb,
> >     tree result;
> >     tree_code newcmp_code;
> >     newcmp_code = combine_comparisons (logical, outer_code, inner_code,
> > -                                  boolean_type_node,
> > +                                  boolean_type_node, boolean_type_node,
> >                                    HONOR_NANS (larg), &result);
> >     if (newcmp_code == ERROR_MARK)
> >       return false;
>

Reply via email to